From c53390686eddf591ed39d6339c7a0f6de76d2e16 Mon Sep 17 00:00:00 2001 From: Vlad Ureche Date: Fri, 16 Mar 2012 01:43:27 +0100 Subject: Space/Tab cleanup script - run before committing Running this script will transform tabs into a pair of spaces and will eliminate trailing spaces. Use at your own risk! --- gitignore.SAMPLE | 5 ++ tools/cleanup-commit | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100755 tools/cleanup-commit diff --git a/gitignore.SAMPLE b/gitignore.SAMPLE index 3c15a5de9e..483ad4caca 100644 --- a/gitignore.SAMPLE +++ b/gitignore.SAMPLE @@ -27,4 +27,9 @@ /src/intellij/*.iml /src/intellij/*.ipr /src/intellij/*.iws +/.cache +/.idea +/.settings +# bak files produced by ./cleanup-commit +*.bak diff --git a/tools/cleanup-commit b/tools/cleanup-commit new file mode 100755 index 0000000000..400d434359 --- /dev/null +++ b/tools/cleanup-commit @@ -0,0 +1,130 @@ +#!/bin/bash + +## +## The cleanup-commit script +## ------------------------- +## This little script will cleanup your commit before you send it. You need to add the files to the staged area and +## run this script. It will automatically cleanup tabs and trailing spaces for the files you added and then add the +## clean versions to the staging area. +## +## Use at your own risk, I spent some time making the script error-proof so it will abort if sees any inconsistency, +## but of course playing around with your commit might break things. Btw, it saves the original file to file.bak. +## +## Happy hacking! +## + +ABORT="Ab0rT0p3r4+|0n" + +# +# Cleanup function +# +function cleanup { + echo Cleaning up $1... + # prepare the ground + rm -rf $1.bak + # compress into double and eliminate trailing s + sed -i.bak -e 's/\t/ /g' -e 's/ *$//' $1 +} + + +# +# Get the git status for the current staged commit +# +FULLSTATUS=`git status --porcelain` + +if [ $? -ne 0 ] +then + echo "Unable to run git. Check if:" + echo " -- git is installed (you can run git in the command line)" + echo " -- the current directory is a valid git repository" + exit 1 +fi + +echo + +# +# Based on the status decide what files will get cleaned up +# +CLEANUP_FILES=`echo "$FULLSTATUS" | while read LINE +do + + STATUS=$(echo $LINE | sed 's/^\(..\).*$/\1/') + if [ $? -ne 0 ] + then + echo "Could not get the status for line: $LINE" + echo " -- you have the basic unix tools installed (grep, cut, sed)" + echo $ABORT # This goes to CLEANUP_FILES + exit 1 + fi + + FILES=$(echo $LINE | sed 's/^..//') + FILE1=$(echo $FILES | cut -d ' ' -f 1) + FILE2=$(echo $FILES | cut -d ' ' -f 3) + + case "$STATUS" in + [AMRDC]" ") + case "$STATUS" in + "A "|"M ") + echo $FILE1 + ;; + "R ") + echo $FILE2 + ;; + "D ") + #nothing to do + ;; + "C ") + echo $FILE1 + echo $FILE2 + ;; + esac + ;; + "??") + # File is not tracked, no need to do anything about it + # echo Untracked: $FILE1 + ;; + *) + echo "Unstable status of file $FILE1 (\"$STATUS\")" >&2 + echo "Aborting cleanup!" >&2 + echo $ABORT # This goes to CLEANUP_FILES + exit 1 + esac +done; echo $CLEANUP_FILES` + + +# +# Perform actual cleanup +# +case $CLEANUP_FILES in +*"$ABORT") + echo + exit 1 + ;; +"") + echo Nothing to do! + ;; +*) + cd $(git rev-parse --show-toplevel) + + if [ $? -ne 0 ] + then + echo Unexpected error: cannot cd to the repository root + echo Aborting cleanup! + exit 1 + fi + + echo "$CLEANUP_FILES" | while read FILE + do + cleanup $FILE + done + + cd - &>/dev/null + + echo + echo "Cleanup done: " + echo " - original files saved as .bak" + echo " - you can do \"git diff\" to see the changes the script did" + echo " - you can do \"git commit -a\" to commit the cleaned up files" + echo + ;; +esac -- cgit v1.2.3 From f93e2189dd4f6bf129e70f85c03af34e1b507377 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 10 Apr 2012 23:03:41 +0200 Subject: Fix memory leak related to default arguments in presentation compiler. This bug exists for a long time, but was triggered / discovered only lately by the default argument of mkParams in 118aef558f. This reverts the workaroud commit 19b6ad5ee4. The fix is tested by test/files/presentation/memory-leaks which runs the presentation compiler several times on Typers.scala. I could not reproduce the memory leak in a smaller test case. --- src/compiler/scala/tools/nsc/typechecker/Namers.scala | 4 ++-- src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 3 ++- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 2539091966..81cf1e3fbe 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -684,7 +684,7 @@ trait Namers extends MethodSynthesis { val acc = sym.lazyAccessor if (acc != NoSymbol) enterIfNotThere(acc) } - defaultParametersOfMethod(sym) foreach enterIfNotThere + defaultParametersOfMethod(sym) foreach { symRef => enterIfNotThere(symRef()) } } this.context } @@ -1161,7 +1161,7 @@ trait Namers extends MethodSynthesis { // if compiling the same local block several times (which can happen in interactive mode) // we might otherwise not find the default symbol, because the second time it the // method symbol will be re-entered in the scope but the default parameter will not. - defaultParametersOfMethod(meth) += default + defaultParametersOfMethod(meth) += new WeakReference(default) } } else if (baseHasDefault) { // the parameter does not have a default itself, but the diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 2573678f8c..4d84bf4af2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -8,6 +8,7 @@ package typechecker import symtab.Flags._ import scala.collection.mutable +import scala.ref.WeakReference /** * @author Lukas Rytz @@ -20,7 +21,7 @@ trait NamesDefaults { self: Analyzer => import NamesDefaultsErrorsGen._ val defaultParametersOfMethod = - perRunCaches.newWeakMap[Symbol, Set[Symbol]]() withDefaultValue Set() + perRunCaches.newWeakMap[Symbol, Set[WeakReference[Symbol]]]() withDefaultValue Set() case class NamedApplyInfo( qual: Option[Tree], diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f558e0afc7..c9679faa7d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2202,7 +2202,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { vparams map {p => if(p.tpt.tpe == null) typedType(p.tpt).tpe else p.tpt.tpe} } - def mkParams(methodSym: Symbol, formals: List[Type]/* = deriveFormals*/) = { + def mkParams(methodSym: Symbol, formals: List[Type] = deriveFormals) = { selOverride match { case None if targs.isEmpty => MissingParameterTypeAnonMatchError(tree, pt); (Nil, EmptyTree) case None => @@ -2228,7 +2228,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // rig the show so we can get started typing the method body -- later we'll correct the infos... anonClass setInfo ClassInfoType(List(ObjectClass.tpe, pt, SerializableClass.tpe), newScope, anonClass) val methodSym = anonClass.newMethod(nme.apply, tree.pos, FINAL) - val (paramSyms, selector) = mkParams(methodSym, deriveFormals) + val (paramSyms, selector) = mkParams(methodSym) if (selector eq EmptyTree) EmptyTree else { @@ -2292,7 +2292,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def isDefinedAtMethod = { val methodSym = anonClass.newMethod(nme.isDefinedAt, tree.pos, FINAL) - val (paramSyms, selector) = mkParams(methodSym, deriveFormals) + val (paramSyms, selector) = mkParams(methodSym) if (selector eq EmptyTree) EmptyTree else { val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it) -- cgit v1.2.3 From 9ea4ca3c80ece5c3c9ce6573aabc1920cf519507 Mon Sep 17 00:00:00 2001 From: gakuzzzz Date: Thu, 12 Apr 2012 00:36:38 +0900 Subject: This change enables the alphanumeric method to be called from SecureRandom --- src/library/scala/util/Random.scala | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/library/scala/util/Random.scala b/src/library/scala/util/Random.scala index 791582c9ec..62cba1fc5b 100644 --- a/src/library/scala/util/Random.scala +++ b/src/library/scala/util/Random.scala @@ -120,15 +120,6 @@ class Random(val self: java.util.Random) { bf(xs) ++= buf result } -} - -/** The object `Random` offers a default implementation - * of scala.util.Random and random-related convenience methods. - * - * @since 2.8 - */ -object Random extends Random { - /** Returns a Stream of pseudorandomly chosen alphanumeric characters, * equally chosen from A-Z, a-z, and 0-9. * @@ -141,3 +132,14 @@ object Random extends Random { } } + +/** The object `Random` offers a default implementation + * of scala.util.Random and random-related convenience methods. + * + * @since 2.8 + */ +object Random extends Random { + + implicit def javaRandomToRandom(r: java.util.Random): Random = new Random(r) + +} -- cgit v1.2.3 From d4d8f15ad121edfc0b924deaeb9c30a9d9b71e84 Mon Sep 17 00:00:00 2001 From: Dominik Gruntz Date: Wed, 11 Apr 2012 18:03:30 +0200 Subject: changed applyDynamic explanation in trait Dynamic --- src/library/scala/Dynamic.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/scala/Dynamic.scala b/src/library/scala/Dynamic.scala index 32b57ee88f..dcf7599742 100644 --- a/src/library/scala/Dynamic.scala +++ b/src/library/scala/Dynamic.scala @@ -11,7 +11,7 @@ package scala /** A marker trait that enables dynamic invocations. Instances `x` of this * trait allow calls `x.meth(args)` for arbitrary method names `meth` and * argument lists `args`. If a call is not natively supported by `x`, it - * is rewritten to `x.applyDynamic("meth", args)`. + * is rewritten to `x.applyDynamic("meth")(args)`. * * As of scala 2.9, `scalac` must receive the `-Xexperimental` option for * `Dynamic` to receive this treatment. -- cgit v1.2.3 From f7a0558059559305a88ffa2c28506b29b2bc57f2 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Apr 2012 11:06:54 -0700 Subject: Implementation of SIP 18. We still need to get rid of the warnings caused by it. Before we do that, I'd like to check in the SIP 13 implementation. --- .../scala/reflect/internal/Definitions.scala | 14 +++++- src/compiler/scala/reflect/internal/Symbols.scala | 6 +-- src/compiler/scala/reflect/internal/Types.scala | 17 +++++-- .../scala/tools/nsc/CompilationUnits.scala | 11 ++++- src/compiler/scala/tools/nsc/ast/Trees.scala | 4 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 3 +- .../scala/tools/nsc/interactive/Global.scala | 1 + .../scala/tools/nsc/settings/ScalaSettings.scala | 1 + .../scala/tools/nsc/typechecker/Typers.scala | 56 ++++++++++++++++++++-- 9 files changed, 97 insertions(+), 16 deletions(-) diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 8ea3cd511a..d3a9821596 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -914,6 +914,18 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val GetterTargetClass = getMetaAnnotation("getter") lazy val ParamTargetClass = getMetaAnnotation("param") lazy val SetterTargetClass = getMetaAnnotation("setter") + lazy val LanguageFeatureClass = getMetaAnnotation("languageFeature") + + // Language features + lazy val languageFeatureModule = getRequiredModule("scala.languageFeature") + lazy val MacrosFeature = getRequiredClass("scala.languageFeature.experimental.macros") + lazy val DynamicsFeature = getRequiredClass("scala.languageFeature.dynamics") + lazy val PostfixOpsFeature = getRequiredClass("scala.languageFeature.postfixOps") + lazy val ReflectiveCallsFeature = getRequiredClass("scala.languageFeature.reflectiveCalls") + lazy val ImplicitConversionsFeature = getRequiredClass("scala.languageFeature.implicitConversions") + lazy val HigherKindsFeature = getRequiredClass("scala.languageFeature.higherKinds") + lazy val ExistentialsFeature = getRequiredClass("scala.languageFeature.existentials") + // TODO: module, moduleClass? package, packageObject? private def getMetaAnnotation(name: String) = getRequiredClass("scala.annotation.meta." + name) @@ -990,7 +1002,7 @@ trait Definitions extends reflect.api.StandardDefinitions { case result => result } } - + def packageExists(packageName: String): Boolean = getModuleIfDefined(packageName).isPackage diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 5c43047046..b984383dd2 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -1191,7 +1191,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * which immediately follows any of parser, namer, typer, or erasure. * In effect that means this will return one of: * - * - packageobjects (follows namer) + * - packageobjects (follows namer) * - superaccessors (follows typer) * - lazyvals (follows erasure) * - null @@ -1882,7 +1882,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Remove private modifier from symbol `sym`s definition. If `sym` is a * is not a constructor nor a static module rename it by expanding its name to avoid name clashes - * @param base the fully qualified name of this class will be appended if name expansion is needed + * @param base the fully qualified name of this class will be appended if name expansion is needed */ final def makeNotPrivate(base: Symbol) { if (this.isPrivate) { @@ -2782,7 +2782,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => assert(validFrom != NoPeriod) override def toString() = "TypeHistory(" + phaseOf(validFrom)+":"+runId(validFrom) + "," + info + "," + prev + ")" - + def toList: List[TypeHistory] = this :: ( if (prev eq null) Nil else prev.toList ) } } diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 786b680ff8..46c56ccd4c 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -2493,26 +2493,33 @@ trait Types extends api.Types { self: SymbolTable => * - where there is a 1-to-1 correspondence between underlying's typeargs and quantified * - and none of the existential parameters is referenced from anywhere else in the type * - and none of the existential parameters are singleton types + * - @param checkBounds if set returns false for situations like + * (S, T) forSome { type S; type T <: S } + * If not set returns true. The reason for this mode is to + * avoid cyclic reference errors when the method is called + * early (e.g. from Typers # checkExistentialsFeature) */ - private def isRepresentableWithWildcards = !settings.debug.value && { + def isRepresentableWithWildcards(checkBounds: Boolean) = { val qset = quantified.toSet - !qset.exists(_.isSingletonExistential) && (underlying match { + underlying match { case TypeRef(_, sym, args) => sameLength(args, quantified) && { args forall { arg => - qset(arg.typeSymbol) && !qset.exists(arg.typeSymbol.info.bounds contains _) + qset(arg.typeSymbol) && + (!checkBounds || !qset.exists(arg.typeSymbol.info.bounds contains _)) } } case _ => false - }) + } } + override def safeToString: String = { def clauses = { val str = quantified map (_.existentialToString) mkString (" forSome { ", "; ", " }") if (settings.explaintypes.value) "(" + str + ")" else str } underlying match { - case TypeRef(pre, sym, args) if isRepresentableWithWildcards => + case TypeRef(pre, sym, args) if !settings.debug.value && isRepresentableWithWildcards(checkBounds = true) => "" + TypeRef(pre, sym, Nil) + wildcardArgsString(quantified.toSet, args).mkString("[", ", ", "]") case MethodType(_, _) | NullaryMethodType(_) | PolyType(_, _) => "(" + underlying + ")" + clauses diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index d6f57801e7..27722a99c9 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -61,6 +61,9 @@ trait CompilationUnits { self: Global => /** things to check at end of compilation unit */ val toCheck = new ListBuffer[() => Unit] + /** The features that were already checked for this unit */ + var checkedFeatures = Set[Symbol]() + def position(pos: Int) = source.position(pos) /** The position of a targeted type check @@ -104,10 +107,14 @@ trait CompilationUnits { self: Global => override def toString() = source.toString() def clear() { - fresh = null - body = null + fresh = new FreshNameCreator.Default + body = EmptyTree depends.clear() defined.clear() + synthetics.clear() + toCheck.clear() + checkedFeatures = Set() + icode.clear() } } } diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 43c231cf2d..de610df93e 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -81,6 +81,8 @@ trait Trees extends reflect.internal.Trees { self: Global => case class InjectDerivedValue(arg: Tree) extends SymTree + class PostfixSelect(qual: Tree, name: Name) extends Select(qual, name) + /** emitted by typer, eliminated by refchecks */ case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree @@ -397,4 +399,4 @@ trait Trees extends reflect.internal.Trees { self: Global => */ - } \ No newline at end of file + } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 45325b4694..eda75ae187 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1456,11 +1456,12 @@ self => return reduceStack(true, base, top, 0, true) top = next } else { + // postfix expression val topinfo = opstack.head opstack = opstack.tail val od = stripParens(reduceStack(true, base, topinfo.operand, 0, true)) return atPos(od.pos.startOrPoint, topinfo.offset) { - Select(od, topinfo.operator.encode) + new PostfixSelect(od, topinfo.operator.encode) } } } diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 166b38f503..4cf31cc576 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -529,6 +529,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") unit.defined.clear() unit.synthetics.clear() unit.toCheck.clear() + unit.checkedFeatures = Set() unit.targetPos = NoPosition unit.contexts.clear() unit.problems.clear() diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 14b3bcc8ce..c0b75fecc4 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -62,6 +62,7 @@ trait ScalaSettings extends AbsScalaSettings val classpath = PathSetting ("-classpath", "Specify where to find user class files.", defaultClasspath) withAbbreviation "-cp" val d = OutputSetting (outputDirs, ".") val nospecialization = BooleanSetting ("-no-specialization", "Ignore @specialize annotations.") + val feature = MultiStringSetting("-language", "feature", "Enable one or more language features.") /** * -X "Advanced" settings diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 36c81b09cd..19d7dde875 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -508,7 +508,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { res } - /** The typer for a label definition. If this is part of a template we * first have to enter the label definition. */ @@ -730,6 +729,38 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } } + def checkFeature(pos: Position, featureTrait: Symbol, construct: => String = "") = + if (!isPastTyper) { + val nestedOwners = + featureTrait.owner.ownerChain.takeWhile(_ != languageFeatureModule.moduleClass).reverse + val featureName = (nestedOwners map (_ + ".")).mkString + featureTrait.name + unit.toCheck += { () => + if (!(unit.checkedFeatures contains featureTrait)) { + def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, true, false, context) != SearchFailure + def hasOption = settings.feature.value contains featureName + if (!hasImport && !hasOption) { + val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) = + featureTrait getAnnotation LanguageFeatureClass + val req = if (required) "needs to" else "should" + val raw = featureDesc + " " + req + " be enabled by making\n" + + "the implicit value language." + featureName + " visible. This can be achieved by adding the import\n" + + "import language." + featureName + " or by setting the compiler option -language:" + featureName + ".\n" + + "See the Scala docs for value scala.language." + featureName + "for a discussion\n" + + "why the feature " + req + " be explicitly enabled." + val msg = raw replace ("#", construct) + if (required) unit.error(pos, msg) else unit.warning(pos, msg) + unit.checkedFeatures += featureTrait + } + } + } + } + + def checkExistentialsFeature(pos: Position, tpe: Type, prefix: String) = tpe match { + case extp: ExistentialType if !extp.isRepresentableWithWildcards(checkBounds = false) => + checkFeature(pos, ExistentialsFeature, prefix+" "+tpe) + case _ => + } + /** Perform the following adaptations of expression, pattern or type `tree` wrt to * given mode `mode` and given prototype `pt`: * (-1) For expressions with annotated types, let AnnotationCheckers decide what to do @@ -1937,6 +1968,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (meth.isStructuralRefinementMember) checkMethodStructuralCompatible(meth) + if (meth.isImplicit) meth.info.paramss match { + case List(param) :: _ if !param.isImplicit => + println("check implicit +"+meth+" "+isPastTyper) + checkFeature(ddef.pos, ImplicitConversionsFeature, meth.toString) + case _ => + } + treeCopy.DefDef(ddef, typedMods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType } @@ -1968,6 +2006,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case TypeBounds(lo1, hi1) if (!(lo1 <:< hi1)) => LowerBoundError(tdef, lo1, hi1) case _ => () } + + if (tdef.symbol.isDeferred && tdef.symbol.info.isHigherKinded) + checkFeature(tdef.pos, HigherKindsFeature) + treeCopy.TypeDef(tdef, typedMods, tdef.name, tparams1, rhs1) setType NoType } @@ -4666,6 +4708,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else typedSelect(qual1, name) + val sym = tree1.symbol + if (sym != null && sym.isTerm && sym.owner.isRefinementClass && !sym.isConstant) + checkFeature(tree1.pos, ReflectiveCallsFeature, sym.toString) + if (qual1.symbol == RootPackage) treeCopy.Ident(tree1, name) else tree1 @@ -4708,9 +4754,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { treeCopy.TypeBoundsTree(tree, lo1, hi1) setType TypeBounds(lo1.tpe, hi1.tpe) case etpt @ ExistentialTypeTree(_, _) => - typerWithLocalContext(context.makeNewScope(tree, context.owner)){ + val tree1 = typerWithLocalContext(context.makeNewScope(tree, context.owner)){ _.typedExistentialTypeTree(etpt, mode) } + checkExistentialsFeature(tree1.pos, tree1.tpe, "the existential type") + tree1 case dc@TypeTreeWithDeferredRefCheck() => dc // TODO: should we re-type the wrapped tree? then we need to change TypeTreeWithDeferredRefCheck's representation to include the wrapped tree explicitly (instead of in its closure) case tpt @ TypeTree() => @@ -4918,7 +4966,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def computeType(tree: Tree, pt: Type): Type = { val tree1 = typed(tree, pt) transformed(tree) = tree1 - packedType(tree1, context.owner) + val tpe = packedType(tree1, context.owner) + checkExistentialsFeature(tree.pos, tpe, "inferred existential type") + tpe } def transformedOrTyped(tree: Tree, mode: Int, pt: Type): Tree = transformed.get(tree) match { -- cgit v1.2.3 From 699bb5886ec9e73d7c90be1a280e7420d30e6e9b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Apr 2012 16:13:09 -0700 Subject: new annotation targets for companion classes/objects/factory methods. --- src/compiler/scala/reflect/internal/Definitions.scala | 4 +++- .../scala/tools/nsc/typechecker/ContextErrors.scala | 8 ++++---- src/library/scala/annotation/meta/companionClass.scala | 17 +++++++++++++++++ src/library/scala/annotation/meta/companionMethod.scala | 17 +++++++++++++++++ src/library/scala/annotation/meta/companionObject.scala | 14 ++++++++++++++ 5 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 src/library/scala/annotation/meta/companionClass.scala create mode 100644 src/library/scala/annotation/meta/companionMethod.scala create mode 100644 src/library/scala/annotation/meta/companionObject.scala diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 6ef6751720..dc8f59b0af 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -905,7 +905,9 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val GetterTargetClass = getMetaAnnotation("getter") lazy val ParamTargetClass = getMetaAnnotation("param") lazy val SetterTargetClass = getMetaAnnotation("setter") - // TODO: module, moduleClass? package, packageObject? + lazy val ClassTargetClass = getMetaAnnotation("companionClass") + lazy val ObjectTargetClass = getMetaAnnotation("companionObject") + lazy val MethodTargetClass = getMetaAnnotation("companionMethod") // TODO: module, moduleClass? package, packageObject? private def getMetaAnnotation(name: String) = getRequiredClass("scala.annotation.meta." + name) def isMetaAnnotation(sym: Symbol): Boolean = metaAnnotations(sym) || ( diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index ff0bdf7580..4a05b28867 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -832,7 +832,7 @@ trait ContextErrors { implicit val context0 = context object SymValidateErrors extends Enumeration { - val ImplicitConstr, ImplicitNotTerm, ImplicitTopObject, + val ImplicitConstr, ImplicitNotTermOrClass, ImplicitAtToplevel, OverrideClass, SealedNonClass, AbstractNonClass, OverrideConstr, AbstractOverride, LazyAndEarlyInit, ByNameParameter, AbstractVar = Value @@ -898,10 +898,10 @@ trait ContextErrors { case ImplicitConstr => "`implicit' modifier not allowed for constructors" - case ImplicitNotTerm => - "`implicit' modifier can be used only for values, variables and methods" + case ImplicitNotTermOrClass => + "`implicit' modifier can be used only for values, variables, methods and classes" - case ImplicitTopObject => + case ImplicitAtToplevel => "`implicit' modifier cannot be used for top-level objects" case OverrideClass => diff --git a/src/library/scala/annotation/meta/companionClass.scala b/src/library/scala/annotation/meta/companionClass.scala new file mode 100644 index 0000000000..8e53f6caf9 --- /dev/null +++ b/src/library/scala/annotation/meta/companionClass.scala @@ -0,0 +1,17 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ +package scala.annotation.meta + +/** + * When defining an implicit class, the Scala compiler creates an implicit + * conversion method for it. Annotations `@companionClass` and `@companionMethod` + * control where an annotation on the implicit class will go. By default, annotations + * on an implicit class end up only on the class. + * + */ +final class companionClass extends annotation.StaticAnnotation diff --git a/src/library/scala/annotation/meta/companionMethod.scala b/src/library/scala/annotation/meta/companionMethod.scala new file mode 100644 index 0000000000..379c4f3385 --- /dev/null +++ b/src/library/scala/annotation/meta/companionMethod.scala @@ -0,0 +1,17 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ +package scala.annotation.meta + +/** + * When defining an implicit class, the Scala compiler creates an implicit + * conversion method for it. Annotations `@companionClass` and `@companionMethod` + * control where an annotation on the implicit class will go. By default, annotations + * on an implicit class end up only on the class. + * + */ +final class companionMethod extends annotation.StaticAnnotation diff --git a/src/library/scala/annotation/meta/companionObject.scala b/src/library/scala/annotation/meta/companionObject.scala new file mode 100644 index 0000000000..d329df5c42 --- /dev/null +++ b/src/library/scala/annotation/meta/companionObject.scala @@ -0,0 +1,14 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ +package scala.annotation.meta + +/** + * Currently unused; intended as an annotation target for classes such as case classes + * that automatically generate a companion object + */ +final class companionObject extends annotation.StaticAnnotation -- cgit v1.2.3 From 814cf34fb00f9ccb001249f4b3445ebc4f9942c9 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 12 Apr 2012 01:59:46 +0200 Subject: Next generation of macros Implements SIP 16: Self-cleaning macros: http://bit.ly/wjjXTZ Features: * Macro defs * Reification * Type tags * Manifests aliased to type tags * Extended reflection API * Several hundred tests * 1111 changed files Not yet implemented: * Reification of refined types * Expr.value splicing * Named and default macro expansions * Intricacies of interaction between macros and implicits * Emission of debug information for macros (compliant with JSR-45) Dedicated to Yuri Alekseyevich Gagarin --- build.xml | 2 +- lib/scala-compiler.jar.desired.sha1 | 2 +- lib/scala-library.jar.desired.sha1 | 2 +- .../scala/reflect/internal/AnnotationInfos.scala | 17 +- .../scala/reflect/internal/CapturedVariables.scala | 36 + .../scala/reflect/internal/Constants.scala | 10 +- .../scala/reflect/internal/Definitions.scala | 96 +- src/compiler/scala/reflect/internal/FreeVars.scala | 60 + .../scala/reflect/internal/Importers.scala | 39 +- .../scala/reflect/internal/NameManglers.scala | 7 +- .../scala/reflect/internal/Positions.scala | 38 +- .../scala/reflect/internal/Reporters.scala | 74 ++ src/compiler/scala/reflect/internal/Required.scala | 2 - src/compiler/scala/reflect/internal/StdNames.scala | 126 +- .../scala/reflect/internal/SymbolTable.scala | 6 +- src/compiler/scala/reflect/internal/Symbols.scala | 89 +- .../scala/reflect/internal/TreeBuildUtil.scala | 62 + src/compiler/scala/reflect/internal/TreeGen.scala | 2 +- src/compiler/scala/reflect/internal/TreeInfo.scala | 194 +++ .../scala/reflect/internal/TreePrinters.scala | 5 +- src/compiler/scala/reflect/internal/Trees.scala | 77 +- src/compiler/scala/reflect/internal/Types.scala | 53 +- .../scala/reflect/makro/runtime/Aliases.scala | 21 + .../reflect/makro/runtime/CapturedVariables.scala | 14 + .../scala/reflect/makro/runtime/Context.scala | 26 + .../scala/reflect/makro/runtime/Enclosures.scala | 36 + .../scala/reflect/makro/runtime/Errors.scala | 6 + .../reflect/makro/runtime/Infrastructure.scala | 34 + .../scala/reflect/makro/runtime/Names.scala | 20 + .../scala/reflect/makro/runtime/Reifiers.scala | 69 + .../scala/reflect/makro/runtime/Reporters.scala | 44 + .../scala/reflect/makro/runtime/Settings.scala | 36 + .../scala/reflect/makro/runtime/Symbols.scala | 8 + .../scala/reflect/makro/runtime/Typers.scala | 78 ++ .../scala/reflect/makro/runtime/Util.scala | 34 + src/compiler/scala/reflect/reify/Errors.scala | 63 + .../scala/reflect/reify/NodePrinters.scala | 111 ++ src/compiler/scala/reflect/reify/Phases.scala | 42 + src/compiler/scala/reflect/reify/Reifiers.scala | 154 +++ .../scala/reflect/reify/codegen/Names.scala | 15 + .../scala/reflect/reify/codegen/Positions.scala | 18 + .../scala/reflect/reify/codegen/Symbols.scala | 111 ++ .../scala/reflect/reify/codegen/Trees.scala | 220 ++++ .../scala/reflect/reify/codegen/Types.scala | 226 ++++ .../scala/reflect/reify/codegen/Util.scala | 112 ++ src/compiler/scala/reflect/reify/package.scala | 22 + .../scala/reflect/reify/phases/Calculate.scala | 61 + .../scala/reflect/reify/phases/Metalevels.scala | 148 +++ .../scala/reflect/reify/phases/Reify.scala | 42 + .../scala/reflect/reify/phases/Reshape.scala | 296 +++++ .../scala/reflect/runtime/ClassLoaders.scala | 25 + .../scala/reflect/runtime/ConversionUtil.scala | 1 + .../scala/reflect/runtime/JavaToScala.scala | 209 ++- src/compiler/scala/reflect/runtime/Loaders.scala | 130 -- src/compiler/scala/reflect/runtime/Memoizer.scala | 15 - src/compiler/scala/reflect/runtime/Mirror.scala | 36 +- .../scala/reflect/runtime/RuntimeTypes.scala | 27 - .../scala/reflect/runtime/SymbolLoaders.scala | 135 ++ .../scala/reflect/runtime/SymbolTable.scala | 23 +- .../reflect/runtime/SynchronizedSymbols.scala | 7 +- src/compiler/scala/reflect/runtime/ToolBoxes.scala | 363 ++++-- .../scala/reflect/runtime/TreeBuildUtil.scala | 49 - src/compiler/scala/reflect/runtime/Universe.scala | 20 +- src/compiler/scala/reflect/runtime/package.scala | 5 + src/compiler/scala/tools/cmd/FromString.scala | 4 +- src/compiler/scala/tools/nsc/ClassLoaders.scala | 64 + src/compiler/scala/tools/nsc/Global.scala | 46 +- src/compiler/scala/tools/nsc/MacroContext.scala | 10 - src/compiler/scala/tools/nsc/ReflectGlobal.scala | 7 +- src/compiler/scala/tools/nsc/ReflectMain.scala | 11 +- src/compiler/scala/tools/nsc/ToolBoxes.scala | 85 ++ src/compiler/scala/tools/nsc/ast/DocComments.scala | 4 +- src/compiler/scala/tools/nsc/ast/FreeVars.scala | 26 + .../scala/tools/nsc/ast/NodePrinters.scala | 32 +- src/compiler/scala/tools/nsc/ast/Positions.scala | 44 + src/compiler/scala/tools/nsc/ast/Reifiers.scala | 761 ----------- .../scala/tools/nsc/ast/ReifyPrinters.scala | 75 -- src/compiler/scala/tools/nsc/ast/TreeGen.scala | 16 - src/compiler/scala/tools/nsc/ast/Trees.scala | 124 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 129 +- .../scala/tools/nsc/ast/parser/Scanners.scala | 3 +- .../scala/tools/nsc/ast/parser/Tokens.scala | 1 + .../scala/tools/nsc/backend/jvm/GenJVM.scala | 2 +- .../scala/tools/nsc/backend/jvm/GenJVMUtil.scala | 2 +- .../scala/tools/nsc/backend/msil/GenMSIL.scala | 6 +- .../scala/tools/nsc/interactive/Global.scala | 2 +- .../tools/nsc/interactive/RangePositions.scala | 2 +- .../scala/tools/nsc/interpreter/IMain.scala | 12 +- .../scala/tools/nsc/interpreter/Power.scala | 1 - .../scala/tools/nsc/interpreter/ReplVals.scala | 2 +- .../scala/tools/nsc/interpreter/RichClass.scala | 2 +- .../scala/tools/nsc/interpreter/TypeStrings.scala | 9 +- .../tools/nsc/reporters/AbstractReporter.scala | 11 +- .../tools/nsc/reporters/ConsoleReporter.scala | 1 - .../scala/tools/nsc/scratchpad/Executor.scala | 2 +- .../scala/tools/nsc/settings/MutableSettings.scala | 2 +- .../scala/tools/nsc/settings/ScalaSettings.scala | 149 ++- .../scala/tools/nsc/symtab/Positions.scala | 30 - .../scala/tools/nsc/symtab/classfile/Pickler.scala | 6 +- .../scala/tools/nsc/transform/AddInterfaces.scala | 2 +- .../scala/tools/nsc/transform/CleanUp.scala | 2 +- .../scala/tools/nsc/transform/Erasure.scala | 4 +- .../scala/tools/nsc/transform/LambdaLift.scala | 18 +- src/compiler/scala/tools/nsc/transform/Mixin.scala | 2 +- .../scala/tools/nsc/transform/UnCurry.scala | 14 +- .../tools/nsc/typechecker/ContextErrors.scala | 33 +- .../scala/tools/nsc/typechecker/Contexts.scala | 31 +- .../scala/tools/nsc/typechecker/Implicits.scala | 190 ++- .../scala/tools/nsc/typechecker/Infer.scala | 24 +- .../scala/tools/nsc/typechecker/Macros.scala | 1361 +++++++++++++++++--- .../tools/nsc/typechecker/MethodSynthesis.scala | 14 +- .../scala/tools/nsc/typechecker/Namers.scala | 31 +- .../scala/tools/nsc/typechecker/RefChecks.scala | 6 + .../tools/nsc/typechecker/TypeDiagnostics.scala | 20 +- .../scala/tools/nsc/typechecker/Typers.scala | 180 ++- src/compiler/scala/tools/nsc/util/ClassPath.scala | 2 +- src/compiler/scala/tools/nsc/util/Position.scala | 126 +- src/compiler/scala/tools/reflect/package.scala | 2 +- src/library/scala/Predef.scala | 29 +- .../scala/collection/mutable/ArrayBuilder.scala | 18 +- .../scala/collection/mutable/ArrayOps.scala | 10 +- .../scala/collection/mutable/WrappedArray.scala | 2 +- .../collection/mutable/WrappedArrayBuilder.scala | 14 +- src/library/scala/reflect/ArrayTags.scala | 19 + src/library/scala/reflect/ClassManifest.scala | 263 ---- src/library/scala/reflect/ClassTags.scala | 158 +++ src/library/scala/reflect/Manifest.scala | 302 ----- src/library/scala/reflect/NoManifest.scala | 15 - src/library/scala/reflect/OptManifest.scala | 17 - src/library/scala/reflect/ReflectionUtils.scala | 26 +- src/library/scala/reflect/TagMaterialization.scala | 154 +++ src/library/scala/reflect/api/Attachments.scala | 16 + src/library/scala/reflect/api/ClassLoaders.scala | 16 + src/library/scala/reflect/api/Exprs.scala | 48 + src/library/scala/reflect/api/FreeVars.scala | 42 + src/library/scala/reflect/api/Importers.scala | 19 + src/library/scala/reflect/api/Mirror.scala | 17 +- src/library/scala/reflect/api/Positions.scala | 215 +++- src/library/scala/reflect/api/Reporters.scala | 65 + src/library/scala/reflect/api/RuntimeTypes.scala | 20 - src/library/scala/reflect/api/Scopes.scala | 9 +- .../scala/reflect/api/StandardDefinitions.scala | 68 +- src/library/scala/reflect/api/StandardNames.scala | 156 ++- src/library/scala/reflect/api/Symbols.scala | 61 +- src/library/scala/reflect/api/ToolBoxes.scala | 90 ++ src/library/scala/reflect/api/TreeBuildUtil.scala | 111 +- src/library/scala/reflect/api/TreePrinters.scala | 6 +- src/library/scala/reflect/api/Trees.scala | 178 ++- src/library/scala/reflect/api/TypeTags.scala | 193 +++ src/library/scala/reflect/api/Types.scala | 91 +- src/library/scala/reflect/api/Universe.scala | 79 +- src/library/scala/reflect/macro/Context.scala | 36 - src/library/scala/reflect/makro/Aliases.scala | 26 + .../scala/reflect/makro/CapturedVariables.scala | 20 + src/library/scala/reflect/makro/Context.scala | 59 + src/library/scala/reflect/makro/Enclosures.scala | 53 + .../scala/reflect/makro/Infrastructure.scala | 73 ++ src/library/scala/reflect/makro/Names.scala | 14 + src/library/scala/reflect/makro/Reifiers.scala | 82 ++ src/library/scala/reflect/makro/Reporters.scala | 39 + src/library/scala/reflect/makro/Settings.scala | 38 + src/library/scala/reflect/makro/Symbols.scala | 17 + src/library/scala/reflect/makro/Typers.scala | 85 ++ src/library/scala/reflect/makro/Util.scala | 31 + .../scala/reflect/makro/internal/macroImpl.scala | 5 + .../scala/reflect/makro/internal/typeTagImpl.scala | 133 ++ src/library/scala/reflect/package.scala | 43 +- src/library/scala/runtime/ScalaRunTime.scala | 2 +- src/library/scala/util/Marshal.scala | 3 +- .../tools/partest/nest/ConsoleFileManager.scala | 1 + .../scala/tools/partest/nest/TestFile.scala | 4 +- src/partest/scala/tools/partest/nest/Worker.scala | 16 +- test/files/codelib/code.jar.desired.sha1 | 2 +- test/files/jvm/interpreter.check | 738 +++++------ test/files/jvm/interpreter.scala | 9 +- test/files/jvm/manifests.check | 55 - .../files/jvm/manifests.check.temporarily.disabled | 55 + test/files/jvm/manifests.scala | 119 -- .../files/jvm/manifests.scala.temporarily.disabled | 109 ++ test/files/macros/Printf.scala | 39 - test/files/macros/Test.scala | 8 - test/files/macros/macros_v0001.bat | 40 - test/files/macros/macros_v0001.sh | 30 - test/files/neg/checksensible.check | 200 +-- test/files/neg/classtags_contextbound_a.check | 4 + test/files/neg/classtags_contextbound_a.scala | 4 + test/files/neg/classtags_contextbound_b.check | 4 + test/files/neg/classtags_contextbound_b.scala | 5 + test/files/neg/classtags_contextbound_c.check | 4 + test/files/neg/classtags_contextbound_c.scala | 5 + .../neg/macro-argtype-mismatch/Macros_1.scala | 3 - test/files/neg/macro-argtype-mismatch/Test_2.scala | 4 - test/files/neg/macro-basic-mamdmi.check | 5 + test/files/neg/macro-basic-mamdmi.flags | 1 + .../macro-basic-mamdmi/Impls_Macros_Test_1.scala | 37 + test/files/neg/macro-cyclic.check | 4 + test/files/neg/macro-cyclic.flags | 1 + test/files/neg/macro-cyclic/Impls_Macros_1.scala | 25 + ...cro-deprecate-dont-touch-backquotedidents.check | 14 + .../Macros_Bind_12.scala | 6 + .../Macros_Class_4.scala | 3 + .../Macros_Class_5.scala | 3 + .../Macros_Def_13.scala | 3 + .../Macros_Object_6.scala | 3 + .../Macros_Object_7.scala | 3 + .../Macros_Package_10.scala | 3 + .../Macros_Package_11.scala | 3 + .../Macros_Trait_8.scala | 3 + .../Macros_Trait_9.scala | 3 + .../Macros_Type_3.scala | 3 + .../Macros_Val_1.scala | 3 + .../Macros_Var_2.scala | 3 + .../Main.scala | 2 + test/files/neg/macro-deprecate-idents.check | 50 + .../macro-deprecate-idents/Macros_Bind_12.scala | 6 + .../macro-deprecate-idents/Macros_Class_4.scala | 3 + .../macro-deprecate-idents/Macros_Class_5.scala | 3 + .../neg/macro-deprecate-idents/Macros_Def_13.scala | 3 + .../macro-deprecate-idents/Macros_Object_6.scala | 3 + .../macro-deprecate-idents/Macros_Object_7.scala | 3 + .../macro-deprecate-idents/Macros_Package_10.scala | 3 + .../macro-deprecate-idents/Macros_Package_11.scala | 3 + .../macro-deprecate-idents/Macros_Trait_8.scala | 3 + .../macro-deprecate-idents/Macros_Trait_9.scala | 3 + .../neg/macro-deprecate-idents/Macros_Type_3.scala | 3 + .../neg/macro-deprecate-idents/Macros_Val_1.scala | 3 + .../neg/macro-deprecate-idents/Macros_Var_2.scala | 3 + test/files/neg/macro-deprecate-idents/Main.scala | 2 + test/files/neg/macro-invalidimpl-a.check | 4 + test/files/neg/macro-invalidimpl-a.flags | 1 + test/files/neg/macro-invalidimpl-a/Impls_1.scala | 5 + .../neg/macro-invalidimpl-a/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-b.check | 4 + test/files/neg/macro-invalidimpl-b.flags | 1 + test/files/neg/macro-invalidimpl-b/Impls_1.scala | 5 + .../neg/macro-invalidimpl-b/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-c.check | 4 + test/files/neg/macro-invalidimpl-c.flags | 1 + .../neg/macro-invalidimpl-c/Impls_Macros_1.scala | 9 + test/files/neg/macro-invalidimpl-c/Test_2.scala | 3 + test/files/neg/macro-invalidimpl-d.check | 4 + test/files/neg/macro-invalidimpl-d.flags | 1 + test/files/neg/macro-invalidimpl-d/Impls_1.scala | 7 + .../neg/macro-invalidimpl-d/Macros_Test_2.scala | 7 + test/files/neg/macro-invalidimpl-e.check | 13 + test/files/neg/macro-invalidimpl-e.flags | 1 + test/files/neg/macro-invalidimpl-e/Impls_1.scala | 6 + .../neg/macro-invalidimpl-e/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-f.check | 7 + test/files/neg/macro-invalidimpl-f.flags | 1 + test/files/neg/macro-invalidimpl-f/Impls_1.scala | 11 + .../neg/macro-invalidimpl-f/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-g.check | 7 + test/files/neg/macro-invalidimpl-g.flags | 1 + test/files/neg/macro-invalidimpl-g/Impls_1.scala | 11 + .../neg/macro-invalidimpl-g/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidimpl-h.check | 4 + test/files/neg/macro-invalidimpl-h.flags | 1 + test/files/neg/macro-invalidimpl-h/Impls_1.scala | 5 + .../neg/macro-invalidimpl-h/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidret-nontree.check | 7 + test/files/neg/macro-invalidret-nontree.flags | 1 + .../neg/macro-invalidret-nontree/Impls_1.scala | 5 + .../macro-invalidret-nontree/Macros_Test_2.scala | 8 + .../neg/macro-invalidret-nonuniversetree.check | 7 + .../neg/macro-invalidret-nonuniversetree.flags | 1 + .../macro-invalidret-nonuniversetree/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-a.check | 6 + test/files/neg/macro-invalidshape-a.flags | 1 + test/files/neg/macro-invalidshape-a/Impls_1.scala | 5 + .../neg/macro-invalidshape-a/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-b.check | 6 + test/files/neg/macro-invalidshape-b.flags | 1 + test/files/neg/macro-invalidshape-b/Impls_1.scala | 5 + .../neg/macro-invalidshape-b/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-c.check | 6 + test/files/neg/macro-invalidshape-c.flags | 1 + test/files/neg/macro-invalidshape-c/Impls_1.scala | 5 + .../neg/macro-invalidshape-c/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-d.check | 4 + test/files/neg/macro-invalidshape-d.flags | 1 + test/files/neg/macro-invalidshape-d/Impls_1.scala | 5 + .../neg/macro-invalidshape-d/Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-context-bounds.check | 4 + .../neg/macro-invalidsig-context-bounds.flags | 1 + .../macro-invalidsig-context-bounds/Impls_1.scala | 8 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidsig-ctx-badargc.check | 7 + test/files/neg/macro-invalidsig-ctx-badargc.flags | 1 + .../neg/macro-invalidsig-ctx-badargc/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidsig-ctx-badtype.check | 7 + test/files/neg/macro-invalidsig-ctx-badtype.flags | 1 + .../neg/macro-invalidsig-ctx-badtype/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-ctx-badvarargs.check | 7 + .../neg/macro-invalidsig-ctx-badvarargs.flags | 1 + .../macro-invalidsig-ctx-badvarargs/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidsig-ctx-noctx.check | 7 + test/files/neg/macro-invalidsig-ctx-noctx.flags | 1 + .../neg/macro-invalidsig-ctx-noctx/Impls_1.scala | 5 + .../macro-invalidsig-ctx-noctx/Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-implicit-params.check | 4 + .../neg/macro-invalidsig-implicit-params.flags | 1 + .../Impls_Macros_1.scala | 18 + .../macro-invalidsig-implicit-params/Test_2.scala | 4 + .../neg/macro-invalidsig-params-badargc.check | 7 + .../neg/macro-invalidsig-params-badargc.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-invalidsig-params-badargc/Test_2.scala | 4 + .../neg/macro-invalidsig-params-badtype.check | 7 + .../neg/macro-invalidsig-params-badtype.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-invalidsig-params-badtype/Test_2.scala | 4 + .../neg/macro-invalidsig-params-badvarargs.check | 7 + .../neg/macro-invalidsig-params-badvarargs.flags | 1 + .../Impls_Macros_1.scala | 9 + .../Test_2.scala | 4 + .../neg/macro-invalidsig-params-namemismatch.check | 7 + .../neg/macro-invalidsig-params-namemismatch.flags | 1 + .../Impls_Macros_1.scala | 9 + .../Test_2.scala | 4 + .../neg/macro-invalidsig-tparams-badtype.check | 7 + .../neg/macro-invalidsig-tparams-badtype.flags | 1 + .../macro-invalidsig-tparams-badtype/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-bounds-a.check | 4 + .../neg/macro-invalidsig-tparams-bounds-a.flags | 1 + .../Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-bounds-b.check | 4 + .../neg/macro-invalidsig-tparams-bounds-b.flags | 1 + .../Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-notparams-a.check | 4 + .../neg/macro-invalidsig-tparams-notparams-a.flags | 1 + .../Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-notparams-b.check | 4 + .../neg/macro-invalidsig-tparams-notparams-b.flags | 1 + .../Impls_1.scala | 11 + .../Macros_Test_2.scala | 11 + .../neg/macro-invalidsig-tparams-notparams-c.check | 4 + .../neg/macro-invalidsig-tparams-notparams-c.flags | 1 + .../Impls_1.scala | 11 + .../Macros_Test_2.scala | 11 + test/files/neg/macro-invalidusage-badargs.check | 6 + test/files/neg/macro-invalidusage-badargs.flags | 1 + .../neg/macro-invalidusage-badargs/Impls_1.scala | 5 + .../macro-invalidusage-badargs/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidusage-badbounds.check | 4 + test/files/neg/macro-invalidusage-badbounds.flags | 1 + .../neg/macro-invalidusage-badbounds/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidusage-badtargs.check | 4 + test/files/neg/macro-invalidusage-badtargs.flags | 1 + .../neg/macro-invalidusage-badtargs/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidusage-methodvaluesyntax.check | 4 + .../neg/macro-invalidusage-methodvaluesyntax.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-keyword.check | 49 + test/files/neg/macro-keyword.flags | 1 + test/files/neg/macro-keyword/Macros_Bind_12.scala | 6 + test/files/neg/macro-keyword/Macros_Class_4.scala | 3 + test/files/neg/macro-keyword/Macros_Class_5.scala | 3 + test/files/neg/macro-keyword/Macros_Def_13.scala | 3 + test/files/neg/macro-keyword/Macros_Object_6.scala | 3 + test/files/neg/macro-keyword/Macros_Object_7.scala | 3 + .../neg/macro-keyword/Macros_Package_10.scala | 3 + .../neg/macro-keyword/Macros_Package_11.scala | 3 + test/files/neg/macro-keyword/Macros_Trait_8.scala | 3 + test/files/neg/macro-keyword/Macros_Trait_9.scala | 3 + test/files/neg/macro-keyword/Macros_Type_3.scala | 3 + test/files/neg/macro-keyword/Macros_Val_1.scala | 3 + test/files/neg/macro-keyword/Macros_Var_2.scala | 3 + test/files/neg/macro-noexpand.check | 2 +- test/files/neg/macro-noexpand/Impls_1.scala | 5 + test/files/neg/macro-noexpand/Macros_1.scala | 3 - test/files/neg/macro-noexpand/Macros_Test_2.scala | 8 + test/files/neg/macro-noexpand/Test_2.scala | 4 - .../files/neg/macro-noncompilertree/Macros_1.scala | 3 - test/files/neg/macro-nontree/Macros_1.scala | 3 - test/files/neg/macro-nontypeablebody.check | 4 + test/files/neg/macro-nontypeablebody.flags | 1 + test/files/neg/macro-nontypeablebody/Impls_1.scala | 5 + .../neg/macro-nontypeablebody/Macros_Test_2.scala | 8 + ...verride-macro-overrides-abstract-method-a.check | 5 + ...verride-macro-overrides-abstract-method-a.flags | 1 + .../Impls_Macros_1.scala | 13 + .../Test_2.scala | 4 + ...verride-macro-overrides-abstract-method-b.check | 5 + ...verride-macro-overrides-abstract-method-b.flags | 1 + .../Impls_Macros_1.scala | 13 + .../Test_2.scala | 4 + .../macro-override-method-overrides-macro.check | 5 + .../macro-override-method-overrides-macro.flags | 1 + .../Impls_1.scala | 15 + .../Macros_Test_2.scala | 15 + ...o-reify-groundtypetag-hktypeparams-notags.check | 7 + .../Test.scala | 9 + ...cro-reify-groundtypetag-typeparams-notags.check | 7 + .../Test.scala | 9 + .../neg/macro-reify-groundtypetag-usetypetag.check | 7 + .../Test.scala | 9 + test/files/neg/macro-without-xmacros-a.check | 10 + .../neg/macro-without-xmacros-a/Impls_1.scala | 18 + .../neg/macro-without-xmacros-a/Macros_2.scala | 12 + .../files/neg/macro-without-xmacros-a/Test_3.scala | 4 + test/files/neg/macro-without-xmacros-b.check | 10 + .../neg/macro-without-xmacros-b/Impls_1.scala | 18 + .../neg/macro-without-xmacros-b/Macros_2.scala | 10 + .../files/neg/macro-without-xmacros-b/Test_3.scala | 4 + test/files/neg/reify_ann2a.check | 4 - test/files/neg/reify_ann2a.scala | 30 - test/files/neg/reify_ann2b.check | 11 +- test/files/neg/reify_ann2b.scala | 11 +- test/files/neg/t2386.check | 8 +- test/files/neg/t2775.check | 8 +- test/files/neg/t3507.check | 8 +- test/files/neg/t3692.check | 15 +- test/files/neg/t5334_1.check | 4 + test/files/neg/t5334_1.scala | 8 + test/files/neg/t5334_2.check | 4 + test/files/neg/t5334_2.scala | 8 + test/files/pos/implicits.scala | 89 -- .../files/pos/implicits.scala.temporarily.disabled | 89 ++ test/files/pos/liftcode_polymorphic.scala | 4 +- test/files/pos/macros.flags | 1 - test/files/pos/macros.scala | 8 - test/files/pos/manifest1.scala | 21 - .../files/pos/manifest1.scala.temporarily.disabled | 21 + test/files/pos/t5223.scala | 6 +- test/files/pos/t531.scala | 5 +- test/files/pos/t532.scala | 5 +- test/files/run/classtags_contextbound.check | 1 + test/files/run/classtags_contextbound.scala | 5 + test/files/run/classtags_core.check | 30 + test/files/run/classtags_core.scala | 32 + test/files/run/existentials3.check | 22 - .../run/existentials3.check.temporarily.disabled | 22 + test/files/run/existentials3.scala | 73 -- .../run/existentials3.scala.temporarily.disabled | 73 ++ test/files/run/groundtypetags_core.check | 30 + test/files/run/groundtypetags_core.scala | 32 + test/files/run/macro-abort-fresh.check | 6 + test/files/run/macro-abort-fresh.flags | 1 + test/files/run/macro-abort-fresh/Macros_1.scala | 15 + test/files/run/macro-abort-fresh/Test_2.scala | 6 + test/files/run/macro-basic-ma-md-mi.check | 1 + test/files/run/macro-basic-ma-md-mi.flags | 1 + test/files/run/macro-basic-ma-md-mi/Impls_1.scala | 21 + test/files/run/macro-basic-ma-md-mi/Macros_2.scala | 10 + test/files/run/macro-basic-ma-md-mi/Test_3.scala | 4 + test/files/run/macro-basic-ma-mdmi.check | 1 + test/files/run/macro-basic-ma-mdmi.flags | 1 + .../run/macro-basic-ma-mdmi/Impls_Macros_1.scala | 32 + test/files/run/macro-basic-ma-mdmi/Test_2.scala | 4 + test/files/run/macro-basic-mamd-mi.check | 1 + test/files/run/macro-basic-mamd-mi.flags | 1 + test/files/run/macro-basic-mamd-mi/Impls_1.scala | 19 + .../run/macro-basic-mamd-mi/Macros_Test_2.scala | 15 + test/files/run/macro-basic.check | 1 - test/files/run/macro-basic.flags | 1 - test/files/run/macro-basic/Macros_1.scala | 10 - test/files/run/macro-basic/Test_2.scala | 4 - test/files/run/macro-bodyexpandstoimpl.check | 1 + test/files/run/macro-bodyexpandstoimpl.flags | 1 + .../run/macro-bodyexpandstoimpl/Impls_1.scala | 12 + .../macro-bodyexpandstoimpl/Macros_Test_2.scala | 10 + test/files/run/macro-declared-in-annotation.check | 1 + test/files/run/macro-declared-in-annotation.flags | 1 + .../run/macro-declared-in-annotation/Impls_1.scala | 11 + .../macro-declared-in-annotation/Macros_2.scala | 8 + .../run/macro-declared-in-annotation/Test_3.scala | 3 + test/files/run/macro-declared-in-anonymous.check | 2 + test/files/run/macro-declared-in-anonymous.flags | 1 + .../run/macro-declared-in-anonymous/Impls_1.scala | 11 + .../Macros_Test_2.scala | 4 + test/files/run/macro-declared-in-block.check | 2 + test/files/run/macro-declared-in-block.flags | 1 + .../run/macro-declared-in-block/Impls_1.scala | 11 + .../macro-declared-in-block/Macros_Test_2.scala | 6 + test/files/run/macro-declared-in-class-class.check | 2 + test/files/run/macro-declared-in-class-class.flags | 1 + .../macro-declared-in-class-class/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + .../files/run/macro-declared-in-class-object.check | 2 + .../files/run/macro-declared-in-class-object.flags | 1 + .../macro-declared-in-class-object/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + test/files/run/macro-declared-in-class.check | 2 + test/files/run/macro-declared-in-class.flags | 1 + .../run/macro-declared-in-class/Impls_1.scala | 11 + .../macro-declared-in-class/Macros_Test_2.scala | 7 + .../run/macro-declared-in-default-param.check | 5 + .../run/macro-declared-in-default-param.flags | 1 + .../macro-declared-in-default-param/Impls_1.scala | 11 + .../Macros_Test_2.scala | 7 + .../run/macro-declared-in-implicit-class.check | 2 + .../run/macro-declared-in-implicit-class.flags | 1 + .../Impls_Macros_1.scala | 19 + .../macro-declared-in-implicit-class/Test_2.scala | 4 + test/files/run/macro-declared-in-method.check | 2 + test/files/run/macro-declared-in-method.flags | 1 + .../run/macro-declared-in-method/Impls_1.scala | 11 + .../macro-declared-in-method/Macros_Test_2.scala | 8 + .../files/run/macro-declared-in-object-class.check | 2 + .../files/run/macro-declared-in-object-class.flags | 1 + .../macro-declared-in-object-class/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + .../run/macro-declared-in-object-object.check | 2 + .../run/macro-declared-in-object-object.flags | 1 + .../macro-declared-in-object-object/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + test/files/run/macro-declared-in-object.check | 2 + test/files/run/macro-declared-in-object.flags | 1 + .../run/macro-declared-in-object/Impls_1.scala | 11 + .../macro-declared-in-object/Macros_Test_2.scala | 7 + .../run/macro-declared-in-package-object.check | 2 + .../run/macro-declared-in-package-object.flags | 1 + .../macro-declared-in-package-object/Impls_1.scala | 11 + .../Macros_Test_2.scala | 8 + test/files/run/macro-declared-in-refinement.check | 2 + test/files/run/macro-declared-in-refinement.flags | 1 + .../run/macro-declared-in-refinement/Impls_1.scala | 11 + .../Macros_Test_2.scala | 6 + test/files/run/macro-declared-in-trait.check | 15 + test/files/run/macro-declared-in-trait.flags | 1 + .../run/macro-declared-in-trait/Impls_1.scala | 11 + .../macro-declared-in-trait/Macros_Test_2.scala | 13 + test/files/run/macro-def-infer-return-type-a.check | 1 + test/files/run/macro-def-infer-return-type-a.flags | 1 + .../macro-def-infer-return-type-a/Impls_1.scala | 5 + .../Macros_Test_2.scala | 4 + test/files/run/macro-def-infer-return-type-b.check | 6 + test/files/run/macro-def-infer-return-type-b.flags | 1 + .../Impls_Macros_1.scala | 10 + .../run/macro-def-infer-return-type-b/Test_2.scala | 6 + test/files/run/macro-def-infer-return-type-c.check | 1 + test/files/run/macro-def-infer-return-type-c.flags | 1 + .../macro-def-infer-return-type-c/Impls_1.scala | 5 + .../Macros_Test_2.scala | 4 + test/files/run/macro-def-path-dependent-a.check | 1 + test/files/run/macro-def-path-dependent-a.flags | 1 + .../Impls_Macros_1.scala | 21 + .../run/macro-def-path-dependent-a/Test_2.scala | 3 + test/files/run/macro-def-path-dependent-b.check | 1 + test/files/run/macro-def-path-dependent-b.flags | 1 + .../Impls_Macros_1.scala | 20 + .../run/macro-def-path-dependent-b/Test_2.scala | 3 + test/files/run/macro-def-path-dependent-c.check | 1 + test/files/run/macro-def-path-dependent-c.flags | 1 + .../Impls_Macros_1.scala | 20 + .../run/macro-def-path-dependent-c/Test_2.scala | 3 + test/files/run/macro-def-path-dependent-d.check | 1 + test/files/run/macro-def-path-dependent-d.flags | 1 + .../Impls_Macros_1.scala | 8 + .../run/macro-def-path-dependent-d/Test_2.scala | 3 + .../macro-expand-implicit-macro-has-implicit.check | 1 + .../macro-expand-implicit-macro-has-implicit.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 5 + .../macro-expand-implicit-macro-is-implicit.check | 2 + .../macro-expand-implicit-macro-is-implicit.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 10 + .../run/macro-expand-implicit-macro-is-val.check | 1 + .../run/macro-expand-implicit-macro-is-val.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 5 + .../run/macro-expand-implicit-macro-is-view.check | 1 + .../run/macro-expand-implicit-macro-is-view.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 9 + .../files/run/macro-expand-multiple-arglists.check | 1 + .../files/run/macro-expand-multiple-arglists.flags | 1 + .../macro-expand-multiple-arglists/Impls_1.scala | 10 + .../Macros_Test_2.scala | 4 + test/files/run/macro-expand-nullary-generic.check | 6 + test/files/run/macro-expand-nullary-generic.flags | 1 + .../run/macro-expand-nullary-generic/Impls_1.scala | 14 + .../Macros_Test_2.scala | 15 + .../run/macro-expand-nullary-nongeneric.check | 6 + .../run/macro-expand-nullary-nongeneric.flags | 1 + .../macro-expand-nullary-nongeneric/Impls_1.scala | 14 + .../Macros_Test_2.scala | 15 + test/files/run/macro-expand-overload.check | 6 + test/files/run/macro-expand-overload.flags | 1 + test/files/run/macro-expand-overload/Impls_1.scala | 15 + .../run/macro-expand-overload/Macros_Test_2.scala | 20 + test/files/run/macro-expand-override.check | 15 + test/files/run/macro-expand-override.flags | 1 + test/files/run/macro-expand-override/Impls_1.scala | 15 + .../run/macro-expand-override/Macros_Test_2.scala | 43 + test/files/run/macro-expand-recursive.check | 1 + test/files/run/macro-expand-recursive.flags | 1 + .../files/run/macro-expand-recursive/Impls_1.scala | 15 + .../run/macro-expand-recursive/Macros_Test_2.scala | 8 + test/files/run/macro-expand-tparams-bounds-a.check | 0 test/files/run/macro-expand-tparams-bounds-a.flags | 1 + .../macro-expand-tparams-bounds-a/Impls_1.scala | 8 + .../Macros_Test_2.scala | 8 + test/files/run/macro-expand-tparams-bounds-b.check | 0 test/files/run/macro-expand-tparams-bounds-b.flags | 1 + .../macro-expand-tparams-bounds-b/Impls_1.scala | 10 + .../Macros_Test_2.scala | 10 + test/files/run/macro-expand-tparams-explicit.check | 1 + test/files/run/macro-expand-tparams-explicit.flags | 1 + .../macro-expand-tparams-explicit/Impls_1.scala | 10 + .../Macros_Test_2.scala | 4 + test/files/run/macro-expand-tparams-implicit.check | 2 + test/files/run/macro-expand-tparams-implicit.flags | 1 + .../macro-expand-tparams-implicit/Impls_1.scala | 10 + .../Macros_Test_2.scala | 5 + .../run/macro-expand-tparams-only-in-impl.flags | 1 + .../Impls_1.scala | 8 + .../Macros_Test_2.scala | 8 + test/files/run/macro-expand-tparams-optional.check | 1 + test/files/run/macro-expand-tparams-optional.flags | 1 + .../macro-expand-tparams-optional/Impls_1.scala | 9 + .../Macros_Test_2.scala | 4 + test/files/run/macro-expand-tparams-prefix-a.check | 4 + test/files/run/macro-expand-tparams-prefix-a.flags | 1 + .../macro-expand-tparams-prefix-a/Impls_1.scala | 10 + .../Macros_Test_2.scala | 10 + test/files/run/macro-expand-tparams-prefix-b.check | 2 + test/files/run/macro-expand-tparams-prefix-b.flags | 1 + .../macro-expand-tparams-prefix-b/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + .../files/run/macro-expand-tparams-prefix-c1.check | 3 + .../files/run/macro-expand-tparams-prefix-c1.flags | 1 + .../macro-expand-tparams-prefix-c1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 11 + .../files/run/macro-expand-tparams-prefix-c2.check | 3 + .../files/run/macro-expand-tparams-prefix-c2.flags | 1 + .../Impls_Macros_1.scala | 18 + .../macro-expand-tparams-prefix-c2/Test_2.scala | 5 + .../files/run/macro-expand-tparams-prefix-d1.check | 3 + .../files/run/macro-expand-tparams-prefix-d1.flags | 1 + .../macro-expand-tparams-prefix-d1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 11 + ...pand-varargs-explicit-over-nonvarargs-bad.check | 4 + ...pand-varargs-explicit-over-nonvarargs-bad.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 10 + ...and-varargs-explicit-over-nonvarargs-good.check | 1 + ...and-varargs-explicit-over-nonvarargs-good.flags | 1 + .../Impls_1.scala | 13 + .../Macros_Test_2.scala | 8 + ...acro-expand-varargs-explicit-over-varargs.check | 1 + ...acro-expand-varargs-explicit-over-varargs.flags | 1 + .../Impls_1.scala | 13 + .../Macros_Test_2.scala | 8 + ...o-expand-varargs-implicit-over-nonvarargs.check | 1 + ...o-expand-varargs-implicit-over-nonvarargs.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 7 + ...acro-expand-varargs-implicit-over-varargs.check | 1 + ...acro-expand-varargs-implicit-over-varargs.flags | 1 + .../Impls_1.scala | 13 + .../Macros_Test_2.scala | 7 + test/files/run/macro-impl-default-params.check | 5 + test/files/run/macro-impl-default-params.flags | 1 + .../macro-impl-default-params/Impls_Macros_1.scala | 20 + .../run/macro-impl-default-params/Test_2.scala | 4 + test/files/run/macro-impl-rename-context.check | 2 + test/files/run/macro-impl-rename-context.flags | 1 + .../macro-impl-rename-context/Impls_Macros_1.scala | 15 + .../run/macro-impl-rename-context/Test_2.scala | 4 + ...-invalidret-doesnt-conform-to-def-rettype.check | 5 + ...-invalidret-doesnt-conform-to-def-rettype.flags | 1 + .../Impls_Macros_1.scala | 12 + .../Test_2.scala | 6 + ...invalidret-doesnt-conform-to-impl-rettype.check | 0 ...invalidret-doesnt-conform-to-impl-rettype.flags | 1 + test/files/run/macro-invalidret-nontypeable.check | 3 + test/files/run/macro-invalidret-nontypeable.flags | 1 + .../Impls_Macros_1.scala | 13 + .../run/macro-invalidret-nontypeable/Test_2.scala | 6 + test/files/run/macro-invalidusage-badret.check | 5 + test/files/run/macro-invalidusage-badret.flags | 1 + .../macro-invalidusage-badret/Impls_Macros_1.scala | 9 + .../run/macro-invalidusage-badret/Test_2.scala | 6 + .../macro-invalidusage-partialapplication.check | 3 + .../macro-invalidusage-partialapplication.flags | 1 + .../Impls_Macros_1.scala | 14 + .../Test_2.scala | 6 + test/files/run/macro-openmacros.check | 3 + test/files/run/macro-openmacros.flags | 1 + .../run/macro-openmacros/Impls_Macros_1.scala | 26 + test/files/run/macro-openmacros/Test_2.scala | 3 + test/files/run/macro-quasiinvalidbody-c.check | 1 + test/files/run/macro-quasiinvalidbody-c.flags | 1 + .../macro-quasiinvalidbody-c/Impls_Macros_1.scala | 9 + .../run/macro-quasiinvalidbody-c/Test_2.scala | 4 + test/files/run/macro-range/Common_1.scala | 48 + .../run/macro-range/Expansion_Impossible_2.scala | 53 + .../run/macro-range/Expansion_Possible_3.scala | 7 + test/files/run/macro-range/macro_range_1.scala | 99 -- test/files/run/macro-range/macro_range_2.scala | 99 -- .../run/macro-reflective-ma-normal-mdmi.check | 1 + .../run/macro-reflective-ma-normal-mdmi.flags | 1 + .../Impls_Macros_1.scala | 13 + .../macro-reflective-ma-normal-mdmi/Test_2.scala | 5 + .../run/macro-reflective-mamd-normal-mi.check | 1 + .../run/macro-reflective-mamd-normal-mi.flags | 0 .../macro-reflective-mamd-normal-mi/Impls_1.scala | 9 + .../Macros_Test_2.scala | 16 + test/files/run/macro-reify-basic.check | 1 + test/files/run/macro-reify-basic.flags | 1 + test/files/run/macro-reify-basic/Macros_1.scala | 11 + test/files/run/macro-reify-basic/Test_2.scala | 3 + test/files/run/macro-reify-eval-eval.check | 1 + test/files/run/macro-reify-eval-eval.flags | 1 + .../files/run/macro-reify-eval-eval/Macros_1.scala | 12 + test/files/run/macro-reify-eval-eval/Test_2.scala | 3 + .../files/run/macro-reify-eval-outside-reify.check | 1 + .../files/run/macro-reify-eval-outside-reify.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-reify-eval-outside-reify/Test_2.scala | 5 + test/files/run/macro-reify-freevars.check | 3 + test/files/run/macro-reify-freevars.flags | 1 + test/files/run/macro-reify-freevars/Macros_1.scala | 19 + test/files/run/macro-reify-freevars/Test_2.scala | 9 + .../macro-reify-groundtypetag-notypeparams.check | 2 + .../Test.scala | 6 + ...macro-reify-groundtypetag-typeparams-tags.check | 2 + .../Test.scala | 9 + test/files/run/macro-reify-nested-a.check | 0 test/files/run/macro-reify-nested-a.flags | 1 + .../run/macro-reify-nested-a/Impls_Macros_1.scala | 43 + test/files/run/macro-reify-nested-a/Test_2.scala | 4 + test/files/run/macro-reify-nested-b.check | 0 test/files/run/macro-reify-nested-b.flags | 1 + .../run/macro-reify-nested-b/Impls_Macros_1.scala | 43 + test/files/run/macro-reify-nested-b/Test_2.scala | 4 + .../files/run/macro-reify-ref-to-packageless.check | 1 + .../files/run/macro-reify-ref-to-packageless.flags | 1 + .../macro-reify-ref-to-packageless/Impls_1.scala | 6 + .../macro-reify-ref-to-packageless/Test_2.scala | 4 + test/files/run/macro-reify-tagful-a.check | 1 + test/files/run/macro-reify-tagful-a.flags | 1 + test/files/run/macro-reify-tagful-a/Macros_1.scala | 11 + test/files/run/macro-reify-tagful-a/Test_2.scala | 4 + test/files/run/macro-reify-tagless-a.check | 3 + test/files/run/macro-reify-tagless-a.flags | 1 + .../run/macro-reify-tagless-a/Impls_Macros_1.scala | 11 + test/files/run/macro-reify-tagless-a/Test_2.scala | 12 + .../run/macro-reify-typetag-notypeparams.check | 2 + .../macro-reify-typetag-notypeparams/Test.scala | 6 + .../macro-reify-typetag-typeparams-notags.check | 2 + .../Test.scala | 9 + .../run/macro-reify-typetag-typeparams-tags.check | 2 + .../macro-reify-typetag-typeparams-tags/Test.scala | 9 + .../run/macro-reify-typetag-usegroundtypetag.check | 2 + .../Test.scala | 9 + test/files/run/macro-reify-unreify.check | 1 + test/files/run/macro-reify-unreify.flags | 1 + test/files/run/macro-reify-unreify/Macros_1.scala | 19 + test/files/run/macro-reify-unreify/Test_2.scala | 3 + .../run/macro-reify-value-outside-reify.check | 1 + .../run/macro-reify-value-outside-reify.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-reify-value-outside-reify/Test_2.scala | 6 + test/files/run/macro-repl-basic.check | 34 +- test/files/run/macro-repl-basic.scala | 27 +- test/files/run/macro-repl-dontexpand.check | 5 +- test/files/run/macro-repl-dontexpand.scala | 3 +- .../run/macro-rettype-mismatch/Macros_1.scala | 3 - test/files/run/macro-rettype-mismatch/Test_2.scala | 16 - test/files/run/macro-settings.check | 1 + test/files/run/macro-settings.flags | 1 + test/files/run/macro-settings/Impls_Macros_1.scala | 11 + test/files/run/macro-settings/Test_2.scala | 3 + test/files/run/macro-sip19-revised.check | 5 + test/files/run/macro-sip19-revised.flags | 1 + .../run/macro-sip19-revised/Impls_Macros_1.scala | 34 + test/files/run/macro-sip19-revised/Test_2.scala | 12 + test/files/run/macro-sip19.check | 5 + test/files/run/macro-sip19.flags | 1 + test/files/run/macro-sip19/Impls_Macros_1.scala | 25 + test/files/run/macro-sip19/Test_2.scala | 16 + .../run/macro-typecheck-implicitsdisabled.check | 2 + .../run/macro-typecheck-implicitsdisabled.flags | 1 + .../Impls_Macros_1.scala | 28 + .../macro-typecheck-implicitsdisabled/Test_2.scala | 4 + .../files/run/macro-typecheck-macrosdisabled.check | 5 + .../files/run/macro-typecheck-macrosdisabled.flags | 1 + .../Impls_Macros_1.scala | 36 + .../macro-typecheck-macrosdisabled/Test_2.scala | 4 + test/files/run/macro-undetparams-consfromsls.check | 5 + test/files/run/macro-undetparams-consfromsls.flags | 1 + .../Impls_Macros_1.scala | 17 + .../run/macro-undetparams-consfromsls/Test_2.scala | 7 + test/files/run/macro-undetparams-implicitval.check | 1 + test/files/run/macro-undetparams-implicitval.flags | 1 + .../run/macro-undetparams-implicitval/Test.scala | 4 + test/files/run/macro-undetparams-macroitself.check | 2 + test/files/run/macro-undetparams-macroitself.flags | 1 + .../Impls_Macros_1.scala | 7 + .../run/macro-undetparams-macroitself/Test_2.scala | 4 + test/files/run/manifests.scala | 71 +- test/files/run/primitive-sigs-2.check | 14 +- test/files/run/reify_ann1a.check | 60 +- test/files/run/reify_ann1a.scala | 11 +- test/files/run/reify_ann1b.check | 60 +- test/files/run/reify_ann1b.scala | 11 +- test/files/run/reify_ann2a.check | 44 + test/files/run/reify_ann2a.scala | 25 + test/files/run/reify_ann3.check | 21 + test/files/run/reify_ann3.scala | 19 + test/files/run/reify_ann4.check | 32 + test/files/run/reify_ann4.scala | 23 + test/files/run/reify_ann5.check | 22 + test/files/run/reify_ann5.scala | 20 + test/files/run/reify_anonymous.scala | 12 +- test/files/run/reify_classfileann_a.check | 36 +- test/files/run/reify_classfileann_a.scala | 11 +- test/files/run/reify_classfileann_b.check | 20 + test/files/run/reify_classfileann_b.scala | 23 + test/files/run/reify_closure1.scala | 9 +- test/files/run/reify_closure2a.scala | 9 +- test/files/run/reify_closure3a.scala | 9 +- test/files/run/reify_closure4a.scala | 9 +- test/files/run/reify_closure5a.scala | 17 +- test/files/run/reify_closure6.scala | 17 +- test/files/run/reify_closure7.scala | 17 +- test/files/run/reify_closure8a.scala | 10 +- test/files/run/reify_closure8b.check | 3 + test/files/run/reify_closure8b.scala | 18 + test/files/run/reify_closures10.scala | 10 +- test/files/run/reify_complex.scala | 12 +- test/files/run/reify_extendbuiltins.scala | 12 +- test/files/run/reify_for1.scala | 12 +- test/files/run/reify_fors.scala | 12 +- test/files/run/reify_generic.scala | 12 +- test/files/run/reify_generic2.scala | 12 +- test/files/run/reify_getter.scala | 11 +- test/files/run/reify_implicits.scala | 12 +- test/files/run/reify_inheritance.scala | 12 +- test/files/run/reify_inner1.scala | 12 +- test/files/run/reify_inner2.scala | 12 +- test/files/run/reify_inner3.scala | 12 +- test/files/run/reify_inner4.scala | 12 +- test/files/run/reify_maps.scala | 12 +- .../reify_metalevel_breach_+0_refers_to_1.check | 1 + .../reify_metalevel_breach_+0_refers_to_1.scala | 13 + .../reify_metalevel_breach_-1_refers_to_0_a.check | 1 + .../reify_metalevel_breach_-1_refers_to_0_a.scala | 11 + .../reify_metalevel_breach_-1_refers_to_0_b.check | 1 + .../reify_metalevel_breach_-1_refers_to_0_b.scala | 15 + .../reify_metalevel_breach_-1_refers_to_1.check | 1 + .../reify_metalevel_breach_-1_refers_to_1.scala | 13 + .../run/reify_nested_inner_refers_to_global.check | 1 + .../run/reify_nested_inner_refers_to_global.scala | 14 + .../run/reify_nested_inner_refers_to_local.check | 1 + .../run/reify_nested_inner_refers_to_local.scala | 12 + .../run/reify_nested_outer_refers_to_global.check | 1 + .../run/reify_nested_outer_refers_to_global.scala | 16 + .../run/reify_nested_outer_refers_to_local.check | 1 + .../run/reify_nested_outer_refers_to_local.scala | 16 + test/files/run/reify_newimpl_01.check | 1 + test/files/run/reify_newimpl_01.scala | 11 + test/files/run/reify_newimpl_02.check | 1 + test/files/run/reify_newimpl_02.scala | 11 + test/files/run/reify_newimpl_03.check | 1 + test/files/run/reify_newimpl_03.scala | 11 + test/files/run/reify_newimpl_04.check | 1 + test/files/run/reify_newimpl_04.scala | 11 + test/files/run/reify_newimpl_05.check | 1 + test/files/run/reify_newimpl_05.scala | 12 + test/files/run/reify_newimpl_06.check | 1 + test/files/run/reify_newimpl_06.scala | 11 + test/files/run/reify_newimpl_09.check | 1 + test/files/run/reify_newimpl_09.scala | 11 + test/files/run/reify_newimpl_10.check | 1 + test/files/run/reify_newimpl_10.scala | 12 + test/files/run/reify_newimpl_11.check | 2 + test/files/run/reify_newimpl_11.scala | 17 + test/files/run/reify_newimpl_12.check | 1 + test/files/run/reify_newimpl_12.scala | 12 + test/files/run/reify_newimpl_13.check | 2 + test/files/run/reify_newimpl_13.scala | 19 + test/files/run/reify_newimpl_14.check | 1 + test/files/run/reify_newimpl_14.scala | 14 + test/files/run/reify_newimpl_15.check | 1 + test/files/run/reify_newimpl_15.scala | 13 + test/files/run/reify_newimpl_16.check | 1 + test/files/run/reify_newimpl_16.scala | 15 + test/files/run/reify_newimpl_17.check | 2 + test/files/run/reify_newimpl_17.scala | 18 + test/files/run/reify_newimpl_18.check | 1 + test/files/run/reify_newimpl_18.scala | 13 + test/files/run/reify_newimpl_19.check | 2 + test/files/run/reify_newimpl_19.scala | 18 + test/files/run/reify_newimpl_20.check | 1 + test/files/run/reify_newimpl_20.scala | 14 + test/files/run/reify_newimpl_21.check | 1 + test/files/run/reify_newimpl_21.scala | 18 + test/files/run/reify_newimpl_22.check | 23 + test/files/run/reify_newimpl_22.scala | 15 + test/files/run/reify_newimpl_23.check | 22 + test/files/run/reify_newimpl_23.scala | 14 + test/files/run/reify_newimpl_24.check | 24 + test/files/run/reify_newimpl_24.scala | 16 + test/files/run/reify_newimpl_25.check | 21 + test/files/run/reify_newimpl_25.scala | 13 + test/files/run/reify_newimpl_26.check | 23 + test/files/run/reify_newimpl_26.scala | 13 + test/files/run/reify_newimpl_27.check | 1 + test/files/run/reify_newimpl_27.scala | 13 + test/files/run/reify_newimpl_28.check | 1 + test/files/run/reify_newimpl_28.scala | 15 + test/files/run/reify_newimpl_29.check | 1 + test/files/run/reify_newimpl_29.scala | 13 + test/files/run/reify_newimpl_30.check | 1 + test/files/run/reify_newimpl_30.scala | 15 + test/files/run/reify_newimpl_31.check | 1 + test/files/run/reify_newimpl_31.scala | 13 + test/files/run/reify_newimpl_32.check | 1 + test/files/run/reify_newimpl_32.scala | 15 + test/files/run/reify_newimpl_33.check | 1 + test/files/run/reify_newimpl_33.scala | 14 + test/files/run/reify_newimpl_34.check | 1 + test/files/run/reify_newimpl_34.scala | 16 + test/files/run/reify_newimpl_36.check | 1 + test/files/run/reify_newimpl_36.scala | 14 + test/files/run/reify_newimpl_37.check | 1 + test/files/run/reify_newimpl_37.scala | 15 + test/files/run/reify_newimpl_38.check | 1 + test/files/run/reify_newimpl_38.scala | 14 + test/files/run/reify_newimpl_39.check | 1 + test/files/run/reify_newimpl_39.scala | 15 + test/files/run/reify_newimpl_40.check | 1 + test/files/run/reify_newimpl_40.scala | 15 + test/files/run/reify_newimpl_41.check | 3 + test/files/run/reify_newimpl_41.scala | 17 + test/files/run/reify_newimpl_42.check | 3 + test/files/run/reify_newimpl_42.scala | 16 + test/files/run/reify_newimpl_43.check | 2 + test/files/run/reify_newimpl_43.scala | 15 + test/files/run/reify_newimpl_44.check | 2 + test/files/run/reify_newimpl_44.scala | 15 + test/files/run/reify_newimpl_45.check | 2 + test/files/run/reify_newimpl_45.scala | 12 + test/files/run/reify_newimpl_47.check | 1 + test/files/run/reify_newimpl_47.scala | 15 + test/files/run/reify_newimpl_48.check | 1 + test/files/run/reify_newimpl_48.scala | 20 + test/files/run/reify_newimpl_49.check | 3 + test/files/run/reify_newimpl_49.scala | 15 + test/files/run/reify_newimpl_50.check | 3 + test/files/run/reify_newimpl_50.scala | 14 + test/files/run/reify_newimpl_51.check | 3 + test/files/run/reify_newimpl_51.scala | 17 + test/files/run/reify_newimpl_52.check | 3 + test/files/run/reify_newimpl_52.scala | 17 + test/files/run/reify_printf.scala | 11 +- test/files/run/reify_sort.scala | 12 +- test/files/run/reify_sort1.scala | 12 +- test/files/run/reify_this.scala | 25 +- test/files/run/reify_timeofday.scala | 12 +- test/files/run/reify_typerefs_1a.check | 1 + test/files/run/reify_typerefs_1a.scala | 15 + test/files/run/reify_typerefs_1b.check | 1 + test/files/run/reify_typerefs_1b.scala | 15 + test/files/run/reify_typerefs_2a.check | 1 + test/files/run/reify_typerefs_2a.scala | 17 + test/files/run/reify_typerefs_2b.check | 1 + test/files/run/reify_typerefs_2b.scala | 17 + test/files/run/reify_typerefs_3a.check | 1 + test/files/run/reify_typerefs_3a.scala | 17 + test/files/run/reify_typerefs_3b.check | 1 + test/files/run/reify_typerefs_3b.scala | 17 + test/files/run/reify_varargs.scala | 12 +- test/files/run/repl-power.check | 64 +- test/files/run/t1195.check | 6 - test/files/run/t1195.check.temporarily.disabled | 6 + test/files/run/t1195.scala | 26 - test/files/run/t1195.scala.temporarily.disabled | 26 + test/files/run/t3758.check | 6 + test/files/run/t3758.scala | 12 +- test/files/run/t4110.check | 2 - test/files/run/t4110.check.temporarily.disabled | 2 + test/files/run/t4110.scala | 11 - test/files/run/t4110.scala.temporarily.disabled | 11 + test/files/run/t5224.check | 18 +- test/files/run/t5224.scala | 5 +- test/files/run/t5225_1.check | 8 +- test/files/run/t5225_1.scala | 5 +- test/files/run/t5225_2.check | 8 +- test/files/run/t5225_2.scala | 5 +- test/files/run/t5229_1.scala | 12 +- test/files/run/t5229_2.scala | 9 +- test/files/run/t5230.scala | 9 +- test/files/run/t5258a.check | 1 - test/files/run/t5258a.scala | 13 - test/files/run/t5266_1.scala | 9 +- test/files/run/t5266_2.scala | 9 +- test/files/run/t5269.scala | 12 +- test/files/run/t5270.scala | 12 +- test/files/run/t5271_1.check | 22 +- test/files/run/t5271_1.scala | 9 +- test/files/run/t5271_2.check | 24 +- test/files/run/t5271_2.scala | 9 +- test/files/run/t5271_3.check | 38 +- test/files/run/t5271_3.scala | 9 +- test/files/run/t5271_4.scala | 12 +- test/files/run/t5272_1.scala | 12 +- test/files/run/t5272_2.scala | 12 +- test/files/run/t5273_1.scala | 12 +- test/files/run/t5273_2a.scala | 12 +- test/files/run/t5273_2b.scala | 12 +- test/files/run/t5274_1.scala | 12 +- test/files/run/t5274_2.scala | 12 +- test/files/run/t5275.scala | 12 +- test/files/run/t5276_1a.scala | 12 +- test/files/run/t5276_1b.scala | 12 +- test/files/run/t5276_2a.scala | 12 +- test/files/run/t5276_2b.scala | 12 +- test/files/run/t5277_1.scala | 12 +- test/files/run/t5277_2.scala | 12 +- test/files/run/t5279.scala | 12 +- test/files/run/t5334_1.scala | 12 +- test/files/run/t5334_2.scala | 12 +- test/files/run/t5335.scala | 12 +- test/files/run/t5415.scala | 10 +- test/files/run/t5419.check | 2 +- test/files/run/t5419.scala | 5 +- test/files/run/t5423.scala | 3 - test/files/run/toolbox_console_reporter.check | 0 test/files/run/toolbox_console_reporter.scala | 16 + .../run/toolbox_default_reporter_is_silent.check | 1 + .../run/toolbox_default_reporter_is_silent.scala | 13 + test/files/run/toolbox_silent_reporter.check | 4 + test/files/run/toolbox_silent_reporter.scala | 16 + .../run/toolbox_typecheck_implicitsdisabled.check | 5 + .../run/toolbox_typecheck_implicitsdisabled.scala | 24 + .../run/toolbox_typecheck_macrosdisabled.check | 5 + .../run/toolbox_typecheck_macrosdisabled.scala | 17 + test/files/run/treePrint.check | 5 - .../files/run/treePrint.check.temporarily.disabled | 5 + test/files/run/treePrint.scala | 42 - .../files/run/treePrint.scala.temporarily.disabled | 42 + test/files/run/typetags_core.check | 30 + test/files/run/typetags_core.scala | 32 + test/pending/neg/reify_packed.check | 4 + test/pending/neg/reify_packed.scala | 10 + test/pending/run/macro-expand-default.flags | 1 + .../pending/run/macro-expand-default/Impls_1.scala | 10 + .../run/macro-expand-default/Macros_Test_2.scala | 8 + ...o-expand-implicit-macro-has-context-bound.check | 1 + ...o-expand-implicit-macro-has-context-bound.flags | 1 + .../Impls_1.scala | 10 + .../Macros_Test_2.scala | 4 + test/pending/run/macro-expand-named.flags | 1 + test/pending/run/macro-expand-named/Impls_1.scala | 10 + .../run/macro-expand-named/Macros_Test_2.scala | 5 + .../run/macro-expand-tparams-prefix-e1.check | 3 + .../run/macro-expand-tparams-prefix-e1.flags | 1 + .../macro-expand-tparams-prefix-e1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 13 + .../run/macro-expand-tparams-prefix-f1.check | 3 + .../run/macro-expand-tparams-prefix-f1.flags | 1 + .../macro-expand-tparams-prefix-f1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 13 + test/pending/run/macro-overload.check | 4 - test/pending/run/macro-overload.flags | 1 - test/pending/run/macro-overload/Macros_1.scala | 9 - test/pending/run/macro-overload/Test_2.scala | 6 - test/pending/run/macro-quasiinvalidbody-a.check | 1 + test/pending/run/macro-quasiinvalidbody-a.flags | 1 + .../run/macro-quasiinvalidbody-a/Impls_1.scala | 5 + .../macro-quasiinvalidbody-a/Macros_Test_2.scala | 10 + test/pending/run/macro-quasiinvalidbody-b.check | 1 + test/pending/run/macro-quasiinvalidbody-b.flags | 1 + .../run/macro-quasiinvalidbody-b/Impls_1.scala | 7 + .../macro-quasiinvalidbody-b/Macros_Test_2.scala | 10 + test/pending/run/macro-reify-array.flags | 1 + test/pending/run/macro-reify-array/Macros_1.scala | 11 + test/pending/run/macro-reify-array/Test_2.scala | 4 + test/pending/run/macro-reify-eval-vs-value.flags | 1 + .../run/macro-reify-eval-vs-value/Macros_1.scala | 25 + .../run/macro-reify-eval-vs-value/Test_2.scala | 5 + ...cro-reify-groundtypetag-hktypeparams-tags.check | 2 + .../Test.scala | 9 + test/pending/run/macro-reify-tagful-b.check | 1 + test/pending/run/macro-reify-tagful-b.flags | 1 + .../run/macro-reify-tagful-b/Macros_1.scala | 11 + test/pending/run/macro-reify-tagful-b/Test_2.scala | 4 + test/pending/run/macro-reify-tagless-b.check | 3 + test/pending/run/macro-reify-tagless-b.flags | 1 + .../run/macro-reify-tagless-b/Impls_Macros_1.scala | 11 + .../pending/run/macro-reify-tagless-b/Test_2.scala | 11 + .../macro-reify-typetag-hktypeparams-notags.check | 2 + .../Test.scala | 9 + .../macro-reify-typetag-hktypeparams-tags.check | 2 + .../Test.scala | 9 + test/pending/run/reify_addressbook.scala | 12 +- test/pending/run/reify_brainf_ck.scala | 12 +- test/pending/run/reify_callccinterpreter.scala | 12 +- test/pending/run/reify_classfileann_b.check | 0 test/pending/run/reify_classfileann_b.scala | 24 - test/pending/run/reify_closure2b.scala | 9 +- test/pending/run/reify_closure3b.scala | 9 +- test/pending/run/reify_closure4b.scala | 9 +- test/pending/run/reify_closure5b.scala | 9 +- test/pending/run/reify_closure8b.check | 1 - test/pending/run/reify_closure8b.scala | 16 - test/pending/run/reify_closure9a.scala | 11 +- test/pending/run/reify_closure9b.scala | 11 +- test/pending/run/reify_closures11.scala | 11 +- test/pending/run/reify_csv.scala | 12 +- test/pending/run/reify_gadts.scala | 12 +- test/pending/run/reify_lazyevaluation.scala | 12 +- test/pending/run/reify_newimpl_07.scala | 13 + test/pending/run/reify_newimpl_08.scala | 15 + test/pending/run/reify_newimpl_35.scala | 10 + test/pending/run/reify_newimpl_46.scala | 12 + test/pending/run/reify_newimpl_53.scala | 15 + test/pending/run/reify_properties.scala | 12 +- test/pending/run/reify_simpleinterpreter.scala | 12 +- test/pending/run/t5258a.check | 1 + test/pending/run/t5258a.scala | 5 + test/pending/run/t5258b.scala | 12 +- test/pending/run/t5258c.scala | 12 +- test/pending/run/t5271_1.scala | 12 +- test/pending/run/t5271_2.scala | 12 +- test/pending/run/t5271_3.scala | 12 +- test/pending/run/t5418.scala | 12 +- 1134 files changed, 15211 insertions(+), 5479 deletions(-) create mode 100644 src/compiler/scala/reflect/internal/CapturedVariables.scala create mode 100644 src/compiler/scala/reflect/internal/FreeVars.scala create mode 100644 src/compiler/scala/reflect/internal/Reporters.scala create mode 100644 src/compiler/scala/reflect/internal/TreeBuildUtil.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Aliases.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Context.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Enclosures.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Errors.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Infrastructure.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Names.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Reifiers.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Reporters.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Settings.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Symbols.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Typers.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Util.scala create mode 100644 src/compiler/scala/reflect/reify/Errors.scala create mode 100644 src/compiler/scala/reflect/reify/NodePrinters.scala create mode 100644 src/compiler/scala/reflect/reify/Phases.scala create mode 100644 src/compiler/scala/reflect/reify/Reifiers.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Names.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Positions.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Symbols.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Trees.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Types.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Util.scala create mode 100644 src/compiler/scala/reflect/reify/package.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Calculate.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Metalevels.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Reify.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Reshape.scala create mode 100644 src/compiler/scala/reflect/runtime/ClassLoaders.scala delete mode 100644 src/compiler/scala/reflect/runtime/Loaders.scala delete mode 100644 src/compiler/scala/reflect/runtime/Memoizer.scala delete mode 100644 src/compiler/scala/reflect/runtime/RuntimeTypes.scala create mode 100644 src/compiler/scala/reflect/runtime/SymbolLoaders.scala delete mode 100644 src/compiler/scala/reflect/runtime/TreeBuildUtil.scala create mode 100644 src/compiler/scala/reflect/runtime/package.scala create mode 100644 src/compiler/scala/tools/nsc/ClassLoaders.scala delete mode 100644 src/compiler/scala/tools/nsc/MacroContext.scala create mode 100644 src/compiler/scala/tools/nsc/ToolBoxes.scala create mode 100644 src/compiler/scala/tools/nsc/ast/FreeVars.scala create mode 100644 src/compiler/scala/tools/nsc/ast/Positions.scala delete mode 100644 src/compiler/scala/tools/nsc/ast/Reifiers.scala delete mode 100644 src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala delete mode 100644 src/compiler/scala/tools/nsc/symtab/Positions.scala create mode 100644 src/library/scala/reflect/ArrayTags.scala delete mode 100644 src/library/scala/reflect/ClassManifest.scala create mode 100644 src/library/scala/reflect/ClassTags.scala delete mode 100644 src/library/scala/reflect/Manifest.scala delete mode 100644 src/library/scala/reflect/NoManifest.scala delete mode 100644 src/library/scala/reflect/OptManifest.scala create mode 100644 src/library/scala/reflect/TagMaterialization.scala create mode 100644 src/library/scala/reflect/api/Attachments.scala create mode 100644 src/library/scala/reflect/api/ClassLoaders.scala create mode 100644 src/library/scala/reflect/api/Exprs.scala create mode 100644 src/library/scala/reflect/api/FreeVars.scala create mode 100644 src/library/scala/reflect/api/Importers.scala create mode 100644 src/library/scala/reflect/api/Reporters.scala delete mode 100644 src/library/scala/reflect/api/RuntimeTypes.scala create mode 100644 src/library/scala/reflect/api/ToolBoxes.scala create mode 100644 src/library/scala/reflect/api/TypeTags.scala delete mode 100644 src/library/scala/reflect/macro/Context.scala create mode 100644 src/library/scala/reflect/makro/Aliases.scala create mode 100644 src/library/scala/reflect/makro/CapturedVariables.scala create mode 100644 src/library/scala/reflect/makro/Context.scala create mode 100644 src/library/scala/reflect/makro/Enclosures.scala create mode 100644 src/library/scala/reflect/makro/Infrastructure.scala create mode 100644 src/library/scala/reflect/makro/Names.scala create mode 100644 src/library/scala/reflect/makro/Reifiers.scala create mode 100644 src/library/scala/reflect/makro/Reporters.scala create mode 100644 src/library/scala/reflect/makro/Settings.scala create mode 100644 src/library/scala/reflect/makro/Symbols.scala create mode 100644 src/library/scala/reflect/makro/Typers.scala create mode 100644 src/library/scala/reflect/makro/Util.scala create mode 100644 src/library/scala/reflect/makro/internal/macroImpl.scala create mode 100644 src/library/scala/reflect/makro/internal/typeTagImpl.scala delete mode 100644 test/files/jvm/manifests.check create mode 100644 test/files/jvm/manifests.check.temporarily.disabled delete mode 100644 test/files/jvm/manifests.scala create mode 100644 test/files/jvm/manifests.scala.temporarily.disabled delete mode 100644 test/files/macros/Printf.scala delete mode 100644 test/files/macros/Test.scala delete mode 100644 test/files/macros/macros_v0001.bat delete mode 100644 test/files/macros/macros_v0001.sh create mode 100644 test/files/neg/classtags_contextbound_a.check create mode 100644 test/files/neg/classtags_contextbound_a.scala create mode 100644 test/files/neg/classtags_contextbound_b.check create mode 100644 test/files/neg/classtags_contextbound_b.scala create mode 100644 test/files/neg/classtags_contextbound_c.check create mode 100644 test/files/neg/classtags_contextbound_c.scala delete mode 100644 test/files/neg/macro-argtype-mismatch/Macros_1.scala delete mode 100644 test/files/neg/macro-argtype-mismatch/Test_2.scala create mode 100644 test/files/neg/macro-basic-mamdmi.check create mode 100644 test/files/neg/macro-basic-mamdmi.flags create mode 100644 test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala create mode 100644 test/files/neg/macro-cyclic.check create mode 100644 test/files/neg/macro-cyclic.flags create mode 100644 test/files/neg/macro-cyclic/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents.check create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala create mode 100644 test/files/neg/macro-deprecate-idents.check create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Class_4.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Class_5.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Def_13.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Object_6.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Object_7.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Package_10.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Package_11.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Type_3.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Val_1.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Var_2.scala create mode 100644 test/files/neg/macro-deprecate-idents/Main.scala create mode 100644 test/files/neg/macro-invalidimpl-a.check create mode 100644 test/files/neg/macro-invalidimpl-a.flags create mode 100644 test/files/neg/macro-invalidimpl-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-b.check create mode 100644 test/files/neg/macro-invalidimpl-b.flags create mode 100644 test/files/neg/macro-invalidimpl-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-c.check create mode 100644 test/files/neg/macro-invalidimpl-c.flags create mode 100644 test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidimpl-c/Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-d.check create mode 100644 test/files/neg/macro-invalidimpl-d.flags create mode 100644 test/files/neg/macro-invalidimpl-d/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-e.check create mode 100644 test/files/neg/macro-invalidimpl-e.flags create mode 100644 test/files/neg/macro-invalidimpl-e/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-f.check create mode 100644 test/files/neg/macro-invalidimpl-f.flags create mode 100644 test/files/neg/macro-invalidimpl-f/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-g.check create mode 100644 test/files/neg/macro-invalidimpl-g.flags create mode 100644 test/files/neg/macro-invalidimpl-g/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-h.check create mode 100644 test/files/neg/macro-invalidimpl-h.flags create mode 100644 test/files/neg/macro-invalidimpl-h/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidret-nontree.check create mode 100644 test/files/neg/macro-invalidret-nontree.flags create mode 100644 test/files/neg/macro-invalidret-nontree/Impls_1.scala create mode 100644 test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidret-nonuniversetree.check create mode 100644 test/files/neg/macro-invalidret-nonuniversetree.flags create mode 100644 test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala create mode 100644 test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-a.check create mode 100644 test/files/neg/macro-invalidshape-a.flags create mode 100644 test/files/neg/macro-invalidshape-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-b.check create mode 100644 test/files/neg/macro-invalidshape-b.flags create mode 100644 test/files/neg/macro-invalidshape-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-c.check create mode 100644 test/files/neg/macro-invalidshape-c.flags create mode 100644 test/files/neg/macro-invalidshape-c/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-c/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-d.check create mode 100644 test/files/neg/macro-invalidshape-d.flags create mode 100644 test/files/neg/macro-invalidshape-d/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-d/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-context-bounds.check create mode 100644 test/files/neg/macro-invalidsig-context-bounds.flags create mode 100644 test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc.check create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype.check create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs.check create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx.check create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-implicit-params.check create mode 100644 test/files/neg/macro-invalidsig-implicit-params.flags create mode 100644 test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-implicit-params/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-badargc.check create mode 100644 test/files/neg/macro-invalidsig-params-badargc.flags create mode 100644 test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-badargc/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-badtype.check create mode 100644 test/files/neg/macro-invalidsig-params-badtype.flags create mode 100644 test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-badtype/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs.check create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs.flags create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch.check create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch.flags create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype.check create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a.check create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b.check create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a.check create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b.check create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c.check create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badargs.check create mode 100644 test/files/neg/macro-invalidusage-badargs.flags create mode 100644 test/files/neg/macro-invalidusage-badargs/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badbounds.check create mode 100644 test/files/neg/macro-invalidusage-badbounds.flags create mode 100644 test/files/neg/macro-invalidusage-badbounds/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badtargs.check create mode 100644 test/files/neg/macro-invalidusage-badtargs.flags create mode 100644 test/files/neg/macro-invalidusage-badtargs/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax.check create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax.flags create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala create mode 100644 test/files/neg/macro-keyword.check create mode 100644 test/files/neg/macro-keyword.flags create mode 100644 test/files/neg/macro-keyword/Macros_Bind_12.scala create mode 100644 test/files/neg/macro-keyword/Macros_Class_4.scala create mode 100644 test/files/neg/macro-keyword/Macros_Class_5.scala create mode 100644 test/files/neg/macro-keyword/Macros_Def_13.scala create mode 100644 test/files/neg/macro-keyword/Macros_Object_6.scala create mode 100644 test/files/neg/macro-keyword/Macros_Object_7.scala create mode 100644 test/files/neg/macro-keyword/Macros_Package_10.scala create mode 100644 test/files/neg/macro-keyword/Macros_Package_11.scala create mode 100644 test/files/neg/macro-keyword/Macros_Trait_8.scala create mode 100644 test/files/neg/macro-keyword/Macros_Trait_9.scala create mode 100644 test/files/neg/macro-keyword/Macros_Type_3.scala create mode 100644 test/files/neg/macro-keyword/Macros_Val_1.scala create mode 100644 test/files/neg/macro-keyword/Macros_Var_2.scala create mode 100644 test/files/neg/macro-noexpand/Impls_1.scala delete mode 100644 test/files/neg/macro-noexpand/Macros_1.scala create mode 100644 test/files/neg/macro-noexpand/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-noexpand/Test_2.scala delete mode 100644 test/files/neg/macro-noncompilertree/Macros_1.scala delete mode 100644 test/files/neg/macro-nontree/Macros_1.scala create mode 100644 test/files/neg/macro-nontypeablebody.check create mode 100644 test/files/neg/macro-nontypeablebody.flags create mode 100644 test/files/neg/macro-nontypeablebody/Impls_1.scala create mode 100644 test/files/neg/macro-nontypeablebody/Macros_Test_2.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a.check create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a.flags create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b.check create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b.flags create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala create mode 100644 test/files/neg/macro-override-method-overrides-macro.check create mode 100644 test/files/neg/macro-override-method-overrides-macro.flags create mode 100644 test/files/neg/macro-override-method-overrides-macro/Impls_1.scala create mode 100644 test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala create mode 100644 test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check create mode 100644 test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala create mode 100644 test/files/neg/macro-reify-groundtypetag-typeparams-notags.check create mode 100644 test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala create mode 100644 test/files/neg/macro-reify-groundtypetag-usetypetag.check create mode 100644 test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala create mode 100644 test/files/neg/macro-without-xmacros-a.check create mode 100644 test/files/neg/macro-without-xmacros-a/Impls_1.scala create mode 100644 test/files/neg/macro-without-xmacros-a/Macros_2.scala create mode 100644 test/files/neg/macro-without-xmacros-a/Test_3.scala create mode 100644 test/files/neg/macro-without-xmacros-b.check create mode 100644 test/files/neg/macro-without-xmacros-b/Impls_1.scala create mode 100644 test/files/neg/macro-without-xmacros-b/Macros_2.scala create mode 100644 test/files/neg/macro-without-xmacros-b/Test_3.scala delete mode 100644 test/files/neg/reify_ann2a.check delete mode 100644 test/files/neg/reify_ann2a.scala create mode 100644 test/files/neg/t5334_1.check create mode 100644 test/files/neg/t5334_1.scala create mode 100644 test/files/neg/t5334_2.check create mode 100644 test/files/neg/t5334_2.scala delete mode 100644 test/files/pos/implicits.scala create mode 100644 test/files/pos/implicits.scala.temporarily.disabled delete mode 100644 test/files/pos/macros.flags delete mode 100644 test/files/pos/macros.scala delete mode 100644 test/files/pos/manifest1.scala create mode 100644 test/files/pos/manifest1.scala.temporarily.disabled create mode 100644 test/files/run/classtags_contextbound.check create mode 100644 test/files/run/classtags_contextbound.scala create mode 100644 test/files/run/classtags_core.check create mode 100644 test/files/run/classtags_core.scala delete mode 100644 test/files/run/existentials3.check create mode 100644 test/files/run/existentials3.check.temporarily.disabled delete mode 100644 test/files/run/existentials3.scala create mode 100644 test/files/run/existentials3.scala.temporarily.disabled create mode 100644 test/files/run/groundtypetags_core.check create mode 100644 test/files/run/groundtypetags_core.scala create mode 100644 test/files/run/macro-abort-fresh.check create mode 100644 test/files/run/macro-abort-fresh.flags create mode 100644 test/files/run/macro-abort-fresh/Macros_1.scala create mode 100644 test/files/run/macro-abort-fresh/Test_2.scala create mode 100644 test/files/run/macro-basic-ma-md-mi.check create mode 100644 test/files/run/macro-basic-ma-md-mi.flags create mode 100644 test/files/run/macro-basic-ma-md-mi/Impls_1.scala create mode 100644 test/files/run/macro-basic-ma-md-mi/Macros_2.scala create mode 100644 test/files/run/macro-basic-ma-md-mi/Test_3.scala create mode 100644 test/files/run/macro-basic-ma-mdmi.check create mode 100644 test/files/run/macro-basic-ma-mdmi.flags create mode 100644 test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala create mode 100644 test/files/run/macro-basic-ma-mdmi/Test_2.scala create mode 100644 test/files/run/macro-basic-mamd-mi.check create mode 100644 test/files/run/macro-basic-mamd-mi.flags create mode 100644 test/files/run/macro-basic-mamd-mi/Impls_1.scala create mode 100644 test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala delete mode 100644 test/files/run/macro-basic.check delete mode 100644 test/files/run/macro-basic.flags delete mode 100644 test/files/run/macro-basic/Macros_1.scala delete mode 100644 test/files/run/macro-basic/Test_2.scala create mode 100644 test/files/run/macro-bodyexpandstoimpl.check create mode 100644 test/files/run/macro-bodyexpandstoimpl.flags create mode 100644 test/files/run/macro-bodyexpandstoimpl/Impls_1.scala create mode 100644 test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-annotation.check create mode 100644 test/files/run/macro-declared-in-annotation.flags create mode 100644 test/files/run/macro-declared-in-annotation/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-annotation/Macros_2.scala create mode 100644 test/files/run/macro-declared-in-annotation/Test_3.scala create mode 100644 test/files/run/macro-declared-in-anonymous.check create mode 100644 test/files/run/macro-declared-in-anonymous.flags create mode 100644 test/files/run/macro-declared-in-anonymous/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-block.check create mode 100644 test/files/run/macro-declared-in-block.flags create mode 100644 test/files/run/macro-declared-in-block/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-block/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-class-class.check create mode 100644 test/files/run/macro-declared-in-class-class.flags create mode 100644 test/files/run/macro-declared-in-class-class/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-class-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-class-object.check create mode 100644 test/files/run/macro-declared-in-class-object.flags create mode 100644 test/files/run/macro-declared-in-class-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-class-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-class.check create mode 100644 test/files/run/macro-declared-in-class.flags create mode 100644 test/files/run/macro-declared-in-class/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-default-param.check create mode 100644 test/files/run/macro-declared-in-default-param.flags create mode 100644 test/files/run/macro-declared-in-default-param/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-default-param/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-implicit-class.check create mode 100644 test/files/run/macro-declared-in-implicit-class.flags create mode 100644 test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala create mode 100644 test/files/run/macro-declared-in-implicit-class/Test_2.scala create mode 100644 test/files/run/macro-declared-in-method.check create mode 100644 test/files/run/macro-declared-in-method.flags create mode 100644 test/files/run/macro-declared-in-method/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-method/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-object-class.check create mode 100644 test/files/run/macro-declared-in-object-class.flags create mode 100644 test/files/run/macro-declared-in-object-class/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-object-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-object-object.check create mode 100644 test/files/run/macro-declared-in-object-object.flags create mode 100644 test/files/run/macro-declared-in-object-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-object-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-object.check create mode 100644 test/files/run/macro-declared-in-object.flags create mode 100644 test/files/run/macro-declared-in-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-package-object.check create mode 100644 test/files/run/macro-declared-in-package-object.flags create mode 100644 test/files/run/macro-declared-in-package-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-package-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-refinement.check create mode 100644 test/files/run/macro-declared-in-refinement.flags create mode 100644 test/files/run/macro-declared-in-refinement/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-refinement/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-trait.check create mode 100644 test/files/run/macro-declared-in-trait.flags create mode 100644 test/files/run/macro-declared-in-trait/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-trait/Macros_Test_2.scala create mode 100644 test/files/run/macro-def-infer-return-type-a.check create mode 100644 test/files/run/macro-def-infer-return-type-a.flags create mode 100644 test/files/run/macro-def-infer-return-type-a/Impls_1.scala create mode 100644 test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala create mode 100644 test/files/run/macro-def-infer-return-type-b.check create mode 100644 test/files/run/macro-def-infer-return-type-b.flags create mode 100644 test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-infer-return-type-b/Test_2.scala create mode 100644 test/files/run/macro-def-infer-return-type-c.check create mode 100644 test/files/run/macro-def-infer-return-type-c.flags create mode 100644 test/files/run/macro-def-infer-return-type-c/Impls_1.scala create mode 100644 test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-a.check create mode 100644 test/files/run/macro-def-path-dependent-a.flags create mode 100644 test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-a/Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-b.check create mode 100644 test/files/run/macro-def-path-dependent-b.flags create mode 100644 test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-b/Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-c.check create mode 100644 test/files/run/macro-def-path-dependent-c.flags create mode 100644 test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-c/Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-d.check create mode 100644 test/files/run/macro-def-path-dependent-d.flags create mode 100644 test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-d/Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit.check create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit.flags create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit.check create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit.flags create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-val.check create mode 100644 test/files/run/macro-expand-implicit-macro-is-val.flags create mode 100644 test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-view.check create mode 100644 test/files/run/macro-expand-implicit-macro-is-view.flags create mode 100644 test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-multiple-arglists.check create mode 100644 test/files/run/macro-expand-multiple-arglists.flags create mode 100644 test/files/run/macro-expand-multiple-arglists/Impls_1.scala create mode 100644 test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-nullary-generic.check create mode 100644 test/files/run/macro-expand-nullary-generic.flags create mode 100644 test/files/run/macro-expand-nullary-generic/Impls_1.scala create mode 100644 test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-nullary-nongeneric.check create mode 100644 test/files/run/macro-expand-nullary-nongeneric.flags create mode 100644 test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala create mode 100644 test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-overload.check create mode 100644 test/files/run/macro-expand-overload.flags create mode 100644 test/files/run/macro-expand-overload/Impls_1.scala create mode 100644 test/files/run/macro-expand-overload/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-override.check create mode 100644 test/files/run/macro-expand-override.flags create mode 100644 test/files/run/macro-expand-override/Impls_1.scala create mode 100644 test/files/run/macro-expand-override/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-recursive.check create mode 100644 test/files/run/macro-expand-recursive.flags create mode 100644 test/files/run/macro-expand-recursive/Impls_1.scala create mode 100644 test/files/run/macro-expand-recursive/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-a.check create mode 100644 test/files/run/macro-expand-tparams-bounds-a.flags create mode 100644 test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-b.check create mode 100644 test/files/run/macro-expand-tparams-bounds-b.flags create mode 100644 test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-explicit.check create mode 100644 test/files/run/macro-expand-tparams-explicit.flags create mode 100644 test/files/run/macro-expand-tparams-explicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-implicit.check create mode 100644 test/files/run/macro-expand-tparams-implicit.flags create mode 100644 test/files/run/macro-expand-tparams-implicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-only-in-impl.flags create mode 100644 test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-optional.check create mode 100644 test/files/run/macro-expand-tparams-optional.flags create mode 100644 test/files/run/macro-expand-tparams-optional/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-a.check create mode 100644 test/files/run/macro-expand-tparams-prefix-a.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-b.check create mode 100644 test/files/run/macro-expand-tparams-prefix-b.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c1.check create mode 100644 test/files/run/macro-expand-tparams-prefix-c1.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c2.check create mode 100644 test/files/run/macro-expand-tparams-prefix-c2.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-d1.check create mode 100644 test/files/run/macro-expand-tparams-prefix-d1.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs.check create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs.flags create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs.check create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs.flags create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala create mode 100644 test/files/run/macro-impl-default-params.check create mode 100644 test/files/run/macro-impl-default-params.flags create mode 100644 test/files/run/macro-impl-default-params/Impls_Macros_1.scala create mode 100644 test/files/run/macro-impl-default-params/Test_2.scala create mode 100644 test/files/run/macro-impl-rename-context.check create mode 100644 test/files/run/macro-impl-rename-context.flags create mode 100644 test/files/run/macro-impl-rename-context/Impls_Macros_1.scala create mode 100644 test/files/run/macro-impl-rename-context/Test_2.scala create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags create mode 100644 test/files/run/macro-invalidret-nontypeable.check create mode 100644 test/files/run/macro-invalidret-nontypeable.flags create mode 100644 test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidret-nontypeable/Test_2.scala create mode 100644 test/files/run/macro-invalidusage-badret.check create mode 100644 test/files/run/macro-invalidusage-badret.flags create mode 100644 test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidusage-badret/Test_2.scala create mode 100644 test/files/run/macro-invalidusage-partialapplication.check create mode 100644 test/files/run/macro-invalidusage-partialapplication.flags create mode 100644 test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidusage-partialapplication/Test_2.scala create mode 100644 test/files/run/macro-openmacros.check create mode 100644 test/files/run/macro-openmacros.flags create mode 100644 test/files/run/macro-openmacros/Impls_Macros_1.scala create mode 100644 test/files/run/macro-openmacros/Test_2.scala create mode 100644 test/files/run/macro-quasiinvalidbody-c.check create mode 100644 test/files/run/macro-quasiinvalidbody-c.flags create mode 100644 test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala create mode 100644 test/files/run/macro-quasiinvalidbody-c/Test_2.scala create mode 100644 test/files/run/macro-range/Common_1.scala create mode 100644 test/files/run/macro-range/Expansion_Impossible_2.scala create mode 100644 test/files/run/macro-range/Expansion_Possible_3.scala delete mode 100644 test/files/run/macro-range/macro_range_1.scala delete mode 100644 test/files/run/macro-range/macro_range_2.scala create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi.check create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi.flags create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala create mode 100644 test/files/run/macro-reflective-mamd-normal-mi.check create mode 100644 test/files/run/macro-reflective-mamd-normal-mi.flags create mode 100644 test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala create mode 100644 test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala create mode 100644 test/files/run/macro-reify-basic.check create mode 100644 test/files/run/macro-reify-basic.flags create mode 100644 test/files/run/macro-reify-basic/Macros_1.scala create mode 100644 test/files/run/macro-reify-basic/Test_2.scala create mode 100644 test/files/run/macro-reify-eval-eval.check create mode 100644 test/files/run/macro-reify-eval-eval.flags create mode 100644 test/files/run/macro-reify-eval-eval/Macros_1.scala create mode 100644 test/files/run/macro-reify-eval-eval/Test_2.scala create mode 100644 test/files/run/macro-reify-eval-outside-reify.check create mode 100644 test/files/run/macro-reify-eval-outside-reify.flags create mode 100644 test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-eval-outside-reify/Test_2.scala create mode 100644 test/files/run/macro-reify-freevars.check create mode 100644 test/files/run/macro-reify-freevars.flags create mode 100644 test/files/run/macro-reify-freevars/Macros_1.scala create mode 100644 test/files/run/macro-reify-freevars/Test_2.scala create mode 100644 test/files/run/macro-reify-groundtypetag-notypeparams.check create mode 100644 test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala create mode 100644 test/files/run/macro-reify-groundtypetag-typeparams-tags.check create mode 100644 test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala create mode 100644 test/files/run/macro-reify-nested-a.check create mode 100644 test/files/run/macro-reify-nested-a.flags create mode 100644 test/files/run/macro-reify-nested-a/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-nested-a/Test_2.scala create mode 100644 test/files/run/macro-reify-nested-b.check create mode 100644 test/files/run/macro-reify-nested-b.flags create mode 100644 test/files/run/macro-reify-nested-b/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-nested-b/Test_2.scala create mode 100644 test/files/run/macro-reify-ref-to-packageless.check create mode 100644 test/files/run/macro-reify-ref-to-packageless.flags create mode 100644 test/files/run/macro-reify-ref-to-packageless/Impls_1.scala create mode 100644 test/files/run/macro-reify-ref-to-packageless/Test_2.scala create mode 100644 test/files/run/macro-reify-tagful-a.check create mode 100644 test/files/run/macro-reify-tagful-a.flags create mode 100644 test/files/run/macro-reify-tagful-a/Macros_1.scala create mode 100644 test/files/run/macro-reify-tagful-a/Test_2.scala create mode 100644 test/files/run/macro-reify-tagless-a.check create mode 100644 test/files/run/macro-reify-tagless-a.flags create mode 100644 test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-tagless-a/Test_2.scala create mode 100644 test/files/run/macro-reify-typetag-notypeparams.check create mode 100644 test/files/run/macro-reify-typetag-notypeparams/Test.scala create mode 100644 test/files/run/macro-reify-typetag-typeparams-notags.check create mode 100644 test/files/run/macro-reify-typetag-typeparams-notags/Test.scala create mode 100644 test/files/run/macro-reify-typetag-typeparams-tags.check create mode 100644 test/files/run/macro-reify-typetag-typeparams-tags/Test.scala create mode 100644 test/files/run/macro-reify-typetag-usegroundtypetag.check create mode 100644 test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala create mode 100644 test/files/run/macro-reify-unreify.check create mode 100644 test/files/run/macro-reify-unreify.flags create mode 100644 test/files/run/macro-reify-unreify/Macros_1.scala create mode 100644 test/files/run/macro-reify-unreify/Test_2.scala create mode 100644 test/files/run/macro-reify-value-outside-reify.check create mode 100644 test/files/run/macro-reify-value-outside-reify.flags create mode 100644 test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-value-outside-reify/Test_2.scala delete mode 100644 test/files/run/macro-rettype-mismatch/Macros_1.scala delete mode 100644 test/files/run/macro-rettype-mismatch/Test_2.scala create mode 100644 test/files/run/macro-settings.check create mode 100644 test/files/run/macro-settings.flags create mode 100644 test/files/run/macro-settings/Impls_Macros_1.scala create mode 100644 test/files/run/macro-settings/Test_2.scala create mode 100644 test/files/run/macro-sip19-revised.check create mode 100644 test/files/run/macro-sip19-revised.flags create mode 100644 test/files/run/macro-sip19-revised/Impls_Macros_1.scala create mode 100644 test/files/run/macro-sip19-revised/Test_2.scala create mode 100644 test/files/run/macro-sip19.check create mode 100644 test/files/run/macro-sip19.flags create mode 100644 test/files/run/macro-sip19/Impls_Macros_1.scala create mode 100644 test/files/run/macro-sip19/Test_2.scala create mode 100644 test/files/run/macro-typecheck-implicitsdisabled.check create mode 100644 test/files/run/macro-typecheck-implicitsdisabled.flags create mode 100644 test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala create mode 100644 test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala create mode 100644 test/files/run/macro-typecheck-macrosdisabled.check create mode 100644 test/files/run/macro-typecheck-macrosdisabled.flags create mode 100644 test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala create mode 100644 test/files/run/macro-typecheck-macrosdisabled/Test_2.scala create mode 100644 test/files/run/macro-undetparams-consfromsls.check create mode 100644 test/files/run/macro-undetparams-consfromsls.flags create mode 100644 test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala create mode 100644 test/files/run/macro-undetparams-consfromsls/Test_2.scala create mode 100644 test/files/run/macro-undetparams-implicitval.check create mode 100644 test/files/run/macro-undetparams-implicitval.flags create mode 100644 test/files/run/macro-undetparams-implicitval/Test.scala create mode 100644 test/files/run/macro-undetparams-macroitself.check create mode 100644 test/files/run/macro-undetparams-macroitself.flags create mode 100644 test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala create mode 100644 test/files/run/macro-undetparams-macroitself/Test_2.scala create mode 100644 test/files/run/reify_ann2a.check create mode 100644 test/files/run/reify_ann2a.scala create mode 100644 test/files/run/reify_ann3.check create mode 100644 test/files/run/reify_ann3.scala create mode 100644 test/files/run/reify_ann4.check create mode 100644 test/files/run/reify_ann4.scala create mode 100644 test/files/run/reify_ann5.check create mode 100644 test/files/run/reify_ann5.scala create mode 100644 test/files/run/reify_classfileann_b.check create mode 100644 test/files/run/reify_classfileann_b.scala create mode 100644 test/files/run/reify_closure8b.check create mode 100644 test/files/run/reify_closure8b.scala create mode 100644 test/files/run/reify_metalevel_breach_+0_refers_to_1.check create mode 100644 test/files/run/reify_metalevel_breach_+0_refers_to_1.scala create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_1.check create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_1.scala create mode 100644 test/files/run/reify_nested_inner_refers_to_global.check create mode 100644 test/files/run/reify_nested_inner_refers_to_global.scala create mode 100644 test/files/run/reify_nested_inner_refers_to_local.check create mode 100644 test/files/run/reify_nested_inner_refers_to_local.scala create mode 100644 test/files/run/reify_nested_outer_refers_to_global.check create mode 100644 test/files/run/reify_nested_outer_refers_to_global.scala create mode 100644 test/files/run/reify_nested_outer_refers_to_local.check create mode 100644 test/files/run/reify_nested_outer_refers_to_local.scala create mode 100644 test/files/run/reify_newimpl_01.check create mode 100644 test/files/run/reify_newimpl_01.scala create mode 100644 test/files/run/reify_newimpl_02.check create mode 100644 test/files/run/reify_newimpl_02.scala create mode 100644 test/files/run/reify_newimpl_03.check create mode 100644 test/files/run/reify_newimpl_03.scala create mode 100644 test/files/run/reify_newimpl_04.check create mode 100644 test/files/run/reify_newimpl_04.scala create mode 100644 test/files/run/reify_newimpl_05.check create mode 100644 test/files/run/reify_newimpl_05.scala create mode 100644 test/files/run/reify_newimpl_06.check create mode 100644 test/files/run/reify_newimpl_06.scala create mode 100644 test/files/run/reify_newimpl_09.check create mode 100644 test/files/run/reify_newimpl_09.scala create mode 100644 test/files/run/reify_newimpl_10.check create mode 100644 test/files/run/reify_newimpl_10.scala create mode 100644 test/files/run/reify_newimpl_11.check create mode 100644 test/files/run/reify_newimpl_11.scala create mode 100644 test/files/run/reify_newimpl_12.check create mode 100644 test/files/run/reify_newimpl_12.scala create mode 100644 test/files/run/reify_newimpl_13.check create mode 100644 test/files/run/reify_newimpl_13.scala create mode 100644 test/files/run/reify_newimpl_14.check create mode 100644 test/files/run/reify_newimpl_14.scala create mode 100644 test/files/run/reify_newimpl_15.check create mode 100644 test/files/run/reify_newimpl_15.scala create mode 100644 test/files/run/reify_newimpl_16.check create mode 100644 test/files/run/reify_newimpl_16.scala create mode 100644 test/files/run/reify_newimpl_17.check create mode 100644 test/files/run/reify_newimpl_17.scala create mode 100644 test/files/run/reify_newimpl_18.check create mode 100644 test/files/run/reify_newimpl_18.scala create mode 100644 test/files/run/reify_newimpl_19.check create mode 100644 test/files/run/reify_newimpl_19.scala create mode 100644 test/files/run/reify_newimpl_20.check create mode 100644 test/files/run/reify_newimpl_20.scala create mode 100644 test/files/run/reify_newimpl_21.check create mode 100644 test/files/run/reify_newimpl_21.scala create mode 100644 test/files/run/reify_newimpl_22.check create mode 100644 test/files/run/reify_newimpl_22.scala create mode 100644 test/files/run/reify_newimpl_23.check create mode 100644 test/files/run/reify_newimpl_23.scala create mode 100644 test/files/run/reify_newimpl_24.check create mode 100644 test/files/run/reify_newimpl_24.scala create mode 100644 test/files/run/reify_newimpl_25.check create mode 100644 test/files/run/reify_newimpl_25.scala create mode 100644 test/files/run/reify_newimpl_26.check create mode 100644 test/files/run/reify_newimpl_26.scala create mode 100644 test/files/run/reify_newimpl_27.check create mode 100644 test/files/run/reify_newimpl_27.scala create mode 100644 test/files/run/reify_newimpl_28.check create mode 100644 test/files/run/reify_newimpl_28.scala create mode 100644 test/files/run/reify_newimpl_29.check create mode 100644 test/files/run/reify_newimpl_29.scala create mode 100644 test/files/run/reify_newimpl_30.check create mode 100644 test/files/run/reify_newimpl_30.scala create mode 100644 test/files/run/reify_newimpl_31.check create mode 100644 test/files/run/reify_newimpl_31.scala create mode 100644 test/files/run/reify_newimpl_32.check create mode 100644 test/files/run/reify_newimpl_32.scala create mode 100644 test/files/run/reify_newimpl_33.check create mode 100644 test/files/run/reify_newimpl_33.scala create mode 100644 test/files/run/reify_newimpl_34.check create mode 100644 test/files/run/reify_newimpl_34.scala create mode 100644 test/files/run/reify_newimpl_36.check create mode 100644 test/files/run/reify_newimpl_36.scala create mode 100644 test/files/run/reify_newimpl_37.check create mode 100644 test/files/run/reify_newimpl_37.scala create mode 100644 test/files/run/reify_newimpl_38.check create mode 100644 test/files/run/reify_newimpl_38.scala create mode 100644 test/files/run/reify_newimpl_39.check create mode 100644 test/files/run/reify_newimpl_39.scala create mode 100644 test/files/run/reify_newimpl_40.check create mode 100644 test/files/run/reify_newimpl_40.scala create mode 100644 test/files/run/reify_newimpl_41.check create mode 100644 test/files/run/reify_newimpl_41.scala create mode 100644 test/files/run/reify_newimpl_42.check create mode 100644 test/files/run/reify_newimpl_42.scala create mode 100644 test/files/run/reify_newimpl_43.check create mode 100644 test/files/run/reify_newimpl_43.scala create mode 100644 test/files/run/reify_newimpl_44.check create mode 100644 test/files/run/reify_newimpl_44.scala create mode 100644 test/files/run/reify_newimpl_45.check create mode 100644 test/files/run/reify_newimpl_45.scala create mode 100644 test/files/run/reify_newimpl_47.check create mode 100644 test/files/run/reify_newimpl_47.scala create mode 100644 test/files/run/reify_newimpl_48.check create mode 100644 test/files/run/reify_newimpl_48.scala create mode 100644 test/files/run/reify_newimpl_49.check create mode 100644 test/files/run/reify_newimpl_49.scala create mode 100644 test/files/run/reify_newimpl_50.check create mode 100644 test/files/run/reify_newimpl_50.scala create mode 100644 test/files/run/reify_newimpl_51.check create mode 100644 test/files/run/reify_newimpl_51.scala create mode 100644 test/files/run/reify_newimpl_52.check create mode 100644 test/files/run/reify_newimpl_52.scala create mode 100644 test/files/run/reify_typerefs_1a.check create mode 100644 test/files/run/reify_typerefs_1a.scala create mode 100644 test/files/run/reify_typerefs_1b.check create mode 100644 test/files/run/reify_typerefs_1b.scala create mode 100644 test/files/run/reify_typerefs_2a.check create mode 100644 test/files/run/reify_typerefs_2a.scala create mode 100644 test/files/run/reify_typerefs_2b.check create mode 100644 test/files/run/reify_typerefs_2b.scala create mode 100644 test/files/run/reify_typerefs_3a.check create mode 100644 test/files/run/reify_typerefs_3a.scala create mode 100644 test/files/run/reify_typerefs_3b.check create mode 100644 test/files/run/reify_typerefs_3b.scala delete mode 100644 test/files/run/t1195.check create mode 100644 test/files/run/t1195.check.temporarily.disabled delete mode 100644 test/files/run/t1195.scala create mode 100644 test/files/run/t1195.scala.temporarily.disabled create mode 100644 test/files/run/t3758.check delete mode 100644 test/files/run/t4110.check create mode 100644 test/files/run/t4110.check.temporarily.disabled delete mode 100644 test/files/run/t4110.scala create mode 100644 test/files/run/t4110.scala.temporarily.disabled delete mode 100644 test/files/run/t5258a.check delete mode 100644 test/files/run/t5258a.scala create mode 100644 test/files/run/toolbox_console_reporter.check create mode 100644 test/files/run/toolbox_console_reporter.scala create mode 100644 test/files/run/toolbox_default_reporter_is_silent.check create mode 100644 test/files/run/toolbox_default_reporter_is_silent.scala create mode 100644 test/files/run/toolbox_silent_reporter.check create mode 100644 test/files/run/toolbox_silent_reporter.scala create mode 100644 test/files/run/toolbox_typecheck_implicitsdisabled.check create mode 100644 test/files/run/toolbox_typecheck_implicitsdisabled.scala create mode 100644 test/files/run/toolbox_typecheck_macrosdisabled.check create mode 100644 test/files/run/toolbox_typecheck_macrosdisabled.scala delete mode 100644 test/files/run/treePrint.check create mode 100644 test/files/run/treePrint.check.temporarily.disabled delete mode 100644 test/files/run/treePrint.scala create mode 100644 test/files/run/treePrint.scala.temporarily.disabled create mode 100644 test/files/run/typetags_core.check create mode 100644 test/files/run/typetags_core.scala create mode 100644 test/pending/neg/reify_packed.check create mode 100644 test/pending/neg/reify_packed.scala create mode 100644 test/pending/run/macro-expand-default.flags create mode 100644 test/pending/run/macro-expand-default/Impls_1.scala create mode 100644 test/pending/run/macro-expand-default/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound.check create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound.flags create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-named.flags create mode 100644 test/pending/run/macro-expand-named/Impls_1.scala create mode 100644 test/pending/run/macro-expand-named/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1.check create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1.flags create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1.check create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1.flags create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala delete mode 100644 test/pending/run/macro-overload.check delete mode 100644 test/pending/run/macro-overload.flags delete mode 100644 test/pending/run/macro-overload/Macros_1.scala delete mode 100644 test/pending/run/macro-overload/Test_2.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-a.check create mode 100644 test/pending/run/macro-quasiinvalidbody-a.flags create mode 100644 test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-b.check create mode 100644 test/pending/run/macro-quasiinvalidbody-b.flags create mode 100644 test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala create mode 100644 test/pending/run/macro-reify-array.flags create mode 100644 test/pending/run/macro-reify-array/Macros_1.scala create mode 100644 test/pending/run/macro-reify-array/Test_2.scala create mode 100644 test/pending/run/macro-reify-eval-vs-value.flags create mode 100644 test/pending/run/macro-reify-eval-vs-value/Macros_1.scala create mode 100644 test/pending/run/macro-reify-eval-vs-value/Test_2.scala create mode 100644 test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check create mode 100644 test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala create mode 100644 test/pending/run/macro-reify-tagful-b.check create mode 100644 test/pending/run/macro-reify-tagful-b.flags create mode 100644 test/pending/run/macro-reify-tagful-b/Macros_1.scala create mode 100644 test/pending/run/macro-reify-tagful-b/Test_2.scala create mode 100644 test/pending/run/macro-reify-tagless-b.check create mode 100644 test/pending/run/macro-reify-tagless-b.flags create mode 100644 test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala create mode 100644 test/pending/run/macro-reify-tagless-b/Test_2.scala create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-notags.check create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-tags.check create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala delete mode 100644 test/pending/run/reify_classfileann_b.check delete mode 100644 test/pending/run/reify_classfileann_b.scala delete mode 100644 test/pending/run/reify_closure8b.check delete mode 100644 test/pending/run/reify_closure8b.scala create mode 100644 test/pending/run/reify_newimpl_07.scala create mode 100644 test/pending/run/reify_newimpl_08.scala create mode 100644 test/pending/run/reify_newimpl_35.scala create mode 100644 test/pending/run/reify_newimpl_46.scala create mode 100644 test/pending/run/reify_newimpl_53.scala create mode 100644 test/pending/run/t5258a.check create mode 100644 test/pending/run/t5258a.scala diff --git a/build.xml b/build.xml index 6a3bc1d4c7..29c84cd610 100644 --- a/build.xml +++ b/build.xml @@ -170,7 +170,7 @@ PROPERTIES - + diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index 0bbbea1e7b..d74b6353d9 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -f9fcb59f3dbe1b060f8c57d4463dde5e0796951f ?scala-compiler.jar +d2808836aef2cbee506f9b0b0e346c749cac9ad8 ?scala-compiler.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 703eb006da..78e9f0b593 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -1d53671b52f2052c0690fcef9c9989150d8a4704 ?scala-library.jar +752baeeb4a01c7c50ac0dc6e0f59f5598696a223 ?scala-library.jar diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala index 9a7c79d856..b86c62661a 100644 --- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala +++ b/src/compiler/scala/reflect/internal/AnnotationInfos.scala @@ -116,7 +116,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable => // Classfile annot: args empty. Scala annot: assocs empty. assert(args.isEmpty || assocs.isEmpty, atp) - // @xeno.by: necessary for reification, see Reifiers.scala for more info + // necessary for reification, see Reifiers.scala for more info private var orig: Tree = EmptyTree def original = orig def setOriginal(t: Tree): this.type = { orig = t; this } @@ -168,24 +168,15 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable => * * `assocs` stores arguments to classfile annotations as name-value pairs. */ - sealed abstract class AnnotationInfo extends Product3[Type, List[Tree], List[(Name, ClassfileAnnotArg)]] { + sealed abstract class AnnotationInfo { def atp: Type def args: List[Tree] def assocs: List[(Name, ClassfileAnnotArg)] - // @xeno.by: necessary for reification, see Reifiers.scala for more info + // necessary for reification, see Reifiers.scala for more info def original: Tree def setOriginal(t: Tree): this.type - /** Hand rolling Product. */ - def _1 = atp - def _2 = args - def _3 = assocs - // @xeno.by: original hasn't become a product member for backward compatibility purposes - // def _4 = original - def canEqual(other: Any) = other.isInstanceOf[AnnotationInfo] - override def productPrefix = "AnnotationInfo" - // see annotationArgRewriter lazy val isTrivial = atp.isTrivial && !hasArgWhich(_.isInstanceOf[This]) @@ -270,7 +261,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable => } lazy val classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] = - reflect.ClassManifest.classType(classOf[ClassfileAnnotArg]) + reflect.ClassManifest[ClassfileAnnotArg](classOf[ClassfileAnnotArg]) object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil) } diff --git a/src/compiler/scala/reflect/internal/CapturedVariables.scala b/src/compiler/scala/reflect/internal/CapturedVariables.scala new file mode 100644 index 0000000000..77909d9157 --- /dev/null +++ b/src/compiler/scala/reflect/internal/CapturedVariables.scala @@ -0,0 +1,36 @@ +package scala.reflect +package internal + +import Flags._ + +trait CapturedVariables { self: SymbolTable => + + import definitions._ + + /** Mark a variable as captured; i.e. force boxing in a *Ref type. + */ + def captureVariable(vble: Symbol): Unit = vble setFlag CAPTURED + + /** Mark given identifier as a reference to a captured variable itself + * suppressing dereferencing with the `elem` field. + */ + def referenceCapturedVariable(vble: Symbol): Tree = ReferenceToBoxed(Ident(vble)) + + /** Convert type of a captured variable to *Ref type. + */ + def capturedVariableType(vble: Symbol): Type = + capturedVariableType(vble, NoType, false) + + /** Convert type of a captured variable to *Ref type. + */ + def capturedVariableType(vble: Symbol, tpe: Type = NoType, erasedTypes: Boolean = false): Type = { + val tpe1 = if (tpe == NoType) vble.tpe else tpe + val symClass = tpe1.typeSymbol + def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) = + if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe + else if (erasedTypes) objectRefClass.tpe + else appliedType(objectRefClass, tpe) + if (vble.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass) + else refType(refClass, ObjectRefClass) + } +} diff --git a/src/compiler/scala/reflect/internal/Constants.scala b/src/compiler/scala/reflect/internal/Constants.scala index c328cc49cb..135d18d5ad 100644 --- a/src/compiler/scala/reflect/internal/Constants.scala +++ b/src/compiler/scala/reflect/internal/Constants.scala @@ -26,7 +26,7 @@ trait Constants extends api.Constants { final val DoubleTag = 9 final val StringTag = 10 final val NullTag = 11 - final val ClassTag = 12 + final val ClazzTag = 12 // For supporting java enumerations inside java annotations (see ClassfileParser) final val EnumTag = 13 @@ -43,7 +43,7 @@ trait Constants extends api.Constants { case x: Double => DoubleTag case x: String => StringTag case x: Char => CharTag - case x: Type => ClassTag + case x: Type => ClazzTag case x: Symbol => EnumTag case _ => throw new Error("bad constant value: " + value + " of class " + value.getClass) } @@ -70,7 +70,7 @@ trait Constants extends api.Constants { case DoubleTag => DoubleClass.tpe case StringTag => StringClass.tpe case NullTag => NullClass.tpe - case ClassTag => ClassType(value.asInstanceOf[Type]) + case ClazzTag => ClassType(value.asInstanceOf[Type]) case EnumTag => // given (in java): "class A { enum E { VAL1 } }" // - symbolValue: the symbol of the actual enumeration value (VAL1) @@ -201,7 +201,7 @@ trait Constants extends api.Constants { def stringValue: String = if (value == null) "null" - else if (tag == ClassTag) signature(typeValue) + else if (tag == ClazzTag) signature(typeValue) else value.toString() @switch def escapedChar(ch: Char): String = ch match { @@ -221,7 +221,7 @@ trait Constants extends api.Constants { tag match { case NullTag => "null" case StringTag => "\"" + escape(stringValue) + "\"" - case ClassTag => "classOf[" + signature(typeValue) + "]" + case ClazzTag => "classOf[" + signature(typeValue) + "]" case CharTag => "'" + escapedChar(charValue) + "'" case LongTag => longValue.toString() + "L" case _ => String.valueOf(value) diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 6ef6751720..b1c822ed97 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -10,10 +10,29 @@ import annotation.{ switch } import scala.collection.{ mutable, immutable } import Flags._ import PartialFunction._ +import scala.reflect.{ mirror => rm } trait Definitions extends reflect.api.StandardDefinitions { self: SymbolTable => + // [Eugene] find a way to make these non-lazy + lazy val ByteTpe = definitions.ByteClass.asType + lazy val ShortTpe = definitions.ShortClass.asType + lazy val CharTpe = definitions.CharClass.asType + lazy val IntTpe = definitions.IntClass.asType + lazy val LongTpe = definitions.LongClass.asType + lazy val FloatTpe = definitions.FloatClass.asType + lazy val DoubleTpe = definitions.DoubleClass.asType + lazy val BooleanTpe = definitions.BooleanClass.asType + lazy val UnitTpe = definitions.UnitClass.asType + lazy val AnyTpe = definitions.AnyClass.asType + lazy val ObjectTpe = definitions.ObjectClass.asType + lazy val AnyValTpe = definitions.AnyValClass.asType + lazy val AnyRefTpe = definitions.AnyRefClass.asType + lazy val NothingTpe = definitions.NothingClass.asType + lazy val NullTpe = definitions.NullClass.asType + lazy val StringTpe = definitions.StringClass.asType + /** 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). @@ -129,6 +148,7 @@ trait Definitions extends reflect.api.StandardDefinitions { DoubleClass ) def ScalaValueClassCompanions: List[Symbol] = ScalaValueClasses map (_.companionSymbol) + def ScalaPrimitiveValueClasses: List[Symbol] = ScalaValueClasses } object definitions extends AbsDefinitions with ValueClassDefinitions { @@ -446,19 +466,38 @@ trait Definitions extends reflect.api.StandardDefinitions { def methodCache_add = getMember(MethodCacheClass, nme.add_) // scala.reflect - lazy val ReflectApiUniverse = getRequiredClass("scala.reflect.api.Universe") - lazy val ReflectMacroContext = getRequiredClass("scala.reflect.macro.Context") - lazy val ReflectRuntimeMirror = getRequiredModule("scala.reflect.runtime.Mirror") - def freeValueMethod = getMember(ReflectRuntimeMirror, nme.freeValue) + lazy val ReflectPackageClass = getMember(ScalaPackageClass, nme.reflect) lazy val ReflectPackage = getPackageObject("scala.reflect") def Reflect_mirror = getMember(ReflectPackage, nme.mirror) - lazy val PartialManifestClass = getRequiredClass("scala.reflect.ClassManifest") - lazy val PartialManifestModule = getRequiredModule("scala.reflect.ClassManifest") - lazy val FullManifestClass = getRequiredClass("scala.reflect.Manifest") - lazy val FullManifestModule = getRequiredModule("scala.reflect.Manifest") - lazy val OptManifestClass = getRequiredClass("scala.reflect.OptManifest") - lazy val NoManifest = getRequiredModule("scala.reflect.NoManifest") + lazy val ExprClass = getMember(getRequiredClass("scala.reflect.api.Exprs"), tpnme.Expr) + def ExprTree = getMember(ExprClass, nme.tree) + def ExprTpe = getMember(ExprClass, nme.tpe) + def ExprEval = getMember(ExprClass, nme.eval) + def ExprValue = getMember(ExprClass, nme.value) + lazy val ExprModule = getMember(getRequiredClass("scala.reflect.api.Exprs"), nme.Expr) + + lazy val ClassTagClass = getRequiredClass("scala.reflect.ClassTag") + def ClassTagErasure = getMember(ClassTagClass, nme.erasure) + def ClassTagTpe = getMember(ClassTagClass, nme.tpe) + lazy val ClassTagModule = getRequiredModule("scala.reflect.ClassTag") + lazy val TypeTagsClass = getRequiredClass("scala.reflect.api.TypeTags") + lazy val TypeTagClass = getMember(TypeTagsClass, tpnme.TypeTag) + def TypeTagTpe = getMember(TypeTagClass, nme.tpe) + lazy val TypeTagModule = getMember(TypeTagsClass, nme.TypeTag) + lazy val GroundTypeTagClass = getMember(TypeTagsClass, tpnme.GroundTypeTag) + lazy val GroundTypeTagModule = getMember(TypeTagsClass, nme.GroundTypeTag) + + lazy val MacroContextClass = getRequiredClass("scala.reflect.makro.Context") + def MacroContextPrefix = getMember(MacroContextClass, nme.prefix) + def MacroContextPrefixType = getMember(MacroContextClass, tpnme.PrefixType) + def MacroContextMirror = getMember(MacroContextClass, nme.mirror) + def MacroContextReify = getMember(MacroContextClass, nme.reify) + lazy val MacroImplAnnotation = getRequiredClass("scala.reflect.makro.internal.macroImpl") + lazy val MacroInternalPackage = getPackageObject("scala.reflect.makro.internal") + def MacroInternal_materializeClassTag = getMember(MacroInternalPackage, nme.materializeClassTag) + def MacroInternal_materializeTypeTag = getMember(MacroInternalPackage, nme.materializeTypeTag) + def MacroInternal_materializeGroundTypeTag = getMember(MacroInternalPackage, nme.materializeGroundTypeTag) lazy val ScalaSignatureAnnotation = getRequiredClass("scala.reflect.ScalaSignature") lazy val ScalaLongSignatureAnnotation = getRequiredClass("scala.reflect.ScalaLongSignature") @@ -467,33 +506,15 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val OptionClass: Symbol = getRequiredClass("scala.Option") lazy val SomeClass: Symbol = getRequiredClass("scala.Some") lazy val NoneModule: Symbol = getRequiredModule("scala.None") + lazy val SomeModule: Symbol = getRequiredModule("scala.Some") - /** Note: don't use this manifest/type function for anything important, - * as it is incomplete. Would love to have things like existential types - * working, but very unfortunately the manifests just stuff the relevant - * information into the toString method. - */ - def manifestToType(m: OptManifest[_]): Type = m match { - case m: ClassManifest[_] => - val sym = manifestToSymbol(m) - val args = m.typeArguments + // [Eugene] how do I make this work without casts? + // private lazy val importerFromRm = self.mkImporter(rm) + private lazy val importerFromRm = self.mkImporter(rm).asInstanceOf[self.Importer { val from: rm.type }] - if ((sym eq NoSymbol) || args.isEmpty) sym.tpe - else appliedType(sym, args map manifestToType: _*) - case _ => - NoType - } + def manifestToType(m: Manifest[_]): Type = importerFromRm.importType(m.tpe) - def manifestToSymbol(m: ClassManifest[_]): Symbol = m match { - case x: scala.reflect.AnyValManifest[_] => - getMember(ScalaPackageClass, newTypeName("" + x)) - case _ => - val name = m.erasure.getName - if (name endsWith nme.MODULE_SUFFIX_STRING) - getModuleIfDefined(name stripSuffix nme.MODULE_SUFFIX_STRING) - else - getClassIfDefined(name) - } + def manifestToSymbol(m: Manifest[_]): Symbol = importerFromRm.importSymbol(m.tpe.typeSymbol) // The given symbol represents either String.+ or StringAdd.+ def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+ @@ -527,11 +548,6 @@ trait Definitions extends reflect.api.StandardDefinitions { } val MaxTupleArity, MaxProductArity, MaxFunctionArity = 22 - /** The maximal dimensions of a generic array creation. - * I.e. new Array[Array[Array[Array[Array[T]]]]] creates a 5 times - * nested array. More is not allowed. - */ - val MaxArrayDims = 5 lazy val ProductClass = { val arr = mkArityArray("Product", MaxProductArity) ; arr(0) = UnitClass ; arr } lazy val TupleClass = mkArityArray("Tuple", MaxTupleArity) lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0) @@ -993,7 +1009,7 @@ trait Definitions extends reflect.api.StandardDefinitions { } def getDeclIfDefined(owner: Symbol, name: Name): Symbol = owner.info.nonPrivateDecl(name) - + def packageExists(packageName: String): Boolean = getModuleIfDefined(packageName).isPackage diff --git a/src/compiler/scala/reflect/internal/FreeVars.scala b/src/compiler/scala/reflect/internal/FreeVars.scala new file mode 100644 index 0000000000..8b6e8b61f3 --- /dev/null +++ b/src/compiler/scala/reflect/internal/FreeVars.scala @@ -0,0 +1,60 @@ +package scala.reflect +package internal + +trait FreeVars extends api.FreeVars { + self: SymbolTable => + + object FreeTerm extends FreeTermExtractor { + def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] = + Some(freeTerm.name, freeTerm.info, freeTerm.value, freeTerm.origin) + } + + object FreeType extends FreeTypeExtractor { + def unapply(freeType: FreeType): Option[(TypeName, Type, String)] = + Some(freeType.name, freeType.info, freeType.origin) + } + + // [Eugene] am I doing this right? + def freeTerms(tree: Tree): List[FreeTerm] = { + def isFreeTermSym(sym: Symbol) = sym != null && sym.isFreeTerm + def isFreeTermTpe(t: Type) = t != null && isFreeTermSym(t.termSymbol) + + val buf = collection.mutable.Set[Symbol]() + tree foreach (sub => { + if (sub.tpe != null) buf ++= (sub.tpe collect { case tpe if isFreeTermTpe(tpe) => tpe.typeSymbol }) + if (sub.symbol != null && isFreeTermSym(sub.symbol)) buf += sub.symbol + }) + + buf.toList.collect{ case fty: FreeTerm => fty } + } + + // [Eugene] am I doing this right? + def freeTypes(tree: Tree): List[FreeType] = { + def isFreeTypeSym(sym: Symbol) = sym != null && sym.isFreeType + def isFreeTypeTpe(t: Type) = t != null && isFreeTypeSym(t.typeSymbol) + + val buf = collection.mutable.Set[Symbol]() + tree foreach (sub => { + if (sub.tpe != null) buf ++= (sub.tpe collect { case tpe if isFreeTypeTpe(tpe) => tpe.typeSymbol }) + if (sub.symbol != null && isFreeTypeSym(sub.symbol)) buf += sub.symbol + }) + + buf.toList.collect{ case fty: FreeType => fty } + } + + // todo. also update tpe's of dependent free vars + // e.g. if we substitute free$C, then free$C$this should have its info updated + // todo. should also transform typetags of types dependent on that free type? + // [Eugene] how do I check that the substitution is legal w.r.t fty.info? + def substituteFreeTypes(tree0: Tree, subs: Map[FreeType, Type]): Tree = { + val tree = tree0.duplicate + new TreeTypeSubstituter(subs.keys.toList, subs.values.toList).traverse(tree) + tree + } + + // [Eugene] how do I check that the substitution is legal w.r.t fty.info? + def substituteFreeTypes(tpe0: Type, subs: Map[FreeType, Type]): Type = { + val tpe = tpe0 // [Eugene] tpe0.duplicate? + tpe.subst(subs.keys.toList, subs.values.toList) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index c9336e8cf1..ab5e19fca9 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -4,7 +4,24 @@ import scala.collection.mutable.WeakHashMap trait Importers { self: SymbolTable => - abstract class Importer { + // [Eugene] possible to make this less cast-heavy? + def mkImporter(from0: api.Universe): Importer { val from: from0.type } = ( + if (self eq from0) { + new Importer { + val from = from0 + val reverse = this.asInstanceOf[from.Importer{ val from: self.type }] + def importSymbol(sym: from.Symbol) = sym.asInstanceOf[self.Symbol] + def importType(tpe: from.Type) = tpe.asInstanceOf[self.Type] + def importTree(tree: from.Tree) = tree.asInstanceOf[self.Tree] + } + } else { + // todo. fix this loophole + assert(from0.isInstanceOf[SymbolTable], "`from` should be an instance of scala.reflect.internal.SymbolTable") + new StandardImporter { val from = from0.asInstanceOf[SymbolTable] } + } + ).asInstanceOf[Importer { val from: from0.type }] + + abstract class StandardImporter extends Importer { val from: SymbolTable @@ -24,13 +41,15 @@ trait Importers { self: SymbolTable => } } - object reverse extends from.Importer { + object reverse extends from.StandardImporter { val from: self.type = self - for ((fromsym, mysym) <- Importer.this.symMap) symMap += ((mysym, fromsym)) - for ((fromtpe, mytpe) <- Importer.this.tpeMap) tpeMap += ((mytpe, fromtpe)) + for ((fromsym, mysym) <- StandardImporter.this.symMap) symMap += ((mysym, fromsym)) + for ((fromtpe, mytpe) <- StandardImporter.this.tpeMap) tpeMap += ((mytpe, fromtpe)) } - def importPosition(pos: from.Position): Position = NoPosition + // todo. careful import of positions + def importPosition(pos: from.Position): Position = + pos.asInstanceOf[Position] def importSymbol(sym0: from.Symbol): Symbol = { def doImport(sym: from.Symbol): Symbol = { @@ -51,8 +70,10 @@ trait Importers { self: SymbolTable => linkReferenced(myowner.newMethod(myname, mypos, myflags), x, importSymbol) case x: from.ModuleSymbol => linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol) - case x: from.FreeVar => - newFreeVar(importName(x.name).toTermName, importType(x.tpe), x.value, myflags) + case x: from.FreeTerm => + newFreeTerm(importName(x.name).toTermName, importType(x.info), x.value, x.origin, myflags) + case x: from.FreeType => + newFreeType(importName(x.name).toTypeName, importType(x.info), x.value, x.origin, myflags) case x: from.TermSymbol => linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol) case x: from.TypeSkolem => @@ -374,6 +395,8 @@ trait Importers { self: SymbolTable => case _ => new Ident(importName(name)) } + case from.ReferenceToBoxed(ident) => + new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident }) case from.Literal(constant @ from.Constant(_)) => new Literal(importConstant(constant)) case from.TypeTree() => @@ -425,7 +448,7 @@ trait Importers { self: SymbolTable => def importIdent(tree: from.Ident): Ident = importTree(tree).asInstanceOf[Ident] def importCaseDef(tree: from.CaseDef): CaseDef = importTree(tree).asInstanceOf[CaseDef] def importConstant(constant: from.Constant): Constant = new Constant(constant.tag match { - case ClassTag => importType(constant.value.asInstanceOf[from.Type]) + case ClazzTag => importType(constant.value.asInstanceOf[from.Type]) case EnumTag => importSymbol(constant.value.asInstanceOf[from.Symbol]) case _ => constant.value }) diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala index 05578a2042..ac22017569 100644 --- a/src/compiler/scala/reflect/internal/NameManglers.scala +++ b/src/compiler/scala/reflect/internal/NameManglers.scala @@ -128,12 +128,7 @@ trait NameManglers { else name ) - def macroMethodName(name: Name) = { - val base = if (name.isTypeName) nme.TYPEkw else nme.DEFkw - base append nme.MACRO append name - } - - /** Return the original name and the types on which this name + /** Return the original name and the types on which this name * is specialized. For example, * {{{ * splitSpecializedName("foo$mIcD$sp") == ('foo', "I", "D") diff --git a/src/compiler/scala/reflect/internal/Positions.scala b/src/compiler/scala/reflect/internal/Positions.scala index 78de8d0ff2..5ec2659098 100644 --- a/src/compiler/scala/reflect/internal/Positions.scala +++ b/src/compiler/scala/reflect/internal/Positions.scala @@ -3,9 +3,8 @@ package internal trait Positions extends api.Positions { self: SymbolTable => - def focusPos(pos: Position): Position - def isRangePos(pos: Position): Boolean - def showPos(pos: Position): String + type Position = scala.tools.nsc.util.Position + val NoPosition = scala.tools.nsc.util.NoPosition /** A position that wraps a set of trees. * The point of the wrapping position is the point of the default position. @@ -27,4 +26,37 @@ trait Positions extends api.Positions { self: SymbolTable => * to some of the nodes in `tree`. */ def ensureNonOverlapping(tree: Tree, others: List[Tree]) {} + + trait PosAssigner extends Traverser { + var pos: Position + } + protected[this] lazy val posAssigner: PosAssigner = new DefaultPosAssigner + + protected class DefaultPosAssigner extends PosAssigner { + var pos: Position = _ + override def traverse(t: Tree) { + if (t eq EmptyTree) () + else if (t.pos == NoPosition) { + t.setPos(pos) + super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if? + // @PP: it's pruning whenever it encounters a node with a + // position, which I interpret to mean that (in the author's + // mind at least) either the children of a positioned node will + // already be positioned, or the children of a positioned node + // do not merit positioning. + // + // Whatever the author's rationale, it does seem like a bad idea + // to press on through a positioned node to find unpositioned + // children beneath it and then to assign whatever happens to + // be in `pos` to such nodes. There are supposed to be some + // position invariants which I can't imagine surviving that. + } + } + } + + def atPos[T <: Tree](pos: Position)(tree: T): T = { + posAssigner.pos = pos + posAssigner.traverse(tree) + tree + } } \ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/Reporters.scala b/src/compiler/scala/reflect/internal/Reporters.scala new file mode 100644 index 0000000000..20d4a1d026 --- /dev/null +++ b/src/compiler/scala/reflect/internal/Reporters.scala @@ -0,0 +1,74 @@ +package scala.reflect +package internal + +trait Reporters { self: SymbolTable => + + import self.{Reporter => ApiReporter} + import scala.tools.nsc.reporters._ + import scala.tools.nsc.reporters.{Reporter => NscReporter} + import scala.tools.nsc.Settings + + def mkConsoleReporter(minSeverity: Int = 1): ApiReporter = { + val settings = new Settings() + if (minSeverity <= 0) settings.verbose.value = true + if (minSeverity > 1) settings.nowarn.value = true + wrapNscReporter(new ConsoleReporter(settings)) + } + + abstract class ApiToNscReporterProxy(val apiReporter: ApiReporter) extends AbstractReporter { + import apiReporter.{Severity => ApiSeverity} + val API_INFO = apiReporter.INFO + val API_WARNING = apiReporter.WARNING + val API_ERROR = apiReporter.ERROR + + type NscSeverity = Severity + val NSC_INFO = INFO + val NSC_WARNING = WARNING + val NSC_ERROR = ERROR + + def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit = + apiReporter.log(pos, msg, nscSeverity match { + case NSC_INFO => API_INFO + case NSC_WARNING => API_WARNING + case NSC_ERROR => API_ERROR + }) + + def displayPrompt(): Unit = + apiReporter.interactive() + } + + def wrapApiReporter(apiReporter: ApiReporter): NscReporter = new ApiToNscReporterProxy(apiReporter) { + val settings = new Settings() + settings.verbose.value = true + settings.nowarn.value = false + } + + class NscToApiReporterProxy(val nscReporter: NscReporter) extends ApiReporter { + val API_INFO = INFO + val API_WARNING = WARNING + val API_ERROR = ERROR + + def display(info: Info): Unit = info.severity match { + case API_INFO => nscReporter.info(info.pos, info.msg, false) + case API_WARNING => nscReporter.warning(info.pos, info.msg) + case API_ERROR => nscReporter.error(info.pos, info.msg) + } + + def interactive(): Unit = nscReporter match { + case nscReporter: AbstractReporter => nscReporter.displayPrompt() + case _ => // do nothing + } + + override def flush(): Unit = { + super.flush() + nscReporter.flush() + } + + override def reset(): Unit = { + super.reset() + nscReporter.reset() + } + } + + def wrapNscReporter(nscReporter: NscReporter): ApiReporter = new NscToApiReporterProxy(nscReporter) +} diff --git a/src/compiler/scala/reflect/internal/Required.scala b/src/compiler/scala/reflect/internal/Required.scala index 1bf1a2e97e..ba6d65a306 100644 --- a/src/compiler/scala/reflect/internal/Required.scala +++ b/src/compiler/scala/reflect/internal/Required.scala @@ -12,8 +12,6 @@ trait Required { self: SymbolTable => def picklerPhase: Phase - val gen: TreeGen { val global: Required.this.type } - def settings: MutableSettings def forInteractive: Boolean diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 0cd3616ba9..b72610f1e0 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -44,6 +44,7 @@ trait StdNames extends NameManglers { self: SymbolTable => final val IMPLICITkw: TermName = kw("implicit") final val IMPORTkw: TermName = kw("import") final val LAZYkw: TermName = kw("lazy") + final val MACROkw: TermName = kw("macro") final val MATCHkw: TermName = kw("match") final val NEWkw: TermName = kw("new") final val NULLkw: TermName = kw("null") @@ -123,6 +124,9 @@ trait StdNames extends NameManglers { self: SymbolTable => final val List: NameType = "List" final val Seq: NameType = "Seq" final val Symbol: NameType = "Symbol" + final val ClassTag: NameType = "ClassTag" + final val TypeTag : NameType = "TypeTag" + final val GroundTypeTag: NameType = "GroundTypeTag" // fictions we use as both types and terms final val ERROR: NameType = "" @@ -140,10 +144,12 @@ trait StdNames extends NameManglers { self: SymbolTable => final val Any: NameType = "Any" final val AnyVal: NameType = "AnyVal" + final val Expr: NameType = "Expr" final val Nothing: NameType = "Nothing" final val Null: NameType = "Null" final val Object: NameType = "Object" final val PartialFunction: NameType = "PartialFunction" + final val PrefixType: NameType = "PrefixType" final val Product: NameType = "Product" final val Serializable: NameType = "Serializable" final val Singleton: NameType = "Singleton" @@ -185,32 +191,34 @@ trait StdNames extends NameManglers { self: SymbolTable => trait TermNames extends Keywords with CommonNames { // Compiler internal names - val EXPAND_SEPARATOR_STRING = "$$" - - val ANYNAME: NameType = "" - val CONSTRUCTOR: NameType = "" - val FAKE_LOCAL_THIS: NameType = "this$" - val INITIALIZER: NameType = CONSTRUCTOR // Is this buying us something? - val LAZY_LOCAL: NameType = "$lzy" - val LOCAL_SUFFIX_STRING = " " - val MACRO: NameType = "macro$" - val MIRROR_PREFIX: NameType = "$mr." - val MIRROR_SHORT: NameType = "$mr" - val MIXIN_CONSTRUCTOR: NameType = "$init$" - val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$" - val OUTER: NameType = "$outer" - val OUTER_LOCAL: NameType = OUTER + LOCAL_SUFFIX_STRING // "$outer ", note the space - val OUTER_SYNTH: NameType = "" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter - val SELECTOR_DUMMY: NameType = "" - val SELF: NameType = "$this" - val SPECIALIZED_INSTANCE: NameType = "specInstance$" - val STAR: NameType = "*" - val THIS: NameType = "_$this" - - final val Nil: NameType = "Nil" - final val Predef: NameType = "Predef" - final val ScalaRunTime: NameType = "ScalaRunTime" - final val Some: NameType = "Some" + val EXPAND_SEPARATOR_STRING = "$$" + + val ANYNAME: NameType = "" + val CONSTRUCTOR: NameType = "" + val FAKE_LOCAL_THIS: NameType = "this$" + val INITIALIZER: NameType = CONSTRUCTOR // Is this buying us something? + val LAZY_LOCAL: NameType = "$lzy" + val LOCAL_SUFFIX_STRING = " " + val MIRROR_PREFIX: NameType = "$mr." + val MIRROR_SHORT: NameType = "$mr" + val MIRROR_FREE_PREFIX: NameType = "free$" + val MIRROR_FREE_THIS_SUFFIX: NameType = "$this" + val MIRROR_FREE_VALUE_SUFFIX: NameType = "$value" + val MIXIN_CONSTRUCTOR: NameType = "$init$" + val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$" + val OUTER: NameType = "$outer" + val OUTER_LOCAL: NameType = OUTER + LOCAL_SUFFIX_STRING // "$outer ", note the space + val OUTER_SYNTH: NameType = "" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter + val SELECTOR_DUMMY: NameType = "" + val SELF: NameType = "$this" + val SPECIALIZED_INSTANCE: NameType = "specInstance$" + val STAR: NameType = "*" + val THIS: NameType = "_$this" + + final val Nil: NameType = "Nil" + final val Predef: NameType = "Predef" + final val ScalaRunTime: NameType = "ScalaRunTime" + final val Some: NameType = "Some" val _1 : NameType = "_1" val _2 : NameType = "_2" @@ -260,6 +268,8 @@ trait StdNames extends NameManglers { self: SymbolTable => case _ => newTermName("x$" + i) } + // [Eugene to Paul] see comments in StandardNames.scala to find out why's this here + val QQQ = ??? val ??? = encode("???") val wrapRefArray: NameType = "wrapRefArray" @@ -275,12 +285,38 @@ trait StdNames extends NameManglers { self: SymbolTable => val genericWrapArray: NameType = "genericWrapArray" // Compiler utilized names - // val productElementName: NameType = "productElementName" + + val AnnotatedType: NameType = "AnnotatedType" + val AnnotationInfo: NameType = "AnnotationInfo" + val Any: NameType = "Any" + val AnyVal: NameType = "AnyVal" + val Apply: NameType = "Apply" + val ArrayAnnotArg: NameType = "ArrayAnnotArg" + val ConstantType: NameType = "ConstantType" + val EmptyPackage: NameType = "EmptyPackage" + val EmptyPackageClass: NameType = "EmptyPackageClass" + val Expr: NameType = "Expr" val Ident: NameType = "Ident" + val Import: NameType = "Import" + val Literal: NameType = "Literal" + val LiteralAnnotArg: NameType = "LiteralAnnotArg" + val NestedAnnotArg: NameType = "NestedAnnotArg" + val NoPrefix: NameType = "NoPrefix" + val NoSymbol: NameType = "NoSymbol" + val Nothing: NameType = "Nothing" + val NoType: NameType = "NoType" + val Null: NameType = "Null" + val Object: NameType = "Object" + val RootPackage: NameType = "RootPackage" + val RootClass: NameType = "RootClass" + val Select: NameType = "Select" val StringContext: NameType = "StringContext" val This: NameType = "This" val Tree : NameType = "Tree" + val Tuple2: NameType = "Tuple2" val TYPE_ : NameType = "TYPE" + val TypeApply: NameType = "TypeApply" + val TypeRef: NameType = "TypeRef" val TypeTree: NameType = "TypeTree" val UNIT : NameType = "UNIT" val add_ : NameType = "add" @@ -311,6 +347,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val clone_ : NameType = if (forMSIL) "MemberwiseClone" else "clone" // sn.OClone causes checkinit failure val conforms: NameType = "conforms" val copy: NameType = "copy" + val definitions: NameType = "definitions" val delayedInit: NameType = "delayedInit" val delayedInitArg: NameType = "delayedInit$body" val drop: NameType = "drop" @@ -322,7 +359,9 @@ trait StdNames extends NameManglers { self: SymbolTable => val equalsNumNum : NameType = "equalsNumNum" val equalsNumObject : NameType = "equalsNumObject" val equals_ : NameType = if (forMSIL) "Equals" else "equals" + val erasure: NameType = "erasure" val error: NameType = "error" + val eval: NameType = "eval" val ex: NameType = "ex" val false_ : NameType = "false" val filter: NameType = "filter" @@ -330,7 +369,6 @@ trait StdNames extends NameManglers { self: SymbolTable => val find_ : NameType = "find" val flatMap: NameType = "flatMap" val foreach: NameType = "foreach" - val freeValue : NameType = "freeValue" val genericArrayOps: NameType = "genericArrayOps" val get: NameType = "get" val getOrElse: NameType = "getOrElse" @@ -339,6 +377,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val hash_ : NameType = "hash" val head: NameType = "head" val identity: NameType = "identity" + val info: NameType = "info" val inlinedEquals: NameType = "inlinedEquals" val isArray: NameType = "isArray" val isDefinedAt: NameType = "isDefinedAt" @@ -350,36 +389,54 @@ trait StdNames extends NameManglers { self: SymbolTable => val lang: NameType = "lang" val length: NameType = "length" val lengthCompare: NameType = "lengthCompare" - val lift_ : NameType = "lift" - val macro_ : NameType = "macro" val macroThis : NameType = "_this" - val macroContext : NameType = "_context" + val macroContext : NameType = "c" val main: NameType = "main" + val manifest: NameType = "manifest" val map: NameType = "map" + val materializeClassTag: NameType = "materializeClassTag" + val materializeTypeTag: NameType = "materializeTypeTag" + val materializeGroundTypeTag: NameType = "materializeGroundTypeTag" val mirror : NameType = "mirror" + val moduleClass : NameType = "moduleClass" + val name: NameType = "name" val ne: NameType = "ne" val newArray: NameType = "newArray" + val newFreeTerm: NameType = "newFreeTerm" + val newFreeType: NameType = "newFreeType" + val newNestedSymbol: NameType = "newNestedSymbol" val newScopeWith: NameType = "newScopeWith" + val nmeNewTermName: NameType = "newTermName" + val nmeNewTypeName: NameType = "newTypeName" val next: NameType = "next" val notifyAll_ : NameType = "notifyAll" val notify_ : NameType = "notify" val null_ : NameType = "null" val ofDim: NameType = "ofDim" + val origin: NameType = "origin" + val prefix : NameType = "prefix" val productArity: NameType = "productArity" val productElement: NameType = "productElement" val productIterator: NameType = "productIterator" val productPrefix: NameType = "productPrefix" val readResolve: NameType = "readResolve" + val reflect : NameType = "reflect" + val reify : NameType = "reify" val runOrElse: NameType = "runOrElse" val runtime: NameType = "runtime" val sameElements: NameType = "sameElements" val scala_ : NameType = "scala" + val selectOverloadedMethod: NameType = "selectOverloadedMethod" + val selectTerm: NameType = "selectTerm" + val selectType: NameType = "selectType" val self: NameType = "self" val setAccessible: NameType = "setAccessible" val setAnnotations: NameType = "setAnnotations" val setSymbol: NameType = "setSymbol" val setType: NameType = "setType" val setTypeSignature: NameType = "setTypeSignature" + val staticClass : NameType = "staticClass" + val staticModule : NameType = "staticModule" val synchronized_ : NameType = "synchronized" val tail: NameType = "tail" val thisModuleType: NameType = "thisModuleType" @@ -390,6 +447,8 @@ trait StdNames extends NameManglers { self: SymbolTable => val toObjectArray : NameType = "toObjectArray" val toSeq: NameType = "toSeq" val toString_ : NameType = if (forMSIL) "ToString" else "toString" + val tpe : NameType = "tpe" + val tree : NameType = "tree" val true_ : NameType = "true" val typedProductIterator: NameType = "typedProductIterator" val unapply: NameType = "unapply" @@ -582,9 +641,14 @@ trait StdNames extends NameManglers { self: SymbolTable => val ZOR = encode("||") // unary operators + // [Eugene to Paul] see comments in StandardNames.scala to find out why's this here + val UNARY_TILDE = UNARY_~ val UNARY_~ = encode("unary_~") + val UNARY_PLUS = UNARY_+ val UNARY_+ = encode("unary_+") + val UNARY_MINUS = UNARY_- val UNARY_- = encode("unary_-") + val UNARY_NOT = UNARY_! val UNARY_! = encode("unary_!") // Grouped here so Cleanup knows what tests to perform. diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 83a24dce68..ffc8178528 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -16,6 +16,7 @@ abstract class SymbolTable extends api.Universe with SymbolCreations with Symbols with SymbolFlags + with FreeVars with Types with Kinds with ExistentialsAndSkolems @@ -34,6 +35,9 @@ abstract class SymbolTable extends api.Universe with TypeDebugging with Importers with Required + with TreeBuildUtil + with Reporters + with CapturedVariables { def rootLoader: LazyType def log(msg: => AnyRef): Unit @@ -158,7 +162,7 @@ abstract class SymbolTable extends api.Universe try op finally popPhase(saved) } - + /** Since when it is to be "at" a phase is inherently ambiguous, * a couple unambiguously named methods. diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 04bdb0f4ad..fc94e96acd 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -45,10 +45,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => m } - /** Create a new free variable. Its owner is NoSymbol. + /** Create a new free term. Its owner is NoSymbol. */ - def newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar = - new FreeVar(name, value) initFlags newFlags setInfo tpe + def newFreeTerm(name: TermName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeTerm = + new FreeTerm(name, value, origin) initFlags newFlags setInfo info + + /** Create a new free type. Its owner is NoSymbol. + */ + def newFreeType(name: TypeName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeType = + new FreeType(name, value, origin) initFlags newFlags setInfo info /** The original owner of a class. Used by the backend to generate * EnclosingMethod attributes. @@ -58,6 +63,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => abstract class AbsSymbolImpl extends AbsSymbol { this: Symbol => + def kind: String = kindString + def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { case n: TermName => newTermSymbol(n, pos, newFlags) case n: TypeName => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags) @@ -324,7 +331,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[Symbol]] = { var cnt = 0 def freshName() = { cnt += 1; nme.syntheticParamName(cnt) } - mmap(argtypess)(tp => newValueParameter(freshName(), focusPos(owner.pos), SYNTHETIC) setInfo tp) + mmap(argtypess)(tp => newValueParameter(freshName(), owner.pos.focus, SYNTHETIC) setInfo tp) } def newSyntheticTypeParam(): Symbol = newSyntheticTypeParam("T0", 0L) @@ -543,6 +550,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isTypeParameter = false def isTypeParameterOrSkolem = false def isTypeSkolem = false + def isTypeMacro = false + def isFreeType = false /** Qualities of Terms, always false for TypeSymbols. */ @@ -563,13 +572,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isValueParameter = false def isVariable = false override def hasDefault = false + def isTermMacro = false + def isFreeTerm = false /** Qualities of MethodSymbols, always false for TypeSymbols * and other TermSymbols. */ def isCaseAccessorMethod = false def isLiftedMethod = false - def isMacro = false def isMethod = false def isSourceMethod = false def isVarargsMethod = false @@ -613,11 +623,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => @inline final override def hasFlag(mask: Long): Boolean = (flags & mask) != 0 /** Does symbol have ALL the flags in `mask` set? */ @inline final override def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask - + override def setFlag(mask: Long): this.type = { _rawflags |= mask ; this } override def resetFlag(mask: Long): this.type = { _rawflags &= ~mask ; this } override def resetFlags() { rawflags &= (TopLevelCreationFlags | alwaysHasFlags) } - + /** Default implementation calls the generic string function, which * will print overloaded flags as . Subclasses * of Symbol refine. @@ -632,7 +642,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => _rawflags = mask this } - + final def flags: Long = { val fs = _rawflags & phase.flagMask (fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift) @@ -780,7 +790,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => ) final def isModuleVar = hasFlag(MODULEVAR) - /** Is this symbol static (i.e. with no outer instance)? */ + /** Is this symbol static (i.e. with no outer instance)? + * Q: When exactly is a sym marked as STATIC? + * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep. + * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6 + */ def isStatic = (this hasFlag STATIC) || owner.isStaticOwner /** Is this symbol a static constructor? */ @@ -865,6 +879,23 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isInitialized: Boolean = validTo != NoPeriod + // [Eugene] is this correct? + /** Determines whether this symbol can be loaded by subsequent reflective compilation */ + final def isLocatable: Boolean = { + if (this == NoSymbol) return false + if (isRoot || isRootPackage) return true + + if (!owner.isLocatable) return false + if (owner.isTerm) return false + + if (isType && isNonClassType) return false + return true + } + + // [Eugene] is it a good idea to add ``dealias'' to Symbol? + /** Expands type aliases */ + def dealias: Symbol = this + /** The variance of this symbol as an integer */ final def variance: Int = if (isCovariant) 1 @@ -1292,7 +1323,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * which immediately follows any of parser, namer, typer, or erasure. * In effect that means this will return one of: * - * - packageobjects (follows namer) + * - packageobjects (follows namer) * - superaccessors (follows typer) * - lazyvals (follows erasure) * - null @@ -1946,7 +1977,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Remove private modifier from symbol `sym`s definition. If `sym` is a * is not a constructor nor a static module rename it by expanding its name to avoid name clashes - * @param base the fully qualified name of this class will be appended if name expansion is needed + * @param base the fully qualified name of this class will be appended if name expansion is needed */ final def makeNotPrivate(base: Symbol) { if (this.isPrivate) { @@ -2032,8 +2063,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => private case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) private def symbolKind: SymbolKind = { - val kind = - if (isInstanceOf[FreeVar]) ("free variable", "free variable", "FV") + var kind = + if (isTermMacro) ("macro method", "macro method", "MAC") + else if (isInstanceOf[FreeTerm]) ("free term", "free term", "FTE") + else if (isInstanceOf[FreeType]) ("free type", "free type", "FTY") else if (isPackage) ("package", "package", "PK") else if (isPackageClass) ("package class", "package", "PKC") else if (isPackageObject) ("package object", "package", "PKO") @@ -2054,6 +2087,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => else if (isSourceMethod) ("method", "method", "METH") else if (isTerm) ("value", "value", "VAL") else ("", "", "???") + if (isSkolem) kind = (kind._1, kind._2, kind._3 + "#SKO") SymbolKind(kind._1, kind._2, kind._3) } @@ -2216,8 +2250,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Term symbols with the exception of static parts of Java classes and packages. */ - override def isValue = !(isModule && hasFlag(PACKAGE | JAVA)) - override def isVariable = isMutable && !isMethod + override def isValue = !(isModule && hasFlag(PACKAGE | JAVA)) + override def isVariable = isMutable && !isMethod + override def isTermMacro = hasFlag(MACRO) // interesting only for lambda lift. Captured variables are accessed from inner lambdas. override def isCapturedVariable = hasAllFlags(MUTABLE | CAPTURED) && !hasFlag(METHOD) @@ -2406,7 +2441,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isMethod = true override def isLabel = this hasFlag LABEL - override def isMacro = this hasFlag MACRO override def isVarargsMethod = this hasFlag VARARGS override def isLiftedMethod = this hasFlag LIFTED @@ -2438,6 +2472,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => extends TypeSymbol(initOwner, initPos, initName) { type TypeOfClonedSymbol = TypeSymbol final override def isAliasType = true + final override def dealias = info.typeSymbol.dealias override def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeSymbol = owner.newNonClassSymbol(name, pos, newFlags) } @@ -2469,7 +2504,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => final override def isType = true override def isNonClassType = true - + override def isTypeMacro = hasFlag(MACRO) + override def resolveOverloadedFlag(flag: Long) = flag match { case TRAIT => "" // DEFAULTPARAM case EXISTENTIAL => "" // MIXEDIN @@ -2877,7 +2913,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => abort("Can't rename a package object to " + name) } } - + trait ImplClassSymbol extends ClassSymbol { override def sourceModule = companionModule // override def isImplClass = true @@ -2913,12 +2949,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => ) } - class FreeVar(name0: TermName, val value: Any) extends TermSymbol(NoSymbol, NoPosition, name0) { - override def hashCode = if (value == null) 0 else value.hashCode - override def equals(other: Any): Boolean = other match { - case that: FreeVar => this.value.asInstanceOf[AnyRef] eq that.value.asInstanceOf[AnyRef] - case _ => false - } + class FreeTerm(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) { + def value = value0 + override def isFreeTerm = true + } + + // [Eugene] the NoSymbol origin works for type parameters. what about existential free types? + class FreeType(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) { + def value = value0 + override def isFreeType = true } /** An object representing a missing symbol */ @@ -3068,7 +3107,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def toString() = "TypeHistory(" + phaseOf(validFrom)+":"+runId(validFrom) + "," + info + "," + prev + ")" - + def toList: List[TypeHistory] = this :: ( if (prev eq null) Nil else prev.toList ) } } diff --git a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala new file mode 100644 index 0000000000..fbcd5043bc --- /dev/null +++ b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala @@ -0,0 +1,62 @@ +package scala.reflect +package internal + +trait TreeBuildUtil extends api.TreeBuildUtil { self: SymbolTable => + + // ``staticClass'' and ``staticModule'' rely on ClassLoaders + // which are implementation-specific for different Universes + + def staticClassIfDefined(fullName: String): Symbol = + try staticClass(fullName) + catch { case _: MissingRequirementError => NoSymbol } + + def staticModuleIfDefined(fullName: String): Symbol = + try staticModule(fullName) + catch { case _: MissingRequirementError => NoSymbol } + + def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.thisType + + def selectType(owner: Symbol, name: String): Symbol = + owner.info.decl(newTypeName(name)) orElse { + MissingRequirementError.notFound("type %s in %s".format(name, owner.fullName)) + } + + def selectTypeIfDefined(owner: Symbol, name: String): Symbol = + try selectType(owner, name) + catch { case _: MissingRequirementError => NoSymbol } + +// try getModule(fullname.toTermName) +// catch { case _: MissingRequirementError => NoSymbol } + + def selectTerm(owner: Symbol, name: String): Symbol = { + val sym = owner.info.decl(newTermName(name)) + val result = + if (sym.isOverloaded) sym suchThat (!_.isMethod) + else sym + result orElse { + MissingRequirementError.notFound("term %s in %s".format(name, owner.fullName)) + } + } + + def selectTermIfDefined(owner: Symbol, name: String): Symbol = + try selectTerm(owner, name) + catch { case _: MissingRequirementError => NoSymbol } + + def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol = + owner.info.decl(newTermName(name)).alternatives(index) orElse { + MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName)) + } + + def selectOverloadedMethodIfDefined(owner: Symbol, name: String, index: Int): Symbol = + try selectOverloadedMethod(owner, name, index) + catch { case _: MissingRequirementError => NoSymbol } + + def newFreeTerm(name: String, info: Type, value: => Any, origin: String) = newFreeTerm(newTermName(name), info, value, origin) + + def newFreeType(name: String, info: Type, value: => Any, origin: String) = newFreeType(newTypeName(name), info, value, origin) + + def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers = + Modifiers(flags, privateWithin, annotations) + + val gen: TreeGen { val global: TreeBuildUtil.this.type } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala index 141ff12f8a..1a374b6e59 100644 --- a/src/compiler/scala/reflect/internal/TreeGen.scala +++ b/src/compiler/scala/reflect/internal/TreeGen.scala @@ -1,7 +1,7 @@ package scala.reflect package internal -abstract class TreeGen { +abstract class TreeGen extends api.AbsTreeGen { val global: SymbolTable import global._ diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index ce3de94335..ed22cad730 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -531,4 +531,198 @@ abstract class TreeInfo { case _ => None } } + + // domain-specific extractors for reification + + import definitions._ + + object TypedOrAnnotated { + def unapply(tree: Tree): Option[Tree] = tree match { + case ty @ Typed(_, _) => + Some(ty) + case at @ Annotated(_, _) => + Some(at) + case _ => + None + } + } + + object TreeSplice { + def unapply(tree: Tree): Option[Tree] = tree match { + case Select(splicee, _) if tree.symbol == ExprEval || tree.symbol == ExprValue => + Some(splicee) + case _ => + None + } + } + + object EvalSplice { + def unapply(tree: Tree): Option[Tree] = tree match { + case Select(splicee, _) if tree.symbol == ExprEval => + Some(splicee) + case _ => + None + } + } + + object ValueSplice { + def unapply(tree: Tree): Option[Tree] = tree match { + case Select(splicee, _) if tree.symbol == ExprValue => + Some(splicee) + case _ => + None + } + } + + object Reified { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match { + case ReifiedTree(reifee, symbolTable, reified, _) => + Some(reifee, symbolTable, reified) + case ReifiedType(reifee, symbolTable, reified) => + Some(reifee, symbolTable, reified) + case _ => + None + } + } + + object ReifiedTree { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree)] = tree match { + case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(Apply(_, List(tree)), List(Apply(_, List(tpe))))) if mrDef.name == nme.MIRROR_SHORT => + Some(reifee, symbolTable map (_.asInstanceOf[ValDef]), tree, tpe) + case _ => + None + } + } + + object InlineableTreeSplice { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree, Symbol)] = tree match { + case select @ Select(ReifiedTree(splicee, symbolTable, tree, tpe), _) if select.symbol == ExprEval || select.symbol == ExprValue => + Some(splicee, symbolTable, tree, tpe, select.symbol) + case _ => + None + } + } + + object InlinedTreeSplice { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree)] = tree match { + case Select(ReifiedTree(splicee, symbolTable, tree, tpe), name) if name == ExprTree.name => + Some(splicee, symbolTable, tree, tpe) + case _ => + None + } + } + + object ReifiedType { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match { + case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(_, List(tpe))) if mrDef.name == nme.MIRROR_SHORT => + Some(reifee, symbolTable map (_.asInstanceOf[ValDef]), tpe) + case _ => + None + } + } + + object InlinedTypeSplice { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match { + case Select(ReifiedType(splicee, symbolTable, tpe), name) if name == TypeTagTpe.name => + Some(splicee, symbolTable, tpe) + case _ => + None + } + } + + object FreeDef { + def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match { + case FreeTermDef(mrRef, name, binding, origin) => + Some(mrRef, name, binding, origin) + case FreeTypeDef(mrRef, name, binding, origin) => + Some(mrRef, name, binding, origin) + case _ => + None + } + } + + object FreeTermDef { + lazy val newFreeTermMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeTerm) + + def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match { + case ValDef(_, name, _, Apply(Select(mrRef @ Ident(_), newFreeTerm), List(_, _, binding, Literal(Constant(origin: String))))) + if mrRef.name == nme.MIRROR_SHORT && newFreeTerm == newFreeTermMethod.name => + Some(mrRef, name, binding, origin) + case _ => + None + } + } + + object FreeTypeDef { + lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType) + + def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match { + case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(origin: String))))) + if mrRef1.name == nme.MIRROR_SHORT && newFreeType == newFreeTypeMethod.name => + value match { + case Apply(TypeApply(Select(Select(mrRef2 @ Ident(_), typeTag), apply), List(binding)), List(Literal(Constant(null)))) + if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag && apply == nme.apply => + Some(mrRef1, name, binding, origin) + case Apply(TypeApply(Select(mrRef2 @ Ident(_), typeTag), List(binding)), List(Literal(Constant(null)))) + if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag => + Some(mrRef1, name, binding, origin) + case _ => + throw new Error("unsupported free type def: " + showRaw(tree)) + } + case _ => + None + } + } + + object FreeRef { + def unapply(tree: Tree): Option[(Tree, TermName)] = tree match { + case Apply(Select(mrRef @ Ident(_), ident), List(Ident(name: TermName))) if ident == nme.Ident && name.startsWith(nme.MIRROR_FREE_PREFIX) => + Some(mrRef, name) + case _ => + None + } + } + + object TypeRefToFreeType { + def unapply(tree: Tree): Option[TermName] = tree match { + case Apply(Select(Select(mrRef @ Ident(_), typeRef), apply), List(Select(_, noSymbol), Ident(freeType: TermName), nil)) + if (mrRef.name == nme.MIRROR_SHORT && typeRef == nme.TypeRef && noSymbol == nme.NoSymbol && freeType.startsWith(nme.MIRROR_FREE_PREFIX)) => + Some(freeType) + case _ => + None + } + } + + object NestedExpr { + def unapply(tree: Tree): Option[(Tree, Tree, Tree)] = tree match { + case Apply(Apply(factory @ Select(expr, apply), List(tree)), List(typetag)) if expr.symbol == ExprModule && apply == nme.apply => + Some(factory, tree, typetag) + case _ => + None + } + } + + object BoundTerm { + def unapply(tree: Tree): Option[Tree] = tree match { + case Ident(name) if name.isTermName => + Some(tree) + case This(_) => + Some(tree) + case _ => + None + } + } + + object BoundType { + def unapply(tree: Tree): Option[Tree] = tree match { + case Select(_, name) if name.isTypeName => + Some(tree) + case SelectFromTypeTree(_, name) if name.isTypeName => + Some(tree) + case Ident(name) if name.isTypeName => + Some(tree) + case _ => + None + } + } } diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala index 7a084304a8..9b4c18ce86 100644 --- a/src/compiler/scala/reflect/internal/TreePrinters.scala +++ b/src/compiler/scala/reflect/internal/TreePrinters.scala @@ -23,6 +23,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => else s } def quotedName(name: Name): String = quotedName(name, false) + def quotedName(name: String): String = quotedName(newTermName(name), false) private def symNameInternal(tree: Tree, name: Name, decoded: Boolean): String = { val sym = tree.symbol @@ -31,7 +32,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => var suffix = "" if (settings.uniqid.value) suffix += ("#" + sym.id) if (settings.Yshowsymkinds.value) suffix += ("#" + sym.abbreviatedKindString) - prefix + tree.symbol.decodedName + suffix + prefix + quotedName(tree.symbol.decodedName) + suffix } else { quotedName(name, decoded) } @@ -64,7 +65,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => def indent() = indentMargin += indentStep def undent() = indentMargin -= indentStep - def printPosition(tree: Tree) = if (doPrintPositions) print(showPos(tree.pos)) + def printPosition(tree: Tree) = if (doPrintPositions) print(tree.pos.show) def println() { out.println() diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index c0d6f54b1a..0d7e68aee3 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -184,7 +184,7 @@ trait Trees extends api.Trees { self: SymbolTable => def ValDef(sym: Symbol, rhs: Tree): ValDef = atPos(sym.pos) { ValDef(Modifiers(sym.flags), sym.name.toTermName, - TypeTree(sym.tpe) setPos focusPos(sym.pos), + TypeTree(sym.tpe) setPos sym.pos.focus, rhs) setSymbol sym } @@ -203,7 +203,7 @@ trait Trees extends api.Trees { self: SymbolTable => sym.name.toTermName, sym.typeParams map TypeDef, vparamss, - TypeTree(sym.tpe.finalResultType) setPos focusPos(sym.pos), + TypeTree(sym.tpe.finalResultType) setPos sym.pos.focus, rhs) setSymbol sym } @@ -235,7 +235,8 @@ trait Trees extends api.Trees { self: SymbolTable => } /** casedef shorthand */ - def CaseDef(pat: Tree, body: Tree): CaseDef = CaseDef(pat, EmptyTree, body) + def CaseDef(pat: Tree, body: Tree): CaseDef = + CaseDef(pat, EmptyTree, body) def Bind(sym: Symbol, body: Tree): Bind = Bind(sym.name, body) setSymbol sym @@ -249,10 +250,39 @@ trait Trees extends api.Trees { self: SymbolTable => def Apply(sym: Symbol, args: Tree*): Tree = Apply(Ident(sym), args.toList) + /** Factory method for object creation `new tpt(args_1)...(args_n)` + * A `New(t, as)` is expanded to: `(new t).(as)` + */ + def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match { + case Nil => new ApplyConstructor(tpt, Nil) + case xs :: rest => rest.foldLeft(new ApplyConstructor(tpt, xs): Tree)(Apply) + } + + /** 0-1 argument list new, based on a type. + */ + def New(tpe: Type, args: Tree*): Tree = + new ApplyConstructor(TypeTree(tpe), args.toList) + def New(sym: Symbol, args: Tree*): Tree = New(sym.tpe, args: _*) - def Super(sym: Symbol, mix: TypeName): Tree = Super(This(sym), mix) + def Super(sym: Symbol, mix: TypeName): Tree = + Super(This(sym), mix) + + def This(sym: Symbol): Tree = + This(sym.name.toTypeName) setSymbol sym + + def Select(qualifier: Tree, name: String): Select = + Select(qualifier, newTermName(name)) + + def Select(qualifier: Tree, sym: Symbol): Select = + Select(qualifier, sym.name) setSymbol sym + + def Ident(name: String): Ident = + Ident(newTermName(name)) + + def Ident(sym: Symbol): Ident = + Ident(sym.name) setSymbol sym /** Block factory that flattens directly nested blocks. */ @@ -266,6 +296,7 @@ trait Trees extends api.Trees { self: SymbolTable => } // --- specific traversers and transformers + // todo. move these into scala.reflect.api protected[scala] def duplicateTree(tree: Tree): Tree = duplicator transform tree @@ -273,44 +304,11 @@ trait Trees extends api.Trees { self: SymbolTable => override val treeCopy = newStrictTreeCopier override def transform(t: Tree) = { val t1 = super.transform(t) - if ((t1 ne t) && isRangePos(t1.pos)) t1 setPos focusPos(t.pos) + if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus t1 } } - trait PosAssigner extends Traverser { - var pos: Position - } - protected[this] lazy val posAssigner: PosAssigner = new DefaultPosAssigner - - protected class DefaultPosAssigner extends PosAssigner { - var pos: Position = _ - override def traverse(t: Tree) { - if (t eq EmptyTree) () - else if (t.pos == NoPosition) { - t.setPos(pos) - super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if? - // @PP: it's pruning whenever it encounters a node with a - // position, which I interpret to mean that (in the author's - // mind at least) either the children of a positioned node will - // already be positioned, or the children of a positioned node - // do not merit positioning. - // - // Whatever the author's rationale, it does seem like a bad idea - // to press on through a positioned node to find unpositioned - // children beneath it and then to assign whatever happens to - // be in `pos` to such nodes. There are supposed to be some - // position invariants which I can't imagine surviving that. - } - } - } - - def atPos[T <: Tree](pos: Position)(tree: T): T = { - posAssigner.pos = pos - posAssigner.traverse(tree) - tree - } - class ForeachPartialTreeTraverser(pf: PartialFunction[Tree, Tree]) extends Traverser { override def traverse(tree: Tree) { val t = if (pf isDefinedAt tree) pf(tree) else tree @@ -363,7 +361,7 @@ trait Trees extends api.Trees { self: SymbolTable => override def toString = substituterString("Symbol", "Tree", from, to) } - /** Substitute clazz.this with `to`. `to` must be an attributed tree. + /** Substitute clazz.this with `to`. `to` must be an attributed tree. */ class ThisSubstituter(clazz: Symbol, to: => Tree) extends Transformer { val newtpe = to.tpe @@ -430,4 +428,3 @@ trait Trees extends api.Trees { self: SymbolTable => override def toString() = "TreeSymSubstituter/" + substituterString("Symbol", "Symbol", from, to) } } - diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 575d84eab4..73a8f5c55c 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -254,7 +254,9 @@ trait Types extends api.Types { self: SymbolTable => case object UnmappableTree extends TermTree { override def toString = "" super.tpe_=(NoType) - override def tpe_=(t: Type) = if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for ") + override def tpe_=(t: Type) = if (t != NoType) { + throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for ") + } } abstract class AbsTypeImpl extends AbsType { this: Type => @@ -262,7 +264,7 @@ trait Types extends api.Types { self: SymbolTable => def nonPrivateDeclaration(name: Name): Symbol = nonPrivateDecl(name) def declarations = decls def typeArguments = typeArgs - def erasedType = transformedType(this) + def erasure = transformedType(this) def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to) } @@ -723,6 +725,9 @@ trait Types extends api.Types { self: SymbolTable => /** Apply `f` to each part of this type */ def foreach(f: Type => Unit) { new ForEachTypeTraverser(f).traverse(this) } + /** Apply `pf' to each part of this type on which the function is defined */ + def collect[T](pf: PartialFunction[Type, T]): List[T] = new CollectTypeCollector(pf).collect(this) + /** Apply `f` to each part of this type; children get mapped before their parents */ def map(f: Type => Type): Type = new TypeMap { def apply(x: Type) = f(mapOver(x)) @@ -1194,6 +1199,8 @@ trait Types extends api.Types { self: SymbolTable => override def kind = "BoundedWildcardType" } + object BoundedWildcardType extends BoundedWildcardTypeExtractor + /** An object representing a non-existing type */ case object NoType extends Type { override def isTrivial: Boolean = true @@ -1822,7 +1829,35 @@ trait Types extends api.Types { self: SymbolTable => object ConstantType extends ConstantTypeExtractor { def apply(value: Constant): ConstantType = { - unique(new UniqueConstantType(value)).asInstanceOf[ConstantType] + val tpe = new UniqueConstantType(value) + if (value.tag == ClazzTag) { + // if we carry a classOf, we might be in trouble + // http://groups.google.com/group/scala-internals/browse_thread/thread/45185b341aeb6a30 + // I don't have time for a thorough fix, so I put a hacky workaround here + val alreadyThere = uniques findEntry tpe + if ((alreadyThere ne null) && (alreadyThere ne tpe) && (alreadyThere.toString != tpe.toString)) { + // we need to remove a stale type that has the same hashcode as we do + // HashSet doesn't support removal, and this makes our task non-trivial + // also we cannot simply recreate it, because that'd skew hashcodes (that change over time, omg!) + // the only solution I can see is getting into the underlying array and sneakily manipulating it + val ftable = uniques.getClass.getDeclaredFields().find(f => f.getName endsWith "table").get + ftable.setAccessible(true) + val table = ftable.get(uniques).asInstanceOf[Array[AnyRef]] + def overwrite(hc: Int, x: Type) { + def index(x: Int): Int = math.abs(x % table.length) + var h = index(hc) + var entry = table(h) + while (entry ne null) { + if (x == entry) + table(h) = x + h = index(h + 1) + entry = table(h) + } + } + overwrite(tpe.##, tpe) + } + } + unique(tpe).asInstanceOf[ConstantType] } } @@ -3751,6 +3786,8 @@ trait Types extends api.Types { self: SymbolTable => } } + // todo. move these into scala.reflect.api + /** A prototype for mapping a function over all possible types */ abstract class TypeMap extends (Type => Type) { @@ -4563,6 +4600,16 @@ trait Types extends api.Types { self: SymbolTable => } } + /** A map to implement the `collect` method. */ + class CollectTypeCollector[T](pf: PartialFunction[Type, T]) extends TypeCollector[List[T]](Nil) { + override def collect(tp: Type) = super.collect(tp).reverse + + def traverse(tp: Type) { + if (pf.isDefinedAt(tp)) result ::= pf(tp) + mapOver(tp) + } + } + class ForEachTypeTraverser(f: Type => Unit) extends TypeTraverser { def traverse(tp: Type) { f(tp) diff --git a/src/compiler/scala/reflect/makro/runtime/Aliases.scala b/src/compiler/scala/reflect/makro/runtime/Aliases.scala new file mode 100644 index 0000000000..a4f208ca34 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Aliases.scala @@ -0,0 +1,21 @@ +package scala.reflect.makro +package runtime + +trait Aliases { + self: Context => + + /** Aliases of mirror types */ + override type Symbol = mirror.Symbol + override type Type = mirror.Type + override type Name = mirror.Name + override type Tree = mirror.Tree + override type Position = mirror.Position + override type Scope = mirror.Scope + override type Modifiers = mirror.Modifiers + override type Expr[+T] = mirror.Expr[T] + override type TypeTag[T] = mirror.TypeTag[T] + + /** Creator/extractor objects for Expr and TypeTag values */ + override val TypeTag = mirror.TypeTag + override val Expr = mirror.Expr +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala b/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala new file mode 100644 index 0000000000..4e93d4e06d --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala @@ -0,0 +1,14 @@ +package scala.reflect.makro +package runtime + +trait CapturedVariables { + self: Context => + + import mirror._ + + def captureVariable(vble: Symbol): Unit = mirror.captureVariable(vble) + + def referenceCapturedVariable(vble: Symbol): Tree = mirror.referenceCapturedVariable(vble) + + def capturedVariableType(vble: Symbol): Type = mirror.capturedVariableType(vble) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Context.scala b/src/compiler/scala/reflect/makro/runtime/Context.scala new file mode 100644 index 0000000000..184008658e --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Context.scala @@ -0,0 +1,26 @@ +package scala.reflect.makro +package runtime + +import scala.tools.nsc.Global + +abstract class Context extends scala.reflect.makro.Context + with Aliases + with CapturedVariables + with Infrastructure + with Enclosures + with Names + with Reifiers + with Reporters + with Settings + with Symbols + with Typers + with Util { + + val mirror: Global + + val callsiteTyper: mirror.analyzer.Typer + + val prefix: Expr[PrefixType] + + val expandee: Tree +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala new file mode 100644 index 0000000000..f9a6987e48 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala @@ -0,0 +1,36 @@ +package scala.reflect.makro +package runtime + +trait Enclosures { + self: Context => + + import mirror._ + + // vals are eager to simplify debugging + // after all we wouldn't save that much time by making them lazy + + val macroApplication: Tree = expandee + + val enclosingMacros: List[Context] = this :: mirror.analyzer.openMacros + + val enclosingImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits + + val enclosingPosition: Position = enclosingMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication.pos).getOrElse(NoPosition) + + val enclosingApplication: Tree = { + def loop(context: analyzer.Context): Tree = context match { + case analyzer.NoContext => EmptyTree + case context if context.tree.isInstanceOf[Apply] => context.tree + case context => loop(context.outer) + } + + val context = callsiteTyper.context + loop(context) + } + + val enclosingMethod: Tree = callsiteTyper.context.enclMethod.tree + + val enclosingClass: Tree = callsiteTyper.context.enclClass.tree + + val enclosingUnit: CompilationUnit = currentRun.currentUnit +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Errors.scala b/src/compiler/scala/reflect/makro/runtime/Errors.scala new file mode 100644 index 0000000000..d78eae9237 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Errors.scala @@ -0,0 +1,6 @@ +package scala.reflect.makro +package runtime + +import scala.reflect.api.Position + +class AbortMacroException(val pos: Position, val msg: String) extends Throwable(msg) diff --git a/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala b/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala new file mode 100644 index 0000000000..6d8e55cc35 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala @@ -0,0 +1,34 @@ +package scala.reflect.makro +package runtime + +trait Infrastructure { + self: Context => + + val forJVM: Boolean = mirror.forJVM + + val forMSIL: Boolean = mirror.forMSIL + + val forInteractive: Boolean = mirror.forInteractive + + val forScaladoc: Boolean = mirror.forScaladoc + + val currentRun: Run = mirror.currentRun + + type Run = mirror.Run + + object Run extends RunExtractor { + def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])] = Some(run.currentUnit, run.units.toList) + } + + type CompilationUnit = mirror.CompilationUnit + + object CompilationUnit extends CompilationUnitExtractor { + def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)] = Some(compilationUnit.source.file.file, compilationUnit.source.content, compilationUnit.body) + } + + val currentMacro: Symbol = expandee.symbol + + val globalCache: collection.mutable.Map[Any, Any] = mirror.analyzer.globalMacroCache + + val cache: collection.mutable.Map[Any, Any] = mirror.analyzer.perRunMacroCache.getOrElseUpdate(currentMacro, collection.mutable.Map[Any, Any]()) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Names.scala b/src/compiler/scala/reflect/makro/runtime/Names.scala new file mode 100644 index 0000000000..d8ecc2b89e --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Names.scala @@ -0,0 +1,20 @@ +package scala.reflect.makro +package runtime + +trait Names { + self: Context => + + lazy val freshNameCreator = callsiteTyper.context.unit.fresh + + def fresh(): String = { + freshNameCreator.newName() + } + + def fresh(name: String): String = { + freshNameCreator.newName(name) + } + + def fresh(name: Name): Name = { + name.mapName(freshNameCreator.newName(_)) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala new file mode 100644 index 0000000000..826fa7153f --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -0,0 +1,69 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Gilles Dubochet + */ + +package scala.reflect.makro +package runtime + +trait Reifiers { + self: Context => + + import mirror._ + + lazy val reflectMirrorPrefix: Tree = { + // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure? + val prefix: Tree = Select(Select(Ident(definitions.ScalaPackage), newTermName("reflect")), newTermName("mirror")) + val prefixTpe = typeCheck(TypeApply(Select(prefix, newTermName("asInstanceOf")), List(SingletonTypeTree(prefix)))).tpe + typeCheck(prefix) setType prefixTpe + } + + def reifyTree(prefix: Tree, tree: Tree): Tree = + reifyTopLevel(prefix, tree) + + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, noTypeVariablesInResult: Boolean = false): Tree = + reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, noTypeVariablesInResult) + + def unreifyTree(tree: Tree): Tree = + Select(tree, definitions.ExprEval) + + def reifyTopLevel(prefix: Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Tree = { + // [Eugene] the plumbing is not very pretty, but anyways factoring out the reifier seems like a necessary step to me + import scala.reflect.reify._ + val reifier = mkReifier(mirror)(callsiteTyper, prefix, reifee, dontSpliceAtTopLevel, requireGroundTypeTag) + + try { + val result = reifier.reified + logFreeVars(expandee.pos, result) + result + } catch { + case ex: reifier.ReificationError => +// // this is a "soft" exception - it will normally be caught by the macro +// // consequently, we need to log the stack trace here, so that it doesn't get lost +// if (settings.Yreifydebug.value) { +// val message = new java.io.StringWriter() +// ex.printStackTrace(new java.io.PrintWriter(message)) +// println(scala.compat.Platform.EOL + message) +// } + val xlated = new ReificationError(ex.pos, ex.msg) + xlated.setStackTrace(ex.getStackTrace) + throw xlated + case ex: reifier.UnexpectedReificationError => + val xlated = new UnexpectedReificationError(ex.pos, ex.msg, ex.cause) + xlated.setStackTrace(ex.getStackTrace) + throw xlated + } + } + + class ReificationError(var pos: Position, val msg: String) extends Throwable(msg) + + object ReificationError extends ReificationErrorExtractor { + def unapply(error: ReificationError): Option[(Position, String)] = Some((error.pos, error.msg)) + } + + class UnexpectedReificationError(val pos: Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause) + + object UnexpectedReificationError extends UnexpectedReificationErrorExtractor { + def unapply(error: UnexpectedReificationError): Option[(Position, String, Throwable)] = Some((error.pos, error.msg, error.cause)) + } +} diff --git a/src/compiler/scala/reflect/makro/runtime/Reporters.scala b/src/compiler/scala/reflect/makro/runtime/Reporters.scala new file mode 100644 index 0000000000..0fd037bdd2 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Reporters.scala @@ -0,0 +1,44 @@ +package scala.reflect.makro +package runtime + +trait Reporters { + self: Context => + + import mirror._ + + def reporter: mirror.Reporter = wrapNscReporter(mirror.reporter) + + def setReporter(reporter: mirror.Reporter): this.type = { + mirror.reporter = wrapApiReporter(reporter) + this + } + + def withReporter[T](reporter: Reporter)(op: => T): T = { + val old = mirror.reporter + setReporter(reporter) + try op + finally mirror.reporter = old + } + + def echo(pos: Position, msg: String): Unit = mirror.reporter.echo(pos, msg) + + def info(pos: Position, msg: String, force: Boolean): Unit = mirror.reporter.info(pos, msg, force) + + def hasWarnings: Boolean = mirror.reporter.hasErrors + + def hasErrors: Boolean = mirror.reporter.hasErrors + + def warning(pos: Position, msg: String): Unit = callsiteTyper.context.warning(pos, msg) + + def error(pos: Position, msg: String): Unit = callsiteTyper.context.error(pos, msg) + + def abort(pos: Position, msg: String): Nothing = { + callsiteTyper.context.error(pos, msg) + throw new AbortMacroException(pos, msg) + } + + def interactive(): Unit = mirror.reporter match { + case reporter: tools.nsc.reporters.AbstractReporter => reporter.displayPrompt() + case _ => () + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Settings.scala b/src/compiler/scala/reflect/makro/runtime/Settings.scala new file mode 100644 index 0000000000..32f7115db8 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Settings.scala @@ -0,0 +1,36 @@ +package scala.reflect.makro +package runtime + +trait Settings { + self: Context => + + def settings: List[String] = { + val optionName = mirror.settings.XmacroSettings.name + val settings = compilerSettings.find(opt => opt.startsWith(optionName)).map(opt => opt.substring(optionName.length + 1)).getOrElse("") + settings.split(",").toList + } + + def compilerSettings: List[String] = mirror.settings.recreateArgs + + def setCompilerSettings(options: String): this.type = + // todo. is not going to work with quoted arguments with embedded 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(mirror.settings) + this + } + + def withCompilerSettings[T](options: String)(op: => T): T = + // todo. is not going to work with quoted arguments with embedded whitespaces + withCompilerSettings(options.split(" ").toList)(op) + + def withCompilerSettings[T](options: List[String])(op: => T): T = { + val old = options + setCompilerSettings(options) + try op + finally setCompilerSettings(old) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Symbols.scala b/src/compiler/scala/reflect/makro/runtime/Symbols.scala new file mode 100644 index 0000000000..552ad2a303 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Symbols.scala @@ -0,0 +1,8 @@ +package scala.reflect.makro +package runtime + +trait Symbols { + self: Context => + + def isLocatable(sym: Symbol) = sym.isLocatable +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala new file mode 100644 index 0000000000..38e819746d --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala @@ -0,0 +1,78 @@ +package scala.reflect.makro +package runtime + +trait Typers { + self: Context => + + val openMacros: List[Context] = this :: mirror.analyzer.openMacros + + val openImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits + + def typeCheck(tree: Tree, pt: Type = mirror.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { + def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) + trace("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled)) + val wrapper1 = if (!withImplicitViewsDisabled) (callsiteTyper.context.withImplicitsEnabled[Tree] _) else (callsiteTyper.context.withImplicitsDisabled[Tree] _) + val wrapper2 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[Tree] _) else (callsiteTyper.context.withMacrosDisabled[Tree] _) + def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) + // if you get a "silent mode is not available past typer" here + // don't rush to change the typecheck not to use the silent method when the silent parameter is false + // typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time + // I'd advise fixing the root cause: finding why the context is not set to report errors + // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you) + wrapper(callsiteTyper.silent(_.typed(tree, mirror.analyzer.EXPRmode, pt)) match { + case mirror.analyzer.SilentResultValue(result) => + trace(result) + result + case error @ mirror.analyzer.SilentTypeError(_) => + trace(error.err.errMsg) + if (!silent) throw new mirror.TypeError(error.err.errPos, error.err.errMsg) + mirror.EmptyTree + }) + } + + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { + def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) + trace("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) + import mirror.analyzer.SearchResult + val wrapper1 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[SearchResult] _) else (callsiteTyper.context.withMacrosDisabled[SearchResult] _) + def wrapper (inference: => SearchResult) = wrapper1(inference) + val context = callsiteTyper.context.makeImplicit(true) + wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, pt, true, false, context, !silent, pos)) match { + case failure if failure.tree.isEmpty => + trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits") + if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg) + mirror.EmptyTree + case success => + success.tree + } + } + + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree = { + def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) + trace("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous)) + import mirror.analyzer.SearchResult + val wrapper1 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[SearchResult] _) else (callsiteTyper.context.withMacrosDisabled[SearchResult] _) + def wrapper (inference: => SearchResult) = wrapper1(inference) + val fun1 = mirror.definitions.FunctionClass(1) + val viewTpe = mirror.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to)) + val context = callsiteTyper.context.makeImplicit(reportAmbiguous) + wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match { + case failure if failure.tree.isEmpty => + trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits") + if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg) + mirror.EmptyTree + case success => + success.tree + } + } + + type TypeError = mirror.TypeError + + object TypeError extends TypeErrorExtractor { + def unapply(error: TypeError): Option[(Position, String)] = Some((error.pos, error.msg)) + } + + def resetAllAttrs[T <: Tree](tree: T): T = mirror.resetAllAttrs(tree) + + def resetLocalAttrs[T <: Tree](tree: T): T = mirror.resetLocalAttrs(tree) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Util.scala b/src/compiler/scala/reflect/makro/runtime/Util.scala new file mode 100644 index 0000000000..2671155721 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Util.scala @@ -0,0 +1,34 @@ +package scala.reflect.makro +package runtime + +trait Util { + self: Context => + + import mirror._ + + def literalNull = Expr[Null](Literal(Constant(null)))(TypeTag.Null) + + def literalUnit = Expr[Unit](Literal(Constant(())))(TypeTag.Unit) + + def literalTrue = Expr[Boolean](Literal(Constant(true)))(TypeTag.Boolean) + + def literalFalse = Expr[Boolean](Literal(Constant(false)))(TypeTag.Boolean) + + def literal(x: Boolean) = Expr[Boolean](Literal(Constant(x)))(TypeTag.Boolean) + + def literal(x: Byte) = Expr[Byte](Literal(Constant(x)))(TypeTag.Byte) + + def literal(x: Short) = Expr[Short](Literal(Constant(x)))(TypeTag.Short) + + def literal(x: Int) = Expr[Int](Literal(Constant(x)))(TypeTag.Int) + + def literal(x: Long) = Expr[Long](Literal(Constant(x)))(TypeTag.Long) + + def literal(x: Float) = Expr[Float](Literal(Constant(x)))(TypeTag.Float) + + def literal(x: Double) = Expr[Double](Literal(Constant(x)))(TypeTag.Double) + + def literal(x: String) = Expr[String](Literal(Constant(x)))(TypeTag.String) + + def literal(x: Char) = Expr[Char](Literal(Constant(x)))(TypeTag.Char) +} diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala new file mode 100644 index 0000000000..8bfe64621b --- /dev/null +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -0,0 +1,63 @@ +package scala.reflect +package reify + +import scala.tools.nsc.Global + +trait Errors { + self: Reifier => + + import mirror._ + import definitions._ + + class ReificationError(var pos: Position, val msg: String) extends Throwable(msg) + class UnexpectedReificationError(val pos: Position, val msg: String, val cause: Throwable = null) extends Throwable(msg) + + lazy val defaultErrorPosition: Position = + mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication.pos).getOrElse(NoPosition) + + // expected errors: these can happen if the user casually writes whatever.reify(...) + // hence we don't crash here, but nicely report a typechecking error and bail out asap + + def CannotReifyReifeeThatHasTypeLocalToReifee(tree: Tree) = { + val msg = "implementation restriction: cannot reify block of type %s that involves a type declared inside the block being reified. consider casting the return value to a suitable type".format(tree.tpe) + throw new ReificationError(tree.pos, msg) + } + + def CannotReifyType(tpe: Type) = { + val msg = "implementation restriction: cannot reify type %s (%s)".format(tpe, tpe.kind) + throw new ReificationError(defaultErrorPosition, msg) + } + + def CannotReifySymbol(sym: Symbol) = { + val msg = "implementation restriction: cannot reify symbol %s (%s)".format(sym, sym.accurateKindString) + throw new ReificationError(defaultErrorPosition, msg) + } + + def CannotReifyGroundTypeTagHavingUnresolvedTypeParameters(tpe: Type) = { + val msg = "cannot reify GroundTypeTag having unresolved type parameter %s".format(tpe) + throw new ReificationError(defaultErrorPosition, msg) + } + + // unexpected errors: these can never happen under normal conditions unless there's a bug in the compiler (or in a compiler plugin or in a macro) + // hence, we fail fast and loudly and don't care about being nice - in this situation noone will appreciate our quiet nicety + + def CannotReifyUntypedPrefix(prefix: Tree) = { + val msg = "internal error: untyped prefixes are not supported, consider typechecking the prefix before passing it to the reifier" + throw new UnexpectedReificationError(defaultErrorPosition, msg) + } + + def CannotReifyUntypedReifee(reifee: Any) = { + val msg = "internal error: untyped trees are not supported, consider typechecking the reifee before passing it to the reifier" + throw new UnexpectedReificationError(defaultErrorPosition, msg) + } + + def CannotReifyErroneousPrefix(prefix: Tree) = { + val msg = "internal error: erroneous prefixes are not supported, make sure that your prefix has typechecked successfully before passing it to the reifier" + throw new UnexpectedReificationError(defaultErrorPosition, msg) + } + + def CannotReifyErroneousReifee(reifee: Any) = { + val msg = "internal error: erroneous reifees are not supported, make sure that your reifee has typechecked successfully before passing it to the reifier" + throw new UnexpectedReificationError(defaultErrorPosition, msg) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/NodePrinters.scala b/src/compiler/scala/reflect/reify/NodePrinters.scala new file mode 100644 index 0000000000..eaca9a4968 --- /dev/null +++ b/src/compiler/scala/reflect/reify/NodePrinters.scala @@ -0,0 +1,111 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package reify + +import scala.Array.canBuildFrom +import scala.compat.Platform.EOL +import scala.tools.nsc.symtab.Flags +import scala.tools.nsc.Global + +trait NodePrinters { self: scala.tools.nsc.ast.NodePrinters => + + val global: Global + import global._ + + object reifiedNodeToString extends Function2[Tree, Tree, String] { + def apply(prefix: Tree, tree: Tree): String = { + import scala.reflect.api.Modifier + var modifierIsUsed = false + var flagsAreUsed = false + + // @PP: I fervently hope this is a test case or something, not anything being + // 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. + val (List(mirror), reified) = (for (line <- (tree.toString.split(EOL).toList drop 1 dropRight 1)) yield { + var s = line.trim + s = s.replace("$mr.", "") + s = s.replace(".apply", "") + s = s.replace("scala.collection.immutable.", "") + s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List") + s = "List\\[.*?\\]".r.replaceAllIn(s, "List") + s = s.replace("immutable.this.Nil", "List()") + s = s.replace("modifiersFromInternalFlags", "Modifiers") + s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()") + s = """Modifiers\((\d+)[lL], newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => { + val buf = new collection.mutable.ListBuffer[String] + + val annotations = m.group(3) + if (buf.nonEmpty || annotations.nonEmpty) + buf.append("List(" + annotations + ")") + + val privateWithin = "" + m.group(2) + if (buf.nonEmpty || privateWithin != "") + buf.append("newTypeName(\"" + privateWithin + "\")") + + val flags = m.group(1).toLong + val s_flags = Flags.modifiersOfFlags(flags) map (_.sourceString) mkString ", " + if (buf.nonEmpty || s_flags != "") { + modifierIsUsed = true + buf.append("Set(" + s_flags + ")") + } + + "Modifiers(" + buf.reverse.mkString(", ") + ")" + }) + s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => { + flagsAreUsed = true + val flags = m.group(1).toLong + val mods = Flags.modifiersOfFlags(flags) map (_.sourceString) + "setInternalFlags(flagsOfModifiers(List(" + mods.mkString(", ") + ")))" + }) + + s + }) splitAt 1 + + val printout = collection.mutable.ListBuffer(mirror); + printout += "import " + nme.MIRROR_SHORT + "._" + if (modifierIsUsed) printout += "import scala.reflect.api.Modifier._" + if (flagsAreUsed) printout += "import scala.reflect.internal.Flags._" + val body = reified dropWhile (_.startsWith("val")) + if (body.length > 0 && body(0).startsWith("Expr[")) { + if (reified(0) startsWith "val") { + printout += "val code = {" + printout ++= (reified map (" " + _)) + printout += "}" + printout += "mkToolBox().runExpr(code)" + } else { + printout += "val code = " + reified(0) + printout ++= reified drop 1 + printout += "mkToolBox().runExpr(code)" + } + try { + val prefix = Select(Select(Ident(definitions.ScalaPackage), newTermName("reflect")), newTermName("mirror")) + val tree1 = new global.Transformer { + override def transform(tree: Tree) = super.transform(tree match { + case Block(ValDef(_, mr, _, _) :: Nil, expr) if mr == nme.MIRROR_SHORT => transform(expr) + case Block(ValDef(_, mr, _, _) :: symbolTable, expr) if mr == nme.MIRROR_SHORT => transform(Block(symbolTable, expr)) + case Select(Ident(mr), name) if mr == nme.MIRROR_SHORT => Select(prefix, name) + case tree => tree + }) + }.transform(tree) + val stringified = mkToolBox().runExpr(tree1).toString + if (settings.Yreifydebug.value) printout += "*****************************" + printout += stringified + } catch { + case ex: Throwable => +// val realex = ReflectionUtils.unwrapThrowable(ex) +// val message = new java.io.StringWriter() +// realex.printStackTrace(new java.io.PrintWriter(message)) +// println(message) + } + } else { + printout ++= reified + } + printout mkString EOL + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/Phases.scala b/src/compiler/scala/reflect/reify/Phases.scala new file mode 100644 index 0000000000..49d5a45e8e --- /dev/null +++ b/src/compiler/scala/reflect/reify/Phases.scala @@ -0,0 +1,42 @@ +package scala.reflect +package reify + +import scala.reflect.reify.phases._ + +trait Phases extends Calculate + with Reshape + with Metalevels + with Reify { + + self: Reifier => + + import mirror._ + import definitions._ + + private var alreadyRun = false + + lazy val mkReificationPipeline: Tree => Tree = tree0 => { + assert(!alreadyRun, "reifier instance cannot be used more than once") + alreadyRun = true + + var tree = tree0 + + if (reifyDebug) println("[calculate phase]") + calculate.traverse(tree) + + if (reifyDebug) println("[reshape phase]") + tree = reshape.transform(tree) + + if (reifyDebug) println("[metalevels phase]") + tree = metalevels.transform(tree) + + if (reifyDebug) println("[interlude]") + if (reifyDebug) println("symbol table = " + (if (symbolTable.length == 0) "" else "")) + if (reifyDebug) symbolTable foreach (println(_)) + if (reifyDebug) println("reifee = " + (if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString)) + if (reifyDebug) println("[reify phase]") + var result = reify(tree) + + result + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/Reifiers.scala b/src/compiler/scala/reflect/reify/Reifiers.scala new file mode 100644 index 0000000000..6854710949 --- /dev/null +++ b/src/compiler/scala/reflect/reify/Reifiers.scala @@ -0,0 +1,154 @@ +package scala.reflect +package reify + +import scala.tools.nsc.Global + +/** Given a tree or a type, generate a tree that when executed at runtime produces the original tree or type. + * See more info in the comments to ``reify'' in scala.reflect.api.Universe. + * + * @author Martin Odersky + * @version 2.10 + */ +abstract class Reifier extends Phases + with Errors { + + val mirror: Global + import mirror._ + import definitions._ + import treeInfo._ + + val typer: mirror.analyzer.Typer + val prefix: Tree + val reifee: Any + val dontSpliceAtTopLevel: Boolean + val requireGroundTypeTag: Boolean + + /** + * For ``reifee'' and other reification parameters, generate a tree of the form + * + * { + * val $mr = <[ prefix ]> + * $mr.Expr[T](rtree) // if data is a Tree + * $mr.TypeTag[T](rtree) // if data is a Type + * } + * + * where + * + * - `prefix` is the tree that represents the universe + * the result will be bound to + * - `rtree` is code that generates `reifee` at runtime. + * - `T` is the type that corresponds to `data`. + * + * This is not a method, but a value to indicate the fact that Reifier instances are a one-off. + */ + lazy val reified: Tree = { + try { + // [Eugene] conventional way of doing this? + if (prefix exists (_.isErroneous)) CannotReifyErroneousPrefix(prefix) + if (prefix.tpe == null) CannotReifyUntypedPrefix(prefix) + + val rtree = reifee match { + case tree: Tree => + reifyTrace("reifying = ")(if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) + reifyTrace("reifee is located at: ")(tree.pos) + reifyTrace("prefix = ")(prefix) + // [Eugene] conventional way of doing this? + if (tree exists (_.isErroneous)) CannotReifyErroneousReifee(prefix) + if (tree.tpe == null) CannotReifyUntypedReifee(tree) + val pipeline = mkReificationPipeline + val rtree = pipeline(tree) + + // consider the following code snippet + // + // val x = reify { class C; new C } + // + // inferred type for x will be C + // but C ceases to exist after reification so this type is clearly incorrect + // however, reify is "just" a library function, so it cannot affect type inference + // + // hence we crash here even though the reification itself goes well + // fortunately, all that it takes to fix the error is to cast "new C" to Object + // so I'm not very much worried about introducing this restriction + if (tree.tpe exists (sub => sub.typeSymbol.isLocalToReifee)) + CannotReifyReifeeThatHasTypeLocalToReifee(tree) + + val manifestedType = typer.packedType(tree, NoSymbol) + val manifestedRtype = reifyType(manifestedType) + val tagModule = if (definitelyGround) GroundTypeTagModule else TypeTagModule + var typeTagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) + var exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType))) + Apply(Apply(exprCtor, List(rtree)), List(Apply(typeTagCtor, List(manifestedRtype)))) + + case tpe: Type => + reifyTrace("reifying = ")(tpe.toString) + reifyTrace("prefix = ")(prefix) + val rtree = reify(tpe) + + val manifestedType = tpe + var tagModule = if (definitelyGround) GroundTypeTagModule else TypeTagModule + var ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) + Apply(ctor, List(rtree)) + + case _ => + throw new Error("reifee %s of type %s is not supported".format(reifee, if (reifee == null) "null" else reifee.getClass.toString)) + } + + val mirrorAlias = ValDef(NoMods, nme.MIRROR_SHORT, SingletonTypeTree(prefix), prefix) + val wrapped = Block(mirrorAlias :: symbolTable, rtree) + + // todo. why do we resetAllAttrs? + // + // typically we do some preprocessing before reification and + // the code emitted/moved around during preprocessing is very hard to typecheck, so we leave it as it is + // however this "as it is" sometimes doesn't make any sense + // + // ===example 1=== + // we move a freevar from a nested symbol table to a top-level symbol table, + // and then the reference to mr$ becomes screwed up, because nested symbol tables are already typechecked, + // so we have an mr$ symbol that points to the nested mr$ rather than to the top-level one. + // + // ===example 2=== + // we inline a freevar by replacing a reference to it, e.g. $mr.Apply($mr.Select($mr.Ident($mr.newTermName("$mr")), $mr.newTermName("Ident")), List($mr.Ident($mr.newTermName("free$x")))) + // with its original binding (e.g. $mr.Ident("x")) + // we'd love to typecheck the result, but we cannot do this easily, because $mr is external to this tree + // what's even worse, sometimes $mr can point to the top-level symbol table's $mr, which doesn't have any symbol/type yet - + // it's just a ValDef that will be emitted only after the reification is completed + // + // hence, the simplest solution is to erase all attrs so that invalid (as well as non-existent) bindings get rebound correctly + // this is ugly, but it's the best we can do + // + // 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: + // 1) local freetype inlining in Nested + // 2) external freevar moving in Nested + // 3) local freeterm inlining in Metalevels + // 4) trivial tree splice inlining in Reify (Trees.scala) + // 5) trivial type splice inlining in Reify (Types.scala) + val freevarBindings = symbolTable collect { case freedef @ FreeDef(_, _, binding, _) => binding.symbol } toSet + val untyped = resetAllAttrs(wrapped, leaveAlone = { + case ValDef(_, mr, _, _) if mr == nme.MIRROR_SHORT => true + case tree if freevarBindings contains tree.symbol => true + case _ => false + }) + + if (reifyCopypaste) { + if (reifyDebug) println("=============================") + println(reifiedNodeToString(prefix, untyped)) + if (reifyDebug) println("=============================") + } else { + reifyTrace("reified = ")(untyped) + } + + untyped + } catch { + case ex: ReificationError => + throw ex + case ex: UnexpectedReificationError => + throw ex + case ex: Throwable => + throw new UnexpectedReificationError(defaultErrorPosition, "reification crashed", ex) + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Names.scala b/src/compiler/scala/reflect/reify/codegen/Names.scala new file mode 100644 index 0000000000..589f6355d0 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Names.scala @@ -0,0 +1,15 @@ +package scala.reflect.reify +package codegen + +trait Names { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + def reifyName(name: Name) = { + val factory = if (name.isTypeName) nme.nmeNewTypeName else nme.nmeNewTermName + mirrorCall(factory, Literal(Constant(name.toString))) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Positions.scala b/src/compiler/scala/reflect/reify/codegen/Positions.scala new file mode 100644 index 0000000000..ac9195ef31 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Positions.scala @@ -0,0 +1,18 @@ +package scala.reflect.reify +package codegen + +trait Positions { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + // we do not reify positions because this inflates resulting trees, but doesn't buy as anything + // where would one use positions? right, in error messages + // but I can hardly imagine when one would need a position that points to the reified code + // usually reified trees are used to compose macro expansions or to be fed to the runtime compiler + // however both macros and toolboxes have their own means to report errors in synthetic trees + def reifyPosition(pos: Position): Tree = + reifyMirrorObject(NoPosition) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala new file mode 100644 index 0000000000..3328f5e402 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala @@ -0,0 +1,111 @@ +package scala.reflect.reify +package codegen + +trait Symbols { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** Reify a reference to a symbol */ + def reifySymRef(sym0: Symbol): Tree = { + assert(sym0 != null, "sym is null") + val sym = sym0.dealias + + if (sym == NoSymbol) + mirrorSelect(nme.NoSymbol) + else if (sym == RootPackage) + Select(mirrorSelect(nme.definitions), nme.RootPackage) + else if (sym == RootClass) + Select(mirrorSelect(nme.definitions), nme.RootClass) + else if (sym == EmptyPackage) + Select(mirrorSelect(nme.definitions), nme.EmptyPackage) + else if (sym == EmptyPackageClass) + Select(mirrorSelect(nme.definitions), nme.EmptyPackageClass) + else if (sym.isModuleClass) + Select(reify(sym.sourceModule), nme.moduleClass) + else if (sym.isLocatable) { + // [Eugene] am I doing this right? +// if (sym.isStaticOwner) { // no good for us, because it returns false for packages + if (sym.isStatic && (sym.isClass || sym.isModule)) { + val resolver = if (sym.isType) nme.staticClass else nme.staticModule + mirrorCall(resolver, reify(sym.fullName)) + } else { + if (reifyDebug) println("Locatable: %s (%s) owned by %s (%s) at %s".format(sym, sym.accurateKindString, sym.owner, sym.owner.accurateKindString, sym.owner.fullNameString)) + val rowner = reify(sym.owner) + val rname = reify(sym.name.toString) + if (sym.isType) + mirrorCall(nme.selectType, rowner, rname) + else if (sym.isMethod && sym.owner.isClass && sym.owner.info.decl(sym.name).isOverloaded) { + val index = sym.owner.info.decl(sym.name).alternatives indexOf sym + assert(index >= 0, sym) + mirrorCall(nme.selectOverloadedMethod, rowner, rname, reify(index)) + } else + mirrorCall(nme.selectTerm, rowner, rname) + } + } else { + // todo. make sure that free methods and free local defs work correctly + if (sym.isTerm) { + if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym) + reifyFreeTerm(sym, Ident(sym)) + } else { + if (reifyDebug) println("Free type: " + sym) + reifyFreeType(sym, Ident(sym)) + } + } + } + + def reifyFreeTerm(sym: Symbol, value: Tree): Tree = + locallyReified get sym match { + case Some(reified) => + reified + case None => + if (sym.isCapturedVariable) { + assert(value.isInstanceOf[Ident], showRaw(value)) + val capturedTpe = capturedVariableType(sym) + val capturedValue = referenceCapturedVariable(sym) + locallyReify(sym, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, reify(origin(sym)))) + } else { + locallyReify(sym, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, reify(origin(sym)))) + } + } + + def reifyFreeType(sym: Symbol, value: Tree): Tree = + locallyReified get sym match { + case Some(reified) => + reified + case None => + val phantomTypeTag = Apply(TypeApply(Select(Ident(nme.MIRROR_SHORT), nme.TypeTag), List(value)), List(Literal(Constant(null)))) + // todo. implement info reification for free types: type bounds, HK-arity, whatever else that can be useful + locallyReify(sym, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(origin(sym)))) + } + + import scala.collection.mutable._ + private val localReifications = ArrayBuffer[ValDef]() + private val locallyReified = Map[Symbol, Tree]() + def symbolTable: List[ValDef] = localReifications.toList + def symbolTable_=(newSymbolTable: List[ValDef]): Unit = { + localReifications.clear() + locallyReified.clear() + newSymbolTable foreach { + case freedef @ FreeDef(_, name, binding, _) => + if (!(locallyReified contains binding.symbol)) { + localReifications += freedef + locallyReified(binding.symbol) = Ident(name) + } + } + } + + private def locallyReify(sym: Symbol, reificode: => Tree): Tree = { + val reified = reificode + val Apply(Select(_, flavor), _) = reified + // [Eugene] name clashes are impossible, right? + var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name) + if (flavor == nme.newFreeTerm && sym.isType) name = name.append(nme.MIRROR_FREE_THIS_SUFFIX); + // todo. also reify annotations for free vars + localReifications += ValDef(NoMods, name, TypeTree(), reified) + locallyReified(sym) = Ident(name) + locallyReified(sym) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Trees.scala b/src/compiler/scala/reflect/reify/codegen/Trees.scala new file mode 100644 index 0000000000..22f42aea49 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala @@ -0,0 +1,220 @@ +package scala.reflect.reify +package codegen + +trait Trees { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * Reify a tree. + * For internal use only, use ``reified'' instead. + */ + def reifyTree(tree: Tree): Tree = { + assert(tree != null, "tree is null") + + if (tree.isErroneous) + CannotReifyErroneousReifee(tree) + + val splicedTree = spliceTree(tree) + if (splicedTree != EmptyTree) + return splicedTree + + // the idea behind the new reincarnation of reifier is a simple maxim: + // + // never call ``reifyType'' to reify a tree + // + // this works because the stuff we are reifying was once represented with trees only + // and lexical scope information can be fully captured by reifying symbols + // + // to enable this idyll, we work hard in the ``Reshape'' phase + // which replaces all types with equivalent trees and works around non-idempotencies of the typechecker + // + // why bother? because this brings method to the madness + // the first prototype of reification reified all types and symbols for all trees => this quickly became unyieldy + // the second prototype reified external types, but avoided reifying local ones => this created an ugly irregularity + // current approach is uniform and compact + var rtree = tree match { + case mirror.EmptyTree => + reifyMirrorObject(EmptyTree) + case mirror.emptyValDef => + mirrorSelect(nme.emptyValDef) + case FreeDef(_, _, _, _) => + reifyNestedFreeDef(tree) + case FreeRef(_, _) => + reifyNestedFreeRef(tree) + case BoundTerm(tree) => + reifyBoundTerm(tree) + case BoundType(tree) => + reifyBoundType(tree) + case NestedExpr(_, _, _) => + reifyNestedExpr(tree) + case Literal(const @ Constant(_)) => + mirrorCall(nme.Literal, reifyProduct(const)) + case Import(expr, selectors) => + mirrorCall(nme.Import, reify(expr), mkList(selectors map reifyProduct)) + case _ => + reifyProduct(tree) + } + + rtree + } + + def reifyModifiers(m: mirror.Modifiers) = + mirrorCall("modifiersFromInternalFlags", reify(m.flags), reify(m.privateWithin), reify(m.annotations)) + + private def spliceTree(tree: Tree): Tree = { + tree match { + case EvalSplice(splicee) => + if (reifyDebug) println("splicing eval " + tree) + + // see ``Metalevels'' for more info about metalevel breaches + // and about how we deal with splices that contain them + if (splicee exists (sub => sub.hasSymbol && sub.symbol != NoSymbol && sub.symbol.metalevel > 0)) { + if (reifyDebug) println("splicing has failed: cannot splice when facing a metalevel breach") + EmptyTree + } else { + if (reifyDebug) println("splicing has succeeded") + var splice = Select(splicee, nme.tree) + splice match { + case InlinedTreeSplice(_, inlinedSymbolTable, tree, _) => + if (reifyDebug) println("inlining the splicee") + // all free vars local to the enclosing reifee should've already been inlined by ``Metalevels'' + inlinedSymbolTable foreach { case freedef @ FreeDef(_, _, binding, _) => assert(!binding.symbol.isLocalToReifee, freedef) } + symbolTable ++= inlinedSymbolTable + tree + case tree => + // we need to preserve types of exprs, because oftentimes they cannot be inferred later + // this circumvents regular reification scheme, therefore we go the extra mile here + new Transformer { + override def transform(tree: Tree) = super.transform(tree match { + case NestedExpr(factory, tree, typetag) => + val typedFactory = TypeApply(factory, List(TypeTree(typetag.tpe.typeArgs(0)))) + Apply(Apply(typedFactory, List(tree)), List(typetag)) + case _ => + tree + }) + }.transform(tree) + } + } + case ValueSplice(splicee) => + // todo. implement this + ??? + case _ => + EmptyTree + } + } + + private def reifyBoundTerm(tree: Tree): Tree = tree match { + case tree @ This(_) if tree.symbol == NoSymbol => + throw new Error("unexpected: bound term that doesn't have a symbol: " + showRaw(tree)) + case tree @ This(_) if tree.symbol.isClass && !tree.symbol.isModuleClass && !tree.symbol.isLocalToReifee => + val sym = tree.symbol + if (reifyDebug) println("This for %s, reified as freeVar".format(sym)) + if (reifyDebug) println("Free: " + sym) + mirrorCall(nme.Ident, reifyFreeTerm(sym, This(sym))) + case tree @ This(_) if !tree.symbol.isLocalToReifee => + if (reifyDebug) println("This for %s, reified as This".format(tree.symbol)) + mirrorCall(nme.This, reify(tree.symbol)) + case tree @ This(_) if tree.symbol.isLocalToReifee => + mirrorCall(nme.This, reify(tree.qual)) + case tree @ Ident(_) if tree.symbol == NoSymbol => + // this sometimes happens, e.g. for binds that don't have a body + // or for untyped code generated during previous phases + // (see a comment in Reifiers about the latter, starting with "why do we resetAllAttrs?") + mirrorCall(nme.Ident, reify(tree.name)) + case tree @ Ident(_) if !tree.symbol.isLocalToReifee => + if (tree.symbol.isVariable && tree.symbol.owner.isTerm) { + captureVariable(tree.symbol) // Note order dependency: captureVariable needs to come before reification here. + mirrorCall(nme.Select, mirrorCall(nme.Ident, reify(tree.symbol)), reify(nme.elem)) + } else { + mirrorCall(nme.Ident, reify(tree.symbol)) + } + case tree @ Ident(_) if tree.symbol.isLocalToReifee => + mirrorCall(nme.Ident, reify(tree.name)) + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } + + private def reifyBoundType(tree: Tree): Tree = { + def reifyBoundType(tree: Tree): Tree = { + if (tree.tpe == null) + throw new Error("unexpected: bound type that doesn't have a tpe: " + showRaw(tree)) + + if (tree.symbol.isLocalToReifee) + reifyProduct(tree) + else { + val sym0 = tree.symbol + val sym = sym0.dealias + val tpe0 = tree.tpe + val tpe = tpe0.dealias + if (reifyDebug) println("reifying bound type %s (underlying type is %s, dealiased is %s)".format(sym0, tpe0, tpe)) + + if (eligibleForSplicing(tpe)) { + val spliced = spliceType(tpe) + if (spliced == EmptyTree) { + if (reifyDebug) println("splicing failed: reify as is") + mirrorCall(nme.TypeTree, reifyType(tpe)) + } else { + spliced match { + case TypeRefToFreeType(freeType) => + if (reifyDebug) println("splicing returned a free type: " + freeType) + Ident(freeType) + case _ => + if (reifyDebug) println("splicing succeeded: " + spliced) + mirrorCall(nme.TypeTree, spliced) + } + } + } else { + if (sym.isLocatable) { + if (reifyDebug) println("tpe is locatable: reify as Ident(%s)".format(sym)) + mirrorCall(nme.Ident, reify(sym)) + } else { + if (reifyDebug) println("tpe is an alias, but not a locatable: reify as TypeTree(%s)".format(tpe)) + mirrorCall(nme.TypeTree, reifyType(tpe)) + } + } + } + } + + tree match { + case Select(_, _) => + reifyBoundType(tree) + case SelectFromTypeTree(_, _) => + reifyBoundType(tree) + case Ident(_) => + reifyBoundType(tree) + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } + } + + private def reifyNestedFreeDef(tree: Tree): Tree = { + if (reifyDebug) println("nested free def: %s".format(showRaw(tree))) + reifyProduct(tree) + } + + private def reifyNestedFreeRef(tree: Tree): Tree = tree match { + case Apply(Select(mrRef @ Ident(_), ident), List(Ident(name: TermName))) if ident == nme.Ident && name.startsWith(nme.MIRROR_FREE_PREFIX) => + if (reifyDebug) println("nested free ref: %s".format(showRaw(tree))) + reifyProduct(tree) + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } + + private def reifyNestedExpr(tree: Tree): Tree = tree match { + case NestedExpr(factory, tree, typetag) => + // we need to preserve types of exprs, because oftentimes they cannot be inferred later + // this circumvents regular reification scheme, therefore we go through this crazy dance + if (reifyDebug) println("nested expr: %s".format(showRaw(tree))) + val rtype = mirrorCall(nme.TypeTree, reify(typetag.tpe.typeArgs(0))) + val rfactory = mirrorCall(nme.TypeApply, reify(factory), mkList(List(rtype))) + val rexpr = mirrorCall(nme.Apply, rfactory, reify(List(tree))) + val rwrapped = mirrorCall(nme.Apply, rexpr, reify(List(typetag))) + rwrapped + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala new file mode 100644 index 0000000000..6f3a60a076 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -0,0 +1,226 @@ +package scala.reflect.reify +package codegen + +trait Types { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * Reify a type. + * For internal use only, use ``reified'' instead. + */ + def reifyType(tpe0: Type): Tree = { + assert(tpe0 != null, "tpe is null") + val tpe = tpe0.dealias + + if (tpe.isErroneous) + CannotReifyErroneousReifee(tpe) + if (tpe.isLocalToReifee) + CannotReifyType(tpe) + + // [Eugene] how do I check that the substitution is legal w.r.t tpe.info? + val spliced = spliceType(tpe) + if (spliced != EmptyTree) + return spliced + + val tsym = tpe.typeSymbol + if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic) + Select(reify(tpe.typeSymbol), nme.asTypeConstructor) + else tpe match { + case tpe @ NoType => + reifyMirrorObject(tpe) + case tpe @ NoPrefix => + reifyMirrorObject(tpe) + case tpe @ ThisType(root) if root == RootClass => + mirrorSelect("definitions.RootClass.thisPrefix") + case tpe @ ThisType(empty) if empty == EmptyPackageClass => + mirrorSelect("definitions.EmptyPackageClass.thisPrefix") + case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic => + mirrorCall(nme.thisModuleType, reify(clazz.fullName)) + case tpe @ ThisType(_) => + reifyProduct(tpe) + case tpe @ SuperType(thistpe, supertpe) => + reifyProduct(tpe) + case tpe @ SingleType(pre, sym) => + reifyProduct(tpe) + case tpe @ ConstantType(value) => + mirrorFactoryCall(nme.ConstantType, reifyProduct(value)) + case tpe @ TypeRef(pre, sym, args) => + reifyProduct(tpe) + case tpe @ TypeBounds(lo, hi) => + reifyProduct(tpe) + case tpe @ NullaryMethodType(restpe) => + reifyProduct(tpe) + case tpe @ AnnotatedType(anns, underlying, selfsym) => +// reifyAnnotatedType(tpe) + CannotReifyType(tpe) + case _ => +// reifyToughType(tpe) + CannotReifyType(tpe) + } + } + + /** An obscure flag necessary for implicit TypeTag generation */ + private var spliceTypesEnabled = !dontSpliceAtTopLevel + + /** Keeps track of whether this reification contains abstract type parameters */ + var maybeGround = true + var definitelyGround = true + + def eligibleForSplicing(tpe: Type): Boolean = { + // [Eugene] is this comprehensive? + // the only thingies that we want to splice are: 1) type parameters, 2) type members + // this check seems to cover them all, right? + tpe.isInstanceOf[TypeRef] && tpe.typeSymbol.isAbstractType + } + + private type SpliceCacheKey = (Symbol, Symbol) + private lazy val spliceCache: collection.mutable.Map[SpliceCacheKey, Tree] = { + val cache = analyzer.perRunMacroCache.getOrElseUpdate(MacroContextReify, collection.mutable.Map[Any, Any]()) + cache.getOrElseUpdate("spliceCache", collection.mutable.Map[SpliceCacheKey, Tree]()).asInstanceOf[collection.mutable.Map[SpliceCacheKey, Tree]] + } + + def spliceType(tpe: Type): Tree = { + if (eligibleForSplicing(tpe)) { + if (reifyDebug) println("splicing " + tpe) + + if (spliceTypesEnabled) { + var tagClass = if (requireGroundTypeTag) GroundTypeTagClass else TypeTagClass + val tagTpe = singleType(prefix.tpe, prefix.tpe member tagClass.name) + + // [Eugene] this should be enough for an abstract type, right? + val key = (tagClass, tpe.typeSymbol) + if (reifyDebug && spliceCache.contains(key)) println("cache hit: " + spliceCache(key)) + val result = spliceCache.getOrElseUpdate(key, { + // if this fails, it might produce the dreaded "erroneous or inaccessible type" error + // to find out the whereabouts of the error run scalac with -Ydebug + if (reifyDebug) println("launching implicit search for %s.%s[%s]".format(prefix, tagClass.name, tpe)) + val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] + typer.resolveTypeTag(positionBearer, prefix.tpe, tpe, requireGroundTypeTag) match { + case failure if failure.isEmpty => + if (reifyDebug) println("implicit search was fruitless") + definitelyGround &= false + maybeGround &= false + EmptyTree + case success => + if (reifyDebug) println("implicit search has produced a result: " + success) + definitelyGround |= requireGroundTypeTag + maybeGround |= true + var splice = Select(success, nme.tpe) + splice match { + case InlinedTypeSplice(_, inlinedSymbolTable, tpe) => + // all free vars local to the enclosing reifee should've already been inlined by ``Metalevels'' + inlinedSymbolTable foreach { case freedef @ FreeDef(_, _, binding, _) => assert(!binding.symbol.isLocalToReifee, freedef) } + symbolTable ++= inlinedSymbolTable + reifyTrace("inlined the splicee: ")(tpe) + case tpe => + tpe + } + } + }) + if (result != EmptyTree) return result.duplicate + } else { + if (reifyDebug) println("splicing has been cancelled: spliceTypesEnabled = false") + } + + if (requireGroundTypeTag) + CannotReifyGroundTypeTagHavingUnresolvedTypeParameters(tpe) + } + + spliceTypesEnabled = true + EmptyTree + } + + // yet another thingie disabled for simplicity + // in principle, we could retain and reify AnnotatedTypes + // but that'd require reifying every type and symbol inside ann.args + // however, since we've given up on tough types for the moment, the former would be problematic +// private def reifyAnnotatedType(tpe: AnnotatedType): Tree = { +// // ``Reshaper'' transforms annotation infos from symbols back into Modifier.annotations, which are trees +// // so the only place on Earth that can lead to reification of AnnotationInfos is the Ay Tee Land +// // therefore this function is as local as possible, don't move it out of this scope +// def reifyAnnotationInfo(ann: AnnotationInfo): Tree = { +// val reifiedArgs = ann.args map { arg => +// val saved1 = reifyTreeSymbols +// val saved2 = reifyTreeTypes +// +// try { +// // one more quirk of reifying annotations +// // +// // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs +// // that's because a lot of logic expects post-typer trees to have non-null tpes +// // +// // Q: reified trees are pre-typer, so there's shouldn't be a problem. +// // reflective typechecker will fill in missing symbols and types, right? +// // A: actually, no. annotation ASTs live inside AnnotatedTypes, +// // and insides of the types is the place where typechecker doesn't look. +// reifyTreeSymbols = true +// reifyTreeTypes = true +// +// // todo. every AnnotationInfo is an island, entire of itself +// // no regular Traverser or Transformer can reach it +// // hence we need to run its contents through the entire reification pipeline +// // e.g. to apply reshaping or to check metalevels +// reify(arg) +// } finally { +// reifyTreeSymbols = saved1 +// reifyTreeTypes = saved2 +// } +// } +// +// def reifyClassfileAnnotArg(arg: ClassfileAnnotArg): Tree = arg match { +// case LiteralAnnotArg(const) => +// mirrorFactoryCall(nme.LiteralAnnotArg, reifyProduct(const)) +// case ArrayAnnotArg(args) => +// mirrorFactoryCall(nme.ArrayAnnotArg, scalaFactoryCall(nme.Array, args map reifyClassfileAnnotArg: _*)) +// case NestedAnnotArg(ann) => +// mirrorFactoryCall(nme.NestedAnnotArg, reifyAnnotationInfo(ann)) +// } +// +// // if you reify originals of anns, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important +// val reifiedAssocs = ann.assocs map (assoc => scalaFactoryCall(nme.Tuple2, reify(assoc._1), reifyClassfileAnnotArg(assoc._2))) +// mirrorFactoryCall(nme.AnnotationInfo, reify(ann.atp), mkList(reifiedArgs), mkList(reifiedAssocs)) +// } +// +// val AnnotatedType(anns, underlying, selfsym) = tpe +// mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying), reify(selfsym)) +// } + + // previous solution to reifying tough types involved creating dummy symbols (see ``registerReifiableSymbol'' calls below) + // however such symbols lost all the connections with their origins and became almost useless, except for typechecking + // hence this approach was replaced by less powerful, but more principled one based on ``reifyFreeType'' + // it's possible that later on we will revise and revive ``reifyToughType'', but for now it's disabled under an implementation restriction +// /** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */ +// // This is the uncharted territory in the reifier +// private def reifyToughType(tpe: Type): Tree = { +// if (reifyDebug) println("tough type: %s (%s)".format(tpe, tpe.kind)) +// +// def reifyScope(scope: Scope): Tree = { +// scope foreach registerReifiableSymbol +// mirrorCall(nme.newScopeWith, scope.toList map reify: _*) +// } +// +// tpe match { +// case tpe @ RefinedType(parents, decls) => +// registerReifiableSymbol(tpe.typeSymbol) +// mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) +// case tpe @ ExistentialType(tparams, underlying) => +// tparams foreach registerReifiableSymbol +// mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) +// case tpe @ ClassInfoType(parents, decls, clazz) => +// registerReifiableSymbol(clazz) +// mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) +// case tpe @ MethodType(params, restpe) => +// params foreach registerReifiableSymbol +// mirrorFactoryCall(tpe, reify(params), reify(restpe)) +// case tpe @ PolyType(tparams, underlying) => +// tparams foreach registerReifiableSymbol +// mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) +// case _ => +// throw new Error("internal error: %s (%s) is not supported".format(tpe, tpe.kind)) +// } +// } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Util.scala b/src/compiler/scala/reflect/reify/codegen/Util.scala new file mode 100644 index 0000000000..bb369a1adb --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Util.scala @@ -0,0 +1,112 @@ +package scala.reflect.reify +package codegen + +trait Util { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + val reifyDebug = settings.Yreifydebug.value + val reifyCopypaste = settings.Yreifycopypaste.value + val reifyTrace = scala.tools.nsc.util.trace when reifyDebug + object reifiedNodePrinters extends { val global: mirror.type = mirror } with tools.nsc.ast.NodePrinters with NodePrinters + val reifiedNodeToString = reifiedNodePrinters.reifiedNodeToString + + def reifyList(xs: List[Any]): Tree = + mkList(xs map reify) + + def reifyProduct(x: Product): Tree = + reifyProduct(x.productPrefix, x.productIterator.toList) + + def reifyProduct(prefix: String, elements: List[Any]): Tree = { + // reflection would be more robust, but, hey, this is a hot path + if (prefix.startsWith("Tuple")) scalaFactoryCall(prefix, (elements map reify).toList: _*) + else mirrorCall(prefix, (elements map reify): _*) + } + + // helper functions + + /** Reify a case object defined in Mirror */ + def reifyMirrorObject(name: String): Tree = + mirrorSelect(name) + + def reifyMirrorObject(x: Product): Tree = + reifyMirrorObject(x.productPrefix) + + def call(fname: String, args: Tree*): Tree = + Apply(termPath(fname), args.toList) + + def mirrorSelect(name: String): Tree = + termPath(nme.MIRROR_PREFIX + name) + + def mirrorCall(name: TermName, args: Tree*): Tree = + call("" + (nme.MIRROR_PREFIX append name), args: _*) + + def mirrorCall(name: String, args: Tree*): Tree = + call(nme.MIRROR_PREFIX + name, args: _*) + + def mirrorFactoryCall(value: Product, args: Tree*): Tree = + mirrorFactoryCall(value.productPrefix, args: _*) + + def mirrorFactoryCall(prefix: String, args: Tree*): Tree = + mirrorCall(prefix, args: _*) + + def scalaFactoryCall(name: String, args: Tree*): Tree = + call("scala." + name + ".apply", args: _*) + + def mkList(args: List[Tree]): Tree = + scalaFactoryCall("collection.immutable.List", args: _*) + + /** + * An (unreified) path that refers to definition with given fully qualified name + * @param mkName Creator for last portion of name (either TermName or TypeName) + */ + def path(fullname: String, mkName: String => Name): Tree = { + val parts = fullname split "\\." + val prefixParts = parts.init + val lastName = mkName(parts.last) + if (prefixParts.isEmpty) Ident(lastName) + else { + val prefixTree = ((Ident(prefixParts.head): Tree) /: prefixParts.tail)(Select(_, _)) + Select(prefixTree, lastName) + } + } + + /** An (unreified) path that refers to term definition with given fully qualified name */ + def termPath(fullname: String): Tree = path(fullname, newTermName) + + /** An (unreified) path that refers to type definition with given fully qualified name */ + def typePath(fullname: String): Tree = path(fullname, newTypeName) + + def isTough(tpe: Type) = { + def isTough(tpe: Type) = tpe match { + case _: RefinedType => true + case _: ExistentialType => true + case _: ClassInfoType => true + case _: MethodType => true + case _: PolyType => true + case _ => false + } + + tpe != null && (tpe exists isTough) + } + + def isAnnotated(tpe: Type) = { + def isAnnotated(tpe: Type) = tpe match { + case _: AnnotatedType => true + case _ => false + } + + tpe != null && (tpe exists isAnnotated) + } + + def origin(sym: Symbol) = { + var origin = "" + if (sym.owner != NoSymbol) origin += "defined by %s".format(sym.owner.name) + if (sym.pos != NoPosition) origin += " in %s:%s:%s".format(sym.pos.source.file.name, sym.pos.line, sym.pos.column) + if (origin == "") origin = "of unknown origin" + origin + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala new file mode 100644 index 0000000000..7041fbf6ed --- /dev/null +++ b/src/compiler/scala/reflect/reify/package.scala @@ -0,0 +1,22 @@ +package scala.reflect + +import scala.tools.nsc.Global + +package object reify { + def mkReifier(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Reifier { val mirror: global.type } = { + val typer1: typer.type = typer + val prefix1: prefix.type = prefix + val reifee1 = reifee + val dontSpliceAtTopLevel1 = dontSpliceAtTopLevel + val requireGroundTypeTag1 = requireGroundTypeTag + + new { + val mirror: global.type = global + val typer = typer1 + val prefix = prefix1 + val reifee = reifee1 + val dontSpliceAtTopLevel = dontSpliceAtTopLevel1 + val requireGroundTypeTag = requireGroundTypeTag1 + } with Reifier + } +} diff --git a/src/compiler/scala/reflect/reify/phases/Calculate.scala b/src/compiler/scala/reflect/reify/phases/Calculate.scala new file mode 100644 index 0000000000..59a36f0ba4 --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala @@ -0,0 +1,61 @@ +package scala.reflect.reify +package phases + +trait Calculate { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + implicit def sym2richSym(sym: Symbol): RichSymbol = new RichSymbol(sym) + class RichSymbol(sym: Symbol) { + def metalevel: Int = { assert(sym != NoSymbol); localSymbols.getOrElse(sym, 0) } + def isLocalToReifee = (localSymbols contains sym) // [Eugene] how do I account for local skolems? + } + + implicit def tpe2richTpe(tpe: Type): RichType = new RichType(tpe) + class RichType(tpe: Type) { + def isLocalToReifee = tpe != null && (tpe exists (tp => (localSymbols contains tp.typeSymbol) || (localSymbols contains tp.termSymbol))) + } + + private var localSymbols = collection.mutable.Map[Symbol, Int]() // set of all symbols that are local to the tree to be reified + private def registerLocalSymbol(sym: Symbol, metalevel: Int): Unit = + if (sym != null && sym != NoSymbol) { + if (localSymbols contains sym) + assert(localSymbols(sym) == metalevel, "metalevel mismatch: expected %s, actual %s".format(localSymbols(sym), metalevel)) + localSymbols(sym) = metalevel + } + + /** + * Merely traverses the reifiee and records local symbols along with their metalevels. + */ + val calculate = new Traverser { + // see the explanation of metalevels in ``Metalevels'' + var currMetalevel = 1 + + override def traverse(tree: Tree): Unit = tree match { + case TreeSplice(_) => + currMetalevel -= 1 + try super.traverse(tree) + finally currMetalevel += 1 + case tree if tree.isDef => + if (reifyDebug) println("boundSym: %s of type %s".format(tree.symbol, (tree.productIterator.toList collect { case tt: TypeTree => tt } headOption).getOrElse(TypeTree(tree.tpe)))) + registerLocalSymbol(tree.symbol, currMetalevel) + + bindRelatedSymbol(tree.symbol.sourceModule, "sourceModule") + bindRelatedSymbol(tree.symbol.moduleClass, "moduleClass") + bindRelatedSymbol(tree.symbol.companionClass, "companionClass") + bindRelatedSymbol(tree.symbol.companionModule, "companionModule") + Some(tree.symbol) collect { case termSymbol: TermSymbol => bindRelatedSymbol(termSymbol.referenced, "referenced") } + def bindRelatedSymbol(related: Symbol, name: String): Unit = + if (related != null && related != NoSymbol) { + if (reifyDebug) println("boundSym (" + name + "): " + related) + registerLocalSymbol(related, currMetalevel) + } + super.traverse(tree) + case _ => + super.traverse(tree) + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/phases/Metalevels.scala b/src/compiler/scala/reflect/reify/phases/Metalevels.scala new file mode 100644 index 0000000000..a329a1043d --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Metalevels.scala @@ -0,0 +1,148 @@ +package scala.reflect.reify +package phases + +trait Metalevels { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * Makes sense of cross-stage bindings. + * + * ================ + * + * Analysis of cross-stage bindings becomes convenient if we introduce the notion of metalevels. + * Metalevel of a tree is a number that gets incremented every time you reify something and gets decremented when you splice something. + * Metalevel of a symbol is equal to the metalevel of its definition. + * + * Example 1. Consider the following snippet: + * + * reify { + * val x = 2 // metalevel of symbol x is 1, because it's declared inside reify + * val y = reify{x} // metalevel of symbol y is 1, because it's declared inside reify + * // metalevel of Ident(x) is 2, because it's inside two reifies + * y.eval // metalevel of Ident(y) is 0, because it's inside a designator of a splice + * } + * + * Cross-stage bindings are introduced when symbol.metalevel != curr_metalevel. + * Both bindings introduced in Example 1 are cross-stage. + * + * Depending on what side of the inequality is greater, the following situations might occur: + * + * 1) symbol.metalevel < curr_metalevel. In this case reifier will generate a free variable + * that captures both the name of the symbol (to be compiled successfully) and its value (to be run successfully). + * For example, x in Example 1 will be reified as follows: Ident(newFreeVar("x", IntClass.tpe, x)) + * + * 2) symbol.metalevel > curr_metalevel. This leads to a metalevel breach that violates intuitive perception of splicing. + * As defined in macro spec, splicing takes a tree and inserts it into another tree - as simple as that. + * However, how exactly do we do that in the case of y.eval? In this very scenario we can use dataflow analysis and inline it, + * but what if y were a var, and what if it were calculated randomly at runtime? + * + * This question has a genuinely simple answer. Sure, we cannot resolve such splices statically (i.e. during macro expansion of ``reify''), + * but now we have runtime toolboxes, so noone stops us from picking up that reified tree and evaluating it at runtime + * (in fact, this is something that ``Expr.eval'' and ``Expr.value'' do transparently). + * + * This is akin to early vs late binding dilemma. + * The prior is faster, plus, the latter (implemented with reflection) might not work because of visibility issues or might be not available on all platforms. + * But the latter still has its uses, so I'm allowing metalevel breaches, but introducing the -Xlog-runtime-evals to log them. + * + * ================ + * + * As we can see, the only problem is the fact that lhs'es of eval can be code blocks that can capture variables from the outside. + * Code inside the lhs of an eval is not reified, while the code from the enclosing reify is. + * + * Hence some bindings become cross-stage, which is not bad per se (in fact, some cross-stage bindings have sane semantics, as in the example above). + * However this affects freevars, since they are delicate inter-dimensional beings that refer to both current and next planes of existence. + * When splicing tears the fabric of the reality apart, some freevars have to go single-dimensional to retain their sanity. + * + * Example 2. Consider the following snippet: + * + * reify { + * val x = 2 + * reify{x}.eval + * } + * + * Since the result of the inner reify is wrapped in an eval, it won't be reified + * together with the other parts of the outer reify, but will be inserted into that result verbatim. + * + * The inner reify produces an Expr[Int] that wraps Ident(freeVar("x", IntClass.tpe, x)). + * However the freevar the reification points to will vanish when the compiler processes the outer reify. + * That's why we need to replace that freevar with a regular symbol that will point to reified x. + * + * Example 3. Consider the following fragment: + * + * reify { + * val x = 2 + * val y = reify{x} + * y.eval + * } + * + * In this case the inner reify doesn't appear next to eval, so it will be reified together with x. + * This means that no special processing is needed here. + * + * Example 4. Consider the following fragment: + * + * reify { + * val x = 2 + * { + * val y = 2 + * val z = reify{reify{x + y}} + * z.eval + * }.eval + * } + * + * The reasoning from Example 2 still holds here - we do need to inline the freevar that refers to x. + * However, we must not touch anything inside the eval'd block, because it's not getting reified. + */ + var metalevels = new Transformer { + var insideSplice = false + var freedefsToInline = collection.mutable.Map[String, ValDef]() + + def withinSplice[T](op: => T) = { + val old = insideSplice + insideSplice = true + try op + finally insideSplice = old + } + + // Q: here we deal with all sorts of reified trees. what about ReifiedType(_, _, _, _)? + // A: nothing. reified trees give us problems because they sometimes create dimensional rifts as described above + // to the contrast, reified types (i.e. synthetic typetags materialized by Implicits.scala) always stay on the same metalevel as their enclosing code + override def transform(tree: Tree): Tree = tree match { + case InlineableTreeSplice(splicee, inlinedSymbolTable, _, _, flavor) => + if (reifyDebug) println("entering inlineable splice: " + splicee) + val Block(mrDef :: symbolTable, expr) = splicee + // [Eugene] how to express the fact that a scrutinee is both of some type and matches an extractor? + val freedefsToInline = symbolTable collect { case freedef @ FreeTermDef(_, _, binding, _) if binding.symbol.isLocalToReifee => freedef.asInstanceOf[ValDef] } + freedefsToInline foreach (vdef => this.freedefsToInline(vdef.name) = vdef) + val symbolTable1 = symbolTable diff freedefsToInline + val tree1 = Select(Block(mrDef :: symbolTable1, expr), flavor) + if (reifyDebug) println("trimmed %s inlineable free defs from its symbol table: %s".format(freedefsToInline.length, freedefsToInline map (_.name) mkString(", "))) + withinSplice { super.transform(tree1) } + case TreeSplice(splicee) => + if (reifyDebug) println("entering splice: " + splicee) + val hasBreaches = splicee exists (_.symbol.metalevel > 0) + if (!insideSplice && hasBreaches) { + if (settings.logRuntimeSplices.value) reporter.echo(tree.pos, "this splice cannot be resolved statically") + if (reifyDebug) println("metalevel breach in %s: %s".format(tree, (splicee filter (_.symbol.metalevel > 0) map (_.symbol) distinct) mkString ", ")) + } + withinSplice { super.transform(tree) } + // todo. also inline usages of ``freedefsToInline'' in the symbolTable itself + // e.g. a free$Foo can well use free$x, if Foo is path-dependent w.r.t x + // FreeRef(_, _) check won't work, because metalevels of symbol table and body are different, hence, freerefs in symbol table look different from freerefs in body + // todo. also perform garbage collection on local symbols + // so that local symbols used only in type signatures of free vars get removed + case FreeRef(mr, name) if freedefsToInline contains name => + if (reifyDebug) println("inlineable free ref: %s in %s".format(name, showRaw(tree))) + val freedef @ FreeDef(_, _, binding, _) = freedefsToInline(name) + if (reifyDebug) println("related definition: %s".format(showRaw(freedef))) + val inlined = reify(binding) + if (reifyDebug) println("verdict: inlined as %s".format(showRaw(inlined))) + inlined + case _ => + super.transform(tree) + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala new file mode 100644 index 0000000000..f6d6423605 --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Reify.scala @@ -0,0 +1,42 @@ +package scala.reflect.reify +package phases + +import scala.runtime.ScalaRunTime.isAnyVal +import scala.runtime.ScalaRunTime.isTuple +import scala.reflect.reify.codegen._ + +trait Reify extends Symbols + with Types + with Names + with Trees + with Positions + with Util { + + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * Reifies any supported value. + * For internal use only, use ``reified'' instead. + */ + def reify(reifee: Any): Tree = reifee match { + // before adding some case here, in global scope, please, consider + // whether it can be localized like reifyAnnotationInfo or reifyScope + // this will help reification stay as sane as possible + case sym: Symbol => reifySymRef(sym) + case tpe: Type => reifyType(tpe) + case name: Name => reifyName(name) + case tree: Tree => reifyTree(tree) + case pos: Position => reifyPosition(pos) + case mods: mirror.Modifiers => reifyModifiers(mods) + case xs: List[_] => reifyList(xs) + case s: String => Literal(Constant(s)) + case v if isAnyVal(v) => Literal(Constant(v)) + case null => Literal(Constant(null)) + case _ => + throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass)) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala new file mode 100644 index 0000000000..e700604612 --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -0,0 +1,296 @@ +package scala.reflect.reify +package phases + +import scala.tools.nsc.symtab.Flags._ + +trait Reshape { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * Rolls back certain changes that were introduced during typechecking of the reifee. + * + * These include: + * * Replacing type trees with TypeTree(tpe) + * * Transforming Modifiers.annotations into Symbol.annotations + * * Transforming Annotated annotations into AnnotatedType annotations + * * Transforming Annotated(annot, expr) into Typed(expr, TypeTree(Annotated(annot, _)) + * * Non-idempotencies of the typechecker: https://issues.scala-lang.org/browse/SI-5464 + */ + val reshape = new Transformer { + var currentSymbol: Symbol = NoSymbol + + override def transform(tree: Tree) = { + currentSymbol = tree.symbol + + val preTyper = tree match { + case tree if tree.isErroneous => + tree + case tt @ TypeTree() => + toPreTyperTypeTree(tt) + case toa @ TypedOrAnnotated(_) => + toPreTyperTypedOrAnnotated(toa) + case ta @ TypeApply(hk, ts) => + val discard = ts collect { case tt: TypeTree => tt } exists isDiscarded + if (reifyDebug && discard) println("discarding TypeApply: " + tree) + if (discard) hk else ta + case classDef @ ClassDef(mods, name, params, impl) => + val Template(parents, self, body) = impl + var body1 = trimAccessors(classDef, body) + body1 = trimSyntheticCaseClassMembers(classDef, body1) + var impl1 = Template(parents, self, body1).copyAttrs(impl) + ClassDef(mods, name, params, impl1).copyAttrs(classDef) + case moduledef @ ModuleDef(mods, name, impl) => + val Template(parents, self, body) = impl + var body1 = trimAccessors(moduledef, body) + body1 = trimSyntheticCaseClassMembers(moduledef, body1) + var impl1 = Template(parents, self, body1).copyAttrs(impl) + ModuleDef(mods, name, impl1).copyAttrs(moduledef) + case template @ Template(parents, self, body) => + val discardedParents = parents collect { case tt: TypeTree => tt } filter isDiscarded + if (reifyDebug && discardedParents.length > 0) println("discarding parents in Template: " + discardedParents.mkString(", ")) + val parents1 = parents diff discardedParents + val body1 = trimSyntheticCaseClassCompanions(body) + Template(parents1, self, body1).copyAttrs(template) + case block @ Block(stats, expr) => + val stats1 = trimSyntheticCaseClassCompanions(stats) + Block(stats1, expr).copyAttrs(block) + case valdef @ ValDef(mods, name, tpt, rhs) if valdef.symbol.isLazy => + if (reifyDebug) println("dropping $lzy in lazy val's name: " + tree) + val name1 = if (name endsWith nme.LAZY_LOCAL) name dropRight nme.LAZY_LOCAL.length else name + ValDef(mods, name1, tpt, rhs).copyAttrs(valdef) + case unapply @ UnApply(fun, args) => + def extractExtractor(tree: Tree): Tree = { + val Apply(fun, args) = tree + args match { + case List(Ident(special)) if special == nme.SELECTOR_DUMMY => + val Select(extractor, flavor) = fun + assert(flavor == nme.unapply || flavor == nme.unapplySeq) + extractor + case _ => + extractExtractor(fun) + } + } + + if (reifyDebug) println("unapplying unapply: " + tree) + val fun1 = extractExtractor(fun) + Apply(fun1, args).copyAttrs(unapply) + case Literal(const @ Constant(tpe: Type)) => + // todo. implement this + ??? + case Literal(const @ Constant(sym: Symbol)) => + // todo. implement this + ??? + case _ => + tree + } + + super.transform(preTyper) + } + + override def transformModifiers(mods: Modifiers) = { + val mods1 = toPreTyperModifiers(mods, currentSymbol) + super.transformModifiers(mods1) + } + + private def toPreTyperModifiers(mods: Modifiers, sym: Symbol) = { + if (!sym.annotations.isEmpty) { + val Modifiers(flags, privateWithin, annotations) = mods + val postTyper = sym.annotations filter (_.original != EmptyTree) + if (reifyDebug && !postTyper.isEmpty) println("reify symbol annotations for: " + sym) + if (reifyDebug && !postTyper.isEmpty) println("originals are: " + sym.annotations) + val preTyper = postTyper map toPreTyperAnnotation + mods.withAnnotations(preTyper) + } else { + mods + } + } + + /** Restore pre-typer representation of a type. + * + * NB: This is the trickiest part of reification! + * + * In most cases, we're perfectly fine to reify a Type itself (see ``reifyType''). + * However if the type involves a symbol declared inside the quasiquote (i.e. registered in ``boundSyms''), + * then we cannot reify it, or otherwise subsequent reflective compilation will fail. + * + * Why will it fail? Because reified deftrees (e.g. ClassDef(...)) will generate fresh symbols during that compilation, + * so naively reified symbols will become out of sync, which brings really funny compilation errors and/or crashes, e.g.: + * https://issues.scala-lang.org/browse/SI-5230 + * + * To deal with this unpleasant fact, we need to fall back from types to equivalent trees (after all, parser trees don't contain any types, just trees, so it should be possible). + * Luckily, these original trees get preserved for us in the ``original'' field when Trees get transformed into TypeTrees. + * And if an original of a type tree is empty, we can safely assume that this type is non-essential (e.g. was inferred/generated by the compiler). + * In that case the type can be omitted (e.g. reified as an empty TypeTree), since it will be inferred again later on. + * + * An important property of the original is that it isn't just a pre-typer tree. + * It's actually kind of a post-typer tree with symbols assigned to its Idents (e.g. Ident("List") will contain a symbol that points to immutable.this.List). + * This is very important, since subsequent reflective compilation won't have to resolve these symbols. + * In general case, such resolution cannot be performed, since reification doesn't preserve lexical context, + * which means that reflective compilation won't be aware of, say, imports that were provided when the reifee has been compiled. + * + * This workaround worked surprisingly well and allowed me to fix several important reification bugs, until the abstraction has leaked. + * Suddenly I found out that in certain contexts original trees do not contain symbols, but are just parser trees. + * To the moment I know only one such situation: typedAnnotations does not typecheck the annotation in-place, but rather creates new trees and typechecks them, so the original remains symless. + * Thus we apply a workaround for that in typedAnnotated. I hope this will be the only workaround in this department. + * + * upd. Recently I went ahead and started using original for all TypeTrees, regardless of whether they refer to local symbols or not. + * As a result, ``reifyType'' is never called directly by tree reification (and, wow, it seems to work great!). + * The only usage of ``reifyType'' now is for servicing typetags, however, I have some ideas how to get rid of that as well. + */ + private def isDiscarded(tt: TypeTree) = tt.original == null + private def toPreTyperTypeTree(tt: TypeTree): Tree = { + if (tt.original != null) { + // here we rely on the fact that the originals that reach this point + // have all necessary symbols attached to them (i.e. that they can be recompiled in any lexical context) + // if this assumption fails, please, don't be quick to add postprocessing here (like I did before) + // but rather try to fix this in Typer, so that it produces quality originals (like it's done for typedAnnotated) + if (reifyDebug) println("TypeTree, essential: %s (%s)".format(tt.tpe, tt.tpe.kind)) + if (reifyDebug) println("verdict: rolled back to original %s".format(tt.original)) + transform(tt.original) + } else { + // type is deemed to be non-essential + // erase it and hope that subsequent reflective compilation will be able to recreate it again + if (reifyDebug) println("TypeTree, non-essential: %s (%s)".format(tt.tpe, tt.tpe.kind)) + if (reifyDebug) println("verdict: discarded") + TypeTree() + } + } + + private def toPreTyperTypedOrAnnotated(tree: Tree): Tree = tree match { + case ty @ Typed(expr1, tt @ TypeTree()) => + if (reifyDebug) println("reify typed: " + tree) + val annotatedArg = { + def loop(tree: Tree): Tree = tree match { + case annotated1 @ Annotated(ann, annotated2 @ Annotated(_, _)) => loop(annotated2) + case annotated1 @ Annotated(ann, arg) => arg + case _ => EmptyTree + } + + loop(tt.original) + } + if (annotatedArg != EmptyTree) { + if (annotatedArg.isType) { + if (reifyDebug) println("verdict: was an annotated type, reify as usual") + ty + } else { + if (reifyDebug) println("verdict: was an annotated value, equivalent is " + tt.original) + toPreTyperTypedOrAnnotated(tt.original) + } + } else { + if (reifyDebug) println("verdict: wasn't annotated, reify as usual") + ty + } + case at @ Annotated(annot, arg) => + if (reifyDebug) println("reify type annotations for: " + tree) + assert(at.tpe.isInstanceOf[AnnotatedType], "%s (%s)".format(at.tpe, at.tpe.kind)) + val annot1 = toPreTyperAnnotation(at.tpe.asInstanceOf[AnnotatedType].annotations(0)) + if (reifyDebug) println("originals are: " + annot1) + Annotated(annot1, arg).copyAttrs(at) + } + + /** Restore pre-typer representation of an annotation. + * The trick here is to retain the symbols that have been populated during typechecking of the annotation. + * If we do not do that, subsequent reflective compilation will fail. + */ + private def toPreTyperAnnotation(ann: AnnotationInfo): Tree = { + val args = if (ann.assocs.isEmpty) { + ann.args + } else { + def toScalaAnnotation(jann: ClassfileAnnotArg): Tree = jann match { + case LiteralAnnotArg(const) => + Literal(const) + case ArrayAnnotArg(arr) => + Apply(Ident(definitions.ArrayModule), arr.toList map toScalaAnnotation) + case NestedAnnotArg(ann) => + toPreTyperAnnotation(ann) + } + + ann.assocs map { case (nme, arg) => AssignOrNamedArg(Ident(nme), toScalaAnnotation(arg)) } + } + + def extractOriginal: PartialFunction[Tree, Tree] = { case Apply(Select(New(tpt), _), _) => tpt } + assert(extractOriginal.isDefinedAt(ann.original), showRaw(ann.original)) + 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]]() + stats collect { case ddef: DefDef => ddef } foreach (defdef => { + val valdef = symdefs get defdef.symbol.accessedOrSelf collect { case vdef: ValDef => vdef } getOrElse null + if (valdef != null) accessors(valdef) = accessors.getOrElse(valdef, Nil) :+ defdef + + def detectBeanAccessors(prefix: String): Unit = { + if (defdef.name.startsWith(prefix)) { + var name = defdef.name.toString.substring(prefix.length) + def uncapitalize(s: String) = if (s.length == 0) "" else { val chars = s.toCharArray; chars(0) = chars(0).toLower; new String(chars) } + def findValDef(name: String) = symdefs.values collect { case vdef: ValDef if nme.dropLocalSuffix(vdef.name).toString == name => vdef } headOption; + val valdef = findValDef(name) orElse findValDef(uncapitalize(name)) orNull; + if (valdef != null) accessors(valdef) = accessors.getOrElse(valdef, Nil) :+ defdef + } + } + detectBeanAccessors("get") + detectBeanAccessors("set") + detectBeanAccessors("is") + }); + + var stats1 = stats flatMap { + case vdef @ ValDef(mods, name, tpt, rhs) => + val mods1 = if (accessors.contains(vdef)) { + val ddef = accessors(vdef)(0) // any accessor will do + val Modifiers(flags, privateWithin, annotations) = mods + var flags1 = flags & ~LOCAL + if (!ddef.symbol.isPrivate) flags1 = flags1 & ~PRIVATE + val privateWithin1 = ddef.mods.privateWithin + val annotations1 = accessors(vdef).foldLeft(annotations)((curr, acc) => curr ++ (acc.symbol.annotations map toPreTyperAnnotation)) + Modifiers(flags1, privateWithin1, annotations1) setPositions mods.positions + } else { + mods + } + val mods2 = toPreTyperModifiers(mods1, vdef.symbol) + 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 + case ddef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) => + if (accessors.values.exists(_.contains(ddef))) { + if (reifyDebug) println("discarding accessor method: " + ddef) + None + } else { + Some(ddef) + } + case tree => + Some(tree) + } + + stats1 + } + + private def trimSyntheticCaseClassMembers(deff: Tree, stats: List[Tree]): List[Tree] = + stats filterNot (memberDef => memberDef.isDef && { + val isSynthetic = memberDef.symbol.isSynthetic + // this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass) + // that's why I replace the check with an assumption that all synthetic members are, in fact, generated of case classes + // val isCaseMember = deff.symbol.isCaseClass || deff.symbol.companionClass.isCaseClass + val isCaseMember = true + if (isSynthetic && isCaseMember && reifyDebug) println("discarding case class synthetic def: " + memberDef) + isSynthetic && isCaseMember + }) + + private def trimSyntheticCaseClassCompanions(stats: List[Tree]): List[Tree] = + stats diff (stats collect { case moddef: ModuleDef => moddef } filter (moddef => { + val isSynthetic = moddef.symbol.isSynthetic + // this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass) + // that's why I replace the check with an assumption that all synthetic modules are, in fact, companions of case classes + // val isCaseCompanion = moddef.symbol.companionClass.isCaseClass + val isCaseCompanion = true + if (isSynthetic && isCaseCompanion && reifyDebug) println("discarding synthetic case class companion: " + moddef) + isSynthetic && isCaseCompanion + })) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/runtime/ClassLoaders.scala b/src/compiler/scala/reflect/runtime/ClassLoaders.scala new file mode 100644 index 0000000000..b73d57c04d --- /dev/null +++ b/src/compiler/scala/reflect/runtime/ClassLoaders.scala @@ -0,0 +1,25 @@ +package scala.reflect +package runtime + +trait ClassLoaders extends internal.SymbolTable { self: SymbolTable => + + def staticClass(fullname: String) = + definitions.getRequiredClass(fullname) + + def staticModule(fullname: String) = + definitions.getRequiredModule(fullname) + + /** If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package + * ., otherwise return NoSymbol. + * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead. + */ + override def missingHook(owner: Symbol, name: Name): Symbol = + if (owner.isRoot && isJavaClass(name.toString)) + definitions.EmptyPackageClass.info decl name + else if (name.isTermName && owner.hasPackageFlag && !owner.isEmptyPackageClass) + makeScalaPackage(if (owner.isRoot) name.toString else owner.fullName+"."+name).sourceModule + else { + info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass) + super.missingHook(owner, name) + } +} diff --git a/src/compiler/scala/reflect/runtime/ConversionUtil.scala b/src/compiler/scala/reflect/runtime/ConversionUtil.scala index 8c32026e37..e45fc243c6 100644 --- a/src/compiler/scala/reflect/runtime/ConversionUtil.scala +++ b/src/compiler/scala/reflect/runtime/ConversionUtil.scala @@ -12,6 +12,7 @@ trait ConversionUtil { self: SymbolTable => /** A cache that maintains a bijection between Java reflection type `J` * and Scala reflection type `S`. */ + // todo. should be weak protected class TwoWayCache[J, S] { private val toScalaMap = new HashMap[J, S] diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala index 89fd6bab64..6688d77985 100644 --- a/src/compiler/scala/reflect/runtime/JavaToScala.scala +++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala @@ -34,16 +34,42 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => val global: JavaToScala.this.type = self } - protected def defaultReflectiveClassLoader(): JClassLoader = { - val cl = Thread.currentThread.getContextClassLoader - if (cl == null) getClass.getClassLoader else cl - } + /** Defines the classloader that will be used for all class resolution activities in this mirror. + * Is mutable, since sometimes we need to change it in flight (e.g. to make the default mirror work with REPL). + * + * If you want to have a mirror with non-standard class resolution, override this var + * (or, even simpler, use the `mkMirror` function from `scala.reflect` package) + * + * Be careful, though, since fancy stuff might happen. + * Here's one example: + * + * partest uses a URLClassLoader(urls, null) with custom classpath to run workers (in separate threads) + * however it doesn't set the context classloader for them, so they inherit the system classloader + * http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html + * + * Once upon a time, scala.reflect.mirror was loaded using getClass.getClassLoader, + * which also means that classOf[...] constructs such as: + * + * classOf[scala.reflect.ScalaSignature] + * + * in unpickleClass were also loaded by the URLClassLoader + * + * But mirror's classLoader used Thread.currentThread.getContextClassLoader, + * which introduced a subtle bug that made the following snippet incorrectly: + * + * jclazz.getAnnotation(classOf[scala.reflect.ScalaSignature]) + * + * Indeed, jclazz was loaded by context classloader, which defaulted to system classloader, + * while ScalaSignature class was loaded by getClass.getClassLoader, which was incompatible with system classloader. + * As a result, unpickler couldn't see the signature and that blew up the mirror. + */ + var classLoader: ClassLoader /** Paul: It seems the default class loader does not pick up root classes, whereas the system classloader does. * Can you check with your newly acquired classloader fu whether this implementation makes sense? */ def javaClass(path: String): jClass[_] = - javaClass(path, defaultReflectiveClassLoader()) + javaClass(path, classLoader) def javaClass(path: String, classLoader: JClassLoader): jClass[_] = Class.forName(path, true, classLoader) @@ -75,19 +101,70 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => (if (msg eq null) "reflection error while loading " + clazz.name else "error while loading " + clazz.name) + ", " + msg) } - try { - markAbsent(NoType) - val ssig = jclazz.getAnnotation(classOf[scala.reflect.ScalaSignature]) + // don't use classOf[scala.reflect.ScalaSignature] here, because it will use getClass.getClassLoader, not mirror's classLoader + // don't use asInstanceOf either because of the same reason (lol, I cannot believe I fell for it) + // don't use structural types to simplify reflective invocations because of the same reason + // todo. test for this + def loadAnnotation(name: String): java.lang.annotation.Annotation = { + def inferClasspath(cl: ClassLoader) = cl match { + case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]" + case _ => "" + } + def show(cl: ClassLoader) = cl match { + case cl if cl != null => + "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl)) + case null => + import scala.tools.util.PathResolver.Environment._ + "primordial classloader with boot classpath [%s]".format(javaBootClassPath) + } + + try { + val cls_ann = Class.forName(name, true, classLoader) + val anns = jclazz.getAnnotations + val ann = anns find (_.annotationType == cls_ann) orNull; + if (ann == null && anns.find(_.annotationType.getName == name).isDefined) { + val msg = "Mirror classloader mismatch: %s (loaded by %s)%nis unrelated to the mirror's classloader (%s)" + throw new Error(msg.format(jclazz, show(jclazz.getClassLoader), show(classLoader))) + } + ann + } catch { + case ex: ClassNotFoundException => + val msg = "Dysfunctional mirror classloader, cannot load %s: %s." + throw new Error(msg.format(name, show(classLoader)), ex) + } + } + def loadScalaSignature: Option[String] = { + val ssig = loadAnnotation("scala.reflect.ScalaSignature") if (ssig != null) { - info("unpickling Scala "+clazz + " and " + module+ ", owner = " + clazz.owner) - val bytes = ssig.bytes.getBytes - val len = ByteCodecs.decode(bytes) - unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName) + val bytesMethod = ssig.annotationType.getMethod("bytes") + val result = bytesMethod.invoke(ssig) + Some(result.asInstanceOf[String]) } else { - val slsig = jclazz.getAnnotation(classOf[scala.reflect.ScalaLongSignature]) - if (slsig != null) { + None + } + } + def loadScalaLongSignature: Option[Array[String]] = { + val slsig = loadAnnotation("scala.reflect.ScalaLongSignature") + if (slsig != null) { + val bytesMethod = slsig.annotationType.getMethod("bytes") + val result = bytesMethod.invoke(slsig) + Some(result.asInstanceOf[Array[String]]) + } else { + None + } + } + try { + markAbsent(NoType) + val sigs = (loadScalaSignature, loadScalaLongSignature) + sigs match { + case (Some(ssig), _) => + info("unpickling Scala "+clazz + " and " + module+ ", owner = " + clazz.owner) + val bytes = ssig.getBytes + val len = ByteCodecs.decode(bytes) + unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName) + case (_, Some(slsig)) => info("unpickling Scala "+clazz + " and " + module + " with long Scala signature") - val byteSegments = slsig.bytes map (_.getBytes) + val byteSegments = slsig map (_.getBytes) val lens = byteSegments map ByteCodecs.decode val bytes = Array.ofDim[Byte](lens.sum) var len = 0 @@ -96,10 +173,10 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => len += l } unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName) - } else { // class does not have a Scala signature; it's a Java class + case (None, None) => + // class does not have a Scala signature; it's a Java class info("translating reflection info for Java " + jclazz) //debug initClassModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz)) - } } } catch { case ex: MissingRequirementError => @@ -383,52 +460,70 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => */ def classToScala(jclazz: jClass[_]): Symbol = classCache.toScala(jclazz) { val jname = javaTypeName(jclazz) - val owner = sOwner(jclazz) - val simpleName = scalaSimpleName(jclazz) - - val sym = { - def lookup = { - def coreLookup(name: Name): Symbol = { - val sym = owner.info.decl(name) - sym orElse { - if (name.startsWith(nme.NAME_JOIN_STRING)) - coreLookup(name.subName(1, name.length)) - else - NoSymbol + + val sym = + if (jname == fulltpnme.RuntimeNothing) + NothingClass + else if (jname == fulltpnme.RuntimeNull) + NullClass + else + { + val owner = sOwner(jclazz) + val simpleName = scalaSimpleName(jclazz) + + def lookup = { + def coreLookup(name: Name): Symbol = { + val sym = owner.info.decl(name) + sym orElse { + if (name.startsWith(nme.NAME_JOIN_STRING)) + coreLookup(name.subName(1, name.length)) + else + NoSymbol + } + } + + if (nme.isModuleName(simpleName)) { + val moduleName = nme.stripModuleSuffix(simpleName).toTermName + val sym = coreLookup(moduleName) + if (sym == NoSymbol) sym else sym.moduleClass + } else { + coreLookup(simpleName) } } - if (nme.isModuleName(simpleName)) { - val moduleName = nme.stripModuleSuffix(simpleName).toTermName - val sym = coreLookup(moduleName) - if (sym == NoSymbol) sym else sym.moduleClass - } else { - coreLookup(simpleName) + val sym = { + if (jclazz.isMemberClass && !nme.isImplClassName(jname)) { + lookup + } else if (jclazz.isLocalClass || invalidClassName(jname)) { + // local classes and implementation classes not preserved by unpickling - treat as Java + jclassAsScala(jclazz) + } else if (jclazz.isArray) { + ArrayClass + } else javaTypeToValueClass(jclazz) orElse { + // jclazz is top-level - get signature + lookup + // val (clazz, module) = createClassModule( + // sOwner(jclazz), newTypeName(jclazz.getSimpleName), new TopClassCompleter(_, _)) + // classCache enter (jclazz, clazz) + // clazz + } } - } - if (jclazz.isMemberClass && !nme.isImplClassName(jname)) { - lookup - } else if (jclazz.isLocalClass || invalidClassName(jname)) { - // local classes and implementation classes not preserved by unpickling - treat as Java - jclassAsScala(jclazz) - } else if (jclazz.isArray) { - ArrayClass - } else javaTypeToValueClass(jclazz) orElse { - // jclazz is top-level - get signature - lookup - // val (clazz, module) = createClassModule( - // sOwner(jclazz), newTypeName(jclazz.getSimpleName), new TopClassCompleter(_, _)) - // classCache enter (jclazz, clazz) - // clazz - } - } + if (!sym.isType) { + val classloader = jclazz.getClassLoader + println("classloader is: %s of type %s".format(classloader, classloader.getClass)) + def inferClasspath(cl: ClassLoader) = cl match { + case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]" + case _ => "" + } + println("classpath is: %s".format(inferClasspath(classloader))) + def msgNoSym = "no symbol could be loaded from %s (scala equivalent is %s) by name %s".format(owner, jclazz, simpleName) + def msgIsNotType = "not a type: symbol %s loaded from %s (scala equivalent is %s) by name %s".format(sym, owner, jclazz, simpleName) + assert(false, if (sym == NoSymbol) msgNoSym else msgIsNotType) + } - if (!sym.isType) { - def msgNoSym = "no symbol could be loaded from %s (scala equivalent is %s) by name %s".format(owner, jclazz, simpleName) - def msgIsNotType = "not a type: symbol %s loaded from %s (scala equivalent is %s) by name %s".format(sym, owner, jclazz, simpleName) - assert(false, if (sym == NoSymbol) msgNoSym else msgIsNotType) - } + sym + } sym.asInstanceOf[ClassSymbol] } diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala deleted file mode 100644 index 4b35a5b37e..0000000000 --- a/src/compiler/scala/reflect/runtime/Loaders.scala +++ /dev/null @@ -1,130 +0,0 @@ -package scala.reflect -package runtime - -import internal.Flags -import java.lang.{Class => jClass, Package => jPackage} -import collection.mutable - -trait Loaders { self: SymbolTable => - - /** The lazy type for root. - */ - override val rootLoader = new LazyType { - override def complete(sym: Symbol) = sym setInfo new LazyPackageType - } - - /** The standard completer for top-level classes - * @param clazz The top-level class - * @param module The companion object of `clazz` - * Calling `complete` on this type will assign the infos of `clazz` and `module` - * by unpickling information from the corresponding Java class. If no Java class - * is found, a package is created instead. - */ - class TopClassCompleter(clazz: Symbol, module: Symbol) extends SymLoader { -// def makePackage() { -// println("wrong guess; making package "+clazz) -// val ptpe = newPackageType(module.moduleClass) -// for (sym <- List(clazz, module, module.moduleClass)) { -// sym setFlag Flags.PACKAGE -// sym setInfo ptpe -// } -// } - - override def complete(sym: Symbol) = { - debugInfo("completing "+sym+"/"+clazz.fullName) - assert(sym == clazz || sym == module || sym == module.moduleClass) -// try { - atPhaseNotLaterThan(picklerPhase) { - unpickleClass(clazz, module, javaClass(clazz.javaClassName)) -// } catch { -// case ex: ClassNotFoundException => makePackage() -// case ex: NoClassDefFoundError => makePackage() - // Note: We catch NoClassDefFoundError because there are situations - // where a package and a class have the same name except for capitalization. - // It seems in this case the class is loaded even if capitalization differs - // but then a NoClassDefFound error is issued with a ("wrong name: ...") - // reason. (I guess this is a concession to Windows). - // The present behavior is a bit too forgiving, in that it masks - // all class load errors, not just wrong name errors. We should try - // to be more discriminating. To get on the right track simply delete - // the clause above and load a collection class such as collection.Iterable. - // You'll see an error that class `parallel` has the wrong name. -// } - } - } - override def load(sym: Symbol) = complete(sym) - } - - /** Create a class and a companion object, enter in enclosing scope, - * and initialize with a lazy type completer. - * @param owner The owner of the newly created class and object - * @param name The simple name of the newly created class - * @param completer The completer to be used to set the info of the class and the module - */ - protected def createClassModule(owner: Symbol, name: TypeName, completer: (Symbol, Symbol) => LazyType) = { - assert(!(name.toString endsWith "[]"), name) - val clazz = owner.newClass(name) - val module = owner.newModule(name.toTermName) - owner.info.decls enter clazz - owner.info.decls enter module - initClassModule(clazz, module, completer(clazz, module)) - (clazz, module) - } - - protected def setAllInfos(clazz: Symbol, module: Symbol, info: Type) = { - List(clazz, module, module.moduleClass) foreach (_ setInfo info) - } - - protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) = - setAllInfos(clazz, module, completer) - - /** The type completer for packages. - */ - class LazyPackageType extends LazyType { - override def complete(sym: Symbol) { - assert(sym.isPackageClass) - sym setInfo new ClassInfoType(List(), new PackageScope(sym), sym) - // override def safeToString = pkgClass.toString - openPackageModule(sym) - } - } - - /** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because - * these are nested classes or anonymous classes, - */ - def invalidClassName(name: Name) = { - val dp = name pos '$' - 0 < dp && dp < (name.length - 1) - } - - class PackageScope(pkgClass: Symbol) extends Scope() with SynchronizedScope { - assert(pkgClass.isType) - private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. - override def lookupEntry(name: Name): ScopeEntry = { - val e = super.lookupEntry(name) - if (e != null) - e - else if (invalidClassName(name) || (negatives contains name)) - null - else { - val path = - if (pkgClass.isEmptyPackageClass) name.toString - else pkgClass.fullName + "." + name - if (isJavaClass(path)) { - val (clazz, module) = createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _)) - debugInfo("created "+module+"/"+module.moduleClass+" in "+pkgClass) - lookupEntry(name) - } else { - debugInfo("*** not found : "+path) - negatives += name - null - } - } - } - } - - override def newPackageScope(pkgClass: Symbol) = new PackageScope(pkgClass) - - override def scopeTransform(owner: Symbol)(op: => Scope): Scope = - if (owner.isPackageClass) owner.info.decls else op -} diff --git a/src/compiler/scala/reflect/runtime/Memoizer.scala b/src/compiler/scala/reflect/runtime/Memoizer.scala deleted file mode 100644 index 4c1b82ae6d..0000000000 --- a/src/compiler/scala/reflect/runtime/Memoizer.scala +++ /dev/null @@ -1,15 +0,0 @@ -package scala.reflect.runtime - -import collection.mutable.ArrayBuffer -import Mirror.Type - -/** Class that can be used for memoizing types in reified trees */ -class Memoizer { - private val mem = new ArrayBuffer[Mirror.Type] - def get(n: Int): Type = mem(n) - def add(n: Int, tpe: Type): Type = { - while (mem.length <= n) mem += null - mem(n) = tpe - tpe - } -} diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala index d3e4dd7619..20024ed058 100644 --- a/src/compiler/scala/reflect/runtime/Mirror.scala +++ b/src/compiler/scala/reflect/runtime/Mirror.scala @@ -1,24 +1,24 @@ package scala.reflect package runtime -import internal.{SomePhase, NoPhase, Phase, TreeGen} import java.lang.reflect.Array +import ReflectionUtils._ +import scala.tools.nsc.util.ScalaClassLoader._ /** The mirror for standard runtime reflection from Java. */ -class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxes with api.Mirror { +class Mirror(var classLoader: ClassLoader) extends Universe with api.Mirror { definitions.init() - import definitions._ def symbolForName(name: String): Symbol = { - val clazz = javaClass(name, defaultReflectiveClassLoader()) + val clazz = javaClass(name, classLoader) classToScala(clazz) } def companionInstance(clazz: Symbol): AnyRef = { - val singleton = ReflectionUtils.singletonInstance(clazz.fullName, defaultReflectiveClassLoader()) + val singleton = singletonInstance(classLoader, clazz.fullName) singleton } @@ -46,17 +46,31 @@ class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxe jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*) } - override def classToType(jclazz: java.lang.Class[_]): Type = typeToScala(jclazz) - override def classToSymbol(jclazz: java.lang.Class[_]): Symbol = classToScala(jclazz) + private def validateIncomingClassLoader(wannabeCl: ClassLoader) = { + val ourCls = loaderChain(classLoader) + if (wannabeCl != null && !(ourCls contains wannabeCl)) + throw new Error("class doesn't belong to the classloader chain of the mirror") + } + + def classToType(jclazz: java.lang.Class[_]): Type = { + validateIncomingClassLoader(jclazz.getClassLoader) + typeToScala(jclazz) + } + + def classToSymbol(jclazz: java.lang.Class[_]): Symbol = { + validateIncomingClassLoader(jclazz.getClassLoader) + classToScala(jclazz) + } + + def typeToClass(tpe: Type): java.lang.Class[_] = + typeToJavaClass(tpe) - override def typeToClass(tpe: Type): java.lang.Class[_] = typeToJavaClass(tpe) - override def symbolToClass(sym: Symbol): java.lang.Class[_] = classToJava(sym) + def symbolToClass(sym: Symbol): java.lang.Class[_] = + classToJava(sym) override def inReflexiveMirror = true } -object Mirror extends Mirror - /** test code; should go to tests once things settle down a bit * diff --git a/src/compiler/scala/reflect/runtime/RuntimeTypes.scala b/src/compiler/scala/reflect/runtime/RuntimeTypes.scala deleted file mode 100644 index 84d02ab7a0..0000000000 --- a/src/compiler/scala/reflect/runtime/RuntimeTypes.scala +++ /dev/null @@ -1,27 +0,0 @@ -package scala.reflect -package runtime - -import collection.mutable.ListBuffer - -trait RuntimeTypes extends Universe with api.RuntimeTypes { - - /** To lift path dependent types into reflection, we use InstanceRefSymbols. - * Two of these are equal if they point to the same object reference. Todo: remove - */ - case class InstanceRefSymbol(value: AnyRef) extends TermSymbol(NoSymbol, NoPosition, nme.EMPTY) - object InstanceRefSymbol extends InstanceRefSymbolExtractor - - override private[reflect] def namedType(pre: Type, sym: Symbol, args: List[Type]): Type = { - val tparamBuf = new ListBuffer[Symbol] - val args1 = for (arg <- args) yield arg match { - case _: TypeBounds => - val ex = pre.typeSymbol.freshExistential("$ex") setInfo arg - tparamBuf += ex - TypeRef(NoPrefix, ex, List()) - case _ => - arg - } - existentialAbstraction(tparamBuf.toList, typeRef(pre, sym, args1)) - } - -} \ No newline at end of file diff --git a/src/compiler/scala/reflect/runtime/SymbolLoaders.scala b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala new file mode 100644 index 0000000000..7c1cc16152 --- /dev/null +++ b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala @@ -0,0 +1,135 @@ +package scala.reflect +package runtime + +import internal.Flags +import java.lang.{Class => jClass, Package => jPackage} +import collection.mutable + +trait SymbolLoaders { self: SymbolTable => + + /** The lazy type for root. + */ + override val rootLoader = new LazyType { + override def complete(sym: Symbol) = sym setInfo new LazyPackageType + } + + /** The standard completer for top-level classes + * @param clazz The top-level class + * @param module The companion object of `clazz` + * Calling `complete` on this type will assign the infos of `clazz` and `module` + * by unpickling information from the corresponding Java class. If no Java class + * is found, a package is created instead. + */ + class TopClassCompleter(clazz: Symbol, module: Symbol) extends SymLoader { +// def makePackage() { +// println("wrong guess; making package "+clazz) +// val ptpe = newPackageType(module.moduleClass) +// for (sym <- List(clazz, module, module.moduleClass)) { +// sym setFlag Flags.PACKAGE +// sym setInfo ptpe +// } +// } + + override def complete(sym: Symbol) = { + debugInfo("completing "+sym+"/"+clazz.fullName) + assert(sym == clazz || sym == module || sym == module.moduleClass) +// try { + atPhaseNotLaterThan(picklerPhase) { + unpickleClass(clazz, module, javaClass(clazz.javaClassName)) +// } catch { +// case ex: ClassNotFoundException => makePackage() +// case ex: NoClassDefFoundError => makePackage() + // Note: We catch NoClassDefFoundError because there are situations + // where a package and a class have the same name except for capitalization. + // It seems in this case the class is loaded even if capitalization differs + // but then a NoClassDefFound error is issued with a ("wrong name: ...") + // reason. (I guess this is a concession to Windows). + // The present behavior is a bit too forgiving, in that it masks + // all class load errors, not just wrong name errors. We should try + // to be more discriminating. To get on the right track simply delete + // the clause above and load a collection class such as collection.Iterable. + // You'll see an error that class `parallel` has the wrong name. +// } + } + } + override def load(sym: Symbol) = complete(sym) + } + + /** Create a class and a companion object, enter in enclosing scope, + * and initialize with a lazy type completer. + * @param owner The owner of the newly created class and object + * @param name The simple name of the newly created class + * @param completer The completer to be used to set the info of the class and the module + */ + protected def createClassModule(owner: Symbol, name: TypeName, completer: (Symbol, Symbol) => LazyType) = { + assert(!(name.toString endsWith "[]"), name) + val clazz = owner.newClass(name) + val module = owner.newModule(name.toTermName) + owner.info.decls enter clazz + owner.info.decls enter module + initClassModule(clazz, module, completer(clazz, module)) + (clazz, module) + } + + protected def setAllInfos(clazz: Symbol, module: Symbol, info: Type) = { + List(clazz, module, module.moduleClass) foreach (_ setInfo info) + } + + protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) = + setAllInfos(clazz, module, completer) + + /** The type completer for packages. + */ + class LazyPackageType extends LazyType { + override def complete(sym: Symbol) { + assert(sym.isPackageClass) + sym setInfo new ClassInfoType(List(), new PackageScope(sym), sym) + // override def safeToString = pkgClass.toString + openPackageModule(sym) + } + } + + /** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because + * these are nested classes or anonymous classes, + */ + def invalidClassName(name: Name) = { + val dp = name pos '$' + 0 < dp && dp < (name.length - 1) + } + + class PackageScope(pkgClass: Symbol) extends Scope() with SynchronizedScope { + assert(pkgClass.isType) + private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. + override def lookupEntry(name: Name): ScopeEntry = { + val e = super.lookupEntry(name) + if (e != null) + e + else if (invalidClassName(name) || (negatives contains name)) + null + else { + val path = + if (pkgClass.isEmptyPackageClass) name.toString + else pkgClass.fullName + "." + name + if (isJavaClass(path)) { + val (clazz, module) = createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _)) + debugInfo("created "+module+"/"+module.moduleClass+" in "+pkgClass) + lookupEntry(name) + } else { + debugInfo("*** not found : "+path) + negatives += name + null + } + } + } + } + + /** Assert that packages have package scopes */ + override def validateClassInfo(tp: ClassInfoType) { + assert(!tp.typeSymbol.isPackageClass || tp.decls.isInstanceOf[PackageScope]) + } + + override def newPackageScope(pkgClass: Symbol) = new PackageScope(pkgClass) + + override def scopeTransform(owner: Symbol)(op: => Scope): Scope = + if (owner.isPackageClass) owner.info.decls else op +} diff --git a/src/compiler/scala/reflect/runtime/SymbolTable.scala b/src/compiler/scala/reflect/runtime/SymbolTable.scala index 5331f0a53e..64a5894d01 100644 --- a/src/compiler/scala/reflect/runtime/SymbolTable.scala +++ b/src/compiler/scala/reflect/runtime/SymbolTable.scala @@ -3,29 +3,10 @@ package runtime /** * This symbol table trait fills in the definitions so that class information is obtained by refection. - * It can be used either from the reflexive mirror itself (class Universe), or else from + * It can be used either from the reflexive mirror itself (class Mirror), or else from * a runtime compiler that uses reflection to get a class information (class scala.tools.nsc.ReflectGlobal) */ -trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with Loaders with SynchronizedOps { - - /** If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package - * ., otherwise return NoSymbol. - * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead. - */ - override def missingHook(owner: Symbol, name: Name): Symbol = - if (owner.isRoot && isJavaClass(name.toString)) - definitions.EmptyPackageClass.info decl name - else if (name.isTermName && owner.hasPackageFlag && !owner.isEmptyPackageClass) - makeScalaPackage(if (owner.isRoot) name.toString else owner.fullName+"."+name).sourceModule - else { - info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass) - super.missingHook(owner, name) - } - - /** Assert that packages have package scopes */ - override def validateClassInfo(tp: ClassInfoType) { - assert(!tp.typeSymbol.isPackageClass || tp.decls.isInstanceOf[PackageScope]) - } +trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with ClassLoaders with SymbolLoaders with SynchronizedOps { def info(msg: => String) = if (settings.verbose.value) println("[reflect-compiler] "+msg) diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala index 5ae4ec15ee..6fc5f7ed8a 100644 --- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala @@ -14,8 +14,11 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol = synchronized { super.connectModuleToClass(m, moduleClass) } - override def newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar = - new FreeVar(name, value) with SynchronizedTermSymbol initFlags newFlags setInfo tpe + override def newFreeTerm(name: TermName, info: Type, value: => Any, origin: String = null, newFlags: Long = 0L): FreeTerm = + new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags newFlags setInfo info + + override def newFreeType(name: TypeName, info: Type, value: => Any, origin: String = null, newFlags: Long = 0L): FreeType = + new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags newFlags setInfo info override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala index 28f12b378f..6d832a590f 100644 --- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala +++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala @@ -1,28 +1,30 @@ package scala.reflect package runtime -import scala.tools.nsc -import scala.tools.nsc.reporters.Reporter -import scala.tools.nsc.reporters.StoreReporter -import scala.tools.nsc.reporters.AbstractReporter +import scala.tools.nsc.reporters._ import scala.tools.nsc.ReflectGlobal import scala.tools.nsc.CompilerCommand import scala.tools.nsc.Global import scala.tools.nsc.typechecker.Modes import scala.tools.nsc.io.VirtualDirectory import scala.tools.nsc.interpreter.AbstractFileClassLoader -import reflect.{mirror => rm} import scala.tools.nsc.util.FreshNameCreator import scala.reflect.internal.Flags import scala.tools.nsc.util.{NoSourceFile, NoFile} import java.lang.{Class => jClass} -import scala.tools.nsc.util.trace +import scala.compat.Platform.EOL trait ToolBoxes extends { self: Universe => - class ToolBox(val reporter: Reporter = new StoreReporter, val options: String = "") { + import self.{Reporter => ApiReporter} + import scala.tools.nsc.reporters.{Reporter => NscReporter} - class ToolBoxGlobal(settings0: nsc.Settings, reporter0: nsc.reporters.Reporter) extends ReflectGlobal(settings0, reporter0) { + def mkToolBox(reporter: ApiReporter = mkSilentReporter(), options: String = "") = new ToolBox(reporter, options) + + class ToolBox(val reporter: ApiReporter, val options: String) extends AbsToolBox { + + class ToolBoxGlobal(settings: scala.tools.nsc.Settings, reporter: NscReporter) + extends ReflectGlobal(settings, reporter, ToolBox.this.classLoader) { import definitions._ private val trace = scala.tools.nsc.util.trace when settings.debug.value @@ -36,64 +38,7 @@ trait ToolBoxes extends { self: Universe => newTermName("__wrapper$" + wrapCount) } - private def moduleFileName(className: String) = className + "$" - - private def isFree(t: Tree) = t.isInstanceOf[Ident] && t.symbol.isInstanceOf[FreeVar] - - def typedTopLevelExpr(tree: Tree, pt: Type): Tree = { - // !!! Why is this is in the empty package? If it's only to make - // it inaccessible then please put it somewhere designed for that - // rather than polluting the empty package with synthetics. - trace("typing: ")(showAttributed(tree, true, true, settings.Yshowsymkinds.value)) - val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName(""), List(ObjectClass.tpe), newScope) - val owner = ownerClass.newLocalDummy(tree.pos) - val ttree = typer.atOwner(tree, owner).typed(tree, analyzer.EXPRmode, pt) - trace("typed: ")(showAttributed(ttree, true, true, settings.Yshowsymkinds.value)) - ttree - } - - def defOwner(tree: Tree): Symbol = tree find (_.isDef) map (_.symbol) match { - case Some(sym) if sym != null && sym != NoSymbol => sym.owner - case _ => NoSymbol - } - - def wrapInObject(expr: Tree, fvs: List[Symbol]): ModuleDef = { - val obj = EmptyPackageClass.newModule(nextWrapperModuleName()) - val minfo = ClassInfoType(List(ObjectClass.tpe), newScope, obj.moduleClass) - obj.moduleClass setInfo minfo - obj setInfo obj.moduleClass.tpe - val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName)) - def makeParam(fv: Symbol) = meth.newValueParameter(fv.name.toTermName) setInfo fv.tpe - meth setInfo MethodType(fvs map makeParam, AnyClass.tpe) - minfo.decls enter meth - trace("wrapping ")(defOwner(expr) -> meth) - val methdef = DefDef(meth, expr changeOwner (defOwner(expr) -> meth)) - val moduledef = ModuleDef( - obj, - Template( - List(TypeTree(ObjectClass.tpe)), - emptyValDef, - NoMods, - List(), - List(List()), - List(methdef), - NoPosition)) - trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value)) - val cleanedUp = resetLocalAttrs(moduledef) - trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value)) - cleanedUp - } - - def wrapInPackage(clazz: Tree): PackageDef = - PackageDef(Ident(nme.EMPTY_PACKAGE_NAME), List(clazz)) - - def wrapInCompilationUnit(tree: Tree): CompilationUnit = { - val unit = new CompilationUnit(NoSourceFile) - unit.body = tree - unit - } - - def compileExpr(expr: Tree, fvs: List[Symbol]): String = { + def verifyExpr(expr: Tree): Unit = { // Previously toolboxes used to typecheck their inputs before compiling. // Actually, the initial demo by Martin first typechecked the reified tree, // then ran it, which typechecked it again, and only then launched the @@ -104,44 +49,190 @@ trait ToolBoxes extends { self: Universe => // That's why we cannot allow inputs of toolboxes to be typechecked, // at least not until the aforementioned issue is closed. val typed = expr filter (t => t.tpe != null && t.tpe != NoType && !t.isInstanceOf[TypeTree]) - if (!typed.isEmpty) { - throw new Error("cannot compile trees that are already typed") + if (!typed.isEmpty) throw new ToolBoxError(ToolBox.this, "reflective toolbox has failed: cannot operate on trees that are already typed") + + val freeTypes = this.freeTypes(expr) + if (freeTypes.length > 0) { + var msg = "reflective toolbox has failed:" + EOL + msg += "unresolved free type variables (namely: " + (freeTypes map (ft => "%s %s".format(ft.name, ft.origin)) mkString ", ") + "). " + msg += "have you forgot to use TypeTag annotations for type parameters external to a reifee? " + msg += "if you have troubles tracking free type variables, consider using -Xlog-free-types" + throw new ToolBoxError(ToolBox.this, msg) } + } - val mdef = wrapInObject(expr, fvs) - val pdef = wrapInPackage(mdef) - val unit = wrapInCompilationUnit(pdef) - val run = new Run - run.compileUnits(List(unit), run.namerPhase) - mdef.symbol.fullName + def typeCheckExpr(expr0: Tree, pt: Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { + verifyExpr(expr0) + + // need to wrap the expr, because otherwise you won't be able to typecheck macros against something that contains free vars + // [Eugene] get rid of the copy/paste w.r.t compileExpr + val freeTerms = this.freeTerms(expr0) + val freeTermNames = collection.mutable.Map[Symbol, TermName]() + freeTerms foreach (ft => { + var name = ft.name.toString + val namesakes = freeTerms takeWhile (_ != ft) filter (ft2 => ft != ft2 && ft.name == ft2.name) + if (namesakes.length > 0) name += ("$" + (namesakes.length + 1)) + freeTermNames += (ft -> newTermName(name + nme.MIRROR_FREE_VALUE_SUFFIX)) + }) + var expr = new Transformer { + override def transform(tree: Tree): Tree = + if (tree.hasSymbol && tree.symbol.isFreeTerm) { + tree match { + case Ident(_) => + Ident(freeTermNames(tree.symbol)) + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } + } else { + super.transform(tree) + } + }.transform(expr0) + val dummies = freeTerms map (freeTerm => ValDef(NoMods, freeTermNames(freeTerm), TypeTree(freeTerm.info), Select(Ident(PredefModule), newTermName("$qmark$qmark$qmark")))) + expr = Block(dummies, expr) + + // [Eugene] how can we implement that? + // !!! Why is this is in the empty package? If it's only to make + // it inaccessible then please put it somewhere designed for that + // rather than polluting the empty package with synthetics. + val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName(""), List(ObjectClass.tpe), newScope) + val owner = ownerClass.newLocalDummy(expr.pos) + var currentTyper = typer.atOwner(expr, owner) + val wrapper1 = if (!withImplicitViewsDisabled) (currentTyper.context.withImplicitsEnabled[Tree] _) else (currentTyper.context.withImplicitsDisabled[Tree] _) + val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _) + def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) + + phase = (new Run).typerPhase // need to set a phase to something <= typerPhase, otherwise implicits in typedSelect will be disabled + currentTyper.context.setReportErrors() // need to manually set context mode, otherwise typer.silent will throw exceptions + reporter.reset() + + trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value)) + wrapper(currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match { + case analyzer.SilentResultValue(result) => + trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value)) + var Block(dummies, unwrapped) = result + var reversedFreeTermNames = freeTermNames map (_.swap) + // todo. also fixup singleton types + unwrapped = new Transformer { + override def transform(tree: Tree): Tree = + tree match { + case Ident(name) if reversedFreeTermNames contains name => + Ident(reversedFreeTermNames(name)) + case _ => + super.transform(tree) + } + }.transform(unwrapped) + new TreeTypeSubstituter(dummies map (_.symbol), dummies map (dummy => SingleType(NoPrefix, reversedFreeTermNames(dummy.symbol.name)))).traverse(unwrapped) + unwrapped + case error @ analyzer.SilentTypeError(_) => + trace("failed: ")(error.err.errMsg) + if (!silent) throw new ToolBoxError(ToolBox.this, "reflective typecheck has failed: %s".format(error.err.errMsg)) + EmptyTree + }) } - private def getMethod(jclazz: jClass[_], name: String) = - jclazz.getDeclaredMethods.find(_.getName == name).get + def compileExpr(expr: Tree): (Object, java.lang.reflect.Method) = { + verifyExpr(expr) + + def wrapExpr(expr0: Tree): Tree = { + def defOwner(tree: Tree): Symbol = tree find (_.isDef) map (_.symbol) match { + case Some(sym) if sym != null && sym != NoSymbol => sym.owner + case _ => NoSymbol + } + + val freeTerms = this.freeTerms(expr0) + val freeTermNames = collection.mutable.Map[Symbol, TermName]() + freeTerms foreach (ft => { + var name = ft.name.toString + val namesakes = freeTerms takeWhile (_ != ft) filter (ft2 => ft != ft2 && ft.name == ft2.name) + if (namesakes.length > 0) name += ("$" + (namesakes.length + 1)) + freeTermNames += (ft -> newTermName(name + nme.MIRROR_FREE_VALUE_SUFFIX)) + }) + val expr = new Transformer { + override def transform(tree: Tree): Tree = + if (tree.hasSymbol && tree.symbol.isFreeTerm) { + tree match { + case Ident(_) => + Apply(Ident(freeTermNames(tree.symbol)), List()) + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } + } else { + super.transform(tree) + } + }.transform(expr0) + + val obj = EmptyPackageClass.newModule(nextWrapperModuleName()) + val minfo = ClassInfoType(List(ObjectClass.tpe), newScope, obj.moduleClass) + obj.moduleClass setInfo minfo + obj setInfo obj.moduleClass.tpe + val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName)) + def makeParam(fv: Symbol) = { + // [Eugene] conventional way of doing this? + val underlying = fv.tpe.resultType + val tpe = appliedType(definitions.FunctionClass(0).tpe, List(underlying)) + meth.newValueParameter(freeTermNames(fv)) setInfo tpe + } + meth setInfo MethodType(freeTerms map makeParam, AnyClass.tpe) + minfo.decls enter meth + trace("wrapping ")(defOwner(expr) -> meth) + val methdef = DefDef(meth, expr changeOwner (defOwner(expr) -> meth)) + val moduledef = ModuleDef( + obj, + Template( + List(TypeTree(ObjectClass.tpe)), + emptyValDef, + NoMods, + List(), + List(List()), + List(methdef), + NoPosition)) + trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value)) + var cleanedUp = resetLocalAttrs(moduledef) + trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value)) + cleanedUp + } - def runExpr(expr: Tree): Any = { - val fvs = (expr filter isFree map (_.symbol)).distinct + val mdef = wrapExpr(expr) + val pdef = PackageDef(Ident(nme.EMPTY_PACKAGE_NAME), List(mdef)) + val unit = new CompilationUnit(NoSourceFile) + unit.body = pdef + val run = new Run reporter.reset() - val className = compileExpr(expr, fvs) + run.compileUnits(List(unit), run.namerPhase) if (reporter.hasErrors) { - throw new Error("reflective compilation has failed") + var msg = "reflective compilation has failed: " + EOL + EOL + msg += ToolBox.this.reporter.infos map (_.msg) mkString EOL + throw new ToolBoxError(ToolBox.this, msg) } + val className = mdef.symbol.fullName if (settings.debug.value) println("generated: "+className) + def moduleFileName(className: String) = className + "$" val jclazz = jClass.forName(moduleFileName(className), true, classLoader) val jmeth = jclazz.getDeclaredMethods.find(_.getName == wrapperMethodName).get val jfield = jclazz.getDeclaredFields.find(_.getName == NameTransformer.MODULE_INSTANCE_NAME).get val singleton = jfield.get(null) + (singleton, jmeth) + } + + def runExpr(expr: Tree, freeTypes: Map[TypeName, Type] = Map[TypeName, Type]()): Any = { + val freeTerms = this.freeTerms(expr) // need to calculate them here, because later on they will be erased + val thunks = freeTerms map (fte => () => fte.value) // need to be lazy in order not to distort evaluation order + // @odersky writes: Not sure we will be able to drop this. I forgot the reason why we dereference () functions, // but there must have been one. So I propose to leave old version in comments to be resurrected if the problem resurfaces. -// val result = jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*) + // @Eugene writes: this dates back to the days when one could only reify functions + // hence, blocks were translated into nullary functions, so + // presumably, it was useful to immediately evaluate them to get the result of a block +// val result = jmeth.invoke(singleton, freeTerms map (sym => sym.asInstanceOf[FreeTermVar].value.asInstanceOf[AnyRef]): _*) // if (etpe.typeSymbol != FunctionClass(0)) result // else { // val applyMeth = result.getClass.getMethod("apply") // applyMeth.invoke(result) // } - jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*) + val (singleton, jmeth) = compileExpr(expr) + jmeth.invoke(singleton, thunks map (_.asInstanceOf[AnyRef]): _*) } def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = { @@ -161,6 +252,7 @@ trait ToolBoxes extends { self: Universe => } } + // todo. is not going to work with quoted arguments with embedded whitespaces lazy val arguments = options.split(" ") lazy val virtualDirectory = @@ -170,49 +262,96 @@ trait ToolBoxes extends { self: Universe => } lazy val compiler: ToolBoxGlobal = { - val errorFn: String => Unit = reporter.error(scala.tools.nsc.util.NoPosition, _) - val command = reporter match { - case reporter: AbstractReporter => new CompilerCommand(arguments.toList, reporter.settings, errorFn) - case _ => new CompilerCommand(arguments.toList, errorFn) + try { + val errorFn: String => Unit = msg => reporter.log(NoPosition, msg, reporter.ERROR) + // [Eugene] settings shouldn't be passed via reporters, this is crazy +// val command = reporter match { +// case reporter: AbstractReporter => new CompilerCommand(arguments.toList, reporter.settings, errorFn) +// case _ => new CompilerCommand(arguments.toList, errorFn) +// } + val command = new CompilerCommand(arguments.toList, errorFn) + command.settings.outputDirs setSingleOutput virtualDirectory + val nscReporter = new ApiToNscReporterProxy(reporter) { val settings = command.settings } + val instance = new ToolBoxGlobal(command.settings, nscReporter) + if (nscReporter.hasErrors) { + var msg = "reflective compilation has failed: cannot initialize the compiler: " + EOL + EOL + msg += reporter.infos map (_.msg) mkString EOL + throw new ToolBoxError(this, msg) + } + instance.phase = (new instance.Run).typerPhase // need to manually set a phase, because otherwise TypeHistory will crash + instance + } catch { + case ex: Throwable => + var msg = "reflective compilation has failed: cannot initialize the compiler due to %s".format(ex.toString) + throw new ToolBoxError(this, msg, ex) } - - command.settings.outputDirs setSingleOutput virtualDirectory - val instance = new ToolBoxGlobal(command.settings, reporter) - - // need to establish a run an phase because otherwise we run into an assertion in TypeHistory - // that states that the period must be different from NoPeriod - val run = new instance.Run - instance.phase = run.refchecksPhase - instance } - lazy val importer = new compiler.Importer { - val from: self.type = self - } + // @Eugene: how do I make this work without casts? + // lazy val importer = compiler.mkImporter(self) + lazy val importer = compiler.mkImporter(self).asInstanceOf[compiler.Importer { val from: self.type }] lazy val exporter = importer.reverse - lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, defaultReflectiveClassLoader) + lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, self.classLoader) - def typeCheck(tree: rm.Tree, expectedType: rm.Type): rm.Tree = { - if (compiler.settings.verbose.value) println("typing "+tree+", pt = "+expectedType) - val ctree: compiler.Tree = importer.importTree(tree.asInstanceOf[Tree]) - val pt: compiler.Type = importer.importType(expectedType.asInstanceOf[Type]) - val ttree: compiler.Tree = compiler.typedTopLevelExpr(ctree, pt) - val rmttree = exporter.importTree(ttree).asInstanceOf[rm.Tree] + def typeCheck(tree: Tree, expectedType: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { + if (compiler.settings.verbose.value) println("typing "+tree+", expectedType = "+expectedType+", freeTypes = "+freeTypes) + var ctree: compiler.Tree = importer.importTree(tree) + var cexpectedType: compiler.Type = importer.importType(expectedType) + + if (compiler.settings.verbose.value) println("substituting "+ctree+", expectedType = "+expectedType) + val cfreeTypes: Map[compiler.FreeType, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeType], importer.importType(v)) } + ctree = compiler.substituteFreeTypes(ctree, cfreeTypes) + cexpectedType = compiler.substituteFreeTypes(cexpectedType, cfreeTypes) + + if (compiler.settings.verbose.value) println("typing "+ctree+", expectedType = "+expectedType) + val ttree: compiler.Tree = compiler.typeCheckExpr(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled) + val rmttree = exporter.importTree(ttree) rmttree } - def typeCheck(tree: rm.Tree): rm.Tree = - typeCheck(tree, WildcardType.asInstanceOf[rm.Type]) + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree = + // todo. implement this + ??? + + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree = + // todo. implement this + ??? + + def resetAllAttrs[T <: Tree](tree: T): T = { + val ctree: compiler.Tree = importer.importTree(tree) + val ttree: compiler.Tree = compiler.resetAllAttrs(ctree) + val rmttree = exporter.importTree(ttree) + rmttree.asInstanceOf[T] + } + + def resetLocalAttrs[T <: Tree](tree: T): T = { + val ctree: compiler.Tree = importer.importTree(tree) + val ttree: compiler.Tree = compiler.resetLocalAttrs(ctree) + val rmttree = exporter.importTree(ttree) + rmttree.asInstanceOf[T] + } + + def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = + compiler.showAttributed(importer.importTree(tree), printTypes, printIds, printKinds) + + def runExpr(tree: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any = { + if (compiler.settings.verbose.value) println("running "+tree+", freeTypes = "+freeTypes) + var ctree: compiler.Tree = importer.importTree(tree) - def showAttributed(tree: rm.Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = - compiler.showAttributed(importer.importTree(tree.asInstanceOf[Tree]), printTypes, printIds, printKinds) + if (compiler.settings.verbose.value) println("substituting "+ctree) + val cfreeTypes: Map[compiler.FreeType, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeType], importer.importType(v)) } + ctree = compiler.substituteFreeTypes(ctree, cfreeTypes) - def runExpr(tree: rm.Tree): Any = { - if (compiler.settings.verbose.value) println("running "+tree) - val ctree: compiler.Tree = importer.importTree(tree.asInstanceOf[Tree]) + if (compiler.settings.verbose.value) println("running "+ctree) compiler.runExpr(ctree) } + + class ToolBoxError(val toolBox: ToolBox, val message: String, val cause: Throwable = null) extends Throwable(message, cause) + + object ToolBoxError extends ToolBoxErrorExtractor { + def unapply(error: ToolBoxError): Option[(ToolBox, String)] = Some((error.toolBox, error.message)) + } } } diff --git a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala deleted file mode 100644 index 61001a4778..0000000000 --- a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala +++ /dev/null @@ -1,49 +0,0 @@ -package scala.reflect -package runtime - -trait TreeBuildUtil extends Universe with api.TreeBuildUtil { - /** A comment to the effect of why initialize was added to all these - * would be appreciated. (We may as well start somewhere.) - */ - def staticClass(fullname: String) = definitions.getRequiredClass(fullname).initialize - def staticModule(fullname: String) = definitions.getRequiredModule(fullname).initialize - def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.initialize.thisType - - /** Selects type symbol with given name from the defined members of prefix type - */ - def selectType(owner: Symbol, name: String): Symbol = - owner.info.decl(newTypeName(name)) - - /** Selects term symbol with given name and type from the defined members of prefix type - * @pre The prefix type - * @name The name of the selected member - */ - def selectTerm(owner: Symbol, name: String): Symbol = { - val sym = owner.info.decl(newTermName(name)) - if (sym.isOverloaded) sym suchThat (!_.isMethod) - else sym - } - - def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol = - owner.info.decl(newTermName(name)).alternatives(index) - - def selectParam(owner: Symbol, idx: Int): Symbol = { - def selectInList(params: List[Symbol], idx: Int, fallback: Type): Symbol = { - if (params.isEmpty) selectIn(fallback, idx) - else if (idx == 0) params.head - else selectInList(params.tail, idx - 1, fallback) - } - def selectIn(tpe: Type, idx: Int): Symbol = tpe match { - case PolyType(tparams, res) => selectInList(tparams, idx, res) - case MethodType(params, res) => selectInList(params, idx, res) - case _ => NoSymbol - } - selectIn(owner.info, idx) - } - - def newFreeVar(name: String, info: Type, value: Any) = newFreeVar(newTermName(name), info, value) - - def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers = - Modifiers(flags, privateWithin, annotations) - -} \ No newline at end of file diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala index dca6d6041b..fd53308d0a 100644 --- a/src/compiler/scala/reflect/runtime/Universe.scala +++ b/src/compiler/scala/reflect/runtime/Universe.scala @@ -8,12 +8,14 @@ import internal.{SomePhase, NoPhase, Phase, TreeGen} * It also provides methods to go from Java members to Scala members, * using the code in JavaConversions. */ -class Universe extends SymbolTable { +abstract class Universe extends SymbolTable with ToolBoxes { type AbstractFileType = AbstractFile def picklerPhase = SomePhase + type TreeGen = internal.TreeGen + val gen = new TreeGen { val global: Universe.this.type = Universe.this } lazy val settings = new Settings @@ -30,24 +32,12 @@ class Universe extends SymbolTable { def newStrictTreeCopier: TreeCopier = new StrictTreeCopier def newLazyTreeCopier: TreeCopier = new LazyTreeCopier - def focusPos(pos: Position) = pos - def isRangePos(pos: Position) = false - def showPos(pos: Position) = "" - - type Position = String // source file? - val NoPosition = "" - definitions.AnyValClass // force it. - type TreeAnnotation = Position - def NoTreeAnnotation: TreeAnnotation = NoPosition - def positionToAnnotation(pos: Position): TreeAnnotation = pos // TODO - def annotationToPosition(annot: TreeAnnotation): Position = annot //TODO - // establish root association to avoid cyclic dependency errors later - classToScala(classOf[java.lang.Object]).initialize + // don't use classOf[...] here, because it gets serviced by getClass.getClassLoader! + classToScala(Class.forName("java.lang.Object", true, classLoader)).initialize // println("initializing definitions") definitions.init() - } diff --git a/src/compiler/scala/reflect/runtime/package.scala b/src/compiler/scala/reflect/runtime/package.scala new file mode 100644 index 0000000000..52ab2c5deb --- /dev/null +++ b/src/compiler/scala/reflect/runtime/package.scala @@ -0,0 +1,5 @@ +package scala.reflect + +package object runtime { + def mkMirror(classLoader: ClassLoader): api.Mirror = new Mirror(classLoader) +} \ No newline at end of file diff --git a/src/compiler/scala/tools/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala index 3792c26c34..9592e7a716 100644 --- a/src/compiler/scala/tools/cmd/FromString.scala +++ b/src/compiler/scala/tools/cmd/FromString.scala @@ -7,14 +7,14 @@ package scala.tools package cmd import nsc.io.{ Path, File, Directory } -import scala.reflect.OptManifest +import scala.reflect.Manifest /** A general mechanism for defining how a command line argument * (always a String) is transformed into an arbitrary type. A few * example instances are in the companion object, but in general * either IntFromString will suffice or you'll want custom transformers. */ -abstract class FromString[+T](implicit m: OptManifest[T]) extends PartialFunction[String, T] { +abstract class FromString[+T](implicit m: Manifest[T]) extends PartialFunction[String, T] { def apply(s: String): T def isDefinedAt(s: String): Boolean = true def zero: T = apply("") diff --git a/src/compiler/scala/tools/nsc/ClassLoaders.scala b/src/compiler/scala/tools/nsc/ClassLoaders.scala new file mode 100644 index 0000000000..4058ee9324 --- /dev/null +++ b/src/compiler/scala/tools/nsc/ClassLoaders.scala @@ -0,0 +1,64 @@ +package scala.tools.nsc + +import util.ScalaClassLoader + +trait ClassLoaders { self: Global => + + def staticClass(fullname: String) = { + if (self.forMSIL) + throw new UnsupportedOperationException("Scala reflection not available on this platform") + + getClass(newTypeName(fullname)) + } + + def staticModule(fullname: String) = { + if (self.forMSIL) + throw new UnsupportedOperationException("Scala reflection not available on this platform") + + getModule(newTermName(fullname)) + } + + private def getClass(fullname: Name): Symbol = { + var result = getModuleOrClass(fullname.toTypeName) + while (result.isAliasType) result = result.info.typeSymbol + result + } + + private def getModule(fullname: Name): Symbol = + getModuleOrClass(fullname.toTermName) + + private def getModuleOrClass(path: Name): Symbol = + getModuleOrClass(path, path.length) + + private def getModuleOrClass(path: Name, len: Int): Symbol = { + val point = path lastPos('.', len - 1) + val owner = + if (point > 0) getModuleOrClass(path.toTermName, point) + else definitions.RootClass + val name = path subName (point + 1, len) + val sym = owner.info member name + val result = if (path.isTermName) sym.suchThat(_ hasFlag symtab.Flags.MODULE) else sym + if (result != NoSymbol) result + else { + if (settings.debug.value) { log(sym.info); log(sym.info.members) }//debug + if (owner.isRoot && isJavaClass(name.toString)) + definitions.EmptyPackageClass.info decl name + else { + def info(msg: => String) = if (settings.verbose.value) println(msg) + info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass) + MissingRequirementError.notFound((if (path.isTermName) "object " else "class ")+path) + } + } + } + + private def isJavaClass(path: String): Boolean = + try { + val classpath = platform.classPath.asURLs + var classLoader = ScalaClassLoader.fromURLs(classpath) + Class.forName(path, true, classLoader) + true + } catch { + case (_: ClassNotFoundException) | (_: NoClassDefFoundError) | (_: IncompatibleClassChangeError) => + false + } +} diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 5e0c24d304..b7d7f5d16f 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -12,7 +12,7 @@ import compat.Platform.currentTime import scala.tools.util.{ Profiling, PathResolver } import scala.collection.{ mutable, immutable } import io.{ SourceReader, AbstractFile, Path } -import reporters.{ Reporter, ConsoleReporter } +import reporters.{ Reporter => NscReporter, ConsoleReporter } import util.{ NoPosition, Exceptional, ClassPath, SourceFile, NoSourceFile, Statistics, StatisticsInfo, BatchSourceFile, ScriptSourceFile, ShowPickled, ScalaClassLoader, returning } import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat } import settings.{ AestheticSettings } @@ -32,24 +32,25 @@ import backend.jvm.GenJVM import backend.opt.{ Inliners, InlineExceptionHandlers, ClosureElimination, DeadCodeElimination } import backend.icode.analysis._ -class Global(var currentSettings: Settings, var reporter: Reporter) extends SymbolTable - with CompilationUnits - with Plugins - with PhaseAssembly - with Trees - with Reifiers - with TreePrinters - with DocComments - with MacroContext - with symtab.Positions { +class Global(var currentSettings: Settings, var reporter: NscReporter) extends SymbolTable + with ClassLoaders + with ToolBoxes + with CompilationUnits + with Plugins + with PhaseAssembly + with Trees + with FreeVars + with TreePrinters + with DocComments + with Positions { override def settings = currentSettings - + import definitions.{ findNamedMember, findMemberFromRoot } // alternate constructors ------------------------------------------ - def this(reporter: Reporter) = + def this(reporter: NscReporter) = this(new Settings(err => reporter.error(null, err)), reporter) def this(settings: Settings) = @@ -61,7 +62,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb type AbstractFileType = scala.tools.nsc.io.AbstractFile def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = gen.mkAttributedQualifier(tpe, termSym) - + def picklerPhase: Phase = if (currentRun.isDefined) currentRun.picklerPhase else NoPhase // platform specific elements @@ -78,6 +79,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb // sub-components -------------------------------------------------- /** Generate ASTs */ + type TreeGen = scala.tools.nsc.ast.TreeGen + object gen extends { val global: Global.this.type = Global.this } with TreeGen { @@ -127,7 +130,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb /** Print tree in detailed form */ object nodePrinters extends { val global: Global.this.type = Global.this - } with NodePrinters with ReifyPrinters { + } with NodePrinters { infolevel = InfoLevel.Verbose } @@ -137,7 +140,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb } with TreeBrowsers val nodeToString = nodePrinters.nodeToString - val reifiedNodeToString = nodePrinters.reifiedNodeToString val treeBrowser = treeBrowsers.create() // ------------ Hooks for interactive mode------------------------- @@ -215,7 +217,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def logAfterEveryPhase[T](msg: String)(op: => T) { log("Running operation '%s' after every phase.\n".format(msg) + describeAfterEveryPhase(op)) } - + def shouldLogAtThisPhase = ( (settings.log.isSetByUser) && ((settings.log containsPhase globalPhase) || (settings.log containsPhase phase)) @@ -319,7 +321,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def showNames = List(showClass, showObject).flatten def showPhase = isActive(settings.Yshow) def showSymbols = settings.Yshowsyms.value - def showTrees = settings.Xshowtrees.value + def showTrees = settings.Xshowtrees.value || settings.XshowtreesCompact.value || settings.XshowtreesStringified.value val showClass = optSetting[String](settings.Xshowcls) map (x => splitClassAndPhase(x, false)) val showObject = optSetting[String](settings.Xshowobj) map (x => splitClassAndPhase(x, true)) @@ -1108,7 +1110,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def phaseNamed(name: String): Phase = findOrElse(firstPhase.iterator)(_.name == name)(NoPhase) - + /** All phases as of 3/2012 here for handiness; the ones in * active use uncommented. */ @@ -1581,7 +1583,7 @@ object Global { * This allows the use of a custom Global subclass with the software which * wraps Globals, such as scalac, fsc, and the repl. */ - def fromSettings(settings: Settings, reporter: Reporter): Global = { + def fromSettings(settings: Settings, reporter: NscReporter): Global = { // !!! The classpath isn't known until the Global is created, which is too // late, so we have to duplicate it here. Classpath is too tightly coupled, // it is a construct external to the compiler and should be treated as such. @@ -1589,7 +1591,7 @@ object Global { val loader = ScalaClassLoader.fromURLs(new PathResolver(settings).result.asURLs, parentLoader) val name = settings.globalClass.value val clazz = Class.forName(name, true, loader) - val cons = clazz.getConstructor(classOf[Settings], classOf[Reporter]) + val cons = clazz.getConstructor(classOf[Settings], classOf[NscReporter]) cons.newInstance(settings, reporter).asInstanceOf[Global] } @@ -1597,7 +1599,7 @@ object Global { /** A global instantiated this way honors -Yglobal-class setting, and * falls back on calling the Global constructor directly. */ - def apply(settings: Settings, reporter: Reporter): Global = { + def apply(settings: Settings, reporter: NscReporter): Global = { val g = ( if (settings.globalClass.isDefault) null else try fromSettings(settings, reporter) catch { case x => diff --git a/src/compiler/scala/tools/nsc/MacroContext.scala b/src/compiler/scala/tools/nsc/MacroContext.scala deleted file mode 100644 index 9ea1f87125..0000000000 --- a/src/compiler/scala/tools/nsc/MacroContext.scala +++ /dev/null @@ -1,10 +0,0 @@ -package scala.tools.nsc - -import symtab.Flags._ - -trait MacroContext extends reflect.macro.Context { self: Global => - - def captureVariable(vble: Symbol): Unit = vble setFlag CAPTURED - - def referenceCapturedVariable(id: Ident): Tree = ReferenceToBoxed(id) -} diff --git a/src/compiler/scala/tools/nsc/ReflectGlobal.scala b/src/compiler/scala/tools/nsc/ReflectGlobal.scala index 3132a9987d..68a6a4d336 100644 --- a/src/compiler/scala/tools/nsc/ReflectGlobal.scala +++ b/src/compiler/scala/tools/nsc/ReflectGlobal.scala @@ -5,7 +5,7 @@ import reporters.Reporter /** A version of Global that uses reflection to get class * infos, instead of reading class or source files. */ -class ReflectGlobal(currentSettings: Settings, reporter: Reporter) +class ReflectGlobal(currentSettings: Settings, reporter: Reporter, var classLoader: ClassLoader) extends Global(currentSettings, reporter) with reflect.runtime.SymbolTable { override def transformedType(sym: Symbol) = @@ -13,4 +13,9 @@ class ReflectGlobal(currentSettings: Settings, reporter: Reporter) uncurry.transformInfo(sym, refChecks.transformInfo(sym, sym.info))) + override def staticClass(fullname: String) = + super[SymbolTable].staticClass(fullname) + + override def staticModule(fullname: String) = + super[SymbolTable].staticModule(fullname) } diff --git a/src/compiler/scala/tools/nsc/ReflectMain.scala b/src/compiler/scala/tools/nsc/ReflectMain.scala index 7167f5aa27..f9a18abc25 100644 --- a/src/compiler/scala/tools/nsc/ReflectMain.scala +++ b/src/compiler/scala/tools/nsc/ReflectMain.scala @@ -1,7 +1,16 @@ package scala.tools.nsc +import util.ScalaClassLoader +import tools.util.PathResolver +import util.ClassPath.DefaultJavaContext + object ReflectMain extends Driver { - override def newCompiler(): Global = new ReflectGlobal(settings, reporter) + private def reflectionClassloaderFromSettings(settings: Settings) = { + val classpath = new PathResolver(settings).result + ScalaClassLoader.fromURLs(classpath.asURLs, getClass.getClassLoader) + } + + override def newCompiler(): Global = new ReflectGlobal(settings, reporter, reflectionClassloaderFromSettings(settings)) } \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/ToolBoxes.scala b/src/compiler/scala/tools/nsc/ToolBoxes.scala new file mode 100644 index 0000000000..eb298833b8 --- /dev/null +++ b/src/compiler/scala/tools/nsc/ToolBoxes.scala @@ -0,0 +1,85 @@ +package scala.tools.nsc + +import util.ScalaClassLoader + +trait ToolBoxes { self: Global => + + import self.{Reporter => ApiReporter} + + def mkToolBox(reporter: ApiReporter = mkSilentReporter(), options: String = "") = new ToolBox(reporter, options) + + class ToolBox(val reporter: ApiReporter, val options: String) extends AbsToolBox { + def typeCheck(tree0: Tree, pt: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { + val tree = substituteFreeTypes(tree0, freeTypes) + val currentTyper = typer + val wrapper1 = if (!withImplicitViewsDisabled) (currentTyper.context.withImplicitsEnabled[Tree] _) else (currentTyper.context.withImplicitsDisabled[Tree] _) + val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _) + def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) + wrapper(currentTyper.silent(_.typed(tree, analyzer.EXPRmode, pt)) match { + case analyzer.SilentResultValue(result) => + result + case error @ analyzer.SilentTypeError(_) => + if (!silent) throw new ToolBoxError(this, "reflective typecheck has failed: %s".format(error.err.errMsg)) + EmptyTree + }) + } + + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree = + // todo. implement this + ??? + + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree = + // todo. implement this + ??? + + def resetAllAttrs[T <: Tree](tree: T): T = + self.resetAllAttrs(tree) + + def resetLocalAttrs[T <: Tree](tree: T): T = + self.resetLocalAttrs(tree) + + def runExpr(tree0: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any = { + var tree = substituteFreeTypes(tree0, freeTypes) + // need to reset the tree, otherwise toolbox will refuse to work with it + tree = resetAllAttrs(tree0.duplicate) + val imported = importer.importTree(tree) + val toolBox = libraryClasspathMirror.mkToolBox(reporter.asInstanceOf[libraryClasspathMirror.Reporter], options) + try toolBox.runExpr(imported) + catch { + case ex: toolBox.ToolBoxError => + throw new ToolBoxError(this, ex.message, ex.cause) + } + } + + // [Eugene] how do I make this work without casts? + // private lazy val importer = libraryClasspathMirror.mkImporter(self) + private lazy val importer = libraryClasspathMirror.mkImporter(self).asInstanceOf[libraryClasspathMirror.Importer { val from: self.type }] + + private lazy val libraryClasspathMirror = { + if (self.forMSIL) + throw new UnsupportedOperationException("Scala reflection not available on this platform") + + val libraryClassLoader = { + val classpath = self.classPath.asURLs + var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) + + // [Eugene] a heuristic to detect REPL + if (self.settings.exposeEmptyPackage.value) { + import scala.tools.nsc.interpreter._ + val virtualDirectory = self.settings.outputDirs.getSingleOutput.get + loader = new AbstractFileClassLoader(virtualDirectory, loader) {} + } + + loader + } + + new scala.reflect.runtime.Mirror(libraryClassLoader) + } + + class ToolBoxError(val toolBox: ToolBox, val message: String, val cause: Throwable = null) extends Throwable(message, cause) + + object ToolBoxError extends ToolBoxErrorExtractor { + def unapply(error: ToolBoxError): Option[(ToolBox, String)] = Some((error.toolBox, error.message)) + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 456e7eae9e..ff4e2f3fb5 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -7,7 +7,7 @@ package scala.tools.nsc package ast import symtab._ -import reporters.Reporter +import reporters.{Reporter => NscReporter} import util.{Position, NoPosition} import util.DocStrings._ import scala.reflect.internal.Chars._ @@ -21,7 +21,7 @@ trait DocComments { self: Global => var cookedDocComments = Map[Symbol, String]() - def reporter: Reporter + def reporter: NscReporter /** The raw doc comment map */ val docComments = mutable.HashMap[Symbol, DocComment]() diff --git a/src/compiler/scala/tools/nsc/ast/FreeVars.scala b/src/compiler/scala/tools/nsc/ast/FreeVars.scala new file mode 100644 index 0000000000..1bf36e8bf2 --- /dev/null +++ b/src/compiler/scala/tools/nsc/ast/FreeVars.scala @@ -0,0 +1,26 @@ +package scala.tools.nsc +package ast + +trait FreeVars extends reflect.internal.FreeVars { self: Global => + + import self._ + import definitions._ + import treeInfo._ + + def logFreeVars(position: Position, reified: Tree): Unit = { + if (settings.logFreeTerms.value || settings.logFreeTypes.value) { + reified match { + case Reified(_, symbolTable, _) => + // logging free vars only when they are untyped prevents avalanches of duplicate messages + symbolTable foreach { + case FreeTermDef(_, _, binding, origin) if settings.logFreeTerms.value && binding.tpe == null => + reporter.echo(position, "free term: %s %s".format(showRaw(binding), origin)) + case FreeTypeDef(_, _, binding, origin) if settings.logFreeTypes.value && binding.tpe == null => + reporter.echo(position, "free type: %s %s".format(showRaw(binding), origin)) + case _ => + // do nothing + } + } + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala index acbdcd501f..c79ca1206e 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -27,24 +27,24 @@ abstract class NodePrinters { def nodeToString: Tree => String = if (sys.props contains "scala.colors") nodeToColorizedString else nodeToRegularString - + object nodeToRegularString extends DefaultPrintAST with (Tree => String) { def apply(tree: Tree) = stringify(tree) } - + object nodeToColorizedString extends ColorPrintAST with (Tree => String) { def apply(tree: Tree) = stringify(tree) } trait ColorPrintAST extends DefaultPrintAST { import scala.tools.util.color._ - + def keywordColor = Cyan def typeColor = Yellow def termColor = Blue def flagColor = Red def literalColor = Green - + override def showFlags(tree: MemberDef) = super.showFlags(tree) in flagColor.bright @@ -81,7 +81,7 @@ abstract class NodePrinters { if (tpe == null || tpe == NoType) "" else "tree.tpe=" + tpe } - + def showAttributes(tree: Tree): String = { if (infolevel == InfoLevel.Quiet) "" else { @@ -90,7 +90,7 @@ abstract class NodePrinters { } } } - + trait PrintAST { private val buf = new StringBuilder private var level = 0 @@ -101,7 +101,7 @@ abstract class NodePrinters { def showLiteral(lit: Literal): String def showTypeTree(tt: TypeTree): String def showAttributes(tree: Tree): String // symbol and type - + def showRefTreeName(tree: Tree): String = tree match { case SelectFromTypeTree(qual, name) => showRefTreeName(qual) + "#" + showName(name) case Select(qual, name) => showRefTreeName(qual) + "." + showName(name) @@ -122,8 +122,14 @@ abstract class NodePrinters { def stringify(tree: Tree): String = { buf.clear() - level = 0 - traverse(tree) + if (settings.XshowtreesStringified.value) buf.append(tree.toString + EOL) + if (settings.XshowtreesCompact.value) { + // todo. colors for compact representation + buf.append(showRaw(tree)) + } else { + level = 0 + traverse(tree) + } buf.toString } def traverseAny(x: Any) { @@ -134,7 +140,7 @@ abstract class NodePrinters { } } def println(s: String) = printLine(s, "") - + def printLine(value: String, comment: String) { buf append " " * level buf append value @@ -183,7 +189,7 @@ abstract class NodePrinters { traverseList("Nil", "argument")(args) } } - + def printMultiline(tree: Tree)(body: => Unit) { printMultiline(tree.printingPrefix, showAttributes(tree))(body) } @@ -299,7 +305,7 @@ abstract class NodePrinters { } case Template(parents, self, body) => printMultiline(tree) { - val ps0 = parents map { p => + val ps0 = parents map { p => if (p.tpe eq null) p match { case x: RefTree => showRefTree(x) case x => "" + x @@ -339,7 +345,7 @@ abstract class NodePrinters { traverseList("[]", "type parameter")(tparams) traverse(rhs) } - + case PackageDef(pid, stats) => printMultiline("PackageDef", "")(pid :: stats foreach traverse) diff --git a/src/compiler/scala/tools/nsc/ast/Positions.scala b/src/compiler/scala/tools/nsc/ast/Positions.scala new file mode 100644 index 0000000000..83a67cfbe3 --- /dev/null +++ b/src/compiler/scala/tools/nsc/ast/Positions.scala @@ -0,0 +1,44 @@ +package scala.tools.nsc +package ast + +import scala.tools.nsc.util.{ SourceFile, Position, OffsetPosition, NoPosition } + +trait Positions extends scala.reflect.internal.Positions { + self: Global => + + def rangePos(source: SourceFile, start: Int, point: Int, end: Int) = + new OffsetPosition(source, point) + + 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.tools.nsc.util.Position] || !annot.isInstanceOf[scala.tools.nsc.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) { + if (t eq EmptyTree) () + else if (t.pos == NoPosition) super.traverse(t setPos pos) + else if (globalPhase.id <= currentRun.picklerPhase.id) { + // When we prune due to encountering a position, traverse the + // pruned children so we can warn about those lacking positions. + t.children foreach { c => + if ((c eq EmptyTree) || (c eq emptyValDef)) () + else if (c.pos == NoPosition) { + reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase) + inform("parent: " + treeSymStatus(t)) + inform(" child: " + treeSymStatus(c) + "\n") + } + } + } + } + } + + override protected[this] lazy val posAssigner: PosAssigner = + if (settings.Yrangepos.value && settings.debug.value || settings.Yposdebug.value) new ValidatingPosAssigner + else new DefaultPosAssigner +} diff --git a/src/compiler/scala/tools/nsc/ast/Reifiers.scala b/src/compiler/scala/tools/nsc/ast/Reifiers.scala deleted file mode 100644 index 04468a096d..0000000000 --- a/src/compiler/scala/tools/nsc/ast/Reifiers.scala +++ /dev/null @@ -1,761 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Gilles Dubochet - */ - -package scala.tools.nsc -package ast - -import symtab._ -import Flags._ -import scala.reflect.api.Modifier._ -import scala.collection.{ mutable, immutable } -import scala.collection.mutable.ListBuffer -import scala.tools.nsc.util.FreshNameCreator -import scala.runtime.ScalaRunTime.{ isAnyVal, isTuple } - -/** Given a tree or type, generate a tree that when executed at runtime produces the original tree or type. - * See more info in the comments to `reify' in scala.reflect.macro.Context. - * - * @author Martin Odersky - * @version 2.10 - */ -trait Reifiers { self: Global => - - def reify(tree: Tree): Tree = { - class Reifier { - import definitions._ - import Reifier._ - - final val scalaPrefix = "scala." - final val localPrefix = "$local" - final val memoizerName = "$memo" - - val reifyDebug = settings.Yreifydebug.value - - private val reifiableSyms = mutable.ArrayBuffer[Symbol]() // the symbols that are reified with the tree - private val symIndex = mutable.HashMap[Symbol, Int]() // the index of a reifiable symbol in `reifiableSyms` - private var boundSyms = Set[Symbol]() // set of all symbols that are bound in tree to be reified - - private def definedInLiftedCode(tpe: Type) = - tpe exists (tp => boundSyms contains tp.typeSymbol) - - private def definedInLiftedCode(sym: Symbol) = - boundSyms contains sym - - /** - * Generate tree of the form - * - * { val $mr = scala.reflect.runtime.Mirror - * $local1 = new TypeSymbol(owner1, NoPosition, name1) - * ... - * $localN = new TermSymbol(ownerN, NoPositiion, nameN) - * $local1.setInfo(tpe1) - * ... - * $localN.setInfo(tpeN) - * $localN.setAnnotations(annotsN) - * rtree - * } - * - * where - * - * - `$localI` are free type symbols in the environment, as well as local symbols - * of refinement types. - * - `tpeI` are the info's of `symI` - * - `rtree` is code that generates `data` at runtime, maintaining all attributes. - * - `data` is typically a tree or a type. - */ - def reifyTopLevel(data: Any): Tree = { - val rtree = reify(data) - Block(mirrorAlias :: reifySymbolTableSetup, rtree) - } - - private def isLocatable(sym: Symbol) = - sym.isPackageClass || sym.owner.isClass || sym.isTypeParameter && sym.paramPos >= 0 - - private def registerReifiableSymbol(sym: Symbol): Unit = - if (!(symIndex contains sym)) { - sym.owner.ownersIterator find (x => !isLocatable(x)) foreach registerReifiableSymbol - symIndex(sym) = reifiableSyms.length - reifiableSyms += sym - } - - // helper methods - - private def localName(sym: Symbol): TermName = - newTermName(localPrefix + symIndex(sym)) - - private def call(fname: String, args: Tree*): Tree = - Apply(termPath(fname), args.toList) - - private def mirrorSelect(name: String): Tree = - termPath(nme.MIRROR_PREFIX + name) - - private def mirrorCall(name: TermName, args: Tree*): Tree = - call("" + (nme.MIRROR_PREFIX append name), args: _*) - - private def mirrorCall(name: String, args: Tree*): Tree = - call(nme.MIRROR_PREFIX + name, args: _*) - - private def mirrorFactoryCall(value: Product, args: Tree*): Tree = - mirrorFactoryCall(value.productPrefix, args: _*) - - private def mirrorFactoryCall(prefix: String, args: Tree*): Tree = - mirrorCall(prefix, args: _*) - - private def scalaFactoryCall(name: String, args: Tree*): Tree = - call(scalaPrefix + name + ".apply", args: _*) - - private def mkList(args: List[Tree]): Tree = - scalaFactoryCall("collection.immutable.List", args: _*) - - private def reifyModifiers(m: Modifiers) = - mirrorCall("modifiersFromInternalFlags", reify(m.flags), reify(m.privateWithin), reify(m.annotations)) - - private def reifyAggregate(name: String, args: Any*) = - scalaFactoryCall(name, (args map reify).toList: _*) - - /** - * Reify a list - */ - private def reifyList(xs: List[Any]): Tree = - mkList(xs map reify) - - /** - * Reify an array - */ - private def reifyArray(xs: Array[_]): Tree = - // @xeno.by: doesn't work for Array(LiteralAnnotArg(...)) - // because we cannot generate manifests for path-dependent types - scalaFactoryCall(nme.Array, xs map reify: _*) - - /** Reify a name */ - private def reifyName(name: Name) = - mirrorCall(if (name.isTypeName) "newTypeName" else "newTermName", Literal(Constant(name.toString))) - - private def isFree(sym: Symbol) = - !(symIndex contains sym) - - /** - * Reify a reference to a symbol - */ - private def reifySymRef(sym: Symbol): Tree = { - symIndex get sym match { - case Some(idx) => - Ident(localName(sym)) - case None => - if (sym == NoSymbol) - mirrorSelect("NoSymbol") - else if (sym == RootPackage) - mirrorSelect("definitions.RootPackage") - else if (sym == RootClass) - mirrorSelect("definitions.RootClass") - else if (sym == EmptyPackage) - mirrorSelect("definitions.EmptyPackage") - else if (sym.isModuleClass) - Select(reifySymRef(sym.sourceModule), "moduleClass") - else if (sym.isStatic && sym.isClass) - mirrorCall("staticClass", reify(sym.fullName)) - else if (sym.isStatic && sym.isModule) - mirrorCall("staticModule", reify(sym.fullName)) - else if (isLocatable(sym)) - if (sym.isTypeParameter) - mirrorCall("selectParam", reify(sym.owner), reify(sym.paramPos)) - else { - if (reifyDebug) println("locatable: " + sym + " " + sym.isPackageClass + " " + sym.owner + " " + sym.isTypeParameter) - val rowner = reify(sym.owner) - val rname = reify(sym.name.toString) - if (sym.isType) - mirrorCall("selectType", rowner, rname) - else if (sym.isMethod && sym.owner.isClass && sym.owner.info.decl(sym.name).isOverloaded) { - val index = sym.owner.info.decl(sym.name).alternatives indexOf sym - assert(index >= 0, sym) - mirrorCall("selectOverloadedMethod", rowner, rname, reify(index)) - } else - mirrorCall("selectTerm", rowner, rname) - } - else { - if (sym.isTerm) { - if (reifyDebug) println("Free: " + sym) - val symtpe = lambdaLift.boxIfCaptured(sym, sym.tpe, erasedTypes = false) - def markIfCaptured(arg: Ident): Tree = - if (sym.isCapturedVariable) referenceCapturedVariable(arg) else arg - mirrorCall("newFreeVar", reify(sym.name.toString), reify(symtpe), markIfCaptured(Ident(sym))) - } else { - if (reifyDebug) println("Late local: " + sym) - registerReifiableSymbol(sym) - reifySymRef(sym) - } - } - } - } - - /** - * reify the creation of a symbol - */ - private def reifySymbolDef(sym: Symbol): Tree = { - if (reifyDebug) println("reify sym def " + sym) - - ValDef(NoMods, localName(sym), TypeTree(), - Apply( - Select(reify(sym.owner), "newNestedSymbol"), - List(reify(sym.name), reify(sym.pos), Literal(Constant(sym.flags)), Literal(Constant(sym.isClass))) - ) - ) - } - - /** - * Generate code to add type and annotation info to a reified symbol - */ - private def fillInSymbol(sym: Symbol): Tree = { - val rset = Apply(Select(reifySymRef(sym), nme.setTypeSignature), List(reifyType(sym.info))) - if (sym.annotations.isEmpty) rset - else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations))) - } - - /** Reify a scope */ - private def reifyScope(scope: Scope): Tree = { - scope foreach registerReifiableSymbol - mirrorCall(nme.newScopeWith, scope.toList map reifySymRef: _*) - } - - /** Reify a list of symbols that need to be created */ - private def reifySymbols(syms: List[Symbol]): Tree = { - syms foreach registerReifiableSymbol - mkList(syms map reifySymRef) - } - - /** Reify a type that defines some symbols */ - private def reifyTypeBinder(value: Product, bound: List[Symbol], underlying: Type): Tree = - mirrorFactoryCall(value, reifySymbols(bound), reify(underlying)) - - /** Reify a type */ - private def reifyType(tpe0: Type): Tree = { - val tpe = tpe0.normalize - - if (tpe.isErroneous) - CannotReifyErroneousType(tpe) - if (definedInLiftedCode(tpe)) - CannotReifyTypeInvolvingBoundType(tpe) - - val tsym = tpe.typeSymbol - if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic) - Select(reifySymRef(tpe.typeSymbol), nme.asTypeConstructor) - else tpe match { - case t @ NoType => - reifyMirrorObject(t) - case t @ NoPrefix => - reifyMirrorObject(t) - case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic => - mirrorCall(nme.thisModuleType, reify(clazz.fullName)) - case t @ RefinedType(parents, decls) => - registerReifiableSymbol(tpe.typeSymbol) - mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol)) - case t @ ClassInfoType(parents, decls, clazz) => - registerReifiableSymbol(clazz) - mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol)) - case t @ ExistentialType(tparams, underlying) => - reifyTypeBinder(t, tparams, underlying) - case t @ PolyType(tparams, underlying) => - reifyTypeBinder(t, tparams, underlying) - case t @ MethodType(params, restpe) => - reifyTypeBinder(t, params, restpe) - case t @ AnnotatedType(anns, underlying, selfsym) => - val saved1 = reifySymbols - val saved2 = reifyTypes - - try { - // one more quirk of reifying annotations - // - // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs - // that's because a lot of logic expects post-typer trees to have non-null tpes - // - // Q: reified trees are pre-typer, so there's shouldn't be a problem. - // reflective typechecker will fill in missing symbols and types, right? - // A: actually, no. annotation ASTs live inside AnnotatedTypes, - // and insides of the types is the place where typechecker doesn't look. - reifySymbols = true - reifyTypes = true - if (reifyDebug) println("reify AnnotatedType: " + tpe) - reifyProductUnsafe(tpe) - } finally { - reifySymbols = saved1 - reifyTypes = saved2 - } - case _ => - reifyProductUnsafe(tpe) - } - } - - var reifySymbols = false - var reifyTypes = false - - /** Preprocess a tree before reification */ - private def trimTree(tree: Tree): Tree = { - def trimSyntheticCaseClassMembers(deff: Tree, stats: List[Tree]) = { - var stats1 = stats filterNot (stat => stat.isDef && { - if (stat.symbol.isCaseAccessorMethod && reifyDebug) println("discarding case accessor method: " + stat) - stat.symbol.isCaseAccessorMethod - }) - stats1 = stats1 filterNot (memberDef => memberDef.isDef && { - val isSynthetic = memberDef.symbol.isSynthetic - // @xeno.by: this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass) - // that's why I replace the check with an assumption that all synthetic members are, in fact, generated of case classes -// val isCaseMember = deff.symbol.isCaseClass || deff.symbol.companionClass.isCaseClass - val isCaseMember = true - if (isSynthetic && isCaseMember && reifyDebug) println("discarding case class synthetic def: " + memberDef) - isSynthetic && isCaseMember - }) - stats1 = stats1 map { - case valdef @ ValDef(mods, name, tpt, rhs) if valdef.symbol.isCaseAccessor => - if (reifyDebug) println("resetting visibility of case accessor field: " + valdef) - val Modifiers(flags, privateWithin, annotations) = mods - val flags1 = flags & ~Flags.LOCAL & ~Flags.PRIVATE - val mods1 = Modifiers(flags1, privateWithin, annotations) - ValDef(mods1, name, tpt, rhs).copyAttrs(valdef) - case stat => - stat - } - stats1 - } - - def trimSyntheticCaseClassCompanions(stats: List[Tree]) = - stats diff (stats collect { case moddef: ModuleDef => moddef } filter (moddef => { - val isSynthetic = moddef.symbol.isSynthetic - // @xeno.by: this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass) - // that's why I replace the check with an assumption that all synthetic modules are, in fact, companions of case classes -// val isCaseCompanion = moddef.symbol.companionClass.isCaseClass - val isCaseCompanion = true - // @xeno.by: we also have to do this ugly hack for the very same reason described above - // normally this sort of stuff is performed in reifyTree, which binds related symbols, however, local companions will be out of its reach - if (reifyDebug) println("boundSym: "+ moddef.symbol) - boundSyms += moddef.symbol - if (isSynthetic && isCaseCompanion && reifyDebug) println("discarding synthetic case class companion: " + moddef) - isSynthetic && isCaseCompanion - })) - - tree match { - case tree if tree.isErroneous => - tree - case ta @ TypeApply(hk, ts) => - def isErased(tt: TypeTree) = tt.tpe != null && definedInLiftedCode(tt.tpe) && tt.original == null - val discard = ts collect { case tt: TypeTree => tt } exists isErased - if (reifyDebug && discard) println("discarding TypeApply: " + tree) - if (discard) hk else ta - case classDef @ ClassDef(mods, name, params, impl) => - val Template(parents, self, body) = impl - val body1 = trimSyntheticCaseClassMembers(classDef, body) - var impl1 = Template(parents, self, body1).copyAttrs(impl) - ClassDef(mods, name, params, impl1).copyAttrs(classDef) - case moduledef @ ModuleDef(mods, name, impl) => - val Template(parents, self, body) = impl - val body1 = trimSyntheticCaseClassMembers(moduledef, body) - var impl1 = Template(parents, self, body1).copyAttrs(impl) - ModuleDef(mods, name, impl1).copyAttrs(moduledef) - case template @ Template(parents, self, body) => - val body1 = trimSyntheticCaseClassCompanions(body) - Template(parents, self, body1).copyAttrs(template) - case block @ Block(stats, expr) => - val stats1 = trimSyntheticCaseClassCompanions(stats) - Block(stats1, expr).copyAttrs(block) - case valdef @ ValDef(mods, name, tpt, rhs) if valdef.symbol.isLazy => - if (reifyDebug) println("dropping $lzy in lazy val's name: " + tree) - val name1 = if (name endsWith nme.LAZY_LOCAL) name dropRight nme.LAZY_LOCAL.length else name - ValDef(mods, name1, tpt, rhs).copyAttrs(valdef) - case unapply @ UnApply(fun, args) => - def extractExtractor(tree: Tree): Tree = { - val Apply(fun, args) = tree - args match { - case List(Ident(special)) if special == nme.SELECTOR_DUMMY => - val Select(extractor, flavor) = fun - assert(flavor == nme.unapply || flavor == nme.unapplySeq) - extractor - case _ => - extractExtractor(fun) - } - } - - if (reifyDebug) println("unapplying unapply: " + tree) - val fun1 = extractExtractor(fun) - Apply(fun1, args).copyAttrs(unapply) - case _ => - tree - } - } - - /** Reify a tree */ - private def reifyTree(tree0: Tree): Tree = { - val tree = trimTree(tree0) - - var rtree = tree match { - case tree if tree.isErroneous => - CannotReifyErroneousTree(tree) - case self.EmptyTree => - reifyMirrorObject(EmptyTree) - case self.emptyValDef => - mirrorSelect(nme.emptyValDef) - case This(_) if tree.symbol != NoSymbol && !(boundSyms contains tree.symbol) => - reifyFree(tree) - case Ident(_) if tree.symbol != NoSymbol && !(boundSyms contains tree.symbol) => - if (tree.symbol.isVariable && tree.symbol.owner.isTerm) { - if (reifyDebug) println("captured variable: " + tree.symbol) - captureVariable(tree.symbol) // Note order dependency: captureVariable needs to come before reifyTree here. - mirrorCall("Select", reifyFree(tree), reifyName(nme.elem)) - } else reifyFree(tree) - case tt: TypeTree if (tt.tpe != null) => - reifyTypeTree(tt) - case Literal(constant @ Constant(tpe: Type)) if boundSyms exists (tpe contains _) => - CannotReifyClassOfBoundType(tree, tpe) - case Literal(constant @ Constant(sym: Symbol)) if boundSyms contains sym => - CannotReifyClassOfBoundEnum(tree, constant.tpe) - case tree if tree.isDef => - if (reifyDebug) println("boundSym: %s of type %s".format(tree.symbol, (tree.productIterator.toList collect { case tt: TypeTree => tt } headOption).getOrElse(TypeTree(tree.tpe)))) - boundSyms += tree.symbol - - bindRelatedSymbol(tree.symbol.sourceModule, "sourceModule") - bindRelatedSymbol(tree.symbol.moduleClass, "moduleClass") - bindRelatedSymbol(tree.symbol.companionClass, "companionClass") - bindRelatedSymbol(tree.symbol.companionModule, "companionModule") - Some(tree.symbol) collect { case termSymbol: TermSymbol => bindRelatedSymbol(termSymbol.referenced, "referenced") } - def bindRelatedSymbol(related: Symbol, name: String): Unit = - if (related != null && related != NoSymbol) { - if (reifyDebug) println("boundSym (" + name + "): " + related) - boundSyms += related - } - - val prefix = tree.productPrefix - val elements = (tree.productIterator map { - // annotations exist in two flavors: - // 1) pre-typer ones that populate: a) Modifiers, b) Annotated nodes (irrelevant in this context) - // 2) post-typer ones that dwell inside: a) sym.annotations, b) AnnotatedTypes (irrelevant in this context) - // - // here we process Modifiers that are involved in deftrees - // AnnotatedTypes get reified elsewhere (currently, in ``reifyTypeTree'') - case Modifiers(flags, privateWithin, annotations) => - assert(annotations.isEmpty) // should've been eliminated by the typer - val postTyper = tree.symbol.annotations filter (_.original != EmptyTree) - if (reifyDebug && !postTyper.isEmpty) println("reify symbol annotations for %s: %s".format(tree.symbol, tree.symbol.annotations)) - val preTyper = postTyper map toPreTyperAnnotation - Modifiers(flags, privateWithin, preTyper) - case x => - x - }).toList - reifyProduct(prefix, elements) - case _ => - reifyProduct(tree) - } - - // usually we don't reify symbols/types, because they can be re-inferred during subsequent reflective compilation - // however, reification of AnnotatedTypes is special. see ``reifyType'' to find out why. - if (reifySymbols && tree.hasSymbol) { - if (reifyDebug) println("reifying symbol %s for tree %s".format(tree.symbol, tree)) - rtree = Apply(Select(rtree, nme.setSymbol), List(reifySymRef(tree.symbol))) - } - if (reifyTypes && tree.tpe != null) { - if (reifyDebug) println("reifying type %s for tree %s".format(tree.tpe, tree)) - rtree = Apply(Select(rtree, nme.setType), List(reifyType(tree.tpe))) - } - - rtree - } - - /** Reify pre-typer representation of a type. - * - * NB: This is the trickiest part of reification! - * - * In most cases, we're perfectly fine to reify a Type itself (see ``reifyType''). - * However if the type involves a symbol declared inside the quasiquote (i.e. registered in ``boundSyms''), - * then we cannot reify it, or otherwise subsequent reflective compilation will fail. - * - * Why will it fail? Because reified deftrees (e.g. ClassDef(...)) will generate fresh symbols during that compilation, - * so naively reified symbols will become out of sync, which brings really funny compilation errors and/or crashes, e.g.: - * https://issues.scala-lang.org/browse/SI-5230 - * - * To deal with this unpleasant fact, we need to fall back from types to equivalent trees (after all, parser trees don't contain any types, just trees, so it should be possible). - * Luckily, these original trees get preserved for us in the ``original'' field when Trees get transformed into TypeTrees. - * And if an original of a type tree is empty, we can safely assume that this type is non-essential (e.g. was inferred/generated by the compiler). - * In that case the type can be omitted (e.g. reified as an empty TypeTree), since it will be inferred again later on. - * - * An important property of the original is that it isn't just a pre-typer tree. - * It's actually kind of a post-typer tree with symbols assigned to its Idents (e.g. Ident("List") will contain a symbol that points to immutable.this.List). - * This is very important, since subsequent reflective compilation won't have to resolve these symbols. - * In general case, such resolution cannot be performed, since reification doesn't preserve lexical context, - * which means that reflective compilation won't be aware of, say, imports that were provided when the reifee has been compiled. - * - * This workaround worked surprisingly well and allowed me to fix several important reification bugs, until the abstraction has leaked. - * Suddenly I found out that in certain contexts original trees do not contain symbols, but are just parser trees. - * To the moment I know only one such situation: typedAnnotations does not typecheck the annotation in-place, but rather creates new trees and typechecks them, so the original remains symless. - * This is laboriously worked around in the code below. I hope this will be the only workaround in this department. - */ - private def reifyTypeTree(tt: TypeTree): Tree = { - if (definedInLiftedCode(tt.tpe)) { - if (reifyDebug) println("reifyTypeTree, defined in lifted code: " + tt.tpe) - if (tt.original != null) { - val annotations = tt.tpe filter { _.isInstanceOf[AnnotatedType] } collect { case atp: AnnotatedType => atp.annotations } flatten - val annmap = annotations map { ann => (ann.original, ann) } toMap - - // annotations exist in two flavors: - // 1) pre-typer ones that populate: a) Modifiers (irrelevant in this context), b) Annotated nodes - // 2) post-typer ones that dwell inside: a) sym.annotations (irrelevant in this context), b) AnnotatedTypes - // - // here we process AnnotatedTypes, since only they can be involved in TypeTrees - // Modifiers get reified elsewhere (currently, in the "isDef" case of ``reifyTree'') - // - // the problem with annotations is that their originals don't preserve any symbols at all - // read the comment to this method to find out why it's bad - // that's why we transplant typechecked, i.e. symful, annotations onto original trees - class AnnotationFixup extends self.Transformer { - override def transform(tree: Tree) = tree match { - case Annotated(ann0, args) => - assert(annmap contains ann0) - val ann1 = annmap(ann0) - val ann = toPreTyperAnnotation(ann1) - Annotated(ann, transform(args)) - case _ => - tree - } - } - - if (reifyDebug) println("verdict: essential, reify as original") - val patchedOriginal = new AnnotationFixup().transform(tt.original) - reifyTree(patchedOriginal) - } else { - // type is deemed to be non-essential - // erase it and hope that subsequent reflective compilation will be able to recreate it again - if (reifyDebug) println("verdict: non-essential, discard") - mirrorCall("TypeTree") - } - } else { - var rtt = mirrorCall(nme.TypeTree, reifyType(tt.tpe)) - // @xeno.by: temporarily disabling reification of originals - // subsequent reflective compilation will try to typecheck them - // and this means that the reifier has to do additional efforts to ensure that this will succeed - // additional efforts + no clear benefit = will be implemented later -// if (tt.original != null) { -// val setOriginal = Select(rtt, newTermName("setOriginal")) -// val reifiedOriginal = reify(tt.original) -// rtt = Apply(setOriginal, List(reifiedOriginal)) -// } - rtt - } - } - - /** Reify post-typer representation of an annotation */ - private def reifyAnnotation(ann: AnnotationInfo): Tree = - // @xeno.by: if you reify originals, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important - mirrorFactoryCall("AnnotationInfo", reifyType(ann.atp), reifyList(ann.args), reify(ann.assocs)) - - /** Reify pre-typer representation of an annotation. - * The trick here is to retain the symbols that have been populated during typechecking of the annotation. - * If we do not do that, subsequent reflective compilation will fail. - */ - private def toPreTyperAnnotation(ann: AnnotationInfo): Tree = { - if (definedInLiftedCode(ann.atp)) { - // todo. deconstruct reifiable tree from ann.original and ann.args+ann.assocs - // - // keep in mind that we can't simply use ann.original, because its args are symless - // which means that any imported symbol (e.g. List) will crash subsequent reflective compilation - // hint: if I had enough time, I'd try to extract reifiable annotation type from ann.original - // and to apply its constructor to ann.args (that are symful, i.e. suitable for reification) - // - // also, if we pursue the route of reifying annotations defined in lifted code - // we should think about how to provide types for all nodes of the return value - // this will be necessary for reifying AnnotatedTypes, since ASTs inside ATs must all have non-null tpes - // an alternative would be downgrading ATs to Annotated nodes, but this needs careful thinking - // for now I just leave this as an implementation restriction - CannotReifyAnnotationInvolvingBoundType(ann) - } else { - val args = if (ann.assocs.isEmpty) { - ann.args - } else { - def toScalaAnnotation(jann: ClassfileAnnotArg): Tree = jann match { - case LiteralAnnotArg(const) => - Literal(const) - case ArrayAnnotArg(arr) => - Apply(Ident(definitions.ArrayModule), arr.toList map toScalaAnnotation) - case NestedAnnotArg(ann) => - toPreTyperAnnotation(ann) - } - - ann.assocs map { case (nme, arg) => AssignOrNamedArg(Ident(nme), toScalaAnnotation(arg)) } - } - - New(ann.atp, args: _*) - } - } - - /** - * Reify a free reference. The result will be either a mirror reference - * to a global value, or else a mirror Literal. - */ - private def reifyFree(tree: Tree): Tree = tree match { - case This(_) if tree.symbol.isClass && !tree.symbol.isModuleClass => - val sym = tree.symbol - if (reifyDebug) println("This for %s, reified as freeVar".format(sym)) - if (reifyDebug) println("Free: " + sym) - val freeVar = mirrorCall("newFreeVar", reify(sym.name.toString), reify(sym.tpe), This(sym)) - mirrorCall(nme.Ident, freeVar) - case This(_) => - if (reifyDebug) println("This for %s, reified as This".format(tree.symbol)) - mirrorCall(nme.This, reifySymRef(tree.symbol)) - case _ => - mirrorCall(nme.Ident, reifySymRef(tree.symbol)) - } - - // todo: consider whether we should also reify positions - private def reifyPosition(pos: Position): Tree = - reifyMirrorObject(NoPosition) - - // !!! we must eliminate these casts. - private def reifyProductUnsafe(x: Any): Tree = - if (x.isInstanceOf[Product]) reifyProduct(x.asInstanceOf[Product]) - else throw new Exception("%s of type %s cannot be cast to Product".format(x, x.getClass)) - private def reifyProduct(x: Product): Tree = - reifyProduct(x.productPrefix, x.productIterator.toList) - private def reifyProduct(prefix: String, elements: List[Any]): Tree = { - // @xeno.by: reflection would be more robust, but, hey, this is a hot path - if (prefix.startsWith("Tuple")) reifyAggregate(prefix, elements: _*) - else mirrorCall(prefix, (elements map reify): _*) - } - - /** - * Reify a case object defined in Mirror - */ - private def reifyMirrorObject(name: String): Tree = mirrorSelect(name) - private def reifyMirrorObject(x: Product): Tree = reifyMirrorObject(x.productPrefix) - - private def isReifiableConstant(value: Any) = value match { - case null => true // seems pretty reifable to me? - case _: String => true - case _ => isAnyVal(value) - } - - /** Reify an arbitary value */ - private def reify(value: Any): Tree = value match { - case tree: Tree => reifyTree(tree) - case sym: Symbol => reifySymRef(sym) - case tpe: Type => reifyType(tpe) - case xs: List[_] => reifyList(xs) - case xs: Array[_] => reifyArray(xs) - case scope: Scope => reifyScope(scope) - case x: Name => reifyName(x) - case x: Position => reifyPosition(x) - case x: Modifiers => reifyModifiers(x) - case x: AnnotationInfo => reifyAnnotation(x) - case _ => - if (isReifiableConstant(value)) Literal(Constant(value)) - else reifyProductUnsafe(value) - } - - /** - * An (unreified) path that refers to definition with given fully qualified name - * @param mkName Creator for last portion of name (either TermName or TypeName) - */ - private def path(fullname: String, mkName: String => Name): Tree = { - val parts = fullname split "\\." - val prefixParts = parts.init - val lastName = mkName(parts.last) - if (prefixParts.isEmpty) Ident(lastName) - else { - val prefixTree = ((Ident(prefixParts.head): Tree) /: prefixParts.tail)(Select(_, _)) - Select(prefixTree, lastName) - } - } - - /** An (unreified) path that refers to term definition with given fully qualified name */ - private def termPath(fullname: String): Tree = path(fullname, newTermName) - - /** An (unreified) path that refers to type definition with given fully qualified name */ - private def typePath(fullname: String): Tree = path(fullname, newTypeName) - - private def mirrorAlias = - ValDef(NoMods, nme.MIRROR_SHORT, SingletonTypeTree(termPath(fullnme.MirrorPackage)), termPath(fullnme.MirrorPackage)) - - /** - * Generate code that generates a symbol table of all symbols registered in `reifiableSyms` - */ - private def reifySymbolTableSetup: List[Tree] = { - val symDefs, fillIns = new mutable.ArrayBuffer[Tree] - var i = 0 - while (i < reifiableSyms.length) { - // fillInSymbol might create new reifiableSyms, that's why this is done iteratively - symDefs += reifySymbolDef(reifiableSyms(i)) - fillIns += fillInSymbol(reifiableSyms(i)) - i += 1 - } - - symDefs.toList ++ fillIns.toList - } - } // end of Reifier - - object Reifier { - def CannotReifyPreTyperTree(tree: Tree) = { - val msg = "pre-typer trees are not supported, consider typechecking the tree before passing it to the reifier" - throw new ReifierError(tree.pos, msg) - } - - def CannotReifyErroneousTree(tree: Tree) = { - val msg = "erroneous trees are not supported, make sure that your tree typechecks successfully before passing it to the reifier" - throw new ReifierError(tree.pos, msg) - } - - def CannotReifyErroneousType(tpe: Type) = { - val msg = "erroneous types are not supported, make sure that your tree typechecks successfully before passing it to the reifier" - throw new ReifierError(NoPosition, msg) - } - - def CannotReifyClassOfBoundType(tree: Tree, tpe: Type) = { - val msg = "implementation restriction: cannot reify classOf[%s] which refers to a type declared inside the block being reified".format(tpe) - throw new ReifierError(tree.pos, msg) - } - - def CannotReifyClassOfBoundEnum(tree: Tree, tpe: Type) = { - val msg = "implementation restriction: cannot reify classOf[%s] which refers to an enum declared inside the block being reified".format(tpe) - throw new ReifierError(tree.pos, msg) - } - - def CannotReifyTypeInvolvingBoundType(tpe: Type) = { - val msg = "implementation restriction: cannot reify type %s which involves a symbol declared inside the block being reified".format(tpe) - throw new ReifierError(NoPosition, msg) - } - - def CannotReifyAnnotationInvolvingBoundType(ann: AnnotationInfo) = { - val msg = "implementation restriction: cannot reify annotation @%s which involves a symbol declared inside the block being reified".format(ann) - throw new ReifierError(ann.original.pos, msg) - } - } // end of Reifier - - // begin reify - import Reifier._ - if (tree.tpe != null) { - val saved = printTypings - try { - val reifyDebug = settings.Yreifydebug.value - val debugTrace = util.trace when reifyDebug - debugTrace("transforming = ")(if (settings.Xshowtrees.value) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) - debugTrace("transformed = ") { - val reifier = new Reifier() - val untyped = reifier.reifyTopLevel(tree) - - val reifyCopypaste = settings.Yreifycopypaste.value - if (reifyCopypaste) { - if (reifyDebug) println("=======================") - println(reifiedNodeToString(untyped)) - if (reifyDebug) println("=======================") - } - - untyped - } - } finally { - printTypings = saved - } - } else { - CannotReifyPreTyperTree(tree) - } - } - - /** A throwable signalling a reification error */ - class ReifierError(var pos: Position, val msg: String) extends Throwable(msg) { - def this(msg: String) = this(NoPosition, msg) - } -} diff --git a/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala b/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala deleted file mode 100644 index fce59bb099..0000000000 --- a/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala +++ /dev/null @@ -1,75 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.tools.nsc -package ast - -import compat.Platform.EOL -import symtab._ -import Flags._ - -trait ReifyPrinters { self: NodePrinters => - - val global: Global - import global._ - - object reifiedNodeToString extends Function1[Tree, String] { - def apply(tree: Tree): String = { - import scala.reflect.api.Modifier - - // @PP: I fervently hope this is a test case or something, not anything being - // depended upon. Of more fragile code I cannot conceive. - // @eb: 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. - (for (line <- (tree.toString.split(EOL) drop 2 dropRight 1)) yield { - var s = line.trim - s = s.replace("$mr.", "") - s = s.replace(".apply", "") - s = s.replace("scala.collection.immutable.", "") - s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List") - s = "List\\[.*?\\]".r.replaceAllIn(s, "List") - s = s.replace("immutable.this.Nil", "List()") - s = s.replace("modifiersFromInternalFlags", "Modifiers") - s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()") - s = """Modifiers\((\d+)[lL], newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => { - val buf = new collection.mutable.ListBuffer[String] - - val annotations = m.group(3) - if (buf.nonEmpty || annotations.nonEmpty) - buf.append("List(" + annotations + ")") - - val privateWithin = "" + m.group(2) - if (buf.nonEmpty || privateWithin != "") - buf.append("newTypeName(\"" + privateWithin + "\")") - - val flags = m.group(1).toLong - val s_flags = Flags.modifiersOfFlags(flags) map (_.sourceString) mkString ", " - if (buf.nonEmpty || s_flags != "") - buf.append("Set(" + s_flags + ")") - - "Modifiers(" + buf.reverse.mkString(", ") + ")" - }) - s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => { - val flags = m.group(1).toLong - val mods = Flags.modifiersOfFlags(flags) map (_.sourceString) - "setInternalFlags(flagsOfModifiers(List(" + mods.mkString(", ") + ")))" - }) - - s - }) mkString EOL - } - } - - - def printReifyCopypaste(tree: Tree) { - val reifyDebug = settings.Yreifydebug.value - if (reifyDebug) println("=======================") - printReifyCopypaste1(tree) - if (reifyDebug) println("=======================") - } - - def printReifyCopypaste1(tree: Tree) { - } -} \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index ad26ccad5e..19d1e0a51a 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -207,22 +207,6 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { def mkSysErrorCall(message: String): Tree = mkMethodCall(Sys_error, List(Literal(Constant(message)))) - /** A creator for a call to a scala.reflect.Manifest or ClassManifest factory method. - * - * @param full full or partial manifest (target will be Manifest or ClassManifest) - * @param constructor name of the factory method (e.g. "classType") - * @param tparg the type argument - * @param args value arguments - * @return the tree - */ - def mkManifestFactoryCall(full: Boolean, constructor: String, tparg: Type, args: List[Tree]): Tree = - mkMethodCall( - if (full) FullManifestModule else PartialManifestModule, - newTermName(constructor), - List(tparg), - args - ) - /** Make a synchronized block on 'monitor'. */ def mkSynchronized(monitor: Tree, body: Tree): Tree = Apply(Select(monitor, Object_synchronized), List(body)) diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 43c231cf2d..66704680ae 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -13,6 +13,7 @@ import scala.reflect.internal.Flags.PARAM import scala.reflect.internal.Flags.PARAMACCESSOR import scala.reflect.internal.Flags.PRESUPER import scala.reflect.internal.Flags.TRAIT +import scala.compat.Platform.EOL trait Trees extends reflect.internal.Trees { self: Global => @@ -33,30 +34,6 @@ trait Trees extends reflect.internal.Trees { self: Global => ) } - class ValidatingPosAssigner extends PosAssigner { - var pos: Position = _ - override def traverse(t: Tree) { - if (t eq EmptyTree) () - else if (t.pos == NoPosition) super.traverse(t setPos pos) - else if (globalPhase.id <= currentRun.picklerPhase.id) { - // When we prune due to encountering a position, traverse the - // pruned children so we can warn about those lacking positions. - t.children foreach { c => - if ((c eq EmptyTree) || (c eq emptyValDef)) () - else if (c.pos == NoPosition) { - reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase) - inform("parent: " + treeSymStatus(t)) - inform(" child: " + treeSymStatus(c) + "\n") - } - } - } - } - } - - override protected[this] lazy val posAssigner: PosAssigner = - if (settings.Yrangepos.value && settings.debug.value || settings.Yposdebug.value) new ValidatingPosAssigner - else new DefaultPosAssigner - // --- additional cases -------------------------------------------------------- /** Only used during parsing */ case class Parens(args: List[Tree]) extends Tree @@ -84,15 +61,6 @@ trait Trees extends reflect.internal.Trees { self: Global => /** emitted by typer, eliminated by refchecks */ case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree - /** Marks underlying reference to id as boxed. - * @pre: id must refer to a captured variable - * A reference such marked will refer to the boxed entity, no dereferencing - * with `.elem` is done on it. - * This tree node can be emitted by macros such as reify that call markBoxedReference. - * It is eliminated in LambdaLift, where the boxing conversion takes place. - */ - case class ReferenceToBoxed(idt: Ident) extends TermTree - // --- factory methods ---------------------------------------------------------- /** Generates a template with constructor corresponding to @@ -118,7 +86,7 @@ trait Trees extends reflect.internal.Trees { self: Global => // create parameters for as synthetic trees. var vparamss1 = vparamss map (vps => vps.map { vd => - atPos(focusPos(vd.pos)) { + atPos(vd.pos.focus) { ValDef( Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, vd.rhs.duplicate) @@ -130,7 +98,7 @@ trait Trees extends reflect.internal.Trees { self: Global => // !!! I know "atPos in case" wasn't intentionally planted to // add an air of mystery to this file, but it is the sort of // comment which only its author could love. - tpt = atPos(focusPos(vdef.pos))(TypeTree() setOriginal tpt setPos focusPos(tpt.pos)), // atPos in case + tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus), // atPos in case rhs = EmptyTree ) } @@ -198,8 +166,6 @@ trait Trees extends reflect.internal.Trees { self: Global => traverser.traverse(qualifier) case InjectDerivedValue(arg) => traverser.traverse(arg) - case ReferenceToBoxed(idt) => - traverser.traverse(idt) case TypeTreeWithDeferredRefCheck() => // (and rewrap the result? how to update the deferred check? would need to store wrapped tree instead of returning it from check) case _ => super.xtraverse(traverser, tree) @@ -209,7 +175,6 @@ trait Trees extends reflect.internal.Trees { self: Global => def DocDef(tree: Tree, comment: DocComment, definition: Tree): DocDef def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type): SelectFromArray def InjectDerivedValue(tree: Tree, arg: Tree): InjectDerivedValue - def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck } @@ -223,8 +188,6 @@ trait Trees extends reflect.internal.Trees { self: Global => new SelectFromArray(qualifier, selector, erasure).copyAttrs(tree) def InjectDerivedValue(tree: Tree, arg: Tree) = new InjectDerivedValue(arg) - def ReferenceToBoxed(tree: Tree, idt: Ident) = - new ReferenceToBoxed(idt).copyAttrs(tree) def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match { case dc@TypeTreeWithDeferredRefCheck() => new TypeTreeWithDeferredRefCheck()(dc.check).copyAttrs(tree) } @@ -246,11 +209,6 @@ trait Trees extends reflect.internal.Trees { self: Global => if (arg0 == arg) => t case _ => this.treeCopy.InjectDerivedValue(tree, arg) } - def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match { - case t @ ReferenceToBoxed(idt0) - if (idt0 == idt) => t - case _ => this.treeCopy.ReferenceToBoxed(tree, idt) - } def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match { case t @ TypeTreeWithDeferredRefCheck() => t case _ => this.treeCopy.TypeTreeWithDeferredRefCheck(tree) @@ -277,9 +235,6 @@ trait Trees extends reflect.internal.Trees { self: Global => case InjectDerivedValue(arg) => transformer.treeCopy.InjectDerivedValue( tree, transformer.transform(arg)) - case ReferenceToBoxed(idt) => - transformer.treeCopy.ReferenceToBoxed( - tree, transformer.transform(idt) match { case idt1: Ident => idt1 }) case TypeTreeWithDeferredRefCheck() => transformer.treeCopy.TypeTreeWithDeferredRefCheck(tree) } @@ -296,8 +251,8 @@ trait Trees extends reflect.internal.Trees { self: Global => // def resetAllAttrs[A<:Tree](x:A): A = { new ResetAttrsTraverser().traverse(x); x } // def resetLocalAttrs[A<:Tree](x:A): A = { new ResetLocalAttrsTraverser().traverse(x); x } - def resetAllAttrs[A<:Tree](x:A): A = new ResetAttrs(false).transform(x) - def resetLocalAttrs[A<:Tree](x:A): A = new ResetAttrs(true).transform(x) + def resetAllAttrs[A <: Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(false, leaveAlone).transform(x) + def resetLocalAttrs[A <: Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(true, leaveAlone).transform(x) /** A transformer which resets symbol and tpe fields of all nodes in a given tree, * with special treatment of: @@ -308,7 +263,7 @@ trait Trees extends reflect.internal.Trees { self: Global => * * (bq:) This transformer has mutable state and should be discarded after use */ - private class ResetAttrs(localOnly: Boolean) { + private class ResetAttrs(localOnly: Boolean, leaveAlone: Tree => Boolean = null) { val debug = settings.debug.value val trace = scala.tools.nsc.util.trace when debug @@ -328,6 +283,12 @@ trait Trees extends reflect.internal.Trees { self: Global => registerLocal(sym) registerLocal(sym.sourceModule) registerLocal(sym.moduleClass) + registerLocal(sym.companionClass) + registerLocal(sym.companionModule) + sym match { + case sym: TermSymbol => registerLocal(sym.referenced) + case _ => ; + } } } @@ -335,10 +296,8 @@ trait Trees extends reflect.internal.Trees { self: Global => tree match { case _: DefTree | Function(_, _) | Template(_, _, _) => markLocal(tree) - case _ if tree.symbol.isInstanceOf[FreeVar] => - markLocal(tree) case _ => - ; + tree } super.traverse(tree) @@ -346,43 +305,48 @@ trait Trees extends reflect.internal.Trees { self: Global => } class Transformer extends self.Transformer { - override def transform(tree: Tree): Tree = super.transform { - tree match { - case tpt: TypeTree => - if (tpt.original != null) { - transform(tpt.original) - } else { - if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => locals contains tp.typeSymbol)))) - tpt.tpe = null - tree + override def transform(tree: Tree): Tree = { + if (leaveAlone != null && leaveAlone(tree)) + tree + else + super.transform { + tree match { + case tpt: TypeTree => + if (tpt.original != null) { + transform(tpt.original) + } else { + if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => locals contains tp.typeSymbol)))) + tpt.tpe = null + tree + } + case TypeApply(fn, args) if args map transform exists (_.isEmpty) => + transform(fn) + case This(_) if tree.symbol != null && tree.symbol.isPackageClass => + tree + case EmptyTree => + tree + case _ => + if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol))) + tree.symbol = NoSymbol + tree.tpe = null + tree } - case TypeApply(fn, args) if args map transform exists (_.isEmpty) => - transform(fn) - case This(_) if tree.symbol != null && tree.symbol.isPackageClass => - tree - case EmptyTree => - tree - case _ => - if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol))) - tree.symbol = NoSymbol - tree.tpe = null - tree + } } - } } def transform[T <: Tree](x: T): T = { - new MarkLocals().traverse(x) + if (localOnly) + new MarkLocals().traverse(x) - if (debug) { + if (localOnly && debug) { assert(locals.size == orderedLocals.size) - val eoln = System.getProperty("line.separator") - val msg = orderedLocals.toList filter {_ != NoSymbol} map {" " + _} mkString eoln + val msg = orderedLocals.toList filter {_ != NoSymbol} map {" " + _} mkString EOL trace("locals (%d total): %n".format(orderedLocals.size))(msg) } val x1 = new Transformer().transform(x) - assert(x.getClass isInstance x1) + assert(x.getClass isInstance x1, x1.getClass) x1.asInstanceOf[T] } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index e7e3eaabf5..daabfae6b3 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1771,7 +1771,23 @@ self => * }}} */ def pattern2(): Tree = { + val nameOffset = in.offset + def warnIfMacro(tree: Tree): Unit = { + def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + tree match { + case _: BackQuotedIdent => + ; + case Ident(name) => + check(name) + case _ => + ; + } + } + val p = pattern3() + warnIfMacro(p) + if (in.token != AT) p else p match { case Ident(nme.WILDCARD) => @@ -2421,10 +2437,10 @@ self => */ /** {{{ - * FunDef ::= FunSig `:' Type `=' Expr - * | FunSig [nl] `{' Block `}' - * | this ParamClause ParamClauses (`=' ConstrExpr | [nl] ConstrBlock) - * | `macro' FunSig [`:' Type] `=' Expr + * FunDef ::= FunSig [`:' Type] `=' [`macro'] Expr + * | FunSig [nl] `{' Block `}' + * | `this' ParamClause ParamClauses + * (`=' ConstrExpr | [nl] ConstrBlock) * FunDcl ::= FunSig [`:' Type] * FunSig ::= id [FunTypeParamClause] ParamClauses * }}} @@ -2444,18 +2460,16 @@ self => } else { val nameOffset = in.offset + val isBackquoted = in.token == BACKQUOTED_IDENT val name = ident() - if (name == nme.macro_ && isIdent && settings.Xmacros.value) - funDefRest(start, in.offset, mods | Flags.MACRO, ident()) - else - funDefRest(start, nameOffset, mods, name) + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + funDefRest(start, nameOffset, mods, name) } } def funDefRest(start: Int, nameOffset: Int, mods: Modifiers, name: Name): Tree = { val result = atPos(start, if (name.toTermName == nme.ERROR) start else nameOffset) { - val isMacro = mods hasFlag Flags.MACRO - val isTypeMacro = isMacro && name.isTypeName var newmods = mods // contextBoundBuf is for context bounded type parameters of the form // [T : B] or [T : => B]; it contains the equivalent implicit parameter type, @@ -2463,12 +2477,10 @@ self => val contextBoundBuf = new ListBuffer[Tree] val tparams = typeParamClauseOpt(name, contextBoundBuf) val vparamss = paramClauses(name, contextBoundBuf.toList, false) - if (!isMacro) newLineOptWhenFollowedBy(LBRACE) - var restype = if (isTypeMacro) TypeTree() else fromWithinReturnType(typedOpt()) - val rhs = - if (isMacro) - equalsExpr() - else if (isStatSep || in.token == RBRACE) { + newLineOptWhenFollowedBy(LBRACE) + var restype = fromWithinReturnType(typedOpt()) + val rhs = + if (isStatSep || in.token == RBRACE) { if (restype.isEmpty) restype = scalaUnitConstr newmods |= Flags.DEFERRED EmptyTree @@ -2476,10 +2488,12 @@ self => restype = scalaUnitConstr blockExpr() } else { - if (name == nme.macro_ && isIdent && in.token != EQUALS) { - warning("this syntactically invalid code resembles a macro definition. have you forgotten to enable -Xmacros?") + accept(EQUALS) + if (settings.Xmacros.value && in.token == MACRO) { + in.nextToken() + newmods |= Flags.MACRO } - equalsExpr() + expr() } DefDef(newmods, name, tparams, vparamss, restype, rhs) } @@ -2529,7 +2543,7 @@ self => /** {{{ * TypeDef ::= type Id [TypeParamClause] `=' Type - * | `macro' FunSig `=' Expr + * | FunSig `=' Expr * TypeDcl ::= type Id [TypeParamClause] TypeBounds * }}} */ @@ -2537,22 +2551,22 @@ self => in.nextToken() newLinesOpt() atPos(start, in.offset) { + val nameOffset = in.offset + val isBackquoted = in.token == BACKQUOTED_IDENT val name = identForType() - if (name == nme.macro_.toTypeName && isIdent && settings.Xmacros.value) { - funDefRest(start, in.offset, mods | Flags.MACRO, identForType()) - } else { - // @M! a type alias as well as an abstract type may declare type parameters - val tparams = typeParamClauseOpt(name, null) - in.token match { - case EQUALS => - in.nextToken() - TypeDef(mods, name, tparams, typ()) - case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE => - TypeDef(mods | Flags.DEFERRED, name, tparams, typeBounds()) - case _ => - syntaxErrorOrIncomplete("`=', `>:', or `<:' expected", true) - EmptyTree - } + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + // @M! a type alias as well as an abstract type may declare type parameters + val tparams = typeParamClauseOpt(name, null) + in.token match { + case EQUALS => + in.nextToken() + TypeDef(mods, name, tparams, typ()) + case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE => + TypeDef(mods | Flags.DEFERRED, name, tparams, typeBounds()) + case _ => + syntaxErrorOrIncomplete("`=', `>:', or `<:' expected", true) + EmptyTree } } } @@ -2599,7 +2613,10 @@ self => def classDef(start: Int, mods: Modifiers): ClassDef = { in.nextToken val nameOffset = in.offset + val isBackquoted = in.token == BACKQUOTED_IDENT val name = identForType() + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") atPos(start, if (name == tpnme.ERROR) start else nameOffset) { savingClassContextBounds { @@ -2640,7 +2657,10 @@ self => def objectDef(start: Int, mods: Modifiers): ModuleDef = { in.nextToken val nameOffset = in.offset + val isBackquoted = in.token == BACKQUOTED_IDENT val name = ident() + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") val tstart = in.offset atPos(start, if (name == nme.ERROR) start else nameOffset) { val mods1 = if (in.token == SUBTYPE) mods | Flags.DEFERRED else mods @@ -2818,7 +2838,25 @@ self => * }}} */ def packaging(start: Int): Tree = { + val nameOffset = in.offset + def warnIfMacro(tree: Tree): Unit = { + def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + tree match { + case _: BackQuotedIdent => + ; + case Ident(name) => + check(name) + case Select(qual, name) => + warnIfMacro(qual) + check(name) + case _ => + ; + } + } + val pkg = pkgQualId() + warnIfMacro(pkg) val stats = inBracesOrNil(topStatSeq()) makePackaging(start, pkg, stats) } @@ -3020,8 +3058,29 @@ self => ts ++= topStatSeq() } } else { + val nameOffset = in.offset + def warnIfMacro(tree: Tree): Unit = { + def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + tree match { + // [Eugene] pkgQualId never returns BackQuotedIdents + // this means that we'll get spurious warnings even if we wrap macro package name in backquotes + case _: BackQuotedIdent => + ; + case Ident(name) => + check(name) + case Select(qual, name) => + warnIfMacro(qual) + check(name) + case _ => + ; + } + } + in.flushDoc val pkg = pkgQualId() + warnIfMacro(pkg) + if (in.token == EOF) { ts += makePackaging(start, pkg, List()) } else if (isStatSep) { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 2895d02dfe..81d81a4fb7 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -1125,7 +1125,8 @@ trait Scanners extends ScannersCommon { nme.SUPERTYPEkw -> SUPERTYPE, nme.HASHkw -> HASH, nme.ATkw -> AT - ) + ) ++ + (if (settings.Xmacros.value) List(nme.MACROkw -> MACRO) else List()) private var kwOffset: Int = -1 private val kwArray: Array[Int] = { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala index fb4daefd57..e17bbf5e46 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala @@ -110,6 +110,7 @@ object Tokens extends Tokens { final val MATCH = 58 final val FORSOME = 59 final val LAZY = 61 + final val MACRO = 62 def isKeyword(code: Int) = code >= IF && code <= LAZY diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index be1e466f4e..c04be1721e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -651,7 +651,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with case StringTag => buf put 's'.toByte buf putShort cpool.addUtf8(const.stringValue).toShort - case ClassTag => + case ClazzTag => buf put 'c'.toByte buf putShort cpool.addUtf8(javaType(const.typeValue).getSignature()).toShort case EnumTag => diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala index b74981b999..807a3dd0bb 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala @@ -121,7 +121,7 @@ trait GenJVMUtil { case DoubleTag => jcode emitPUSH const.doubleValue case StringTag => jcode emitPUSH const.stringValue case NullTag => jcode.emitACONST_NULL() - case ClassTag => + case ClazzTag => val kind = toTypeKind(const.typeValue) val toPush = if (kind.isValueType) classLiteral(kind) diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index 2fb615f893..98c1fc2f63 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -365,7 +365,7 @@ abstract class GenMSIL extends SubComponent { arr.foreach(emitConst) } - // TODO: other Tags: NoTag, UnitTag, ClassTag, EnumTag, ArrayTag ??? + // TODO: other Tags: NoTag, UnitTag, ClazzTag, EnumTag, ArrayTag ??? case _ => abort("could not handle attribute argument: " + const) } @@ -388,7 +388,7 @@ abstract class GenMSIL extends SubComponent { case DoubleTag => buf.put(0x0d.toByte) case StringTag => buf.put(0x0e.toByte) - // TODO: other Tags: NoTag, UnitTag, ClassTag, EnumTag ??? + // TODO: other Tags: NoTag, UnitTag, ClazzTag, EnumTag ??? // ArrayTag falls in here case _ => abort("could not handle attribute argument: " + c) @@ -968,7 +968,7 @@ abstract class GenMSIL extends SubComponent { case DoubleTag => mcode.Emit(OpCodes.Ldc_R8, const.doubleValue) case StringTag => mcode.Emit(OpCodes.Ldstr, const.stringValue) case NullTag => mcode.Emit(OpCodes.Ldnull) - case ClassTag => + case ClazzTag => mcode.Emit(OpCodes.Ldtoken, msilType(const.typeValue)) mcode.Emit(OpCodes.Call, TYPE_FROM_HANDLE) case _ => abort("Unknown constant value: " + const) diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 5b298b3761..12a3c4b3c6 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -957,7 +957,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") if (ownerTpe.isErroneous) List() else new ImplicitSearch( tree, functionType(List(ownerTpe), AnyClass.tpe), isView = true, - context.makeImplicit(reportAmbiguousErrors = false)).allImplicits + context0 = context.makeImplicit(reportAmbiguousErrors = false)).allImplicits for (view <- applicableViews) { val vtree = viewApply(view) val vpre = stabilizedType(vtree) diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala index 88e3827403..72e5ee42ed 100644 --- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala +++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package interactive import ast.Trees -import symtab.Positions +import ast.Positions import scala.tools.nsc.util.{SourceFile, Position, RangePosition, NoPosition, WorkScheduler} import scala.collection.mutable.ListBuffer diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 0c64bb2901..c0f7d8412a 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -13,6 +13,7 @@ import scala.sys.BooleanProp import io.VirtualDirectory import scala.tools.nsc.io.AbstractFile import reporters._ +import reporters.{Reporter => NscReporter} import symtab.Flags import scala.reflect.internal.Names import scala.tools.util.PathResolver @@ -274,7 +275,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends protected def createLineManager(classLoader: ClassLoader): Line.Manager = new Line.Manager(classLoader) /** Instantiate a compiler. Overridable. */ - protected def newCompiler(settings: Settings, reporter: Reporter) = { + protected def newCompiler(settings: Settings, reporter: NscReporter) = { settings.outputDirs setSingleOutput virtualDirectory settings.exposeEmptyPackage.value = true @@ -340,7 +341,14 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def getInterpreterClassLoader() = classLoader // Set the current Java "context" class loader to this interpreter's class loader - def setContextClassLoader() = classLoader.setAsContext() + def setContextClassLoader() = { + classLoader.setAsContext() + + // this is risky, but it's our only possibility to make default reflexive mirror to work with REPL + // so far we have only used the default mirror to create a few manifests for the compiler + // so it shouldn't be in conflict with our classloader, especially since it respects its parent + scala.reflect.mirror.classLoader = classLoader + } /** Given a simple repl-defined name, returns the real name of * the class representing it, e.g. for "Bippy" it may return diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index 14876425f4..cc06100f5f 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Power.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala @@ -6,7 +6,6 @@ package scala.tools.nsc package interpreter -import scala.reflect.AnyValManifest import scala.collection.{ mutable, immutable } import scala.util.matching.Regex import scala.tools.nsc.util.{ BatchSourceFile } diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala index ad6e8dc48d..e293c0fed9 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala @@ -58,7 +58,7 @@ object ReplVals { * I have this forwarder which widens the type and then cast the result back * to the dependent type. */ - def manifestToType(m: OptManifest[_]): Global#Type = + def manifestToType(m: Manifest[_]): Global#Type = definitions.manifestToType(m) class AppliedTypeFromManifests(sym: Symbol) { diff --git a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala index 5edc8fd202..59a7b9b5d2 100644 --- a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala +++ b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala @@ -7,7 +7,7 @@ package scala.tools.nsc package interpreter class RichClass[T](val clazz: Class[T]) { - def toManifest: Manifest[T] = Manifest.classType(clazz) + def toManifest: Manifest[T] = Manifest[T](ClassManifest[T](clazz).tpe) def toTypeString: String = TypeStrings.fromClazz(clazz) // Sadly isAnonymousClass does not return true for scala anonymous diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala index 6b56d881fc..872ac00bfd 100644 --- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala +++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala @@ -10,6 +10,7 @@ import java.lang.{ reflect => r } import r.TypeVariable import scala.reflect.NameTransformer import NameTransformer._ +import scala.reflect.{mirror => rm} /** Logic for turning a type into a String. The goal is to be * able to take some arbitrary object 'x' and obtain the most precise @@ -72,8 +73,12 @@ trait TypeStrings { brackets(clazz.getTypeParameters map tvarString: _*) } - private def tparamString[T: Manifest] : String = - brackets(manifest[T].typeArguments map (m => tvarString(List(m.erasure))): _*) + private def tparamString[T: Manifest] : String = { + // [Eugene to Paul] needs review!! + def typeArguments: List[rm.Type] = manifest[T].tpe.typeArguments + def typeVariables: List[java.lang.Class[_]] = typeArguments map (targ => rm.typeToClass(targ)) + brackets(typeArguments map (jc => tvarString(List(jc))): _*) + } /** Going for an overabundance of caution right now. Later these types * can be a lot more precise, but right now the manifests have a habit of diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala index 2ba8c8eb6b..ab8fe23909 100644 --- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala @@ -35,17 +35,22 @@ abstract class AbstractReporter extends Reporter { else _severity if (severity == INFO) { - if (isVerbose || force) + if (isVerbose || force) { + severity.count += 1 display(pos, msg, severity) + } } else { val hidden = testAndLog(pos, severity) if (severity == WARNING && noWarnings) () else { - if (!hidden || isPromptSet) + if (!hidden || isPromptSet) { + severity.count += 1 display(pos, msg, severity) - else if (settings.debug.value) + } else if (settings.debug.value) { + severity.count += 1 display(pos, "[ suppressed ] " + msg, severity) + } if (isPromptSet) displayPrompt diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala index f5335fb0f5..956c43c35a 100644 --- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala @@ -75,7 +75,6 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr } def display(pos: Position, msg: String, severity: Severity) { - severity.count += 1 if (severity != ERROR || severity.count <= ERROR_LIMIT) print(pos, msg, severity) } diff --git a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala index ff0f94d897..8a918a829c 100644 --- a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala +++ b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala @@ -28,7 +28,7 @@ object Executor { Console.setOut(newOut) Console.setErr(newOut) try { - singletonInstance(name, classLoader) + singletonInstance(classLoader, name) } catch { case ex: Throwable => unwrapThrowable(ex) match { diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index e7959f36b2..ea12300785 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -28,7 +28,7 @@ class MutableSettings(val errorFn: String => Unit) settings } - protected def copyInto(settings: MutableSettings) { + def copyInto(settings: MutableSettings) { allSettings foreach { thisSetting => val otherSetting = settings.allSettings find { _.name == thisSetting.name } otherSetting foreach { otherSetting => diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 14b3bcc8ce..e9a7e3dab4 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -80,6 +80,9 @@ trait ScalaSettings extends AbsScalaSettings val XlogImplicits = BooleanSetting ("-Xlog-implicits", "Show more detail on why some implicits are not applicable.") val logImplicitConv = BooleanSetting ("-Xlog-implicit-conversions", "Print a message whenever an implicit conversion is inserted.") val logReflectiveCalls = BooleanSetting("-Xlog-reflective-calls", "Print a message when a reflective method call is generated") + val logRuntimeSplices = BooleanSetting("-Xlog-runtime-splices", "Print a message when Expr.eval or Expr.value cannot be resolved statically.") + val logFreeTerms = BooleanSetting ("-Xlog-free-terms", "Print a message when reification creates a free term.") + val logFreeTypes = BooleanSetting ("-Xlog-free-types", "Print a message when reification resorts to generating a free type.") val maxClassfileName = IntSetting ("-Xmax-classfile-name", "Maximum filename length for generated classes", 255, Some((72, 255)), _ => None) val Xmigration28 = BooleanSetting ("-Xmigration", "Warn about constructs whose behavior may have changed between 2.7 and 2.8.") val nouescape = BooleanSetting ("-Xno-uescape", "Disable handling of \\u unicode escapes.") @@ -116,62 +119,62 @@ trait ScalaSettings extends AbsScalaSettings /** * -Y "Private" settings */ - val overrideObjects = BooleanSetting ("-Yoverride-objects", "Allow member objects to be overridden.") - val overrideVars = BooleanSetting ("-Yoverride-vars", "Allow vars to be overridden.") - val Yhelp = BooleanSetting ("-Y", "Print a synopsis of private options.") - val browse = PhasesSetting ("-Ybrowse", "Browse the abstract syntax tree after") - val check = PhasesSetting ("-Ycheck", "Check the tree at the end of") - val Yshow = PhasesSetting ("-Yshow", "(Requires -Xshow-class or -Xshow-object) Show after") - val Xcloselim = BooleanSetting ("-Yclosure-elim", "Perform closure elimination.") - val Ycompacttrees = BooleanSetting ("-Ycompact-trees", "Use compact tree printer when displaying trees.") - val noCompletion = BooleanSetting ("-Yno-completion", "Disable tab-completion in the REPL.") - val Xdce = BooleanSetting ("-Ydead-code", "Perform dead code elimination.") - val debug = BooleanSetting ("-Ydebug", "Increase the quantity of debugging output.") - // val doc = BooleanSetting ("-Ydoc", "Generate documentation") - val termConflict = ChoiceSetting ("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", - List("package", "object", "error"), "error") - val inline = BooleanSetting ("-Yinline", "Perform inlining when possible.") - val inlineHandlers= BooleanSetting ("-Yinline-handlers", "Perform exception handler inlining when possible.") - val Xlinearizer = ChoiceSetting ("-Ylinearizer", "which", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo") - val log = PhasesSetting ("-Ylog", "Log operations during") - val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.") - val Ynogenericsig = BooleanSetting ("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.") - val noimports = BooleanSetting ("-Yno-imports", "Compile without importing scala.*, java.lang.*, or Predef.") - val nopredef = BooleanSetting ("-Yno-predef", "Compile without importing Predef.") - val noAdaptedArgs = BooleanSetting ("-Yno-adapted-args", "Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver.") - val Yprofile = PhasesSetting ("-Yprofile", "(Requires jvm -agentpath to contain yjgpagent) Profile CPU usage of") - val YprofileMem = BooleanSetting ("-Yprofile-memory", "Profile memory, get heap snapshot after each compiler run (requires yjpagent, see above).") - val YprofileClass = StringSetting ("-Yprofile-class", "class", "Name of profiler class.", "scala.tools.util.YourkitProfiling") - val Yrecursion = IntSetting ("-Yrecursion", "Set recursion depth used when locking symbols.", 0, Some((0, Int.MaxValue)), (_: String) => None) - val selfInAnnots = BooleanSetting ("-Yself-in-annots", "Include a \"self\" identifier inside of annotations.") - val Xshowtrees = BooleanSetting ("-Yshow-trees", "(Requires -Xprint:) Print detailed ASTs.") - val Yshowsyms = BooleanSetting ("-Yshow-syms", "Print the AST symbol hierarchy after each phase.") - val Yshowsymkinds = BooleanSetting ("-Yshow-symkinds", "Print abbreviated symbol kinds next to symbol names.") - val skip = PhasesSetting ("-Yskip", "Skip") - val Ygenjavap = StringSetting ("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "") - val Ydumpclasses = StringSetting ("-Ydump-classes", "dir", "Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders).", "") - val Ynosqueeze = BooleanSetting ("-Yno-squeeze", "Disable creation of compact code in matching.") - val Ystatistics = BooleanSetting ("-Ystatistics", "Print compiler statistics.") andThen (util.Statistics.enabled = _) - val stopAfter = PhasesSetting ("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat - val stopBefore = PhasesSetting ("-Ystop-before", "Stop before") - val refinementMethodDispatch = - ChoiceSetting ("-Ystruct-dispatch", "policy", "structural method dispatch policy", - List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache") - val globalClass = StringSetting ("-Yglobal-class", "class", "subclass of scala.tools.nsc.Global to use for compiler", "") - val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.") - val YrichExes = BooleanSetting ("-Yrich-exceptions", - "Fancier exceptions. Set source search path with -D" + - sys.SystemProperties.traceSourcePath.key) - val Ybuilderdebug = ChoiceSetting("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none") - val Yreifycopypaste = - BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") - val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") - val Ynotnull = BooleanSetting ("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.") - val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.") - val etaExpandKeepsStar = BooleanSetting("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.") - val noSelfCheck = BooleanSetting ("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.") - val YvirtPatmat = BooleanSetting ("-Yvirtpatmat", "Translate pattern matches into flatMap/orElse calls. See scala.MatchingStrategy.") - val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes") + val overrideObjects = BooleanSetting ("-Yoverride-objects", "Allow member objects to be overridden.") + val overrideVars = BooleanSetting ("-Yoverride-vars", "Allow vars to be overridden.") + val Yhelp = BooleanSetting ("-Y", "Print a synopsis of private options.") + val browse = PhasesSetting ("-Ybrowse", "Browse the abstract syntax tree after") + val check = PhasesSetting ("-Ycheck", "Check the tree at the end of") + val Yshow = PhasesSetting ("-Yshow", "(Requires -Xshow-class or -Xshow-object) Show after") + val Xcloselim = BooleanSetting ("-Yclosure-elim", "Perform closure elimination.") + val Ycompacttrees = BooleanSetting ("-Ycompact-trees", "Use compact tree printer when displaying trees.") + val noCompletion = BooleanSetting ("-Yno-completion", "Disable tab-completion in the REPL.") + val Xdce = BooleanSetting ("-Ydead-code", "Perform dead code elimination.") + val debug = BooleanSetting ("-Ydebug", "Increase the quantity of debugging output.") + //val doc = BooleanSetting ("-Ydoc", "Generate documentation") + val termConflict = ChoiceSetting ("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error") + val inline = BooleanSetting ("-Yinline", "Perform inlining when possible.") + val inlineHandlers = BooleanSetting ("-Yinline-handlers", "Perform exception handler inlining when possible.") + val Xlinearizer = ChoiceSetting ("-Ylinearizer", "which", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo") + val log = PhasesSetting ("-Ylog", "Log operations during") + val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.") + val Ynogenericsig = BooleanSetting ("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.") + val noimports = BooleanSetting ("-Yno-imports", "Compile without importing scala.*, java.lang.*, or Predef.") + val nopredef = BooleanSetting ("-Yno-predef", "Compile without importing Predef.") + val noAdaptedArgs = BooleanSetting ("-Yno-adapted-args", "Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver.") + val Yprofile = PhasesSetting ("-Yprofile", "(Requires jvm -agentpath to contain yjgpagent) Profile CPU usage of") + val YprofileMem = BooleanSetting ("-Yprofile-memory", "Profile memory, get heap snapshot after each compiler run (requires yjpagent, see above).") + val YprofileClass = StringSetting ("-Yprofile-class", "class", "Name of profiler class.", "scala.tools.util.YourkitProfiling") + val Yrecursion = IntSetting ("-Yrecursion", "Set recursion depth used when locking symbols.", 0, Some((0, Int.MaxValue)), (_: String) => None) + val selfInAnnots = BooleanSetting ("-Yself-in-annots", "Include a \"self\" identifier inside of annotations.") + val Xshowtrees = BooleanSetting ("-Yshow-trees", "(Requires -Xprint:) Print detailed ASTs in formatted form.") + val XshowtreesCompact + = BooleanSetting ("-Yshow-trees-compact", "(Requires -Xprint:) Print detailed ASTs in compact form.") + val XshowtreesStringified + = BooleanSetting ("-Yshow-trees-stringified", "(Requires -Xprint:) Print stringifications along with detailed ASTs.") + val Yshowsyms = BooleanSetting ("-Yshow-syms", "Print the AST symbol hierarchy after each phase.") + val Yshowsymkinds = BooleanSetting ("-Yshow-symkinds", "Print abbreviated symbol kinds next to symbol names.") + val skip = PhasesSetting ("-Yskip", "Skip") + val Ygenjavap = StringSetting ("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "") + val Ydumpclasses = StringSetting ("-Ydump-classes", "dir", "Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders).", "") + val Ynosqueeze = BooleanSetting ("-Yno-squeeze", "Disable creation of compact code in matching.") + val Ystatistics = BooleanSetting ("-Ystatistics", "Print compiler statistics.") andThen (util.Statistics.enabled = _) + val stopAfter = PhasesSetting ("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat + val stopBefore = PhasesSetting ("-Ystop-before", "Stop before") + val refinementMethodDispatch + = ChoiceSetting ("-Ystruct-dispatch", "policy", "structural method dispatch policy", List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache") + val globalClass = StringSetting ("-Yglobal-class", "class", "subclass of scala.tools.nsc.Global to use for compiler", "") + val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.") + val YrichExes = BooleanSetting ("-Yrich-exceptions", "Fancier exceptions. Set source search path with -D" + sys.SystemProperties.traceSourcePath.key) + val Ybuilderdebug = ChoiceSetting ("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none") + val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") + val Ymacrocopypaste = BooleanSetting ("-Ymacro-copypaste", "Dump macro expansions in copypasteable representation.") + val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") + val Ynotnull = BooleanSetting ("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.") + val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.") + val etaExpandKeepsStar = BooleanSetting ("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.") + val noSelfCheck = BooleanSetting ("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.") + val YvirtPatmat = BooleanSetting ("-Yvirtpatmat", "Translate pattern matches into flatMap/orElse calls. See scala.MatchingStrategy.") + val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes") val exposeEmptyPackage = BooleanSetting("-Yexpose-empty-package", "Internal only: expose the empty package.").internalOnly() val YnoProductN = BooleanSetting ("-Yno-productN", "Do not add ProductN to case classes") @@ -180,26 +183,30 @@ trait ScalaSettings extends AbsScalaSettings /** Area-specific debug output. */ - val Ybuildmanagerdebug = BooleanSetting("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.") - val Ycompletion = BooleanSetting("-Ycompletion-debug", "Trace all tab completion activity.") - val Ydocdebug = BooleanSetting("-Ydoc-debug", "Trace all scaladoc activity.") - val Yidedebug = BooleanSetting("-Yide-debug", "Generate, validate and output trees using the interactive compiler.") - val Yinferdebug = BooleanSetting("-Yinfer-debug", "Trace type inference and implicit search.") - val Ymacrodebug = BooleanSetting("-Ymacro-debug", "Trace macro-related activities: generation of synthetics, expansion, exceptions.") - val Ypmatdebug = BooleanSetting("-Ypmat-debug", "Trace all pattern matcher activity.") - val Yposdebug = BooleanSetting("-Ypos-debug", "Trace position validation.") - val Yreifydebug = BooleanSetting("-Yreify-debug", "Trace reification.") - val Yrepldebug = BooleanSetting("-Yrepl-debug", "Trace all repl activity.") andThen (interpreter.replProps.debug setValue _) - val Ytyperdebug = BooleanSetting("-Ytyper-debug", "Trace all type assignments.") + val Ybuildmanagerdebug = BooleanSetting("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.") + val Ycompletion = BooleanSetting("-Ycompletion-debug", "Trace all tab completion activity.") + val Ydocdebug = BooleanSetting("-Ydoc-debug", "Trace all scaladoc activity.") + val Yidedebug = BooleanSetting("-Yide-debug", "Generate, validate and output trees using the interactive compiler.") + val Yinferdebug = BooleanSetting("-Yinfer-debug", "Trace type inference and implicit search.") + val Yissuedebug = BooleanSetting("-Yissue-debug", "Print stack traces when a context issues an error.") + val Ymacrodebug = BooleanSetting("-Ymacro-debug", "Trace macro-related activities: compilation, generation of synthetics, classloading, expansion, exceptions.") + val Ypmatdebug = BooleanSetting("-Ypmat-debug", "Trace all pattern matcher activity.") + val Yposdebug = BooleanSetting("-Ypos-debug", "Trace position validation.") + val Yreifydebug = BooleanSetting("-Yreify-debug", "Trace reification.") + val Yrepldebug = BooleanSetting("-Yrepl-debug", "Trace all repl activity.") andThen (interpreter.replProps.debug setValue _) + val Ytyperdebug = BooleanSetting("-Ytyper-debug", "Trace all type assignments.") /** Groups of Settings. */ - val future = BooleanSetting ("-Xfuture", "Turn on future language features.") enabling futureSettings - val optimise = BooleanSetting ("-optimise", "Generates faster bytecode by applying optimisations to the program") withAbbreviation "-optimize" enabling optimiseSettings - val Xexperimental = BooleanSetting ("-Xexperimental", "Enable experimental extensions.") enabling experimentalSettings + val future = BooleanSetting("-Xfuture", "Turn on future language features.") enabling futureSettings + val optimise = BooleanSetting("-optimise", "Generates faster bytecode by applying optimisations to the program") withAbbreviation "-optimize" enabling optimiseSettings + val Xexperimental = BooleanSetting("-Xexperimental", "Enable experimental extensions.") enabling experimentalSettings // Feature extensions - val Xmacros = BooleanSetting ("-Xmacros", "Enable macros.") + val Xmacros = BooleanSetting("-Xmacros", "Enable macros.") + val XmacroSettings = MultiStringSetting("-Xmacro-settings", "option", "Custom settings for macros.") + val XmacroPrimaryClasspath = PathSetting("-Xmacro-primary-classpath", "Classpath to load macros implementations from, defaults to compilation classpath (aka \"library classpath\".", "") + val XmacroFallbackClasspath = PathSetting("-Xmacro-fallback-classpath", "Classpath to load macros implementations from if they cannot be loaded from library classpath.", "") /** * IDE-specific settings diff --git a/src/compiler/scala/tools/nsc/symtab/Positions.scala b/src/compiler/scala/tools/nsc/symtab/Positions.scala deleted file mode 100644 index 94b619de90..0000000000 --- a/src/compiler/scala/tools/nsc/symtab/Positions.scala +++ /dev/null @@ -1,30 +0,0 @@ -package scala.tools.nsc -package symtab - -import scala.tools.nsc.util.{ SourceFile, Position, OffsetPosition, NoPosition } - -trait Positions extends scala.reflect.internal.Positions { -self: scala.tools.nsc.symtab.SymbolTable => - - def rangePos(source: SourceFile, start: Int, point: Int, end: Int) = - new OffsetPosition(source, point) - - def validatePositions(tree: Tree) {} - - type Position = scala.tools.nsc.util.Position - val NoPosition = scala.tools.nsc.util.NoPosition - - type TreeAnnotation = scala.tools.nsc.util.TreeAnnotation - def NoTreeAnnotation: TreeAnnotation = NoPosition - def positionToAnnotation(pos: Position): TreeAnnotation = pos - def annotationToPosition(annot: TreeAnnotation): Position = annot.pos - 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.tools.nsc.util.Position] || !annot.isInstanceOf[scala.tools.nsc.util.Position]) && tree.isInstanceOf[Block]) - // println("Updating block from "+ tree.annotation +" to "+ annot) - } - def focusPos(pos: Position): Position = pos.focus - def isRangePos(pos: Position): Boolean = pos.isRange - def showPos(pos: Position): String = pos.show - -} diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 758f870d6b..edbe6df472 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -425,7 +425,7 @@ abstract class Pickler extends SubComponent { private def putConstant(c: Constant) { if (putEntry(c)) { if (c.tag == StringTag) putEntry(newTermName(c.stringValue)) - else if (c.tag == ClassTag) putType(c.typeValue) + else if (c.tag == ClazzTag) putType(c.typeValue) else if (c.tag == EnumTag) putSymbol(c.symbolValue) } } @@ -606,7 +606,7 @@ abstract class Pickler extends SubComponent { else if (c.tag == FloatTag) writeLong(floatToIntBits(c.floatValue)) else if (c.tag == DoubleTag) writeLong(doubleToLongBits(c.doubleValue)) else if (c.tag == StringTag) writeRef(newTermName(c.stringValue)) - else if (c.tag == ClassTag) writeRef(c.typeValue) + else if (c.tag == ClazzTag) writeRef(c.typeValue) else if (c.tag == EnumTag) writeRef(c.symbolValue) LITERAL + c.tag // also treats UnitTag, NullTag; no value required case AnnotatedType(annotations, tp, selfsym) => @@ -1059,7 +1059,7 @@ abstract class Pickler extends SubComponent { else if (c.tag == FloatTag) print("Float "+c.floatValue) else if (c.tag == DoubleTag) print("Double "+c.doubleValue) else if (c.tag == StringTag) { print("String "); printRef(newTermName(c.stringValue)) } - else if (c.tag == ClassTag) { print("Class "); printRef(c.typeValue) } + else if (c.tag == ClazzTag) { print("Class "); printRef(c.typeValue) } else if (c.tag == EnumTag) { print("Enum "); printRef(c.symbolValue) } case AnnotatedType(annots, tp, selfsym) => if (settings.selfInAnnots.value) { diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 97e844f6d8..5a11926048 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -179,7 +179,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => /** If `tp` refers to a non-interface trait, return a * reference to its implementation class. Otherwise return `tp`. */ - def mixinToImplClass(tp: Type): Type = erasure(implSym) { + def mixinToImplClass(tp: Type): Type = AddInterfaces.this.erasure(implSym) { tp match { //@MATN: no normalize needed (comes after erasure) case TypeRef(pre, sym, _) if sym.needsImplClass => typeRef(pre, implClass(sym), Nil) diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index e6f5dc5b5f..eea87c8ba6 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -542,7 +542,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { if (forMSIL) savingStatics( transformTemplate(tree) ) else transformTemplate(tree) - case Literal(c) if (c.tag == ClassTag) && !forMSIL=> + case Literal(c) if (c.tag == ClazzTag) && !forMSIL=> val tpe = c.typeValue typedWithPos(tree.pos) { if (isPrimitiveValueClass(tpe.typeSymbol)) { diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index ecfc2b6084..e2ce3b62b4 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -734,7 +734,7 @@ abstract class Erasure extends AddInterfaces /** A replacement for the standard typer's `typed1` method. */ - override protected def typed1(tree: Tree, mode: Int, pt: Type): Tree = { + override def typed1(tree: Tree, mode: Int, pt: Type): Tree = { val tree1 = try { tree match { case InjectDerivedValue(arg) => @@ -1090,7 +1090,7 @@ abstract class Erasure extends AddInterfaces case Match(selector, cases) => Match(Typed(selector, TypeTree(selector.tpe)), cases) - case Literal(ct) if ct.tag == ClassTag + case Literal(ct) if ct.tag == ClazzTag && ct.typeValue.typeSymbol != definitions.UnitClass => val erased = ct.typeValue match { case TypeRef(pre, clazz, args) if clazz.isDerivedValueClass => scalaErasure.eraseNormalClassRef(pre, clazz) diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index f6dc8fbfb0..6bddfe8d57 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -19,19 +19,6 @@ abstract class LambdaLift extends InfoTransform { /** the following two members override abstract members in Transform */ val phaseName: String = "lambdalift" - /** Converts types of captured variables to *Ref types. - */ - def boxIfCaptured(sym: Symbol, tpe: Type, erasedTypes: Boolean) = - if (sym.isCapturedVariable) { - val symClass = tpe.typeSymbol - def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) = - if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe - else if (erasedTypes) objectRefClass.tpe - else appliedType(objectRefClass, tpe) - if (sym.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass) - else refType(refClass, ObjectRefClass) - } else tpe - private val lifted = new TypeMap { def apply(tp: Type): Type = tp match { case TypeRef(NoPrefix, sym, Nil) if sym.isClass && !sym.isPackageClass => @@ -46,7 +33,8 @@ abstract class LambdaLift extends InfoTransform { } def transformInfo(sym: Symbol, tp: Type): Type = - boxIfCaptured(sym, lifted(tp), erasedTypes = true) + if (sym.isCapturedVariable) capturedVariableType(sym, tpe = lifted(tp), erasedTypes = true) + else lifted(tp) protected def newTransformer(unit: CompilationUnit): Transformer = new LambdaLifter(unit) @@ -471,6 +459,8 @@ abstract class LambdaLift extends InfoTransform { private def preTransform(tree: Tree) = super.transform(tree) setType lifted(tree.tpe) override def transform(tree: Tree): Tree = tree match { + case Select(ReferenceToBoxed(idt), elem) if elem == nme.elem => + postTransform(preTransform(idt), isBoxedRef = false) case ReferenceToBoxed(idt) => postTransform(preTransform(idt), isBoxedRef = true) case _ => diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 6d4dab57a3..0e4975c04c 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -1085,7 +1085,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { // add forwarders assert(sym.alias != NoSymbol, sym) // debuglog("New forwarder: " + sym.defString + " => " + sym.alias.defString) - addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident))) + if (!sym.isTermMacro) addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident))) } } } diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index f90d3d45fe..11f06a0541 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -358,18 +358,18 @@ abstract class UnCurry extends InfoTransform def sequenceToArray(tree: Tree) = { val toArraySym = tree.tpe member nme.toArray assert(toArraySym != NoSymbol) - def getManifest(tp: Type): Tree = { - val manifestOpt = localTyper.findManifest(tp, false) + def getClassTag(tp: Type): Tree = { + val tag = localTyper.resolveClassTag(tree, tp) // Don't want bottom types getting any further than this (SI-4024) - if (tp.typeSymbol.isBottomClass) getManifest(AnyClass.tpe) - else if (!manifestOpt.tree.isEmpty) manifestOpt.tree - else if (tp.bounds.hi ne tp) getManifest(tp.bounds.hi) - else localTyper.getManifestTree(tree, tp, false) + if (tp.typeSymbol.isBottomClass) getClassTag(AnyClass.tpe) + else if (!tag.isEmpty) tag + else if (tp.bounds.hi ne tp) getClassTag(tp.bounds.hi) + else localTyper.TyperErrorGen.MissingClassTagError(tree, tp) } afterUncurry { localTyper.typedPos(pos) { Apply(gen.mkAttributedSelect(tree, toArraySym), - List(getManifest(tree.tpe.baseType(TraversableClass).typeArgs.head))) + List(getClassTag(tree.tpe.baseType(TraversableClass).typeArgs.head))) } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index ff0bdf7580..b400743469 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -277,11 +277,6 @@ trait ContextErrors { setError(tree) } - def MultiDimensionalArrayError(tree: Tree) = { - issueNormalTypeError(tree, "cannot create a generic multi-dimensional array of more than "+ definitions.MaxArrayDims+" dimensions") - setError(tree) - } - //typedSuper def MixinMissingParentClassNameError(tree: Tree, mix: Name, clazz: Symbol) = issueNormalTypeError(tree, mix+" does not name a parent class of "+clazz) @@ -344,6 +339,11 @@ trait ContextErrors { setError(tree) } + def MacroEtaError(tree: Tree) = { + issueNormalTypeError(tree, "macros cannot be eta-expanded") + setError(tree) + } + //typedReturn def ReturnOutsideOfDefError(tree: Tree) = { issueNormalTypeError(tree, "return outside method definition") @@ -453,6 +453,9 @@ trait ContextErrors { // doTypeApply //tryNamesDefaults + def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, fun: Tree) = + NormalTypeError(tree, "macros application do not support named and/or default arguments") + def WrongNumberOfArgsError(tree: Tree, fun: Tree) = NormalTypeError(tree, "wrong number of arguments for "+ treeSymTypeMsg(fun)) @@ -581,9 +584,9 @@ trait ContextErrors { def AbstractExistentiallyOverParamerizedTpeError(tree: Tree, tp: Type) = issueNormalTypeError(tree, "can't existentially abstract over parameterized type " + tp) - //manifestTreee - def MissingManifestError(tree: Tree, full: Boolean, tp: Type) = { - issueNormalTypeError(tree, "cannot find "+(if (full) "" else "class ")+"manifest for element type "+tp) + // classTagTree + def MissingClassTagError(tree: Tree, tp: Type) = { + issueNormalTypeError(tree, "cannot find class tag for element type "+tp) setError(tree) } @@ -622,7 +625,6 @@ trait ContextErrors { def DefDefinedTwiceError(sym0: Symbol, sym1: Symbol) = { val isBug = sym0.isAbstractType && sym1.isAbstractType && (sym0.name startsWith "_$") issueSymbolTypeError(sym0, sym1+" is defined twice in " + context0.unit - + ( if (sym0.isMacro && sym1.isMacro) "\n(note that macros cannot be overloaded)" else "" ) + ( if (isBug) "\n(this error is likely due to a bug in the scala compiler involving wildcards in package objects)" else "" ) ) } @@ -848,6 +850,19 @@ trait ContextErrors { def TypeSigError(tree: Tree, ex: TypeError) = { ex match { + case CyclicReference(_, _) if tree.symbol.isTermMacro => + // say, we have a macro def `foo` and its macro impl `impl` + // if impl: 1) omits return type, 2) has anything implicit in its body, 3) sees foo + // + // then implicit search will trigger an error + // (note that this is not a compilation error, it's an artifact of implicit search algorithm) + // normally, such "errors" are discarded by `isCyclicOrErroneous` in Implicits.scala + // but in our case this won't work, because isCyclicOrErroneous catches CyclicReference exceptions + // while our error will manifest itself as a "recursive method needs a return type" + // + // hence we (together with reportTypeError in TypeDiagnostics) make sure that this CyclicReference + // evades all the handlers on its way and successfully reaches `isCyclicOrErroneous` in Implicits + throw ex case CyclicReference(sym, info: TypeCompleter) => issueNormalTypeError(tree, typer.cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage()) case _ => diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 9b1f395ad0..fe1c90fe67 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -105,8 +105,8 @@ trait Contexts { self: Analyzer => // not inherited to child contexts var depth: Int = 0 var imports: List[ImportInfo] = List() // currently visible imports - var openImplicits: List[(Type,Symbol)] = List() // types for which implicit arguments - // are currently searched + var openImplicits: List[(Type,Tree)] = List() // types for which implicit arguments + // are currently searched // for a named application block (Tree) the corresponding NamedApplyInfo var namedApplyBlockInfo: Option[(Tree, NamedApplyInfo)] = None var prefix: Type = NoPrefix @@ -119,6 +119,7 @@ trait Contexts { self: Analyzer => var diagnostic: List[String] = Nil // these messages are printed when issuing an error var implicitsEnabled = false + var macrosEnabled = true var checking = false var retyping = false @@ -181,6 +182,13 @@ trait Contexts { self: Analyzer => def logError(err: AbsTypeError) = buffer += err + def withImplicitsEnabled[T](op: => T): T = { + val saved = implicitsEnabled + implicitsEnabled = true + try op + finally implicitsEnabled = saved + } + def withImplicitsDisabled[T](op: => T): T = { val saved = implicitsEnabled implicitsEnabled = false @@ -188,6 +196,20 @@ trait Contexts { self: Analyzer => finally implicitsEnabled = saved } + def withMacrosEnabled[T](op: => T): T = { + val saved = macrosEnabled + macrosEnabled = true + try op + finally macrosEnabled = saved + } + + def withMacrosDisabled[T](op: => T): T = { + val saved = macrosEnabled + macrosEnabled = false + try op + finally macrosEnabled = saved + } + def make(unit: CompilationUnit, tree: Tree, owner: Symbol, scope: Scope, imports: List[ImportInfo]): Context = { val c = new Context @@ -223,6 +245,7 @@ trait Contexts { self: Analyzer => c.diagnostic = this.diagnostic c.typingIndentLevel = typingIndentLevel c.implicitsEnabled = this.implicitsEnabled + c.macrosEnabled = this.macrosEnabled c.checking = this.checking c.retyping = this.retyping c.openImplicits = this.openImplicits @@ -237,6 +260,7 @@ trait Contexts { self: Analyzer => val c = make(unit, EmptyTree, owner, scope, imports) c.setReportErrors() c.implicitsEnabled = true + c.macrosEnabled = true c } @@ -312,6 +336,7 @@ trait Contexts { self: Analyzer => def issue(err: AbsTypeError) { debugwarn("issue error: " + err.errMsg) + if (settings.Yissuedebug.value) (new Exception).printStackTrace() if (reportErrors) unitError(err.errPos, addDiagString(err.errMsg)) else if (bufferErrors) { buffer += err } else throw new TypeError(err.errPos, err.errMsg) @@ -319,6 +344,7 @@ trait Contexts { self: Analyzer => def issueAmbiguousError(pre: Type, sym1: Symbol, sym2: Symbol, err: AbsTypeError) { debugwarn("issue ambiguous error: " + err.errMsg) + if (settings.Yissuedebug.value) (new Exception).printStackTrace() if (ambiguousErrors) { if (!pre.isErroneous && !sym1.isErroneous && !sym2.isErroneous) unitError(err.errPos, err.errMsg) @@ -328,6 +354,7 @@ trait Contexts { self: Analyzer => def issueAmbiguousError(err: AbsTypeError) { debugwarn("issue ambiguous error: " + err.errMsg) + if (settings.Yissuedebug.value) (new Exception).printStackTrace() if (ambiguousErrors) unitError(err.errPos, addDiagString(err.errMsg)) else if (bufferErrors) { buffer += err } diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 75440a1136..8aa257983a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -32,7 +32,10 @@ trait Implicits { import global.typer.{ printTyping, deindentTyping, indentTyping, printInference } def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context): SearchResult = - inferImplicit(tree, pt, reportAmbiguous, isView, context, true) + inferImplicit(tree, pt, reportAmbiguous, isView, context, true, NoPosition) + + def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean): SearchResult = + inferImplicit(tree, pt, reportAmbiguous, isView, context, saveAmbiguousDivergent, NoPosition) /** Search for an implicit value. See the comment on `result` at the end of class `ImplicitSearch` * for more info how the search is conducted. @@ -48,9 +51,12 @@ trait Implicits { * @param saveAmbiguousDivergent False if any divergent/ambiguous errors should be ignored after * implicits search, * true if they should be reported (used in further typechecking). + * @param pos Position that is should be used for tracing and error reporting + * (useful when we infer synthetic stuff and pass EmptyTree in the `tree` argument) + * If it's set NoPosition, then position-based services will use `tree.pos` * @return A search result */ - def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean): SearchResult = { + def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean, pos: Position): SearchResult = { printInference("[infer %s] %s with pt=%s in %s".format( if (isView) "view" else "implicit", tree, pt, context.owner.enclClass) @@ -71,9 +77,11 @@ trait Implicits { if (printInfers && !tree.isEmpty && !context.undetparams.isEmpty) printTyping("typing implicit: %s %s".format(tree, context.undetparamsString)) val implicitSearchContext = context.makeImplicit(reportAmbiguous) - val result = new ImplicitSearch(tree, pt, isView, implicitSearchContext).bestImplicit - if (saveAmbiguousDivergent && implicitSearchContext.hasErrors) + val result = new ImplicitSearch(tree, pt, isView, implicitSearchContext, pos).bestImplicit + if (saveAmbiguousDivergent && implicitSearchContext.hasErrors) { context.updateBuffer(implicitSearchContext.errBuffer.filter(err => err.kind == ErrorKinds.Ambiguous || err.kind == ErrorKinds.Divergent)) + debugwarn("update buffer: " + implicitSearchContext.errBuffer) + } printInference("[infer implicit] inferred " + result) context.undetparams = context.undetparams filterNot result.subst.from.contains @@ -100,8 +108,6 @@ trait Implicits { improvesCache.clear() } - private val ManifestSymbols = Set(PartialManifestClass, FullManifestClass, OptManifestClass) - /* Map a polytype to one in which all type parameters and argument-dependent types are replaced by wildcards. * Consider `implicit def b(implicit x: A): x.T = error("")`. We need to approximate DebruijnIndex types * when checking whether `b` is a valid implicit, as we haven't even searched a value for the implicit arg `x`, @@ -251,8 +257,11 @@ trait Implicits { * @param pt The original expected type of the implicit. * @param isView We are looking for a view * @param context0 The context used for the implicit search + * @param pos0 Position that is preferable for use in tracing and error reporting + * (useful when we infer synthetic stuff and pass EmptyTree in the `tree` argument) + * If it's set to NoPosition, then position-based services will use `tree.pos` */ - class ImplicitSearch(tree: Tree, pt: Type, isView: Boolean, context0: Context) + class ImplicitSearch(tree: Tree, pt: Type, isView: Boolean, context0: Context, pos0: Position = NoPosition) extends Typer(context0) with ImplicitsContextErrors { printTyping( ptBlock("new ImplicitSearch", @@ -264,6 +273,13 @@ trait Implicits { ) ) // assert(tree.isEmpty || tree.pos.isDefined, tree) + def pos = if (pos0 != NoPosition) pos0 else tree.pos + + def failure(what: Any, reason: String, pos: Position = this.pos): SearchResult = { + if (settings.XlogImplicits.value) + reporter.echo(pos, what+" is not a valid implicit value for "+pt+" because:\n"+reason) + SearchFailure + } import infer._ /** Is implicit info `info1` better than implicit info `info2`? @@ -351,13 +367,13 @@ trait Implicits { * @pre `info.tpe` does not contain an error */ private def typedImplicit(info: ImplicitInfo, ptChecked: Boolean): SearchResult = { - (context.openImplicits find { case (tp, sym) => sym == tree.symbol && dominates(pt, tp)}) match { + (context.openImplicits find { case (tp, tree1) => tree1.symbol == tree.symbol && dominates(pt, tp)}) match { case Some(pending) => // println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams) //@MDEBUG throw DivergentImplicit case None => try { - context.openImplicits = (pt, tree.symbol) :: context.openImplicits + context.openImplicits = (pt, tree) :: context.openImplicits // println(" "*context.openImplicits.length+"typed implicit "+info+" for "+pt) //@MDEBUG typedImplicit0(info, ptChecked) } catch { @@ -515,7 +531,7 @@ trait Implicits { private def typedImplicit1(info: ImplicitInfo): SearchResult = { incCounter(matchingImplicits) - val itree = atPos(tree.pos.focus) { + val itree = atPos(pos.focus) { if (info.pre == NoPrefix) Ident(info.name) else Select(gen.mkAttributedQualifier(info.pre), info.name) } @@ -523,11 +539,7 @@ trait Implicits { typeDebug.ptTree(itree), wildPt, info.name, info.tpe) ) - def fail(reason: String): SearchResult = { - if (settings.XlogImplicits.value) - inform(itree+" is not a valid implicit value for "+pt+" because:\n"+reason) - SearchFailure - } + def fail(reason: String): SearchResult = failure(itree, reason) try { val itree1 = if (isView) { @@ -707,6 +719,7 @@ trait Implicits { info.isCyclicOrErroneous || isView && isPredefMemberNamed(info.sym, nme.conforms) || isShadowed(info.name) + || (!context.macrosEnabled && info.sym.isTermMacro) ) /** True if a given ImplicitInfo (already known isValid) is eligible. @@ -825,7 +838,7 @@ trait Implicits { throw DivergentImplicit if (invalidImplicits.nonEmpty) - setAddendum(tree.pos, () => + setAddendum(pos, () => "\n Note: implicit "+invalidImplicits.head+" is not applicable here"+ " because it comes after the application point and it lacks an explicit result type") } @@ -1085,111 +1098,58 @@ trait Implicits { implicitInfoss1 } - /** Creates a tree that calls the relevant factory method in object - * reflect.Manifest for type 'tp'. An EmptyTree is returned if - * no manifest is found. todo: make this instantiate take type params as well? - */ - private def manifestOfType(tp: Type, full: Boolean): SearchResult = { - - /** Creates a tree that calls the factory method called constructor in object reflect.Manifest */ - def manifestFactoryCall(constructor: String, tparg: Type, args: Tree*): Tree = - if (args contains EmptyTree) EmptyTree - else typedPos(tree.pos.focus) { - val mani = gen.mkManifestFactoryCall(full, constructor, tparg, args.toList) - if (settings.debug.value) println("generated manifest: "+mani) // DEBUG - mani - } + // these should be lazy, otherwise we wouldn't be able to compile scala-library with starr + private val TagSymbols = Set(ClassTagClass, TypeTagClass, GroundTypeTagClass) + private val TagMaterializers = Map( + ClassTagClass -> MacroInternal_materializeClassTag, + TypeTagClass -> MacroInternal_materializeTypeTag, + GroundTypeTagClass -> MacroInternal_materializeGroundTypeTag + ) - /** Creates a tree representing one of the singleton manifests.*/ - def findSingletonManifest(name: String) = typedPos(tree.pos.focus) { - Select(gen.mkAttributedRef(FullManifestModule), name) - } + def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = { + def success(arg: Tree) = + try { + val tree1 = typed(atPos(pos.focus)(arg)) + def isErroneous = tree exists (_.isErroneous) + if (context.hasErrors) failure(tp, "failed to typecheck the materialized typetag: %n%s".format(context.errBuffer.head.errMsg), context.errBuffer.head.errPos) + else new SearchResult(tree1, EmptyTreeTypeSubstituter) + } catch { + case ex: TypeError => + failure(arg, "failed to typecheck the materialized typetag: %n%s".format(ex.msg), ex.pos) + } - /** Re-wraps a type in a manifest before calling inferImplicit on the result */ - def findManifest(tp: Type, manifestClass: Symbol = if (full) FullManifestClass else PartialManifestClass) = - inferImplicit(tree, appliedType(manifestClass, tp), true, false, context).tree - - def findSubManifest(tp: Type) = findManifest(tp, if (full) FullManifestClass else OptManifestClass) - def mot(tp0: Type, from: List[Symbol], to: List[Type]): SearchResult = { - implicit def wrapResult(tree: Tree): SearchResult = - if (tree == EmptyTree) SearchFailure else new SearchResult(tree, if (from.isEmpty) EmptyTreeTypeSubstituter else new TreeTypeSubstituter(from, to)) - - val tp1 = tp0.normalize - tp1 match { - case ThisType(_) | SingleType(_, _) => - // can't generate a reference to a value that's abstracted over by an existential - if (containsExistential(tp1)) EmptyTree - else manifestFactoryCall("singleType", tp, gen.mkAttributedQualifier(tp1)) - case ConstantType(value) => - manifestOfType(tp1.deconst, full) - case TypeRef(pre, sym, args) => - if (isPrimitiveValueClass(sym) || isPhantomClass(sym)) { - findSingletonManifest(sym.name.toString) - } else if (sym == ObjectClass || sym == AnyRefClass) { - findSingletonManifest("Object") - } else if (sym == RepeatedParamClass || sym == ByNameParamClass) { - EmptyTree - } else if (sym == ArrayClass && args.length == 1) { - manifestFactoryCall("arrayType", args.head, findManifest(args.head)) - } else if (sym.isClass) { - val classarg0 = gen.mkClassOf(tp1) - val classarg = tp match { - case _: ExistentialType => gen.mkCast(classarg0, ClassType(tp)) - case _ => classarg0 - } - val suffix = classarg :: (args map findSubManifest) - manifestFactoryCall( - "classType", tp, - (if ((pre eq NoPrefix) || pre.typeSymbol.isStaticOwner) suffix - else findSubManifest(pre) :: suffix): _*) - } else if (sym.isExistentiallyBound && full) { - manifestFactoryCall("wildcardType", tp, - findManifest(tp.bounds.lo), findManifest(tp.bounds.hi)) - } - // looking for a manifest of a type parameter that hasn't been inferred by now, - // can't do much, but let's not fail - else if (undetParams contains sym) { - // #3859: need to include the mapping from sym -> NothingClass.tpe in the SearchResult - mot(NothingClass.tpe, sym :: from, NothingClass.tpe :: to) - } else { - // a manifest should have been found by normal searchImplicit - EmptyTree - } - case RefinedType(parents, decls) => // !!! not yet: if !full || decls.isEmpty => - // refinement is not generated yet - if (hasLength(parents, 1)) findManifest(parents.head) - else if (full) manifestFactoryCall("intersectionType", tp, parents map findSubManifest: _*) - else mot(erasure.intersectionDominator(parents), from, to) - case ExistentialType(tparams, result) => - mot(tp1.skolemizeExistential, from, to) - case _ => - EmptyTree -/* !!! the following is almost right, but we have to splice nested manifest - * !!! types into this type. This requires a substantial extension of - * !!! reifiers. - val reifier = new Reifier() - val rtree = reifier.reifyTopLevel(tp1) - manifestFactoryCall("apply", tp, rtree) -*/ - } + val prefix = (tagClass, pre) match { + // ClassTags only exist for scala.reflect.mirror, so their materializer doesn't care about prefixes + case (ClassTagClass, _) => + gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror) + // [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 + case (_, ThisType(thisSym)) => + gen.mkAttributedThis(thisSym) + case _ => + // if ``pre'' is not a PDT, e.g. if someone wrote + // implicitly[scala.reflect.makro.Context#TypeTag[Int]] + // then we need to fail, because we don't know the prefix to use during type reification + return failure(tp, "tag error: unsupported prefix type %s (%s)".format(pre, pre.kind)) } - mot(tp, Nil, Nil) + // todo. migrate hardcoded materialization in Implicits to corresponding implicit macros + var materializer = atPos(pos.focus)(Apply(TypeApply(Ident(TagMaterializers(tagClass)), List(TypeTree(tp))), List(prefix))) + if (settings.XlogImplicits.value) println("materializing requested %s.%s[%s] using %s".format(pre, tagClass.name, tp, materializer)) + success(materializer) } - def wrapResult(tree: Tree): SearchResult = - if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter) - /** The manifest corresponding to type `pt`, provided `pt` is an instance of Manifest. */ - private def implicitManifestOrOfExpectedType(pt: Type): SearchResult = pt.dealias match { - case TypeRef(_, sym, args) if ManifestSymbols(sym) => - manifestOfType(args.head, sym == FullManifestClass) match { - case SearchFailure if sym == OptManifestClass => wrapResult(gen.mkAttributedRef(NoManifest)) - case result => result - } + private def implicitTagOrOfExpectedType(pt: Type): SearchResult = pt.dealias match { + case TypeRef(pre, sym, args) if TagSymbols(sym) => + tagOfType(pre, args.head, sym) case tp@TypeRef(_, sym, _) if sym.isAbstractType => - implicitManifestOrOfExpectedType(tp.bounds.lo) // #3977: use tp (==pt.dealias), not pt (if pt is a type alias, pt.bounds.lo == pt) + implicitTagOrOfExpectedType(tp.bounds.lo) // #3977: use tp (==pt.dealias), not pt (if pt is a type alias, pt.bounds.lo == pt) case _ => searchImplicit(implicitsOfExpectedType, false) // shouldn't we pass `pt` to `implicitsOfExpectedType`, or is the recursive case @@ -1199,7 +1159,9 @@ trait Implicits { /** The result of the implicit search: * First search implicits visible in current context. * If that fails, search implicits in expected type `pt`. - * If that fails, and `pt` is an instance of Manifest, try to construct a manifest. + * // [Eugene] the following two lines should be deleted after we migrate delegate manifest 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 all fails return SearchFailure */ def bestImplicit: SearchResult = { @@ -1219,7 +1181,7 @@ trait Implicits { val failstart = startTimer(oftypeFailNanos) val succstart = startTimer(oftypeSucceedNanos) - result = implicitManifestOrOfExpectedType(pt) + result = implicitTagOrOfExpectedType(pt) if (result == SearchFailure) { context.updateBuffer(previousErrs) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index ebf8e3fc9a..98b8d7673e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -67,7 +67,7 @@ trait Infer { */ def freshVar(tparam: Symbol): TypeVar = TypeVar(tparam) - private class NoInstance(msg: String) extends Throwable(msg) with ControlThrowable { } + class NoInstance(msg: String) extends Throwable(msg) with ControlThrowable { } private class DeferredNoInstance(getmsg: () => String) extends NoInstance("") { override def getMessage(): String = getmsg() } @@ -267,6 +267,16 @@ trait Infer { setError(tree) } else { + if (context.owner.isTermMacro && (sym1 hasFlag LOCKED)) { + // we must not let CyclicReference to be thrown from sym1.info + // because that would mark sym1 erroneous, which it is not + // but if it's a true CyclicReference then macro def will report it + // see comments to TypeSigError for an explanation of this special case + // [Eugene] is there a better way? + val dummy = new TypeCompleter { val tree = EmptyTree; override def complete(sym: Symbol) {} } + throw CyclicReference(sym1, dummy) + } + if (sym1.isTerm) sym1.cookJavaRawInfo() // xform java rawtypes into existentials @@ -310,6 +320,8 @@ trait Infer { /** Like weakly compatible but don't apply any implicit conversions yet. * Used when comparing the result type of a method with its prototype. + * [Martin] I think Infer is also created by Erasure, with the default + * implementation of isCoercible */ def isConservativelyCompatible(tp: Type, pt: Type): Boolean = context.withImplicitsDisabled(isWeaklyCompatible(tp, pt)) @@ -426,6 +438,9 @@ trait Infer { tvars map (tvar => WildcardType) } + /** [Martin] Can someone comment this please? I have no idea what it's for + * and the code is not exactly readable. + */ object AdjustedTypeArgs { val Result = collection.mutable.LinkedHashMap type Result = collection.mutable.LinkedHashMap[Symbol, Option[Type]] @@ -992,6 +1007,7 @@ trait Infer { PolymorphicExpressionInstantiationError(tree, undetparams, pt) } else { new TreeTypeSubstituter(undetparams, targs).traverse(tree) + notifyUndetparamsInferred(undetparams, targs) } } @@ -1028,6 +1044,7 @@ trait Infer { if (checkBounds(fn, NoPrefix, NoSymbol, undetparams, allargs, "inferred ")) { val treeSubst = new TreeTypeSubstituter(okparams, okargs) treeSubst traverseTrees fn :: args + notifyUndetparamsInferred(okparams, okargs) leftUndet match { case Nil => Nil @@ -1116,6 +1133,7 @@ trait Infer { (inferFor(pt) orElse inferForApproxPt) map { targs => new TreeTypeSubstituter(undetparams, targs).traverse(tree) + notifyUndetparamsInferred(undetparams, targs) } getOrElse { debugwarn("failed inferConstructorInstance for "+ tree +" : "+ tree.tpe +" under "+ undetparams +" pt = "+ pt +(if(isFullyDefined(pt)) " (fully defined)" else " (not fully defined)")) // if (settings.explaintypes.value) explainTypes(resTp.instantiateTypeParams(undetparams, tvars), pt) @@ -1568,9 +1586,9 @@ trait Infer { else infer } - /** Assign tree the type of unique polymorphic alternative + /** Assign tree the type of all polymorphic alternatives * with nparams as the number of type parameters, if it exists. - * If several or none such polymorphic alternatives exist, error. + * If no such polymorphic alternative exist, error. * * @param tree ... * @param nparams ... diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index e43b1fab0b..3b270a92ad 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -3,135 +3,682 @@ package typechecker import symtab.Flags._ import scala.tools.nsc.util._ +import scala.tools.nsc.util.ClassPath._ import scala.reflect.ReflectionUtils +import scala.collection.mutable.ListBuffer +import scala.compat.Platform.EOL +import scala.reflect.makro.runtime.{Context => MacroContext} +import scala.reflect.runtime.Mirror +/** + * Code to deal with macros, namely with: + * * Compilation of macro definitions + * * Expansion of macro applications + * + * Say we have in a class C: + * + * def foo[T](xs: List[T]): T = macro fooBar + * + * Then fooBar needs to point to a static method of the following form: + * + * def fooBar[T: c.TypeTag] + * (c: scala.reflect.makro.Context) + * (xs: c.Expr[List[T]]) + * : c.mirror.Tree = { + * ... + * } + * + * Then, if foo is called in qual.foo[Int](elems), where qual: D, + * the macro application is expanded to a reflective invocation of fooBar with parameters + * + * (simpleMacroContext{ type PrefixType = D; val prefix = qual }) + * (Expr(elems)) + * (TypeTag(Int)) + */ trait Macros { self: Analyzer => import global._ import definitions._ - def macroMeth(mac: Symbol): Symbol = { - var owner = mac.owner - if (!owner.isModuleClass) owner = owner.companionModule.moduleClass - owner.info.decl(nme.macroMethodName(mac.name)) - } + val macroDebug = settings.Ymacrodebug.value + val macroCopypaste = settings.Ymacrocopypaste.value + val macroTrace = scala.tools.nsc.util.trace when macroDebug - def macroArgs(tree: Tree): (List[List[Tree]]) = tree match { - case Apply(fn, args) => - macroArgs(fn) :+ args - case TypeApply(fn, args) => - macroArgs(fn) :+ args - case Select(qual, name) => - List(List(qual)) - case _ => - List(List()) - } + val globalMacroCache = collection.mutable.Map[Any, Any]() + val perRunMacroCache = perRunCaches.newMap[Symbol, collection.mutable.Map[Any, Any]] - /** - * The definition of the method implementing a macro. Example: - * Say we have in a class C + /** A list of compatible macro implementation signatures. * - * def macro foo[T](xs: List[T]): T = expr + * In the example above: + * (c: scala.reflect.makro.Context)(xs: c.Expr[List[T]]): c.Expr[T] * - * Then the following macro method is generated for `foo`: - * - * def defmacro$foo - * (_context: scala.reflect.macro.Context) - * (_this: _context.Tree) - * (T: _context.TypeTree) - * (xs: _context.Tree): _context.Tree = { - * import _context._ // this means that all methods of Context can be used unqualified in macro's body - * expr - * } + * @param macroDef The macro definition symbol + * @param tparams The type parameters of the macro definition + * @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) = { + // 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 + val ownerTpe = macroDef.owner match { + case owner if owner.isModuleClass => new UniqueThisType(macroDef.owner) + case owner if owner.isClass => macroDef.owner.tpe + case _ => NoType + } + val hasTparams = !tparams.isEmpty + + def sigma(tpe: Type): Type = { + class SigmaTypeMap extends TypeMap { + def apply(tp: Type): Type = tp match { + case TypeRef(pre, sym, args) => + val pre1 = pre match { + case ThisType(sym) if sym == macroDef.owner => + SingleType(SingleType(SingleType(NoPrefix, paramsCtx(0)), MacroContextPrefix), ExprValue) + case SingleType(NoPrefix, sym) => + vparamss.flatten.find(_.symbol == sym) match { + case Some(macroDefParam) => + SingleType(SingleType(NoPrefix, param(macroDefParam)), ExprValue) + case _ => + pre + } + case _ => + pre + } + val args1 = args map mapOver + TypeRef(pre1, sym, args1) + case _ => + mapOver(tp) + } + } + + new SigmaTypeMap() apply tpe + } + + def makeParam(name: Name, pos: Position, tpe: Type, flags: Long = 0L) = + macroDef.newValueParameter(name, pos, flags) setInfo tpe + val ctxParam = makeParam(nme.macroContext, macroDef.pos, MacroContextClass.tpe, SYNTHETIC) + def implType(isType: Boolean, origTpe: Type): Type = + if (isRepeatedParamType(origTpe)) + appliedType( + RepeatedParamClass.typeConstructor, + List(implType(isType, sigma(origTpe.typeArgs.head)))) + else { + val tsym = getMember(MacroContextClass, if (isType) tpnme.TypeTag else tpnme.Expr) + typeRef(singleType(NoPrefix, ctxParam), tsym, List(sigma(origTpe))) + } + 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 sigParam = makeParam(sym.name, sym.pos, implType(sym.isType, sym.tpe)) + if (sym.isSynthetic) sigParam.flags |= SYNTHETIC + sigParam + }) + + val paramsCtx = List(ctxParam) + val paramsThis = List(makeParam(nme.macroThis, macroDef.pos, implType(false, ownerTpe), SYNTHETIC)) + val paramsTparams = tparams map param + val paramssParams = vparamss map (_ map 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))) + } + + import SigGenerator._ + macroTrace("generating macroImplSigs for: ")(macroDef) + macroTrace("tparams are: ")(tparams) + macroTrace("vparamss are: ")(vparamss) + macroTrace("retTpe is: ")(retTpe) + macroTrace("macroImplSigs are: ")(paramsss, implRetTpe) + } + + private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Option[Symbol]): List[List[Symbol]] = { + if (paramss.length == 0) + return paramss + + val wannabe = if (paramss.head.length == 1) paramss.head.head else NoSymbol + val contextParam = if (wannabe != NoSymbol && wannabe.tpe <:< definitions.MacroContextClass.tpe) wannabe else NoSymbol + + val lastParamList0 = paramss.lastOption getOrElse Nil + val lastParamList = lastParamList0 flatMap (param => param.tpe match { + case TypeRef(SingleType(NoPrefix, contextParam), sym, List(tparam)) => + var wannabe = sym + while (wannabe.isAliasType) wannabe = wannabe.info.typeSymbol + if (wannabe != definitions.TypeTagClass) + List(param) + else + transform(param, tparam.typeSymbol) map (_ :: Nil) getOrElse Nil + case _ => + List(param) + }) + + var result = paramss.dropRight(1) :+ lastParamList + if (lastParamList0.isEmpty ^ lastParamList.isEmpty) { + result = result dropRight 1 + } + + result + } + + /** As specified above, body of a macro definition must reference its implementation. + * This function verifies that the body indeed refers to a method, and that + * the referenced macro implementation is compatible with the given macro definition. * - * If macro has no type arguments, the third parameter list is omitted (it's not empty, but omitted altogether). + * This means that macro implementation (fooBar in example above) must: + * 1) Refer to a statically accessible, non-overloaded method. + * 2) Have the right parameter lists as outlined in the SIP / in the doc comment of this class. * - * To find out the desugared representation of your particular macro, compile it with -Ymacro-debug. + * @return typechecked rhs of the given macro definition */ - def macroMethDef(mdef: DefDef): Tree = { - def paramDef(name: Name, tpt: Tree) = ValDef(Modifiers(PARAM), name, tpt, EmptyTree) - val contextType = TypeTree(ReflectMacroContext.tpe) - val globParamSec = List(paramDef(nme.macroContext, contextType)) - def globSelect(name: Name) = Select(Ident(nme.macroContext), name) - def globTree = globSelect(tpnme.Tree) - def globTypeTree = globSelect(tpnme.TypeTree) - val thisParamSec = List(paramDef(newTermName(nme.macroThis), globTree)) - def tparamInMacro(tdef: TypeDef) = paramDef(tdef.name.toTermName, globTypeTree) - def vparamInMacro(vdef: ValDef): ValDef = paramDef(vdef.name, vdef.tpt match { - case tpt @ AppliedTypeTree(hk, _) if treeInfo.isRepeatedParamType(tpt) => AppliedTypeTree(hk, List(globTree)) - case _ => globTree - }) - def wrapImplicit(tree: Tree) = atPos(tree.pos) { - // implicit hasn't proven useful so far, so I'm disabling it - //val implicitDecl = ValDef(Modifiers(IMPLICIT), nme.macroContextImplicit, SingletonTypeTree(Ident(nme.macroContext)), Ident(nme.macroContext)) - val importGlob = Import(Ident(nme.macroContext), List(ImportSelector(nme.WILDCARD, -1, null, -1))) - Block(List(importGlob), tree) + def typedMacroBody(typer: Typer, ddef: DefDef): Tree = { + import typer.context + if (macroDebug) println("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos)) + + implicit def augmentString(s: String) = new AugmentedString(s) + class AugmentedString(s: String) { + def abbreviateCoreAliases: String = { // hack! + var result = s + result = result.replace("c.mirror.TypeTag", "c.TypeTag") + result = result.replace("c.mirror.Expr", "c.Expr") + result + } } - var formals = (mdef.vparamss map (_ map vparamInMacro)) - if (mdef.tparams.nonEmpty) formals = (mdef.tparams map tparamInMacro) :: formals - - atPos(mdef.pos) { - new DefDef( // can't call DefDef here; need to find out why - mods = mdef.mods &~ MACRO &~ OVERRIDE, - name = nme.macroMethodName(mdef.name), - tparams = List(), - vparamss = globParamSec :: thisParamSec :: formals, - tpt = globTree, - wrapImplicit(mdef.rhs)) + + var hasErrors = false + def reportError(pos: Position, msg: String) = { + hasErrors = true + context.error(pos, msg) + } + + val macroDef = ddef.symbol + val defpos = macroDef.pos + val implpos = ddef.rhs.pos + assert(macroDef.isTermMacro, ddef) + + def invalidBodyError() = + reportError(defpos, + "macro body has wrong shape:" + + "\n required: macro ." + + "\n or : macro ") + def validatePreTyper(rhs: Tree): Unit = rhs match { + // we do allow macro invocations inside macro bodies + // personally I don't mind if pre-typer tree is a macro invocation + // that later resolves to a valid reference to a macro implementation + // however, I don't think that invalidBodyError() should hint at that + // let this be an Easter Egg :) + case Apply(_, _) => ; + case TypeApply(_, _) => ; + case Super(_, _) => ; + case This(_) => ; + case Ident(_) => ; + case Select(_, _) => ; + case _ => invalidBodyError() } + def validatePostTyper(rhs1: Tree): Unit = { + def loop(tree: Tree): Unit = { + def errorNotStatic() = + reportError(implpos, "macro implementation must be in statically accessible object") + + def ensureRoot(sym: Symbol) = + if (!sym.isModule && !sym.isModuleClass) errorNotStatic() + + def ensureModule(sym: Symbol) = + if (!sym.isModule) errorNotStatic() + + tree match { + case TypeApply(fun, _) => + loop(fun) + case Super(qual, _) => + ensureRoot(macroDef.owner) + loop(qual) + case This(_) => + ensureRoot(tree.symbol) + case Select(qual, name) if name.isTypeName => + loop(qual) + case Select(qual, name) if name.isTermName => + if (tree.symbol != rhs1.symbol) ensureModule(tree.symbol) + loop(qual) + case Ident(name) if name.isTypeName => + ; + case Ident(name) if name.isTermName => + if (tree.symbol != rhs1.symbol) ensureModule(tree.symbol) + case _ => + invalidBodyError() + } + } + + loop(rhs1) + } + + val rhs = ddef.rhs + validatePreTyper(rhs) + if (hasErrors) macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + + // we use typed1 instead of typed, because otherwise adapt is going to mess us up + // if adapt sees ., it will want to perform eta-expansion and will fail + // unfortunately, this means that we have to manually trigger macro expansion + // 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 + var rhs1 = if (hasErrors) 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 + while (!typecheckedWithErrors && rhsNeedsMacroExpansion) { + rhs1 = macroExpand1(typer, rhs1) match { + case Success(expanded) => + try { + val typechecked = typer.typed1(expanded, EXPRmode, WildcardType) + if (macroDebug) { + println("typechecked1:") + println(typechecked) + println(showRaw(typechecked)) + } + + typechecked + } finally { + openMacros = openMacros.tail + } + case Fallback(fallback) => + typer.typed1(fallback, EXPRmode, WildcardType) + case Other(result) => + result + } + } + rhs1 + } catch { + case ex: TypeError => + typer.reportTypeError(context, rhs.pos, ex) + typer.infer.setError(rhs) + } + } + + val prevNumErrors = reporter.ERROR.count // funnily enough, the isErroneous check is not enough + var rhs1 = typecheckRhs(rhs) + def typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors + hasErrors = hasErrors || typecheckedWithErrors + if (typecheckedWithErrors) macroTrace("body of a macro def failed to typecheck: ")(ddef) + + val macroImpl = rhs1.symbol + macroDef withAnnotation AnnotationInfo(MacroImplAnnotation.tpe, List(rhs1), Nil) + if (!hasErrors) { + if (macroImpl == null) { + invalidBodyError() + } else { + if (!macroImpl.isMethod) + invalidBodyError() + 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 (!hasErrors) + validatePostTyper(rhs1) + } + if (hasErrors) + macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + } + + if (!hasErrors) { + def checkCompatibility(reqparamss: List[List[Symbol]], actparamss: List[List[Symbol]], reqres: Type, actres: Type): List[String] = { + var hasErrors = false + var errors = List[String]() + def compatibilityError(msg: String) { + hasErrors = true + errors :+= msg + } + + val flatreqparams = reqparamss.flatten + val flatactparams = actparamss.flatten + val tparams = macroImpl.typeParams + val tvars = tparams map freshVar + def lengthMsg(which: String, extra: Symbol) = + "parameter lists have different length, "+which+" extra parameter "+extra.defString + if (actparamss.length != reqparamss.length) + compatibilityError("number of parameter sections differ") + + if (!hasErrors) { + try { + for ((rparams, aparams) <- reqparamss zip actparamss) { + if (rparams.length < aparams.length) + compatibilityError(lengthMsg("found", aparams(rparams.length))) + if (aparams.length < rparams.length) + compatibilityError(lengthMsg("required", rparams(aparams.length)).abbreviateCoreAliases) + } + // if the implementation signature is already deemed to be incompatible, we bail out + // otherwise, high-order type magic employed below might crash in weird ways + if (!hasErrors) { + for ((rparams, aparams) <- reqparamss zip actparamss) { + for ((rparam, aparam) <- rparams zip aparams) { + def isRepeated(param: Symbol) = param.tpe.typeSymbol == RepeatedParamClass + if (rparam.name != aparam.name && !rparam.isSynthetic) { + val rparam1 = rparam + val aparam1 = aparam + compatibilityError("parameter names differ: "+rparam.name+" != "+aparam.name) + } + if (isRepeated(rparam) && !isRepeated(aparam)) + compatibilityError("types incompatible for parameter "+rparam.name+": corresponding is not a vararg parameter") + if (!isRepeated(rparam) && isRepeated(aparam)) + compatibilityError("types incompatible for parameter "+aparam.name+": corresponding is not a vararg parameter") + if (!hasErrors) { + var atpe = aparam.tpe.substSym(flatactparams, flatreqparams).instantiateTypeParams(tparams, tvars) + + // strip the { type PrefixType = ... } refinement off the Context or otherwise we get compatibility errors + atpe = atpe match { + case RefinedType(List(tpe), Scope(sym)) if tpe == MacroContextClass.tpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe + case _ => atpe + } + + val ok = if (macroDebug) withTypesExplained(rparam.tpe <:< atpe) else rparam.tpe <:< atpe + if (!ok) { + compatibilityError("type mismatch for parameter "+rparam.name+": "+rparam.tpe.toString.abbreviateCoreAliases+" does not conform to "+atpe) + } + } + } + } + } + if (!hasErrors) { + val atpe = actres.substSym(flatactparams, flatreqparams).instantiateTypeParams(tparams, tvars) + val ok = if (macroDebug) withTypesExplained(atpe <:< reqres) else atpe <:< reqres + if (!ok) { + compatibilityError("type mismatch for return type : "+reqres.toString.abbreviateCoreAliases+" does not conform to "+(if (ddef.tpt.tpe != null) atpe.toString else atpe.toString.abbreviateCoreAliases)) + } + } + if (!hasErrors) { + val targs = solvedTypes(tvars, tparams, tparams map varianceInType(actres), false, + lubDepth(flatactparams map (_.tpe)) max lubDepth(flatreqparams map (_.tpe))) + val boundsOk = typer.silent(_.infer.checkBounds(ddef, NoPrefix, NoSymbol, tparams, targs, "")) + boundsOk match { + case SilentResultValue(true) => ; + case SilentResultValue(false) | SilentTypeError(_) => + val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, targs).bounds) + compatibilityError("type arguments " + targs.mkString("[", ",", "]") + + " do not conform to " + tparams.head.owner + "'s type parameter bounds " + + (tparams map (_.defString)).mkString("[", ",", "]")) + } + } + } catch { + case ex: NoInstance => + compatibilityError( + "type parameters "+(tparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+ + ex.getMessage) + } + } + + errors.toList + } + + var actparamss = macroImpl.paramss + actparamss = transformTypeTagEvidenceParams(actparamss, (param, tparam) => None) + + val rettpe = if (ddef.tpt.tpe != null) 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 implicitParams = actparamss.flatten filter (_.isImplicit) + if (implicitParams.length > 0) { + reportError(implicitParams.head.pos, "macro implementations cannot have implicit parameters other than TypeTag evidences") + macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + } + + if (!hasErrors) { + val reqres = reqres0 + val actres = macroImpl.tpe.finalResultType + 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 + var retPart = restpe.toString + if (abbreviate || ddef.tpt.tpe == null) retPart = retPart.abbreviateCoreAliases + argsPart + ": " + retPart + } + 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 found : "+showMeth(actparamss, actres, false)+ + "\n"+addendum) + + macroTrace("considering " + reqparamsss.length + " possibilities of compatible macro impl signatures for macro def: ")(ddef.name) + val results = reqparamsss map (checkCompatibility(_, actparamss, reqres, actres)) + if (macroDebug) (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 (macroDebug) (reqparamsss zip results) filter (_._2.isEmpty) foreach { case (reqparamss, result) => + println("typechecked macro impl as: " + reqparamss) + } + } + } + } + + // if this macro definition is erroneous, then there's no sense in expanding its usages + // in the previous prototype macro implementations were magically generated from macro definitions + // so macro definitions and its usages couldn't be compiled in the same compilation run + // however, now definitions and implementations are decoupled, so it's everything is possible + // hence, we now use IS_ERROR flag to serve as an indicator that given macro definition is broken + if (hasErrors) { + macroDef setFlag IS_ERROR + } + + rhs1 } - def addMacroMethods(templ: Template, namer: Namer): Unit = { - for (ddef @ DefDef(mods, _, _, _, _, _) <- templ.body if mods hasFlag MACRO) { - val trace = scala.tools.nsc.util.trace when settings.Ymacrodebug.value - val sym = namer.enterSyntheticSym(trace("macro def: ")(macroMethDef(ddef))) - trace("added to "+namer.context.owner.enclClass+": ")(sym) + 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 = inferRuntimeType(metaType) + + // 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) + val tparams = macroImpl.typeParams map (_.deSkolemize) + val paramPos = tparams indexOf sym.deSkolemize + val sym1 = if (paramPos == -1) sym else { + val ann = macroDef.getAnnotation(MacroImplAnnotation) + ann match { + case Some(ann) => + val TypeApply(_, implRefTargs) = ann.args(0) + val implRefTarg = implRefTargs(paramPos).tpe.typeSymbol + implRefTarg + case None => + sym + } + } + TypeRef(pre, sym1, args) + case tpe => + tpe + } + + // as stated in the spec, before being matched to macroimpl, type and value parameters of macrodef + // undergo a special transformation, sigma, that adapts them to the different metalevel macroimpl lives in + // as a result, we need to reverse this transformation when inferring macrodef ret from macroimpl ret + def unsigma(tpe: Type): Type = { + // unfortunately, we cannot dereference ``paramss'', because we're in the middle of inferring a type for ``macroDef'' +// val defParamss = macroDef.paramss + val defParamss = macroDdef.vparamss map (_ map (_.symbol)) + var implParamss = macroImpl.paramss + implParamss = transformTypeTagEvidenceParams(implParamss, (param, tparam) => None) + + val implCtxParam = if (implParamss.length > 0 && implParamss(0).length > 0) implParamss(0)(0) else null + def implParamToDefParam(implParam: Symbol): Symbol = { + val indices = (implParamss drop 1 zipWithIndex) map { case (implParams, index) => (index, implParams indexOf implParam) } filter (_._2 != -1) headOption; + val defParam = indices flatMap { + case (plistIndex, pIndex) => + if (defParamss.length <= plistIndex) None + else if (defParamss(plistIndex).length <= pIndex) None + else Some(defParamss(plistIndex)(pIndex)) + } + defParam orNull + } + + class UnsigmaTypeMap extends TypeMap { + def apply(tp: Type): Type = tp match { + case TypeRef(pre, sym, args) => + val pre1 = pre match { + case SingleType(SingleType(SingleType(NoPrefix, param), prefix), value) if param == implCtxParam && prefix == MacroContextPrefix && value == ExprValue => + ThisType(macroDef.owner) + case SingleType(SingleType(NoPrefix, param), value) if implParamToDefParam(param) != null && value == ExprValue => + val macroDefParam = implParamToDefParam(param) + SingleType(NoPrefix, macroDefParam) + case _ => + pre + } + val args1 = args map mapOver + TypeRef(pre1, sym, args1) + case _ => + mapOver(tp) + } + } + + new UnsigmaTypeMap() apply tpe } + runtimeType = unsigma(runtimeType) + + runtimeType } - lazy val mirror = new scala.reflect.runtime.Mirror { - lazy val libraryClassLoader = { - // todo. this is more or less okay, but not completely correct - // see https://issues.scala-lang.org/browse/SI-5433 for more info - val classpath = global.classPath.asURLs - var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) - - // an heuristic to detect REPL - if (global.settings.exposeEmptyPackage.value) { - import scala.tools.nsc.interpreter._ - val virtualDirectory = global.settings.outputDirs.getSingleOutput.get - loader = new AbstractFileClassLoader(virtualDirectory, loader) {} + /** Primary mirror that is used to resolve and run macro implementations. + * Loads classes from -Xmacro-primary-classpath, or from -cp if the option is not specified. + */ + private lazy val primaryMirror: Mirror = { + if (global.forMSIL) + throw new UnsupportedOperationException("Scala reflection not available on this platform") + + val libraryClassLoader = { + if (settings.XmacroPrimaryClasspath.value != "") { + if (macroDebug) println("primary macro mirror: initializing from -Xmacro-primary-classpath: %s".format(settings.XmacroPrimaryClasspath.value)) + val classpath = toURLs(settings.XmacroFallbackClasspath.value) + ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) + } else { + if (macroDebug) println("primary macro mirror: initializing from -cp: %s".format(global.classPath.asURLs)) + val classpath = global.classPath.asURLs + var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) + + // [Eugene] a heuristic to detect REPL + if (global.settings.exposeEmptyPackage.value) { + import scala.tools.nsc.interpreter._ + val virtualDirectory = global.settings.outputDirs.getSingleOutput.get + loader = new AbstractFileClassLoader(virtualDirectory, loader) {} + } + + loader } + } + + new Mirror(libraryClassLoader) { override def toString = "" } + } - loader + /** Fallback mirror that is used to resolve and run macro implementations. + * Loads classes from -Xmacro-fallback-classpath aka "macro fallback classpath". + */ + private lazy val fallbackMirror: Mirror = { + if (global.forMSIL) + throw new UnsupportedOperationException("Scala reflection not available on this platform") + + val fallbackClassLoader = { + if (macroDebug) println("fallback macro mirror: initializing from -Xmacro-fallback-classpath: %s".format(settings.XmacroFallbackClasspath.value)) + val classpath = toURLs(settings.XmacroFallbackClasspath.value) + ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) } - override def defaultReflectiveClassLoader() = libraryClassLoader + new Mirror(fallbackClassLoader) { override def toString = "" } } - /** Return optionally address of companion object and implementation method symbol - * of given macro; or None if implementation classfile cannot be loaded or does - * not contain the macro implementation. + /** Produces a function that can be used to invoke macro implementation for a given macro definition: + * 1) Looks up macro implementation symbol in this universe. + * 2) Loads its enclosing class from the primary mirror. + * 3) Loads the companion of that enclosing class from the primary mirror. + * 4) Resolves macro implementation within the loaded companion. + * 5) If 2-4 fails, repeats them for the fallback mirror. + * + * @return Some(runtime) if macro implementation can be loaded successfully from either of the mirrors, + * None otherwise. */ - def macroImpl(mac: Symbol): Option[(AnyRef, mirror.Symbol)] = { - val debug = settings.Ymacrodebug.value - val trace = scala.tools.nsc.util.trace when debug - trace("looking for macro implementation: ")(mac.fullNameString) - - try { - val mmeth = macroMeth(mac) - trace("found implementation at: ")(mmeth.fullNameString) - - if (mmeth == NoSymbol) None - else { - trace("loading implementation class: ")(mmeth.owner.fullName) - trace("classloader is: ")("%s of type %s".format(mirror.libraryClassLoader, mirror.libraryClassLoader.getClass)) + private def macroRuntime(macroDef: Symbol): Option[List[Any] => Any] = { + macroTrace("looking for macro implementation: ")(macroDef) + macroTrace("macroDef is annotated with: ")(macroDef.annotations) + + val ann = macroDef.getAnnotation(MacroImplAnnotation) + if (ann == None) { + macroTrace("@macroImpl annotation is missing (this means that macro definition failed to typecheck)")(macroDef) + return None + } + + val macroImpl = ann.get.args(0).symbol + if (macroImpl == NoSymbol) { + macroTrace("@macroImpl annotation is malformed (this means that macro definition failed to typecheck)")(macroDef) + return None + } + + if (macroDebug) println("resolved implementation %s at %s".format(macroImpl, macroImpl.pos)) + if (macroImpl.isErroneous) { + macroTrace("macro implementation is erroneous (this means that either macro body or macro implementation signature failed to typecheck)")(macroDef) + return None + } + + def loadMacroImpl(macroMirror: Mirror): Option[(Object, macroMirror.Symbol)] = { + try { + // this logic relies on the assumptions that were valid for the old macro prototype + // namely that macro implementations can only be defined in top-level classes and modules + // with the new prototype that materialized in a SIP, macros need to be statically accessible, which is different + // for example, a macro def could be defined in a trait that is implemented by an object + // 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 + + macroTrace("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName) + macroTrace("classloader is: ")("%s of type %s".format(macroMirror.classLoader, if (macroMirror.classLoader != null) macroMirror.classLoader.getClass.toString else "primordial classloader")) def inferClasspath(cl: ClassLoader) = cl match { case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]" + case null => "[" + scala.tools.util.PathResolver.Environment.javaBootClassPath + "]" case _ => "" } - trace("classpath is: ")(inferClasspath(mirror.libraryClassLoader)) + macroTrace("classpath is: ")(inferClasspath(macroMirror.classLoader)) - // @xeno.by: relies on the fact that macros can only be defined in static classes + // [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? def classfile(sym: Symbol): String = { def recur(sym: Symbol): String = sym match { case sym if sym.owner.isPackageClass => @@ -146,145 +693,535 @@ trait Macros { self: Analyzer => else recur(sym.enclClass) } - // @xeno.by: this doesn't work for inner classes - // neither does mmeth.owner.javaClassName, so I had to roll my own implementation - //val receiverName = mmeth.owner.fullName - val receiverName = classfile(mmeth.owner) - val receiverClass: mirror.Symbol = mirror.symbolForName(receiverName) + // [Eugene] this doesn't work for inner classes + // neither does macroImpl.owner.javaClassName, so I had to roll my own implementation + //val receiverName = macroImpl.owner.fullName + val implClassName = classfile(macroImpl.owner) + val implClassSymbol: macroMirror.Symbol = macroMirror.symbolForName(implClassName) - if (debug) { - println("receiverClass is: " + receiverClass.fullNameString) + if (macroDebug) { + println("implClassSymbol is: " + implClassSymbol.fullNameString) - val jreceiverClass = mirror.classToJava(receiverClass) - val jreceiverSource = jreceiverClass.getProtectionDomain.getCodeSource - println("jreceiverClass is %s from %s".format(jreceiverClass, jreceiverSource)) - println("jreceiverClassLoader is %s with classpath %s".format(jreceiverClass.getClassLoader, inferClasspath(jreceiverClass.getClassLoader))) + if (implClassSymbol != macroMirror.NoSymbol) { + val implClass = macroMirror.classToJava(implClassSymbol) + val implSource = implClass.getProtectionDomain.getCodeSource + println("implClass is %s from %s".format(implClass, implSource)) + println("implClassLoader is %s with classpath %s".format(implClass.getClassLoader, inferClasspath(implClass.getClassLoader))) + } } - val receiverObj = receiverClass.companionModule - trace("receiverObj is: ")(receiverObj.fullNameString) + val implObjSymbol = implClassSymbol.companionModule + macroTrace("implObjSymbol is: ")(implObjSymbol.fullNameString) - if (receiverObj == mirror.NoSymbol) None + if (implObjSymbol == macroMirror.NoSymbol) None else { - // @xeno.by: yet another reflection method that doesn't work for inner classes - //val receiver = mirror.companionInstance(receiverClass) - val clazz = java.lang.Class.forName(receiverName, true, mirror.libraryClassLoader) - val receiver = clazz getField "MODULE$" get null - - val rmeth = receiverObj.info.member(mirror.newTermName(mmeth.name.toString)) - if (debug) { - println("rmeth is: " + rmeth.fullNameString) - println("jrmeth is: " + mirror.methodToJava(rmeth)) + // yet another reflection method that doesn't work for inner classes + //val receiver = macroMirror.companionInstance(receiverClass) + val implObj = try { + val implObjClass = java.lang.Class.forName(implClassName, true, macroMirror.classLoader) + implObjClass getField "MODULE$" get null + } catch { + case ex: NoSuchFieldException => macroTrace("exception when loading implObj: ")(ex); null + case ex: NoClassDefFoundError => macroTrace("exception when loading implObj: ")(ex); null + case ex: ClassNotFoundException => macroTrace("exception when loading implObj: ")(ex); null } - if (rmeth == mirror.NoSymbol) None + if (implObj == null) None else { - Some((receiver, rmeth)) + val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString)) + if (macroDebug) { + println("implMethSymbol is: " + implMethSymbol.fullNameString) + println("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol)) + } + + if (implMethSymbol == macroMirror.NoSymbol) None + else { + if (macroDebug) println("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol)) + Some((implObj, implMethSymbol)) + } } } + } catch { + case ex: ClassNotFoundException => + macroTrace("implementation class failed to load: ")(ex.toString) + None } - } catch { - case ex: ClassNotFoundException => - trace("implementation class failed to load: ")(ex.toString) - None + } + + val primary = loadMacroImpl(primaryMirror) + primary match { + case Some((implObj, implMethSymbol)) => + def runtime(args: List[Any]) = primaryMirror.invoke(implObj, implMethSymbol)(args: _*).asInstanceOf[Any] + Some(runtime) + case None => + if (settings.XmacroFallbackClasspath.value != "") { + if (macroDebug) println("trying to load macro implementation from the fallback mirror: %s".format(settings.XmacroFallbackClasspath.value)) + val fallback = loadMacroImpl(fallbackMirror) + fallback match { + case Some((implObj, implMethSymbol)) => + def runtime(args: List[Any]) = fallbackMirror.invoke(implObj, implMethSymbol)(args: _*).asInstanceOf[Any] + Some(runtime) + case None => + None + } + } else { + None + } } } - /** Return result of macro expansion. - * Or, if that fails, and the macro overrides a method return - * tree that calls this method instead of the macro. + /** Should become private again once we're done with migrating typetag generation from implicits */ + def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext { val mirror: global.type } = + new { + val mirror: global.type = global + val callsiteTyper: mirror.analyzer.Typer = typer.asInstanceOf[global.analyzer.Typer] + // todo. infer precise typetag for this Expr, namely the PrefixType member of the Context refinement + val prefix = Expr(prefixTree)(TypeTag.Nothing) + val expandee = expandeeTree + } with MacroContext { + override def toString = "MacroContext(%s@%s +%d)".format(expandee.symbol.name, expandee.pos, openMacros.length - 1 /* exclude myself */) + } + + /** Calculate the arguments to pass to a macro implementation when expanding the provided tree. + * + * This includes inferring the exact type and instance of the macro context to pass, and also + * allowing for missing parameter sections in macro implementation (see ``macroImplParamsss'' for more info). + * + * @return list of runtime objects to pass to the implementation obtained by ``macroRuntime'' */ - def macroExpand(tree: Tree, typer: Typer): Option[Any] = { - val trace = scala.tools.nsc.util.trace when settings.Ymacrodebug.value - trace("macroExpand: ")(tree) - - val macroDef = tree.symbol - macroImpl(macroDef) match { - case Some((receiver, rmeth)) => - val argss = List(global) :: macroArgs(tree) - val paramss = macroMeth(macroDef).paramss - trace("paramss: ")(paramss) - val rawArgss = for ((as, ps) <- argss zip paramss) yield { - if (isVarArgsList(ps)) as.take(ps.length - 1) :+ as.drop(ps.length - 1) - else as - } - val rawArgs: Seq[Any] = rawArgss.flatten - trace("rawArgs: ")(rawArgs) - val savedInfolevel = nodePrinters.infolevel + private def macroArgs(typer: Typer, expandee: Tree): Option[List[Any]] = { + var prefixTree: Tree = EmptyTree + var typeArgs = List[Tree]() + val exprArgs = new ListBuffer[List[Expr[_]]] + def collectMacroArgs(tree: Tree): Unit = tree match { + case Apply(fn, args) => + // todo. infer precise typetag for this Expr, namely the declared type of the corresponding macro impl argument + exprArgs.prepend(args map (Expr(_)(TypeTag.Nothing))) + collectMacroArgs(fn) + case TypeApply(fn, args) => + typeArgs = args + collectMacroArgs(fn) + case Select(qual, name) => + prefixTree = qual + case _ => + } + collectMacroArgs(expandee) + val context = macroContext(typer, prefixTree, expandee) + var argss: List[List[Any]] = List(context) :: exprArgs.toList + macroTrace("argss: ")(argss) + + val macroDef = expandee.symbol + val ann = macroDef.getAnnotation(MacroImplAnnotation).getOrElse(throw new Error("assertion failed. %s: %s".format(macroDef, macroDef.annotations))) + val macroImpl = ann.args(0).symbol + var paramss = macroImpl.paramss + val tparams = macroImpl.typeParams + macroTrace("paramss: ")(paramss) + + // we need to take care of all possible combos of nullary/empty-paramlist macro defs vs nullary/empty-arglist invocations + // nullary def + nullary invocation => paramss and argss match, everything is okay + // nullary def + empty-arglist invocation => illegal Scala code, impossible, everything is okay + // empty-paramlist def + nullary invocation => uh-oh, we need to append a List() to argss + // empty-paramlist def + empty-arglist invocation => paramss and argss match, everything is okay + // that's almost it, but we need to account for the fact that paramss might have context bounds that mask the empty last paramlist + val paramss_without_evidences = transformTypeTagEvidenceParams(paramss, (param, tparam) => None) + val isEmptyParamlistDef = paramss_without_evidences.length != 0 && paramss_without_evidences.last.isEmpty + val isEmptyArglistInvocation = argss.length != 0 && argss.last.isEmpty + if (isEmptyParamlistDef && !isEmptyArglistInvocation) { + if (macroDebug) println("isEmptyParamlistDef && !isEmptyArglistInvocation: appending a List() to argss") + argss = argss :+ Nil + } + + // nb! check partial application against paramss without evidences + val numParamLists = paramss_without_evidences.length + val numArgLists = argss.length + if (numParamLists != numArgLists) { + typer.context.error(expandee.pos, "macros cannot be partially applied") + return None + } + + // if paramss have typetag context bounds, add an arglist to argss if necessary and instantiate the corresponding evidences + // consider the following example: + // + // class D[T] { + // class C[U] { + // def foo[V] = macro Impls.foo[T, U, V] + // } + // } + // + // val outer1 = new D[Int] + // val outer2 = new outer1.C[String] + // outer2.foo[Boolean] + // + // then T and U need to be inferred from the lexical scope of the call using ``asSeenFrom'' + // whereas V won't be resolved by asSeenFrom and need to be loaded directly from ``expandee'' which needs to contain a TypeApply node + // also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim + paramss = transformTypeTagEvidenceParams(paramss, (param, tparam) => Some(tparam)) + if (paramss.lastOption map (params => !params.isEmpty && params.forall(_.isType)) getOrElse false) argss = argss :+ Nil + val evidences = paramss.last takeWhile (_.isType) map (tparam => { + val TypeApply(_, implRefTargs) = ann.args(0) + var implRefTarg = implRefTargs(tparam.paramPos).tpe.typeSymbol + val tpe = if (implRefTarg.isTypeParameterOrSkolem) { + if (implRefTarg.owner == macroDef) { + // [Eugene] doesn't work when macro def is compiled separately from its usages + // then implRefTarg is not a skolem and isn't equal to any of macroDef.typeParams +// val paramPos = implRefTarg.deSkolemize.paramPos + val paramPos = macroDef.typeParams.indexWhere(_.name == implRefTarg.name) + typeArgs(paramPos).tpe + } else + implRefTarg.tpe.asSeenFrom( + if (prefixTree == EmptyTree) macroDef.owner.tpe else prefixTree.tpe, + macroDef.owner) + } else + implRefTarg.tpe + if (macroDebug) println("resolved tparam %s as %s".format(tparam, tpe)) + tpe + }) map (tpe => { + val ttag = TypeTag(tpe) + if (ttag.isGround) ttag.toGround else ttag + }) + argss = argss.dropRight(1) :+ (evidences ++ argss.last) + + assert(argss.length == paramss.length, "argss: %s, paramss: %s".format(argss, paramss)) + val rawArgss = for ((as, ps) <- argss zip paramss) yield { + if (isVarArgsList(ps)) as.take(ps.length - 1) :+ as.drop(ps.length - 1) + else as + } + val rawArgs = rawArgss.flatten + macroTrace("rawArgs: ")(rawArgs) + Some(rawArgs) + } + + /** Keeps track of macros in-flight. + * See more informations in comments to ``openMacros'' in ``scala.reflect.makro.Context''. + */ + var openMacros = List[MacroContext]() + + /** Performs macro expansion: + * 1) Checks whether the expansion needs to be delayed (see ``mustDelayMacroExpansion'') + * 2) Loads macro implementation using ``macroMirror'' + * 3) Synthesizes invocation arguments for the macro implementation + * 4) Checks that the result is a tree bound to this universe + * 5) Typechecks the result against the return type of the macro definition + * + * If -Ymacro-debug is enabled, you will get detailed log of how exactly this function + * performs class loading and method resolution in order to load the macro implementation. + * The log will also include other non-trivial steps of macro expansion. + * + * If -Ymacro-copypaste is enabled along with -Ymacro-debug, you will get macro expansions + * logged in the form that can be copy/pasted verbatim into REPL (useful for debugging!). + * + * @return + * the expansion result if the expansion has been successful, + * the fallback method invocation if the expansion has been unsuccessful, but there is a fallback, + * the expandee unchanged if the expansion has been delayed, + * the expandee fully expanded if the expansion has been delayed before and has been expanded now, + * the expandee with an error marker set if the expansion has been cancelled due malformed arguments or implementation + * the expandee with an error marker set if there has been an error + */ + def macroExpand(typer: Typer, expandee: Tree, pt: Type): Tree = + macroExpand1(typer, expandee) match { + case Success(expanded) => try { - // @xeno.by: InfoLevel.Verbose examines and prints out infos of symbols - // by the means of this'es these symbols can climb up the lexical scope - // when these symbols will be examined by a node printer - // they will enumerate and analyze their children (ask for infos and tpes) - // if one of those children involves macro expansion, things might get nasty - // that's why I'm temporarily turning this behavior off - nodePrinters.infolevel = nodePrinters.InfoLevel.Quiet - val expanded = mirror.invoke(receiver, rmeth)(rawArgs: _*) - expanded match { - case expanded: Tree => - val expectedTpe = tree.tpe - val typed = typer.typed(expanded, EXPRmode, expectedTpe) - Some(typed) - case expanded if expanded.isInstanceOf[Tree] => - typer.context.unit.error(tree.pos, "macro must return a compiler-specific tree; returned value is Tree, but it doesn't belong to this compiler's universe") - None - case expanded => - typer.context.unit.error(tree.pos, "macro must return a compiler-specific tree; returned value is of class: " + expanded.getClass) - None + 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 Select(_, _) => true + case _ => false } - } catch { - case ex => - val realex = ReflectionUtils.unwrapThrowable(ex) - val msg = if (settings.Ymacrodebug.value) { - val stacktrace = new java.io.StringWriter() - realex.printStackTrace(new java.io.PrintWriter(stacktrace)) - System.getProperty("line.separator") + stacktrace - } else { - realex.getMessage - } - typer.context.unit.error(tree.pos, "exception during macro expansion: " + msg) - None + if (isNullaryInvocation) expectedTpe match { + case MethodType(Nil, restpe) => + macroTrace("nullary invocation of a method with an empty parameter list. unwrapping expectedTpe from " + expectedTpe + " to:")(restpe) + expectedTpe = restpe + case _ => ; + } + + var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe)) + if (macroDebug) { + println("typechecked1:") + println(typechecked) + println(showRaw(typechecked)) + } + + typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt)) + if (macroDebug) { + println("typechecked2:") + println(typechecked) + println(showRaw(typechecked)) + } + + typechecked } finally { - nodePrinters.infolevel = savedInfolevel + openMacros = openMacros.tail } - case None => - def notFound() = { - typer.context.unit.error(tree.pos, "macro implementation not found: " + macroDef.name) - None - } - def fallBackToOverridden(tree: Tree): Option[Tree] = { - tree match { - case Select(qual, name) if (macroDef.isMacro) => - macroDef.allOverriddenSymbols match { - case first :: _ => - Some(Select(qual, name) setPos tree.pos setSymbol first) + case Fallback(fallback) => + typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt)) + case Other(result) => + result + } + + private sealed abstract class MacroExpansionResult extends Product with Serializable + private case class Success(expanded: Tree) extends MacroExpansionResult + private case class Fallback(fallback: Tree) extends MacroExpansionResult + private case class Other(result: Tree) extends MacroExpansionResult + private def Delay(expandee: Tree) = Other(expandee) + private def Skip(expanded: Tree) = Other(expanded) + private def Cancel(expandee: Tree) = Other(expandee) + private def Failure(expandee: Tree) = Other(expandee) + private def fail(typer: Typer, expandee: Tree, msg: String = null) = { + if (macroDebug || macroCopypaste) { + var msg1 = if (msg contains "exception during macro expansion") msg.split(EOL).drop(1).headOption.getOrElse("?") else msg + if (macroDebug) msg1 = msg + println("macro expansion has failed: %s".format(msg1)) + } + val pos = if (expandee.pos != NoPosition) expandee.pos else openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition) + if (msg != null) typer.context.error(pos, msg) + typer.infer.setError(expandee) + Failure(expandee) + } + + /** Does the same as ``macroExpand'', but without typechecking the expansion + * Meant for internal use within the macro infrastructure, don't use it elsewhere. + */ + private def macroExpand1(typer: Typer, expandee: Tree): MacroExpansionResult = { + // if a macro implementation is incompatible or any of the arguments are erroneous + // there is no sense to expand the macro itself => it will only make matters worse + if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) { + val reason = if (expandee.symbol.isErroneous) "incompatible macro implementation" else "erroneous arguments" + macroTrace("cancelled macro expansion because of %s: ".format(reason))(expandee) + return Cancel(typer.infer.setError(expandee)) + } + + if (!isDelayed(expandee)) { + if (macroDebug || macroCopypaste) println("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) + + val undetparams = calculateUndetparams(expandee) + if (undetparams.size != 0) { + macroTrace("macro expansion is delayed: ")(expandee) + delayed += expandee -> (typer.context, undetparams) + Delay(expandee) + } else { + val macroDef = expandee.symbol + macroRuntime(macroDef) match { + case Some(runtime) => + val savedInfolevel = nodePrinters.infolevel + try { + // InfoLevel.Verbose examines and prints out infos of symbols + // by the means of this'es these symbols can climb up the lexical scope + // when these symbols will be examined by a node printer + // they will enumerate and analyze their children (ask for infos and tpes) + // if one of those children involves macro expansion, things might get nasty + // that's why I'm temporarily turning this behavior off + nodePrinters.infolevel = nodePrinters.InfoLevel.Quiet + val args = macroArgs(typer, expandee) + args match { + case Some(args) => + // adding stuff to openMacros is easy, but removing it is a nightmare + // it needs to be sprinkled over several different code locations + val (context: MacroContext) :: _ = args + openMacros = context :: openMacros + val expanded: MacroExpansionResult = try { + val prevNumErrors = reporter.ERROR.count + val expanded = runtime(args) + val currNumErrors = reporter.ERROR.count + if (currNumErrors != prevNumErrors) { + fail(typer, expandee) // errors have been reported by the macro itself + } else { + expanded match { + case expanded: Expr[_] => + if (macroDebug || macroCopypaste) { + if (macroDebug) println("original:") + println(expanded.tree) + println(showRaw(expanded.tree)) + } + + freeTerms(expanded.tree) foreach (fte => typer.context.error(expandee.pos, + ("macro expansion contains free term variable %s %s. "+ + "have you forgot to use eval when splicing this variable into a reifee? " + + "if you have troubles tracking free term variables, consider using -Xlog-free-terms").format(fte.name, fte.origin))) + freeTypes(expanded.tree) foreach (fty => typer.context.error(expandee.pos, + ("macro expansion contains free type variable %s %s. "+ + "have you forgot to use c.TypeTag annotation for this type parameter? " + + "if you have troubles tracking free type variables, consider using -Xlog-free-types").format(fty.name, fty.origin))) + + val currNumErrors = reporter.ERROR.count + if (currNumErrors != prevNumErrors) { + fail(typer, expandee) + } else { + // inherit the position from the first position-ful expandee in macro callstack + // this is essential for sane error messages + var tree = expanded.tree + var position = openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition) + tree = atPos(position.focus)(tree) + + // now macro expansion gets typechecked against the macro definition return type + // however, this happens in macroExpand, not here in macroExpand1 + Success(tree) + } + case expanded if expanded.isInstanceOf[Expr[_]] => + val msg = "macro must return a compiler-specific expr; returned value is Expr, but it doesn't belong to this compiler's universe" + fail(typer, expandee, msg) + case expanded => + val msg = "macro must return a compiler-specific expr; returned value is of class: %s".format(expanded.getClass) + fail(typer, expandee, msg) + } + } + } catch { + case ex: Throwable => + openMacros = openMacros.tail + throw ex + } + if (!expanded.isInstanceOf[Success]) openMacros = openMacros.tail + expanded + case None => + fail(typer, expandee) // error has been reported by macroArgs + } + } catch { + case ex => + // [Eugene] any ideas about how to improve this one? + val realex = ReflectionUtils.unwrapThrowable(ex) + realex match { + case realex: reflect.makro.runtime.AbortMacroException => + if (macroDebug || macroCopypaste) println("macro expansion has failed: %s".format(realex.msg)) + fail(typer, expandee) // error has been reported by abort + case _ => + val message = { + try { + // the most reliable way of obtaining currently executing method + // http://stackoverflow.com/questions/442747/getting-the-name-of-the-current-executing-method + val currentMethodName = new Object(){}.getClass().getEnclosingMethod().getName + val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == currentMethodName) + if (relevancyThreshold == -1) None + else { + var relevantElements = realex.getStackTrace().take(relevancyThreshold + 1) + var framesTillReflectiveInvocationOfMacroImpl = relevantElements.reverse.indexWhere(_.isNativeMethod) + 1 + relevantElements = relevantElements dropRight framesTillReflectiveInvocationOfMacroImpl + + realex.setStackTrace(relevantElements) + val message = new java.io.StringWriter() + realex.printStackTrace(new java.io.PrintWriter(message)) + Some(EOL + message) + } + } catch { + // if the magic above goes boom, just fall back to uninformative, but better than nothing, getMessage + case ex: Throwable => + None + } + } getOrElse realex.getMessage + fail(typer, expandee, "exception during macro expansion: " + message) + } + } finally { + nodePrinters.infolevel = savedInfolevel + } + case None => + def notFound() = { + typer.context.error(expandee.pos, "macro implementation not found: " + macroDef.name + " " + + "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)\n" + + "if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath " + + "in the second phase pointing to the output of the first phase") + None + } + def fallBackToOverridden(tree: Tree): Option[Tree] = { + tree match { + case Select(qual, name) if (macroDef.isTermMacro) => + macroDef.allOverriddenSymbols match { + case first :: _ => + Some(Select(qual, name) setPos tree.pos setSymbol first) + case _ => + macroTrace("macro is not overridden: ")(tree) + notFound() + } + case Apply(fn, args) => + fallBackToOverridden(fn) match { + case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos) + case _ => None + } + case TypeApply(fn, args) => + fallBackToOverridden(fn) match { + case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos) + case _ => None + } case _ => - trace("macro is not overridden: ")(tree) + macroTrace("unexpected tree in fallback: ")(tree) notFound() } - case Apply(fn, args) => - fallBackToOverridden(fn) match { - case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos) - case _ => None - } - case TypeApply(fn, args) => - fallBackToOverridden(fn) match { - case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos) - case _ => None - } - case _ => - trace("unexpected tree in fallback: ")(tree) - notFound() - } - } - fallBackToOverridden(tree) match { - case Some(tree1) => - trace("falling back to ")(tree1) - currentRun.macroExpansionFailed = true - Some(tree1) - case None => - None + } + fallBackToOverridden(expandee) match { + case Some(tree1) => + macroTrace("falling back to ")(tree1) + currentRun.macroExpansionFailed = true + Fallback(tree1) + case None => + fail(typer, expandee) + } } + } + } else { + val undetparams = calculateUndetparams(expandee) + if (undetparams.size != 0) + Delay(expandee) + else + Skip(macroExpandAll(typer, expandee)) } } + + /** Without any restrictions on macro expansion, macro applications will expand at will, + * and when type inference is involved, expansions will end up using yet uninferred type params. + * + * For some macros this might be ok (thanks to TreeTypeSubstituter that replaces + * the occurrences of undetparams with their inferred values), but in general case this won't work. + * E.g. for reification simple substitution is not enough - we actually need to re-reify inferred types. + * + * Luckily, there exists a very simple way to fix the problem: delay macro expansion until everything is inferred. + * Here are the exact rules. Macro application gets delayed if any of its subtrees contain: + * 1) type vars (tpe.isInstanceOf[TypeVar]) // [Eugene] this check is disabled right now, because TypeVars seem to be created from undetparams anyways + * 2) undetparams (sym.isTypeParameter && !sym.isSkolem) + */ + var hasPendingMacroExpansions = false + private val delayed = perRunCaches.newWeakMap[Tree, (Context, collection.mutable.Set[Int])] + private def isDelayed(expandee: Tree) = delayed contains expandee + private def calculateUndetparams(expandee: Tree): collection.mutable.Set[Int] = + delayed.get(expandee).map(_._2).getOrElse { + val calculated = collection.mutable.Set[Int]() + expandee foreach (sub => { + def traverse(sym: Symbol) = if (sym != null && (undetparams contains sym.id)) calculated += sym.id + if (sub.symbol != null) traverse(sub.symbol) + if (sub.tpe != null) sub.tpe foreach (sub => traverse(sub.typeSymbol)) + }) + calculated + } + private val undetparams = perRunCaches.newSet[Int] + def notifyUndetparamsAdded(newUndets: List[Symbol]): Unit = undetparams ++= newUndets map (_.id) + def notifyUndetparamsInferred(undetNoMore: List[Symbol], inferreds: List[Type]): Unit = { + undetparams --= undetNoMore map (_.id) + if (!delayed.isEmpty) + delayed.toList foreach { + case (expandee, (_, undetparams)) if !undetparams.isEmpty => + undetparams --= undetNoMore map (_.id) + if (undetparams.isEmpty) { + hasPendingMacroExpansions = true + macroTrace("macro expansion is pending: ")(expandee) + } + case _ => + // do nothing + } + } + + /** Performs macro expansion on all subtrees of a given tree. + * Innermost macros are expanded first, outermost macros are expanded last. + * See the documentation for ``macroExpand'' for more information. + */ + def macroExpandAll(typer: Typer, expandee: Tree): Tree = + new Transformer { + override def transform(tree: Tree) = super.transform(tree match { + // todo. expansion should work from the inside out + case wannabe if (delayed contains wannabe) && calculateUndetparams(wannabe).isEmpty => + val (context, _) = delayed(wannabe) + delayed -= wannabe + macroExpand(newTyper(context), wannabe, WildcardType) + case _ => + tree + }) + }.transform(expandee) } diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 3d8c2ea564..6382e5a847 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -28,6 +28,7 @@ trait MethodSynthesis { else DefDef(sym, body) def applyTypeInternal(manifests: List[M[_]]): Type = { + // [Eugene to Paul] needs review!! val symbols = manifests map manifestToSymbol val container :: args = symbols val tparams = container.typeConstructor.typeParams @@ -58,12 +59,13 @@ trait MethodSynthesis { def newMethodType[F](owner: Symbol)(implicit m: Manifest[F]): Type = { val fnSymbol = manifestToSymbol(m) - assert(fnSymbol isSubClass FunctionClass(m.typeArguments.size - 1), (owner, m)) - val symbols = m.typeArguments map (m => manifestToSymbol(m)) - val formals = symbols.init map (_.typeConstructor) + assert(fnSymbol isSubClass FunctionClass(m.tpe.typeArguments.size - 1), (owner, m)) + // [Eugene to Paul] needs review!! + // val symbols = m.typeArguments map (m => manifestToSymbol(m)) + // val formals = symbols.init map (_.typeConstructor) + val formals = manifestToType(m).typeArguments val params = owner newSyntheticValueParams formals - - MethodType(params, symbols.last.typeConstructor) + MethodType(params, formals.last) } } import synthesisUtil._ @@ -373,7 +375,7 @@ trait MethodSynthesis { case ExistentialType(_, _) => TypeTree() case tp => TypeTree(tp) } - tpt setPos focusPos(derivedSym.pos) + tpt setPos derivedSym.pos.focus // keep type tree of original abstract field if (mods.isDeferred) tpt setOriginal tree.tpt diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 2539091966..696952fe6a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -624,11 +624,6 @@ trait Namers extends MethodSynthesis { enterCopyMethodOrGetter(tree, tparams) else sym setInfo completerOf(tree, tparams) - - if (mods hasFlag MACRO) { - if (!(sym.owner.isClass && sym.owner.isStatic)) - context.error(tree.pos, "macro definition must appear in globally accessible class") - } } def enterClassDef(tree: ClassDef) { @@ -651,14 +646,6 @@ trait Namers extends MethodSynthesis { val m = ensureCompanionObject(tree) classAndNamerOfModule(m) = (tree, null) } - val hasMacro = impl.body exists { - case DefDef(mods, _, _, _, _, _) => mods hasFlag MACRO - case _ => false - } - if (hasMacro) { - val m = ensureCompanionObject(tree) - classOfModuleClass(m.moduleClass) = new WeakReference(tree) - } val owner = tree.symbol.owner if (owner.isPackageObjectClass) { context.unit.warning(tree.pos, @@ -809,7 +796,9 @@ trait Namers extends MethodSynthesis { */ private def assignTypeToTree(tree: ValOrDefDef, defnTyper: Typer, pt: Type): Type = { // compute result type from rhs - val typedBody = defnTyper.computeType(tree.rhs, pt) + val typedBody = + if (tree.symbol.isTermMacro) defnTyper.computeMacroDefType(tree, pt) + else defnTyper.computeType(tree.rhs, pt) val sym = if (owner.isMethod) owner else tree.symbol val typedDefn = widenIfNecessary(sym, typedBody, pt) assignTypeToTree(tree, typedDefn) @@ -871,10 +860,8 @@ trait Namers extends MethodSynthesis { Namers.this.classOfModuleClass get clazz foreach { cdefRef => val cdef = cdefRef() if (cdef.mods.isCase) addApplyUnapply(cdef, templateNamer) - if (settings.Xmacros.value) addMacroMethods(cdef.impl, templateNamer) classOfModuleClass -= clazz } - if (settings.Xmacros.value) addMacroMethods(templ, templateNamer) } // add the copy method to case classes; this needs to be done here, not in SyntheticMethods, because @@ -1029,12 +1016,20 @@ trait Namers extends MethodSynthesis { } addDefaultGetters(meth, vparamss, tparams, overriddenSymbol) + // macro defs need to be typechecked in advance + // because @macroImpl annotation only gets assigned during typechecking + // otherwise we might find ourselves in the situation when we specified -Xmacro-fallback-classpath + // but macros still don't expand + // that might happen because macro def doesn't have its link a macro impl yet + if (ddef.symbol.isTermMacro) { + val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol)) + typer.computeMacroDefType(ddef, pt) + } + thisMethodType({ val rt = ( if (!tpt.isEmpty) { typer.typedType(tpt).tpe - } else if (meth.isMacro) { - assignTypeToTree(ddef, AnyClass.tpe) } else { // replace deSkolemized symbols with skolemized ones // (for resultPt computed by looking at overridden symbol, right?) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 806ee480f0..ad727d4082 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -227,6 +227,8 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R * 1.8.1 M's type is a subtype of O's type, or * 1.8.2 M is of type []S, O is of type ()T and S <: T, or * 1.8.3 M is of type ()S, O is of type []T and S <: T, or + * 1.9. If M is a macro def, O cannot be deferred. + * 1.10. If M is not a macro def, O cannot be a macro def. * 2. Check that only abstract classes have deferred members * 3. Check that concrete classes do not have deferred definitions * that are not implemented in a subclass. @@ -416,6 +418,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R } else if (other.isValue && other.isLazy && !other.isSourceMethod && !other.isDeferred && member.isValue && !member.isLazy) { overrideError("must be declared lazy to override a concrete lazy value") + } else if (other.isDeferred && member.isTermMacro) { // (1.9) + overrideError("cannot override an abstract method") + } else if (other.isTermMacro && !member.isTermMacro) { // (1.10) + overrideError("cannot override a macro") } else { checkOverrideTypes() if (settings.warnNullaryOverride.value) { diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 3233b7b07c..38c2c5f719 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -456,14 +456,20 @@ trait TypeDiagnostics { ex match { case CyclicReference(sym, info: TypeCompleter) => - val pos = info.tree match { - case Import(expr, _) => expr.pos - case _ => ex.pos + 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 { + case Import(expr, _) => expr.pos + case _ => ex.pos + } + contextError(context0, pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage()) + + if (sym == ObjectClass) + throw new FatalError("cannot redefine root "+sym) } - contextError(context0, pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage()) - - if (sym == ObjectClass) - throw new FatalError("cannot redefine root "+sym) case _ => contextError(context0, ex.pos, ex) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f558e0afc7..1b508a96fe 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -51,6 +51,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { 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 @@ -181,7 +182,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case _ => def wrapImplicit(from: Type): Tree = { val result = inferImplicit(tree, functionType(List(from), to), reportAmbiguous, true, context, saveErrors) - if (result.subst != EmptyTreeTypeSubstituter) result.subst traverse tree + if (result.subst != EmptyTreeTypeSubstituter) { + result.subst traverse tree + notifyUndetparamsInferred(result.subst.from, result.subst.to) + } result.tree } val result = wrapImplicit(from) @@ -813,7 +817,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case Block(_, tree1) => tree1.symbol case _ => tree.symbol } - if (!meth.isConstructor && !meth.isMacro && isFunctionType(pt)) { // (4.2) + if (!meth.isConstructor && !meth.isTermMacro && isFunctionType(pt)) { // (4.2) debuglog("eta-expanding " + tree + ":" + tree.tpe + " to " + pt) checkParamsConvertible(tree, tree.tpe) val tree0 = etaExpand(context.unit, tree) @@ -1008,12 +1012,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else TypeApply(tree, tparams1 map (tparam => TypeTree(tparam.tpeHK) setPos tree.pos.focus)) setPos tree.pos //@M/tcpolyinfer: changed tparam.tpe to tparam.tpeHK context.undetparams ++= tparams1 + notifyUndetparamsAdded(tparams1) adapt(tree1 setType restpe.substSym(tparams, tparams1), mode, pt, original) case mt: MethodType if mt.isImplicit && ((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) => // (4.1) adaptToImplicitMethod(mt) case mt: MethodType if (((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) && - (context.undetparams.isEmpty || inPolyMode(mode))) => + (context.undetparams.isEmpty || inPolyMode(mode))) && !(tree.symbol != null && tree.symbol.isTermMacro) => instantiateToMethodType(mt) case _ => @@ -1026,13 +1031,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } if (tree.isType) adaptType() - else if (inExprModeButNot(mode, FUNmode) && tree.symbol != null && tree.symbol.isMacro && !tree.isDef && !(tree exists (_.isErroneous))) - macroExpand(tree, this) match { - case Some(expanded: Tree) => - typed(expanded, mode, pt) - case None => - setError(tree) // error already reported - } + else if (context.macrosEnabled && // when macros are enabled + inExprModeButNot(mode, FUNmode) && !tree.isDef && // and typechecking application + tree.symbol != null && tree.symbol.isTermMacro) // of a term macro + macroExpand(this, tree, pt) else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode)) adaptConstrPattern() else if (inAllModes(mode, EXPRmode | FUNmode) && @@ -1906,8 +1908,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { meth.owner.isAnonOrRefinementClass)) InvalidConstructorDefError(ddef) typed(ddef.rhs) - } else if (meth.isMacro) { - EmptyTree + } else if (meth.isTermMacro) { + // typechecking macro bodies is sort of unconventional + // that's why we employ our custom typing scheme orchestrated outside of the typer + transformedOr(ddef.rhs, typedMacroBody(this, ddef)) } else { transformedOrTyped(ddef.rhs, EXPRmode, tpt1.tpe) } @@ -2212,7 +2216,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { (ps, sel) case Some((vparams, sel)) => val newParamSyms = (vparams, formals).zipped map {(p, tp) => - methodSym.newValueParameter(p.name, focusPos(p.pos), SYNTHETIC) setInfo tp + methodSym.newValueParameter(p.name, p.pos.focus, SYNTHETIC) setInfo tp } (newParamSyms, sel.duplicate) @@ -2267,7 +2271,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else { // applyOrElse's default parameter: val B1 = methodSym newTypeParameter(newTypeName("B1")) setInfo TypeBounds.empty //lower(resTp) - val default = methodSym newValueParameter(newTermName("default"), focusPos(tree.pos), SYNTHETIC) setInfo functionType(List(A1.tpe), B1.tpe) + val default = methodSym newValueParameter(newTermName("default"), tree.pos.focus, SYNTHETIC) setInfo functionType(List(A1.tpe), B1.tpe) val paramSyms = List(x, default) methodSym setInfoAndEnter polyType(List(A1, B1), MethodType(paramSyms, B1.tpe)) @@ -2489,7 +2493,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { var e1 = scope.lookupNextEntry(e) while ((e1 ne null) && e1.owner == scope) { if (!accesses(e.sym, e1.sym) && !accesses(e1.sym, e.sym) && - (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe) || e.sym.isMacro && e1.sym.isMacro)) + (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe))) // default getters are defined twice when multiple overloads have defaults. an // error for this is issued in RefChecks.checkDefaultsInOverloaded if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefault && @@ -2575,7 +2579,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else if (isByNameParamType(formals.head)) 0 else BYVALmode ) - val tree = typedArg(args.head, mode, typedMode, adapted.head) + var tree = typedArg(args.head, mode, typedMode, adapted.head) + if (hasPendingMacroExpansions) tree = macroExpandAll(this, tree) // formals may be empty, so don't call tail tree :: loop(args.tail, formals drop 1, adapted.tail) } @@ -2737,6 +2742,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def tryNamesDefaults: Tree = { val lencmp = compareLengths(args, formals) + def checkNotMacro() = { + if (fun.symbol != null && fun.symbol.filter(sym => sym != null && sym.isTermMacro) != NoSymbol) + duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun)) + } + if (mt.isErroneous) duplErrTree else if (inPatternMode(mode)) { // #2064 @@ -2755,8 +2765,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else if (isIdentity(argPos) && !isNamedApplyBlock(fun)) { // if there's no re-ordering, and fun is not transformed, no need to transform // more than an optimization, e.g. important in "synchronized { x = update-x }" + checkNotMacro() doTypedApply(tree, fun, namelessArgs, mode, pt) } else { + checkNotMacro() transformNamedApplication(Typer.this, mode, pt)( treeCopy.Apply(tree, fun, namelessArgs), argPos) } @@ -2764,6 +2776,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // defaults are needed. they are added to the argument list in named style as // calls to the default getters. Example: // foo[Int](a)() ==> foo[Int](a)(b = foo$qual.foo$default$2[Int](a)) + checkNotMacro() val fun1 = transformNamedApplication(Typer.this, mode, pt)(fun, x => x) if (fun1.isErroneous) duplErrTree else { @@ -3111,7 +3124,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } if (hasError) annotationError - else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)}).setOriginal(ann).setPos(ann.pos) + else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)}).setOriginal(Apply(typedFun, args)).setPos(ann.pos) } } else if (requireJava) { reportAnnotationError(NestedAnnotationError(ann, annType)) @@ -3151,7 +3164,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def annInfo(t: Tree): AnnotationInfo = t match { case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => - AnnotationInfo(annType, args, List()).setOriginal(ann).setPos(t.pos) + AnnotationInfo(annType, args, List()).setOriginal(typedAnn).setPos(t.pos) case Block(stats, expr) => context.warning(t.pos, "Usage of named or default arguments transformed this annotation\n"+ @@ -3437,7 +3450,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { println(s) } - protected def typed1(tree: Tree, mode: Int, pt: Type): Tree = { + def typed1(tree: Tree, mode: Int, pt: Type): Tree = { def isPatternMode = inPatternMode(mode) //Console.println("typed1("+tree.getClass()+","+Integer.toHexString(mode)+","+pt+")") @@ -3451,10 +3464,27 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } def typedAnnotated(ann: Tree, arg1: Tree): Tree = { - def mkTypeTree(tpe: Type) = TypeTree(tpe) setOriginal tree setPos tree.pos.focus /** mode for typing the annotation itself */ val annotMode = mode & ~TYPEmode | EXPRmode + def resultingTypeTree(tpe: Type) = { + // we need symbol-ful originals for reification + // hence we go the extra mile to hand-craft tis guy + val original = + if (arg1.isType) + (tree, arg1) match { + case (Annotated(annot, arg), tt @ TypeTree()) => Annotated(annot, tt.original) + // this clause is needed to correctly compile stuff like "new C @D" or "@(inline @getter)" + case (Annotated(annot, arg), _) => Annotated(annot, arg1) + case _ => throw new Error("unexpected trees in typedAnnotated: tree = %s, arg1 = %s".format(showRaw(tree), showRaw(arg1))) + } + else + tree + original setType ann.tpe + original setPos tree.pos.focus + TypeTree(tpe) setOriginal original setPos tree.pos.focus + } + if (arg1.isType) { // make sure the annotation is only typechecked once if (ann.tpe == null) { @@ -3497,11 +3527,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { arg1 // simply drop erroneous annotations else { ann.tpe = atype - mkTypeTree(atype) + resultingTypeTree(atype) } } else { // the annotation was typechecked before - mkTypeTree(ann.tpe) + resultingTypeTree(ann.tpe) } } else { @@ -3510,7 +3540,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { ann.tpe = arg1.tpe.withAnnotation(annotInfo) } val atype = ann.tpe - Typed(arg1, mkTypeTree(atype)) setPos tree.pos setType atype + Typed(arg1, resultingTypeTree(atype)) setPos tree.pos.focus setType atype } } @@ -3676,6 +3706,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (checkStablePrefixClassType(tpt0)) if (tpt0.hasSymbol && !tpt0.symbol.typeParams.isEmpty) { context.undetparams = cloneSymbols(tpt0.symbol.typeParams) + notifyUndetparamsAdded(context.undetparams) TypeTree().setOriginal(tpt0) .setType(appliedType(tpt0.tpe, context.undetparams map (_.tpeHK))) // @PP: tpeHK! #3343, #4018, #4347. } else tpt0 @@ -4534,7 +4565,18 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { typedNew(tpt) case Typed(expr, Function(List(), EmptyTree)) => - typedEta(checkDead(typed1(expr, mode, pt))) + // find out whether the programmer is trying to eta-expand a macro def + // to do that we need to typecheck the tree first (we need a symbol of the eta-expandee) + // that typecheck must not trigger macro expansions, so we explicitly prohibit them + // Q: "but, " - you may ask - ", `typed1` doesn't call adapt, which does macro expansion, so why explicit check?" + // A: solely for robustness reasons. this mechanism might change in the future, which might break unprotected code + val expr1 = context.withMacrosDisabled(typed1(expr, mode, pt)) + expr1 match { + case macroDef if macroDef.symbol.isTermMacro => + MacroEtaError(expr1) + case _ => + typedEta(checkDead(expr1)) + } case Typed(expr0, tpt @ Ident(tpnme.WILDCARD_STAR)) => val expr = typed(expr0, onlyStickyModes(mode), WildcardType) @@ -4608,18 +4650,17 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { tpt.tpe.typeSymbol == ArrayClass && args.length == 1 && erasure.GenericArray.unapply(tpt.tpe).isDefined) => // !!! todo simplify by using extractor - // convert new Array[T](len) to evidence[ClassManifest[T]].newArray(len) - // convert new Array^N[T](len) for N > 1 to evidence[ClassManifest[T]].newArrayN(len) - val Some((level, manifType)) = erasure.GenericArray.unapply(tpt.tpe) - if (level > MaxArrayDims) - MultiDimensionalArrayError(tree) - else { - val newArrayApp = atPos(tree.pos) { - val manif = getManifestTree(tree, manifType, false) - new ApplyToImplicitArgs(Select(manif, if (level == 1) "newArray" else "newArray"+level), args) - } - typed(newArrayApp, mode, pt) + // 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) + val Some((level, componentType)) = erasure.GenericArray.unapply(tpt.tpe) + val tagType = List.iterate(componentType, level)(tpe => appliedType(ArrayClass.asType, List(tpe))).last + val newArrayApp = atPos(tree.pos) { + val tag = resolveClassTag(tree, tagType) + if (tag.isEmpty) MissingClassTagError(tree, tagType) + else new ApplyToImplicitArgs(Select(tag, nme.newArray), args) } + typed(newArrayApp, mode, pt) case tree1 => tree1 } @@ -4679,7 +4720,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case ReferenceToBoxed(idt @ Ident(_)) => val id1 = typed1(idt, mode, pt) match { case id: Ident => id } - treeCopy.ReferenceToBoxed(tree, id1) setType AnyRefClass.tpe + // [Eugene] am I doing it right? + val erasedTypes = phaseId(currentPeriod) >= currentRun.erasurePhase.id + val tpe = capturedVariableType(idt.symbol, erasedTypes = erasedTypes) + treeCopy.ReferenceToBoxed(tree, id1) setType tpe case Literal(value) => tree setType ( @@ -4916,31 +4960,75 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def typedTypeConstructor(tree: Tree): Tree = typedTypeConstructor(tree, NOmode) def computeType(tree: Tree, pt: Type): Type = { + // macros employ different logic of `computeType` + assert(!context.owner.isTermMacro, context.owner) val tree1 = typed(tree, pt) transformed(tree) = tree1 packedType(tree1, context.owner) } + def computeMacroDefType(tree: Tree, pt: Type): Type = { + assert(context.owner.isTermMacro, context.owner) + assert(tree.symbol.isTermMacro, tree.symbol) + assert(tree.isInstanceOf[DefDef], tree.getClass) + val ddef = tree.asInstanceOf[DefDef] + + val tree1 = + if (transformed contains ddef.rhs) { + // macro defs are typechecked in `methodSig` (by calling this method) in order to establish their link to macro implementation asap + // if a macro def doesn't have explicitly specified return type, this method will be called again by `assignTypeToTree` + // here we guard against this case + transformed(ddef.rhs) + } else { + val tree1 = typedMacroBody(this, ddef) + transformed(ddef.rhs) = tree1 + tree1 + } + + val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous)) + if (isMacroBodyOkay) computeMacroDefTypeFromMacroImpl(ddef, tree.symbol, tree1.symbol) else AnyClass.tpe + } + + def transformedOr(tree: Tree, op: => Tree): Tree = transformed.get(tree) match { + case Some(tree1) => transformed -= tree; tree1 + case None => op + } + def transformedOrTyped(tree: Tree, mode: Int, pt: Type): Tree = transformed.get(tree) match { case Some(tree1) => transformed -= tree; tree1 case None => typed(tree, mode, pt) } - def findManifest(tp: Type, full: Boolean) = beforeTyper { + // `tree` is only necessary here for its position + // but that's invaluable for error reporting, so I decided to include it into this method's contract + // before passing EmptyTree, please, consider passing something meaningful first + def resolveClassTag(tree: Tree, tp: Type): Tree = beforeTyper { inferImplicit( EmptyTree, - appliedType((if (full) FullManifestClass else PartialManifestClass).typeConstructor, List(tp)), - true, false, context) + appliedType(ClassTagClass.typeConstructor, List(tp)), + /*reportAmbiguous =*/ true, + /*isView =*/ false, + /*context =*/ context, + /*saveAmbiguousDivergent =*/ true, + /*pos =*/ tree.pos + ).tree } - def getManifestTree(tree: Tree, tp: Type, full: Boolean): Tree = { - val manifestOpt = findManifest(tp, full) - if (manifestOpt.tree.isEmpty) { - MissingManifestError(tree, full, tp) - } else { - manifestOpt.tree - } + // `tree` is only necessary here for its position + // but that's invaluable for error reporting, so I decided to include it into this method's contract + // before passing EmptyTree, please, consider passing something meaningful first + def resolveTypeTag(tree: Tree, pre: Type, tp: Type, full: Boolean): Tree = beforeTyper { + inferImplicit( + EmptyTree, + appliedType(singleType(pre, pre member (if (full) GroundTypeTagClass else TypeTagClass).name), List(tp)), + /*reportAmbiguous =*/ true, + /*isView =*/ false, + /*context =*/ context, + /*saveAmbiguousDivergent =*/ true, + /*pos =*/ tree.pos + ).tree } + /* def convertToTypeTree(tree: Tree): Tree = tree match { case TypeTree() => tree diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index ce10ee34a2..11d7db5180 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -27,7 +27,7 @@ object ClassPath { def scalaCompiler = locate[Global] def infoFor[T](value: T) = info(value.getClass) - def info[T](clazz: Class[T]) = new ClassAndJarInfo()(ClassManifest fromClass clazz) + def info[T](clazz: Class[T]) = new ClassAndJarInfo()(ClassManifest[T](clazz)) def info[T: ClassManifest] = new ClassAndJarInfo[T] def locate[T: ClassManifest] = info[T] rootClasspath def locateJar[T: ClassManifest] = info[T].rootPossibles find (x => isJarOrZip(x)) map (x => File(x)) diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala index bc74717366..573f7bc7b2 100644 --- a/src/compiler/scala/tools/nsc/util/Position.scala +++ b/src/compiler/scala/tools/nsc/util/Position.scala @@ -33,62 +33,24 @@ object Position { } } -/** - * A tree does not directly store a Position. It stores a TreeAnnotation, which /typically/ is a Position. - * - * A TreeAnnotion may encompass more than just a Position, though, depending on the exact subclass of TreeAnnotation. - */ -trait TreeAnnotation { - def pos: Position -} +trait Position extends scala.reflect.api.Position with scala.reflect.api.Attachment { + /** Exposes itself as payload of Attachment */ + // necessary for conformance with Attachment + def pos: Position = this + /** A bit weird method that is necessary to safely update positions without destroying custom attachments */ + // necessary for conformance with Attachment + def withPos(pos: scala.reflect.api.Position) = pos -/** The Position class and its subclasses represent positions of ASTs and symbols. - * Except for NoPosition and FakePos, every position refers to a SourceFile - * and to an offset in the sourcefile (its `point`). For batch compilation, - * that's all. For interactive IDE's there are also RangePositions - * and TransparentPositions. A RangePosition indicates a start and an end - * in addition to its point. TransparentPositions are a subclass of RangePositions. - * Range positions that are not transparent are called opaque. - * Trees with RangePositions need to satisfy the following invariants. - * - * INV1: A tree with an offset position never contains a child - * with a range position - * INV2: If the child of a tree with a range position also has a range position, - * then the child's range is contained in the parent's range. - * INV3: Opaque range positions of children of the same node are non-overlapping - * (this means their overlap is at most a single point). - * - * The following tests are useful on positions: - * - * pos.isDefined true if position is not a NoPosition nor a FakePosition - * pos.isRange true if position is a range - * pos.isOpaqueRange true if position is an opaque range - * - * The following accessor methods are provided: - * - * pos.source The source file of the position, which must be defined - * pos.point The offset of the position's point, which must be defined - * pos.start The start of the position, which must be a range - * pos.end The end of the position, which must be a range - * - * There are also convenience methods, such as - * - * pos.startOrPoint - * pos.endOrPoint - * pos.pointOrElse(default) - * - * These are less strict about the kind of position on which they can be applied. - * - * The following conversion methods are often used: - * - * pos.focus converts a range position to an offset position, keeping its point; - * returns all other positions unchanged. - * pos.makeTransparent converts an opaque range position into a transparent one. - * returns all other positions unchanged. - */ -trait Position extends TreeAnnotation { - def pos: Position = this + /** Java file corresponding to the source file of this position. + */ + // necessary for conformance with scala.reflect.api.Position + def fileInfo: java.io.File = source.file.file + + /** Contents of the source file that contains this position. + */ + // necessary for conformance with scala.reflect.api.Position + def fileContent: Array[Char] = source.content /** An optional value containing the source file referred to by this position, or * None if not defined. @@ -134,74 +96,74 @@ trait Position extends TreeAnnotation { def offset: Option[Int] = if (isDefined) Some(point) else None /** The same position with a different start value (if a range) */ - def withStart(off: Int) = this + def withStart(off: Int): Position = this /** The same position with a different end value (if a range) */ - def withEnd(off: Int) = this + def withEnd(off: Int): Position = this /** The same position with a different point value (if a range or offset) */ - def withPoint(off: Int) = this + def withPoint(off: Int): Position = this /** The same position with a different source value, and its values shifted by given offset */ - def withSource(source: SourceFile, shift: Int) = this + def withSource(source: SourceFile, shift: Int): Position = this /** If this is a range, the union with the other range, with the point of this position. * Otherwise, this position */ - def union(pos: Position) = this + def union(pos: scala.reflect.api.Position): Position = this /** If this is a range position, the offset position of its start. * Otherwise the position itself */ - def focusStart = this + def focusStart: Position = this /** If this is a range position, the offset position of its point. * Otherwise the position itself */ - def focus = this + def focus: Position = this /** If this is a range position, the offset position of its end. * Otherwise the position itself */ - def focusEnd = this + def focusEnd: Position = this /** Does this position include the given position `pos`. * This holds if `this` is a range position and its range [start..end] * is the same or covers the range of the given position, which may or may not be a range position. */ - def includes(pos: Position) = false + def includes(pos: scala.reflect.api.Position): Boolean = false /** Does this position properly include the given position `pos` ("properly" meaning their * ranges are not the same)? */ - def properlyIncludes(pos: Position) = + def properlyIncludes(pos: scala.reflect.api.Position): Boolean = includes(pos) && (start < pos.startOrPoint || pos.endOrPoint < end) /** Does this position precede that position? * This holds if both positions are defined and the end point of this position * is not larger than the start point of the given position. */ - def precedes(pos: Position) = + def precedes(pos: scala.reflect.api.Position): Boolean = isDefined && pos.isDefined && endOrPoint <= pos.startOrPoint /** Does this position properly precede the given position `pos` ("properly" meaning their ranges * do not share a common point). */ - def properlyPrecedes(pos: Position) = + def properlyPrecedes(pos: scala.reflect.api.Position): Boolean = isDefined && pos.isDefined && endOrPoint < pos.startOrPoint /** Does this position overlap with that position? * This holds if both positions are ranges and there is an interval of * non-zero length that is shared by both position ranges. */ - def overlaps(pos: Position) = + def overlaps(pos: scala.reflect.api.Position): Boolean = isRange && pos.isRange && ((pos.start < end && start < pos.end) || (start < pos.end && pos.start < end)) /** Does this position cover the same range as that position? * Holds only if both position are ranges */ - def sameRange(pos: Position) = + def sameRange(pos: scala.reflect.api.Position): Boolean = isRange && pos.isRange && start == pos.start && end == pos.end def line: Int = throw new UnsupportedOperationException("Position.line") @@ -219,11 +181,11 @@ trait Position extends TreeAnnotation { * file. If the SourceFile is a normal SourceFile, simply * return this. */ - def inUltimateSource(source : SourceFile) = + def inUltimateSource(source : SourceFile): Position = if (source == null) this else source.positionInUltimateSource(this) - def dbgString = toString - def safeLine = try line catch { case _: UnsupportedOperationException => -1 } + def dbgString: String = toString + def safeLine: Int = try line catch { case _: UnsupportedOperationException => -1 } def show: String = "["+toString+"]" } @@ -254,8 +216,10 @@ class OffsetPosition(override val source: SourceFile, override val point: Int) e col + 1 } - override def union(pos: Position) = - if (pos.isRange) pos else this + override def union(pos: scala.reflect.api.Position) = + // [Eugene] how do I get rid of this cast? + // I could introduce a "type PositionType <: scala.reflect.api.Position", but that's also ugly + if (pos.isRange) pos.asInstanceOf[Position] else this override def equals(that : Any) = that match { case that : OffsetPosition => point == that.point && source.file == that.source.file @@ -265,7 +229,7 @@ class OffsetPosition(override val source: SourceFile, override val point: Int) e override def toString = { val pointmsg = if (point > source.length) "out-of-bounds-" else "offset=" - "source-%s,line-%s,%s%s".format(source.path, line, pointmsg, point) + "source-%s,line-%s,%s%s".format(source.file.canonicalPath, line, pointmsg, point) } override def show = "["+point+"]" } @@ -289,8 +253,8 @@ extends OffsetPosition(source, point) { } override def focusEnd = new OffsetPosition(source, end) override def makeTransparent = new TransparentPosition(source, start, point, end) - override def includes(pos: Position) = pos.isDefined && start <= pos.startOrPoint && pos.endOrPoint <= end - override def union(pos: Position) = + override def includes(pos: scala.reflect.api.Position) = pos.isDefined && start <= pos.startOrPoint && pos.endOrPoint <= end + override def union(pos: scala.reflect.api.Position): Position = if (pos.isRange) new RangePosition(source, start min pos.start, point, end max pos.end) else this override def toSingleLine: Position = source match { @@ -301,7 +265,7 @@ extends OffsetPosition(source, point) { case _ => this } - override def toString = "RangePosition("+source+", "+start+", "+point+", "+end+")" + override def toString = "RangePosition("+source.file.canonicalPath+", "+start+", "+point+", "+end+")" override def show = "["+start+":"+end+"]" private var focusCache: Position = NoPosition } @@ -311,10 +275,4 @@ class TransparentPosition(source: SourceFile, start: Int, point: Int, end: Int) override def isTransparent = true override def makeTransparent = this override def show = "<"+start+":"+end+">" -} - - - - - - +} \ No newline at end of file diff --git a/src/compiler/scala/tools/reflect/package.scala b/src/compiler/scala/tools/reflect/package.scala index 8f5e099fbf..f5c836a4e9 100644 --- a/src/compiler/scala/tools/reflect/package.scala +++ b/src/compiler/scala/tools/reflect/package.scala @@ -27,7 +27,7 @@ package object reflect { } } - def zeroOfClass(clazz: Class[_]) = zeroOf(Manifest.classType(clazz)) + def zeroOfClass(clazz: Class[_]) = zeroOf(Manifest(ClassManifest(clazz).tpe)) def zeroOf[T](implicit m: Manifest[T]): AnyRef = { if (m == manifest[Boolean] || m == manifest[jl.Boolean]) false: jl.Boolean else if (m == manifest[Unit] || m == manifest[jl.Void] || m == manifest[scala.runtime.BoxedUnit]) scala.runtime.BoxedUnit.UNIT diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index b5006e7948..d241d2ddc0 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -99,17 +99,40 @@ object Predef extends LowPriorityImplicits { // def AnyRef = scala.AnyRef // Manifest types, companions, and incantations for summoning + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") type ClassManifest[T] = scala.reflect.ClassManifest[T] - type Manifest[T] = scala.reflect.Manifest[T] + @deprecated("OptManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0") type OptManifest[T] = scala.reflect.OptManifest[T] + @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + type Manifest[T] = scala.reflect.Manifest[T] + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") val ClassManifest = scala.reflect.ClassManifest - val Manifest = scala.reflect.Manifest - val NoManifest = scala.reflect.NoManifest + // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies. + @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + lazy val Manifest = scala.reflect.Manifest // needs to be lazy, because requires scala.reflect.mirror instance + @deprecated("NoManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0") + lazy val NoManifest = scala.reflect.NoManifest // needs to be lazy, because requires scala.reflect.mirror instance def manifest[T](implicit m: Manifest[T]) = m def classManifest[T](implicit m: ClassManifest[T]) = m def optManifest[T](implicit m: OptManifest[T]) = m + // Tag types and companions, and incantations for summoning + type ClassTag[T] = scala.reflect.ClassTag[T] + type TypeTag[T] = scala.reflect.TypeTag[T] + type GroundTypeTag[T] = scala.reflect.GroundTypeTag[T] + val ClassTag = scala.reflect.ClassTag // doesn't need to be lazy, because it's not a path-dependent type + // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies. + lazy val TypeTag = scala.reflect.TypeTag // needs to be lazy, because requires scala.reflect.mirror instance + lazy val GroundTypeTag = scala.reflect.GroundTypeTag + + // [Eugene to Martin] it's really tedious to type "implicitly[...]" all the time, so I'm reintroducing these shortcuts + def classTag[T](implicit ctag: ClassTag[T]) = ctag + def tag[T](implicit ttag: TypeTag[T]) = ttag + def typeTag[T](implicit ttag: TypeTag[T]) = ttag + def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag + def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag + // Minor variations on identity functions def identity[A](x: A): A = x // @see `conforms` for the implicit version @inline def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world -- TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero` diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala index f0e4c79abf..e396b0695e 100644 --- a/src/library/scala/collection/mutable/ArrayBuilder.scala +++ b/src/library/scala/collection/mutable/ArrayBuilder.scala @@ -33,8 +33,22 @@ object ArrayBuilder { * @tparam T type of the elements for the array builder, with a `ClassManifest` context bound. * @return a new empty array builder. */ - def make[T: ClassManifest](): ArrayBuilder[T] = - implicitly[ClassManifest[T]].newArrayBuilder() + def make[T: ClassManifest](): ArrayBuilder[T] = { + val manifest = implicitly[ClassManifest[T]] + val erasure = manifest.erasure + erasure match { + case java.lang.Byte.TYPE => new ArrayBuilder.ofByte().asInstanceOf[ArrayBuilder[T]] + case java.lang.Short.TYPE => new ArrayBuilder.ofShort().asInstanceOf[ArrayBuilder[T]] + case java.lang.Character.TYPE => new ArrayBuilder.ofChar().asInstanceOf[ArrayBuilder[T]] + case java.lang.Integer.TYPE => new ArrayBuilder.ofInt().asInstanceOf[ArrayBuilder[T]] + case java.lang.Long.TYPE => new ArrayBuilder.ofLong().asInstanceOf[ArrayBuilder[T]] + case java.lang.Float.TYPE => new ArrayBuilder.ofFloat().asInstanceOf[ArrayBuilder[T]] + case java.lang.Double.TYPE => new ArrayBuilder.ofDouble().asInstanceOf[ArrayBuilder[T]] + case java.lang.Boolean.TYPE => new ArrayBuilder.ofBoolean().asInstanceOf[ArrayBuilder[T]] + case java.lang.Void.TYPE => new ArrayBuilder.ofUnit().asInstanceOf[ArrayBuilder[T]] + case _ => new ArrayBuilder.ofRef[T with AnyRef]()(manifest.asInstanceOf[ClassManifest[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]] + } + } /** A class for array builders for arrays of reference types. * diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index 5f7c508181..3e7b8071be 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -39,8 +39,8 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza private def rowBuilder[U]: Builder[U, Array[U]] = Array.newBuilder( - ClassManifest.fromClass( - repr.getClass.getComponentType.getComponentType.asInstanceOf[Predef.Class[U]])) + ClassManifest[U]( + repr.getClass.getComponentType.getComponentType)) override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) { var l = math.min(len, repr.length) @@ -87,8 +87,8 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza } } val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder( - ClassManifest.fromClass( - repr.getClass.getComponentType.asInstanceOf[Predef.Class[Array[U]]])) + ClassManifest[Array[U]]( + repr.getClass.getComponentType)) for (b <- bs) bb += b.result bb.result } @@ -110,7 +110,7 @@ object ArrayOps { override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr) override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](repr) override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()( - ClassManifest.classType[T](repr.getClass.getComponentType)) + ClassManifest[T](repr.getClass.getComponentType)) def length: Int = repr.length def apply(index: Int): T = repr(index) diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala index 4287bac249..fac4eb77bb 100644 --- a/src/library/scala/collection/mutable/WrappedArray.scala +++ b/src/library/scala/collection/mutable/WrappedArray.scala @@ -112,7 +112,7 @@ object WrappedArray { def newBuilder[A]: Builder[A, IndexedSeq[A]] = new ArrayBuffer final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] with Serializable { - lazy val elemManifest = ClassManifest.classType[T](array.getClass.getComponentType) + lazy val elemManifest = ClassManifest[T](array.getClass.getComponentType) def length: Int = array.length def apply(index: Int): T = array(index).asInstanceOf[T] def update(index: Int, elem: T) { array(index) = elem } diff --git a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala index 9771a45a28..fce65468e9 100644 --- a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala +++ b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala @@ -28,7 +28,19 @@ class WrappedArrayBuilder[A](manifest: ClassManifest[A]) extends Builder[A, Wrap private var size: Int = 0 private def mkArray(size: Int): WrappedArray[A] = { - val newelems = manifest.newWrappedArray(size) + val erasure = manifest.erasure + val newelems = erasure match { + case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](size)).asInstanceOf[WrappedArray[A]] + case _ => new WrappedArray.ofRef[A with AnyRef](manifest.newArray(size).asInstanceOf[Array[A with AnyRef]]).asInstanceOf[WrappedArray[A]] + } if (this.size > 0) Array.copy(elems.array, 0, newelems.array, 0, this.size) newelems } diff --git a/src/library/scala/reflect/ArrayTags.scala b/src/library/scala/reflect/ArrayTags.scala new file mode 100644 index 0000000000..8df7fe5f4e --- /dev/null +++ b/src/library/scala/reflect/ArrayTags.scala @@ -0,0 +1,19 @@ +package scala.reflect + +/** An `ArrayTag[T]` is a descriptor that is requested by the compiler every time + * when an array is instantiated, but the element type is unknown at compile time. + * + * Scala library provides a standard implementation of this trait, + * `ClassTag[T]` that explicitly carries the `java.lang.Class` erasure of type T. + * + * However other platforms (e.g. a Scala -> JS crosscompiler) may reimplement this trait as they see fit + * and then expose the implementation via an implicit macro. + */ +@annotation.implicitNotFound(msg = "No ArrayTag available for ${T}") +trait ArrayTag[T] { + /** Produces an `ArrayTag` that knows how to build `Array[Array[T]]` */ + def wrap: ArrayTag[Array[T]] + + /** Produces a new array with element type `T` and length `len` */ + def newArray(len: Int): Array[T] +} \ No newline at end of file diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala deleted file mode 100644 index 37be067614..0000000000 --- a/src/library/scala/reflect/ClassManifest.scala +++ /dev/null @@ -1,263 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -/* [Martin] - * Todo: ClassManifests currently contain all available type arguments. - * That's a waste of cycles if all that's needed is the class. - * We should have instead consider a structure like this: - * - * OptManifest - * / \ - * / \ - * PartialManifest ClassManifest - * \ / - * \ / - * Manifest - * - * where PartialManifest means: generate as much as you can, use NoManifest - * where nothing is known, and - * ClassManifest means: generate exactly the top-level class, and nothing else. - */ -package scala.reflect - -import scala.collection.mutable.{ WrappedArray, ArrayBuilder } -import java.lang.{ Class => jClass } - -/** A `ClassManifest[T]` is an opaque descriptor for type `T`. - * It is used by the compiler to preserve information necessary - * for instantiating `Arrays` in those cases where the element type - * is unknown at compile time. - * - * The type-relation operators make an effort to present a more accurate - * picture than can be realized with erased types, but they should not be - * relied upon to give correct answers. In particular they are likely to - * be wrong when variance is involved or when a subtype has a different - * number of type arguments than a supertype. - */ -trait ClassManifest[T] extends OptManifest[T] with Equals with Serializable { - /** A class representing the type `U` to which `T` would be erased. Note - * that there is no subtyping relationship between `T` and `U`. */ - def erasure: jClass[_] - - /** The Scala type described by this manifest. - */ - lazy val tpe: mirror.Type = mirror.classToType(erasure) - - def symbol: mirror.Symbol = mirror.classToSymbol(erasure) - - private def subtype(sub: jClass[_], sup: jClass[_]): Boolean = { - def loop(left: Set[jClass[_]], seen: Set[jClass[_]]): Boolean = { - left.nonEmpty && { - val next = left.head - val supers = next.getInterfaces.toSet ++ Option(next.getSuperclass) - supers(sup) || { - val xs = left ++ supers filterNot seen - loop(xs - next, seen + next) - } - } - } - loop(Set(sub), Set()) - } - - private def subargs(args1: List[OptManifest[_]], args2: List[OptManifest[_]]) = (args1 corresponds args2) { - // !!! [Martin] this is wrong, need to take variance into account - case (x: ClassManifest[_], y: ClassManifest[_]) => x <:< y - case (x, y) => (x eq NoManifest) && (y eq NoManifest) - } - - /** Tests whether the type represented by this manifest is a subtype - * of the type represented by `that` manifest, subject to the limitations - * described in the header. - */ - def <:<(that: ClassManifest[_]): Boolean = { - // All types which could conform to these types will override <:<. - def cannotMatch = { - import Manifest._ - that.isInstanceOf[AnyValManifest[_]] || (that eq AnyVal) || (that eq Nothing) || (that eq Null) - } - - // This is wrong, and I don't know how it can be made right - // without more development of Manifests, due to arity-defying - // relationships like: - // - // List[String] <: AnyRef - // Map[Int, Int] <: Iterable[(Int, Int)] - // - // Given the manifest for Map[A, B] how do I determine that a - // supertype has single type argument (A, B) ? I don't see how we - // can say whether X <:< Y when type arguments are involved except - // when the erasure is the same, even before considering variance. - !cannotMatch && { - // this part is wrong for not considering variance - if (this.erasure == that.erasure) - subargs(this.typeArguments, that.typeArguments) - // this part is wrong for punting unless the rhs has no type - // arguments, but it's better than a blindfolded pinata swing. - else - that.typeArguments.isEmpty && subtype(this.erasure, that.erasure) - } - } - - /** Tests whether the type represented by this manifest is a supertype - * of the type represented by `that` manifest, subject to the limitations - * described in the header. - */ - def >:>(that: ClassManifest[_]): Boolean = - that <:< this - - def canEqual(other: Any) = other match { - case _: ClassManifest[_] => true - case _ => false - } - - /** Tests whether the type represented by this manifest is equal to - * the type represented by `that` manifest, subject to the limitations - * described in the header. - */ - override def equals(that: Any): Boolean = that match { - case m: ClassManifest[_] => (m canEqual this) && (this.erasure == m.erasure) - case _ => false - } - override def hashCode = this.erasure.## - - protected def arrayClass[T](tp: jClass[_]): jClass[Array[T]] = - java.lang.reflect.Array.newInstance(tp, 0).getClass.asInstanceOf[jClass[Array[T]]] - - def arrayManifest: ClassManifest[Array[T]] = - ClassManifest.classType[Array[T]](arrayClass[T](erasure), this) - - def newArray(len: Int): Array[T] = - java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] - - def newArray2(len: Int): Array[Array[T]] = - java.lang.reflect.Array.newInstance(arrayClass[T](erasure), len) - .asInstanceOf[Array[Array[T]]] - - def newArray3(len: Int): Array[Array[Array[T]]] = - java.lang.reflect.Array.newInstance(arrayClass[Array[T]](arrayClass[T](erasure)), len) - .asInstanceOf[Array[Array[Array[T]]]] - - def newArray4(len: Int): Array[Array[Array[Array[T]]]] = - java.lang.reflect.Array.newInstance(arrayClass[Array[Array[T]]](arrayClass[Array[T]](arrayClass[T](erasure))), len) - .asInstanceOf[Array[Array[Array[Array[T]]]]] - - def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = - java.lang.reflect.Array.newInstance(arrayClass[Array[Array[Array[T]]]](arrayClass[Array[Array[T]]](arrayClass[Array[T]](arrayClass[T](erasure)))), len) - .asInstanceOf[Array[Array[Array[Array[Array[T]]]]]] - - def newWrappedArray(len: Int): WrappedArray[T] = - // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests - new WrappedArray.ofRef[T with AnyRef](newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] - - def newArrayBuilder(): ArrayBuilder[T] = - // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests - new ArrayBuilder.ofRef[T with AnyRef]()(this.asInstanceOf[ClassManifest[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]] - - def typeArguments: List[OptManifest[_]] = List() - - protected def argString = - if (typeArguments.nonEmpty) typeArguments.mkString("[", ", ", "]") - else if (erasure.isArray) "["+ClassManifest.fromClass(erasure.getComponentType)+"]" - else "" -} - -/** The object `ClassManifest` defines factory methods for manifests. - * It is intended for use by the compiler and should not be used in client code. - */ -object ClassManifest { - val Byte = Manifest.Byte - val Short = Manifest.Short - val Char = Manifest.Char - val Int = Manifest.Int - val Long = Manifest.Long - val Float = Manifest.Float - val Double = Manifest.Double - val Boolean = Manifest.Boolean - val Unit = Manifest.Unit - val Any = Manifest.Any - val Object = Manifest.Object - val AnyVal = Manifest.AnyVal - val Nothing = Manifest.Nothing - val Null = Manifest.Null - - def fromClass[T](clazz: jClass[T]): ClassManifest[T] = clazz match { - case java.lang.Byte.TYPE => Byte.asInstanceOf[ClassManifest[T]] - case java.lang.Short.TYPE => Short.asInstanceOf[ClassManifest[T]] - case java.lang.Character.TYPE => Char.asInstanceOf[ClassManifest[T]] - case java.lang.Integer.TYPE => Int.asInstanceOf[ClassManifest[T]] - case java.lang.Long.TYPE => Long.asInstanceOf[ClassManifest[T]] - case java.lang.Float.TYPE => Float.asInstanceOf[ClassManifest[T]] - case java.lang.Double.TYPE => Double.asInstanceOf[ClassManifest[T]] - case java.lang.Boolean.TYPE => Boolean.asInstanceOf[ClassManifest[T]] - case java.lang.Void.TYPE => Unit.asInstanceOf[ClassManifest[T]] - case _ => classType[T with AnyRef](clazz).asInstanceOf[ClassManifest[T]] - } - - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = Manifest.singleType(value) - - /** ClassManifest for the class type `clazz`, where `clazz` is - * a top-level or static class. - * @note This no-prefix, no-arguments case is separate because we - * it's called from ScalaRunTime.boxArray itself. If we - * pass varargs as arrays into this, we get an infinitely recursive call - * to boxArray. (Besides, having a separate case is more efficient) - */ - def classType[T](clazz: jClass[_]): ClassManifest[T] = - new ClassTypeManifest[T](None, clazz, Nil) - - /** ClassManifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class and `args` are its type arguments */ - def classType[T](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) - - /** ClassManifest for the class type `clazz[args]`, where `clazz` is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - def classType[T](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassTypeManifest[T](Some(prefix), clazz, args.toList) - - def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match { - case NoManifest => Object.asInstanceOf[ClassManifest[Array[T]]] - case m: ClassManifest[_] => m.asInstanceOf[ClassManifest[T]].arrayManifest - } - - /** ClassManifest for the abstract type `prefix # name`. `upperBound` is not - * strictly necessary as it could be obtained by reflection. It was - * added so that erasure can be calculated without reflection. */ - def abstractType[T](prefix: OptManifest[_], name: String, clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassManifest[T] { - def erasure = clazz - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } - - /** ClassManifest for the abstract type `prefix # name`. `upperBound` is not - * strictly necessary as it could be obtained by reflection. It was - * added so that erasure can be calculated without reflection. - * todo: remove after next boostrap - */ - def abstractType[T](prefix: OptManifest[_], name: String, upperbound: ClassManifest[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassManifest[T] { - def erasure = upperbound.erasure - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } -} - -/** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class: todo: we should try to merge this with Manifest's class */ -private class ClassTypeManifest[T]( - prefix: Option[OptManifest[_]], - val erasure: jClass[_], - override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T] -{ - override def toString = - (if (prefix.isEmpty) "" else prefix.get.toString+"#") + - (if (erasure.isArray) "Array" else erasure.getName) + - argString -} diff --git a/src/library/scala/reflect/ClassTags.scala b/src/library/scala/reflect/ClassTags.scala new file mode 100644 index 0000000000..2833e7cc8e --- /dev/null +++ b/src/library/scala/reflect/ClassTags.scala @@ -0,0 +1,158 @@ +package scala.reflect + +import java.lang.{ Class => jClass } +import scala.reflect.{ mirror => rm } + +/** A `ClassTag[T]` wraps a Java class, which can be accessed via the `erasure` method. + * This is useful in itself, but also enables very important use case. + * Having this knowledge ClassTag can instantiate `Arrays` + * in those cases where the element type is unknown at compile time. + * Hence, ClassTag[T] conforms to the ArrayTag[T] trait. + */ +// please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` +// class tags, and all tags in general, should be as minimalistic as possible +@annotation.implicitNotFound(msg = "No ClassTag available for ${T}") +abstract case class ClassTag[T](erasure: jClass[_]) extends ArrayTag[T] { + // quick and dirty fix to a deadlock in Predef: + // http://groups.google.com/group/scala-internals/browse_thread/thread/977de028a4e75d6f + // todo. fix that in a sane way + // assert(erasure != null) + + /** A Scala reflection type representing T. + * For ClassTags this representation is lossy (in their case tpe is retrospectively constructed from erasure). + * For TypeTags and GroundTypeTags the representation is almost precise, because it uses reification + * (information is lost only when T refers to non-locatable symbols, which are then reified as free variables). */ + def tpe: rm.Type = rm.classToType(erasure) + + /** A Scala reflection symbol representing T. */ + def symbol: rm.Symbol = rm.classToSymbol(erasure) + + /** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */ + def wrap: ClassTag[Array[T]] = { + val arrayClazz = java.lang.reflect.Array.newInstance(erasure, 0).getClass.asInstanceOf[jClass[Array[T]]] + ClassTag[Array[T]](arrayClazz) + } + + /** Produces a new array with element type `T` and length `len` */ + def newArray(len: Int): Array[T] = + erasure match { + case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] + case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] + case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] + case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] + case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] + case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] + case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] + case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] + case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] + case _ => java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] + } +} + +object ClassTag { + private val ObjectTYPE = classOf[java.lang.Object] + private val StringTYPE = classOf[java.lang.String] + + val Byte : ClassTag[scala.Byte] = new ClassTag[scala.Byte](java.lang.Byte.TYPE) { private def readResolve() = ClassTag.Byte } + val Short : ClassTag[scala.Short] = new ClassTag[scala.Short](java.lang.Short.TYPE) { private def readResolve() = ClassTag.Short } + val Char : ClassTag[scala.Char] = new ClassTag[scala.Char](java.lang.Character.TYPE) { private def readResolve() = ClassTag.Char } + val Int : ClassTag[scala.Int] = new ClassTag[scala.Int](java.lang.Integer.TYPE) { private def readResolve() = ClassTag.Int } + val Long : ClassTag[scala.Long] = new ClassTag[scala.Long](java.lang.Long.TYPE) { private def readResolve() = ClassTag.Long } + val Float : ClassTag[scala.Float] = new ClassTag[scala.Float](java.lang.Float.TYPE) { private def readResolve() = ClassTag.Float } + val Double : ClassTag[scala.Double] = new ClassTag[scala.Double](java.lang.Double.TYPE) { private def readResolve() = ClassTag.Double } + val Boolean : ClassTag[scala.Boolean] = new ClassTag[scala.Boolean](java.lang.Boolean.TYPE) { private def readResolve() = ClassTag.Boolean } + val Unit : ClassTag[scala.Unit] = new ClassTag[scala.Unit](java.lang.Void.TYPE) { private def readResolve() = ClassTag.Unit } + val Any : ClassTag[scala.Any] = new ClassTag[scala.Any](ObjectTYPE) { private def readResolve() = ClassTag.Any } + val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object](ObjectTYPE) { private def readResolve() = ClassTag.Object } + val AnyVal : ClassTag[scala.AnyVal] = new ClassTag[scala.AnyVal](ObjectTYPE) { private def readResolve() = ClassTag.AnyVal } + val AnyRef : ClassTag[scala.AnyRef] = new ClassTag[scala.AnyRef](ObjectTYPE) { private def readResolve() = ClassTag.AnyRef } + val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing](ObjectTYPE) { private def readResolve() = ClassTag.Nothing } + val Null : ClassTag[scala.Null] = new ClassTag[scala.Null](ObjectTYPE) { private def readResolve() = ClassTag.Null } + val String : ClassTag[java.lang.String] = new ClassTag[java.lang.String](StringTYPE) { private def readResolve() = ClassTag.String } + + def apply[T](clazz: jClass[_]): ClassTag[T] = + clazz match { + case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] + case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] + case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] + case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] + case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] + case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] + case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] + case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] + case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] + case ObjectTYPE => ClassTag.Object.asInstanceOf[ClassTag[T]] + case StringTYPE => ClassTag.String.asInstanceOf[ClassTag[T]] + case _ => new ClassTag[T](clazz) {} + } + + def apply[T](tpe: rm.Type): ClassTag[T] = + tpe match { + case rm.ByteTpe => ClassTag.Byte.asInstanceOf[ClassTag[T]] + case rm.ShortTpe => ClassTag.Short.asInstanceOf[ClassTag[T]] + case rm.CharTpe => ClassTag.Char.asInstanceOf[ClassTag[T]] + case rm.IntTpe => ClassTag.Int.asInstanceOf[ClassTag[T]] + case rm.LongTpe => ClassTag.Long.asInstanceOf[ClassTag[T]] + case rm.FloatTpe => ClassTag.Float.asInstanceOf[ClassTag[T]] + case rm.DoubleTpe => ClassTag.Double.asInstanceOf[ClassTag[T]] + case rm.BooleanTpe => ClassTag.Boolean.asInstanceOf[ClassTag[T]] + case rm.UnitTpe => ClassTag.Unit.asInstanceOf[ClassTag[T]] + case rm.AnyTpe => ClassTag.Any.asInstanceOf[ClassTag[T]] + case rm.ObjectTpe => ClassTag.Object.asInstanceOf[ClassTag[T]] + case rm.AnyValTpe => ClassTag.AnyVal.asInstanceOf[ClassTag[T]] + case rm.AnyRefTpe => ClassTag.AnyRef.asInstanceOf[ClassTag[T]] + case rm.NothingTpe => ClassTag.Nothing.asInstanceOf[ClassTag[T]] + case rm.NullTpe => ClassTag.Null.asInstanceOf[ClassTag[T]] + case rm.StringTpe => ClassTag.String.asInstanceOf[ClassTag[T]] + case _ => apply[T](rm.typeToClass(tpe.erasure)) + } + + implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag) +} + +// this class should not be used directly in client code +class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) { + import scala.collection.mutable.{ WrappedArray, ArrayBuilder } + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def <:<(that: ClassManifest[_]): Boolean = ctag.tpe <:< that.tpe + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def >:>(that: ClassManifest[_]): Boolean = that <:< ctag + + @deprecated("Use `wrap` instead", "2.10.0") + def arrayManifest: ClassManifest[Array[T]] = ctag.wrap + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray2(len: Int): Array[Array[T]] = ctag.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray3(len: Int): Array[Array[Array[T]]] = ctag.wrap.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray4(len: Int): Array[Array[Array[Array[T]]]] = ctag.wrap.wrap.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = ctag.wrap.wrap.wrap.wrap.newArray(len) + + @deprecated("Use `@scala.collection.mutable.WrappedArray` object instead", "2.10.0") + def newWrappedArray(len: Int): WrappedArray[T] = + ctag.erasure match { + case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](len)).asInstanceOf[WrappedArray[T]] + case _ => new WrappedArray.ofRef[T with AnyRef](ctag.newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] + } + + @deprecated("Use `@scala.collection.mutable.ArrayBuilder` object instead", "2.10.0") + def newArrayBuilder(): ArrayBuilder[T] = ArrayBuilder.make[T]()(ctag) + + @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.GroundTypeTag` to capture and analyze type arguments", "2.10.0") + def typeArguments: List[OptManifest[_]] = List() +} \ No newline at end of file diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala deleted file mode 100644 index e5df487be9..0000000000 --- a/src/library/scala/reflect/Manifest.scala +++ /dev/null @@ -1,302 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.reflect - -import scala.collection.mutable.{ ArrayBuilder, WrappedArray } -import mirror._ - -/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use - * is to give access to the erasure of the type as a `Class` instance, as - * is necessary for the creation of native `Arrays` if the class is not - * known at compile time. - * - * The type-relation operators `<:<` and `=:=` should be considered - * approximations only, as there are numerous aspects of type conformance - * which are not yet adequately represented in manifests. - * - * Example usages: -{{{ - def arr[T] = new Array[T](0) // does not compile - def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles - def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding - - // Methods manifest, classManifest, and optManifest are in [[scala.Predef]]. - def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U] - isApproxSubType[List[String], List[AnyRef]] // true - isApproxSubType[List[String], List[Int]] // false - - def methods[T: ClassManifest] = classManifest[T].erasure.getMethods - def retType[T: ClassManifest](name: String) = - methods[T] find (_.getName == name) map (_.getGenericReturnType) - - retType[Map[_, _]]("values") // Some(scala.collection.Iterable) -}}} - * - */ -@annotation.implicitNotFound(msg = "No Manifest available for ${T}.") -trait Manifest[T] extends ClassManifest[T] with Equals { - override def typeArguments: List[Manifest[_]] = Nil - - override def arrayManifest: Manifest[Array[T]] = - Manifest.classType[Array[T]](arrayClass[T](erasure), this) - - override def canEqual(that: Any): Boolean = that match { - case _: Manifest[_] => true - case _ => false - } - /** Note: testing for erasure here is important, as it is many times - * faster than <:< and rules out most comparisons. - */ - override def equals(that: Any): Boolean = that match { - case m: Manifest[_] => (m canEqual this) && (this.erasure == m.erasure) && (this <:< m) && (m <:< this) - case _ => false - } - override def hashCode = this.erasure.## -} - -abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals { - override def <:<(that: ClassManifest[_]): Boolean = - (that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal) - override def canEqual(other: Any) = other match { - case _: AnyValManifest[_] => true - case _ => false - } - override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] - override val hashCode = System.identityHashCode(this) -} - -/** The object `Manifest` defines factory methods for manifests. - * It is intended for use by the compiler and should not be used - * in client code. - */ -object Manifest { - import mirror.{ definitions => mdefs } - - def valueManifests: List[AnyValManifest[_]] = - List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit) - - val Byte: AnyValManifest[Byte] = new AnyValManifest[scala.Byte]("Byte") { - def erasure = java.lang.Byte.TYPE - override def newArray(len: Int): Array[Byte] = new Array[Byte](len) - override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len)) - override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte() - private def readResolve(): Any = Manifest.Byte - } - - val Short: AnyValManifest[Short] = new AnyValManifest[scala.Short]("Short") { - def erasure = java.lang.Short.TYPE - override def newArray(len: Int): Array[Short] = new Array[Short](len) - override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len)) - override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort() - private def readResolve(): Any = Manifest.Short - } - - val Char: AnyValManifest[Char] = new AnyValManifest[scala.Char]("Char") { - def erasure = java.lang.Character.TYPE - override def newArray(len: Int): Array[Char] = new Array[Char](len) - override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len)) - override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar() - private def readResolve(): Any = Manifest.Char - } - - val Int: AnyValManifest[Int] = new AnyValManifest[scala.Int]("Int") { - def erasure = java.lang.Integer.TYPE - override def newArray(len: Int): Array[Int] = new Array[Int](len) - override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len)) - override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt() - private def readResolve(): Any = Manifest.Int - } - - val Long: AnyValManifest[Long] = new AnyValManifest[scala.Long]("Long") { - def erasure = java.lang.Long.TYPE - override def newArray(len: Int): Array[Long] = new Array[Long](len) - override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len)) - override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong() - private def readResolve(): Any = Manifest.Long - } - - val Float: AnyValManifest[Float] = new AnyValManifest[scala.Float]("Float") { - def erasure = java.lang.Float.TYPE - override def newArray(len: Int): Array[Float] = new Array[Float](len) - override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len)) - override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat() - private def readResolve(): Any = Manifest.Float - } - - val Double: AnyValManifest[Double] = new AnyValManifest[scala.Double]("Double") { - def erasure = java.lang.Double.TYPE - override def newArray(len: Int): Array[Double] = new Array[Double](len) - override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len)) - override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble() - private def readResolve(): Any = Manifest.Double - } - - val Boolean: AnyValManifest[Boolean] = new AnyValManifest[scala.Boolean]("Boolean") { - def erasure = java.lang.Boolean.TYPE - override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) - override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len)) - override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean() - private def readResolve(): Any = Manifest.Boolean - } - - val Unit: AnyValManifest[Unit] = new AnyValManifest[scala.Unit]("Unit") { - def erasure = java.lang.Void.TYPE - override def newArray(len: Int): Array[Unit] = new Array[Unit](len) - override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len)) - override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit() - private def readResolve(): Any = Manifest.Unit - } - - val Any: Manifest[scala.Any] = new PhantomManifest[scala.Any]("Any") { - override def symbol = mdefs.AnyClass - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) - private def readResolve(): Any = Manifest.Any - } - - val Object: Manifest[java.lang.Object] = new PhantomManifest[java.lang.Object]("Object") { - override def symbol = mdefs.ObjectClass - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.Object - } - - val AnyVal: Manifest[scala.AnyVal] = new PhantomManifest[scala.AnyVal]("AnyVal") { - override def symbol = mdefs.AnyValClass - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.AnyVal - } - - val Null: Manifest[scala.Null] = new PhantomManifest[scala.Null]("Null") { - override def symbol = mdefs.NullClass - override def <:<(that: ClassManifest[_]): Boolean = - (that ne null) && (that ne Nothing) && !(that <:< AnyVal) - private def readResolve(): Any = Manifest.Null - } - - val Nothing: Manifest[scala.Nothing] = new PhantomManifest[scala.Nothing]("Nothing") { - override def symbol = mdefs.NothingClass - override def <:<(that: ClassManifest[_]): Boolean = (that ne null) - private def readResolve(): Any = Manifest.Nothing - } - - private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] { - lazy val erasure = value.getClass - override lazy val symbol = InstanceRefSymbol(value) // todo: change to freevar - override lazy val tpe = mirror.SingleType(mirror.NoPrefix, symbol) - override lazy val toString = value.toString + ".type" - } - - /** Manifest for the singleton type `value.type`. */ - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = - new SingletonTypeManifest[T](value) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. - * @note This no-prefix, no-arguments case is separate because we - * it's called from ScalaRunTime.boxArray itself. If we - * pass varargs as arrays into this, we get an infinitely recursive call - * to boxArray. (Besides, having a separate case is more efficient) - */ - def classType[T](clazz: Predef.Class[_]): Manifest[T] = - new ClassTypeManifest[T](None, clazz, Nil) - - /** Manifest for the class type `clazz`, where `clazz` is - * a top-level or static class and args are its type arguments. */ - def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](Some(prefix), clazz, args.toList) - - /** Phantom types have no runtime representation; they all erase to Object, - * but the Symbol preserves their identity. - */ - private abstract class PhantomManifest[T](override val toString: String) extends ClassTypeManifest[T](None, classOf[java.lang.Object], Nil) { - override lazy val tpe = namedType(mirror.NoPrefix, symbol, Nil) - override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] - override val hashCode = System.identityHashCode(this) - } - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. */ - private class ClassTypeManifest[T](prefix: Option[Manifest[_]], - val erasure: Predef.Class[_], - override val typeArguments: List[Manifest[_]]) extends Manifest[T] { - - override lazy val tpe = { - val pre = prefix match { - case Some(pm) => pm.tpe - case None => symbol.owner.thisPrefix - } - namedType(pre, symbol, typeArguments map (_.tpe)) - } - - override def toString = - (if (prefix.isEmpty) "" else prefix.get.toString+"#") + - (if (erasure.isArray) "Array" else erasure.getName) + - argString - } - - def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = - arg.asInstanceOf[Manifest[T]].arrayManifest - - /** Manifest for the abstract type `prefix # name'. `upperBound` is not - * strictly necessary as it could be obtained by reflection. It was - * added so that erasure can be calculated without reflection. */ - def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new Manifest[T] { - def erasure = upperBound - override lazy val tpe = namedType(prefix.tpe, prefix.tpe.member(newTypeName(name)), args map (_.tpe) toList) - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } - - /** Manifest for the unknown type `_ >: L <: U` in an existential. - */ - def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = - new Manifest[T] { - def erasure = upperBound.erasure - override lazy val tpe = mirror.TypeBounds(lowerBound.tpe, upperBound.tpe) - override def toString = - "_" + - (if (lowerBound eq Nothing) "" else " >: "+lowerBound) + - (if (upperBound eq Nothing) "" else " <: "+upperBound) - } - - /** Manifest for the intersection type `parents_0 with ... with parents_n'. */ - def intersectionType[T](parents: Manifest[_]*): Manifest[T] = - new Manifest[T] { - def erasure = parents.head.erasure - override lazy val tpe = mirror.RefinedType((parents map (_.tpe)).toList, newScope) - override def toString = parents.mkString(" with ") - } - - /** A generic manifest factory from a reflect.Type. Except where - * mandated by performance considerations, we should replace most - * other manifest factories by this one. There's just one thing - * that needs to be done first: A Manifest's type can refer - * to type variables that are controlled by manifests. In that - * case the reified type needs to contain the type passed in the manifest - * instead of the reference to the manifest. Note that splicing manifests - * into manfifests is completely analogous to splicing code blocks into - * code blocks. Manifest[T] and Code[T] are really the same thing, only one - * works for types, the other for trees. - * Another complication is that once we generate manifests from types, we really - * should have reflection as a standard component shipped with the standard library, - * instead of in scala-compiler.jar. - */ - def apply[T](_tpe: mirror.Type): Manifest[T] = new Manifest[T] { - override def symbol = _tpe.typeSymbol - override lazy val tpe = _tpe - override def erasure = mirror.typeToClass(_tpe.erasedType) - override def toString = _tpe.toString - } -} diff --git a/src/library/scala/reflect/NoManifest.scala b/src/library/scala/reflect/NoManifest.scala deleted file mode 100644 index 191e46ae39..0000000000 --- a/src/library/scala/reflect/NoManifest.scala +++ /dev/null @@ -1,15 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.reflect - -/** One of the branches of an [[scala.reflect.OptManifest]]. - */ -object NoManifest extends OptManifest[Nothing] with Serializable { - override def toString = "" -} diff --git a/src/library/scala/reflect/OptManifest.scala b/src/library/scala/reflect/OptManifest.scala deleted file mode 100644 index 2a955deb2c..0000000000 --- a/src/library/scala/reflect/OptManifest.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.reflect - -/** A `OptManifest[T]` is an optional [[scala.reflect.Manifest]]. - * - * It is either a `Manifest` or the value `NoManifest`. - * - * @author Martin Odersky - */ -trait OptManifest[+T] extends Serializable diff --git a/src/library/scala/reflect/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala index 510f0819c6..1be46eac55 100644 --- a/src/library/scala/reflect/ReflectionUtils.scala +++ b/src/library/scala/reflect/ReflectionUtils.scala @@ -27,7 +27,17 @@ object ReflectionUtils { case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex)) } - def singletonInstance(className: String, cl: ClassLoader = getClass.getClassLoader): AnyRef = { + def defaultReflectionClassLoader() = { + // say no to non-determinism of mirror classloaders + // default classloader will be instantiated using current system classloader + // if you wish so, you can rebind it by setting ``mirror.classLoader'' to whatever is necessary +// val cl = Thread.currentThread.getContextClassLoader +// if (cl == null) getClass.getClassLoader else cl +// cl + getClass.getClassLoader + } + + def singletonInstance(cl: ClassLoader, className: String): AnyRef = { val name = if (className endsWith "$") className else className + "$" val clazz = java.lang.Class.forName(name, true, cl) val singleton = clazz getField "MODULE$" get null @@ -35,7 +45,17 @@ object ReflectionUtils { } // Retrieves the MODULE$ field for the given class name. - def singletonInstanceOpt(className: String, cl: ClassLoader = getClass.getClassLoader): Option[AnyRef] = - try Some(singletonInstance(className, cl)) + def singletonInstanceOpt(cl: ClassLoader, className: String): Option[AnyRef] = + try Some(singletonInstance(cl, className)) + catch { case _: ClassNotFoundException => None } + + def invokeFactory(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): AnyRef = { + val singleton = singletonInstance(cl, className) + val method = singleton.getClass.getMethod(methodName, classOf[ClassLoader]) + method.invoke(singleton, args: _*) + } + + def invokeFactoryOpt(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): Option[AnyRef] = + try Some(invokeFactory(cl, className, methodName, args: _*)) catch { case _: ClassNotFoundException => None } } diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala new file mode 100644 index 0000000000..991feb3bac --- /dev/null +++ b/src/library/scala/reflect/TagMaterialization.scala @@ -0,0 +1,154 @@ +package scala.reflect + +import api.Universe +import makro.Context + +// todo. unfortunately, current type inferencer doesn't infer type parameters of implicit values +// this means that during macro expansion these macros will get Nothing instead of real T +// Oh how much I'd love to implement this now, but I have to postpone this until we have a solution for type inference + +/** This object is required by the compiler and should not be used in client code. */ +object TagMaterialization { + def materializeClassTag[T: c.TypeTag](c: Context): c.Expr[ClassTag[T]] = { + import c.mirror._ + val tpe = implicitly[c.TypeTag[T]].tpe + c.materializeClassTag(tpe) + } + + def materializeTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.TypeTag[T]] = { + import c.mirror._ + val tpe = implicitly[c.TypeTag[T]].tpe + c.materializeTypeTag(tpe, requireGroundTypeTag = false) + } + + def materializeGroundTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.GroundTypeTag[T]] = { + import c.mirror._ + val tpe = implicitly[c.TypeTag[T]].tpe + c.materializeTypeTag(tpe, requireGroundTypeTag = true) + } + + private implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils + + private abstract class Utils { + val c: Context + + import c.mirror._ + import definitions._ + + val coreTags = Map( + ByteClass.asType -> newTermName("Byte"), + ShortClass.asType -> newTermName("Short"), + CharClass.asType -> newTermName("Char"), + IntClass.asType -> newTermName("Int"), + LongClass.asType -> newTermName("Long"), + FloatClass.asType -> newTermName("Float"), + DoubleClass.asType -> newTermName("Double"), + BooleanClass.asType -> newTermName("Boolean"), + UnitClass.asType -> newTermName("Unit"), + AnyClass.asType -> newTermName("Any"), + ObjectClass.asType -> newTermName("Object"), + AnyValClass.asType -> newTermName("AnyVal"), + AnyRefClass.asType -> newTermName("AnyRef"), + NothingClass.asType -> newTermName("Nothing"), + NullClass.asType -> newTermName("Null")) + + val ReflectPackage = staticModule("scala.reflect.package") + val Reflect_mirror = selectTerm(ReflectPackage, "mirror") + val ClassTagClass = staticClass("scala.reflect.ClassTag") + val ClassTagErasure = selectTerm(ClassTagClass, "erasure") + val ClassTagModule = staticModule("scala.reflect.ClassTag") + val TypeTagsClass = staticClass("scala.reflect.api.TypeTags") + val TypeTagClass = selectType(TypeTagsClass, "TypeTag") + val TypeTagTpe = selectTerm(TypeTagClass, "tpe") + val TypeTagModule = selectTerm(TypeTagsClass, "TypeTag") + val GroundTypeTagClass = selectType(TypeTagsClass, "GroundTypeTag") + val GroundTypeTagModule = selectTerm(TypeTagsClass, "GroundTypeTag") + + def materializeClassTag(tpe: Type): Tree = { + val prefix = gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror) + materializeClassTag(prefix, tpe) + } + + def materializeClassTag(prefix: Tree, tpe: Type): Tree = { + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, TypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == GroundTypeTagModule)) + typetagInScope match { + case success if !success.isEmpty && !typetagIsSynthetic(success) => + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(Select(typetagInScope, newTermName("tpe")))) + case _ => + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Ident(ClassTagModule), coreTags(coreTpe)) + case _ => + if (tpe.typeSymbol == ArrayClass) { + val componentTpe = tpe.typeArguments(0) + val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe))) + val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe) + Select(componentTag, newTermName("wrap")) + } else { + // [Eugene] what's the intended behavior? there's no spec on ClassManifests + // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? + // if its the latter, what should be the result of tagging Array[T] where T <: Int? + if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type") + val erasure = + if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct? + else tpe.erasure.normalize // necessary to deal with erasures of HK types + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure))))) + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + } + + def materializeTypeTag(tpe: Type, requireGroundTypeTag: Boolean): Tree = { + def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix + materializeTypeTag(prefix, tpe, requireGroundTypeTag) + } + + def materializeTypeTag(prefix: Tree, tpe: Type, requireGroundTypeTag: Boolean): Tree = { + val tagModule = if (requireGroundTypeTag) GroundTypeTagModule else TypeTagModule + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Select(prefix, tagModule.name), coreTags(coreTpe)) + case _ => + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireGroundTypeTag = requireGroundTypeTag) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + val ex1 = ex + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case c.ReificationError(pos, msg) => + c.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case c.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + + private def fail(reason: Any): Nothing = { + val Apply(TypeApply(fun, List(tpeTree)), _) = c.macroApplication + val tpe = tpeTree.tpe + val PolyType(_, MethodType(_, tagTpe)) = fun.tpe + val tagModule = tagTpe.typeSymbol.companionSymbol + if (c.compilerSettings.contains("-Xlog-implicits")) + c.echo(c.enclosingPosition, "cannot materialize " + tagModule.name + "[" + tpe + "] because:\n" + reason) + c.abort(c.enclosingPosition, "No %s available for %s".format(tagModule.name, tpe)) + } + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Attachments.scala b/src/library/scala/reflect/api/Attachments.scala new file mode 100644 index 0000000000..dfd362ebe0 --- /dev/null +++ b/src/library/scala/reflect/api/Attachments.scala @@ -0,0 +1,16 @@ +package scala.reflect +package api + +/** Attachment is a generalisation of Position. + * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads. + * + * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree + * imposing an unnecessary memory tax because of something that will not be used in most cases. + */ +trait Attachment { + /** Gets the underlying position */ + def pos: Position + + /** Creates a copy of this attachment with its position updated */ + def withPos(pos: Position): Attachment +} diff --git a/src/library/scala/reflect/api/ClassLoaders.scala b/src/library/scala/reflect/api/ClassLoaders.scala new file mode 100644 index 0000000000..7be402d3df --- /dev/null +++ b/src/library/scala/reflect/api/ClassLoaders.scala @@ -0,0 +1,16 @@ +package scala.reflect +package api + +trait ClassLoaders { self: Universe => + + /** The symbol corresponding to the globally accessible class with the + * given fully qualified name `fullName`. + */ + def staticClass(fullName: String): Symbol + + /** The symbol corresponding to the globally accessible object with the + * given fully qualified name `fullName`. + */ + def staticModule(fullName: String): Symbol + +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Exprs.scala b/src/library/scala/reflect/api/Exprs.scala new file mode 100644 index 0000000000..8c3f12783b --- /dev/null +++ b/src/library/scala/reflect/api/Exprs.scala @@ -0,0 +1,48 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package api + +trait Exprs { self: Universe => + + /** An expression tree tagged with its type */ + case class Expr[+T: TypeTag](tree: Tree) { + def tpe: Type = implicitly[TypeTag[T]].tpe + def eval: T = mkToolBox().runExpr(tree).asInstanceOf[T] + lazy val value: T = eval + override def toString = "Expr["+tpe+"]("+tree+")" + } + + // [Eugene] had to move this to the companion of Tree to make stuff compile. weirdo! +// object Expr { +// // would be great if in future this generated an Expr[Magic] +// // where Magic is a magic untyped type that propagates through the entire quasiquote +// // and turns off typechecking whenever it's involved +// // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked +// // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo +// implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree) +// implicit def expr2tree(expr: Expr[_]): Tree = expr.tree +// +// // [Eugene] good idea? +// implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr +// implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree +// } + + // [Eugene] even weirder - implicits didn't feel at home in Trees :( + + // would be great if in future this generated an Expr[Magic] + // where Magic is a magic untyped type that propagates through the entire quasiquote + // and turns off typechecking whenever it's involved + // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked + // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo + implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree)(TypeTag.Nothing) + implicit def expr2tree(expr: Expr[_]): Tree = expr.tree + + // [Eugene] good idea? + implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr + implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree +} + diff --git a/src/library/scala/reflect/api/FreeVars.scala b/src/library/scala/reflect/api/FreeVars.scala new file mode 100644 index 0000000000..0bef099a55 --- /dev/null +++ b/src/library/scala/reflect/api/FreeVars.scala @@ -0,0 +1,42 @@ +package scala.reflect +package api + +trait FreeVars { + self: Universe => + + /** Represents a free term captured by reification. + */ + type FreeTerm <: Symbol + + val FreeTerm: FreeTermExtractor + + abstract class FreeTermExtractor { + def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] + } + + /** Extracts free terms from a tree that is reified or contains reified subtrees. + */ + def freeTerms(tree: Tree): List[FreeTerm] + + /** Represents a free type captured by reification. + */ + type FreeType <: Symbol + + val FreeType: FreeTypeExtractor + + abstract class FreeTypeExtractor { + def unapply(freeType: FreeType): Option[(TypeName, Type, String)] + } + + /** Extracts free types from a tree that is reified or contains reified subtrees. + */ + def freeTypes(tree: Tree): List[FreeType] + + /** Substitutes free types in a reified tree. + */ + def substituteFreeTypes(tree: Tree, subs: Map[FreeType, Type]): Tree + + /** Substitutes free types in a reified type. + */ + def substituteFreeTypes(tpe: Type, subs: Map[FreeType, Type]): Type +} diff --git a/src/library/scala/reflect/api/Importers.scala b/src/library/scala/reflect/api/Importers.scala new file mode 100644 index 0000000000..1d8890b7db --- /dev/null +++ b/src/library/scala/reflect/api/Importers.scala @@ -0,0 +1,19 @@ +package scala.reflect +package api + +trait Importers { self: Universe => + + def mkImporter(from0: Universe): Importer { val from: from0.type } + + trait Importer { + val from: Universe + + val reverse: from.Importer { val from: self.type } + + def importSymbol(sym: from.Symbol): Symbol + + def importType(tpe: from.Type): Type + + def importTree(tree: from.Tree): Tree + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Mirror.scala b/src/library/scala/reflect/api/Mirror.scala index cea9e1a37d..ed8ead7aaf 100644 --- a/src/library/scala/reflect/api/Mirror.scala +++ b/src/library/scala/reflect/api/Mirror.scala @@ -5,7 +5,22 @@ package api * runtime entities such as class names and object instances * with a reflexive universe. */ -trait Mirror extends Universe with RuntimeTypes with TreeBuildUtil { +trait Mirror extends Universe { + + /** Class loader that is a mastermind behind the reflexive mirror. + * + * By default it is set to system classloader (more precisely, to the classloader that loads the `scala.reflect.package` class). + * However, sometimes it is useful to have a mirror services by a custom classloader. + * + * There are two ways to customize the `classLoader`: + * 1) Create a new mirror using the `scala.reflect.mkMirror(classLoader: ClassLoader)` method + * 2) Set `classLoader` to the new value + * + * The first, immutable, way should be strongly preferred in most situation. + * However sometimes it is necessary to migrate the default reflexive mirror (`scala.reflect.mirror`) to a new classloader. + * In that and only that case, use the setter, but be very careful not to introduce inconsistencies. + */ + var classLoader: ClassLoader /** The Scala class symbol that has given fully qualified name * @param name The fully qualified name of the class to be returned diff --git a/src/library/scala/reflect/api/Positions.scala b/src/library/scala/reflect/api/Positions.scala index 91f1081b4d..8f01e0ced1 100644 --- a/src/library/scala/reflect/api/Positions.scala +++ b/src/library/scala/reflect/api/Positions.scala @@ -1,21 +1,202 @@ package scala.reflect package api -trait Positions { self: Universe => - /** TreeAnnotation is a generalisation of Position. - * - * TreeAnnotation cannot be an upperbound of Position since the corresponding classes - * must live outside of the universe for backwards compatibility (see scala.tools.nsc.util.Position). - * Thus, represent subtyping as coercions. - * - * Typically, positionToAnnotation is the identity, and annotationToPosition returns annot.pos - */ - type TreeAnnotation // <: { def pos: Position } - def NoTreeAnnotation: TreeAnnotation - implicit def positionToAnnotation(pos: Position): TreeAnnotation // = pos - def annotationToPosition(annot: TreeAnnotation): Position // = annot.pos - def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = () // check that annot may overwrite tree.annot - - type Position // <: TreeAnnotation, but not practical to enforce this (would require moving Position, SourceFile, Reporter,... into the universe) +trait Positions { + self: Universe => + + // [Eugene] in quite a lot of situations (mostly related to error reporting) we need positions in the API + // however it seems that neither runtime compilation, nor macros need facilities to create positions from scratch + // both emit ASTs, which can be automatically transformed into synthetic sources and assigned with synthetic positions + // hence I added possibilities to inspect everything we can, but add any position factories + // this simplified a lot of things, the biggest of them is that we don't need to expose SourceFile/AbstractFile + type Position <: scala.reflect.api.Position val NoPosition: Position -} \ No newline at end of file + + /** 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 + * Otherwise returns default position. + */ + def wrappingPos(default: Position, trees: List[Tree]): Position + + /** A position that wraps the non-empty set of trees. + * The point of the wrapping position is the point of the first trees' position. + * If all some the trees are non-synthetic, returns a range position enclosing the non-synthetic trees + * 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]) + + /** Assigns a given position to all position-less nodes of a given AST. + */ + def atPos[T <: Tree](pos: Position)(tree: T): T +} + +/** The Position class and its subclasses represent positions of ASTs and symbols. + * Except for NoPosition and FakePos, every position refers to a SourceFile + * and to an offset in the sourcefile (its `point`). For batch compilation, + * that's all. For interactive IDE's there are also RangePositions + * and TransparentPositions. A RangePosition indicates a start and an end + * in addition to its point. TransparentPositions are a subclass of RangePositions. + * Range positions that are not transparent are called opaque. + * Trees with RangePositions need to satisfy the following invariants. + * + * INV1: A tree with an offset position never contains a child + * with a range position + * INV2: If the child of a tree with a range position also has a range position, + * then the child's range is contained in the parent's range. + * INV3: Opaque range positions of children of the same node are non-overlapping + * (this means their overlap is at most a single point). + * + * The following tests are useful on positions: + * + * pos.isDefined true if position is not a NoPosition nor a FakePosition + * pos.isRange true if position is a range + * pos.isOpaqueRange true if position is an opaque range + * + * The following accessor methods are provided: + * + * pos.source The source file of the position, which must be defined + * pos.point The offset of the position's point, which must be defined + * pos.start The start of the position, which must be a range + * pos.end The end of the position, which must be a range + * + * There are also convenience methods, such as + * + * pos.startOrPoint + * pos.endOrPoint + * pos.pointOrElse(default) + * + * These are less strict about the kind of position on which they can be applied. + * + * The following conversion methods are often used: + * + * pos.focus converts a range position to an offset position, keeping its point; + * returns all other positions unchanged. + * pos.makeTransparent converts an opaque range position into a transparent one. + * returns all other positions unchanged. + */ +trait Position extends Attachment { + + /** Java file corresponding to the source file of this position. + */ + def fileInfo: java.io.File + + /** Content of the source file that contains this position. + */ + def fileContent: Array[Char] + + /** Is this position neither a NoPosition nor a FakePosition? + * If isDefined is true, offset and source are both defined. + */ + def isDefined: Boolean + + /** Is this position a transparent position? */ + def isTransparent: Boolean + + /** Is this position a range position? */ + def isRange: Boolean + + /** Is this position a non-transparent range position? */ + def isOpaqueRange: Boolean + + /** if opaque range, make this position transparent */ + def makeTransparent: Position + + /** The start of the position's range, error if not a range position */ + def start: Int + + /** The start of the position's range, or point if not a range position */ + def startOrPoint: Int + + /** The point (where the ^ is) of the position */ + def point: Int + + /** The point (where the ^ is) of the position, or else `default` if undefined */ + def pointOrElse(default: Int): Int + + /** The end of the position's range, error if not a range position */ + def end: Int + + /** The end of the position's range, or point if not a range position */ + def endOrPoint: Int + + /** The same position with a different start value (if a range) */ + def withStart(off: Int): Position + + /** The same position with a different end value (if a range) */ + def withEnd(off: Int): Position + + /** The same position with a different point value (if a range or offset) */ + def withPoint(off: Int): Position + + /** If this is a range, the union with the other range, with the point of this position. + * Otherwise, this position + */ + def union(pos: Position): Position + + /** If this is a range position, the offset position of its start. + * Otherwise the position itself + */ + def focusStart: Position + + /** If this is a range position, the offset position of its point. + * Otherwise the position itself + */ + def focus: Position + + /** If this is a range position, the offset position of its end. + * Otherwise the position itself + */ + def focusEnd: Position + + /** Does this position include the given position `pos`. + * This holds if `this` is a range position and its range [start..end] + * is the same or covers the range of the given position, which may or may not be a range position. + */ + def includes(pos: Position): Boolean + + /** Does this position properly include the given position `pos` ("properly" meaning their + * ranges are not the same)? + */ + def properlyIncludes(pos: Position): Boolean + + /** Does this position precede that position? + * This holds if both positions are defined and the end point of this position + * is not larger than the start point of the given position. + */ + def precedes(pos: Position): Boolean + + /** Does this position properly precede the given position `pos` ("properly" meaning their ranges + * do not share a common point). + */ + def properlyPrecedes(pos: Position): Boolean + + /** Does this position overlap with that position? + * This holds if both positions are ranges and there is an interval of + * non-zero length that is shared by both position ranges. + */ + def overlaps(pos: Position): Boolean + + /** Does this position cover the same range as that position? + * Holds only if both position are ranges + */ + def sameRange(pos: Position): Boolean + + def line: Int + + def column: Int + + /** Convert this to a position around `point` that spans a single source line */ + def toSingleLine: Position + + def lineContent: String + + def show: String +} diff --git a/src/library/scala/reflect/api/Reporters.scala b/src/library/scala/reflect/api/Reporters.scala new file mode 100644 index 0000000000..b7428e1599 --- /dev/null +++ b/src/library/scala/reflect/api/Reporters.scala @@ -0,0 +1,65 @@ +package scala.reflect +package api + +trait Reporters { self: Universe => + + trait Reporter { + object severity extends Enumeration + class Severity(val id: Int) extends severity.Value { + var count: Int = 0 + override def toString() = this match { + case INFO => "INFO" + case WARNING => "WARNING" + case ERROR => "ERROR" + case _ => "" + } + } + val INFO = new Severity(0) + val WARNING = new Severity(1) + val ERROR = new Severity(2) + + case class Info(val pos: Position, val msg: String, val severity: Severity) + val infos = new collection.mutable.LinkedHashSet[Info] + + /** Handles incoming info */ + def log(pos: Position, msg: String, severity: Severity) { + infos += new Info(pos, msg, severity) + severity.count += 1 + display(infos.last) + } + + /** Displays incoming info */ + def display(info: Info): Unit + + /** Services a request to drop into interactive mode */ + def interactive(): Unit + + /** Refreshes the UI */ + def flush(): Unit = {} + + /** Resets the reporter */ + def reset(): Unit = { + INFO.count = 0 + WARNING.count = 0 + ERROR.count = 0 + infos.clear() + } + } + + class SilentReporter extends Reporter { + def display(info: Info) {} + def interactive() {} + } + + /** Creates a UI-less reporter that simply accumulates all the messages + */ + def mkSilentReporter(): Reporter = new SilentReporter() + + /** Creates a reporter that prints messages to the console according to the settings. + * + * ``minSeverity'' determines minimum severity of the messages to be printed. + * 0 stands for INFO, 1 stands for WARNING and 2 stands for ERROR. + */ + // todo. untangle warningsAsErrors from Reporters. I don't feel like moving this flag here! + def mkConsoleReporter(minSeverity: Int = 1): Reporter +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/RuntimeTypes.scala b/src/library/scala/reflect/api/RuntimeTypes.scala deleted file mode 100644 index f58b328868..0000000000 --- a/src/library/scala/reflect/api/RuntimeTypes.scala +++ /dev/null @@ -1,20 +0,0 @@ -package scala.reflect -package api - -/** A mirror establishes connections of - * runtime entities such as class names and object instances - * with a refexive universe. - */ -private[reflect] trait RuntimeTypes extends Universe { - - type InstanceRefSymbol >: Null <: Symbol - - val InstanceRefSymbol: InstanceRefSymbolExtractor - - private[reflect] def namedType(pre: Type, sym: Symbol, args: List[Type]): Type - - abstract class InstanceRefSymbolExtractor { - def apply(value: AnyRef): InstanceRefSymbol - def unapply(tpe: InstanceRefSymbol): Option[AnyRef] - } -} diff --git a/src/library/scala/reflect/api/Scopes.scala b/src/library/scala/reflect/api/Scopes.scala index d4e4e24f29..4a5702eadc 100755 --- a/src/library/scala/reflect/api/Scopes.scala +++ b/src/library/scala/reflect/api/Scopes.scala @@ -5,7 +5,12 @@ trait Scopes { self: Universe => type Scope <: Iterable[Symbol] - def newScope(): Scope -} + /** Create a new scope */ + def newScope: Scope + /** Create a new scope nested in another one with which it shares its elements */ + def newNestedScope(outer: Scope): Scope + /** Create a new scope with given initial elements */ + def newScopeWith(elems: Symbol*): Scope +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala index c3d989f971..b4fedbe055 100755 --- a/src/library/scala/reflect/api/StandardDefinitions.scala +++ b/src/library/scala/reflect/api/StandardDefinitions.scala @@ -8,6 +8,23 @@ package api trait StandardDefinitions { 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 ObjectTpe: Type + val AnyValTpe: Type + val AnyRefTpe: Type + val NothingTpe: Type + val NullTpe: Type + val StringTpe: Type + val definitions: AbsDefinitions abstract class AbsDefinitions { @@ -15,7 +32,11 @@ trait StandardDefinitions { self: Universe => def RootPackage: Symbol def RootClass: Symbol def EmptyPackage: Symbol + def EmptyPackageClass: Symbol def ScalaPackage: Symbol + def ScalaPackageClass: Symbol + def JavaLangPackage: Symbol + def JavaLangPackageClass: Symbol // top types def AnyClass : Symbol @@ -37,6 +58,7 @@ trait StandardDefinitions { self: Universe => def FloatClass : Symbol def DoubleClass : Symbol def BooleanClass: Symbol + def ScalaPrimitiveValueClasses: List[Symbol] // fundamental reference classes def SymbolClass : Symbol @@ -48,13 +70,57 @@ trait StandardDefinitions { self: Universe => def ProductClass : Array[Symbol] def FunctionClass : Array[Symbol] - // fundamental modules + // Option classes + def OptionClass: Symbol + def SomeClass: Symbol + def NoneModule: Symbol + def SomeModule: Symbol + + // collections classes + def ConsClass: Symbol + def IterableClass: Symbol + def IteratorClass: Symbol + def ListClass: Symbol + def SeqClass: Symbol + def StringBuilderClass: Symbol + def TraversableClass: Symbol + + // collections modules def PredefModule: Symbol + def ListModule: Symbol + def List_apply: Symbol + def NilModule: Symbol + def SeqModule: Symbol + def IteratorModule: Symbol + def Iterator_apply: Symbol + + // arrays and their members + def ArrayModule: Symbol + def ArrayModule_overloadedApply: Symbol + def ArrayClass: Symbol + def Array_apply: Symbol + def Array_update: Symbol + def Array_length: Symbol + def Array_clone: Symbol + + // special parameter types + def ByNameParamClass: Symbol + def JavaRepeatedParamClass: Symbol + def RepeatedParamClass: Symbol + + // type tags + def ClassTagClass: Symbol + def ClassTagModule: Symbol + def TypeTagClass: Symbol + def TypeTagModule: Symbol + def GroundTypeTagClass: Symbol + def GroundTypeTagModule: Symbol /** Given a type T, returns the type corresponding to the VM's * representation: ClassClass's type constructor applied to `arg`. */ def vmClassType(arg: Type): Type // !!! better name? + // [Eugene] we already have arg.erasure, right? /** The string representation used by the given type in the VM. */ diff --git a/src/library/scala/reflect/api/StandardNames.scala b/src/library/scala/reflect/api/StandardNames.scala index 81517d2a6b..bfc165f613 100644 --- a/src/library/scala/reflect/api/StandardNames.scala +++ b/src/library/scala/reflect/api/StandardNames.scala @@ -8,14 +8,166 @@ package api trait StandardNames { self: Universe => + abstract class AbsNames { + type NameType <: Name + + val EMPTY: NameType + val ANON_FUN_NAME: NameType + val ANON_CLASS_NAME: NameType + val EMPTY_PACKAGE_NAME: NameType + val IMPORT: NameType + val MODULE_VAR_SUFFIX: NameType + val ROOT: NameType + val PACKAGE: NameType + val SPECIALIZED_SUFFIX: NameType + + val ERROR: NameType + val NO_NAME: NameType + val WILDCARD: NameType + + def flattenedName(segments: Name*): NameType + } + val nme: AbsTermNames - abstract class AbsTermNames { + abstract class AbsTermNames extends AbsNames { + val EXPAND_SEPARATOR_STRING: String + + val ANYNAME: TermName val CONSTRUCTOR: TermName + val FAKE_LOCAL_THIS: TermName + val INITIALIZER: TermName + val LAZY_LOCAL: TermName + val LOCAL_SUFFIX_STRING: String + val MIRROR_PREFIX: TermName + val MIRROR_SHORT: TermName + val MIRROR_FREE_PREFIX: TermName + val MIRROR_FREE_THIS_SUFFIX: TermName + val MIRROR_FREE_VALUE_SUFFIX: TermName + val MIXIN_CONSTRUCTOR: TermName + val MODULE_INSTANCE_FIELD: TermName + val OUTER: TermName + val OUTER_LOCAL: TermName + val OUTER_SYNTH: TermName + val SELECTOR_DUMMY: TermName + val SELF: TermName + val SPECIALIZED_INSTANCE: TermName + val STAR: TermName + val THIS: TermName + + val BITMAP_NORMAL: TermName + val BITMAP_TRANSIENT: TermName + val BITMAP_PRIVATE: TermName + val BITMAP_CHECKINIT: TermName + val BITMAP_CHECKINIT_TRANSIENT: TermName + + val INTERPRETER_IMPORT_WRAPPER: String + val INTERPRETER_LINE_PREFIX: String + val INTERPRETER_VAR_PREFIX: String + val INTERPRETER_WRAPPER_SUFFIX: String + + val ROOTPKG: TermName + + val ADD: TermName + val AND: TermName + val ASR: TermName + val DIV: TermName + val EQ: TermName + val EQL: TermName + val GE: TermName + val GT: TermName + val HASHHASH: TermName + val LE: TermName + val LSL: TermName + val LSR: TermName + val LT: TermName + val MINUS: TermName + val MOD: TermName + val MUL: TermName + val NE: TermName + val OR: TermName + val PLUS : TermName + val SUB: TermName + val XOR: TermName + val ZAND: TermName + val ZOR: TermName + + // [Eugene] this doesn't compile. why?! +// val UNARY_~: TermName +// val UNARY_+: TermName +// val UNARY_-: TermName +// val UNARY_!: TermName + val UNARY_TILDE: TermName + val UNARY_PLUS: TermName + val UNARY_MINUS: TermName + val UNARY_NOT: TermName + + // [Eugene] this doesn't compile. why?! +// val ???: TermName + val QQQ: TermName + + val MODULE_SUFFIX_NAME: TermName + val NAME_JOIN_NAME: TermName + val IMPL_CLASS_SUFFIX: String + val LOCALDUMMY_PREFIX: String + val PROTECTED_PREFIX: String + val PROTECTED_SET_PREFIX: String + val SINGLETON_SUFFIX: String + val SUPER_PREFIX_STRING: String + val TRAIT_SETTER_SEPARATOR_STRING: String + val SETTER_SUFFIX: TermName + + def isConstructorName(name: Name): Boolean + def isExceptionResultName(name: Name): Boolean + def isImplClassName(name: Name): Boolean + def isLocalDummyName(name: Name): Boolean + def isLocalName(name: Name): Boolean + def isLoopHeaderLabel(name: Name): Boolean + def isProtectedAccessorName(name: Name): Boolean + def isSuperAccessorName(name: Name): Boolean + def isReplWrapperName(name: Name): Boolean + def isSetterName(name: Name): Boolean + def isTraitSetterName(name: Name): Boolean + def isSingletonName(name: Name): Boolean + def isModuleName(name: Name): Boolean + def isOpAssignmentName(name: Name): Boolean + + def segments(name: String, assumeTerm: Boolean): List[Name] + def originalName(name: Name): Name + def stripModuleSuffix(name: Name): Name + def unspecializedName(name: Name): Name + def splitSpecializedName(name: Name): (Name, String, String) + def dropLocalSuffix(name: Name): Name + + def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName + def expandedSetterName(name: TermName, base: Symbol): TermName + def protName(name: Name): TermName + def protSetterName(name: Name): TermName + def getterName(name: TermName): TermName + def getterToLocal(name: TermName): TermName + def getterToSetter(name: TermName): TermName + def localToGetter(name: TermName): TermName + def setterToGetter(name: TermName): TermName + def defaultGetterName(name: Name, pos: Int): TermName + def defaultGetterToMethod(name: Name): TermName + + def dropSingletonName(name: Name): TypeName + def singletonName(name: Name): TypeName + def implClassName(name: Name): TypeName + def interfaceName(implname: Name): TypeName + def localDummyName(clazz: Symbol): TermName + def superName(name: Name): TermName } val tpnme: AbsTypeNames - abstract class AbsTypeNames { + abstract class AbsTypeNames extends AbsNames { + val REFINE_CLASS_NAME: TypeName + val BYNAME_PARAM_CLASS_NAME: TypeName + val EQUALS_PATTERN_NAME: TypeName + val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName + val LOCAL_CHILD: TypeName + val REPEATED_PARAM_CLASS_NAME: TypeName + val WILDCARD_STAR: TypeName } } diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index ab59a4a39a..a154e5f7a0 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -7,6 +7,10 @@ trait Symbols { self: Universe => abstract class AbsSymbol { this: Symbol => + /** The position of this symbol + */ + def pos: Position + /** The modifiers of this symbol */ def modifiers: Set[Modifier] @@ -47,6 +51,10 @@ trait Symbols { self: Universe => /** An id number which is unique for all symbols in this universe */ def id: Int + /** ... + */ + def orElse[T](alt: => Symbol): Symbol + /** * Set when symbol has a modifier of the form private[X], NoSymbol otherwise. * @@ -112,6 +120,20 @@ trait Symbols { self: Universe => */ def isTerm : Boolean + /** Does this symbol represent the definition of method? + * If yes, `isTerm` is also guaranteed to be true. + */ + def isMethod : Boolean + + /** Is this symbol an overloaded method? + */ + def isOverloaded : Boolean + + /** Does this symbol represent a free term captured by reification? + */ + // needed for ones who wish to inspect reified trees + def isFreeTerm : Boolean + /** Does this symbol represent the definition of type? * Note that every symbol is either a term or a type. * So for every symbol `sym`, either `sym.isTerm` is true @@ -124,6 +146,17 @@ trait Symbols { self: Universe => */ def isClass : Boolean + /** Does this symbol represent the definition of a primitive class? + * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], + * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]? + */ + def isPrimitiveValueClass: Boolean + + /** Does this symbol represent the definition of a custom value class? + * Namely, is AnyVal among its parent classes? + */ + def isDerivedValueClass: Boolean + /** Does this symbol represent the definition of a type alias? * If yes, `isType` is also guaranteed to be true. */ @@ -134,9 +167,28 @@ trait Symbols { self: Universe => */ def isAbstractType : Boolean - /** Is this symbol an overloaded method? + /** Does this symbol represent the definition of a skolem? + * Skolems are used during typechecking to represent type parameters viewed from inside their scopes. + * If yes, `isType` is also guaranteed to be true. */ - def isOverloaded: Boolean + def isSkolem : Boolean + + /** Does this symbol represent a free type captured by reification? + */ + // needed for ones who wish to inspect reified trees + def isFreeType : Boolean + + /** Is the type parameter represented by this symbol contravariant? + */ + def isContravariant : Boolean + + /** Is the type parameter represented by this symbol contravariant? + */ + def isCovariant : Boolean + + /** Does this symbol or its underlying type represent a typechecking error? + */ + def isErroneous : Boolean /** The type signature of this symbol. * Note if the symbol is a member of a class, one almost always is interested @@ -192,7 +244,7 @@ trait Symbols { self: Universe => /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has * the current symbol as its owner. */ - def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol // needed by LiftCode + def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol // needed by LiftCode !!! not enough reason to have in the api /** Low-level operation to set the symbol's flags * @return the symbol itself @@ -207,6 +259,9 @@ trait Symbols { self: Universe => /** Set symbol's annotations to given annotations `annots`. */ def setAnnotations(annots: AnnotationInfo*): this.type // needed by LiftCode !!! not enough reason to have in the api + + /** The kind of this symbol; used for debugging */ + def kind: String } val NoSymbol: Symbol diff --git a/src/library/scala/reflect/api/ToolBoxes.scala b/src/library/scala/reflect/api/ToolBoxes.scala new file mode 100644 index 0000000000..387ef5163b --- /dev/null +++ b/src/library/scala/reflect/api/ToolBoxes.scala @@ -0,0 +1,90 @@ +package scala.reflect +package api + +trait ToolBoxes { self: Universe => + + type ToolBox <: AbsToolBox + + def mkToolBox(reporter: Reporter = mkSilentReporter(), options: String = ""): AbsToolBox + + // [Eugene] what do you think about the interface? namely about the ``freeTypes'' part. + trait AbsToolBox { + + /** UI of the toolbox. + * + * Accumulates and displays warnings and errors, can drop to interactive mode (if supported). + * The latter can be useful to study the typechecker or to debug complex macros. + */ + def reporter: Reporter + + /** Typechecks a tree using this ToolBox. + * This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings. + * + * If the tree has unresolved type variables (represented as instances of ``FreeType'' symbols), + * then they might, might be partially or might not be specified in the ``freeTypes'' parameter. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Ydebug. + * + * Typechecking can be steered with the following optional parameters: + * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false + * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false + */ + def typeCheck(tree: Tree, pt: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree + + /** Infers an implicit value of the expected type ``pt'' in the macro callsite context. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree + + /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context. + * + * Otional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported. + * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree + + /** Recursively resets symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetAllAttrs[T <: Tree](tree: T): T + + /** Recursively resets locally defined symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetLocalAttrs[T <: Tree](tree: T): T + + /** Compiles and runs a tree using this ToolBox. + * + * If the tree has unresolved type variables (represented as instances of ``FreeType'' symbols), + * then they all have to be specified in the ``freeTypes'' parameter or an error occurs. + * + * This spawns the compiler at the Namer phase, and pipelines the tree through that compiler. + * Currently ``runExpr'' does not accept trees that already typechecked, because typechecking isn't idempotent. + * For more info, take a look at https://issues.scala-lang.org/browse/SI-5464. + */ + def runExpr(tree: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any + + /** Represents an error during toolboxing + */ + type ToolBoxError <: Throwable + val ToolBoxError: ToolBoxErrorExtractor + abstract class ToolBoxErrorExtractor { + def unapply(error: ToolBoxError): Option[(ToolBox, String)] + } + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/TreeBuildUtil.scala b/src/library/scala/reflect/api/TreeBuildUtil.scala index f28008bc21..32d7eefa5b 100644 --- a/src/library/scala/reflect/api/TreeBuildUtil.scala +++ b/src/library/scala/reflect/api/TreeBuildUtil.scala @@ -1,46 +1,127 @@ -package scala.reflect.api +package scala.reflect +package api -trait TreeBuildUtil extends Universe { +trait TreeBuildUtil { self: Universe => - /** The symbol corresponding to the globally accessible class with the - * given fully qualified name `fullName`. + /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`. + * Unlike `staticClassIfDefined`, throws `MissingRequirementError` is requested class cannot be found. */ def staticClass(fullName: String): Symbol - /** The symbol corresponding to the globally accessible object with the - * given fully qualified name `fullName`. + /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`. + * Unlike `staticClass`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested class cannot be found. + */ + def staticClassIfDefined(fullName: String): Symbol + + /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`. + * Unlike `staticModuleIfDefined`, throws `MissingRequirementError` is requested object cannot be found. */ def staticModule(fullName: String): Symbol + /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`. + * Unlike `staticModule`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested object cannot be found. + */ + def staticModuleIfDefined(fullName: String): Symbol + /** The this-ptype of the globally accessible object with the * given fully qualified name `fullName`. */ def thisModuleType(fullName: String): Type /** Selects type symbol with given simple name `name` from the defined members of `owner`. + * Unlike `selectTypeIfDefined`, throws `MissingRequirementError` is requested type symbol cannot be found. */ def selectType(owner: Symbol, name: String): Symbol + /** Selects type symbol with given simple name `name` from the defined members of `owner`. + * Unlike `selectType`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested type symbol cannot be found. + */ + def selectTypeIfDefined(owner: Symbol, name: String): Symbol + /** Selects term symbol with given name and type from the defined members of prefix type - * @pre The prefix type - * @name The name of the selected member + * Unlike `selectTermIfDefined`, throws `MissingRequirementError` is requested term symbol cannot be found. */ def selectTerm(owner: Symbol, name: String): Symbol - def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol + /** Selects term symbol with given name and type from the defined members of prefix type + * Unlike `selectTerm`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested term symbol cannot be found. + */ + def selectTermIfDefined(owner: Symbol, name: String): Symbol - def selectParam(owner: Symbol, idx: Int): Symbol + /** Selects overloaded method symbol with given name and index + * Unlike `selectOverloadedMethodIfDefined`, throws `MissingRequirementError` is requested overloaded method cannot be found. + */ + def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol - def newScopeWith(decls: Symbol*): Scope + /** Selects overloaded method symbol with given name and index + * Unlike `selectOverloadedMethod`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested overloaded method cannot be found. + */ + def selectOverloadedMethodIfDefined(owner: Symbol, name: String, index: Int): Symbol - /** Create a fresh free variable symbol. + /** Create a fresh free term symbol. * @param name the name of the free variable - * @param tsig the type signature of the free variable + * @param info the type signature of the free variable * @param value the value of the free variable at runtime + * @param origin debug information that tells where this symbol comes from */ - def newFreeVar(name: String, info: Type, value: Any): Symbol + def newFreeTerm(name: String, info: Type, value: => Any, origin: String): Symbol + + /** Create a fresh free type symbol. + * @param name the name of the free variable + * @param info the type signature of the free variable + * @param value a type tag that captures the value of the free variable + * is completely phantom, since the captured type cannot be propagated to the runtime + * if it could be, we wouldn't be creating a free type to begin with + * the only usage for it is preserving the captured symbol for compile-time analysis + * @param origin debug information that tells where this symbol comes from + */ + def newFreeType(name: String, info: Type, value: => Any, origin: String): Symbol /** Create a Modiiers structure given internal flags, qualifier, annotations */ def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers -} \ No newline at end of file + val gen: TreeGen { val global: TreeBuildUtil.this.type } + + type TreeGen <: AbsTreeGen +} + +// [Eugene to Paul] we need to expose some of the functionality provided by TreeGen +// 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? +trait AbsTreeGen { + val global: Universe + + import global._ + import definitions._ + + /** Builds a reference to value whose type is given stable prefix. + * The type must be suitable for this. For example, it + * must not be a TypeRef pointing to an abstract type variable. + */ + def mkAttributedQualifier(tpe: Type): Tree + + /** Builds a reference to value whose type is given stable prefix. + * If the type is unsuitable, e.g. it is a TypeRef for an + * abstract type variable, then an Ident will be made using + * termSym as the Ident's symbol. In that case, termSym must + * not be NoSymbol. + */ + def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree + + /** Builds a typed reference to given symbol with given stable prefix. */ + def mkAttributedRef(pre: Type, sym: Symbol): Tree + + /** Builds a typed reference to given symbol. */ + def mkAttributedRef(sym: Symbol): Tree + + /** Builds a typed This reference to given symbol. */ + def mkAttributedThis(sym: Symbol): Tree + + /** Builds a typed Ident with an underlying symbol. */ + def mkAttributedIdent(sym: Symbol): Tree + + /** Builds a typed Select with an underlying symbol. */ + def mkAttributedSelect(qual: Tree, sym: Symbol): Tree +} diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala index 43865915d3..3d64ec8e40 100644 --- a/src/library/scala/reflect/api/TreePrinters.scala +++ b/src/library/scala/reflect/api/TreePrinters.scala @@ -29,17 +29,21 @@ trait TreePrinters { self: Universe => def newTreePrinter(out: PrintWriter): TreePrinter // emits more or less verbatim representation of the provided tree - // todo. when LiftCode becomes a macro, throw this code away and use that macro class RawTreePrinter(out: PrintWriter) extends TreePrinter { + val EmptyValDef = self.emptyValDef def print(args: Any*): Unit = args foreach { case EmptyTree => print("EmptyTree") + case EmptyValDef => + print("emptyValDef") case tree @ TypeTree() => print("TypeTree()") if (tree.tpe != null) print(".setType(", tree.tpe, ")") else if (tree.original != null) print(".setOriginal(", tree.original, ")") + case Literal(Constant(s: String)) => + print("Literal(Constant(\"" + s + "\"))") case tree: Tree => print(tree.printingPrefix+"(") val it = tree.productIterator diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index d8180fe029..01f948809c 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -14,6 +14,7 @@ trait Trees { self: Universe => private[scala] var nodeCount = 0 type Modifiers >: Null <: AbsModifiers + val NoMods: Modifiers abstract class AbsModifiers { def modifiers: Set[Modifier] @@ -80,18 +81,14 @@ trait Trees { self: Universe => */ def printingPrefix = productPrefix - def pos: Position = annotationToPosition(rawannot) - def pos_=(pos: Position): Unit = annotation = pos + def pos: Position = rawatt.pos.asInstanceOf[Position] // [Eugene] how do we get rid of this cast? + def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) // the "withPos" part is crucial to robustness def setPos(newpos: Position): this.type = { pos = newpos; this } - private[this] var rawannot: TreeAnnotation = NoTreeAnnotation - def annotation: TreeAnnotation = rawannot - def annotation_=(annot: TreeAnnotation): Unit = { - _checkSetAnnotation(this, annot) - rawannot = annot - } - - def setAnnotation(annot: TreeAnnotation): this.type = { annotation = annot; this } + private[this] var rawatt: Attachment = NoPosition + def attachment: Attachment = rawatt + def attachment_=(att: Attachment): Unit = rawatt = att + def setAttachment(att: Attachment): this.type = { rawatt = att; this } private[this] var rawtpe: Type = _ @@ -143,6 +140,7 @@ trait Trees { self: Universe => def hasSymbol = false def isDef = false def isEmpty = false + def orElse(alt: => Tree) = if (!isEmpty) this else alt def hasSymbolWhich(f: Symbol => Boolean) = hasSymbol && f(symbol) @@ -179,6 +177,13 @@ trait Trees { self: Universe => } def filter(f: Tree => Boolean): List[Tree] = withFilter(f) + /** Apply `pf' to each subtree on which the function is defined */ + def collect[T](pf: PartialFunction[Tree, T]): List[T] = { + val ctt = new CollectTreeTraverser[T](pf) + ctt.traverse(this) + ctt.results.toList + } + /** Returns optionally first tree (in a preorder traversal) which satisfies predicate `p`, * or None if none exists. */ @@ -188,9 +193,12 @@ trait Trees { self: Universe => ft.result } - /** Is there part of this tree which satisfies predicate `p`? */ + /** Is there exists a part of this tree which satisfies predicate `p`? */ def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty + /** Do all parts of this tree satisfy predicate `p`? */ + def forAll(p: Tree => Boolean): Boolean = find(!p(_)).isEmpty + def equalsStructure(that : Tree) = equalsStructure0(that)(_ eq _) def equalsStructure0(that: Tree)(f: (Tree,Tree) => Boolean): Boolean = f(this, that) || ((this.productArity == that.productArity) && { @@ -230,7 +238,7 @@ trait Trees { self: Universe => duplicateTree(this).asInstanceOf[this.type] private[scala] def copyAttrs(tree: Tree): this.type = { - annotation = tree.annotation + attachment = tree.attachment tpe = tree.tpe if (hasSymbol) symbol = tree.symbol this @@ -241,6 +249,34 @@ trait Trees { self: Universe => override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] } + // [Eugene] uh-oh + // locker.comp: + // [mkdir] Created dir: C:\Projects\Kepler\build\locker\classes\compiler + // [scalacfork] Compiling 471 files to C:\Projects\Kepler\build\locker\classes\compiler + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree +// object Tree { +// // would be great if in future this generated an Expr[Magic] +// // where Magic is a magic untyped type that propagates through the entire quasiquote +// // and turns off typechecking whenever it's involved +// // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked +// // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo +// implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree) +// implicit def expr2tree(expr: Expr[_]): Tree = expr.tree +// +// // [Eugene] good idea? +// implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr +// implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree +// } + /** A tree for a term. Not all terms are TermTrees; use isTerm * to reliably identify terms. */ @@ -319,12 +355,23 @@ trait Trees { self: Universe => case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template) extends ImplDef + /** @param sym the class symbol + * @return the implementation template + */ + def ClassDef(sym: Symbol, impl: Template): ClassDef + /** An object definition, e.g. `object Foo`. Internally, objects are * quite frequently called modules to reduce ambiguity. */ case class ModuleDef(mods: Modifiers, name: TermName, impl: Template) extends ImplDef + /** + * @param sym the class symbol + * @param impl the implementation template + */ + def ModuleDef(sym: Symbol, impl: Template): ModuleDef + /** A common base class for ValDefs and DefDefs. */ abstract class ValOrDefDef extends MemberDef { @@ -343,17 +390,37 @@ trait Trees { self: Universe => */ case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef + def ValDef(sym: Symbol, rhs: Tree): ValDef + + def ValDef(sym: Symbol): ValDef + /** A method or macro definition. * @param name The name of the method or macro. Can be a type name in case this is a type macro */ case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef + def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef + + def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef + + def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef + + def DefDef(sym: Symbol, rhs: Tree): DefDef + + def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef + /** An abstract type, a type parameter, or a type alias. */ case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree) extends MemberDef + /** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */ + def TypeDef(sym: Symbol, rhs: Tree): TypeDef + + /** A TypeDef node which defines abstract type or type parameter for given `sym` */ + def TypeDef(sym: Symbol): TypeDef + /** A labelled expression. Not expressible in language syntax, but * generated by the compiler to simulate while/do-while loops, and * also by the pattern matcher. @@ -371,6 +438,8 @@ trait Trees { self: Universe => case class LabelDef(name: TermName, params: List[Ident], rhs: Tree) extends DefTree with TermTree + def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef + /** Import selector * * Representation of an imported name its optional rename and their optional positions @@ -415,12 +484,19 @@ trait Trees { self: Universe => case class Block(stats: List[Tree], expr: Tree) extends TermTree + /** Block factory that flattens directly nested blocks. + */ + def Block(stats: Tree*): Block + /** Case clause in a pattern match, eliminated during explicitouter * (except for occurrences in switch statements) */ case class CaseDef(pat: Tree, guard: Tree, body: Tree) extends Tree + /** casedef shorthand */ + def CaseDef(pat: Tree, body: Tree): CaseDef + /** Alternatives of patterns, eliminated by explicitouter, except for * occurrences in encoded Switch stmt (=remaining Match(CaseDef(...)) */ @@ -439,6 +515,8 @@ trait Trees { self: Universe => case class Bind(name: Name, body: Tree) extends DefTree + def Bind(sym: Symbol, body: Tree): Bind + case class UnApply(fun: Tree, args: List[Tree]) extends TermTree @@ -489,10 +567,14 @@ trait Trees { self: Universe => case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree) extends TermTree + def Try(body: Tree, cases: (Tree, Tree)*): Try + /** Throw expression */ case class Throw(expr: Tree) extends TermTree + def Throw(tpe: Type, args: Tree*): Throw + /** Object instantiation * One should always use factory method below to build a user level new. * @@ -503,14 +585,13 @@ trait Trees { self: Universe => /** Factory method for object creation `new tpt(args_1)...(args_n)` * A `New(t, as)` is expanded to: `(new t).(as)` */ - def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match { - case Nil => new ApplyConstructor(tpt, Nil) - case xs :: rest => rest.foldLeft(new ApplyConstructor(tpt, xs): Tree)(Apply) - } + def New(tpt: Tree, argss: List[List[Tree]]): Tree + /** 0-1 argument list new, based on a type. */ - def New(tpe: Type, args: Tree*): Tree = - new ApplyConstructor(TypeTree(tpe), args.toList) + def New(tpe: Type, args: Tree*): Tree + + def New(sym: Symbol, args: Tree*): Tree /** Type annotation, eliminated by explicit outer */ case class Typed(expr: Tree, tpt: Tree) @@ -545,6 +626,8 @@ trait Trees { self: Universe => override def symbol_=(sym: Symbol) { fun.symbol = sym } } + def Apply(sym: Symbol, args: Tree*): Tree + class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args) class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args) @@ -563,7 +646,9 @@ trait Trees { self: Universe => extends TermTree with SymTree // The symbol of an ApplyDynamic is the function symbol of `qual`, or NoSymbol, if there is none. - /** Super reference, qual = corresponding this reference */ + /** Super reference, qual = corresponding this reference + * A super reference C.super[M] is represented as Super(This(C), M). + */ case class Super(qual: Tree, mix: TypeName) extends TermTree { // The symbol of a Super is the class _from_ which the super reference is made. // For instance in C.super(...), it would be C. @@ -571,38 +656,47 @@ trait Trees { self: Universe => override def symbol_=(sym: Symbol) { qual.symbol = sym } } + def Super(sym: Symbol, mix: TypeName): Tree + /** Self reference */ case class This(qual: TypeName) extends TermTree with SymTree // The symbol of a This is the class to which the this refers. // For instance in C.this, it would be C. - def This(sym: Symbol): Tree = - This(sym.name.toTypeName) setSymbol sym + def This(sym: Symbol): Tree /** Designator . */ case class Select(qualifier: Tree, name: Name) extends RefTree - def Select(qualifier: Tree, name: String): Select = - Select(qualifier, newTermName(name)) + def Select(qualifier: Tree, name: String): Select - def Select(qualifier: Tree, sym: Symbol): Select = - Select(qualifier, sym.name) setSymbol sym + def Select(qualifier: Tree, sym: Symbol): Select /** Identifier */ case class Ident(name: Name) extends RefTree { def qualifier: Tree = EmptyTree } - def Ident(name: String): Ident = - Ident(newTermName(name)) + def Ident(name: String): Ident - def Ident(sym: Symbol): Ident = - Ident(sym.name) setSymbol sym + def Ident(sym: Symbol): Ident class BackQuotedIdent(name: Name) extends Ident(name) + /** Marks underlying reference to id as boxed. + * @pre: id must refer to a captured variable + * A reference such marked will refer to the boxed entity, no dereferencing + * with `.elem` is done on it. + * This tree node can be emitted by macros such as reify that call referenceCapturedVariable. + * It is eliminated in LambdaLift, where the boxing conversion takes place. + */ + case class ReferenceToBoxed(ident: Ident) extends TermTree { + override def symbol: Symbol = ident.symbol + override def symbol_=(sym: Symbol) { ident.symbol = sym } + } + /** Literal */ case class Literal(value: Constant) extends TermTree { @@ -873,6 +967,8 @@ trait Trees { self: Universe => traverse(qualifier) case Ident(_) => ; + case ReferenceToBoxed(idt) => + traverse(idt) case Literal(_) => ; case TypeTree() => @@ -958,6 +1054,7 @@ trait Trees { self: Universe => def This(tree: Tree, qual: Name): This def Select(tree: Tree, qualifier: Tree, selector: Name): Select def Ident(tree: Tree, name: Name): Ident + def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed def Literal(tree: Tree, value: Constant): Literal def TypeTree(tree: Tree): TypeTree def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated @@ -1040,6 +1137,8 @@ trait Trees { self: Universe => new Select(qualifier, selector).copyAttrs(tree) def Ident(tree: Tree, name: Name) = new Ident(name).copyAttrs(tree) + def ReferenceToBoxed(tree: Tree, idt: Ident) = + new ReferenceToBoxed(idt).copyAttrs(tree) def Literal(tree: Tree, value: Constant) = new Literal(value).copyAttrs(tree) def TypeTree(tree: Tree) = @@ -1228,6 +1327,11 @@ trait Trees { self: Universe => if name0 == name => t case _ => treeCopy.Ident(tree, name) } + def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match { + case t @ ReferenceToBoxed(idt0) + if (idt0 == idt) => t + case _ => this.treeCopy.ReferenceToBoxed(tree, idt) + } def Literal(tree: Tree, value: Constant) = tree match { case t @ Literal(value0) if value0 == value => t @@ -1372,6 +1476,8 @@ trait Trees { self: Universe => treeCopy.Select(tree, transform(qualifier), selector) case Ident(name) => treeCopy.Ident(tree, name) + case ReferenceToBoxed(idt) => + treeCopy.ReferenceToBoxed(tree, transform(idt) match { case idt1: Ident => idt1 }) case Literal(value) => treeCopy.Literal(tree, value) case TypeTree() => @@ -1443,6 +1549,14 @@ trait Trees { self: Universe => } } + class CollectTreeTraverser[T](pf: PartialFunction[Tree, T]) extends Traverser { + val results = new ListBuffer[T] + override def traverse(t: Tree) { + if (pf.isDefinedAt(t)) results += pf(t) + super.traverse(t) + } + } + class FindTreeTraverser(p: Tree => Boolean) extends Traverser { var result: Option[Tree] = None override def traverse(t: Tree) { @@ -1535,7 +1649,7 @@ trait Trees { self: Universe => case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup) // fun(args) case Super(qual, mix) => - // qual.super[mix] if qual and/or mix is empty, ther are tpnme.EMPTY + // qual.super[mix] qual is always This(something), if mix is empty, it is tpnme.EMPTY case This(qual) => // qual.this case Select(qualifier, selector) => @@ -1544,6 +1658,10 @@ trait Trees { self: Universe => // name // note: type checker converts idents that refer to enclosing fields or methods // to selects; name ==> this.name + case ReferenceToBoxed(ident) => (created by typer, eliminated by lambdalift) + // synthetic node emitted by macros to reference capture vars directly without going through ``elem'' + // var x = ...; fun { x } will emit Ident(x), which gets transformed to Select(Ident(x), "elem") + // if ReferenceToBoxed were used instead of Ident, no transformation would be performed case Literal(value) => // value case TypeTree() => (introduced by refcheck) diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala new file mode 100644 index 0000000000..a38c21a9d4 --- /dev/null +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -0,0 +1,193 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package api + +import scala.reflect.{ mirror => rm } + +/** + * Type tags encapsulate a representation of type T. + * They are supposed to replace the pre-2.10 concept of a [[scala.reflect.Manifest]]. + * TypeTags are much better integrated with reflection than manifests are, and are consequently much simpler. + * + * Type tags are organized in a hierarchy of two classes: + * [[scala.reflect.ClassTag]], [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#GroundTypeTag]]. + * A [[scala.reflect.ClassTag]] value wraps a Java class, which can be accessed via the erasure method. + * A [[scala.reflect.api.Universe#TypeTag]] value wraps a full Scala type in its tpe field. + * A [[scala.reflect.api.Universe#GroundTypeTag]] value is a type tag that is guaranteed not to contain any references to type parameters or abstract types. + * + * TypeTags correspond loosely to Manifests. More precisely: + * The previous notion of a [[scala.reflect.ClassManifest]] corresponds to a scala.reflect.ClassTag, + * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.mirror.GroundTypeTag, + * Whereas scala.reflect.mirror.TypeTag is approximated by the previous notion of [[scala.reflect.OptManifest]]. + * + * Implicit in the contract for all Tag classes is that the reified type tpe represents the type parameter T. + * Tags are typically created by the compiler, which makes sure that this contract is kept. + * + * An example that illustrates the TypeTag embedding, consider the following function: + * + * import reflect.mirror._ + * def f[T: TypeTag, U] = { + * type L = T => U + * implicitly[TypeTag[L]] + * } + * + * Then a call of f[String, Int] will yield a result of the form + * + * TypeTag(<[ String => U ]>). + * + * Note that T has been replaced by String, because it comes with a TypeTag in f, whereas U was left as a type parameter. + */ +trait TypeTags { self: Universe => + + /** + * If an implicit value of type u.TypeTag[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. + * In that value, any occurrences of type parameters or abstract types U + * which come themselves with a TypeTag are represented by the type referenced by that TypeTag. + * + * @see [[scala.reflect.api.TypeTags]] + */ + @annotation.implicitNotFound(msg = "No TypeTag available for ${T}") + abstract case class TypeTag[T](tpe: Type) { + // it's unsafe to use assert here, because we might run into deadlocks with Predef + // also see comments in ClassTags.scala + // assert(tpe != null) + + def sym = tpe.typeSymbol + + def isGround = !isNotGround + def isNotGround = tpe exists (_.typeSymbol.isAbstractType) + + def toGround: GroundTypeTag[T] = { + assert(isGround, tpe) + GroundTypeTag[T](tpe) + } + + override def toString = { + var prefix = if (isGround) "GroundTypeTag" else "TypeTag" + if (prefix != this.productPrefix) prefix = "*" + prefix + prefix + "[" + tpe + "]" + } + } + + object TypeTag { + val Byte : TypeTag[scala.Byte] = GroundTypeTag.Byte + val Short : TypeTag[scala.Short] = GroundTypeTag.Short + val Char : TypeTag[scala.Char] = GroundTypeTag.Char + val Int : TypeTag[scala.Int] = GroundTypeTag.Int + val Long : TypeTag[scala.Long] = GroundTypeTag.Long + val Float : TypeTag[scala.Float] = GroundTypeTag.Float + val Double : TypeTag[scala.Double] = GroundTypeTag.Double + val Boolean : TypeTag[scala.Boolean] = GroundTypeTag.Boolean + val Unit : TypeTag[scala.Unit] = GroundTypeTag.Unit + val Any : TypeTag[scala.Any] = GroundTypeTag.Any + val Object : TypeTag[java.lang.Object] = GroundTypeTag.Object + val AnyVal : TypeTag[scala.AnyVal] = GroundTypeTag.AnyVal + val AnyRef : TypeTag[scala.AnyRef] = GroundTypeTag.AnyRef + val Nothing : TypeTag[scala.Nothing] = GroundTypeTag.Nothing + val Null : TypeTag[scala.Null] = GroundTypeTag.Null + val String : TypeTag[java.lang.String] = GroundTypeTag.String + + def apply[T](tpe: Type): TypeTag[T] = + tpe match { + case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]] + case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]] + case CharTpe => TypeTag.Char.asInstanceOf[TypeTag[T]] + case IntTpe => TypeTag.Int.asInstanceOf[TypeTag[T]] + case LongTpe => TypeTag.Long.asInstanceOf[TypeTag[T]] + case FloatTpe => TypeTag.Float.asInstanceOf[TypeTag[T]] + case DoubleTpe => TypeTag.Double.asInstanceOf[TypeTag[T]] + case BooleanTpe => TypeTag.Boolean.asInstanceOf[TypeTag[T]] + case UnitTpe => TypeTag.Unit.asInstanceOf[TypeTag[T]] + case AnyTpe => TypeTag.Any.asInstanceOf[TypeTag[T]] + case ObjectTpe => TypeTag.Object.asInstanceOf[TypeTag[T]] + case AnyValTpe => TypeTag.AnyVal.asInstanceOf[TypeTag[T]] + case AnyRefTpe => TypeTag.AnyRef.asInstanceOf[TypeTag[T]] + case NothingTpe => TypeTag.Nothing.asInstanceOf[TypeTag[T]] + case NullTpe => TypeTag.Null.asInstanceOf[TypeTag[T]] + case StringTpe => TypeTag.String.asInstanceOf[TypeTag[T]] + case _ => new TypeTag[T](tpe) {} + } + } + + /** + * If an implicit value of type u.GroundTypeTag[T] is required, the compiler will make one up on demand following the same procedure as for TypeTags. + * However, if the resulting type still contains references to type parameters or abstract types, a static error results. + * + * @see [[scala.reflect.api.TypeTags]] + */ + @annotation.implicitNotFound(msg = "No GroundTypeTag available for ${T}") + class GroundTypeTag[T](tpe: Type) extends TypeTag[T](tpe) { + assert(isGround, tpe) + override def productPrefix = "GroundTypeTag" + } + + object GroundTypeTag { + val Byte : GroundTypeTag[scala.Byte] = new GroundTypeTag[scala.Byte](ByteTpe) { private def readResolve() = GroundTypeTag.Byte } + val Short : GroundTypeTag[scala.Short] = new GroundTypeTag[scala.Short](ShortTpe) { private def readResolve() = GroundTypeTag.Short } + val Char : GroundTypeTag[scala.Char] = new GroundTypeTag[scala.Char](CharTpe) { private def readResolve() = GroundTypeTag.Char } + val Int : GroundTypeTag[scala.Int] = new GroundTypeTag[scala.Int](IntTpe) { private def readResolve() = GroundTypeTag.Int } + val Long : GroundTypeTag[scala.Long] = new GroundTypeTag[scala.Long](LongTpe) { private def readResolve() = GroundTypeTag.Long } + val Float : GroundTypeTag[scala.Float] = new GroundTypeTag[scala.Float](FloatTpe) { private def readResolve() = GroundTypeTag.Float } + val Double : GroundTypeTag[scala.Double] = new GroundTypeTag[scala.Double](DoubleTpe) { private def readResolve() = GroundTypeTag.Double } + val Boolean : GroundTypeTag[scala.Boolean] = new GroundTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = GroundTypeTag.Boolean } + val Unit : GroundTypeTag[scala.Unit] = new GroundTypeTag[scala.Unit](UnitTpe) { private def readResolve() = GroundTypeTag.Unit } + val Any : GroundTypeTag[scala.Any] = new GroundTypeTag[scala.Any](AnyTpe) { private def readResolve() = GroundTypeTag.Any } + val Object : GroundTypeTag[java.lang.Object] = new GroundTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = GroundTypeTag.Object } + val AnyVal : GroundTypeTag[scala.AnyVal] = new GroundTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = GroundTypeTag.AnyVal } + val AnyRef : GroundTypeTag[scala.AnyRef] = new GroundTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = GroundTypeTag.AnyRef } + val Nothing : GroundTypeTag[scala.Nothing] = new GroundTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = GroundTypeTag.Nothing } + val Null : GroundTypeTag[scala.Null] = new GroundTypeTag[scala.Null](NullTpe) { private def readResolve() = GroundTypeTag.Null } + val String : GroundTypeTag[java.lang.String] = new GroundTypeTag[java.lang.String](StringTpe) { private def readResolve() = GroundTypeTag.String } + + def apply[T](tpe: Type): GroundTypeTag[T] = + tpe match { + case ByteTpe => GroundTypeTag.Byte.asInstanceOf[GroundTypeTag[T]] + case ShortTpe => GroundTypeTag.Short.asInstanceOf[GroundTypeTag[T]] + case CharTpe => GroundTypeTag.Char.asInstanceOf[GroundTypeTag[T]] + case IntTpe => GroundTypeTag.Int.asInstanceOf[GroundTypeTag[T]] + case LongTpe => GroundTypeTag.Long.asInstanceOf[GroundTypeTag[T]] + case FloatTpe => GroundTypeTag.Float.asInstanceOf[GroundTypeTag[T]] + case DoubleTpe => GroundTypeTag.Double.asInstanceOf[GroundTypeTag[T]] + case BooleanTpe => GroundTypeTag.Boolean.asInstanceOf[GroundTypeTag[T]] + case UnitTpe => GroundTypeTag.Unit.asInstanceOf[GroundTypeTag[T]] + case AnyTpe => GroundTypeTag.Any.asInstanceOf[GroundTypeTag[T]] + case ObjectTpe => GroundTypeTag.Object.asInstanceOf[GroundTypeTag[T]] + case AnyValTpe => GroundTypeTag.AnyVal.asInstanceOf[GroundTypeTag[T]] + case AnyRefTpe => GroundTypeTag.AnyRef.asInstanceOf[GroundTypeTag[T]] + case NothingTpe => GroundTypeTag.Nothing.asInstanceOf[GroundTypeTag[T]] + case NullTpe => GroundTypeTag.Null.asInstanceOf[GroundTypeTag[T]] + case StringTpe => GroundTypeTag.String.asInstanceOf[GroundTypeTag[T]] + case _ => new GroundTypeTag[T](tpe) {} + } + + def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isGround) Some(ttag.tpe) else None + + implicit def toClassTag[T](ttag: rm.GroundTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure)) + + implicit def toDeprecatedManifestApis[T](ttag: rm.GroundTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) + + // this class should not be used directly in client code + class DeprecatedManifestApis[T](ttag: rm.GroundTypeTag[T]) extends DeprecatedClassManifestApis[T](toClassTag(ttag)) { + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def <:<(that: Manifest[_]): Boolean = ttag.tpe <:< that.tpe + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def >:>(that: Manifest[_]): Boolean = that <:< ttag + + @deprecated("Use `tpe` to analyze the type arguments", "2.10.0") + override def typeArguments: List[Manifest[_]] = ttag.tpe.typeArguments map (targ => rm.GroundTypeTag(targ)) + } + } + + // incantations for summoning + // moved to Context, since rm.tags have their own incantations in Predef, and these guys are only useful in macros +// def tag[T](implicit ttag: TypeTag[T]) = ttag +// def typeTag[T](implicit ttag: TypeTag[T]) = ttag +// def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag +// def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala index 0371e2c5df..12aad453b1 100755 --- a/src/library/scala/reflect/api/Types.scala +++ b/src/library/scala/reflect/api/Types.scala @@ -105,7 +105,8 @@ trait Types { self: Universe => /** The erased type corresponding to this type after * all transformations from Scala to Java have been performed. */ - def erasedType: Type // !!! "erasedType", compare with "widen" (so "erase") or "underlying" (so "erased") + def erasure: Type // !!! "erasedType", compare with "widen" (so "erase") or "underlying" (so "erased") + // why not name it "erasure"? /** Apply `f` to each part of this type, returning * a new type. children get mapped before their parents */ @@ -146,6 +147,33 @@ trait Types { self: Universe => * .widen = o.C */ def widen: Type + + /** The kind of this type; used for debugging */ + def kind: String + } + + /** An object representing an unknown type, used during type inference. + * If you see WildcardType outside of inference it is almost certainly a bug. + */ + val WildcardType: Type + + /** BoundedWildcardTypes, used only during type inference, are created in + * two places that I can find: + * + * 1. If the expected type of an expression is an existential type, + * its hidden symbols are replaced with bounded wildcards. + * 2. When an implicit conversion is being sought based in part on + * the name of a method in the converted type, a HasMethodMatching + * type is created: a MethodType with parameters typed as + * BoundedWildcardTypes. + */ + type BoundedWildcardType >: Null <: Type + + val BoundedWildcardType: BoundedWildcardTypeExtractor + + abstract class BoundedWildcardTypeExtractor { + def apply(bounds: TypeBounds): BoundedWildcardType + def unapply(tpe: BoundedWildcardType): Option[TypeBounds] } /** The type of Scala types, and also Scala type signatures. @@ -424,5 +452,66 @@ trait Types { self: Universe => /** The greatest lower bound wrt <:< of a list of types */ def glb(ts: List[Type]): Type + + // 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 + + /** the canonical creator for a refined type with a given scope */ + def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type + + /** The canonical creator for a refined type with an initially empty scope. + * + * @param parents ... + * @param owner ... + * @return ... + */ + def refinedType(parents: List[Type], owner: Symbol): Type + + /** The canonical creator for typerefs + */ + def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type + + /** A creator for intersection type where intersections of a single type are + * replaced by the type itself. */ + def intersectionType(tps: List[Type]): Type + + /** A creator for intersection type where intersections of a single type are + * replaced by the type itself, and repeated parent classes are merged. + * + * !!! Repeated parent classes are not merged - is this a bug in the + * comment or in the code? + */ + def intersectionType(tps: List[Type], owner: Symbol): Type + + /** A creator for type applications */ + def appliedType(tycon: Type, args: List[Type]): Type + + /** A creator for type parameterizations that strips empty type parameter lists. + * Use this factory method to indicate the type has kind * (it's a polymorphic value) + * until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty). + */ + def polyType(tparams: List[Symbol], tpe: Type): Type + + /** A creator for existential types. This generates: + * + * tpe1 where { tparams } + * + * where `tpe1` is the result of extrapolating `tpe` wrt to `tparams`. + * Extrapolating means that type variables in `tparams` occurring + * in covariant positions are replaced by upper bounds, (minus any + * SingletonClass markers), type variables in `tparams` occurring in + * contravariant positions are replaced by upper bounds, provided the + * resulting type is legal wrt to stability, and does not contain any type + * variable in `tparams`. + * + * The abstraction drops all type parameters that are not directly or + * indirectly referenced by type `tpe1`. If there are no remaining type + * parameters, simply returns result type `tpe`. + */ + def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type } diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala index a3cec3271b..60abd267cb 100755 --- a/src/library/scala/reflect/api/Universe.scala +++ b/src/library/scala/reflect/api/Universe.scala @@ -2,18 +2,87 @@ package scala.reflect package api abstract class Universe extends Symbols + with FreeVars with Types with Constants with Scopes with Names with Trees - with Positions - with TreePrinters with AnnotationInfos + with Positions + with Exprs with StandardDefinitions - with StandardNames { - type Position - val NoPosition: Position + with TypeTags + with TreePrinters + with StandardNames + with ClassLoaders + with TreeBuildUtil + with ToolBoxes + with Reporters + with Importers { + /** Given an expression, generate a tree that when compiled and executed produces the original tree. + * The produced tree will be bound to the Universe it was called from. + * + * For instance, given the abstract syntax tree representation of the <[ x + 1 ]> expression: + * + * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1)))) + * + * The reifier transforms it to the following expression: + * + * <[ + * val $mr: scala.reflect.api.Universe = + * $mr.Expr[Int]($mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", , x), "+"), List($mr.Literal($mr.Constant(1)))))) + * ]> + * + * Reification performs expression splicing (when processing Expr.eval and Expr.value) + * and type splicing (for every type T that has a TypeTag[T] implicit in scope): + * + * val two = mirror.reify(2) // Literal(Constant(2)) + * val four = mirror.reify(two.eval + two.eval) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree)) + * + * def macroImpl[T](c: Context) = { + * ... + * // T here is just a type parameter, so the tree produced by reify won't be of much use in a macro expansion + * // however, if T were annotated with c.TypeTag (which would declare an implicit parameter for macroImpl) + * // then reification would subtitute T with the TypeTree that was used in a TypeApply of this particular macro invocation + * val factory = c.reify{ new Queryable[T] } + * ... + * } + * + * The transformation looks mostly straightforward, but it has its tricky parts: + * * Reifier retains symbols and types defined outside the reified tree, however + * locally defined entities get erased and replaced with their original trees + * * Free variables are detected and wrapped in symbols of the type FreeVar + * * Mutable variables that are accessed from a local function are wrapped in refs + * * Since reified trees can be compiled outside of the scope they've been created in, + * special measures are taken to ensure that all members accessed in the reifee remain visible + */ + def reify[T](expr: T): Expr[T] = macro Universe.reify[T] } +object Universe { + def reify[T](cc: scala.reflect.makro.Context{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = { + import cc.mirror._ + try cc.reifyTree(cc.prefix, expr) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + val ex1 = ex + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case cc.ReificationError(pos, msg) => + cc.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case cc.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } +} diff --git a/src/library/scala/reflect/macro/Context.scala b/src/library/scala/reflect/macro/Context.scala deleted file mode 100644 index 2fd9bb6484..0000000000 --- a/src/library/scala/reflect/macro/Context.scala +++ /dev/null @@ -1,36 +0,0 @@ -package scala.reflect -package macro - -trait Context extends api.Universe { - - /** Mark a variable as captured; i.e. force boxing in a *Ref type. - */ - def captureVariable(vble: Symbol): Unit - - /** Mark given identifier as a reference to a captured variable itself - * suppressing dereferencing with the `elem` field. - */ - def referenceCapturedVariable(id: Ident): Tree - - /** Given a tree or type, generate a tree that when executed at runtime produces the original tree or type. - * For instance, given the abstract syntax tree representation of the `x + 1` expression: - * - * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1)))) - * - * The reifier transforms it to the following tree: - * - * $mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", , x), "+"), List($mr.Literal($mr.Constant(1)))))) - * - * The transformation looks mostly straightforward, but it has its tricky parts: - * * Reifier retains symbols and types defined outside the reified tree, however - * locally defined entities get erased and replaced with their original trees - * * Free variables are detected and wrapped in symbols of the type FreeVar - * * Mutable variables that are accessed from a local function are wrapped in refs - * * Since reified trees can be compiled outside of the scope they've been created in, - * special measures are taken to ensure that all freeVars remain visible - * - * Typical usage of this function is to retain some of the trees received/created by a macro - * into the form that can be inspected (via pattern matching) or compiled/run (by a reflective ToolBox) during the runtime. - */ - def reify(tree: Tree): Tree -} diff --git a/src/library/scala/reflect/makro/Aliases.scala b/src/library/scala/reflect/makro/Aliases.scala new file mode 100644 index 0000000000..e8b847600c --- /dev/null +++ b/src/library/scala/reflect/makro/Aliases.scala @@ -0,0 +1,26 @@ +package scala.reflect.makro + +trait Aliases { + self: Context => + + /** Aliases of mirror types */ + type Symbol = mirror.Symbol + type Type = mirror.Type + type Name = mirror.Name + type Tree = mirror.Tree + type Position = mirror.Position + type Scope = mirror.Scope + type Modifiers = mirror.Modifiers + type Expr[+T] = mirror.Expr[T] + type TypeTag[T] = mirror.TypeTag[T] + + /** Creator/extractor objects for Expr and TypeTag values */ + val TypeTag = mirror.TypeTag + val Expr = mirror.Expr + + /** incantations for summoning tags */ + def tag[T](implicit ttag: TypeTag[T]) = ttag + def typeTag[T](implicit ttag: TypeTag[T]) = ttag + def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag + def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag +} diff --git a/src/library/scala/reflect/makro/CapturedVariables.scala b/src/library/scala/reflect/makro/CapturedVariables.scala new file mode 100644 index 0000000000..6ce832b2b3 --- /dev/null +++ b/src/library/scala/reflect/makro/CapturedVariables.scala @@ -0,0 +1,20 @@ +package scala.reflect.makro + +trait CapturedVariables { + self: Context => + + import mirror._ + + /** Mark a variable as captured; i.e. force boxing in a *Ref type. + */ + def captureVariable(vble: Symbol): Unit + + /** Mark given identifier as a reference to a captured variable itself + * suppressing dereferencing with the `elem` field. + */ + def referenceCapturedVariable(vble: Symbol): Tree + + /** Convert type of a captured variable to *Ref type. + */ + def capturedVariableType(vble: Symbol): Type +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala new file mode 100644 index 0000000000..96a41377b3 --- /dev/null +++ b/src/library/scala/reflect/makro/Context.scala @@ -0,0 +1,59 @@ +package scala.reflect.makro + +// todo. introduce context hierarchy +// the most lightweight context should just expose the stuff from the SIP +// the full context should include all traits from scala.reflect.makro (and probably reside in scala-compiler.jar) + +trait Context extends Aliases + with CapturedVariables + with Enclosures + with Infrastructure + with Names + with Reifiers + with Reporters + with Settings + with Symbols + with Typers + with Util { + + /** The mirror that corresponds to the compile-time universe */ + val mirror: scala.reflect.api.Universe + + /** The type of the prefix tree from which the macro is selected */ + type PrefixType + + /** The prefix tree from which the macro is selected */ + val prefix: Expr[PrefixType] + + /** Alias to the underlying mirror's reify */ + def reify[T](expr: T): Expr[T] = macro Context.reify[T] +} + +object Context { + def reify[T](cc: Context{ type PrefixType = Context })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = { + import cc.mirror._ + // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure? + val prefix: Tree = Select(cc.prefix, newTermName("mirror")) + val prefixTpe = cc.typeCheck(TypeApply(Select(prefix, newTermName("asInstanceOf")), List(SingletonTypeTree(prefix)))).tpe + prefix setType prefixTpe + try cc.reifyTree(prefix, expr) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case cc.ReificationError(pos, msg) => + cc.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case cc.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } +} diff --git a/src/library/scala/reflect/makro/Enclosures.scala b/src/library/scala/reflect/makro/Enclosures.scala new file mode 100644 index 0000000000..136d39498e --- /dev/null +++ b/src/library/scala/reflect/makro/Enclosures.scala @@ -0,0 +1,53 @@ +package scala.reflect.makro + +trait Enclosures { + self: Context => + + /** The tree that undergoes macro expansion. + * Can be useful to get an offset or a range position of the entire tree being processed. + */ + val macroApplication: Tree + + /** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only. + * Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion. + * + * Is also priceless for emitting sane error messages for macros that are called by other macros on synthetic (i.e. position-less) trees. + * In that dire case navigate the ``enclosingMacros'' stack, and it will most likely contain at least one macro with a position-ful macro application. + * See ``enclosingPosition'' for a default implementation of this logic. + * + * Unlike `openMacros`, this is a val, which means that it gets initialized when the context is created + * and always stays the same regardless of whatever happens during macro expansion. + */ + val enclosingMacros: List[Context] + + /** Types along with corresponding trees for which implicit arguments are currently searched. + * Can be useful to get information about an application with an implicit parameter that is materialized during current macro expansion. + * + * Unlike `openImplicits`, this is a val, which means that it gets initialized when the context is created + * and always stays the same regardless of whatever happens during macro expansion. + */ + val enclosingImplicits: List[(Type, Tree)] + + /** Tries to guess a position for the enclosing application. + * But that is simple, right? Just dereference ``pos'' of ``macroApplication''? Not really. + * If we're in a synthetic macro expansion (no positions), we must do our best to infer the position of something that triggerd this expansion. + * Surprisingly, quite often we can do this by navigation the ``enclosingMacros'' stack. + */ + val enclosingPosition: Position + + /** Tree that corresponds to the enclosing application, or EmptyTree if not applicable. + */ + val enclosingApplication: Tree + + /** Tree that corresponds to the enclosing method, or EmptyTree if not applicable. + */ + val enclosingMethod: Tree + + /** Tree that corresponds to the enclosing class, or EmptyTree if not applicable. + */ + val enclosingClass: Tree + + /** Compilation unit that contains this macro application. + */ + val enclosingUnit: CompilationUnit +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Infrastructure.scala b/src/library/scala/reflect/makro/Infrastructure.scala new file mode 100644 index 0000000000..2bf49dca77 --- /dev/null +++ b/src/library/scala/reflect/makro/Infrastructure.scala @@ -0,0 +1,73 @@ +package scala.reflect.makro + +trait Infrastructure { + self: Context => + + /** Determines whether the compiler expanding a macro targets JVM. + */ + val forJVM: Boolean + + /** Determines whether the compiler expanding a macro targets CLR. + */ + val forMSIL: Boolean + + /** Determines whether the compiler expanding a macro is a presentation compiler. + */ + val forInteractive: Boolean + + /** Determines whether the compiler expanding a macro is a Scaladoc compiler. + */ + val forScaladoc: Boolean + + /** Exposes current compilation run. + */ + val currentRun: Run + + /** As seen by macro API, compilation run is an opaque type that can be deconstructed into: + * 1) Current compilation unit + * 2) List of all compilation units that comprise the run + */ + type Run + + val Run: RunExtractor + + abstract class RunExtractor { + def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])] + } + + /** As seen by macro API, compilation unit is an opaque type that can be deconstructed into: + * 1) File that corresponds to the unit (if not applicable, null) + * 2) Content of the file (if not applicable, empty array) + * 3) Body, i.e. the AST that represents the compilation unit + */ + type CompilationUnit + + val CompilationUnit: CompilationUnitExtractor + + abstract class CompilationUnitExtractor { + def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)] + } + + /** Returns a macro definition which triggered this macro expansion. + */ + val currentMacro: Symbol + + // todo. redo caches as discussed on Reflecting Meeting 2012/03/29 + // https://docs.google.com/document/d/1oUZGQpdt2qwioTlJcSt8ZFQwVLTvpxn8xa67P8OGVpU/edit + + /** A cache shared by all invocations of all macros across all compilation runs. + * + * Needs to be used with extreme care, since memory leaks here will swiftly crash the presentation compiler. + * For example, Scala IDE typically launches a compiler run on every edit action so there might be hundreds of runs per minute. + */ + val globalCache: collection.mutable.Map[Any, Any] + + /** A cache shared by all invocations of the same macro within a single compilation run. + * + * This cache is cleared automatically after a compilation run is completed or abandoned. + * It is also specific to a particular macro definition. + * + * To share data between different macros and/or different compilation runs, use ``globalCache''. + */ + val cache: collection.mutable.Map[Any, Any] +} diff --git a/src/library/scala/reflect/makro/Names.scala b/src/library/scala/reflect/makro/Names.scala new file mode 100644 index 0000000000..8a823d19cb --- /dev/null +++ b/src/library/scala/reflect/makro/Names.scala @@ -0,0 +1,14 @@ +package scala.reflect.makro + +trait Names { + self: Context => + + /** Creates a fresh string */ + def fresh(): String + + /** Creates a fresh string from the provided string */ + def fresh(name: String): String + + /** Creates a fresh name from the provided name */ + def fresh(name: Name): Name +} diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala new file mode 100644 index 0000000000..9bd25cf0f8 --- /dev/null +++ b/src/library/scala/reflect/makro/Reifiers.scala @@ -0,0 +1,82 @@ +package scala.reflect.makro + +trait Reifiers { + self: Context => + + /** Reification prefix that refers to the standard reflexive mirror, ``scala.reflect.mirror''. + * Providing it for the ``prefix'' parameter of ``reifyTree'' or ``reifyType'' will create a tree that can be inspected at runtime. + */ + val reflectMirrorPrefix: Tree + + /** Given a tree, generate a tree that when compiled and executed produces the original tree. + * The produced tree will be bound to the mirror specified by ``prefix'' (also see ``reflectMirrorPrefix''). + * For more information and examples see the documentation for ``Universe.reify''. + * + * This function is deeply connected to ``Universe.reify'', a macro that reifies arbitrary expressions into runtime trees. + * They do very similar things (``Universe.reify'' calls ``Context.reifyTree'' to implement itself), but they operate on different metalevels (see below). + * + * Let's study the differences between ``Context.reifyTree'' and ``Universe.reify'' on an example of using them inside a ``fooMacro'' macro: + * + * * Since reify itself is a macro, it will be executed when fooMacro is being compiled (metalevel -1) + * and will produce a tree that when evaluated during macro expansion of fooMacro (metalevel 0) will recreate the input tree. + * + * This provides a facility analogous to quasi-quoting. Writing "reify{ expr }" will generate an AST that represents expr. + * Afterwards this AST (or its parts) can be used to construct the return value of fooMacro. + * + * * reifyTree is evaluated during macro expansion (metalevel 0) + * and will produce a tree that when evaluated during the runtime of the program (metalevel 1) will recreate the input tree. + * + * This provides a way to retain certain trees from macro expansion time to be inspected later, in the runtime. + * For example, DSL authors may find it useful to capture DSL snippets into ASTs that are then processed at runtime in a domain-specific way. + * + * Also note the difference between universes of the runtime trees produced by two reifies: + * + * * The result of compiling and running the result of reify will be bound to the Universe that called reify. + * This is possible because it's a macro, so it can generate whatever code it wishes. + * + * * The result of compiling and running the result of reifyTree will be the ``prefix'' that needs to be passed explicitly. + * This happens because the Universe of the evaluated result is from a different metalevel than the Context the called reify. + * + * Typical usage of this function is to retain some of the trees received/created by a macro + * into the form that can be inspected (via pattern matching) or compiled/run (by a reflective ToolBox) during the runtime. + */ + def reifyTree(prefix: Tree, tree: Tree): Tree + + /** Given a type, generate a tree that when compiled and executed produces the original type. + * The produced tree will be bound to the mirror specified by ``prefix'' (also see ``reflectMirrorPrefix''). + * For more information and examples see the documentation for ``Context.reifyTree'' and ``Universe.reify''. + */ + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Tree + + /** Undoes reification of a tree. + * + * This reversion doesn't simply restore the original tree (that would lose the context of reification), + * but does something more involved that conforms to the following laws: + * + * 1) unreifyTree(reifyTree(tree)) != tree // unreified tree is tree + saved context + * // in current implementation, the result of unreify is opaque + * // i.e. there's no possibility to inspect underlying tree/context + * + * 2) reifyTree(unreifyTree(reifyTree(tree))) == reifyTree(tree) // the result of reifying a tree in its original context equals to + * // the result of reifying a tree along with its saved context + * + * 3) compileAndEval(unreifyTree(reifyTree(tree))) ~ compileAndEval(tree) // at runtime original and unreified trees are behaviorally equivalent + */ + def unreifyTree(tree: Tree): Tree + + /** Represents an error during reification + */ + type ReificationError <: Throwable + val ReificationError: ReificationErrorExtractor + abstract class ReificationErrorExtractor { + def unapply(error: ReificationError): Option[(Position, String)] + } + + /** Wraps an unexpected error during reification + */ + type UnexpectedReificationError <: Throwable + val UnexpectedReificationError: UnexpectedReificationErrorExtractor + abstract class UnexpectedReificationErrorExtractor { + def unapply(error: UnexpectedReificationError): Option[(Position, String, Throwable)] + } +} diff --git a/src/library/scala/reflect/makro/Reporters.scala b/src/library/scala/reflect/makro/Reporters.scala new file mode 100644 index 0000000000..7341b0e0b7 --- /dev/null +++ b/src/library/scala/reflect/makro/Reporters.scala @@ -0,0 +1,39 @@ +package scala.reflect.makro + +trait Reporters { + self: Context => + + import mirror._ + + /** Exposes means to control the compiler UI */ + def reporter: Reporter + def setReporter(reporter: Reporter): this.type + def withReporter[T](reporter: Reporter)(op: => T): T + + /** For sending a message which should not be labeled as a warning/error, + * but also shouldn't require -verbose to be visible. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def echo(pos: Position, msg: String): Unit + + /** Informational messages, suppressed unless -verbose or force=true. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def info(pos: Position, msg: String, force: Boolean): Unit + + /** Warnings and errors. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def hasWarnings: Boolean + def hasErrors: Boolean + def warning(pos: Position, msg: String): Unit + def error(pos: Position, msg: String): Unit + + /** Abruptly terminates current macro expansion leaving a note about what happened. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def abort(pos: Position, msg: String): Nothing + + /** Drops into interactive mode if supported by the compiler UI */ + def interactive(): Unit +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Settings.scala b/src/library/scala/reflect/makro/Settings.scala new file mode 100644 index 0000000000..c4a8ebd1b5 --- /dev/null +++ b/src/library/scala/reflect/makro/Settings.scala @@ -0,0 +1,38 @@ +package scala.reflect.makro + +trait Settings { + self: Context => + + /** Exposes macro-specific settings as a list of strings. + * These settings are passed to the compiler via the "-Xmacro-settings:setting1,setting2...,settingN" command-line option. + */ + def settings: List[String] + + /** 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. + */ + def setCompilerSettings(options: String): this.type + + /** Updates current compiler settings with a list of options. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + def setCompilerSettings(options: List[String]): this.type + + /** Temporary 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. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + def withCompilerSettings[T](options: List[String])(op: => T): T +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Symbols.scala b/src/library/scala/reflect/makro/Symbols.scala new file mode 100644 index 0000000000..91a5f6d8a5 --- /dev/null +++ b/src/library/scala/reflect/makro/Symbols.scala @@ -0,0 +1,17 @@ +package scala.reflect.makro + +trait Symbols { + self: Context => + + /** Can this symbol be loaded by a reflective mirror? + * + * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs. + * Such annotations (also called "pickles") are applied on top-level classes and include information + * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block) + * are typically unreachable and information about them gets lost. + * + * This method is useful for macro writers who wish to save certain ASTs to be used at runtime. + * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment. + */ + def isLocatable(sym: Symbol): Boolean +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Typers.scala b/src/library/scala/reflect/makro/Typers.scala new file mode 100644 index 0000000000..1ced2daccd --- /dev/null +++ b/src/library/scala/reflect/makro/Typers.scala @@ -0,0 +1,85 @@ +package scala.reflect.makro + +trait Typers { + self: Context => + + import mirror._ + + /** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only. + * Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion. + * + * Is also priceless for emitting sane error messages for macros that are called by other macros on synthetic (i.e. position-less) trees. + * In that dire case navigate the ``openMacros'' stack, and it will most likely contain at least one macro with a position-ful macro application. + * See ``enclosingPosition'' for a default implementation of this logic. + * + * Unlike `enclosingMacros`, this is a def, which means that it gets recalculated on every invocation, + * so it might change depending on what is going on during macro expansion. + */ + def openMacros: List[Context] + + /** Types along with corresponding trees for which implicit arguments are currently searched. + * Can be useful to get information about an application with an implicit parameter that is materialized during current macro expansion. + * + * Unlike `enclosingImplicits`, this is a def, which means that it gets recalculated on every invocation, + * so it might change depending on what is going on during macro expansion. + */ + def openImplicits: List[(Type, Tree)] + + /** Typechecks the provided tree against the expected type ``pt'' in the macro callsite context. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Ymacro-debug. + * Unlike in ``inferImplicitValue'' and ``inferImplicitView'', ``silent'' is false by default. + * + * Typechecking can be steered with the following optional parameters: + * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false + * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false + */ + def typeCheck(tree: Tree, pt: Type = WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree + + /** Infers an implicit value of the expected type ``pt'' in the macro callsite context. + * Optional ``pos'' parameter provides a position that will be associated with the implicit search. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree + + /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context. + * + * Optional ``pos'' parameter provides a position that will be associated with the implicit search. + * Another optional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported. + * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree + + /** Recursively resets symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetAllAttrs[T <: Tree](tree: T): T + + /** Recursively resets locally defined symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetLocalAttrs[T <: Tree](tree: T): T + + /** Represents an error during typechecking + */ + type TypeError <: Throwable + val TypeError: TypeErrorExtractor + abstract class TypeErrorExtractor { + def unapply(error: TypeError): Option[(Position, String)] + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Util.scala b/src/library/scala/reflect/makro/Util.scala new file mode 100644 index 0000000000..16eb2395a9 --- /dev/null +++ b/src/library/scala/reflect/makro/Util.scala @@ -0,0 +1,31 @@ +package scala.reflect.makro + +trait Util { + self: Context => + + def literalNull: Expr[Null] + + def literalUnit: Expr[Unit] + + def literalTrue: Expr[Boolean] + + def literalFalse: Expr[Boolean] + + def literal(x: Boolean): Expr[Boolean] + + def literal(x: Byte): Expr[Byte] + + def literal(x: Short): Expr[Short] + + def literal(x: Int): Expr[Int] + + def literal(x: Long): Expr[Long] + + def literal(x: Float): Expr[Float] + + def literal(x: Double): Expr[Double] + + def literal(x: String): Expr[String] + + def literal(x: Char): Expr[Char] +} diff --git a/src/library/scala/reflect/makro/internal/macroImpl.scala b/src/library/scala/reflect/makro/internal/macroImpl.scala new file mode 100644 index 0000000000..86600ba0a1 --- /dev/null +++ b/src/library/scala/reflect/makro/internal/macroImpl.scala @@ -0,0 +1,5 @@ +package scala.reflect.makro +package internal + +/** This type is required by the compiler and should not be used in client code. */ +class macroImpl(val referenceToMacroImpl: Any) extends StaticAnnotation diff --git a/src/library/scala/reflect/makro/internal/typeTagImpl.scala b/src/library/scala/reflect/makro/internal/typeTagImpl.scala new file mode 100644 index 0000000000..6c49ef45de --- /dev/null +++ b/src/library/scala/reflect/makro/internal/typeTagImpl.scala @@ -0,0 +1,133 @@ +package scala.reflect.makro + +import scala.reflect.api.Universe + +/** This package is required by the compiler and should not be used in client code. */ +package object internal { + /** This method is required by the compiler and should not be used in client code. */ + def materializeClassTag[T](u: Universe): ClassTag[T] = macro materializeClassTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeClassTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[ClassTag[T]] = + c.Expr[Nothing](c.materializeClassTag(u.tree, implicitly[c.TypeTag[T]].tpe))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + def materializeTypeTag[T](u: Universe): u.TypeTag[T] = macro materializeTypeTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.TypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireGroundTypeTag = false))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + def materializeGroundTypeTag[T](u: Universe): u.GroundTypeTag[T] = macro materializeGroundTypeTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeGroundTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.GroundTypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireGroundTypeTag = true))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + private[scala] implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils +} + +package internal { + private[scala] abstract class Utils { + val c: Context + + import c.mirror._ + import definitions._ + + val coreTags = Map( + ByteClass.asType -> newTermName("Byte"), + ShortClass.asType -> newTermName("Short"), + CharClass.asType -> newTermName("Char"), + IntClass.asType -> newTermName("Int"), + LongClass.asType -> newTermName("Long"), + FloatClass.asType -> newTermName("Float"), + DoubleClass.asType -> newTermName("Double"), + BooleanClass.asType -> newTermName("Boolean"), + UnitClass.asType -> newTermName("Unit"), + AnyClass.asType -> newTermName("Any"), + ObjectClass.asType -> newTermName("Object"), + AnyValClass.asType -> newTermName("AnyVal"), + AnyRefClass.asType -> newTermName("AnyRef"), + NothingClass.asType -> newTermName("Nothing"), + NullClass.asType -> newTermName("Null")) + + def materializeClassTag(prefix: Tree, tpe: Type): Tree = { + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, TypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == GroundTypeTagModule)) + typetagInScope match { + case success if !success.isEmpty && !typetagIsSynthetic(success) => + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(Select(typetagInScope, newTermName("tpe")))) + case _ => + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Ident(ClassTagModule), coreTags(coreTpe)) + case _ => + if (tpe.typeSymbol == ArrayClass) { + val componentTpe = tpe.typeArguments(0) + val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe))) + val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe) + Select(componentTag, newTermName("wrap")) + } else { + // [Eugene] what's the intended behavior? there's no spec on ClassManifests + // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? + // if its the latter, what should be the result of tagging Array[T] where T <: Int? + if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type") + val erasure = + if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct? + else tpe.erasure.normalize // necessary to deal with erasures of HK types + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure))))) + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + } + + def materializeTypeTag(prefix: Tree, tpe: Type, requireGroundTypeTag: Boolean): Tree = { + val tagModule = if (requireGroundTypeTag) GroundTypeTagModule else TypeTagModule + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Select(prefix, tagModule.name), coreTags(coreTpe)) + case _ => + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireGroundTypeTag = requireGroundTypeTag) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + val ex1 = ex + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case c.ReificationError(pos, msg) => + c.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case c.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + + private def fail(reason: Any): Nothing = { + val Apply(TypeApply(fun, List(tpeTree)), _) = c.macroApplication + val tpe = tpeTree.tpe + val PolyType(_, MethodType(_, tagTpe)) = fun.tpe + val tagModule = tagTpe.typeSymbol.companionSymbol + if (c.compilerSettings.contains("-Xlog-implicits")) + c.echo(c.enclosingPosition, "cannot materialize " + tagModule.name + "[" + tpe + "] because:\n" + reason) + c.abort(c.enclosingPosition, "No %s available for %s".format(tagModule.name, tpe)) + } + } +} diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 1c3e618520..7a8267e689 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -2,21 +2,28 @@ package scala package object reflect { + import ReflectionUtils._ + // !!! This was a val; we can't throw exceptions that aggressively without breaking // non-standard environments, e.g. google app engine. I made it a lazy val, but // I think it would be better yet to throw the exception somewhere else - not during // initialization, but in response to a doomed attempt to utilize it. - lazy val mirror: api.Mirror = { + + // todo. default mirror (a static object) might become a source for memory leaks (because it holds a strong reference to a classloader)! + lazy val mirror: api.Mirror = mkMirror(defaultReflectionClassLoader) + + def mkMirror(classLoader: ClassLoader): api.Mirror = { // we use (Java) reflection here so that we can keep reflect.runtime and reflect.internals in a seperate jar - ReflectionUtils.singletonInstanceOpt("scala.reflect.runtime.Mirror") collect { case x: api.Mirror => x } getOrElse { - throw new UnsupportedOperationException("Scala reflection not available on this platform") + // note that we must instantiate the mirror with current classloader, otherwise we won't be able to cast it to api.Mirror + // that's not a problem, though, because mirror can service classes from arbitrary classloaders + val instance = invokeFactoryOpt(getClass.getClassLoader, "scala.reflect.runtime.package", "mkMirror", classLoader) + instance match { + case Some(x: api.Mirror) => x + case Some(_) => throw new UnsupportedOperationException("Available scala reflection implementation is incompatible with this interface") + case None => throw new UnsupportedOperationException("Scala reflection not available on this platform") } } - type Symbol = mirror.Symbol - type Type = mirror.Type - type Tree = mirror.Tree - @deprecated("Use `@scala.beans.BeanDescription` instead", "2.10.0") type BeanDescription = scala.beans.BeanDescription @deprecated("Use `@scala.beans.BeanDisplayName` instead", "2.10.0") @@ -31,4 +38,26 @@ package object reflect { type BooleanBeanProperty = scala.beans.BooleanBeanProperty @deprecated("Use `@scala.beans.ScalaBeanInfo` instead", "2.10.0") type ScalaBeanInfo = scala.beans.ScalaBeanInfo + + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") + type ClassManifest[T] = ClassTag[T] + @deprecated("OptManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") + type OptManifest[T] = TypeTag[T] + @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + type Manifest[T] = GroundTypeTag[T] + + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") + val ClassManifest = ClassTag + @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + lazy val Manifest = GroundTypeTag + @deprecated("NoManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") + object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.definitions.NothingClass.asType) with Serializable + + // ClassTag class is defined separately from the mirror + type TypeTag[T] = scala.reflect.mirror.TypeTag[T] + type GroundTypeTag[T] = scala.reflect.mirror.GroundTypeTag[T] + + // ClassTag object is defined separately from the mirror + lazy val TypeTag = scala.reflect.mirror.TypeTag + lazy val GroundTypeTag = scala.reflect.mirror.GroundTypeTag } diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 8bc63ae3a0..d06eba8f7d 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -31,7 +31,7 @@ object ScalaRunTime { clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) def isValueClass(clazz: Class[_]) = clazz.isPrimitive() - def isTuple(x: Any) = tupleNames(x.getClass.getName) + def isTuple(x: Any) = x != null && tupleNames(x.getClass.getName) def isAnyVal(x: Any) = x match { case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true case _ => false diff --git a/src/library/scala/util/Marshal.scala b/src/library/scala/util/Marshal.scala index daeaf4c53b..c2269cde45 100644 --- a/src/library/scala/util/Marshal.scala +++ b/src/library/scala/util/Marshal.scala @@ -35,7 +35,8 @@ object Marshal { def load[A](buffer: Array[Byte])(implicit expected: ClassManifest[A]): A = { val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) val found = in.readObject.asInstanceOf[ClassManifest[_]] - if (found <:< expected) { + // todo. [Eugene] needs review, since ClassManifests no longer capture typeArguments + if (found.tpe <:< expected.tpe) { val o = in.readObject.asInstanceOf[A] in.close() o diff --git a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala index fa533eeb10..8d239a84bd 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala @@ -96,6 +96,7 @@ class ConsoleFileManager extends FileManager { latestActorsFile = dir / "lib/scala-actors.jar" latestCompFile = dir / "lib/scala-compiler.jar" latestPartestFile = dir / "lib/scala-partest.jar" + latestFjbgFile = testParent / "lib" / "fjbg.jar" } else { def setupQuick() { diff --git a/src/partest/scala/tools/partest/nest/TestFile.scala b/src/partest/scala/tools/partest/nest/TestFile.scala index fc5792e886..1aa0a7baf6 100644 --- a/src/partest/scala/tools/partest/nest/TestFile.scala +++ b/src/partest/scala/tools/partest/nest/TestFile.scala @@ -35,7 +35,9 @@ abstract class TestFile(val kind: String) extends TestFileCommon { if (setOutDir) settings.outputDirs setSingleOutput setOutDirTo.path - // adding code.jar to the classpath (to provide Code.lift services for reification tests) + // adding codelib.jar to the classpath + // codelib provides the possibility to override standard reify + // this shields the massive amount of reification tests from changes in the API settings.classpath prepend PathSettings.srcCodeLib.toString if (propIsSet("java.class.path")) setProp("java.class.path", PathSettings.srcCodeLib.toString + ";" + propOrElse("java.class.path", "")) diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index cb6f2a0edc..00ee8ba857 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -181,7 +181,9 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor // private def replaceSlashes(dir: File, s: String): String = { val base = (dir.getAbsolutePath + File.separator).replace('\\', '/') - s.replace('\\', '/').replaceAll("""\Q%s\E""" format base, "") + var regex = """\Q%s\E""" format base + if (isWin) regex = "(?i)" + regex + s.replace('\\', '/').replaceAll(regex, "") } private def currentFileString = { @@ -521,9 +523,15 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor runTestCommon(file, expectFailure = false)((logFile, outDir) => { val dir = file.getParentFile - // adding code.jar to the classpath (to provide Code.lift services for reification tests) - execTest(outDir, logFile, PathSettings.srcCodeLib.toString) && - diffCheck(compareOutput(dir, logFile)) + // adding codelib.jar to the classpath + // codelib provides the possibility to override standard reify + // this shields the massive amount of reification tests from changes in the API + execTest(outDir, logFile, PathSettings.srcCodeLib.toString) && { + // cannot replace paths here since this also inverts slashes + // which affects a bunch of tests + //fileManager.mapFile(logFile, replaceSlashes(dir, _)) + diffCheck(compareOutput(dir, logFile)) + } }) // Apache Ant 1.6 or newer diff --git a/test/files/codelib/code.jar.desired.sha1 b/test/files/codelib/code.jar.desired.sha1 index 8dabf404b9..21c4dccb30 100644 --- a/test/files/codelib/code.jar.desired.sha1 +++ b/test/files/codelib/code.jar.desired.sha1 @@ -1 +1 @@ -e76a8883d275ca4870f745b505fb0a1cb9cbe446 ?code.jar +3ddb9fded6e19ca591a78b8a294284c9e945da30 ?code.jar diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index 243c9aa3be..d93e314d8e 100755 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -1,372 +1,372 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> - -scala> // basics - -scala> 3+4 -res0: Int = 7 - -scala> def gcd(x: Int, y: Int): Int = { - if (x == 0) y - else if (y == 0) x - else gcd(y%x, x) -} -gcd: (x: Int, y: Int)Int - -scala> val five = gcd(15,35) -five: Int = 5 - -scala> var x = 1 -x: Int = 1 - -scala> x = 2 -x: Int = 2 - -scala> val three = x+1 -three: Int = 3 - -scala> type anotherint = Int -defined type alias anotherint - -scala> val four: anotherint = 4 -four: anotherint = 4 - -scala> val bogus: anotherint = "hello" -:8: error: type mismatch; - found : String("hello") - required: anotherint - (which expands to) Int - val bogus: anotherint = "hello" - ^ - -scala> trait PointlessTrait -defined trait PointlessTrait - -scala> val (x,y) = (2,3) -x: Int = 2 -y: Int = 3 - -scala> println("hello") -hello - -scala> - -scala> // ticket #1513 - -scala> val t1513 = Array(null) -t1513: Array[Null] = Array(null) - -scala> // ambiguous toString problem from #547 - -scala> val atom = new scala.xml.Atom() -atom: scala.xml.Atom[Unit] = () - -scala> // overriding toString problem from #1404 - -scala> class S(override val toString : String) -defined class S - -scala> val fish = new S("fish") -fish: S = fish - -scala> // Test that arrays pretty print nicely. - -scala> val arr = Array("What's", "up", "doc?") -arr: Array[String] = Array(What's, up, doc?) - -scala> // Test that arrays pretty print nicely, even when we give them type Any - -scala> val arrInt : Any = Array(1,2,3) -arrInt: Any = Array(1, 2, 3) - -scala> // Test that nested arrays are pretty-printed correctly - -scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4)) -arrArrInt: Any = Array(Array(1, 2), Array(3, 4)) - -scala> - -scala> // implicit conversions - -scala> case class Foo(n: Int) -defined class Foo - -scala> case class Bar(n: Int) -defined class Bar - -scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) -foo2bar: (foo: Foo)Bar - -scala> val bar: Bar = Foo(3) -bar: Bar = Bar(3) - -scala> - -scala> // importing from a previous result - -scala> import bar._ -import bar._ - -scala> val m = n -m: Int = 3 - -scala> - -scala> // stressing the imports mechanism - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> - -scala> - -scala> val x1 = 1 -x1: Int = 1 - -scala> val x2 = 1 -x2: Int = 1 - -scala> val x3 = 1 -x3: Int = 1 - -scala> val x4 = 1 -x4: Int = 1 - -scala> val x5 = 1 -x5: Int = 1 - -scala> val x6 = 1 -x6: Int = 1 - -scala> val x7 = 1 -x7: Int = 1 - -scala> val x8 = 1 -x8: Int = 1 - -scala> val x9 = 1 -x9: Int = 1 - -scala> val x10 = 1 -x10: Int = 1 - -scala> val x11 = 1 -x11: Int = 1 - -scala> val x12 = 1 -x12: Int = 1 - -scala> val x13 = 1 -x13: Int = 1 - -scala> val x14 = 1 -x14: Int = 1 - -scala> val x15 = 1 -x15: Int = 1 - -scala> val x16 = 1 -x16: Int = 1 - -scala> val x17 = 1 -x17: Int = 1 - -scala> val x18 = 1 -x18: Int = 1 - -scala> val x19 = 1 -x19: Int = 1 - -scala> val x20 = 1 -x20: Int = 1 - -scala> - -scala> val two = one + x5 -two: Int = 2 - -scala> - -scala> // handling generic wildcard arrays (#2386) - -scala> // It's put here because type feedback is an important part of it. - -scala> val xs: Array[_] = Array(1, 2) -xs: Array[_] = Array(1, 2) - -scala> xs.size -res2: Int = 2 - -scala> xs.head -res3: Any = 1 - -scala> xs filter (_ == 2) -res4: Array[_] = Array(2) - -scala> xs map (_ => "abc") -res5: Array[String] = Array(abc, abc) - -scala> xs map (x => x) -res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(1, 2) - -scala> xs map (x => (x, x)) -res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) - -scala> - -scala> // interior syntax errors should *not* go into multi-line input mode. - -scala> // both of the following should abort immediately: - -scala> def x => y => z -:1: error: '=' expected but '=>' found. - def x => y => z - ^ - -scala> [1,2,3] -:1: error: illegal start of definition - [1,2,3] - ^ - -scala> - -scala> - -scala> // multi-line XML - -scala> - -res8: scala.xml.Elem = - - - -scala> - -scala> - -scala> /* - /* - multi-line comment - */ -*/ - -scala> - -scala> - -scala> // multi-line string - -scala> """ -hello -there -""" -res9: String = -" -hello -there -" - -scala> - -scala> (1 + // give up early by typing two blank lines - - -You typed two blank lines. Starting a new command. - -scala> // defining and using quoted names should work (ticket #323) - -scala> def `match` = 1 -match: Int - -scala> val x = `match` -x: Int = 1 - -scala> - -scala> // multiple classes defined on one line - -scala> sealed class Exp; class Fact extends Exp; class Term extends Exp -defined class Exp -defined class Fact -defined class Term - -scala> def f(e: Exp) = e match { // non-exhaustive warning here - case _:Fact => 3 -} -:18: warning: match is not exhaustive! -missing combination Exp -missing combination Term - - def f(e: Exp) = e match { // non-exhaustive warning here - ^ -f: (e: Exp)Int - -scala> - -scala> +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> // basics + +scala> 3+4 +res0: Int = 7 + +scala> def gcd(x: Int, y: Int): Int = { + if (x == 0) y + else if (y == 0) x + else gcd(y%x, x) +} +gcd: (x: Int, y: Int)Int + +scala> val five = gcd(15,35) +five: Int = 5 + +scala> var x = 1 +x: Int = 1 + +scala> x = 2 +x: Int = 2 + +scala> val three = x+1 +three: Int = 3 + +scala> type anotherint = Int +defined type alias anotherint + +scala> val four: anotherint = 4 +four: anotherint = 4 + +scala> val bogus: anotherint = "hello" +:8: error: type mismatch; + found : String("hello") + required: anotherint + (which expands to) Int + val bogus: anotherint = "hello" + ^ + +scala> trait PointlessTrait +defined trait PointlessTrait + +scala> val (x,y) = (2,3) +x: Int = 2 +y: Int = 3 + +scala> println("hello") +hello + +scala> + +scala> // ticket #1513 + +scala> val t1513 = Array(null) +t1513: Array[Null] = Array(null) + +scala> // ambiguous toString problem from #547 + +scala> val atom = new scala.xml.Atom() +atom: scala.xml.Atom[Unit] = () + +scala> // overriding toString problem from #1404 + +scala> class S(override val toString : String) +defined class S + +scala> val fish = new S("fish") +fish: S = fish + +scala> // Test that arrays pretty print nicely. + +scala> val arr = Array("What's", "up", "doc?") +arr: Array[String] = Array(What's, up, doc?) + +scala> // Test that arrays pretty print nicely, even when we give them type Any + +scala> val arrInt : Any = Array(1,2,3) +arrInt: Any = Array(1, 2, 3) + +scala> // Test that nested arrays are pretty-printed correctly + +scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4)) +arrArrInt: Any = Array(Array(1, 2), Array(3, 4)) + +scala> + +scala> // implicit conversions + +scala> case class Foo(n: Int) +defined class Foo + +scala> case class Bar(n: Int) +defined class Bar + +scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) +foo2bar: (foo: Foo)Bar + +scala> val bar: Bar = Foo(3) +bar: Bar = Bar(3) + +scala> + +scala> // importing from a previous result + +scala> import bar._ +import bar._ + +scala> val m = n +m: Int = 3 + +scala> + +scala> // stressing the imports mechanism + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> + +scala> + +scala> val x1 = 1 +x1: Int = 1 + +scala> val x2 = 1 +x2: Int = 1 + +scala> val x3 = 1 +x3: Int = 1 + +scala> val x4 = 1 +x4: Int = 1 + +scala> val x5 = 1 +x5: Int = 1 + +scala> val x6 = 1 +x6: Int = 1 + +scala> val x7 = 1 +x7: Int = 1 + +scala> val x8 = 1 +x8: Int = 1 + +scala> val x9 = 1 +x9: Int = 1 + +scala> val x10 = 1 +x10: Int = 1 + +scala> val x11 = 1 +x11: Int = 1 + +scala> val x12 = 1 +x12: Int = 1 + +scala> val x13 = 1 +x13: Int = 1 + +scala> val x14 = 1 +x14: Int = 1 + +scala> val x15 = 1 +x15: Int = 1 + +scala> val x16 = 1 +x16: Int = 1 + +scala> val x17 = 1 +x17: Int = 1 + +scala> val x18 = 1 +x18: Int = 1 + +scala> val x19 = 1 +x19: Int = 1 + +scala> val x20 = 1 +x20: Int = 1 + +scala> + +scala> val two = one + x5 +two: Int = 2 + +scala> + +scala> // handling generic wildcard arrays (#2386) + +scala> // It's put here because type feedback is an important part of it. + +scala> val xs: Array[_] = Array(1, 2) +xs: Array[_] = Array(1, 2) + +scala> xs.size +res2: Int = 2 + +scala> xs.head +res3: Any = 1 + +scala> xs filter (_ == 2) +res4: Array[_] = Array(2) + +scala> xs map (_ => "abc") +res5: Array[String] = Array(abc, abc) + +scala> xs map (x => x) +res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(1, 2) + +scala> xs map (x => (x, x)) +res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) + +scala> + +scala> // interior syntax errors should *not* go into multi-line input mode. + +scala> // both of the following should abort immediately: + +scala> def x => y => z +:1: error: '=' expected but '=>' found. + def x => y => z + ^ + +scala> [1,2,3] +:1: error: illegal start of definition + [1,2,3] + ^ + +scala> + +scala> + +scala> // multi-line XML + +scala> + +res8: scala.xml.Elem = + + + +scala> + +scala> + +scala> /* + /* + multi-line comment + */ +*/ + +scala> + +scala> + +scala> // multi-line string + +scala> """ +hello +there +""" +res9: String = +" +hello +there +" + +scala> + +scala> (1 + // give up early by typing two blank lines + + +You typed two blank lines. Starting a new command. + +scala> // defining and using quoted names should work (ticket #323) + +scala> def `match` = 1 +match: Int + +scala> val x = `match` +x: Int = 1 + +scala> + +scala> // multiple classes defined on one line + +scala> sealed class Exp; class Fact extends Exp; class Term extends Exp +defined class Exp +defined class Fact +defined class Term + +scala> def f(e: Exp) = e match { // non-exhaustive warning here + case _:Fact => 3 +} +:18: warning: match is not exhaustive! +missing combination Exp +missing combination Term + + def f(e: Exp) = e match { // non-exhaustive warning here + ^ +f: (e: Exp)Int + +scala> + +scala> plusOne: (x: Int)Int res0: Int = 6 res0: String = after reset diff --git a/test/files/jvm/interpreter.scala b/test/files/jvm/interpreter.scala index f0bc8b5818..1f289d9335 100644 --- a/test/files/jvm/interpreter.scala +++ b/test/files/jvm/interpreter.scala @@ -2,6 +2,7 @@ import scala.tools.nsc._ import scala.tools.partest.ReplTest object Test extends ReplTest { + override def extraSettings = "-deprecation" def code = // basics 3+4 @@ -29,7 +30,7 @@ val atom = new scala.xml.Atom() class S(override val toString : String) val fish = new S("fish") // Test that arrays pretty print nicely. -val arr = Array("What's", "up", "doc?") +val arr = Array("What's", "up", "doc?") // Test that arrays pretty print nicely, even when we give them type Any val arrInt : Any = Array(1,2,3) // Test that nested arrays are pretty-printed correctly @@ -132,8 +133,8 @@ there // defining and using quoted names should work (ticket #323) -def `match` = 1 -val x = `match` +def `match` = 1 +val x = `match` // multiple classes defined on one line sealed class Exp; class Fact extends Exp; class Term extends Exp @@ -153,6 +154,6 @@ def f(e: Exp) = e match {{ // non-exhaustive warning here interp.interpret("\"after reset\"") interp.interpret("plusOne(5) // should be undefined now") } - + appendix() } diff --git a/test/files/jvm/manifests.check b/test/files/jvm/manifests.check deleted file mode 100644 index 54f504b929..0000000000 --- a/test/files/jvm/manifests.check +++ /dev/null @@ -1,55 +0,0 @@ -x=(), m=Unit -x=true, m=Boolean -x=a, m=Char -x=1, m=Int -x=abc, m=java.lang.String -x='abc, m=scala.Symbol - -x=List(()), m=scala.collection.immutable.List[Unit] -x=List(true), m=scala.collection.immutable.List[Boolean] -x=List(1), m=scala.collection.immutable.List[Int] -x=List(abc), m=scala.collection.immutable.List[java.lang.String] -x=List('abc), m=scala.collection.immutable.List[scala.Symbol] - -x=[Z, m=Array[Boolean] -x=[C, m=Array[Char] -x=[I, m=Array[Int] -x=[Ljava.lang.String;, m=Array[java.lang.String] -x=[Lscala.Symbol;, m=Array[scala.Symbol] - -x=((),()), m=scala.Tuple2[Unit, Unit] -x=(true,false), m=scala.Tuple2[Boolean, Boolean] -x=(1,2), m=scala.Tuple2[Int, Int] -x=(abc,xyz), m=scala.Tuple2[java.lang.String, java.lang.String] -x=('abc,'xyz), m=scala.Tuple2[scala.Symbol, scala.Symbol] - - -x=Foo, m=Foo[Int] -x=Foo, m=Foo[scala.collection.immutable.List[Int]] -x=Foo, m=Foo[Foo[Int]] -x=Foo, m=Foo[scala.collection.immutable.List[Foo[Int]]] - -x=Test1$$anon$1, m=Object with Bar[java.lang.String] - -()=() -true=true -a=a -1=1 -'abc='abc - -List(())=List(()) -List(true)=List(true) -List('abc)=List('abc) - -Array()=Array() -Array(true)=Array(true) -Array(a)=Array(a) -Array(1)=Array(1) - -((),())=((),()) -(true,false)=(true,false) - -List(List(1), List(2))=List(List(1), List(2)) - -Array(Array(1), Array(2))=Array(Array(1), Array(2)) - diff --git a/test/files/jvm/manifests.check.temporarily.disabled b/test/files/jvm/manifests.check.temporarily.disabled new file mode 100644 index 0000000000..54f504b929 --- /dev/null +++ b/test/files/jvm/manifests.check.temporarily.disabled @@ -0,0 +1,55 @@ +x=(), m=Unit +x=true, m=Boolean +x=a, m=Char +x=1, m=Int +x=abc, m=java.lang.String +x='abc, m=scala.Symbol + +x=List(()), m=scala.collection.immutable.List[Unit] +x=List(true), m=scala.collection.immutable.List[Boolean] +x=List(1), m=scala.collection.immutable.List[Int] +x=List(abc), m=scala.collection.immutable.List[java.lang.String] +x=List('abc), m=scala.collection.immutable.List[scala.Symbol] + +x=[Z, m=Array[Boolean] +x=[C, m=Array[Char] +x=[I, m=Array[Int] +x=[Ljava.lang.String;, m=Array[java.lang.String] +x=[Lscala.Symbol;, m=Array[scala.Symbol] + +x=((),()), m=scala.Tuple2[Unit, Unit] +x=(true,false), m=scala.Tuple2[Boolean, Boolean] +x=(1,2), m=scala.Tuple2[Int, Int] +x=(abc,xyz), m=scala.Tuple2[java.lang.String, java.lang.String] +x=('abc,'xyz), m=scala.Tuple2[scala.Symbol, scala.Symbol] + + +x=Foo, m=Foo[Int] +x=Foo, m=Foo[scala.collection.immutable.List[Int]] +x=Foo, m=Foo[Foo[Int]] +x=Foo, m=Foo[scala.collection.immutable.List[Foo[Int]]] + +x=Test1$$anon$1, m=Object with Bar[java.lang.String] + +()=() +true=true +a=a +1=1 +'abc='abc + +List(())=List(()) +List(true)=List(true) +List('abc)=List('abc) + +Array()=Array() +Array(true)=Array(true) +Array(a)=Array(a) +Array(1)=Array(1) + +((),())=((),()) +(true,false)=(true,false) + +List(List(1), List(2))=List(List(1), List(2)) + +Array(Array(1), Array(2))=Array(Array(1), Array(2)) + diff --git a/test/files/jvm/manifests.scala b/test/files/jvm/manifests.scala deleted file mode 100644 index 6bbea4d052..0000000000 --- a/test/files/jvm/manifests.scala +++ /dev/null @@ -1,119 +0,0 @@ -object Test extends App { - Test1 - Test2 - //Test3 // Java 1.5+ only -} - -class Foo[T](x: T) -trait Bar[T] { def f: T } - -object Test1 extends TestUtil { - print(()) - print(true) - print('a') - print(1) - print("abc") - print('abc) - println() - - print(List(())) - print(List(true)) - print(List(1)) - print(List("abc")) - print(List('abc)) - println() - - //print(Array(())) //Illegal class name "[V" in class file Test$ - print(Array(true)) - print(Array('a')) - print(Array(1)) - print(Array("abc")) - print(Array('abc)) - println() - - print(((), ())) - print((true, false)) - print((1, 2)) - print(("abc", "xyz")) - print(('abc, 'xyz)) - println() - - // Disabled: should these work? changing the inference for objects from - // "object Test" to "Test.type" drags in a singleton manifest which for - // some reason leads to serialization failure. - // print(Test) - // print(List) - println() - - print(new Foo(2)) - print(new Foo(List(2))) - print(new Foo(new Foo(2))) - print(new Foo(List(new Foo(2)))) - println() - - print(new Bar[String] { def f = "abc" }) - println() -} - -object Test2 { - import scala.util.Marshal._ - println("()="+load[Unit](dump(()))) - println("true="+load[Boolean](dump(true))) - println("a="+load[Char](dump('a'))) - println("1="+load[Int](dump(1))) - println("'abc="+load[Symbol](dump('abc))) - println() - - println("List(())="+load[List[Unit]](dump(List(())))) - println("List(true)="+load[List[Boolean]](dump(List(true)))) - println("List('abc)="+load[List[Symbol]](dump(List('abc)))) - println() - - def loadArray[T](x: Array[Byte])(implicit m: reflect.Manifest[Array[T]]) = - load[Array[T]](x)(m).deep.toString - println("Array()="+loadArray[Int](dump(Array(): Array[Int]))) - println("Array(true)="+loadArray[Boolean](dump(Array(true)))) - println("Array(a)="+loadArray[Char](dump(Array('a')))) - println("Array(1)="+loadArray[Int](dump(Array(1)))) - println() - - println("((),())="+load[(Unit, Unit)](dump(((), ())))) - println("(true,false)="+load[(Boolean, Boolean)](dump((true, false)))) - println() - - println("List(List(1), List(2))="+load[List[List[Int]]](dump(List(List(1), List(2))))) - println() - - println("Array(Array(1), Array(2))="+loadArray[Array[Int]](dump(Array(Array(1), Array(2))))) - println() -} - -object Test3 extends TestUtil { - import scala.reflect.Manifest._ - val ct1 = classType(classOf[Char]) - val ct2 = classType(classOf[List[_]], ct1) - print(ct1) - //print(ct2) // ??? x=scala.List[char], m=scala.reflect.Manifest[scala.runtime.Nothing$] - println() -} - -trait TestUtil { - import java.io._ - def write[A](o: A): Array[Byte] = { - val ba = new ByteArrayOutputStream(512) - val out = new ObjectOutputStream(ba) - out.writeObject(o) - out.close() - ba.toByteArray() - } - def read[A](buffer: Array[Byte]): A = { - val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) - in.readObject().asInstanceOf[A] - } - import scala.reflect._ - def print[T](x: T)(implicit m: Manifest[T]) { - val m1: Manifest[T] = read(write(m)) - val x1 = x.toString.replaceAll("@[0-9a-z]+$", "") - println("x="+x1+", m="+m1) - } -} diff --git a/test/files/jvm/manifests.scala.temporarily.disabled b/test/files/jvm/manifests.scala.temporarily.disabled new file mode 100644 index 0000000000..241966fd9d --- /dev/null +++ b/test/files/jvm/manifests.scala.temporarily.disabled @@ -0,0 +1,109 @@ +object Test extends App { + Test1 + Test2 +} + +class Foo[T](x: T) +trait Bar[T] { def f: T } + +object Test1 extends TestUtil { + print(()) + print(true) + print('a') + print(1) + print("abc") + print('abc) + println() + + print(List(())) + print(List(true)) + print(List(1)) + print(List("abc")) + print(List('abc)) + println() + + //print(Array(())) //Illegal class name "[V" in class file Test$ + print(Array(true)) + print(Array('a')) + print(Array(1)) + print(Array("abc")) + print(Array('abc)) + println() + + print(((), ())) + print((true, false)) + print((1, 2)) + print(("abc", "xyz")) + print(('abc, 'xyz)) + println() + + // Disabled: should these work? changing the inference for objects from + // "object Test" to "Test.type" drags in a singleton manifest which for + // some reason leads to serialization failure. + // print(Test) + // print(List) + println() + + print(new Foo(2)) + print(new Foo(List(2))) + print(new Foo(new Foo(2))) + print(new Foo(List(new Foo(2)))) + println() + + print(new Bar[String] { def f = "abc" }) + println() +} + +object Test2 { + import scala.util.Marshal._ + println("()="+load[Unit](dump(()))) + println("true="+load[Boolean](dump(true))) + println("a="+load[Char](dump('a'))) + println("1="+load[Int](dump(1))) + println("'abc="+load[Symbol](dump('abc))) + println() + + println("List(())="+load[List[Unit]](dump(List(())))) + println("List(true)="+load[List[Boolean]](dump(List(true)))) + println("List('abc)="+load[List[Symbol]](dump(List('abc)))) + println() + + def loadArray[T](x: Array[Byte])(implicit m: reflect.Manifest[Array[T]]) = + load[Array[T]](x)(m).deep.toString + println("Array()="+loadArray[Int](dump(Array(): Array[Int]))) + println("Array(true)="+loadArray[Boolean](dump(Array(true)))) + println("Array(a)="+loadArray[Char](dump(Array('a')))) + println("Array(1)="+loadArray[Int](dump(Array(1)))) + println() + + println("((),())="+load[(Unit, Unit)](dump(((), ())))) + println("(true,false)="+load[(Boolean, Boolean)](dump((true, false)))) + println() + + println("List(List(1), List(2))="+load[List[List[Int]]](dump(List(List(1), List(2))))) + println() + + println("Array(Array(1), Array(2))="+loadArray[Array[Int]](dump(Array(Array(1), Array(2))))) + println() +} + +trait TestUtil { + import java.io._ + def write[A](o: A): Array[Byte] = { + val ba = new ByteArrayOutputStream(512) + val out = new ObjectOutputStream(ba) + out.writeObject(o) + out.close() + ba.toByteArray() + } + def read[A](buffer: Array[Byte]): A = { + val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) + in.readObject().asInstanceOf[A] + } + import scala.reflect._ + def print[T](x: T)(implicit m: Manifest[T]) { + val m1: Manifest[T] = read(write(m)) + val x1 = x.toString.replaceAll("@[0-9a-z]+$", "") + println("x="+x1+", m="+m1) + } +} diff --git a/test/files/macros/Printf.scala b/test/files/macros/Printf.scala deleted file mode 100644 index 4a88e5b069..0000000000 --- a/test/files/macros/Printf.scala +++ /dev/null @@ -1,39 +0,0 @@ -// macros should be built separately from their clients, so simple "scalac Printf.scala Test.scala" won't work -// 1) first build this file with "scalac -Xmacros Printf.scala" -// 2) the build the test with "scalac -cp Test.scala" - -object Printf extends App { - def macro printf(format: String, params: Any*) : String = { - var i = 0 - def gensym(name: String) = { i += 1; newTermName(name + i) } - - def createTempValDef(value: Tree, clazz: Class[_]): (Option[Tree], Tree) = { - val local = gensym("temp") - val tpe = if (clazz == classOf[Int]) Ident(newTypeName("Int")) - else if (clazz == classOf[String]) Select(Select(Ident(newTermName("java")), newTermName("lang")), newTypeName("String")) - else throw new Exception("unknown class " + clazz.toString) - (Some(ValDef(Modifiers(), local, tpe, value)), Ident(local)) - } - - def tree_printf(format: Tree, params: Tree*) = { - val Literal(Constant(s_format: String)) = format - val paramsStack = scala.collection.mutable.Stack(params: _*) - val parsed = s_format.split("(?<=%[\\w%])|(?=%[\\w%])") map { - case "%d" => createTempValDef(paramsStack.pop, classOf[Int]) - case "%s" => createTempValDef(paramsStack.pop, classOf[String]) - case "%%" => (None, Literal(Constant("%"))) - case part => (None, Literal(Constant(part))) - } - - val evals = for ((Some(eval), _) <- parsed if eval != None) yield eval - val prints = for ((_, ref) <- parsed) yield { - val print = Select(Select(Ident(newTermName("scala")), newTermName("Predef")), newTermName("print")) - Apply(print, List(ref)) - } - - Block((evals ++ prints).toList, Literal(Constant(()))) - } - - tree_printf(format, params: _*) - } -} diff --git a/test/files/macros/Test.scala b/test/files/macros/Test.scala deleted file mode 100644 index d8cdcf6756..0000000000 --- a/test/files/macros/Test.scala +++ /dev/null @@ -1,8 +0,0 @@ -// macros should be built separately from their clients, so simple "scalac Printf.scala Test.scala" won't work -// 1) first build the printf macro with "scalac -Xmacros Printf.scala" -// 2) the build this file with "scalac -cp Test.scala" - -object Test extends App { - import Printf._ - printf("hello %s", "world") -} \ No newline at end of file diff --git a/test/files/macros/macros_v0001.bat b/test/files/macros/macros_v0001.bat deleted file mode 100644 index 3395d2e3c1..0000000000 --- a/test/files/macros/macros_v0001.bat +++ /dev/null @@ -1,40 +0,0 @@ -@echo off - -set scalahome=%~dp0\..\..\.. -set scaladeps=%scalahome%\lib\jline.jar;%scalahome%\lib\fjbg.jar -set scalalib=%scalahome%\build\pack\lib\scala-library.jar -if not exist "%scalalib%" set scalalib=%scalahome%\build\locker\classes\library -set scalacomp="%scalahome%\build\pack\lib\scala-compiler.jar" -if not exist "%scalacomp%" set scalacomp=%scalahome%\build\locker\classes\compiler -set stdcp=%scaladeps%;%scalalib%;%scalacomp% - -echo Compiling macros... -set cp=%stdcp% -call :scalac -Xmacros "%~dp0\Printf.scala" - -echo Compiling the program... -set cp=%stdcp%;%~dp0. -call :scalac "%~dp0\Test.scala" - -echo. -echo NOW LOOK!!! -echo =============================================== -set cp=%stdcp%;%~dp0. -call :scala Test -echo. -echo =============================================== -goto :eof - -:scalac -setlocal -call set args=%* -rem echo java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.Main %args% -java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.Main %args% -endlocal&goto :eof - -:scala -setlocal -call set args=%* -rem echo java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner %args% -java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner %args% -endlocal&goto :eof diff --git a/test/files/macros/macros_v0001.sh b/test/files/macros/macros_v0001.sh deleted file mode 100644 index abe09836bb..0000000000 --- a/test/files/macros/macros_v0001.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -set -o errexit - -if [[ $(uname -s) == CYGWIN* ]]; then cpsep=";"; else cpsep=":"; fi -scripthome="$(dirname "$0")" -scalahome="$scripthome/../../.." -scaladeps="$scalahome/lib/jline.jar;$scalahome/lib/fjbg.jar" -scalalib="$scalahome/build/pack/lib/scala-library.jar" -if [ ! -f "$scalalib" ]; then scalalib="$scalahome/build/locker/classes/library"; fi -scalacomp="$scalahome/build/pack/lib/scala-compiler.jar" -if [ ! -f "$scalacomp" ]; then scalacomp="$scalahome/build/locker/classes/compiler"; fi -stdcp="$scaladeps$cpsep$scalalib$cpsep$scalacomp" -function scalac { java -cp "$cp" -Dscala.usejavacp=true scala.tools.nsc.Main $*; } -function scala { java -cp "$cp" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner $*; } - -echo "Compiling macros..." -cp="$stdcp" -scalac -Xmacros "$scripthome/Printf.scala" - -echo "Compiling the program..." -cp="$stdcp$cpsep$scripthome" -scalac "$scripthome/Test.scala" - -echo "" -echo "NOW LOOK" -echo "===============================================" -cp="$stdcp$cpsep$scripthome" -scala Test -echo "" -echo "===============================================" diff --git a/test/files/neg/checksensible.check b/test/files/neg/checksensible.check index d785179a56..23af94180a 100644 --- a/test/files/neg/checksensible.check +++ b/test/files/neg/checksensible.check @@ -1,100 +1,100 @@ -checksensible.scala:13: error: comparing a fresh object using `eq' will always yield false - (new AnyRef) eq (new AnyRef) - ^ -checksensible.scala:14: error: comparing a fresh object using `ne' will always yield true - (new AnyRef) ne (new AnyRef) - ^ -checksensible.scala:15: error: comparing a fresh object using `eq' will always yield false - Shmoopie eq (new AnyRef) - ^ -checksensible.scala:16: error: comparing a fresh object using `eq' will always yield false - (Shmoopie: AnyRef) eq (new AnyRef) - ^ -checksensible.scala:17: error: comparing a fresh object using `eq' will always yield false - (new AnyRef) eq Shmoopie - ^ -checksensible.scala:18: error: comparing a fresh object using `eq' will always yield false - (new AnyRef) eq null - ^ -checksensible.scala:19: error: comparing a fresh object using `eq' will always yield false - null eq new AnyRef - ^ -checksensible.scala:26: error: comparing values of types Unit and Int using `==' will always yield false - (c = 1) == 0 - ^ -checksensible.scala:27: error: comparing values of types Int and Unit using `==' will always yield false - 0 == (c = 1) - ^ -checksensible.scala:29: error: comparing values of types Int and String using `==' will always yield false - 1 == "abc" - ^ -checksensible.scala:33: error: comparing values of types Some[Int] and Int using `==' will always yield false - Some(1) == 1 // as above - ^ -checksensible.scala:38: error: comparing a fresh object using `==' will always yield false - new AnyRef == 1 - ^ -checksensible.scala:41: error: comparing values of types Int and Boolean using `==' will always yield false - 1 == (new java.lang.Boolean(true)) - ^ -checksensible.scala:43: error: comparing values of types Int and Boolean using `!=' will always yield true - 1 != true - ^ -checksensible.scala:44: error: comparing values of types Unit and Boolean using `==' will always yield false - () == true - ^ -checksensible.scala:45: error: comparing values of types Unit and Unit using `==' will always yield true - () == () - ^ -checksensible.scala:46: error: comparing values of types Unit and Unit using `==' will always yield true - () == println - ^ -checksensible.scala:47: error: comparing values of types Unit and scala.runtime.BoxedUnit using `==' will always yield true - () == scala.runtime.BoxedUnit.UNIT // these should warn for always being true/false - ^ -checksensible.scala:48: error: comparing values of types scala.runtime.BoxedUnit and Unit using `!=' will always yield false - scala.runtime.BoxedUnit.UNIT != () - ^ -checksensible.scala:51: error: comparing values of types Int and Unit using `!=' will always yield true - (1 != println) - ^ -checksensible.scala:52: error: comparing values of types Int and Symbol using `!=' will always yield true - (1 != 'sym) - ^ -checksensible.scala:58: error: comparing a fresh object using `==' will always yield false - ((x: Int) => x + 1) == null - ^ -checksensible.scala:59: error: comparing a fresh object using `==' will always yield false - Bep == ((_: Int) + 1) - ^ -checksensible.scala:61: error: comparing a fresh object using `==' will always yield false - new Object == new Object - ^ -checksensible.scala:62: error: comparing a fresh object using `==' will always yield false - new Object == "abc" - ^ -checksensible.scala:63: error: comparing a fresh object using `!=' will always yield true - new Exception() != new Exception() - ^ -checksensible.scala:66: error: comparing values of types Int and Null using `==' will always yield false - if (foo.length == null) "plante" else "plante pas" - ^ -checksensible.scala:71: error: comparing values of types Bip and Bop using `==' will always yield false - (x1 == x2) - ^ -checksensible.scala:81: error: comparing values of types EqEqRefTest.this.C3 and EqEqRefTest.this.Z1 using `==' will always yield false - c3 == z1 - ^ -checksensible.scala:82: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `==' will always yield false - z1 == c3 - ^ -checksensible.scala:83: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `!=' will always yield true - z1 != c3 - ^ -checksensible.scala:84: error: comparing values of types EqEqRefTest.this.C3 and String using `!=' will always yield true - c3 != "abc" - ^ -checksensible.scala:95: error: comparing values of types Unit and Int using `!=' will always yield true - while ((c = in.read) != -1) - ^ -33 errors found +checksensible.scala:13: error: comparing a fresh object using `eq' will always yield false + (new AnyRef) eq (new AnyRef) + ^ +checksensible.scala:14: error: comparing a fresh object using `ne' will always yield true + (new AnyRef) ne (new AnyRef) + ^ +checksensible.scala:15: error: comparing a fresh object using `eq' will always yield false + Shmoopie eq (new AnyRef) + ^ +checksensible.scala:16: error: comparing a fresh object using `eq' will always yield false + (Shmoopie: AnyRef) eq (new AnyRef) + ^ +checksensible.scala:17: error: comparing a fresh object using `eq' will always yield false + (new AnyRef) eq Shmoopie + ^ +checksensible.scala:18: error: comparing a fresh object using `eq' will always yield false + (new AnyRef) eq null + ^ +checksensible.scala:19: error: comparing a fresh object using `eq' will always yield false + null eq new AnyRef + ^ +checksensible.scala:26: error: comparing values of types Unit and Int using `==' will always yield false + (c = 1) == 0 + ^ +checksensible.scala:27: error: comparing values of types Int and Unit using `==' will always yield false + 0 == (c = 1) + ^ +checksensible.scala:29: error: comparing values of types Int and String using `==' will always yield false + 1 == "abc" + ^ +checksensible.scala:33: error: comparing values of types Some[Int] and Int using `==' will always yield false + Some(1) == 1 // as above + ^ +checksensible.scala:38: error: comparing a fresh object using `==' will always yield false + new AnyRef == 1 + ^ +checksensible.scala:41: error: comparing values of types Int and Boolean using `==' will always yield false + 1 == (new java.lang.Boolean(true)) + ^ +checksensible.scala:43: error: comparing values of types Int and Boolean using `!=' will always yield true + 1 != true + ^ +checksensible.scala:44: error: comparing values of types Unit and Boolean using `==' will always yield false + () == true + ^ +checksensible.scala:45: error: comparing values of types Unit and Unit using `==' will always yield true + () == () + ^ +checksensible.scala:46: error: comparing values of types Unit and Unit using `==' will always yield true + () == println + ^ +checksensible.scala:47: error: comparing values of types Unit and scala.runtime.BoxedUnit using `==' will always yield true + () == scala.runtime.BoxedUnit.UNIT // these should warn for always being true/false + ^ +checksensible.scala:48: error: comparing values of types scala.runtime.BoxedUnit and Unit using `!=' will always yield false + scala.runtime.BoxedUnit.UNIT != () + ^ +checksensible.scala:51: error: comparing values of types Int and Unit using `!=' will always yield true + (1 != println) + ^ +checksensible.scala:52: error: comparing values of types Int and Symbol using `!=' will always yield true + (1 != 'sym) + ^ +checksensible.scala:58: error: comparing a fresh object using `==' will always yield false + ((x: Int) => x + 1) == null + ^ +checksensible.scala:59: error: comparing a fresh object using `==' will always yield false + Bep == ((_: Int) + 1) + ^ +checksensible.scala:61: error: comparing a fresh object using `==' will always yield false + new Object == new Object + ^ +checksensible.scala:62: error: comparing a fresh object using `==' will always yield false + new Object == "abc" + ^ +checksensible.scala:63: error: comparing a fresh object using `!=' will always yield true + new Exception() != new Exception() + ^ +checksensible.scala:66: error: comparing values of types Int and Null using `==' will always yield false + if (foo.length == null) "plante" else "plante pas" + ^ +checksensible.scala:71: error: comparing values of types Bip and Bop using `==' will always yield false + (x1 == x2) + ^ +checksensible.scala:81: error: comparing values of types EqEqRefTest.this.C3 and EqEqRefTest.this.Z1 using `==' will always yield false + c3 == z1 + ^ +checksensible.scala:82: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `==' will always yield false + z1 == c3 + ^ +checksensible.scala:83: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `!=' will always yield true + z1 != c3 + ^ +checksensible.scala:84: error: comparing values of types EqEqRefTest.this.C3 and String using `!=' will always yield true + c3 != "abc" + ^ +checksensible.scala:95: error: comparing values of types Unit and Int using `!=' will always yield true + while ((c = in.read) != -1) + ^ +33 errors found diff --git a/test/files/neg/classtags_contextbound_a.check b/test/files/neg/classtags_contextbound_a.check new file mode 100644 index 0000000000..f4b6ff5af1 --- /dev/null +++ b/test/files/neg/classtags_contextbound_a.check @@ -0,0 +1,4 @@ +classtags_contextbound_a.scala:2: error: No ClassTag available for T + def foo[T] = Array[T]() + ^ +one error found diff --git a/test/files/neg/classtags_contextbound_a.scala b/test/files/neg/classtags_contextbound_a.scala new file mode 100644 index 0000000000..d18beda341 --- /dev/null +++ b/test/files/neg/classtags_contextbound_a.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[T] = Array[T]() + println(foo[Int].getClass) +} \ No newline at end of file diff --git a/test/files/neg/classtags_contextbound_b.check b/test/files/neg/classtags_contextbound_b.check new file mode 100644 index 0000000000..f1f48bed72 --- /dev/null +++ b/test/files/neg/classtags_contextbound_b.check @@ -0,0 +1,4 @@ +classtags_contextbound_b.scala:3: error: No ClassTag available for T + def foo[T] = mkArray[T] + ^ +one error found diff --git a/test/files/neg/classtags_contextbound_b.scala b/test/files/neg/classtags_contextbound_b.scala new file mode 100644 index 0000000000..3247a8ff29 --- /dev/null +++ b/test/files/neg/classtags_contextbound_b.scala @@ -0,0 +1,5 @@ +object Test extends App { + def mkArray[T: ClassTag] = Array[T]() + def foo[T] = mkArray[T] + println(foo[Int].getClass) +} \ No newline at end of file diff --git a/test/files/neg/classtags_contextbound_c.check b/test/files/neg/classtags_contextbound_c.check new file mode 100644 index 0000000000..54f630862a --- /dev/null +++ b/test/files/neg/classtags_contextbound_c.check @@ -0,0 +1,4 @@ +classtags_contextbound_c.scala:2: error: No ClassTag available for T + def mkArray[T] = Array[T]() + ^ +one error found diff --git a/test/files/neg/classtags_contextbound_c.scala b/test/files/neg/classtags_contextbound_c.scala new file mode 100644 index 0000000000..0b63f8407e --- /dev/null +++ b/test/files/neg/classtags_contextbound_c.scala @@ -0,0 +1,5 @@ +object Test extends App { + def mkArray[T] = Array[T]() + def foo[T: ClassTag] = mkArray[T] + println(foo[Int].getClass) +} \ No newline at end of file diff --git a/test/files/neg/macro-argtype-mismatch/Macros_1.scala b/test/files/neg/macro-argtype-mismatch/Macros_1.scala deleted file mode 100644 index 4b5f98ba37..0000000000 --- a/test/files/neg/macro-argtype-mismatch/Macros_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Macros { - def macro foo(x: Int) = x -} \ No newline at end of file diff --git a/test/files/neg/macro-argtype-mismatch/Test_2.scala b/test/files/neg/macro-argtype-mismatch/Test_2.scala deleted file mode 100644 index 18feb69425..0000000000 --- a/test/files/neg/macro-argtype-mismatch/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo("2") -} \ No newline at end of file diff --git a/test/files/neg/macro-basic-mamdmi.check b/test/files/neg/macro-basic-mamdmi.check new file mode 100644 index 0000000000..eef444f7b3 --- /dev/null +++ b/test/files/neg/macro-basic-mamdmi.check @@ -0,0 +1,5 @@ +Impls_Macros_Test_1.scala:36: error: macro implementation not found: foo (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them) +if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath in the second phase pointing to the output of the first phase + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) + ^ +one error found diff --git a/test/files/neg/macro-basic-mamdmi.flags b/test/files/neg/macro-basic-mamdmi.flags new file mode 100644 index 0000000000..06a7b31f11 --- /dev/null +++ b/test/files/neg/macro-basic-mamdmi.flags @@ -0,0 +1 @@ +-Xmacros diff --git a/test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala b/test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala new file mode 100644 index 0000000000..e9876e32e9 --- /dev/null +++ b/test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala @@ -0,0 +1,37 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } + + def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + Expr[Int](body) + } + + def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} + +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo + } + def bar(x: Int): Int = macro Impls.bar +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux +} + +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/neg/macro-cyclic.check b/test/files/neg/macro-cyclic.check new file mode 100644 index 0000000000..608381e0e8 --- /dev/null +++ b/test/files/neg/macro-cyclic.check @@ -0,0 +1,4 @@ +Impls_Macros_1.scala:5: error: could not find implicit value for parameter e: SourceLocation + c.reify { implicitly[SourceLocation] } + ^ +one error found diff --git a/test/files/neg/macro-cyclic.flags b/test/files/neg/macro-cyclic.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-cyclic.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-cyclic/Impls_Macros_1.scala b/test/files/neg/macro-cyclic/Impls_Macros_1.scala new file mode 100644 index 0000000000..1ea06fc968 --- /dev/null +++ b/test/files/neg/macro-cyclic/Impls_Macros_1.scala @@ -0,0 +1,25 @@ +import scala.reflect.makro.Context + +object Macros { + def impl(c: Context) = { + c.reify { implicitly[SourceLocation] } + } + + implicit def sourceLocation: SourceLocation1 = macro impl +} + +trait SourceLocation { + /** Source location of the outermost call */ + val outer: SourceLocation + + /** The name of the source file */ + val fileName: String + + /** The line number */ + val line: Int + + /** The character offset */ + val charOffset: Int +} + +case class SourceLocation1(val outer: SourceLocation, val fileName: String, val line: Int, val charOffset: Int) extends SourceLocation diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check new file mode 100644 index 0000000000..c97be5d9f6 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check @@ -0,0 +1,14 @@ +Macros_Package_10.scala:1: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro` + ^ +Macros_Package_10.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro`.bar + ^ +Macros_Package_11.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro`.foo + ^ +Main.scala:2: error: Unmatched closing brace '}' ignored here +} +^ +three warnings found +one error found diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala new file mode 100644 index 0000000000..97c07b04a0 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(`macro`) = Some(42) + `macro` match { + case `macro` => println(`macro`) + } +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala new file mode 100644 index 0000000000..f0037b5f82 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala @@ -0,0 +1,3 @@ +package test4 + +class `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala new file mode 100644 index 0000000000..a6d0903cbb --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala @@ -0,0 +1,3 @@ +object Test5 { + class `macro` +} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala new file mode 100644 index 0000000000..6af8e1d65e --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala @@ -0,0 +1,3 @@ +object Test13 { + def `macro` = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala new file mode 100644 index 0000000000..29dab017d2 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala @@ -0,0 +1,3 @@ +package test6 + +object `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala new file mode 100644 index 0000000000..6cbcac55ca --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala @@ -0,0 +1,3 @@ +object Test7 { + object `macro` +} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala new file mode 100644 index 0000000000..4985d6691e --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala @@ -0,0 +1,3 @@ +package `macro` + +package `macro`.bar \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala new file mode 100644 index 0000000000..35ed610637 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala @@ -0,0 +1,3 @@ +package foo + +package `macro`.foo diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala new file mode 100644 index 0000000000..7895cf9a43 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala @@ -0,0 +1,3 @@ +package test8 + +trait `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala new file mode 100644 index 0000000000..90ba2207b7 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala @@ -0,0 +1,3 @@ +object Test9 { + trait `macro` +} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala new file mode 100644 index 0000000000..7a2196c9cd --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala @@ -0,0 +1,3 @@ +object Test3 { + type `macro` = Int +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala new file mode 100644 index 0000000000..9ad08b8ba0 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala @@ -0,0 +1,3 @@ +object Test1 { + val `macro` = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala new file mode 100644 index 0000000000..4fbe152e76 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala @@ -0,0 +1,3 @@ +object Test2 { + var `macro` = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala new file mode 100644 index 0000000000..f5278d9e7e --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala @@ -0,0 +1,2 @@ +object Test extends App +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents.check b/test/files/neg/macro-deprecate-idents.check new file mode 100644 index 0000000000..5fa1dc84d0 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents.check @@ -0,0 +1,50 @@ +Macros_Bind_12.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + val Some(macro) = Some(42) + ^ +Macros_Bind_12.scala:4: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + case macro => println(macro) + ^ +Macros_Class_4.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +class macro + ^ +Macros_Class_5.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + class macro + ^ +Macros_Def_13.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + def macro = 2 + ^ +Macros_Object_6.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +object macro + ^ +Macros_Object_7.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + object macro + ^ +Macros_Package_10.scala:1: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro + ^ +Macros_Package_10.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro.bar + ^ +Macros_Package_11.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro.foo + ^ +Macros_Trait_8.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +trait macro + ^ +Macros_Trait_9.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + trait macro + ^ +Macros_Type_3.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + type macro = Int + ^ +Macros_Val_1.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + val macro = ??? + ^ +Macros_Var_2.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + var macro = ??? + ^ +Main.scala:2: error: Unmatched closing brace '}' ignored here +} +^ +15 warnings found +one error found diff --git a/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala b/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala new file mode 100644 index 0000000000..a3b1553348 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala b/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala new file mode 100644 index 0000000000..8635d1f4f6 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala @@ -0,0 +1,3 @@ +package test4 + +class macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala b/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala new file mode 100644 index 0000000000..af24a489d0 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala @@ -0,0 +1,3 @@ +object Test5 { + class macro +} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala b/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala new file mode 100644 index 0000000000..f4e25bfdfc --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala @@ -0,0 +1,3 @@ +object Test13 { + def macro = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala b/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala new file mode 100644 index 0000000000..66eb494e6b --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala @@ -0,0 +1,3 @@ +package test6 + +object macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala b/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala new file mode 100644 index 0000000000..6f5b9ceacd --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala @@ -0,0 +1,3 @@ +object Test7 { + object macro +} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala b/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala new file mode 100644 index 0000000000..52d3fbabf6 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala @@ -0,0 +1,3 @@ +package macro + +package macro.bar \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala b/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala new file mode 100644 index 0000000000..a68ebd935f --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala @@ -0,0 +1,3 @@ +package foo + +package macro.foo diff --git a/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala b/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala new file mode 100644 index 0000000000..e32d4c1385 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala @@ -0,0 +1,3 @@ +package test8 + +trait macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala b/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala new file mode 100644 index 0000000000..243a54abe6 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala @@ -0,0 +1,3 @@ +object Test9 { + trait macro +} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala b/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala new file mode 100644 index 0000000000..30e523bcaf --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala @@ -0,0 +1,3 @@ +object Test3 { + type macro = Int +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala b/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala new file mode 100644 index 0000000000..96f57acb30 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala @@ -0,0 +1,3 @@ +object Test1 { + val macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala b/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala new file mode 100644 index 0000000000..a79dda6dc2 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala @@ -0,0 +1,3 @@ +object Test2 { + var macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Main.scala b/test/files/neg/macro-deprecate-idents/Main.scala new file mode 100644 index 0000000000..f5278d9e7e --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Main.scala @@ -0,0 +1,2 @@ +object Test extends App +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-a.check b/test/files/neg/macro-invalidimpl-a.check new file mode 100644 index 0000000000..855fe2d169 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-a.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:3: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-a.flags b/test/files/neg/macro-invalidimpl-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-a/Impls_1.scala b/test/files/neg/macro-invalidimpl-a/Impls_1.scala new file mode 100644 index 0000000000..c2f1843b8b --- /dev/null +++ b/test/files/neg/macro-invalidimpl-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +class Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala new file mode 100644 index 0000000000..2220ddae0c --- /dev/null +++ b/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala @@ -0,0 +1,9 @@ +object Macros { + val impls = new Impls + def foo(x: Any) = macro impls.foo +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-b.check b/test/files/neg/macro-invalidimpl-b.check new file mode 100644 index 0000000000..855fe2d169 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-b.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:3: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-b.flags b/test/files/neg/macro-invalidimpl-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-b/Impls_1.scala b/test/files/neg/macro-invalidimpl-b/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-b/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala new file mode 100644 index 0000000000..81e40837d2 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala @@ -0,0 +1,9 @@ +object Macros { + val impls = Impls + def foo(x: Any) = macro impls.foo +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c.check b/test/files/neg/macro-invalidimpl-c.check new file mode 100644 index 0000000000..722ec3c7bd --- /dev/null +++ b/test/files/neg/macro-invalidimpl-c.check @@ -0,0 +1,4 @@ +Impls_Macros_1.scala:8: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-c.flags b/test/files/neg/macro-invalidimpl-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala b/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala new file mode 100644 index 0000000000..657e2d4260 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +class Macros { + object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? + } + + def foo(x: Any) = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c/Test_2.scala b/test/files/neg/macro-invalidimpl-c/Test_2.scala new file mode 100644 index 0000000000..e75a8ba101 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-c/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + new Macros().foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d.check b/test/files/neg/macro-invalidimpl-d.check new file mode 100644 index 0000000000..6fedfa74fc --- /dev/null +++ b/test/files/neg/macro-invalidimpl-d.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-d.flags b/test/files/neg/macro-invalidimpl-d.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-d.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d/Impls_1.scala b/test/files/neg/macro-invalidimpl-d/Impls_1.scala new file mode 100644 index 0000000000..f18e699a1e --- /dev/null +++ b/test/files/neg/macro-invalidimpl-d/Impls_1.scala @@ -0,0 +1,7 @@ +import scala.reflect.makro.{Context => Ctx} + +trait MacroHelpers { + object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = x + } +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala new file mode 100644 index 0000000000..067ab1ddec --- /dev/null +++ b/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala @@ -0,0 +1,7 @@ +class Macros extends MacroHelpers { + def foo(x: Any) = macro Impls.foo +} + +object Test extends App { + println(new Macros().foo(42)) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-e.check b/test/files/neg/macro-invalidimpl-e.check new file mode 100644 index 0000000000..61d1e05b87 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-e.check @@ -0,0 +1,13 @@ +Macros_Test_2.scala:2: error: ambiguous reference to overloaded definition, +both method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing +and method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any])Nothing +match expected type ? + def foo(x: Any) = macro Impls.foo + ^ +Macros_Test_2.scala:3: error: ambiguous reference to overloaded definition, +both method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing +and method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any])Nothing +match expected type ? + def foo(x: Any, y: Any) = macro Impls.foo + ^ +two errors found diff --git a/test/files/neg/macro-invalidimpl-e.flags b/test/files/neg/macro-invalidimpl-e.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-e.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-e/Impls_1.scala b/test/files/neg/macro-invalidimpl-e/Impls_1.scala new file mode 100644 index 0000000000..ad3eed5cd5 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-e/Impls_1.scala @@ -0,0 +1,6 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? + def foo(c: Ctx)(x: c.Expr[Any], y: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala new file mode 100644 index 0000000000..6edde08167 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala @@ -0,0 +1,9 @@ +object Macros { + def foo(x: Any) = macro Impls.foo + def foo(x: Any, y: Any) = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-f.check b/test/files/neg/macro-invalidimpl-f.check new file mode 100644 index 0000000000..ec82faa58c --- /dev/null +++ b/test/files/neg/macro-invalidimpl-f.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(): c.Expr[Unit] + found : (c: scala.reflect.makro.Context): c.Expr[Unit] +number of parameter sections differ + def bar1() = macro Impls.fooNullary + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-f.flags b/test/files/neg/macro-invalidimpl-f.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-f.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-f/Impls_1.scala b/test/files/neg/macro-invalidimpl-f/Impls_1.scala new file mode 100644 index 0000000000..06c6efbb1f --- /dev/null +++ b/test/files/neg/macro-invalidimpl-f/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def fooNullary(c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))) + Expr[Unit](body) + } + + def fooEmpty(c: Ctx)() = fooNullary(c) +} diff --git a/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala new file mode 100644 index 0000000000..493edf1df8 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala @@ -0,0 +1,9 @@ +object Macros { + def bar1() = macro Impls.fooNullary +} + +object Test extends App { + Macros.bar1 + Macros.bar1() + println("kkthxbai") +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-g.check b/test/files/neg/macro-invalidimpl-g.check new file mode 100644 index 0000000000..9c01f01dc8 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-g.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Unit] + found : (c: scala.reflect.makro.Context)(): c.Expr[Unit] +number of parameter sections differ + def foo1 = macro Impls.fooEmpty + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-g.flags b/test/files/neg/macro-invalidimpl-g.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-g.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-g/Impls_1.scala b/test/files/neg/macro-invalidimpl-g/Impls_1.scala new file mode 100644 index 0000000000..06c6efbb1f --- /dev/null +++ b/test/files/neg/macro-invalidimpl-g/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def fooNullary(c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))) + Expr[Unit](body) + } + + def fooEmpty(c: Ctx)() = fooNullary(c) +} diff --git a/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala new file mode 100644 index 0000000000..5561db9f9a --- /dev/null +++ b/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo1 = macro Impls.fooEmpty +} + +object Test extends App { + Macros.foo1 + println("kkthxbai") +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-h.check b/test/files/neg/macro-invalidimpl-h.check new file mode 100644 index 0000000000..cc7fc794d3 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-h.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: type arguments [String] do not conform to method foo's type parameter bounds [U <: Int] + def foo = macro Impls.foo[String] + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-h.flags b/test/files/neg/macro-invalidimpl-h.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-h.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-h/Impls_1.scala b/test/files/neg/macro-invalidimpl-h/Impls_1.scala new file mode 100644 index 0000000000..7db8bcd324 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-h/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: Int](c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala new file mode 100644 index 0000000000..218c7aec7f --- /dev/null +++ b/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo[String] +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nontree.check b/test/files/neg/macro-invalidret-nontree.check new file mode 100644 index 0000000000..7fcc396463 --- /dev/null +++ b/test/files/neg/macro-invalidret-nontree.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : (c: scala.reflect.makro.Context): Int +type mismatch for return type : c.Expr[Any] does not conform to Int + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidret-nontree.flags b/test/files/neg/macro-invalidret-nontree.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidret-nontree.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nontree/Impls_1.scala b/test/files/neg/macro-invalidret-nontree/Impls_1.scala new file mode 100644 index 0000000000..efc8d4bfec --- /dev/null +++ b/test/files/neg/macro-invalidret-nontree/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = 2 +} diff --git a/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala b/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nonuniversetree.check b/test/files/neg/macro-invalidret-nonuniversetree.check new file mode 100644 index 0000000000..a97d6daaa9 --- /dev/null +++ b/test/files/neg/macro-invalidret-nonuniversetree.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : (c: scala.reflect.makro.Context): reflect.mirror.Literal +type mismatch for return type : c.Expr[Any] does not conform to reflect.mirror.Literal + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidret-nonuniversetree.flags b/test/files/neg/macro-invalidret-nonuniversetree.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidret-nonuniversetree.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala b/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala new file mode 100644 index 0000000000..86b7c8d8d0 --- /dev/null +++ b/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = scala.reflect.mirror.Literal(scala.reflect.mirror.Constant(42)) +} diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala b/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-a.check b/test/files/neg/macro-invalidshape-a.check new file mode 100644 index 0000000000..246b5c3226 --- /dev/null +++ b/test/files/neg/macro-invalidshape-a.check @@ -0,0 +1,6 @@ +Macros_Test_2.scala:2: error: macro body has wrong shape: + required: macro . + or : macro + def foo(x: Any) = macro 2 + ^ +one error found diff --git a/test/files/neg/macro-invalidshape-a.flags b/test/files/neg/macro-invalidshape-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-a/Impls_1.scala b/test/files/neg/macro-invalidshape-a/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidshape-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala new file mode 100644 index 0000000000..ffff17d1e7 --- /dev/null +++ b/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro 2 +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-b.check b/test/files/neg/macro-invalidshape-b.check new file mode 100644 index 0000000000..59701d023b --- /dev/null +++ b/test/files/neg/macro-invalidshape-b.check @@ -0,0 +1,6 @@ +Macros_Test_2.scala:2: error: macro body has wrong shape: + required: macro . + or : macro + def foo(x: Any) = macro Impls.foo(null)(null) + ^ +one error found diff --git a/test/files/neg/macro-invalidshape-b.flags b/test/files/neg/macro-invalidshape-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-b/Impls_1.scala b/test/files/neg/macro-invalidshape-b/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidshape-b/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala new file mode 100644 index 0000000000..b67cd32a6e --- /dev/null +++ b/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro Impls.foo(null)(null) +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-c.check b/test/files/neg/macro-invalidshape-c.check new file mode 100644 index 0000000000..84d8c35222 --- /dev/null +++ b/test/files/neg/macro-invalidshape-c.check @@ -0,0 +1,6 @@ +Macros_Test_2.scala:2: error: macro body has wrong shape: + required: macro . + or : macro + def foo(x: Any) = macro {2; Impls.foo} + ^ +one error found diff --git a/test/files/neg/macro-invalidshape-c.flags b/test/files/neg/macro-invalidshape-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-c/Impls_1.scala b/test/files/neg/macro-invalidshape-c/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidshape-c/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala new file mode 100644 index 0000000000..552c3710c7 --- /dev/null +++ b/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro {2; Impls.foo} +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d.check b/test/files/neg/macro-invalidshape-d.check new file mode 100644 index 0000000000..031aa653ab --- /dev/null +++ b/test/files/neg/macro-invalidshape-d.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: illegal start of statement + def foo(x: Any) = {2; macro Impls.foo} + ^ +one error found diff --git a/test/files/neg/macro-invalidshape-d.flags b/test/files/neg/macro-invalidshape-d.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-d.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d/Impls_1.scala b/test/files/neg/macro-invalidshape-d/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidshape-d/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala new file mode 100644 index 0000000000..bacd9a6e7c --- /dev/null +++ b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = {2; macro Impls.foo} +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-context-bounds.check b/test/files/neg/macro-invalidsig-context-bounds.check new file mode 100644 index 0000000000..dd68e5db1b --- /dev/null +++ b/test/files/neg/macro-invalidsig-context-bounds.check @@ -0,0 +1,4 @@ +Impls_1.scala:4: error: macro implementations cannot have implicit parameters other than TypeTag evidences + def foo[U: c.TypeTag: Numeric](c: Ctx) = { + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-context-bounds.flags b/test/files/neg/macro-invalidsig-context-bounds.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-context-bounds.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala b/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala new file mode 100644 index 0000000000..2eb2ab3947 --- /dev/null +++ b/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U: c.TypeTag: Numeric](c: Ctx) = { + import c.mirror._ + Literal(Constant(42)) + } +} diff --git a/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala new file mode 100644 index 0000000000..5b4602f328 --- /dev/null +++ b/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + println(foo[String]) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badargc.check b/test/files/neg/macro-invalidsig-ctx-badargc.check new file mode 100644 index 0000000000..1e1621ab61 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badargc.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : : Nothing +number of parameter sections differ + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-ctx-badargc.flags b/test/files/neg/macro-invalidsig-ctx-badargc.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badargc.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala new file mode 100644 index 0000000000..da28944d27 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.api.{Mirror => Ctx} + +object Impls { + def foo = ??? +} diff --git a/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badtype.check b/test/files/neg/macro-invalidsig-ctx-badtype.check new file mode 100644 index 0000000000..3913a8e3cb --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badtype.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : (c: scala.reflect.api.Mirror): Nothing +type mismatch for parameter c: scala.reflect.makro.Context does not conform to scala.reflect.api.Mirror + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-ctx-badtype.flags b/test/files/neg/macro-invalidsig-ctx-badtype.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badtype.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala new file mode 100644 index 0000000000..747a2e9ca8 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.api.{Mirror => Ctx} + +object Impls { + def foo(c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs.check b/test/files/neg/macro-invalidsig-ctx-badvarargs.check new file mode 100644 index 0000000000..18e3d6201f --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badvarargs.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : (cs: scala.reflect.makro.Context*): Nothing +types incompatible for parameter cs: corresponding is not a vararg parameter + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs.flags b/test/files/neg/macro-invalidsig-ctx-badvarargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badvarargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala new file mode 100644 index 0000000000..b2fb2539ec --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(cs: Ctx*) = ??? +} diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-noctx.check b/test/files/neg/macro-invalidsig-ctx-noctx.check new file mode 100644 index 0000000000..66fa7c3514 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-noctx.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(x: c.Expr[Any]): c.Expr[Any] + found : (c: scala.reflect.makro.Context): Nothing +number of parameter sections differ + def foo(x: Any) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-ctx-noctx.flags b/test/files/neg/macro-invalidsig-ctx-noctx.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-noctx.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala new file mode 100644 index 0000000000..1e0ed755af --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala new file mode 100644 index 0000000000..e053cf99df --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-implicit-params.check b/test/files/neg/macro-invalidsig-implicit-params.check new file mode 100644 index 0000000000..0dd1c27b50 --- /dev/null +++ b/test/files/neg/macro-invalidsig-implicit-params.check @@ -0,0 +1,4 @@ +Impls_Macros_1.scala:4: error: macro implementations cannot have implicit parameters other than TypeTag evidences + def foo_targs[T, U: c.TypeTag](c: Ctx)(implicit x: c.Expr[Int]) = { + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-implicit-params.flags b/test/files/neg/macro-invalidsig-implicit-params.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-implicit-params.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala new file mode 100644 index 0000000000..662ad2ab52 --- /dev/null +++ b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_targs[T, U: c.TypeTag](c: Ctx)(implicit x: c.Expr[Int]) = { + import c.{prefix => prefix} + import c.mirror._ + val body = Block( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo_targs...")))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix is: " + prefix.tpe)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + implicitly[c.TypeTag[U]].tpe)))), + Literal(Constant(()))) + Expr[Unit](body) + } +} + +class Macros[T] { + def foo_targs[U](x: Int) = macro Impls.foo_targs[T, U] +} diff --git a/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala b/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala new file mode 100644 index 0000000000..90e850df21 --- /dev/null +++ b/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + println("foo_targs:") + new Macros[Int]().foo_targs[String](42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badargc.check b/test/files/neg/macro-invalidsig-params-badargc.check new file mode 100644 index 0000000000..6de8c5e95a --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badargc.check @@ -0,0 +1,7 @@ +Impls_Macros_1.scala:8: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(x: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.makro.Context)(x: c.Expr[Int], y: c.Expr[Int]): Nothing +parameter lists have different length, found extra parameter y: c.Expr[Int] + def foo(x: Int) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-params-badargc.flags b/test/files/neg/macro-invalidsig-params-badargc.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badargc.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala new file mode 100644 index 0000000000..4b449f35ed --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = ??? +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala b/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala new file mode 100644 index 0000000000..cbd6232073 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badtype.check b/test/files/neg/macro-invalidsig-params-badtype.check new file mode 100644 index 0000000000..71a65aec84 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badtype.check @@ -0,0 +1,7 @@ +Impls_Macros_1.scala:8: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(x: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.makro.Context)(x: c.mirror.Tree): Nothing +type mismatch for parameter x: c.Expr[Int] does not conform to c.mirror.Tree + def foo(x: Int) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-params-badtype.flags b/test/files/neg/macro-invalidsig-params-badtype.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badtype.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala new file mode 100644 index 0000000000..29220c1c82 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.mirror.Tree) = ??? +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala b/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala new file mode 100644 index 0000000000..cbd6232073 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badvarargs.check b/test/files/neg/macro-invalidsig-params-badvarargs.check new file mode 100644 index 0000000000..0827680299 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badvarargs.check @@ -0,0 +1,7 @@ +Impls_Macros_1.scala:8: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.makro.Context)(xs: c.Expr[Int]*): Nothing +parameter lists have different length, required extra parameter y: c.Expr[Int] + def foo(x: Int, y: Int) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-params-badvarargs.flags b/test/files/neg/macro-invalidsig-params-badvarargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badvarargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala new file mode 100644 index 0000000000..2ee1c2767c --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(xs: c.Expr[Int]*) = ??? +} + +object Macros { + def foo(x: Int, y: Int) = macro Impls.foo +} diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala new file mode 100644 index 0000000000..cbd6232073 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-namemismatch.check b/test/files/neg/macro-invalidsig-params-namemismatch.check new file mode 100644 index 0000000000..ca7270cca8 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-namemismatch.check @@ -0,0 +1,7 @@ +Impls_Macros_1.scala:8: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.makro.Context)(y: c.Expr[Int], x: c.Expr[Int]): Nothing +parameter names differ: x != y + def foo(x: Int, y: Int) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-params-namemismatch.flags b/test/files/neg/macro-invalidsig-params-namemismatch.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-namemismatch.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala new file mode 100644 index 0000000000..89c5347647 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(y: c.Expr[Int], x: c.Expr[Int]) = ??? +} + +object Macros { + def foo(x: Int, y: Int) = macro Impls.foo +} diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala new file mode 100644 index 0000000000..cbd6232073 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-badtype.check b/test/files/neg/macro-invalidsig-tparams-badtype.check new file mode 100644 index 0000000000..bd1acc4a0a --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-badtype.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : (c: scala.reflect.makro.Context)(U: c.mirror.Type): Nothing +number of parameter sections differ + def foo[U] = macro Impls.foo[U] + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-badtype.flags b/test/files/neg/macro-invalidsig-tparams-badtype.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-badtype.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala new file mode 100644 index 0000000000..b43251df33 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U](c: Ctx)(U: c.mirror.Type) = ??? +} diff --git a/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala new file mode 100644 index 0000000000..a82e813221 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a.check b/test/files/neg/macro-invalidsig-tparams-bounds-a.check new file mode 100644 index 0000000000..6ba80b45c0 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-a.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String] + def foo[U] = macro Impls.foo[U] + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a.flags b/test/files/neg/macro-invalidsig-tparams-bounds-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala new file mode 100644 index 0000000000..88b85d48f4 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala new file mode 100644 index 0000000000..a82e813221 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b.check b/test/files/neg/macro-invalidsig-tparams-bounds-b.check new file mode 100644 index 0000000000..50f0944acc --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-b.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String] + def foo[U <: Int] = macro Impls.foo[U] + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b.flags b/test/files/neg/macro-invalidsig-tparams-bounds-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala new file mode 100644 index 0000000000..88b85d48f4 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala new file mode 100644 index 0000000000..eed6369a16 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U <: Int] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a.check b/test/files/neg/macro-invalidsig-tparams-notparams-a.check new file mode 100644 index 0000000000..5b4ef42ea5 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-a.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: macro implementation reference needs type arguments + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a.flags b/test/files/neg/macro-invalidsig-tparams-notparams-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala new file mode 100644 index 0000000000..bbe5b4e519 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U: c.TypeTag](c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b.check b/test/files/neg/macro-invalidsig-tparams-notparams-b.check new file mode 100644 index 0000000000..261e3b8293 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:3: error: macro implementation reference needs type arguments + def foo[V] = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b.flags b/test/files/neg/macro-invalidsig-tparams-notparams-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala new file mode 100644 index 0000000000..7bc46ff876 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T: c.TypeTag, U: c.TypeTag, V](c: Ctx)(implicit V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + println(implicitly[c.TypeTag[T]]) + println(implicitly[c.TypeTag[U]]) + println(V) + Literal(Constant(())) + } +} diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala new file mode 100644 index 0000000000..7d02bf613a --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala @@ -0,0 +1,11 @@ +class D[T] { + class C[U] { + def foo[V] = macro Impls.foo + } +} + +object Test extends App { + val outer1 = new D[Int] + val outer2 = new outer1.C[String] + outer2.foo[Boolean] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c.check b/test/files/neg/macro-invalidsig-tparams-notparams-c.check new file mode 100644 index 0000000000..b64a469cc3 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:3: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.makro.Context)(implicit evidence$1: c.TypeTag[T], implicit evidence$2: c.TypeTag[U], implicit V: c.TypeTag[V])c.Expr[Unit] + def foo[V] = macro Impls.foo[V] + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c.flags b/test/files/neg/macro-invalidsig-tparams-notparams-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala new file mode 100644 index 0000000000..7bc46ff876 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T: c.TypeTag, U: c.TypeTag, V](c: Ctx)(implicit V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + println(implicitly[c.TypeTag[T]]) + println(implicitly[c.TypeTag[U]]) + println(V) + Literal(Constant(())) + } +} diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala new file mode 100644 index 0000000000..109e142e52 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala @@ -0,0 +1,11 @@ +class D[T] { + class C[U] { + def foo[V] = macro Impls.foo[V] + } +} + +object Test extends App { + val outer1 = new D[Int] + val outer2 = new outer1.C[String] + outer2.foo[Boolean] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badargs.check b/test/files/neg/macro-invalidusage-badargs.check new file mode 100644 index 0000000000..52beda5b61 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badargs.check @@ -0,0 +1,6 @@ +Macros_Test_2.scala:7: error: type mismatch; + found : String("42") + required: Int + val s: String = foo("42") + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-badargs.flags b/test/files/neg/macro-invalidusage-badargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badargs/Impls_1.scala b/test/files/neg/macro-invalidusage-badargs/Impls_1.scala new file mode 100644 index 0000000000..2346a6106d --- /dev/null +++ b/test/files/neg/macro-invalidusage-badargs/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = x +} diff --git a/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala new file mode 100644 index 0000000000..a6af1bb277 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Int) = macro Impls.foo +} + +object Test extends App { + import Macros._ + val s: String = foo("42") +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badbounds.check b/test/files/neg/macro-invalidusage-badbounds.check new file mode 100644 index 0000000000..fd0b64533e --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:7: error: type arguments [Int] do not conform to macro method foo's type parameter bounds [U <: String] + foo[Int] + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-badbounds.flags b/test/files/neg/macro-invalidusage-badbounds.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala b/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala new file mode 100644 index 0000000000..88b85d48f4 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala new file mode 100644 index 0000000000..3139599108 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U <: String] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badtargs.check b/test/files/neg/macro-invalidusage-badtargs.check new file mode 100644 index 0000000000..61ef6f5af7 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:7: error: macro method foo: (x: Int)Int does not take type parameters. + val s: String = foo[String](42) + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-badtargs.flags b/test/files/neg/macro-invalidusage-badtargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badtargs/Impls_1.scala b/test/files/neg/macro-invalidusage-badtargs/Impls_1.scala new file mode 100644 index 0000000000..2346a6106d --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = x +} diff --git a/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala new file mode 100644 index 0000000000..c54093b637 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Int) = macro Impls.foo +} + +object Test extends App { + import Macros._ + val s: String = foo[String](42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax.check b/test/files/neg/macro-invalidusage-methodvaluesyntax.check new file mode 100644 index 0000000000..27b2023202 --- /dev/null +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:6: error: macros cannot be eta-expanded + val firstClassFoo = Macros.foo _ + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax.flags b/test/files/neg/macro-invalidusage-methodvaluesyntax.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala b/test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala new file mode 100644 index 0000000000..8e52613b6d --- /dev/null +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))) + Expr[Unit](body) + } +} diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala new file mode 100644 index 0000000000..343cec99b5 --- /dev/null +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + val firstClassFoo = Macros.foo _ + firstClassFoo +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword.check b/test/files/neg/macro-keyword.check new file mode 100644 index 0000000000..fd63db951c --- /dev/null +++ b/test/files/neg/macro-keyword.check @@ -0,0 +1,49 @@ +Macros_Bind_12.scala:2: error: illegal start of simple pattern + val Some(macro) = Some(42) + ^ +Macros_Bind_12.scala:6: error: ')' expected but '}' found. +} +^ +Macros_Class_4.scala:3: error: identifier expected but 'macro' found. +class macro + ^ +Macros_Class_5.scala:2: error: identifier expected but 'macro' found. + class macro + ^ +Macros_Def_13.scala:2: error: identifier expected but 'macro' found. + def macro = 2 + ^ +Macros_Object_6.scala:3: error: identifier expected but 'macro' found. +object macro + ^ +Macros_Object_7.scala:2: error: identifier expected but 'macro' found. + object macro + ^ +Macros_Package_10.scala:1: error: identifier expected but 'macro' found. +package macro + ^ +Macros_Package_11.scala:3: error: identifier expected but 'macro' found. +package macro.foo + ^ +Macros_Trait_8.scala:3: error: identifier expected but 'macro' found. +trait macro + ^ +Macros_Trait_9.scala:2: error: identifier expected but 'macro' found. + trait macro + ^ +Macros_Type_3.scala:2: error: identifier expected but 'macro' found. + type macro = Int + ^ +Macros_Val_1.scala:2: error: illegal start of simple pattern + val macro = ??? + ^ +Macros_Val_1.scala:3: error: '=' expected but '}' found. +} +^ +Macros_Var_2.scala:2: error: illegal start of simple pattern + var macro = ??? + ^ +Macros_Var_2.scala:3: error: '=' expected but '}' found. +} +^ +16 errors found diff --git a/test/files/neg/macro-keyword.flags b/test/files/neg/macro-keyword.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Bind_12.scala b/test/files/neg/macro-keyword/Macros_Bind_12.scala new file mode 100644 index 0000000000..a3b1553348 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Bind_12.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Class_4.scala b/test/files/neg/macro-keyword/Macros_Class_4.scala new file mode 100644 index 0000000000..8635d1f4f6 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Class_4.scala @@ -0,0 +1,3 @@ +package test4 + +class macro diff --git a/test/files/neg/macro-keyword/Macros_Class_5.scala b/test/files/neg/macro-keyword/Macros_Class_5.scala new file mode 100644 index 0000000000..af24a489d0 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Class_5.scala @@ -0,0 +1,3 @@ +object Test5 { + class macro +} diff --git a/test/files/neg/macro-keyword/Macros_Def_13.scala b/test/files/neg/macro-keyword/Macros_Def_13.scala new file mode 100644 index 0000000000..f4e25bfdfc --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Def_13.scala @@ -0,0 +1,3 @@ +object Test13 { + def macro = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Object_6.scala b/test/files/neg/macro-keyword/Macros_Object_6.scala new file mode 100644 index 0000000000..66eb494e6b --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Object_6.scala @@ -0,0 +1,3 @@ +package test6 + +object macro diff --git a/test/files/neg/macro-keyword/Macros_Object_7.scala b/test/files/neg/macro-keyword/Macros_Object_7.scala new file mode 100644 index 0000000000..6f5b9ceacd --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Object_7.scala @@ -0,0 +1,3 @@ +object Test7 { + object macro +} diff --git a/test/files/neg/macro-keyword/Macros_Package_10.scala b/test/files/neg/macro-keyword/Macros_Package_10.scala new file mode 100644 index 0000000000..52d3fbabf6 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Package_10.scala @@ -0,0 +1,3 @@ +package macro + +package macro.bar \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Package_11.scala b/test/files/neg/macro-keyword/Macros_Package_11.scala new file mode 100644 index 0000000000..a68ebd935f --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Package_11.scala @@ -0,0 +1,3 @@ +package foo + +package macro.foo diff --git a/test/files/neg/macro-keyword/Macros_Trait_8.scala b/test/files/neg/macro-keyword/Macros_Trait_8.scala new file mode 100644 index 0000000000..e32d4c1385 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Trait_8.scala @@ -0,0 +1,3 @@ +package test8 + +trait macro diff --git a/test/files/neg/macro-keyword/Macros_Trait_9.scala b/test/files/neg/macro-keyword/Macros_Trait_9.scala new file mode 100644 index 0000000000..243a54abe6 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Trait_9.scala @@ -0,0 +1,3 @@ +object Test9 { + trait macro +} diff --git a/test/files/neg/macro-keyword/Macros_Type_3.scala b/test/files/neg/macro-keyword/Macros_Type_3.scala new file mode 100644 index 0000000000..30e523bcaf --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Type_3.scala @@ -0,0 +1,3 @@ +object Test3 { + type macro = Int +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Val_1.scala b/test/files/neg/macro-keyword/Macros_Val_1.scala new file mode 100644 index 0000000000..96f57acb30 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Val_1.scala @@ -0,0 +1,3 @@ +object Test1 { + val macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Var_2.scala b/test/files/neg/macro-keyword/Macros_Var_2.scala new file mode 100644 index 0000000000..a79dda6dc2 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Var_2.scala @@ -0,0 +1,3 @@ +object Test2 { + var macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-noexpand.check b/test/files/neg/macro-noexpand.check index c15d54bb32..c829bbab71 100644 --- a/test/files/neg/macro-noexpand.check +++ b/test/files/neg/macro-noexpand.check @@ -1,4 +1,4 @@ -Test_2.scala:3: error: not found: value x +Macros_Test_2.scala:7: error: not found: value x foo(x) ^ one error found diff --git a/test/files/neg/macro-noexpand/Impls_1.scala b/test/files/neg/macro-noexpand/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-noexpand/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-noexpand/Macros_1.scala b/test/files/neg/macro-noexpand/Macros_1.scala deleted file mode 100644 index 7a6aadf6a1..0000000000 --- a/test/files/neg/macro-noexpand/Macros_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Macros { - def macro foo(x: Any) = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-noexpand/Macros_Test_2.scala b/test/files/neg/macro-noexpand/Macros_Test_2.scala new file mode 100644 index 0000000000..e783e2b53e --- /dev/null +++ b/test/files/neg/macro-noexpand/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo(x) +} \ No newline at end of file diff --git a/test/files/neg/macro-noexpand/Test_2.scala b/test/files/neg/macro-noexpand/Test_2.scala deleted file mode 100644 index 0bed592883..0000000000 --- a/test/files/neg/macro-noexpand/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(x) -} \ No newline at end of file diff --git a/test/files/neg/macro-noncompilertree/Macros_1.scala b/test/files/neg/macro-noncompilertree/Macros_1.scala deleted file mode 100644 index eb1253e5e9..0000000000 --- a/test/files/neg/macro-noncompilertree/Macros_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Macros { - def macro foo = scala.reflect.mirror.Literal(scala.reflect.mirror.Constant(2)) -} \ No newline at end of file diff --git a/test/files/neg/macro-nontree/Macros_1.scala b/test/files/neg/macro-nontree/Macros_1.scala deleted file mode 100644 index 2433974a85..0000000000 --- a/test/files/neg/macro-nontree/Macros_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Macros { - def macro foo = 2 -} \ No newline at end of file diff --git a/test/files/neg/macro-nontypeablebody.check b/test/files/neg/macro-nontypeablebody.check new file mode 100644 index 0000000000..0cfc864df8 --- /dev/null +++ b/test/files/neg/macro-nontypeablebody.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: value foo2 is not a member of object Impls + def foo(x: Any) = macro Impls.foo2 + ^ +one error found diff --git a/test/files/neg/macro-nontypeablebody.flags b/test/files/neg/macro-nontypeablebody.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-nontypeablebody.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-nontypeablebody/Impls_1.scala b/test/files/neg/macro-nontypeablebody/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-nontypeablebody/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-nontypeablebody/Macros_Test_2.scala b/test/files/neg/macro-nontypeablebody/Macros_Test_2.scala new file mode 100644 index 0000000000..2031893970 --- /dev/null +++ b/test/files/neg/macro-nontypeablebody/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro Impls.foo2 +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a.check b/test/files/neg/macro-override-macro-overrides-abstract-method-a.check new file mode 100644 index 0000000000..4d95dfc45c --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a.check @@ -0,0 +1,5 @@ +Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int; + macro method foo cannot override an abstract method + def foo(x: Int) = macro Impls.impl + ^ +one error found diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags b/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala new file mode 100644 index 0000000000..cb0b152852 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx)(x: c.Expr[Int]) = x +} + +trait Foo { + def foo(x: Int): Int +} + +object Macros extends Foo { + def foo(x: Int) = macro Impls.impl +} diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala new file mode 100644 index 0000000000..7e3357ec28 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val designator: Macros.type = Macros + designator.foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b.check b/test/files/neg/macro-override-macro-overrides-abstract-method-b.check new file mode 100644 index 0000000000..4d95dfc45c --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b.check @@ -0,0 +1,5 @@ +Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int; + macro method foo cannot override an abstract method + def foo(x: Int) = macro Impls.impl + ^ +one error found diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags b/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..cb0b152852 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx)(x: c.Expr[Int]) = x +} + +trait Foo { + def foo(x: Int): Int +} + +object Macros extends Foo { + def foo(x: Int) = macro Impls.impl +} diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala new file mode 100644 index 0000000000..08fff30baf --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val designator: Foo = Macros + designator.foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-override-method-overrides-macro.check b/test/files/neg/macro-override-method-overrides-macro.check new file mode 100644 index 0000000000..42edb0ff23 --- /dev/null +++ b/test/files/neg/macro-override-method-overrides-macro.check @@ -0,0 +1,5 @@ +Macros_Test_2.scala:8: error: overriding macro method foo in class B of type (x: String)Unit; + method foo cannot override a macro + override def foo(x: String) = println("fooDString") + ^ +one error found diff --git a/test/files/neg/macro-override-method-overrides-macro.flags b/test/files/neg/macro-override-method-overrides-macro.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-override-method-overrides-macro.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-override-method-overrides-macro/Impls_1.scala b/test/files/neg/macro-override-method-overrides-macro/Impls_1.scala new file mode 100644 index 0000000000..0b127f5a59 --- /dev/null +++ b/test/files/neg/macro-override-method-overrides-macro/Impls_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx)(tag: String, x: c.Expr[_]) = { + import c.{prefix => prefix} + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(tag)), Literal(Constant(prefix.toString)), x.tree)) + Expr[Unit](body) + } + + def fooBString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBString", x) + def fooBInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBInt", x) + def fooDInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooDInt", x) + def fooZString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooZString", x) +} diff --git a/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala b/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala new file mode 100644 index 0000000000..36821b05d8 --- /dev/null +++ b/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala @@ -0,0 +1,15 @@ +class B { + def foo(x: String) = macro Impls.fooBString + def foo(x: Int) = macro Impls.fooBInt + def foo(x: Boolean) = println("fooBBoolean") +} + +class D extends B { + override def foo(x: String) = println("fooDString") + override def foo(x: Int) = macro Impls.fooDInt +} + +class Z extends D { + override def foo(x: String) = macro Impls.fooZString + override def foo(x: Boolean) = println("fooZBoolean") +} diff --git a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check new file mode 100644 index 0000000000..d9c390ba25 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check @@ -0,0 +1,7 @@ +Test.scala:5: error: No GroundTypeTag available for C[T] + println(implicitly[GroundTypeTag[C[T]]]) + ^ +Test.scala:6: error: No GroundTypeTag available for List[C[T]] + println(implicitly[GroundTypeTag[List[C[T]]]]) + ^ +two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala new file mode 100644 index 0000000000..d5ee61b91d --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooNoTypeTagHK[C[_], T] = { + println(implicitly[GroundTypeTag[C[T]]]) + println(implicitly[GroundTypeTag[List[C[T]]]]) + } + fooNoTypeTagHK[List, Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check new file mode 100644 index 0000000000..c678a2a313 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check @@ -0,0 +1,7 @@ +Test.scala:5: error: No GroundTypeTag available for T + println(implicitly[GroundTypeTag[T]]) + ^ +Test.scala:6: error: No GroundTypeTag available for List[T] + println(implicitly[GroundTypeTag[List[T]]]) + ^ +two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala b/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala new file mode 100644 index 0000000000..98bdf6d67f --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooNoTypeTag[T] = { + println(implicitly[GroundTypeTag[T]]) + println(implicitly[GroundTypeTag[List[T]]]) + } + fooNoTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-reify-groundtypetag-usetypetag.check b/test/files/neg/macro-reify-groundtypetag-usetypetag.check new file mode 100644 index 0000000000..c678a2a313 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-usetypetag.check @@ -0,0 +1,7 @@ +Test.scala:5: error: No GroundTypeTag available for T + println(implicitly[GroundTypeTag[T]]) + ^ +Test.scala:6: error: No GroundTypeTag available for List[T] + println(implicitly[GroundTypeTag[List[T]]]) + ^ +two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala b/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala new file mode 100644 index 0000000000..507d03a390 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTag[T: TypeTag] = { + println(implicitly[GroundTypeTag[T]]) + println(implicitly[GroundTypeTag[List[T]]]) + } + fooTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-a.check b/test/files/neg/macro-without-xmacros-a.check new file mode 100644 index 0000000000..a3ca081f04 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a.check @@ -0,0 +1,10 @@ +Macros_2.scala:5: error: not found: value macro + def foo(x: Int): Int = macro foo_impl + ^ +Macros_2.scala:7: error: not found: value macro + def bar(x: Int): Int = macro bar_impl + ^ +Macros_2.scala:11: error: not found: value macro + def quux(x: Int): Int = macro quux_impl + ^ +three errors found diff --git a/test/files/neg/macro-without-xmacros-a/Impls_1.scala b/test/files/neg/macro-without-xmacros-a/Impls_1.scala new file mode 100644 index 0000000000..2493c81c95 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a/Impls_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + } +} diff --git a/test/files/neg/macro-without-xmacros-a/Macros_2.scala b/test/files/neg/macro-without-xmacros-a/Macros_2.scala new file mode 100644 index 0000000000..62f9dcf505 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a/Macros_2.scala @@ -0,0 +1,12 @@ +import Impls._ + +object Macros { + object Shmacros { + def foo(x: Int): Int = macro foo_impl + } + def bar(x: Int): Int = macro bar_impl +} + +class Macros { + def quux(x: Int): Int = macro quux_impl +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-a/Test_3.scala b/test/files/neg/macro-without-xmacros-a/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-b.check b/test/files/neg/macro-without-xmacros-b.check new file mode 100644 index 0000000000..dce4a084c9 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b.check @@ -0,0 +1,10 @@ +Macros_2.scala:3: error: ';' expected but '.' found. + def foo(x: Int): Int = macro Impls.foo_impl + ^ +Macros_2.scala:5: error: ';' expected but '.' found. + def bar(x: Int): Int = macro Impls.bar_impl + ^ +Macros_2.scala:9: error: ';' expected but '.' found. + def quux(x: Int): Int = macro Impls.quux_impl + ^ +three errors found diff --git a/test/files/neg/macro-without-xmacros-b/Impls_1.scala b/test/files/neg/macro-without-xmacros-b/Impls_1.scala new file mode 100644 index 0000000000..2493c81c95 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b/Impls_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + } +} diff --git a/test/files/neg/macro-without-xmacros-b/Macros_2.scala b/test/files/neg/macro-without-xmacros-b/Macros_2.scala new file mode 100644 index 0000000000..de7080c7e8 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b/Macros_2.scala @@ -0,0 +1,10 @@ +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo_impl + } + def bar(x: Int): Int = macro Impls.bar_impl +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux_impl +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-b/Test_3.scala b/test/files/neg/macro-without-xmacros-b/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/neg/reify_ann2a.check b/test/files/neg/reify_ann2a.check deleted file mode 100644 index 2afe37e1d8..0000000000 --- a/test/files/neg/reify_ann2a.check +++ /dev/null @@ -1,4 +0,0 @@ -reify_ann2a.scala:9: error: exception during macro expansion: implementation restriction: cannot reify annotation @ann(immutable.this.List.apply[String]("1a")) which involves a symbol declared inside the block being reified - val tree = scala.reflect.Code.lift{ - ^ -one error found diff --git a/test/files/neg/reify_ann2a.scala b/test/files/neg/reify_ann2a.scala deleted file mode 100644 index 8de0984074..0000000000 --- a/test/files/neg/reify_ann2a.scala +++ /dev/null @@ -1,30 +0,0 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - // test 1: reify - val tree = scala.reflect.Code.lift{ - class ann(bar: List[String]) extends StaticAnnotation - - @ann(bar=List("1a")) @ann(bar=List("1b")) class C[@ann(bar=List("2a")) @ann(bar=List("2b")) T](@ann(bar=List("3a")) @ann(bar=List("3b")) x: T @ann(bar=List("4a")) @ann(bar=List("4b"))) { - @ann(bar=List("5a")) @ann(bar=List("5b")) def f(x: Int @ann(bar=List("6a")) @ann(bar=List("6b"))) = { - @ann(bar=List("7a")) @ann(bar=List("7b")) val r = (x + 3): @ann(bar=List("8a")) @ann(bar=List("8b")) - val s = 4: Int @ann(bar=List("9a")) @ann(bar=List("9b")) - r + s - } - } - }.tree - println(tree.toString) - - // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - val ttree = toolbox.typeCheck(tree) - println(ttree.toString) - - // test 3: import and compile - toolbox.runExpr(tree) -} \ No newline at end of file diff --git a/test/files/neg/reify_ann2b.check b/test/files/neg/reify_ann2b.check index ceb70689f1..b9dd84c1ee 100644 --- a/test/files/neg/reify_ann2b.check +++ b/test/files/neg/reify_ann2b.check @@ -1,7 +1,4 @@ -reify_ann2b.scala:10: error: inner classes cannot be classfile annotations - class ann(bar: String) extends ClassfileAnnotation - ^ -reify_ann2b.scala:9: error: exception during macro expansion: implementation restriction: cannot reify annotation @ann(bar = "1a") which involves a symbol declared inside the block being reified - val tree = scala.reflect.Code.lift{ - ^ -two errors found +reify_ann2b.scala:6: error: inner classes cannot be classfile annotations + class ann(bar: String) extends ClassfileAnnotation + ^ +one error found diff --git a/test/files/neg/reify_ann2b.scala b/test/files/neg/reify_ann2b.scala index b43567c2a7..6b6da8f790 100644 --- a/test/files/neg/reify_ann2b.scala +++ b/test/files/neg/reify_ann2b.scala @@ -1,12 +1,8 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { // test 1: reify - val tree = scala.reflect.Code.lift{ + val tree = reify{ class ann(bar: String) extends ClassfileAnnotation @ann(bar="1a") @ann(bar="1b") class C[@ann(bar="2a") @ann(bar="2b") T](@ann(bar="3a") @ann(bar="3b") x: T @ann(bar="4a") @ann(bar="4b")) { @@ -20,8 +16,7 @@ object Test extends App { println(tree.toString) // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val ttree = toolbox.typeCheck(tree) println(ttree.toString) diff --git a/test/files/neg/t2386.check b/test/files/neg/t2386.check index 1a01696a9a..f70f12535f 100644 --- a/test/files/neg/t2386.check +++ b/test/files/neg/t2386.check @@ -1,4 +1,4 @@ -t2386.scala:2: error: could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[Array[_ >: String with Int]] - val a = Array(Array(1, 2), Array("a","b")) - ^ -one error found +t2386.scala:2: error: No ClassTag available for Array[_ >: String with Int] + val a = Array(Array(1, 2), Array("a","b")) + ^ +one error found diff --git a/test/files/neg/t2775.check b/test/files/neg/t2775.check index a30d35fdd9..f357221cd9 100644 --- a/test/files/neg/t2775.check +++ b/test/files/neg/t2775.check @@ -1,4 +1,4 @@ -t2775.scala:1: error: cannot find class manifest for element type B.this.T -trait B[S] { type T = S; val c = new Array[T](1) } - ^ -one error found +t2775.scala:1: error: cannot find class tag for element type B.this.T +trait B[S] { type T = S; val c = new Array[T](1) } + ^ +one error found diff --git a/test/files/neg/t3507.check b/test/files/neg/t3507.check index 8e538e4a8b..6b6df6ba76 100644 --- a/test/files/neg/t3507.check +++ b/test/files/neg/t3507.check @@ -1,4 +1,4 @@ -t3507.scala:13: error: No Manifest available for _1.b.c.type. - mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier - ^ -one error found +t3507.scala:13: error: No GroundTypeTag available for _1.b.c.type + mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier + ^ +one error found diff --git a/test/files/neg/t3692.check b/test/files/neg/t3692.check index 96ddd2a461..ec67e76bb4 100644 --- a/test/files/neg/t3692.check +++ b/test/files/neg/t3692.check @@ -1,4 +1,11 @@ -t3692.scala:15: error: unreachable code - case m2: Map[T, Int] => new java.util.HashMap[T, Integer] - ^ -one error found +t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.GroundTypeTag` instead + private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = { + ^ +t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.GroundTypeTag` instead + private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = { + ^ +t3692.scala:15: error: unreachable code + case m2: Map[T, Int] => new java.util.HashMap[T, Integer] + ^ +two warnings found +one error found diff --git a/test/files/neg/t5334_1.check b/test/files/neg/t5334_1.check new file mode 100644 index 0000000000..1d5a7cbc01 --- /dev/null +++ b/test/files/neg/t5334_1.check @@ -0,0 +1,4 @@ +t5334_1.scala:4: error: implementation restriction: cannot reify block of type C that involves a type declared inside the block being reified. consider casting the return value to a suitable type + reify { + ^ +one error found diff --git a/test/files/neg/t5334_1.scala b/test/files/neg/t5334_1.scala new file mode 100644 index 0000000000..a7de5a0915 --- /dev/null +++ b/test/files/neg/t5334_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.mirror._ + +object Test extends App { + reify { + class C { override def toString = "C" } + new C + }.eval +} diff --git a/test/files/neg/t5334_2.check b/test/files/neg/t5334_2.check new file mode 100644 index 0000000000..a62bfff7a5 --- /dev/null +++ b/test/files/neg/t5334_2.check @@ -0,0 +1,4 @@ +t5334_2.scala:4: error: implementation restriction: cannot reify block of type List[(C, C)] that involves a type declared inside the block being reified. consider casting the return value to a suitable type + reify { + ^ +one error found diff --git a/test/files/neg/t5334_2.scala b/test/files/neg/t5334_2.scala new file mode 100644 index 0000000000..fc6dfcd0c1 --- /dev/null +++ b/test/files/neg/t5334_2.scala @@ -0,0 +1,8 @@ +import scala.reflect.mirror._ + +object Test extends App { + reify { + class C { override def toString() = "C" } + List((new C, new C)) + }.eval +} diff --git a/test/files/pos/implicits.scala b/test/files/pos/implicits.scala deleted file mode 100644 index 2c01dd0ba8..0000000000 --- a/test/files/pos/implicits.scala +++ /dev/null @@ -1,89 +0,0 @@ -// #1435 -object t1435 { - implicit def a(s:String):String = error("") - implicit def a(i:Int):String = error("") - implicit def b(i:Int):String = error("") -} - -class C1435 { - val v:String = { - import t1435.a - 2 - } -} - -// #1492 -class C1492 { - - class X - - def foo(x: X => X) {} - - foo ( implicit x => implicitly[X] ) - foo { implicit x => implicitly[X] } -} - -// #1579 -object Test1579 { - class Column - class Query[E](val value: E) - class Invoker(q: Any) { val foo = null } - - implicit def unwrap[C](q: Query[C]) = q.value - implicit def invoker(q: Query[Column]) = new Invoker(q) - - val q = new Query(new Column) - q.foo -} -// #1625 -object Test1625 { - - class Wrapped(x:Any) { - def unwrap() = x - } - - implicit def byName[A](x: =>A) = new Wrapped(x) - - implicit def byVal[A](x: A) = x - - def main(args: Array[String]) = { - -// val res:Wrapped = 7 // works - - val res = 7.unwrap() // doesn't work - - println("=> result: " + res) - } -} - -object Test2188 { - implicit def toJavaList[A: ClassManifest](t:collection.Seq[A]):java.util.List[A] = java.util.Arrays.asList(t.toArray:_*) - - val x: java.util.List[String] = List("foo") -} - -object TestNumericWidening { - val y = 1 - val x: java.lang.Long = y -} - -// #2709 -package foo2709 { - class A - class B - - package object bar { - implicit def a2b(a: A): B = new B - } - - package bar { - object test { - new A: B - } - } -} - -// Problem with specs -object specsProblem { - println(implicitly[Manifest[Class[_]]]) -} diff --git a/test/files/pos/implicits.scala.temporarily.disabled b/test/files/pos/implicits.scala.temporarily.disabled new file mode 100644 index 0000000000..2c01dd0ba8 --- /dev/null +++ b/test/files/pos/implicits.scala.temporarily.disabled @@ -0,0 +1,89 @@ +// #1435 +object t1435 { + implicit def a(s:String):String = error("") + implicit def a(i:Int):String = error("") + implicit def b(i:Int):String = error("") +} + +class C1435 { + val v:String = { + import t1435.a + 2 + } +} + +// #1492 +class C1492 { + + class X + + def foo(x: X => X) {} + + foo ( implicit x => implicitly[X] ) + foo { implicit x => implicitly[X] } +} + +// #1579 +object Test1579 { + class Column + class Query[E](val value: E) + class Invoker(q: Any) { val foo = null } + + implicit def unwrap[C](q: Query[C]) = q.value + implicit def invoker(q: Query[Column]) = new Invoker(q) + + val q = new Query(new Column) + q.foo +} +// #1625 +object Test1625 { + + class Wrapped(x:Any) { + def unwrap() = x + } + + implicit def byName[A](x: =>A) = new Wrapped(x) + + implicit def byVal[A](x: A) = x + + def main(args: Array[String]) = { + +// val res:Wrapped = 7 // works + + val res = 7.unwrap() // doesn't work + + println("=> result: " + res) + } +} + +object Test2188 { + implicit def toJavaList[A: ClassManifest](t:collection.Seq[A]):java.util.List[A] = java.util.Arrays.asList(t.toArray:_*) + + val x: java.util.List[String] = List("foo") +} + +object TestNumericWidening { + val y = 1 + val x: java.lang.Long = y +} + +// #2709 +package foo2709 { + class A + class B + + package object bar { + implicit def a2b(a: A): B = new B + } + + package bar { + object test { + new A: B + } + } +} + +// Problem with specs +object specsProblem { + println(implicitly[Manifest[Class[_]]]) +} diff --git a/test/files/pos/liftcode_polymorphic.scala b/test/files/pos/liftcode_polymorphic.scala index 3d4b159c83..9c59b34bee 100644 --- a/test/files/pos/liftcode_polymorphic.scala +++ b/test/files/pos/liftcode_polymorphic.scala @@ -1,3 +1,5 @@ +import scala.reflect.mirror._ + object Append extends Application { def append[A](l1: List[A], l2: List[A]):List[A] = @@ -6,6 +8,6 @@ object Append extends Application { case x::xs => x :: append(xs, l2) } - println(scala.reflect.Code.lift(append _).tree) + println(reify(append _).tree) } diff --git a/test/files/pos/macros.flags b/test/files/pos/macros.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/pos/macros.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/pos/macros.scala b/test/files/pos/macros.scala deleted file mode 100644 index 303610d464..0000000000 --- a/test/files/pos/macros.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Test { - - class C { - def macro foo[T](xs: List[T]): T = (T, xs) match { - case (t1: Type, t2: Tree) => t2 - } - } -} diff --git a/test/files/pos/manifest1.scala b/test/files/pos/manifest1.scala deleted file mode 100644 index 8901aa7437..0000000000 --- a/test/files/pos/manifest1.scala +++ /dev/null @@ -1,21 +0,0 @@ -import scala.reflect.Manifest - -object Test { - def foo[T](x: T)(implicit m: Manifest[T]) { - foo(List(x)) - } - foo(1) - foo("abc") - foo(List(1, 2, 3)) - val x: List[Int] with Ordered[List[Int]] = null - foo(x) - foo[x.type](x) - abstract class C { type T = String; val x: T } - val c = new C { val x = "abc" } - foo(c.x) - abstract class D { type T; implicit val m: Manifest[T]; val x: T } - val stringm = implicitly[Manifest[String]] - val d: D = new D { type T = String; val m = stringm; val x = "x" } - import d.m - foo(d.x) -} diff --git a/test/files/pos/manifest1.scala.temporarily.disabled b/test/files/pos/manifest1.scala.temporarily.disabled new file mode 100644 index 0000000000..8901aa7437 --- /dev/null +++ b/test/files/pos/manifest1.scala.temporarily.disabled @@ -0,0 +1,21 @@ +import scala.reflect.Manifest + +object Test { + def foo[T](x: T)(implicit m: Manifest[T]) { + foo(List(x)) + } + foo(1) + foo("abc") + foo(List(1, 2, 3)) + val x: List[Int] with Ordered[List[Int]] = null + foo(x) + foo[x.type](x) + abstract class C { type T = String; val x: T } + val c = new C { val x = "abc" } + foo(c.x) + abstract class D { type T; implicit val m: Manifest[T]; val x: T } + val stringm = implicitly[Manifest[String]] + val d: D = new D { type T = String; val m = stringm; val x = "x" } + import d.m + foo(d.x) +} diff --git a/test/files/pos/t5223.scala b/test/files/pos/t5223.scala index 51682e9254..398630dc61 100644 --- a/test/files/pos/t5223.scala +++ b/test/files/pos/t5223.scala @@ -1,6 +1,6 @@ -import scala.reflect._ +import scala.reflect.mirror._ object Foo extends App { - Code.lift{def printf(format: String, args: Any*): String = null } - Code.lift{def printf(format: String, args: Any*): String = ("abc": @cloneable)} + reify{def printf(format: String, args: Any*): String = null } + reify{def printf(format: String, args: Any*): String = ("abc": @cloneable)} } diff --git a/test/files/pos/t531.scala b/test/files/pos/t531.scala index 856926de4f..5176912ef0 100644 --- a/test/files/pos/t531.scala +++ b/test/files/pos/t531.scala @@ -1,8 +1,9 @@ +import scala.reflect.mirror._ + object Test extends App { - import scala.reflect._; def titi = { var truc = 0 - val tata = Code.lift{() => { + val tata = reify{() => { truc = 6 }} () diff --git a/test/files/pos/t532.scala b/test/files/pos/t532.scala index f864bbf45e..a319fdfa27 100644 --- a/test/files/pos/t532.scala +++ b/test/files/pos/t532.scala @@ -1,8 +1,9 @@ +import scala.reflect.mirror._ + object Test extends App { - import scala.reflect._; def titi: Unit = { var truc = 0 - val tata = Code.lift{() => { + val tata = reify{() => { truc = truc + 6 }} () diff --git a/test/files/run/classtags_contextbound.check b/test/files/run/classtags_contextbound.check new file mode 100644 index 0000000000..4104d544ba --- /dev/null +++ b/test/files/run/classtags_contextbound.check @@ -0,0 +1 @@ +class [I diff --git a/test/files/run/classtags_contextbound.scala b/test/files/run/classtags_contextbound.scala new file mode 100644 index 0000000000..5bb0ae8d80 --- /dev/null +++ b/test/files/run/classtags_contextbound.scala @@ -0,0 +1,5 @@ +object Test extends App { + def mkArray[T: ClassTag] = Array[T]() + def foo[T: ClassTag] = mkArray[T] + println(foo[Int].getClass) +} \ No newline at end of file diff --git a/test/files/run/classtags_core.check b/test/files/run/classtags_core.check new file mode 100644 index 0000000000..ce5a893b08 --- /dev/null +++ b/test/files/run/classtags_core.check @@ -0,0 +1,30 @@ +true +ClassTag(byte) +true +ClassTag(short) +true +ClassTag(char) +true +ClassTag(int) +true +ClassTag(long) +true +ClassTag(float) +true +ClassTag(double) +true +ClassTag(boolean) +true +ClassTag(void) +true +ClassTag(class java.lang.Object) +true +ClassTag(class java.lang.Object) +true +ClassTag(class java.lang.Object) +true +ClassTag(class java.lang.Object) +true +ClassTag(class java.lang.Object) +true +ClassTag(class java.lang.Object) diff --git a/test/files/run/classtags_core.scala b/test/files/run/classtags_core.scala new file mode 100644 index 0000000000..45c54b1fe0 --- /dev/null +++ b/test/files/run/classtags_core.scala @@ -0,0 +1,32 @@ +object Test extends App { + println(implicitly[ClassTag[Byte]] eq ClassTag.Byte) + println(implicitly[ClassTag[Byte]]) + println(implicitly[ClassTag[Short]] eq ClassTag.Short) + println(implicitly[ClassTag[Short]]) + println(implicitly[ClassTag[Char]] eq ClassTag.Char) + println(implicitly[ClassTag[Char]]) + println(implicitly[ClassTag[Int]] eq ClassTag.Int) + println(implicitly[ClassTag[Int]]) + println(implicitly[ClassTag[Long]] eq ClassTag.Long) + println(implicitly[ClassTag[Long]]) + println(implicitly[ClassTag[Float]] eq ClassTag.Float) + println(implicitly[ClassTag[Float]]) + println(implicitly[ClassTag[Double]] eq ClassTag.Double) + println(implicitly[ClassTag[Double]]) + println(implicitly[ClassTag[Boolean]] eq ClassTag.Boolean) + println(implicitly[ClassTag[Boolean]]) + println(implicitly[ClassTag[Unit]] eq ClassTag.Unit) + println(implicitly[ClassTag[Unit]]) + println(implicitly[ClassTag[Any]] eq ClassTag.Any) + println(implicitly[ClassTag[Any]]) + println(implicitly[ClassTag[Object]] eq ClassTag.Object) + println(implicitly[ClassTag[Object]]) + println(implicitly[ClassTag[AnyVal]] eq ClassTag.AnyVal) + println(implicitly[ClassTag[AnyVal]]) + println(implicitly[ClassTag[AnyRef]] eq ClassTag.AnyRef) + println(implicitly[ClassTag[AnyRef]]) + println(implicitly[ClassTag[Null]] eq ClassTag.Null) + println(implicitly[ClassTag[Null]]) + println(implicitly[ClassTag[Nothing]] eq ClassTag.Nothing) + println(implicitly[ClassTag[Nothing]]) +} \ No newline at end of file diff --git a/test/files/run/existentials3.check b/test/files/run/existentials3.check deleted file mode 100644 index 36a458dacc..0000000000 --- a/test/files/run/existentials3.check +++ /dev/null @@ -1,22 +0,0 @@ -_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with Test$ToS with scala.Product with scala.Serializable -Object with Test$ToS -Object with Test$ToS -Object with Test$ToS -scala.Function0[Object with Test$ToS] -scala.Function0[Object with Test$ToS] -_ <: Object with _ <: Object with Object with Test$ToS -_ <: Object with _ <: Object with _ <: Object with Test$ToS -scala.collection.immutable.List[Object with scala.collection.Seq[Int]] -scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] -_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with Test$ToS with scala.Product with scala.Serializable -Object with Test$ToS -Object with Test$ToS -Object with Test$ToS -scala.Function0[Object with Test$ToS] -scala.Function0[Object with Test$ToS] -_ <: Object with _ <: Object with Object with Test$ToS -_ <: Object with _ <: Object with _ <: Object with Test$ToS -scala.collection.immutable.List[Object with scala.collection.Seq[Int]] -scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] diff --git a/test/files/run/existentials3.check.temporarily.disabled b/test/files/run/existentials3.check.temporarily.disabled new file mode 100644 index 0000000000..36a458dacc --- /dev/null +++ b/test/files/run/existentials3.check.temporarily.disabled @@ -0,0 +1,22 @@ +_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with Test$ToS with scala.Product with scala.Serializable +Object with Test$ToS +Object with Test$ToS +Object with Test$ToS +scala.Function0[Object with Test$ToS] +scala.Function0[Object with Test$ToS] +_ <: Object with _ <: Object with Object with Test$ToS +_ <: Object with _ <: Object with _ <: Object with Test$ToS +scala.collection.immutable.List[Object with scala.collection.Seq[Int]] +scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] +_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with Test$ToS with scala.Product with scala.Serializable +Object with Test$ToS +Object with Test$ToS +Object with Test$ToS +scala.Function0[Object with Test$ToS] +scala.Function0[Object with Test$ToS] +_ <: Object with _ <: Object with Object with Test$ToS +_ <: Object with _ <: Object with _ <: Object with Test$ToS +scala.collection.immutable.List[Object with scala.collection.Seq[Int]] +scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] diff --git a/test/files/run/existentials3.scala b/test/files/run/existentials3.scala deleted file mode 100644 index bb80d366cc..0000000000 --- a/test/files/run/existentials3.scala +++ /dev/null @@ -1,73 +0,0 @@ -object Test { - trait ToS { final override def toString = getClass.getName } - - def f1 = { case class Bar() extends ToS; Bar } - def f2 = { case class Bar() extends ToS; Bar() } - def f3 = { class Bar() extends ToS; object Bar extends ToS; Bar } - def f4 = { class Bar() extends ToS; new Bar() } - def f5 = { object Bar extends ToS; Bar } - def f6 = { () => { object Bar extends ToS ; Bar } } - def f7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } - - def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } - def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } - - def f10 = { class A { type T1 } ; List[A#T1]() } - def f11 = { abstract class A extends Seq[Int] ; List[A]() } - def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } - - val g1 = { case class Bar() extends ToS; Bar } - val g2 = { case class Bar() extends ToS; Bar() } - val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar } - val g4 = { class Bar() extends ToS; new Bar() } - val g5 = { object Bar extends ToS; Bar } - val g6 = { () => { object Bar extends ToS ; Bar } } - val g7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } - - val g8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } - val g9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } - - val g10 = { class A { type T1 } ; List[A#T1]() } - val g11 = { abstract class A extends Seq[Int] ; List[A]() } - val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } - - def m[T: Manifest](x: T) = println(manifest[T]) - - // manifests don't work for f10/g10 - def main(args: Array[String]): Unit = { - m(f1) - m(f2) - m(f3) - m(f4) - m(f5) - m(f6) - m(f7) - m(f8) - m(f9) - // m(f10) - m(f11) - m(f12) - m(g1) - m(g2) - m(g3) - m(g4) - m(g5) - m(g6) - m(g7) - m(g8) - m(g9) - // m(g10) - m(g11) - m(g12) - } -} - -object Misc { - trait Bippy { def bippy = "I'm Bippy!" } - object o1 { - def f1 = { trait A extends Seq[U forSome { type U <: Bippy }] ; abstract class B extends A ; trait C extends B ; (null: C) } - def f2 = f1.head.bippy - } - def g1 = o1.f1 _ - def g2 = o1.f2 _ -} diff --git a/test/files/run/existentials3.scala.temporarily.disabled b/test/files/run/existentials3.scala.temporarily.disabled new file mode 100644 index 0000000000..bb80d366cc --- /dev/null +++ b/test/files/run/existentials3.scala.temporarily.disabled @@ -0,0 +1,73 @@ +object Test { + trait ToS { final override def toString = getClass.getName } + + def f1 = { case class Bar() extends ToS; Bar } + def f2 = { case class Bar() extends ToS; Bar() } + def f3 = { class Bar() extends ToS; object Bar extends ToS; Bar } + def f4 = { class Bar() extends ToS; new Bar() } + def f5 = { object Bar extends ToS; Bar } + def f6 = { () => { object Bar extends ToS ; Bar } } + def f7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } + + def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } + def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } + + def f10 = { class A { type T1 } ; List[A#T1]() } + def f11 = { abstract class A extends Seq[Int] ; List[A]() } + def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } + + val g1 = { case class Bar() extends ToS; Bar } + val g2 = { case class Bar() extends ToS; Bar() } + val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar } + val g4 = { class Bar() extends ToS; new Bar() } + val g5 = { object Bar extends ToS; Bar } + val g6 = { () => { object Bar extends ToS ; Bar } } + val g7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } + + val g8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } + val g9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } + + val g10 = { class A { type T1 } ; List[A#T1]() } + val g11 = { abstract class A extends Seq[Int] ; List[A]() } + val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } + + def m[T: Manifest](x: T) = println(manifest[T]) + + // manifests don't work for f10/g10 + def main(args: Array[String]): Unit = { + m(f1) + m(f2) + m(f3) + m(f4) + m(f5) + m(f6) + m(f7) + m(f8) + m(f9) + // m(f10) + m(f11) + m(f12) + m(g1) + m(g2) + m(g3) + m(g4) + m(g5) + m(g6) + m(g7) + m(g8) + m(g9) + // m(g10) + m(g11) + m(g12) + } +} + +object Misc { + trait Bippy { def bippy = "I'm Bippy!" } + object o1 { + def f1 = { trait A extends Seq[U forSome { type U <: Bippy }] ; abstract class B extends A ; trait C extends B ; (null: C) } + def f2 = f1.head.bippy + } + def g1 = o1.f1 _ + def g2 = o1.f2 _ +} diff --git a/test/files/run/groundtypetags_core.check b/test/files/run/groundtypetags_core.check new file mode 100644 index 0000000000..d1b71f0926 --- /dev/null +++ b/test/files/run/groundtypetags_core.check @@ -0,0 +1,30 @@ +true +GroundTypeTag[Byte] +true +GroundTypeTag[Short] +true +GroundTypeTag[Char] +true +GroundTypeTag[Int] +true +GroundTypeTag[Long] +true +GroundTypeTag[Float] +true +GroundTypeTag[Double] +true +GroundTypeTag[Boolean] +true +GroundTypeTag[Unit] +true +GroundTypeTag[Any] +true +GroundTypeTag[Object] +true +GroundTypeTag[AnyVal] +true +GroundTypeTag[AnyRef] +true +GroundTypeTag[Null] +true +GroundTypeTag[Nothing] diff --git a/test/files/run/groundtypetags_core.scala b/test/files/run/groundtypetags_core.scala new file mode 100644 index 0000000000..d779e3fc7e --- /dev/null +++ b/test/files/run/groundtypetags_core.scala @@ -0,0 +1,32 @@ +object Test extends App { + println(implicitly[GroundTypeTag[Byte]] eq GroundTypeTag.Byte) + println(implicitly[GroundTypeTag[Byte]]) + println(implicitly[GroundTypeTag[Short]] eq GroundTypeTag.Short) + println(implicitly[GroundTypeTag[Short]]) + println(implicitly[GroundTypeTag[Char]] eq GroundTypeTag.Char) + println(implicitly[GroundTypeTag[Char]]) + println(implicitly[GroundTypeTag[Int]] eq GroundTypeTag.Int) + println(implicitly[GroundTypeTag[Int]]) + println(implicitly[GroundTypeTag[Long]] eq GroundTypeTag.Long) + println(implicitly[GroundTypeTag[Long]]) + println(implicitly[GroundTypeTag[Float]] eq GroundTypeTag.Float) + println(implicitly[GroundTypeTag[Float]]) + println(implicitly[GroundTypeTag[Double]] eq GroundTypeTag.Double) + println(implicitly[GroundTypeTag[Double]]) + println(implicitly[GroundTypeTag[Boolean]] eq GroundTypeTag.Boolean) + println(implicitly[GroundTypeTag[Boolean]]) + println(implicitly[GroundTypeTag[Unit]] eq GroundTypeTag.Unit) + println(implicitly[GroundTypeTag[Unit]]) + println(implicitly[GroundTypeTag[Any]] eq GroundTypeTag.Any) + println(implicitly[GroundTypeTag[Any]]) + println(implicitly[GroundTypeTag[Object]] eq GroundTypeTag.Object) + println(implicitly[GroundTypeTag[Object]]) + println(implicitly[GroundTypeTag[AnyVal]] eq GroundTypeTag.AnyVal) + println(implicitly[GroundTypeTag[AnyVal]]) + println(implicitly[GroundTypeTag[AnyRef]] eq GroundTypeTag.AnyRef) + println(implicitly[GroundTypeTag[AnyRef]]) + println(implicitly[GroundTypeTag[Null]] eq GroundTypeTag.Null) + println(implicitly[GroundTypeTag[Null]]) + println(implicitly[GroundTypeTag[Nothing]] eq GroundTypeTag.Nothing) + println(implicitly[GroundTypeTag[Nothing]]) +} \ No newline at end of file diff --git a/test/files/run/macro-abort-fresh.check b/test/files/run/macro-abort-fresh.check new file mode 100644 index 0000000000..28057c2883 --- /dev/null +++ b/test/files/run/macro-abort-fresh.check @@ -0,0 +1,6 @@ +$1$ +qwe1 +qwe2 +reflective compilation has failed: + +blargh diff --git a/test/files/run/macro-abort-fresh.flags b/test/files/run/macro-abort-fresh.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-abort-fresh.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-abort-fresh/Macros_1.scala b/test/files/run/macro-abort-fresh/Macros_1.scala new file mode 100644 index 0000000000..4186c4c4a6 --- /dev/null +++ b/test/files/run/macro-abort-fresh/Macros_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.Context + +object Impls { + def impl(c: Context) = { + import c.mirror._ + println(c.fresh()) + println(c.fresh("qwe")) + println(c.fresh(newTypeName("qwe"))) + c.abort(NoPosition, "blargh") + } +} + +object Macros { + def foo = macro Impls.impl +} \ No newline at end of file diff --git a/test/files/run/macro-abort-fresh/Test_2.scala b/test/files/run/macro-abort-fresh/Test_2.scala new file mode 100644 index 0000000000..f389231ca6 --- /dev/null +++ b/test/files/run/macro-abort-fresh/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Select(Ident("Macros"), newTermName("foo")) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-md-mi.check b/test/files/run/macro-basic-ma-md-mi.check new file mode 100644 index 0000000000..b74e882ae3 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi.check @@ -0,0 +1 @@ +31 \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-md-mi.flags b/test/files/run/macro-basic-ma-md-mi.flags new file mode 100644 index 0000000000..06a7b31f11 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi.flags @@ -0,0 +1 @@ +-Xmacros diff --git a/test/files/run/macro-basic-ma-md-mi/Impls_1.scala b/test/files/run/macro-basic-ma-md-mi/Impls_1.scala new file mode 100644 index 0000000000..3f23e349d5 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi/Impls_1.scala @@ -0,0 +1,21 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } + + def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + Expr[Int](body) + } + + def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} diff --git a/test/files/run/macro-basic-ma-md-mi/Macros_2.scala b/test/files/run/macro-basic-ma-md-mi/Macros_2.scala new file mode 100644 index 0000000000..5279043746 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi/Macros_2.scala @@ -0,0 +1,10 @@ +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo + } + def bar(x: Int): Int = macro Impls.bar +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux +} \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-md-mi/Test_3.scala b/test/files/run/macro-basic-ma-md-mi/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-mdmi.check b/test/files/run/macro-basic-ma-mdmi.check new file mode 100644 index 0000000000..b74e882ae3 --- /dev/null +++ b/test/files/run/macro-basic-ma-mdmi.check @@ -0,0 +1 @@ +31 \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-mdmi.flags b/test/files/run/macro-basic-ma-mdmi.flags new file mode 100644 index 0000000000..06a7b31f11 --- /dev/null +++ b/test/files/run/macro-basic-ma-mdmi.flags @@ -0,0 +1 @@ +-Xmacros diff --git a/test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala b/test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala new file mode 100644 index 0000000000..44bfe861e3 --- /dev/null +++ b/test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala @@ -0,0 +1,32 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } + + def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + Expr[Int](body) + } + + def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} + +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo + } + def bar(x: Int): Int = macro Impls.bar +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux +} \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-mdmi/Test_2.scala b/test/files/run/macro-basic-ma-mdmi/Test_2.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/run/macro-basic-ma-mdmi/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/run/macro-basic-mamd-mi.check b/test/files/run/macro-basic-mamd-mi.check new file mode 100644 index 0000000000..b74e882ae3 --- /dev/null +++ b/test/files/run/macro-basic-mamd-mi.check @@ -0,0 +1 @@ +31 \ No newline at end of file diff --git a/test/files/run/macro-basic-mamd-mi.flags b/test/files/run/macro-basic-mamd-mi.flags new file mode 100644 index 0000000000..06a7b31f11 --- /dev/null +++ b/test/files/run/macro-basic-mamd-mi.flags @@ -0,0 +1 @@ +-Xmacros diff --git a/test/files/run/macro-basic-mamd-mi/Impls_1.scala b/test/files/run/macro-basic-mamd-mi/Impls_1.scala new file mode 100644 index 0000000000..eadb63fa8e --- /dev/null +++ b/test/files/run/macro-basic-mamd-mi/Impls_1.scala @@ -0,0 +1,19 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} diff --git a/test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala b/test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala new file mode 100644 index 0000000000..d3746894f0 --- /dev/null +++ b/test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala @@ -0,0 +1,15 @@ +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo + } + def bar(x: Int): Int = macro Impls.bar +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux +} + +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/run/macro-basic.check b/test/files/run/macro-basic.check deleted file mode 100644 index d434014897..0000000000 --- a/test/files/run/macro-basic.check +++ /dev/null @@ -1 +0,0 @@ -10 diff --git a/test/files/run/macro-basic.flags b/test/files/run/macro-basic.flags deleted file mode 100644 index 06a7b31f11..0000000000 --- a/test/files/run/macro-basic.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros diff --git a/test/files/run/macro-basic/Macros_1.scala b/test/files/run/macro-basic/Macros_1.scala deleted file mode 100644 index c2ea183abe..0000000000 --- a/test/files/run/macro-basic/Macros_1.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Macros { - object Shmacros { - def macro foo(x: Int): Int = x - } - def macro bar(x: Int): Int = x -} - -class Macros { - def macro quux(x: Int): Int = x -} \ No newline at end of file diff --git a/test/files/run/macro-basic/Test_2.scala b/test/files/run/macro-basic/Test_2.scala deleted file mode 100644 index e9a10e20c9..0000000000 --- a/test/files/run/macro-basic/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros.Shmacros._ - println(foo(2) + Macros.bar(2) * new Macros().quux(4)) -} \ No newline at end of file diff --git a/test/files/run/macro-bodyexpandstoimpl.check b/test/files/run/macro-bodyexpandstoimpl.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/files/run/macro-bodyexpandstoimpl.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/files/run/macro-bodyexpandstoimpl.flags b/test/files/run/macro-bodyexpandstoimpl.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-bodyexpandstoimpl.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala new file mode 100644 index 0000000000..5c5ec2c999 --- /dev/null +++ b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = x + + def refToFoo(dummy: Int) = macro refToFoo_impl + def refToFoo_impl(c: Ctx)(dummy: c.Expr[Int]) = { + import c.mirror._ + val body = Select(Ident(newTermName("Impls")), newTermName("foo")) + Expr[Int](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala b/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala new file mode 100644 index 0000000000..2934201a16 --- /dev/null +++ b/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo(x: Int) = macro Impls.refToFoo(42) +} + +object Test extends App { + import Macros._ + println(foo(42)) +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation.check b/test/files/run/macro-declared-in-annotation.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-declared-in-annotation.flags b/test/files/run/macro-declared-in-annotation.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation/Impls_1.scala b/test/files/run/macro-declared-in-annotation/Impls_1.scala new file mode 100644 index 0000000000..a1234a7374 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Literal(Constant("this is deprecated"))) + Expr[String](body) + } +} diff --git a/test/files/run/macro-declared-in-annotation/Macros_2.scala b/test/files/run/macro-declared-in-annotation/Macros_2.scala new file mode 100644 index 0000000000..a565849aa9 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation/Macros_2.scala @@ -0,0 +1,8 @@ +class foo(val bar: String) extends StaticAnnotation + +object Api { + // foo in ann must have a different name + // otherwise, we get bitten by https://issues.scala-lang.org/browse/SI-5544 + @foo({def fooInAnn = macro Impls.foo; fooInAnn}) + def foo = println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation/Test_3.scala b/test/files/run/macro-declared-in-annotation/Test_3.scala new file mode 100644 index 0000000000..866487f028 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation/Test_3.scala @@ -0,0 +1,3 @@ +object Test extends App { + Api.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-anonymous.check b/test/files/run/macro-declared-in-anonymous.check new file mode 100644 index 0000000000..09b8d015a6 --- /dev/null +++ b/test/files/run/macro-declared-in-anonymous.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.macros) +it works diff --git a/test/files/run/macro-declared-in-anonymous.flags b/test/files/run/macro-declared-in-anonymous.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-anonymous.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-anonymous/Impls_1.scala b/test/files/run/macro-declared-in-anonymous/Impls_1.scala new file mode 100644 index 0000000000..c0827ace31 --- /dev/null +++ b/test/files/run/macro-declared-in-anonymous/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala b/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala new file mode 100644 index 0000000000..8bd8c172c9 --- /dev/null +++ b/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val macros = new { def foo = macro Impls.foo } + macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-block.check b/test/files/run/macro-declared-in-block.check new file mode 100644 index 0000000000..a61fd13087 --- /dev/null +++ b/test/files/run/macro-declared-in-block.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing]() +it works diff --git a/test/files/run/macro-declared-in-block.flags b/test/files/run/macro-declared-in-block.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-block.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-block/Impls_1.scala b/test/files/run/macro-declared-in-block/Impls_1.scala new file mode 100644 index 0000000000..c0827ace31 --- /dev/null +++ b/test/files/run/macro-declared-in-block/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-block/Macros_Test_2.scala b/test/files/run/macro-declared-in-block/Macros_Test_2.scala new file mode 100644 index 0000000000..69088e24bc --- /dev/null +++ b/test/files/run/macro-declared-in-block/Macros_Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + { + def foo = macro Impls.foo + foo + } +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-class.check b/test/files/run/macro-declared-in-class-class.check new file mode 100644 index 0000000000..480c2f906f --- /dev/null +++ b/test/files/run/macro-declared-in-class-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](new Test.this.outer.Macros()) +it works diff --git a/test/files/run/macro-declared-in-class-class.flags b/test/files/run/macro-declared-in-class-class.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-class-class.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-class/Impls_1.scala b/test/files/run/macro-declared-in-class-class/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-class-class/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala new file mode 100644 index 0000000000..871857a97f --- /dev/null +++ b/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala @@ -0,0 +1,10 @@ +class Macros { + class Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = new Macros() + new outer.Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-object.check b/test/files/run/macro-declared-in-class-object.check new file mode 100644 index 0000000000..f7ba5a53cb --- /dev/null +++ b/test/files/run/macro-declared-in-class-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.outer.Macros) +it works diff --git a/test/files/run/macro-declared-in-class-object.flags b/test/files/run/macro-declared-in-class-object.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-class-object.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-object/Impls_1.scala b/test/files/run/macro-declared-in-class-object/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-class-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala new file mode 100644 index 0000000000..994f9fe935 --- /dev/null +++ b/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala @@ -0,0 +1,10 @@ +class Macros { + object Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = new Macros() + outer.Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class.check b/test/files/run/macro-declared-in-class.check new file mode 100644 index 0000000000..946851e4bb --- /dev/null +++ b/test/files/run/macro-declared-in-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](new Macros()) +it works diff --git a/test/files/run/macro-declared-in-class.flags b/test/files/run/macro-declared-in-class.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-class.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class/Impls_1.scala b/test/files/run/macro-declared-in-class/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-class/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-class/Macros_Test_2.scala new file mode 100644 index 0000000000..1b9d13e775 --- /dev/null +++ b/test/files/run/macro-declared-in-class/Macros_Test_2.scala @@ -0,0 +1,7 @@ +class Macros { + def foo = macro Impls.foo +} + +object Test extends App { + new Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-default-param.check b/test/files/run/macro-declared-in-default-param.check new file mode 100644 index 0000000000..00052ad018 --- /dev/null +++ b/test/files/run/macro-declared-in-default-param.check @@ -0,0 +1,5 @@ +prefix = Expr[Nothing]() +it works +it works +prefix = Expr[Nothing]() +it works diff --git a/test/files/run/macro-declared-in-default-param.flags b/test/files/run/macro-declared-in-default-param.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-default-param.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-default-param/Impls_1.scala b/test/files/run/macro-declared-in-default-param/Impls_1.scala new file mode 100644 index 0000000000..e45095812a --- /dev/null +++ b/test/files/run/macro-declared-in-default-param/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Literal(Constant("it works"))) + Expr[String](body) + } +} diff --git a/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala b/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala new file mode 100644 index 0000000000..356029e63e --- /dev/null +++ b/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala @@ -0,0 +1,7 @@ +object Test extends App { + def foo(bar: String = { def foo = macro Impls.foo; foo }) = println(bar) + + foo() + foo("it works") + foo() +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-implicit-class.check b/test/files/run/macro-declared-in-implicit-class.check new file mode 100644 index 0000000000..b3640ceaa7 --- /dev/null +++ b/test/files/run/macro-declared-in-implicit-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Macros.foo("2")) +Some(2) diff --git a/test/files/run/macro-declared-in-implicit-class.flags b/test/files/run/macro-declared-in-implicit-class.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-implicit-class.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala new file mode 100644 index 0000000000..8605d4a8be --- /dev/null +++ b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala @@ -0,0 +1,19 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def toOptionOfInt(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Ident(definitions.SomeModule), List(Select(Select(prefix.tree, newTermName("x")), newTermName("toInt"))))) + Expr[Option[Int]](body) + } +} + +object Macros { + implicit def foo(x: String): Foo = new Foo(x) + + class Foo(val x: String) { + def toOptionOfInt = macro Impls.toOptionOfInt + } +} diff --git a/test/files/run/macro-declared-in-implicit-class/Test_2.scala b/test/files/run/macro-declared-in-implicit-class/Test_2.scala new file mode 100644 index 0000000000..d0bc9cc38c --- /dev/null +++ b/test/files/run/macro-declared-in-implicit-class/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + println("2".toOptionOfInt) +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-method.check b/test/files/run/macro-declared-in-method.check new file mode 100644 index 0000000000..a61fd13087 --- /dev/null +++ b/test/files/run/macro-declared-in-method.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing]() +it works diff --git a/test/files/run/macro-declared-in-method.flags b/test/files/run/macro-declared-in-method.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-method.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-method/Impls_1.scala b/test/files/run/macro-declared-in-method/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-method/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-method/Macros_Test_2.scala b/test/files/run/macro-declared-in-method/Macros_Test_2.scala new file mode 100644 index 0000000000..ed5c8b7c43 --- /dev/null +++ b/test/files/run/macro-declared-in-method/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Test extends App { + def bar() = { + def foo = macro Impls.foo + foo + } + + bar() +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-class.check b/test/files/run/macro-declared-in-object-class.check new file mode 100644 index 0000000000..480c2f906f --- /dev/null +++ b/test/files/run/macro-declared-in-object-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](new Test.this.outer.Macros()) +it works diff --git a/test/files/run/macro-declared-in-object-class.flags b/test/files/run/macro-declared-in-object-class.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-object-class.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-class/Impls_1.scala b/test/files/run/macro-declared-in-object-class/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-object-class/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala new file mode 100644 index 0000000000..204deed61c --- /dev/null +++ b/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + class Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = Macros + new outer.Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-object.check b/test/files/run/macro-declared-in-object-object.check new file mode 100644 index 0000000000..f7ba5a53cb --- /dev/null +++ b/test/files/run/macro-declared-in-object-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.outer.Macros) +it works diff --git a/test/files/run/macro-declared-in-object-object.flags b/test/files/run/macro-declared-in-object-object.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-object-object.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-object/Impls_1.scala b/test/files/run/macro-declared-in-object-object/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-object-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala new file mode 100644 index 0000000000..e261a50f3d --- /dev/null +++ b/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + object Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = Macros + outer.Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object.check b/test/files/run/macro-declared-in-object.check new file mode 100644 index 0000000000..05a8cc48ea --- /dev/null +++ b/test/files/run/macro-declared-in-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Macros) +it works diff --git a/test/files/run/macro-declared-in-object.flags b/test/files/run/macro-declared-in-object.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-object.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object/Impls_1.scala b/test/files/run/macro-declared-in-object/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-object/Macros_Test_2.scala new file mode 100644 index 0000000000..a5a4862ba0 --- /dev/null +++ b/test/files/run/macro-declared-in-object/Macros_Test_2.scala @@ -0,0 +1,7 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-package-object.check b/test/files/run/macro-declared-in-package-object.check new file mode 100644 index 0000000000..6f797f3c68 --- /dev/null +++ b/test/files/run/macro-declared-in-package-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Macros.`package`) +it works diff --git a/test/files/run/macro-declared-in-package-object.flags b/test/files/run/macro-declared-in-package-object.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-package-object.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-package-object/Impls_1.scala b/test/files/run/macro-declared-in-package-object/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-package-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala new file mode 100644 index 0000000000..54a5962e80 --- /dev/null +++ b/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala @@ -0,0 +1,8 @@ +package object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-refinement.check b/test/files/run/macro-declared-in-refinement.check new file mode 100644 index 0000000000..861cd43b01 --- /dev/null +++ b/test/files/run/macro-declared-in-refinement.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.macros) +it works diff --git a/test/files/run/macro-declared-in-refinement.flags b/test/files/run/macro-declared-in-refinement.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-refinement.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-refinement/Impls_1.scala b/test/files/run/macro-declared-in-refinement/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-refinement/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala b/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala new file mode 100644 index 0000000000..f746c2da57 --- /dev/null +++ b/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala @@ -0,0 +1,6 @@ +class Base + +object Test extends App { + val macros = new Base { def foo = macro Impls.foo } + macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-trait.check b/test/files/run/macro-declared-in-trait.check new file mode 100644 index 0000000000..d5d9e4e457 --- /dev/null +++ b/test/files/run/macro-declared-in-trait.check @@ -0,0 +1,15 @@ +prefix = Expr[Nothing]({ + final class $anon extends Object with Base { + def (): anonymous class $anon = { + $anon.super.(); + () + }; + + }; + new $anon() +}) +it works +prefix = Expr[Nothing](Macros) +it works +prefix = Expr[Nothing](new Macros()) +it works diff --git a/test/files/run/macro-declared-in-trait.flags b/test/files/run/macro-declared-in-trait.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-trait.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-trait/Impls_1.scala b/test/files/run/macro-declared-in-trait/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-trait/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-trait/Macros_Test_2.scala b/test/files/run/macro-declared-in-trait/Macros_Test_2.scala new file mode 100644 index 0000000000..f75906b636 --- /dev/null +++ b/test/files/run/macro-declared-in-trait/Macros_Test_2.scala @@ -0,0 +1,13 @@ +trait Base { + def foo = macro Impls.foo +} + +object Macros extends Base + +class Macros extends Base + +object Test extends App { + (new Base {}).foo + Macros.foo + new Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a.check b/test/files/run/macro-def-infer-return-type-a.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-a.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a.flags b/test/files/run/macro-def-infer-return-type-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a/Impls_1.scala b/test/files/run/macro-def-infer-return-type-a/Impls_1.scala new file mode 100644 index 0000000000..2346a6106d --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = x +} diff --git a/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala new file mode 100644 index 0000000000..60fe9dc1c2 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo(x: Int) = macro Impls.foo + println(foo(42)) +} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b.check b/test/files/run/macro-def-infer-return-type-b.check new file mode 100644 index 0000000000..f34d257c82 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-b.check @@ -0,0 +1,6 @@ +reflective compilation has failed: + +exception during macro expansion: +java.lang.Error: an implementation is missing + at Impls$.foo(Impls_Macros_1.scala:5) + diff --git a/test/files/run/macro-def-infer-return-type-b.flags b/test/files/run/macro-def-infer-return-type-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala b/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..8640713846 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T](c: Ctx)(x: c.Expr[T]) = + throw new Error("an implementation is missing") +} + +object Macros { + def foo[T](x: T) = macro Impls.foo[T] +} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b/Test_2.scala b/test/files/run/macro-def-infer-return-type-b/Test_2.scala new file mode 100644 index 0000000000..8ff4494750 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-b/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c.check b/test/files/run/macro-def-infer-return-type-c.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-c.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c.flags b/test/files/run/macro-def-infer-return-type-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c/Impls_1.scala b/test/files/run/macro-def-infer-return-type-c/Impls_1.scala new file mode 100644 index 0000000000..f3e53bbea7 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-c/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T](c: Ctx)(x: c.Expr[T]): c.Expr[T] = x +} diff --git a/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala new file mode 100644 index 0000000000..967d16f6de --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[T](x: T) = macro Impls.foo[T] + println(foo(42)) +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-a.check b/test/files/run/macro-def-path-dependent-a.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-a.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-def-path-dependent-a.flags b/test/files/run/macro-def-path-dependent-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala new file mode 100644 index 0000000000..d7167e671c --- /dev/null +++ b/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala @@ -0,0 +1,21 @@ +import scala.reflect.makro.{Context => Ctx} + +trait Exprs { + self: Universe => + + class Expr[T] +} + +trait Reifiers { + self: Universe => + + type Expr[T] + + def reify[T](expr: T) = macro Impls.reify[T] +} + +trait Universe extends Exprs with Reifiers + +object Impls { + def reify[T](cc: Ctx{ type PrefixType = Reifiers })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent-a/Test_2.scala b/test/files/run/macro-def-path-dependent-a/Test_2.scala new file mode 100644 index 0000000000..7dffc5107d --- /dev/null +++ b/test/files/run/macro-def-path-dependent-a/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-b.check b/test/files/run/macro-def-path-dependent-b.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-b.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-def-path-dependent-b.flags b/test/files/run/macro-def-path-dependent-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..44af6949a7 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala @@ -0,0 +1,20 @@ +import scala.reflect.makro.{Context => Ctx} + +trait Exprs { + self: Universe => + + class Expr[T] +} + +trait Reifiers { + self: Universe => + +} + +trait Universe extends Exprs with Reifiers { + def reify[T](expr: T) = macro Impls.reify[T] +} + +object Impls { + def reify[T](cc: Ctx{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent-b/Test_2.scala b/test/files/run/macro-def-path-dependent-b/Test_2.scala new file mode 100644 index 0000000000..7dffc5107d --- /dev/null +++ b/test/files/run/macro-def-path-dependent-b/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-c.check b/test/files/run/macro-def-path-dependent-c.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-c.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-def-path-dependent-c.flags b/test/files/run/macro-def-path-dependent-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala new file mode 100644 index 0000000000..305146c48b --- /dev/null +++ b/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala @@ -0,0 +1,20 @@ +import scala.reflect.makro.{Context => Ctx} + +trait Exprs { + self: Universe => + + class Expr[T] +} + +trait Reifiers { + self: Universe => + +} + +trait Universe extends Exprs with Reifiers { + def reify[T](expr: T): Expr[T] = macro Impls.reify[T] +} + +object Impls { + def reify[T](cc: Ctx{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent-c/Test_2.scala b/test/files/run/macro-def-path-dependent-c/Test_2.scala new file mode 100644 index 0000000000..7dffc5107d --- /dev/null +++ b/test/files/run/macro-def-path-dependent-c/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d.check b/test/files/run/macro-def-path-dependent-d.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-d.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-def-path-dependent-d.flags b/test/files/run/macro-def-path-dependent-d.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-d.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala new file mode 100644 index 0000000000..32f03e778e --- /dev/null +++ b/test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.makro.Context +import scala.reflect.api.Universe + +object Test { + def materializeTypeTag[T](u: Universe)(e: T) = macro materializeTypeTag_impl[T] + + def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe])(e: c.Expr[T]): c.Expr[u.value.TypeTag[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent-d/Test_2.scala b/test/files/run/macro-def-path-dependent-d/Test_2.scala new file mode 100644 index 0000000000..7dffc5107d --- /dev/null +++ b/test/files/run/macro-def-path-dependent-d/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit.check b/test/files/run/macro-expand-implicit-macro-has-implicit.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-has-implicit.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit.flags b/test/files/run/macro-expand-implicit-macro-has-implicit.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-has-implicit.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala new file mode 100644 index 0000000000..39db275e1c --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(x.tree)) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala new file mode 100644 index 0000000000..ffb04dc80b --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + implicit val x = 42 + def foo(implicit x: Int) = macro Impls.foo + foo +} \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit.check b/test/files/run/macro-expand-implicit-macro-is-implicit.check new file mode 100644 index 0000000000..42abf4579b --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-implicit.check @@ -0,0 +1,2 @@ +Some(2) +2 diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit.flags b/test/files/run/macro-expand-implicit-macro-is-implicit.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-implicit.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala new file mode 100644 index 0000000000..0262485994 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[String]): c.Expr[Option[Int]] = { + import c.mirror._ + val body = Apply(Ident(definitions.SomeModule), List(Select(x.tree, newTermName("toInt")))) + Expr[Option[Int]](body) + } +} diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala new file mode 100644 index 0000000000..81ebd63c5f --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + implicit def foo(x: String): Option[Int] = macro Impls.foo +} + +object Test extends App { + import Macros._ + println("2": Option[Int]) + val s: Int = "2" getOrElse 0 + println(s) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-val.check b/test/files/run/macro-expand-implicit-macro-is-val.check new file mode 100644 index 0000000000..78c6baefdd --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-val.check @@ -0,0 +1 @@ +2 diff --git a/test/files/run/macro-expand-implicit-macro-is-val.flags b/test/files/run/macro-expand-implicit-macro-is-val.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-val.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala new file mode 100644 index 0000000000..510d8502f6 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.mirror._ + val body = Literal(Constant(2)) + Expr[Int](body) + } +} diff --git a/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala new file mode 100644 index 0000000000..b91b1016c9 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + implicit def foo = macro Impls.foo + def bar(implicit x: Int) = println(x) + bar +} \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-view.check b/test/files/run/macro-expand-implicit-macro-is-view.check new file mode 100644 index 0000000000..78c6baefdd --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-view.check @@ -0,0 +1 @@ +2 diff --git a/test/files/run/macro-expand-implicit-macro-is-view.flags b/test/files/run/macro-expand-implicit-macro-is-view.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-view.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala new file mode 100644 index 0000000000..0262485994 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[String]): c.Expr[Option[Int]] = { + import c.mirror._ + val body = Apply(Ident(definitions.SomeModule), List(Select(x.tree, newTermName("toInt")))) + Expr[Option[Int]](body) + } +} diff --git a/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala new file mode 100644 index 0000000000..0ff1fb80ca --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala @@ -0,0 +1,9 @@ +object Macros { + implicit def foo(x: String): Option[Int] = macro Impls.foo +} + +object Test extends App { + import Macros._ + def bar[T <% Option[Int]](x: T) = println(x) + println("2") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-multiple-arglists.check b/test/files/run/macro-expand-multiple-arglists.check new file mode 100644 index 0000000000..c24b6ae77d --- /dev/null +++ b/test/files/run/macro-expand-multiple-arglists.check @@ -0,0 +1 @@ +38 \ No newline at end of file diff --git a/test/files/run/macro-expand-multiple-arglists.flags b/test/files/run/macro-expand-multiple-arglists.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-multiple-arglists.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-multiple-arglists/Impls_1.scala b/test/files/run/macro-expand-multiple-arglists/Impls_1.scala new file mode 100644 index 0000000000..ae1c50eace --- /dev/null +++ b/test/files/run/macro-expand-multiple-arglists/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int])(y: c.Expr[Int]) = { + import c.mirror._ + val sum = Apply(Select(x.tree, newTermName("$minus")), List(y.tree)) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum)) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala b/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala new file mode 100644 index 0000000000..fa4504b0ea --- /dev/null +++ b/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo(x: Int)(y: Int) = macro Impls.foo + foo(40)(2) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-generic.check b/test/files/run/macro-expand-nullary-generic.check new file mode 100644 index 0000000000..34a453cd3a --- /dev/null +++ b/test/files/run/macro-expand-nullary-generic.check @@ -0,0 +1,6 @@ +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +kkthxbai diff --git a/test/files/run/macro-expand-nullary-generic.flags b/test/files/run/macro-expand-nullary-generic.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-nullary-generic.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-generic/Impls_1.scala b/test/files/run/macro-expand-nullary-generic/Impls_1.scala new file mode 100644 index 0000000000..10352594f5 --- /dev/null +++ b/test/files/run/macro-expand-nullary-generic/Impls_1.scala @@ -0,0 +1,14 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl[T: c.TypeTag](c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works " + implicitly[c.TypeTag[T]])))) + Expr[Unit](body) + } + + def fooNullary[T: c.TypeTag](c: Ctx) = impl[T](c) + def fooEmpty[T: c.TypeTag](c: Ctx)() = impl[T](c) + def barNullary[T: c.TypeTag](c: Ctx)(x: c.Expr[Int]) = impl[T](c) + def barEmpty[T: c.TypeTag](c: Ctx)(x: c.Expr[Int])() = impl[T](c) +} diff --git a/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala b/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala new file mode 100644 index 0000000000..2d5cf53c3c --- /dev/null +++ b/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala @@ -0,0 +1,15 @@ +object Macros { + def foo1[T] = macro Impls.fooNullary[T] + def foo2[T]() = macro Impls.fooEmpty[T] + def bar1[T](x: Int) = macro Impls.barNullary[T] + def bar2[T](x: Int)() = macro Impls.barEmpty[T] +} + +object Test extends App { + Macros.foo1[Int] + Macros.foo2[Int] + Macros.foo2[Int]() + Macros.bar1[Int](42) + Macros.bar2[Int](42)() + println("kkthxbai") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-nongeneric.check b/test/files/run/macro-expand-nullary-nongeneric.check new file mode 100644 index 0000000000..9ab5f3a2bc --- /dev/null +++ b/test/files/run/macro-expand-nullary-nongeneric.check @@ -0,0 +1,6 @@ +it works +it works +it works +it works +it works +kkthxbai diff --git a/test/files/run/macro-expand-nullary-nongeneric.flags b/test/files/run/macro-expand-nullary-nongeneric.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-nullary-nongeneric.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala b/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala new file mode 100644 index 0000000000..7dc58abba8 --- /dev/null +++ b/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala @@ -0,0 +1,14 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))) + Expr[Unit](body) + } + + def fooNullary(c: Ctx) = impl(c) + def fooEmpty(c: Ctx)() = impl(c) + def barNullary(c: Ctx)(x: c.Expr[Int]) = impl(c) + def barEmpty(c: Ctx)(x: c.Expr[Int])() = impl(c) +} diff --git a/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala b/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala new file mode 100644 index 0000000000..1f6d717956 --- /dev/null +++ b/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala @@ -0,0 +1,15 @@ +object Macros { + def foo1 = macro Impls.fooNullary + def foo2() = macro Impls.fooEmpty + def bar1(x: Int) = macro Impls.barNullary + def bar2(x: Int)() = macro Impls.barEmpty +} + +object Test extends App { + Macros.foo1 + Macros.foo2 + Macros.foo2() + Macros.bar1(42) + Macros.bar2(42)() + println("kkthxbai") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-overload.check b/test/files/run/macro-expand-overload.check new file mode 100644 index 0000000000..9d9989d85f --- /dev/null +++ b/test/files/run/macro-expand-overload.check @@ -0,0 +1,6 @@ +(fooObjectString,Expr[Nothing](Macros),42) +(fooObjectInt,Expr[Nothing](Macros),42) +fooObjectBoolean +(fooClassString,Expr[Nothing](new Macros()),42) +(fooClassInt,Expr[Nothing](new Macros()),42) +fooClassBoolean diff --git a/test/files/run/macro-expand-overload.flags b/test/files/run/macro-expand-overload.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-overload.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-overload/Impls_1.scala b/test/files/run/macro-expand-overload/Impls_1.scala new file mode 100644 index 0000000000..1dc4adc20e --- /dev/null +++ b/test/files/run/macro-expand-overload/Impls_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx)(tag: String, x: c.Expr[_]) = { + import c.{prefix => prefix} + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(tag)), Literal(Constant(prefix.toString)), x.tree)) + Expr[Unit](body) + } + + def fooObjectString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooObjectString", x) + def fooObjectInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooObjectInt", x) + def fooClassString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooClassString", x) + def fooClassInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooClassInt", x) +} diff --git a/test/files/run/macro-expand-overload/Macros_Test_2.scala b/test/files/run/macro-expand-overload/Macros_Test_2.scala new file mode 100644 index 0000000000..7f61f85184 --- /dev/null +++ b/test/files/run/macro-expand-overload/Macros_Test_2.scala @@ -0,0 +1,20 @@ +object Macros { + def foo(x: String) = macro Impls.fooObjectString + def foo(x: Int) = macro Impls.fooObjectInt + def foo(x: Boolean) = println("fooObjectBoolean") +} + +class Macros { + def foo(x: String) = macro Impls.fooClassString + def foo(x: Int) = macro Impls.fooClassInt + def foo(x: Boolean) = println("fooClassBoolean") +} + +object Test extends App { + Macros.foo("42") + Macros.foo(42) + Macros.foo(true) + new Macros().foo("42") + new Macros().foo(42) + new Macros().foo(true) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-override.check b/test/files/run/macro-expand-override.check new file mode 100644 index 0000000000..486bec7098 --- /dev/null +++ b/test/files/run/macro-expand-override.check @@ -0,0 +1,15 @@ +(fooBString,Expr[Nothing](Test.this.dd),42) +(fooDInt,Expr[Nothing](Test.this.dd),42) +fooBBoolean +(fooBString,Expr[Nothing](Test.this.db),42) +(fooBInt,Expr[Nothing](Test.this.db),42) +fooBBoolean +(fooZString,Expr[Nothing](Test.this.zz),42) +(fooDInt,Expr[Nothing](Test.this.zz),42) +fooZBoolean +(fooBString,Expr[Nothing](Test.this.zd),42) +(fooDInt,Expr[Nothing](Test.this.zd),42) +fooZBoolean +(fooBString,Expr[Nothing](Test.this.zb),42) +(fooBInt,Expr[Nothing](Test.this.zb),42) +fooZBoolean diff --git a/test/files/run/macro-expand-override.flags b/test/files/run/macro-expand-override.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-override.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-override/Impls_1.scala b/test/files/run/macro-expand-override/Impls_1.scala new file mode 100644 index 0000000000..0b127f5a59 --- /dev/null +++ b/test/files/run/macro-expand-override/Impls_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx)(tag: String, x: c.Expr[_]) = { + import c.{prefix => prefix} + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(tag)), Literal(Constant(prefix.toString)), x.tree)) + Expr[Unit](body) + } + + def fooBString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBString", x) + def fooBInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBInt", x) + def fooDInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooDInt", x) + def fooZString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooZString", x) +} diff --git a/test/files/run/macro-expand-override/Macros_Test_2.scala b/test/files/run/macro-expand-override/Macros_Test_2.scala new file mode 100644 index 0000000000..f162773c95 --- /dev/null +++ b/test/files/run/macro-expand-override/Macros_Test_2.scala @@ -0,0 +1,43 @@ +class B { + def foo(x: String) = macro Impls.fooBString + def foo(x: Int) = macro Impls.fooBInt + def foo(x: Boolean) = println("fooBBoolean") +} + +class D extends B { + //override def foo(x: String) = println("fooDString") => method cannot override a macro + override def foo(x: Int) = macro Impls.fooDInt +} + +class Z extends D { + override def foo(x: String) = macro Impls.fooZString + override def foo(x: Boolean) = println("fooZBoolean") +} + +object Test extends App { + + val dd: D = new D() + dd.foo("42") + dd.foo(42) + dd.foo(true) + + val db: B = new D() + db.foo("42") + db.foo(42) + db.foo(true) + + val zz: Z = new Z() + zz.foo("42") + zz.foo(42) + zz.foo(true) + + val zd: D = new Z() + zd.foo("42") + zd.foo(42) + zd.foo(true) + + val zb: B = new Z() + zb.foo("42") + zb.foo(42) + zb.foo(true) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-recursive.check b/test/files/run/macro-expand-recursive.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-expand-recursive.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-expand-recursive.flags b/test/files/run/macro-expand-recursive.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-recursive.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-recursive/Impls_1.scala b/test/files/run/macro-expand-recursive/Impls_1.scala new file mode 100644 index 0000000000..6eff805989 --- /dev/null +++ b/test/files/run/macro-expand-recursive/Impls_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))) + Expr[Unit](body) + } + + def fooFoo(c: Ctx) = { + import c.mirror._ + val body = Select(Ident(newTermName("Macros")), newTermName("foo")) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-recursive/Macros_Test_2.scala b/test/files/run/macro-expand-recursive/Macros_Test_2.scala new file mode 100644 index 0000000000..6ff691bdb1 --- /dev/null +++ b/test/files/run/macro-expand-recursive/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo + def fooFoo = macro Impls.fooFoo +} + +object Test extends App { + Macros.fooFoo +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-a.check b/test/files/run/macro-expand-tparams-bounds-a.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-expand-tparams-bounds-a.flags b/test/files/run/macro-expand-tparams-bounds-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala new file mode 100644 index 0000000000..4cd98c5838 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx): c.Expr[Unit] = { + import c.mirror._ + Literal(Constant(())) + } +} diff --git a/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala new file mode 100644 index 0000000000..b498e6f65b --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U <: String] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[String] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-b.check b/test/files/run/macro-expand-tparams-bounds-b.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-expand-tparams-bounds-b.flags b/test/files/run/macro-expand-tparams-bounds-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala new file mode 100644 index 0000000000..9103ddb08a --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +class C + +object Impls { + def foo[U <: C](c: Ctx): c.Expr[Unit] = { + import c.mirror._ + Literal(Constant(())) + } +} diff --git a/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala new file mode 100644 index 0000000000..1a261e9f73 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala @@ -0,0 +1,10 @@ +class D extends C + +object Macros { + def foo[T <: D] = macro Impls.foo[T] +} + +object Test extends App { + import Macros._ + foo[D] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-explicit.check b/test/files/run/macro-expand-tparams-explicit.check new file mode 100644 index 0000000000..54da026aa8 --- /dev/null +++ b/test/files/run/macro-expand-tparams-explicit.check @@ -0,0 +1 @@ +GroundTypeTag[Int] diff --git a/test/files/run/macro-expand-tparams-explicit.flags b/test/files/run/macro-expand-tparams-explicit.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-explicit.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-explicit/Impls_1.scala b/test/files/run/macro-expand-tparams-explicit/Impls_1.scala new file mode 100644 index 0000000000..957d8331fc --- /dev/null +++ b/test/files/run/macro-expand-tparams-explicit/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U: c.TypeTag](c: Ctx) = { + import c.mirror._ + val U = implicitly[c.TypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(U.toString)))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala new file mode 100644 index 0000000000..e72c27881a --- /dev/null +++ b/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[U] = macro Impls.foo[U] + foo[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-implicit.check b/test/files/run/macro-expand-tparams-implicit.check new file mode 100644 index 0000000000..60c021a35b --- /dev/null +++ b/test/files/run/macro-expand-tparams-implicit.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[String] diff --git a/test/files/run/macro-expand-tparams-implicit.flags b/test/files/run/macro-expand-tparams-implicit.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-implicit.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-implicit/Impls_1.scala b/test/files/run/macro-expand-tparams-implicit/Impls_1.scala new file mode 100644 index 0000000000..c25d12be60 --- /dev/null +++ b/test/files/run/macro-expand-tparams-implicit/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U: c.TypeTag](c: Ctx)(x: c.Expr[U]) = { + import c.mirror._ + val U = implicitly[c.TypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(U.toString)))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala new file mode 100644 index 0000000000..f8c573f509 --- /dev/null +++ b/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + def foo[U](x: U) = macro Impls.foo[U] + foo(42) + foo("42") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-only-in-impl.flags b/test/files/run/macro-expand-tparams-only-in-impl.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-only-in-impl.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala b/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala new file mode 100644 index 0000000000..4cd98c5838 --- /dev/null +++ b/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx): c.Expr[Unit] = { + import c.mirror._ + Literal(Constant(())) + } +} diff --git a/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala new file mode 100644 index 0000000000..218c7aec7f --- /dev/null +++ b/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo[String] +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-optional.check b/test/files/run/macro-expand-tparams-optional.check new file mode 100644 index 0000000000..3bacd7a4e0 --- /dev/null +++ b/test/files/run/macro-expand-tparams-optional.check @@ -0,0 +1 @@ +don't know U diff --git a/test/files/run/macro-expand-tparams-optional.flags b/test/files/run/macro-expand-tparams-optional.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-optional.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-optional/Impls_1.scala b/test/files/run/macro-expand-tparams-optional/Impls_1.scala new file mode 100644 index 0000000000..37efb009c4 --- /dev/null +++ b/test/files/run/macro-expand-tparams-optional/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U](c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("don't know U")))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala new file mode 100644 index 0000000000..e72c27881a --- /dev/null +++ b/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[U] = macro Impls.foo[U] + foo[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a.check b/test/files/run/macro-expand-tparams-prefix-a.check new file mode 100644 index 0000000000..1447c2478f --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-a.check @@ -0,0 +1,4 @@ +GroundTypeTag[Int] +GroundTypeTag[Int] +GroundTypeTag[String] +GroundTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-a.flags b/test/files/run/macro-expand-tparams-prefix-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala new file mode 100644 index 0000000000..c25d12be60 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U: c.TypeTag](c: Ctx)(x: c.Expr[U]) = { + import c.mirror._ + val U = implicitly[c.TypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(U.toString)))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala new file mode 100644 index 0000000000..81ccb7ff42 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Test extends App { + class C[T] { + def foo[U](x: U) = macro Impls.foo[U] + } + + new C[Int]().foo(42) + new C[Boolean]().foo(42) + new C[Int]().foo("42") + new C[String]().foo(true) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b.check b/test/files/run/macro-expand-tparams-prefix-b.check new file mode 100644 index 0000000000..c7ec594b92 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-b.check @@ -0,0 +1,2 @@ +GroundTypeTag[Boolean] GroundTypeTag[Int] +GroundTypeTag[Boolean] GroundTypeTag[String] diff --git a/test/files/run/macro-expand-tparams-prefix-b.flags b/test/files/run/macro-expand-tparams-prefix-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala new file mode 100644 index 0000000000..8af3ecc9ae --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T: c.TypeTag, U: c.TypeTag](c: Ctx)(x: c.Expr[U]) = { + import c.mirror._ + val T = implicitly[c.TypeTag[T]] + val U = implicitly[c.TypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString + " " + U.toString)))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala new file mode 100644 index 0000000000..a4a0acfe8b --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Test extends App { + class C[T] { + def foo[U](x: U) = macro Impls.foo[T, U] + } + + object D extends C[Boolean] + + D.foo(42) + D.foo("42") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1.check b/test/files/run/macro-expand-tparams-prefix-c1.check new file mode 100644 index 0000000000..fac58e9516 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c1.check @@ -0,0 +1,3 @@ +GroundTypeTag[Int] +GroundTypeTag[String] +GroundTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-c1.flags b/test/files/run/macro-expand-tparams-prefix-c1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala new file mode 100644 index 0000000000..bc880fdf77 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + Block(List( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(()))) + } +} diff --git a/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala new file mode 100644 index 0000000000..4fa0c8cb33 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala @@ -0,0 +1,11 @@ +class D[T] { + class C[U] { + def foo[V] = macro Impls.foo[T, U, V] + } +} + +object Test extends App { + val outer1 = new D[Int] + val outer2 = new outer1.C[String] + outer2.foo[Boolean] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2.check b/test/files/run/macro-expand-tparams-prefix-c2.check new file mode 100644 index 0000000000..fac58e9516 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c2.check @@ -0,0 +1,3 @@ +GroundTypeTag[Int] +GroundTypeTag[String] +GroundTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-c2.flags b/test/files/run/macro-expand-tparams-prefix-c2.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c2.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala b/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala new file mode 100644 index 0000000000..c83e401afb --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + Block(List( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(()))) + } +} + +class D[T] { + class C[U] { + def foo[V] = macro Impls.foo[T, U, V] + } +} diff --git a/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala b/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala new file mode 100644 index 0000000000..e729d4a536 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + val outer1 = new D[Int] + val outer2 = new outer1.C[String] + outer2.foo[Boolean] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1.check b/test/files/run/macro-expand-tparams-prefix-d1.check new file mode 100644 index 0000000000..f78ddea4f3 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-d1.check @@ -0,0 +1,3 @@ +TypeTag[T] +TypeTag[U] +GroundTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-d1.flags b/test/files/run/macro-expand-tparams-prefix-d1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-d1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala new file mode 100644 index 0000000000..bc880fdf77 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + Block(List( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(()))) + } +} diff --git a/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala new file mode 100644 index 0000000000..8222a6d1e8 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala @@ -0,0 +1,11 @@ +object Test extends App { + class D[T] { + class C[U] { + def foo[V] = macro Impls.foo[T, U, V] + foo[Boolean] + } + } + + val outer1 = new D[Int] + new outer1.C[String] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check new file mode 100644 index 0000000000..fd1d654cf8 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check @@ -0,0 +1,4 @@ +reflective compilation has failed: + +no `: _*' annotation allowed here +(such annotations are only allowed in arguments to *-parameters) diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala new file mode 100644 index 0000000000..d97f0af786 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(xs: c.Expr[Int]*) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), xs.map(_.tree).toList) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala new file mode 100644 index 0000000000..523c6b0645 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + def foo(xs: Int*) = macro Impls.foo +} + +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Typed(Apply(Ident(definitions.ListModule), List(Literal(Constant(1)), Literal(Constant(2)))), Ident(tpnme.WILDCARD_STAR)))) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check new file mode 100644 index 0000000000..835137b4a2 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check @@ -0,0 +1 @@ +List(1, 2, 3, 4, 5) diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala new file mode 100644 index 0000000000..f9667d78b8 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(xs: c.Expr[Int]*) = { + import c.mirror._ + val stripped_xs = xs map (_.tree) toList match { + case List(Typed(stripped, Ident(wildstar))) if wildstar == tpnme.WILDCARD_STAR => List(stripped) + case _ => ??? + } + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), stripped_xs) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala new file mode 100644 index 0000000000..f127ebcde7 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(xs: Int*) = macro Impls.foo +} + +object Test extends App { + val numbers = List(1, 2, 3, 4, 5) + Macros.foo(numbers: _*) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs.check b/test/files/run/macro-expand-varargs-explicit-over-varargs.check new file mode 100644 index 0000000000..835137b4a2 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs.check @@ -0,0 +1 @@ +List(1, 2, 3, 4, 5) diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs.flags b/test/files/run/macro-expand-varargs-explicit-over-varargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala b/test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala new file mode 100644 index 0000000000..8c609daa0e --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def myprintln(xs: Int*) = { + println(xs) + } + + def foo(c: Ctx)(xs: c.Expr[Int]*) = { + import c.mirror._ + val body = Apply(Select(Ident(newTermName("Impls")), newTermName("myprintln")), xs.map(_.tree).toList) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala new file mode 100644 index 0000000000..f127ebcde7 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(xs: Int*) = macro Impls.foo +} + +object Test extends App { + val numbers = List(1, 2, 3, 4, 5) + Macros.foo(numbers: _*) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check new file mode 100644 index 0000000000..0a6596858c --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check @@ -0,0 +1 @@ +(1,2,3,4,5) diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala new file mode 100644 index 0000000000..d97f0af786 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(xs: c.Expr[Int]*) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), xs.map(_.tree).toList) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala new file mode 100644 index 0000000000..2311ca0b95 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala @@ -0,0 +1,7 @@ +object Macros { + def foo(xs: Int*) = macro Impls.foo +} + +object Test extends App { + Macros.foo(1, 2, 3, 4, 5) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs.check b/test/files/run/macro-expand-varargs-implicit-over-varargs.check new file mode 100644 index 0000000000..f25fa141d3 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs.check @@ -0,0 +1 @@ +WrappedArray(1, 2, 3, 4, 5) diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs.flags b/test/files/run/macro-expand-varargs-implicit-over-varargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala b/test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala new file mode 100644 index 0000000000..8c609daa0e --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def myprintln(xs: Int*) = { + println(xs) + } + + def foo(c: Ctx)(xs: c.Expr[Int]*) = { + import c.mirror._ + val body = Apply(Select(Ident(newTermName("Impls")), newTermName("myprintln")), xs.map(_.tree).toList) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala new file mode 100644 index 0000000000..2311ca0b95 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala @@ -0,0 +1,7 @@ +object Macros { + def foo(xs: Int*) = macro Impls.foo +} + +object Test extends App { + Macros.foo(1, 2, 3, 4, 5) +} \ No newline at end of file diff --git a/test/files/run/macro-impl-default-params.check b/test/files/run/macro-impl-default-params.check new file mode 100644 index 0000000000..eaf94458e6 --- /dev/null +++ b/test/files/run/macro-impl-default-params.check @@ -0,0 +1,5 @@ +foo_targs: +invoking foo_targs... +type of prefix is: Nothing +type of prefix tree is: Macros[Int] +U is: String diff --git a/test/files/run/macro-impl-default-params.flags b/test/files/run/macro-impl-default-params.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-impl-default-params.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-impl-default-params/Impls_Macros_1.scala b/test/files/run/macro-impl-default-params/Impls_Macros_1.scala new file mode 100644 index 0000000000..cece1c09e4 --- /dev/null +++ b/test/files/run/macro-impl-default-params/Impls_Macros_1.scala @@ -0,0 +1,20 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_targs[T, U: c.TypeTag](c: Ctx = null)(x: c.Expr[Int] = null) = { + import c.{prefix => prefix} + import c.mirror._ + val U = implicitly[c.TypeTag[U]] + val body = Block( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo_targs...")))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix is: " + prefix.tpe)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix tree is: " + prefix.tree.tpe)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + U.tpe)))), + Literal(Constant(()))) + Expr[Unit](body) + } +} + +class Macros[T] { + def foo_targs[U](x: Int) = macro Impls.foo_targs[T, U] +} diff --git a/test/files/run/macro-impl-default-params/Test_2.scala b/test/files/run/macro-impl-default-params/Test_2.scala new file mode 100644 index 0000000000..90e850df21 --- /dev/null +++ b/test/files/run/macro-impl-default-params/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + println("foo_targs:") + new Macros[Int]().foo_targs[String](42) +} \ No newline at end of file diff --git a/test/files/run/macro-impl-rename-context.check b/test/files/run/macro-impl-rename-context.check new file mode 100644 index 0000000000..753edcd970 --- /dev/null +++ b/test/files/run/macro-impl-rename-context.check @@ -0,0 +1,2 @@ +foo +invoking foo... diff --git a/test/files/run/macro-impl-rename-context.flags b/test/files/run/macro-impl-rename-context.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-impl-rename-context.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala b/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala new file mode 100644 index 0000000000..000e351f4d --- /dev/null +++ b/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(unconventionalName: Ctx)(x: unconventionalName.Expr[Int]) = { + import unconventionalName.mirror._ + val body = Block( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo...")))), + Literal(Constant(()))) + Expr[Unit](body) + } +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/run/macro-impl-rename-context/Test_2.scala b/test/files/run/macro-impl-rename-context/Test_2.scala new file mode 100644 index 0000000000..bd9c493544 --- /dev/null +++ b/test/files/run/macro-impl-rename-context/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + println("foo") + Macros.foo(42) +} \ No newline at end of file diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check new file mode 100644 index 0000000000..e21e05157a --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check @@ -0,0 +1,5 @@ +reflective compilation has failed: + +type mismatch; + found : String("42") + required: Int diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala new file mode 100644 index 0000000000..882867fcab --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx): c.Expr[Int] = { + import c.mirror._ + Literal(Constant("42")) + } +} + +object Macros { + def foo: Int = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala new file mode 100644 index 0000000000..f389231ca6 --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Select(Ident("Macros"), newTermName("foo")) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-invalidret-nontypeable.check b/test/files/run/macro-invalidret-nontypeable.check new file mode 100644 index 0000000000..eee08528e2 --- /dev/null +++ b/test/files/run/macro-invalidret-nontypeable.check @@ -0,0 +1,3 @@ +reflective compilation has failed: + +not found: value IDoNotExist diff --git a/test/files/run/macro-invalidret-nontypeable.flags b/test/files/run/macro-invalidret-nontypeable.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidret-nontypeable.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala b/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala new file mode 100644 index 0000000000..f3a0476a35 --- /dev/null +++ b/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.mirror._ + val body = Ident("IDoNotExist") + Expr[Int](body) + } +} + +object Macros { + def foo = macro Impls.foo +} diff --git a/test/files/run/macro-invalidret-nontypeable/Test_2.scala b/test/files/run/macro-invalidret-nontypeable/Test_2.scala new file mode 100644 index 0000000000..f389231ca6 --- /dev/null +++ b/test/files/run/macro-invalidret-nontypeable/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Select(Ident("Macros"), newTermName("foo")) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-badret.check b/test/files/run/macro-invalidusage-badret.check new file mode 100644 index 0000000000..5bdc484644 --- /dev/null +++ b/test/files/run/macro-invalidusage-badret.check @@ -0,0 +1,5 @@ +reflective compilation has failed: + +type mismatch; + found : Int(42) + required: String diff --git a/test/files/run/macro-invalidusage-badret.flags b/test/files/run/macro-invalidusage-badret.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidusage-badret.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala b/test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala new file mode 100644 index 0000000000..c63ad01677 --- /dev/null +++ b/test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = x +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/run/macro-invalidusage-badret/Test_2.scala b/test/files/run/macro-invalidusage-badret/Test_2.scala new file mode 100644 index 0000000000..e171c9d05a --- /dev/null +++ b/test/files/run/macro-invalidusage-badret/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Typed(Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))), Ident(newTypeName("String"))) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-partialapplication.check b/test/files/run/macro-invalidusage-partialapplication.check new file mode 100644 index 0000000000..73f57b0b81 --- /dev/null +++ b/test/files/run/macro-invalidusage-partialapplication.check @@ -0,0 +1,3 @@ +reflective compilation has failed: + +macros cannot be partially applied diff --git a/test/files/run/macro-invalidusage-partialapplication.flags b/test/files/run/macro-invalidusage-partialapplication.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidusage-partialapplication.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala b/test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala new file mode 100644 index 0000000000..449b91d074 --- /dev/null +++ b/test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala @@ -0,0 +1,14 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int])(y: c.Expr[Int]) = { + import c.mirror._ + val sum = Apply(Select(x.tree, newTermName("$plus")), List(y.tree)) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum)) + Expr[Unit](body) + } +} + +object Macros { + def foo(x: Int)(y: Int) = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-partialapplication/Test_2.scala b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala new file mode 100644 index 0000000000..63371a4a82 --- /dev/null +++ b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(40)))) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} diff --git a/test/files/run/macro-openmacros.check b/test/files/run/macro-openmacros.check new file mode 100644 index 0000000000..a4b06a1e1a --- /dev/null +++ b/test/files/run/macro-openmacros.check @@ -0,0 +1,3 @@ +List(MacroContext(foo@source-Test_2.scala,line-2,offset=35 +0)) +List(MacroContext(foo@source-Test_2.scala,line-2,offset=35 +1), MacroContext(foo@source-Test_2.scala,line-2,offset=35 +0)) +List(MacroContext(foo@source-Test_2.scala,line-2,offset=35 +2), MacroContext(foo@source-Test_2.scala,line-2,offset=35 +1), MacroContext(foo@source-Test_2.scala,line-2,offset=35 +0)) diff --git a/test/files/run/macro-openmacros.flags b/test/files/run/macro-openmacros.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-openmacros.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-openmacros/Impls_Macros_1.scala b/test/files/run/macro-openmacros/Impls_Macros_1.scala new file mode 100644 index 0000000000..9fd658656e --- /dev/null +++ b/test/files/run/macro-openmacros/Impls_Macros_1.scala @@ -0,0 +1,26 @@ +import scala.reflect.makro.Context + +object Macros { + def impl(c: Context): c.Expr[Unit] = { + // we're macros, so we can reflect against our source path + // so we don't need any partests to clean up after us! + val c.CompilationUnit(file, _, _) = c.enclosingUnit + val dir = file.getParentFile + def normalizePaths(s: String) = { + val base = (dir.getCanonicalPath + java.io.File.separator).replace('\\', '/') + var regex = """\Q%s\E""" format base + val isWin = System.getProperty("os.name", "") startsWith "Windows" + if (isWin) regex = "(?i)" + regex + s.replace('\\', '/').replaceAll(regex, "") + } + + import c.mirror._ + val next = if (c.enclosingMacros.length < 3) Expr[Unit](Select(Ident(staticModule("Macros")), newTermName("foo"))) else c.literalUnit + c.reify { + println(c.literal(normalizePaths(c.enclosingMacros.toString)).eval) + next.eval + } + } + + def foo = macro impl +} \ No newline at end of file diff --git a/test/files/run/macro-openmacros/Test_2.scala b/test/files/run/macro-openmacros/Test_2.scala new file mode 100644 index 0000000000..5d19639cdd --- /dev/null +++ b/test/files/run/macro-openmacros/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo +} diff --git a/test/files/run/macro-quasiinvalidbody-c.check b/test/files/run/macro-quasiinvalidbody-c.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/files/run/macro-quasiinvalidbody-c.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/files/run/macro-quasiinvalidbody-c.flags b/test/files/run/macro-quasiinvalidbody-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-quasiinvalidbody-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala b/test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala new file mode 100644 index 0000000000..7cb810c86b --- /dev/null +++ b/test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = x + } + + def foo(x: Any) = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/run/macro-quasiinvalidbody-c/Test_2.scala b/test/files/run/macro-quasiinvalidbody-c/Test_2.scala new file mode 100644 index 0000000000..dec29aa857 --- /dev/null +++ b/test/files/run/macro-quasiinvalidbody-c/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + println(foo(42)) +} \ No newline at end of file diff --git a/test/files/run/macro-range/Common_1.scala b/test/files/run/macro-range/Common_1.scala new file mode 100644 index 0000000000..bd46e1f529 --- /dev/null +++ b/test/files/run/macro-range/Common_1.scala @@ -0,0 +1,48 @@ +import reflect.api.Modifier +import reflect.makro.Context + +abstract class RangeDefault { + val from, to: Int + def foreach(f: Int => Unit) = { + var i = from + while (i < to) { f(i); i += 1 } + } +} + +/** This class should go into reflect.macro once it is a bit more stable. */ +abstract class Utils { + val context: Context + import context.mirror._ + + class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer { + override def transform(tree: Tree): Tree = tree match { + case Ident(_) => + def subst(from: List[Symbol], to: List[Tree]): Tree = + if (from.isEmpty) tree + else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`? + else subst(from.tail, to.tail); + subst(from, to) + case _ => + val tree1 = super.transform(tree) + if (tree1 ne tree) tree1.tpe = null + tree1 + } + } + def makeApply(fn: Tree, args: List[Tree]): Tree = fn match { + case Function(vparams, body) => + new TreeSubstituter(vparams map (_.symbol), args) transform body + case Block(stats, expr) => + Block(stats, makeApply(expr, args)) + case _ => + // todo. read the compiler config and print if -Ydebug is set + //println("no beta on "+fn+" "+fn.getClass) + Apply(fn, args) + } + def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = { + val continu = Apply(Ident(lname), Nil) + val rhs = If(cond, Block(List(body), continu), Literal(Constant())) + LabelDef(lname, Nil, rhs) + } + def makeBinop(left: Tree, op: String, right: Tree): Tree = + Apply(Select(left, newTermName(op)), List(right)) +} diff --git a/test/files/run/macro-range/Expansion_Impossible_2.scala b/test/files/run/macro-range/Expansion_Impossible_2.scala new file mode 100644 index 0000000000..7a093b74ee --- /dev/null +++ b/test/files/run/macro-range/Expansion_Impossible_2.scala @@ -0,0 +1,53 @@ +import reflect.api.Modifier +import reflect.makro.Context + +object Impls { + def foreach(c: Context)(f: c.Expr[Int => Unit]): c.Expr[Unit] = { + // todo. read the compiler config and print if -Ydebug is set + //println("macro-expand, _this = "+ _this) + object utils extends Utils { val context: c.type = c } + import utils._ + import c.mirror._ + + val initName = newTermName("") + // Either: + // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } } + // or: + // scala"($_this: RangeDefault).foreach($f)" + c.prefix.tree match { + case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" => + val iname = newTermName("$i") + val hname = newTermName("$h") + def iref = Ident(iname) + def href = Ident(hname) + val labelname = newTermName("$while") + val cond = makeBinop(iref, "$less", href) + val body = Block( + List(makeApply(f, List(iref))), + Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1))))) + val generated = + Block( + List( + ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo), + ValDef(Modifiers(), hname, TypeTree(), hi)), + makeWhile(labelname, cond, body)) + // todo. read the compiler config and print if -Ydebug is set + //tools.nsc.util.trace("generated: ")(generated) + generated + case _ => + Apply( + Select( + Typed(c.prefix, Ident(newTypeName("RangeDefault"))), + newTermName("foreach")), + List(f)) + } + } +} + +class Range(val from: Int, val to: Int) extends RangeDefault { + override def foreach(f: Int => Unit): Unit = macro Impls.foreach +} + +object Test extends App { + new Range(1, 10) foreach println +} \ No newline at end of file diff --git a/test/files/run/macro-range/Expansion_Possible_3.scala b/test/files/run/macro-range/Expansion_Possible_3.scala new file mode 100644 index 0000000000..e7ecbcc362 --- /dev/null +++ b/test/files/run/macro-range/Expansion_Possible_3.scala @@ -0,0 +1,7 @@ +class Range(val from: Int, val to: Int) extends RangeDefault { + override def foreach(f: Int => Unit): Unit = macro Impls.foreach +} + +object Test extends App { + new Range(1, 10) foreach println +} \ No newline at end of file diff --git a/test/files/run/macro-range/macro_range_1.scala b/test/files/run/macro-range/macro_range_1.scala deleted file mode 100644 index fdfe7169ad..0000000000 --- a/test/files/run/macro-range/macro_range_1.scala +++ /dev/null @@ -1,99 +0,0 @@ -import reflect.api.Modifier -import reflect.macro.Context - -abstract class RangeDefault { - val from, to: Int - def foreach(f: Int => Unit) = { - var i = from - while (i < to) { f(i); i += 1 } - } -} - -/** This class should go into reflect.macro once it is a bit more stable. */ -abstract class Utils { - val context: Context - import context._ - - class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer { - override def transform(tree: Tree): Tree = tree match { - case Ident(_) => - def subst(from: List[Symbol], to: List[Tree]): Tree = - if (from.isEmpty) tree - else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`? - else subst(from.tail, to.tail); - subst(from, to) - case _ => - val tree1 = super.transform(tree) - if (tree1 ne tree) tree1.tpe = null - tree1 - } - } - def makeApply(fn: Tree, args: List[Tree]): Tree = fn match { - case Function(vparams, body) => - new TreeSubstituter(vparams map (_.symbol), args) transform body - case Block(stats, expr) => - Block(stats, makeApply(expr, args)) - case _ => - // todo. read the compiler config and print if -Ydebug is set - //println("no beta on "+fn+" "+fn.getClass) - Apply(fn, args) - } - def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = { - val continu = Apply(Ident(lname), Nil) - val rhs = If(cond, Block(List(body), continu), Literal(Constant())) - LabelDef(lname, Nil, rhs) - } - def makeBinop(left: Tree, op: String, right: Tree): Tree = - Apply(Select(left, newTermName(op)), List(right)) -} - -class Range(val from: Int, val to: Int) extends RangeDefault { - override def macro foreach(f: Int => Unit): Unit = { - // todo. read the compiler config and print if -Ydebug is set - //println("macro-expand, _this = "+ _this) - import _context._ - object utils extends Utils { - val context: _context.type = _context - } - import utils._ - - val initName = newTermName("") - // Either: - // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } } - // or: - // scala"($_this: RangeDefault).foreach($f)" - _this match { - case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" => - val iname = newTermName("$i") - val hname = newTermName("$h") - def iref = Ident(iname) - def href = Ident(hname) - val labelname = newTermName("$while") - val cond = makeBinop(iref, "$less", href) - val body = Block( - List(makeApply(f, List(iref))), - Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1))))) - val generated = - Block( - List( - ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo), - ValDef(Modifiers(), hname, TypeTree(), hi)), - makeWhile(labelname, cond, body)) - // todo. read the compiler config and print if -Ydebug is set - //tools.nsc.util.trace("generated: ")(generated) - generated - case _ => - Apply( - Select( - Typed(_this, Ident(newTypeName("RangeDefault"))), - newTermName("foreach")), - List(f)) - } - } -} - -object Test extends App { - - new Range(1, 10) foreach println - -} diff --git a/test/files/run/macro-range/macro_range_2.scala b/test/files/run/macro-range/macro_range_2.scala deleted file mode 100644 index fdfe7169ad..0000000000 --- a/test/files/run/macro-range/macro_range_2.scala +++ /dev/null @@ -1,99 +0,0 @@ -import reflect.api.Modifier -import reflect.macro.Context - -abstract class RangeDefault { - val from, to: Int - def foreach(f: Int => Unit) = { - var i = from - while (i < to) { f(i); i += 1 } - } -} - -/** This class should go into reflect.macro once it is a bit more stable. */ -abstract class Utils { - val context: Context - import context._ - - class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer { - override def transform(tree: Tree): Tree = tree match { - case Ident(_) => - def subst(from: List[Symbol], to: List[Tree]): Tree = - if (from.isEmpty) tree - else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`? - else subst(from.tail, to.tail); - subst(from, to) - case _ => - val tree1 = super.transform(tree) - if (tree1 ne tree) tree1.tpe = null - tree1 - } - } - def makeApply(fn: Tree, args: List[Tree]): Tree = fn match { - case Function(vparams, body) => - new TreeSubstituter(vparams map (_.symbol), args) transform body - case Block(stats, expr) => - Block(stats, makeApply(expr, args)) - case _ => - // todo. read the compiler config and print if -Ydebug is set - //println("no beta on "+fn+" "+fn.getClass) - Apply(fn, args) - } - def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = { - val continu = Apply(Ident(lname), Nil) - val rhs = If(cond, Block(List(body), continu), Literal(Constant())) - LabelDef(lname, Nil, rhs) - } - def makeBinop(left: Tree, op: String, right: Tree): Tree = - Apply(Select(left, newTermName(op)), List(right)) -} - -class Range(val from: Int, val to: Int) extends RangeDefault { - override def macro foreach(f: Int => Unit): Unit = { - // todo. read the compiler config and print if -Ydebug is set - //println("macro-expand, _this = "+ _this) - import _context._ - object utils extends Utils { - val context: _context.type = _context - } - import utils._ - - val initName = newTermName("") - // Either: - // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } } - // or: - // scala"($_this: RangeDefault).foreach($f)" - _this match { - case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" => - val iname = newTermName("$i") - val hname = newTermName("$h") - def iref = Ident(iname) - def href = Ident(hname) - val labelname = newTermName("$while") - val cond = makeBinop(iref, "$less", href) - val body = Block( - List(makeApply(f, List(iref))), - Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1))))) - val generated = - Block( - List( - ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo), - ValDef(Modifiers(), hname, TypeTree(), hi)), - makeWhile(labelname, cond, body)) - // todo. read the compiler config and print if -Ydebug is set - //tools.nsc.util.trace("generated: ")(generated) - generated - case _ => - Apply( - Select( - Typed(_this, Ident(newTypeName("RangeDefault"))), - newTermName("foreach")), - List(f)) - } - } -} - -object Test extends App { - - new Range(1, 10) foreach println - -} diff --git a/test/files/run/macro-reflective-ma-normal-mdmi.check b/test/files/run/macro-reflective-ma-normal-mdmi.check new file mode 100644 index 0000000000..ac4213d6e9 --- /dev/null +++ b/test/files/run/macro-reflective-ma-normal-mdmi.check @@ -0,0 +1 @@ +43 \ No newline at end of file diff --git a/test/files/run/macro-reflective-ma-normal-mdmi.flags b/test/files/run/macro-reflective-ma-normal-mdmi.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reflective-ma-normal-mdmi.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala b/test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala new file mode 100644 index 0000000000..f6caf89dca --- /dev/null +++ b/test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala new file mode 100644 index 0000000000..3c594aed75 --- /dev/null +++ b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + println(tree.eval) +} diff --git a/test/files/run/macro-reflective-mamd-normal-mi.check b/test/files/run/macro-reflective-mamd-normal-mi.check new file mode 100644 index 0000000000..ac4213d6e9 --- /dev/null +++ b/test/files/run/macro-reflective-mamd-normal-mi.check @@ -0,0 +1 @@ +43 \ No newline at end of file diff --git a/test/files/run/macro-reflective-mamd-normal-mi.flags b/test/files/run/macro-reflective-mamd-normal-mi.flags new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala b/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala new file mode 100644 index 0000000000..dc7d42d23e --- /dev/null +++ b/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } +} diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala new file mode 100644 index 0000000000..7cbe425fc8 --- /dev/null +++ b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala @@ -0,0 +1,16 @@ +//object Macros { +// def foo(x: Int) = macro Impls.foo +//} + +object Test extends App { + import scala.reflect.mirror._ + + val macrobody = Select(Ident(newTermName("Impls")), newTermName("foo")) + val macroparam = ValDef(NoMods, newTermName("x"), TypeTree(definitions.IntClass.asType), EmptyTree) + val macrodef = DefDef(Modifiers(Set(scala.reflect.api.Modifier.`macro`)), newTermName("foo"), Nil, List(List(macroparam)), TypeTree(), macrobody) + val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(Apply(Select(Super(This(EmptyTypeName), EmptyTypeName), nme.CONSTRUCTOR), List()))) + val module = ModuleDef(NoMods, newTermName("Macros"), Template(Nil, emptyValDef, List(modulector, macrodef))) + val macroapp = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + val tree = Block(macrodef, module, macroapp) + println(tree.eval) +} diff --git a/test/files/run/macro-reify-basic.check b/test/files/run/macro-reify-basic.check new file mode 100644 index 0000000000..f35d3e67b4 --- /dev/null +++ b/test/files/run/macro-reify-basic.check @@ -0,0 +1 @@ +hello world diff --git a/test/files/run/macro-reify-basic.flags b/test/files/run/macro-reify-basic.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-basic.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-basic/Macros_1.scala b/test/files/run/macro-reify-basic/Macros_1.scala new file mode 100644 index 0000000000..b2243d131c --- /dev/null +++ b/test/files/run/macro-reify-basic/Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo(s: String) = macro Impls.foo + + object Impls { + def foo(c: Ctx)(s: c.Expr[String]) = c.reify { + println("hello " + s.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-basic/Test_2.scala b/test/files/run/macro-reify-basic/Test_2.scala new file mode 100644 index 0000000000..0a762f7ad7 --- /dev/null +++ b/test/files/run/macro-reify-basic/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo("world") +} \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-eval.check b/test/files/run/macro-reify-eval-eval.check new file mode 100644 index 0000000000..f35d3e67b4 --- /dev/null +++ b/test/files/run/macro-reify-eval-eval.check @@ -0,0 +1 @@ +hello world diff --git a/test/files/run/macro-reify-eval-eval.flags b/test/files/run/macro-reify-eval-eval.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-eval-eval.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-eval/Macros_1.scala b/test/files/run/macro-reify-eval-eval/Macros_1.scala new file mode 100644 index 0000000000..6b8ac94f0e --- /dev/null +++ b/test/files/run/macro-reify-eval-eval/Macros_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} +import scala.reflect.{mirror => mr} + +object Macros { + def foo = macro Impls.foo + + object Impls { + def foo(c: Ctx) = c.reify { + { c.reify(c.reify("hello world")) }.eval.eval + } + } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-eval/Test_2.scala b/test/files/run/macro-reify-eval-eval/Test_2.scala new file mode 100644 index 0000000000..f697da6020 --- /dev/null +++ b/test/files/run/macro-reify-eval-eval/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println(Macros.foo) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-outside-reify.check b/test/files/run/macro-reify-eval-outside-reify.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/macro-reify-eval-outside-reify.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/macro-reify-eval-outside-reify.flags b/test/files/run/macro-reify-eval-outside-reify.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-eval-outside-reify.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala b/test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala new file mode 100644 index 0000000000..13b603d610 --- /dev/null +++ b/test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = c.literal(x.eval) +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/run/macro-reify-eval-outside-reify/Test_2.scala b/test/files/run/macro-reify-eval-outside-reify/Test_2.scala new file mode 100644 index 0000000000..3c594aed75 --- /dev/null +++ b/test/files/run/macro-reify-eval-outside-reify/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + println(tree.eval) +} diff --git a/test/files/run/macro-reify-freevars.check b/test/files/run/macro-reify-freevars.check new file mode 100644 index 0000000000..02a6a7436b --- /dev/null +++ b/test/files/run/macro-reify-freevars.check @@ -0,0 +1,3 @@ +reflective compilation has failed: + +macro expansion contains free term variable code defined by map in Macros_1.scala:8:9. have you forgot to use eval when splicing this variable into a reifee? if you have troubles tracking free term variables, consider using -Xlog-free-terms diff --git a/test/files/run/macro-reify-freevars.flags b/test/files/run/macro-reify-freevars.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-freevars.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-freevars/Macros_1.scala b/test/files/run/macro-reify-freevars/Macros_1.scala new file mode 100644 index 0000000000..3cc559a0af --- /dev/null +++ b/test/files/run/macro-reify-freevars/Macros_1.scala @@ -0,0 +1,19 @@ +package scala.collection.slick +object QueryableMacros{ + def map[T:c.TypeTag, S:c.TypeTag] + (c: scala.reflect.makro.Context) + (projection: c.mirror.Expr[T => S]) + : c.mirror.Expr[scala.collection.slick.Queryable[S]] = { + import c.mirror._ + val code = EmptyTree + c.reify{ + Queryable.factory[S]( code.asInstanceOf[reflect.mirror.Tree] ) + } + } +} +class Queryable[T]{ + def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S] +} +object Queryable{ + def factory[S]( projection:scala.reflect.mirror.Tree ) : Queryable[S] = null +} \ No newline at end of file diff --git a/test/files/run/macro-reify-freevars/Test_2.scala b/test/files/run/macro-reify-freevars/Test_2.scala new file mode 100644 index 0000000000..55c677155a --- /dev/null +++ b/test/files/run/macro-reify-freevars/Test_2.scala @@ -0,0 +1,9 @@ +object Test extends App { + import scala.reflect.mirror._ + val q = New(AppliedTypeTree(Select(Select(Select(Ident("scala"), newTermName("collection")), newTermName("slick")), newTypeName("Queryable")), List(Ident("Int")))) + val x = ValDef(NoMods, newTermName("x"), Ident("Int"), EmptyTree) + val fn = Function(List(x), Apply(Select(Ident(newTermName("x")), newTermName("$plus")), List(Literal(Constant("5"))))) + val tree = Apply(Select(q, newTermName("map")), List(fn)) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-groundtypetag-notypeparams.check b/test/files/run/macro-reify-groundtypetag-notypeparams.check new file mode 100644 index 0000000000..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-groundtypetag-notypeparams.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala b/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala new file mode 100644 index 0000000000..3aa40251ec --- /dev/null +++ b/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala @@ -0,0 +1,6 @@ +import scala.reflect.mirror._ + +object Test extends App { + println(implicitly[GroundTypeTag[Int]]) + println(implicitly[GroundTypeTag[List[Int]]]) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-groundtypetag-typeparams-tags.check b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check new file mode 100644 index 0000000000..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala b/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala new file mode 100644 index 0000000000..21735c10d5 --- /dev/null +++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTag[T: GroundTypeTag] = { + println(implicitly[GroundTypeTag[T]]) + println(implicitly[GroundTypeTag[List[T]]]) + } + fooTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-a.check b/test/files/run/macro-reify-nested-a.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-reify-nested-a.flags b/test/files/run/macro-reify-nested-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-nested-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala new file mode 100644 index 0000000000..1ce8f44671 --- /dev/null +++ b/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala @@ -0,0 +1,43 @@ +import scala.reflect.makro.Context + +case class Utils[C <: Context]( c:C ) { + import c.mirror._ + import c.{Tree=>_} + object removeDoubleReify extends c.mirror.Transformer { + def apply( tree:Tree ) = transform(tree) + override def transform(tree: Tree): Tree = { + super.transform { + tree match { + case Apply(TypeApply(Select(_this, termname), _), reified::Nil ) + if termname.toString == "factory" => c.unreifyTree(reified) + case Apply(Select(_this, termname), reified::Nil ) + if termname.toString == "factory" => c.unreifyTree(reified) + case _ => tree + } + } + } + } +} +object QueryableMacros{ + def _helper[C <: Context,S:c.TypeTag]( c:C )( name:String, projection:c.mirror.Expr[_] ) = { + import c.mirror._ + val element_type = implicitly[c.TypeTag[S]].tpe + val foo = Expr[reflect.mirror.Expr[Queryable[S]]]( + c.reifyTree( c.reflectMirrorPrefix, c.typeCheck( + Utils[c.type](c).removeDoubleReify( + Apply(Select(c.prefix.tree, newTermName( name )), List( projection.tree )) + ).asInstanceOf[Tree] + ))) + c.reify{ Queryable.factory[S]( foo.eval )} + } + def map[T:c.TypeTag, S:c.TypeTag] + (c: scala.reflect.makro.Context) + (projection: c.mirror.Expr[T => S]): c.mirror.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection ) +} +class Queryable[T]{ + def _map[S]( projection: T => S ) : Queryable[S] = ??? + def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S] +} +object Queryable{ + def factory[S]( projection:scala.reflect.mirror.Expr[Queryable[S]] ) : Queryable[S] = null +} \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-a/Test_2.scala b/test/files/run/macro-reify-nested-a/Test_2.scala new file mode 100644 index 0000000000..fa0eb378af --- /dev/null +++ b/test/files/run/macro-reify-nested-a/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App{ + val q : Queryable[Any] = new Queryable[Any] + q.map(e1 => q.map(e2=>e1)) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-b.check b/test/files/run/macro-reify-nested-b.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-reify-nested-b.flags b/test/files/run/macro-reify-nested-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-nested-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..1ce8f44671 --- /dev/null +++ b/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala @@ -0,0 +1,43 @@ +import scala.reflect.makro.Context + +case class Utils[C <: Context]( c:C ) { + import c.mirror._ + import c.{Tree=>_} + object removeDoubleReify extends c.mirror.Transformer { + def apply( tree:Tree ) = transform(tree) + override def transform(tree: Tree): Tree = { + super.transform { + tree match { + case Apply(TypeApply(Select(_this, termname), _), reified::Nil ) + if termname.toString == "factory" => c.unreifyTree(reified) + case Apply(Select(_this, termname), reified::Nil ) + if termname.toString == "factory" => c.unreifyTree(reified) + case _ => tree + } + } + } + } +} +object QueryableMacros{ + def _helper[C <: Context,S:c.TypeTag]( c:C )( name:String, projection:c.mirror.Expr[_] ) = { + import c.mirror._ + val element_type = implicitly[c.TypeTag[S]].tpe + val foo = Expr[reflect.mirror.Expr[Queryable[S]]]( + c.reifyTree( c.reflectMirrorPrefix, c.typeCheck( + Utils[c.type](c).removeDoubleReify( + Apply(Select(c.prefix.tree, newTermName( name )), List( projection.tree )) + ).asInstanceOf[Tree] + ))) + c.reify{ Queryable.factory[S]( foo.eval )} + } + def map[T:c.TypeTag, S:c.TypeTag] + (c: scala.reflect.makro.Context) + (projection: c.mirror.Expr[T => S]): c.mirror.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection ) +} +class Queryable[T]{ + def _map[S]( projection: T => S ) : Queryable[S] = ??? + def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S] +} +object Queryable{ + def factory[S]( projection:scala.reflect.mirror.Expr[Queryable[S]] ) : Queryable[S] = null +} \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-b/Test_2.scala b/test/files/run/macro-reify-nested-b/Test_2.scala new file mode 100644 index 0000000000..fa13f57ffb --- /dev/null +++ b/test/files/run/macro-reify-nested-b/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App{ + val q : Queryable[Any] = new Queryable[Any] + q.map(e1 => q.map(e2=>e1).map(e2=>e1)) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-ref-to-packageless.check b/test/files/run/macro-reify-ref-to-packageless.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/macro-reify-ref-to-packageless.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/macro-reify-ref-to-packageless.flags b/test/files/run/macro-reify-ref-to-packageless.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-ref-to-packageless.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-ref-to-packageless/Impls_1.scala b/test/files/run/macro-reify-ref-to-packageless/Impls_1.scala new file mode 100644 index 0000000000..2f2d05678d --- /dev/null +++ b/test/files/run/macro-reify-ref-to-packageless/Impls_1.scala @@ -0,0 +1,6 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + val `Answer to the Ultimate Question of Life, the Universe, and Everything` = 42 + def foo(c: Ctx) = c.reify { `Answer to the Ultimate Question of Life, the Universe, and Everything` } +} diff --git a/test/files/run/macro-reify-ref-to-packageless/Test_2.scala b/test/files/run/macro-reify-ref-to-packageless/Test_2.scala new file mode 100644 index 0000000000..9d475f756d --- /dev/null +++ b/test/files/run/macro-reify-ref-to-packageless/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo = macro Impls.foo + println(foo) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-tagful-a.check b/test/files/run/macro-reify-tagful-a.check new file mode 100644 index 0000000000..8a701df6a5 --- /dev/null +++ b/test/files/run/macro-reify-tagful-a.check @@ -0,0 +1 @@ +List(hello world) diff --git a/test/files/run/macro-reify-tagful-a.flags b/test/files/run/macro-reify-tagful-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-tagful-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-tagful-a/Macros_1.scala b/test/files/run/macro-reify-tagful-a/Macros_1.scala new file mode 100644 index 0000000000..2ff12091a1 --- /dev/null +++ b/test/files/run/macro-reify-tagful-a/Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo[T](s: T) = macro Impls.foo[T] + + object Impls { + def foo[T: c.TypeTag](c: Ctx)(s: c.Expr[T]) = c.reify { + List(s.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-tagful-a/Test_2.scala b/test/files/run/macro-reify-tagful-a/Test_2.scala new file mode 100644 index 0000000000..4d27166341 --- /dev/null +++ b/test/files/run/macro-reify-tagful-a/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val list: List[String] = Macros.foo("hello world") + println(list) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-tagless-a.check b/test/files/run/macro-reify-tagless-a.check new file mode 100644 index 0000000000..b58cff19bc --- /dev/null +++ b/test/files/run/macro-reify-tagless-a.check @@ -0,0 +1,3 @@ +reflective compilation has failed: + +macro expansion contains free type variable T defined by foo in Impls_Macros_1.scala:7:13. have you forgot to use c.TypeTag annotation for this type parameter? if you have troubles tracking free type variables, consider using -Xlog-free-types diff --git a/test/files/run/macro-reify-tagless-a.flags b/test/files/run/macro-reify-tagless-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-tagless-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala b/test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala new file mode 100644 index 0000000000..45e39d7d1c --- /dev/null +++ b/test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo[T](s: T) = macro Impls.foo[T] + + object Impls { + def foo[T](c: Ctx)(s: c.Expr[T]) = c.reify { + List[T](s.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-tagless-a/Test_2.scala b/test/files/run/macro-reify-tagless-a/Test_2.scala new file mode 100644 index 0000000000..d996da1570 --- /dev/null +++ b/test/files/run/macro-reify-tagless-a/Test_2.scala @@ -0,0 +1,12 @@ +object Test extends App { + //val list: List[String] = Macros.foo("hello world") + //println(list) + + import scala.reflect.mirror._ + val tpt = AppliedTypeTree(Ident(definitions.ListClass), List(Ident(definitions.StringClass))) + val rhs = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant("hello world")))) + val list = ValDef(NoMods, newTermName("list"), tpt, rhs) + val tree = Block(list, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name)))) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} diff --git a/test/files/run/macro-reify-typetag-notypeparams.check b/test/files/run/macro-reify-typetag-notypeparams.check new file mode 100644 index 0000000000..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-typetag-notypeparams.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-notypeparams/Test.scala b/test/files/run/macro-reify-typetag-notypeparams/Test.scala new file mode 100644 index 0000000000..041a44273d --- /dev/null +++ b/test/files/run/macro-reify-typetag-notypeparams/Test.scala @@ -0,0 +1,6 @@ +import scala.reflect.mirror._ + +object Test extends App { + println(implicitly[TypeTag[Int]]) + println(implicitly[TypeTag[List[Int]]]) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-typetag-typeparams-notags.check b/test/files/run/macro-reify-typetag-typeparams-notags.check new file mode 100644 index 0000000000..3da30c71ba --- /dev/null +++ b/test/files/run/macro-reify-typetag-typeparams-notags.check @@ -0,0 +1,2 @@ +GroundTypeTag[T] +GroundTypeTag[List[T]] diff --git a/test/files/run/macro-reify-typetag-typeparams-notags/Test.scala b/test/files/run/macro-reify-typetag-typeparams-notags/Test.scala new file mode 100644 index 0000000000..a89499e7fe --- /dev/null +++ b/test/files/run/macro-reify-typetag-typeparams-notags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooNoTypeTag[T] = { + println(implicitly[TypeTag[T]]) + println(implicitly[TypeTag[List[T]]]) + } + fooNoTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-reify-typetag-typeparams-tags.check b/test/files/run/macro-reify-typetag-typeparams-tags.check new file mode 100644 index 0000000000..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-typetag-typeparams-tags.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-typeparams-tags/Test.scala b/test/files/run/macro-reify-typetag-typeparams-tags/Test.scala new file mode 100644 index 0000000000..b32680a4b8 --- /dev/null +++ b/test/files/run/macro-reify-typetag-typeparams-tags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTag[T: TypeTag] = { + println(implicitly[TypeTag[T]]) + println(implicitly[TypeTag[List[T]]]) + } + fooTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag.check b/test/files/run/macro-reify-typetag-usegroundtypetag.check new file mode 100644 index 0000000000..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-typetag-usegroundtypetag.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala b/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala new file mode 100644 index 0000000000..c9b210f35a --- /dev/null +++ b/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTag[T: GroundTypeTag] = { + println(implicitly[TypeTag[T]]) + println(implicitly[TypeTag[List[T]]]) + } + fooTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-reify-unreify.check b/test/files/run/macro-reify-unreify.check new file mode 100644 index 0000000000..a5334cc355 --- /dev/null +++ b/test/files/run/macro-reify-unreify.check @@ -0,0 +1 @@ +hello world = Expr[String("hello world")]("hello world") diff --git a/test/files/run/macro-reify-unreify.flags b/test/files/run/macro-reify-unreify.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-unreify.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-unreify/Macros_1.scala b/test/files/run/macro-reify-unreify/Macros_1.scala new file mode 100644 index 0000000000..1b0b9c6421 --- /dev/null +++ b/test/files/run/macro-reify-unreify/Macros_1.scala @@ -0,0 +1,19 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo(s: String) = macro Impls.foo + + object Impls { + def foo(c: Ctx)(s: c.Expr[String]) = { + import c.mirror._ + + val world = c.reifyTree(c.reflectMirrorPrefix, s.tree) + val greeting = c.reifyTree(c.reflectMirrorPrefix, c.typeCheck(Apply(Select(Literal(Constant("hello ")), newTermName("$plus")), List(c.unreifyTree(world))))) + val typedGreeting = Expr[String](greeting) + + c.reify { + println("hello " + s.eval + " = " + typedGreeting.eval) + } + } + } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-unreify/Test_2.scala b/test/files/run/macro-reify-unreify/Test_2.scala new file mode 100644 index 0000000000..0a762f7ad7 --- /dev/null +++ b/test/files/run/macro-reify-unreify/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo("world") +} \ No newline at end of file diff --git a/test/files/run/macro-reify-value-outside-reify.check b/test/files/run/macro-reify-value-outside-reify.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/macro-reify-value-outside-reify.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/macro-reify-value-outside-reify.flags b/test/files/run/macro-reify-value-outside-reify.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-value-outside-reify.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala b/test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala new file mode 100644 index 0000000000..28ec1ace67 --- /dev/null +++ b/test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = c.literal(x.value) +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/run/macro-reify-value-outside-reify/Test_2.scala b/test/files/run/macro-reify-value-outside-reify/Test_2.scala new file mode 100644 index 0000000000..8225eb0b39 --- /dev/null +++ b/test/files/run/macro-reify-value-outside-reify/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + try println(tree.eval) + catch { case ex: Throwable => println(ex.getMessage) } +} diff --git a/test/files/run/macro-repl-basic.check b/test/files/run/macro-repl-basic.check index f8f0d3ad29..3bc899f49b 100644 --- a/test/files/run/macro-repl-basic.check +++ b/test/files/run/macro-repl-basic.check @@ -3,13 +3,39 @@ Type :help for more information. scala> +scala> import scala.reflect.makro.{Context => Ctx} +import scala.reflect.makro.{Context=>Ctx} + +scala> + +scala> object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } + + def bar(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + Expr[Int](body) + } + + def quux(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} +defined module Impls + scala> object Macros { object Shmacros { - def macro foo(x: Int): Int = x + def foo(x: Int): Int = macro Impls.foo } - def macro bar(x: Int): Int = x + def bar(x: Int): Int = macro Impls.bar }; class Macros { - def macro quux(x: Int): Int = x + def quux(x: Int): Int = macro Impls.quux } defined module Macros defined class Macros @@ -20,6 +46,6 @@ scala> import Macros.Shmacros._ import Macros.Shmacros._ scala> println(foo(2) + Macros.bar(2) * new Macros().quux(4)) -10 +31 scala> diff --git a/test/files/run/macro-repl-basic.scala b/test/files/run/macro-repl-basic.scala index 9b1a53343b..a21eb7815f 100644 --- a/test/files/run/macro-repl-basic.scala +++ b/test/files/run/macro-repl-basic.scala @@ -3,13 +3,34 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { override def extraSettings = "-Xmacros" def code = """ + |import scala.reflect.makro.{Context => Ctx} + | + |object Impls { + | def foo(c: Ctx)(x: c.Expr[Int]) = { + | import c.mirror._ + | val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + | Expr[Int](body) + | } + | + | def bar(c: Ctx)(x: c.Expr[Int]) = { + | import c.mirror._ + | val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + | Expr[Int](body) + | } + | + | def quux(c: Ctx)(x: c.Expr[Int]) = { + | import c.mirror._ + | val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + | Expr[Int](body) + | } + |} |object Macros { | object Shmacros { - | def macro foo(x: Int): Int = x + | def foo(x: Int): Int = macro Impls.foo | } - | def macro bar(x: Int): Int = x + | def bar(x: Int): Int = macro Impls.bar |}; class Macros { - | def macro quux(x: Int): Int = x + | def quux(x: Int): Int = macro Impls.quux |} | |import Macros.Shmacros._ diff --git a/test/files/run/macro-repl-dontexpand.check b/test/files/run/macro-repl-dontexpand.check index d2bb89b6f7..35845f0cff 100644 --- a/test/files/run/macro-repl-dontexpand.check +++ b/test/files/run/macro-repl-dontexpand.check @@ -3,7 +3,10 @@ Type :help for more information. scala> -scala> def macro foo = ??? +scala> def bar(c: scala.reflect.makro.Context) = ??? +bar: (c: scala.reflect.makro.Context)Nothing + +scala> def foo = macro bar foo: Any scala> diff --git a/test/files/run/macro-repl-dontexpand.scala b/test/files/run/macro-repl-dontexpand.scala index 254bce894c..9889a8ffdf 100644 --- a/test/files/run/macro-repl-dontexpand.scala +++ b/test/files/run/macro-repl-dontexpand.scala @@ -3,6 +3,7 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { override def extraSettings = "-Xmacros" def code = """ - |def macro foo = ??? + |def bar(c: scala.reflect.makro.Context) = ??? + |def foo = macro bar |""".stripMargin } \ No newline at end of file diff --git a/test/files/run/macro-rettype-mismatch/Macros_1.scala b/test/files/run/macro-rettype-mismatch/Macros_1.scala deleted file mode 100644 index 64e5b93468..0000000000 --- a/test/files/run/macro-rettype-mismatch/Macros_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Macros { - def macro foo(x: Int): String = x -} \ No newline at end of file diff --git a/test/files/run/macro-rettype-mismatch/Test_2.scala b/test/files/run/macro-rettype-mismatch/Test_2.scala deleted file mode 100644 index 39a7c7ad1a..0000000000 --- a/test/files/run/macro-rettype-mismatch/Test_2.scala +++ /dev/null @@ -1,16 +0,0 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - import scala.reflect.mirror._ - val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(2)))) - - val stderr = new java.io.ByteArrayOutputStream() - Console.setErr(new java.io.PrintStream(stderr)) - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - try { toolbox.runExpr(tree) } - catch { case ex: Throwable => println(stderr); println(ex) } -} diff --git a/test/files/run/macro-settings.check b/test/files/run/macro-settings.check new file mode 100644 index 0000000000..33784d1c15 --- /dev/null +++ b/test/files/run/macro-settings.check @@ -0,0 +1 @@ +List(hello=1) diff --git a/test/files/run/macro-settings.flags b/test/files/run/macro-settings.flags new file mode 100644 index 0000000000..cdc7512197 --- /dev/null +++ b/test/files/run/macro-settings.flags @@ -0,0 +1 @@ +-Xmacros -Xmacro-settings:hello=1 \ No newline at end of file diff --git a/test/files/run/macro-settings/Impls_Macros_1.scala b/test/files/run/macro-settings/Impls_Macros_1.scala new file mode 100644 index 0000000000..8c7254c79a --- /dev/null +++ b/test/files/run/macro-settings/Impls_Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.Context + +object Impls { + def impl(c: Context) = c.reify { + println(c.literal(c.settings.toString).eval) + } +} + +object Macros { + def foo = macro Impls.impl +} \ No newline at end of file diff --git a/test/files/run/macro-settings/Test_2.scala b/test/files/run/macro-settings/Test_2.scala new file mode 100644 index 0000000000..acfddae942 --- /dev/null +++ b/test/files/run/macro-settings/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-sip19-revised.check b/test/files/run/macro-sip19-revised.check new file mode 100644 index 0000000000..aa2fbd11d3 --- /dev/null +++ b/test/files/run/macro-sip19-revised.check @@ -0,0 +1,5 @@ +hey, i've been called from SourceLocation1(null,Test_2.scala,11,251) +hey, i've been called from SourceLocation1(SourceLocation1(null,Test_2.scala,11,251),Test_2.scala,8,222) +hey, i've been called from SourceLocation1(SourceLocation1(SourceLocation1(null,Test_2.scala,11,251),Test_2.scala,8,222),Test_2.scala,8,222) +hey, i've been called from SourceLocation1(SourceLocation1(SourceLocation1(SourceLocation1(null,Test_2.scala,11,251),Test_2.scala,8,222),Test_2.scala,8,222),Test_2.scala,6,180) +2 diff --git a/test/files/run/macro-sip19-revised.flags b/test/files/run/macro-sip19-revised.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-sip19-revised.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-sip19-revised/Impls_Macros_1.scala b/test/files/run/macro-sip19-revised/Impls_Macros_1.scala new file mode 100644 index 0000000000..e8f6e1df85 --- /dev/null +++ b/test/files/run/macro-sip19-revised/Impls_Macros_1.scala @@ -0,0 +1,34 @@ +import scala.reflect.makro.Context + +object Macros { + def impl(c: Context) = { + import c.mirror._ + + val inscope = c.inferImplicitValue(staticClass("SourceLocation").asType) + val outer = Expr[SourceLocation](if (!inscope.isEmpty) inscope else Literal(Constant(null))) + + val Apply(fun, args) = c.enclosingImplicits(0)._2 + val fileName = fun.pos.fileInfo.getName + val line = fun.pos.line + val charOffset = fun.pos.point + c.reify { SourceLocation1(outer.eval, c.literal(fileName).eval, c.literal(line).eval, c.literal(charOffset).eval) } + } + + implicit def sourceLocation: SourceLocation1 = macro impl +} + +trait SourceLocation { + /** Source location of the outermost call */ + val outer: SourceLocation + + /** The name of the source file */ + val fileName: String + + /** The line number */ + val line: Int + + /** The character offset */ + val charOffset: Int +} + +case class SourceLocation1(val outer: SourceLocation, val fileName: String, val line: Int, val charOffset: Int) extends SourceLocation diff --git a/test/files/run/macro-sip19-revised/Test_2.scala b/test/files/run/macro-sip19-revised/Test_2.scala new file mode 100644 index 0000000000..d9a4d7d4fc --- /dev/null +++ b/test/files/run/macro-sip19-revised/Test_2.scala @@ -0,0 +1,12 @@ +import Macros._ + +object Test extends App { + def foo(x: Int, y: Int)(implicit loc: SourceLocation): Int = { + println("hey, i've been called from %s".format(loc)) + if (x < y) foo(y, x) + else if (y == 0) x + else foo(x - y, y) + } + + println(foo(4, 2)) +} diff --git a/test/files/run/macro-sip19.check b/test/files/run/macro-sip19.check new file mode 100644 index 0000000000..6b317ccb47 --- /dev/null +++ b/test/files/run/macro-sip19.check @@ -0,0 +1,5 @@ +hey, i've been called from SourceLocation(Test_2.scala,15,366) +hey, i've been called from SourceLocation(Test_2.scala,11,331) +hey, i've been called from SourceLocation(Test_2.scala,11,331) +hey, i've been called from SourceLocation(Test_2.scala,9,285) +2 diff --git a/test/files/run/macro-sip19.flags b/test/files/run/macro-sip19.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-sip19.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-sip19/Impls_Macros_1.scala b/test/files/run/macro-sip19/Impls_Macros_1.scala new file mode 100644 index 0000000000..39b29ad64c --- /dev/null +++ b/test/files/run/macro-sip19/Impls_Macros_1.scala @@ -0,0 +1,25 @@ +import scala.reflect.makro.Context + +object Macros { + def impl(c: Context) = { + import c.mirror._ + val Apply(fun, args) = c.enclosingImplicits(0)._2 + val fileName = fun.pos.fileInfo.getName + val line = fun.pos.line + val charOffset = fun.pos.point + c.reify { SourceLocation(c.literal(fileName).eval, c.literal(line).eval, c.literal(charOffset).eval) } + } + + implicit def sourceLocation: SourceLocation = macro impl +} + +case class SourceLocation( + /** The name of the source file */ + val fileName: String, + + /** The line number */ + val line: Int, + + /** The character offset */ + val charOffset: Int +) diff --git a/test/files/run/macro-sip19/Test_2.scala b/test/files/run/macro-sip19/Test_2.scala new file mode 100644 index 0000000000..32326e6352 --- /dev/null +++ b/test/files/run/macro-sip19/Test_2.scala @@ -0,0 +1,16 @@ +import Macros._ + +object Test extends App { + def foo(x: Int, y: Int)(implicit loc0: SourceLocation): Int = { + var loc = loc0; + { + var loc0 = 0 // shadow loc0 to disambiguate with the implicit macro + println("hey, i've been called from %s".format(loc)) + if (x < y) foo(y, x) + else if (y == 0) x + else foo(x - y, y) + } + } + + println(foo(4, 2)) +} diff --git a/test/files/run/macro-typecheck-implicitsdisabled.check b/test/files/run/macro-typecheck-implicitsdisabled.check new file mode 100644 index 0000000000..aa6c8e1f07 --- /dev/null +++ b/test/files/run/macro-typecheck-implicitsdisabled.check @@ -0,0 +1,2 @@ +scala.this.Predef.any2ArrowAssoc[Int](1).->[Int](2) +scala.reflect.internal.Types$TypeError: value -> is not a member of Int diff --git a/test/files/run/macro-typecheck-implicitsdisabled.flags b/test/files/run/macro-typecheck-implicitsdisabled.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-typecheck-implicitsdisabled.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala b/test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala new file mode 100644 index 0000000000..4f0f76aed6 --- /dev/null +++ b/test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala @@ -0,0 +1,28 @@ +import scala.reflect.makro.Context + +object Macros { + def impl_with_implicits_enabled(c: Context) = { + import c.mirror._ + + val tree1 = Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2)))) + val ttree1 = c.typeCheck(tree1, withImplicitViewsDisabled = false) + c.literal(ttree1.toString) + } + + def foo_with_implicits_enabled = macro impl_with_implicits_enabled + + def impl_with_implicits_disabled(c: Context) = { + import c.mirror._ + + try { + val tree2 = Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2)))) + val ttree2 = c.typeCheck(tree2, withImplicitViewsDisabled = true) + c.literal(ttree2.toString) + } catch { + case ex: Throwable => + c.literal(ex.toString) + } + } + + def foo_with_implicits_disabled = macro impl_with_implicits_disabled +} \ No newline at end of file diff --git a/test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala b/test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala new file mode 100644 index 0000000000..127e955f0e --- /dev/null +++ b/test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + println(Macros.foo_with_implicits_enabled) + println(Macros.foo_with_implicits_disabled) +} \ No newline at end of file diff --git a/test/files/run/macro-typecheck-macrosdisabled.check b/test/files/run/macro-typecheck-macrosdisabled.check new file mode 100644 index 0000000000..9760c117a7 --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled.check @@ -0,0 +1,5 @@ +{ + val $mr: reflect.mirror.type = scala.reflect.`package`.mirror; + $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.GroundTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) +} +mr.reify[Int](2) diff --git a/test/files/run/macro-typecheck-macrosdisabled.flags b/test/files/run/macro-typecheck-macrosdisabled.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala new file mode 100644 index 0000000000..c253f0b1fb --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala @@ -0,0 +1,36 @@ +import scala.reflect.makro.Context + +object Macros { + def impl_with_macros_enabled(c: Context) = { + import c.mirror._ + + // todo. doesn't work. why? + //val mrPkg = staticModule("scala.reflect.package") + //val mrSym = selectTerm(mrPkg, "mirror") + //val NullaryMethodType(mrTpe) = mrSym.typeSignature + //val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror, null) + //val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) + + val mr = Select(Select(Select(Ident(newTermName("scala")), newTermName("reflect")), newTermName("package")), newTermName("mirror")) + val tree1 = Apply(Select(mr, newTermName("reify")), List(Literal(Constant(2)))) + val ttree1 = c.typeCheck(tree1, withMacrosDisabled = false) + c.literal(ttree1.toString) + } + + def foo_with_macros_enabled = macro impl_with_macros_enabled + + def impl_with_macros_disabled(c: Context) = { + import c.mirror._ + + val mrPkg = staticModule("scala.reflect.package") + val mrSym = selectTerm(mrPkg, "mirror") + val NullaryMethodType(mrTpe) = mrSym.typeSignature + val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror, null) + + val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) + val ttree2 = c.typeCheck(tree2, withMacrosDisabled = true) + c.literal(ttree2.toString) + } + + def foo_with_macros_disabled = macro impl_with_macros_disabled +} \ No newline at end of file diff --git a/test/files/run/macro-typecheck-macrosdisabled/Test_2.scala b/test/files/run/macro-typecheck-macrosdisabled/Test_2.scala new file mode 100644 index 0000000000..bdba39195b --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + println(Macros.foo_with_macros_enabled) + println(Macros.foo_with_macros_disabled) +} \ No newline at end of file diff --git a/test/files/run/macro-undetparams-consfromsls.check b/test/files/run/macro-undetparams-consfromsls.check new file mode 100644 index 0000000000..6bf9bcca5a --- /dev/null +++ b/test/files/run/macro-undetparams-consfromsls.check @@ -0,0 +1,5 @@ +A = GroundTypeTag[Int] +B = GroundTypeTag[Nothing] +List(1) +A = GroundTypeTag[Any] +List(abc, 1) diff --git a/test/files/run/macro-undetparams-consfromsls.flags b/test/files/run/macro-undetparams-consfromsls.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-undetparams-consfromsls.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala b/test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala new file mode 100644 index 0000000000..c22ff96028 --- /dev/null +++ b/test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala @@ -0,0 +1,17 @@ +import scala.reflect.makro.Context + +object Macros { + def cons_impl[A: c.TypeTag](c: Context)(x: c.Expr[A], xs: c.Expr[List[A]]): c.Expr[List[A]] = c.reify { + println("A = " + c.literal(implicitly[c.TypeTag[A]].toString).eval) + x.eval :: xs.eval + } + + def nil_impl[B: c.TypeTag](c: Context): c.Expr[List[B]] = c.reify { + println("B = " + c.literal(implicitly[c.TypeTag[B]].toString).eval) + Nil + } + + def cons[A](x: A, xs: List[A]): List[A] = macro cons_impl[A] + + def nil[B]: List[B] = macro nil_impl[B] +} \ No newline at end of file diff --git a/test/files/run/macro-undetparams-consfromsls/Test_2.scala b/test/files/run/macro-undetparams-consfromsls/Test_2.scala new file mode 100644 index 0000000000..f2c2ce0051 --- /dev/null +++ b/test/files/run/macro-undetparams-consfromsls/Test_2.scala @@ -0,0 +1,7 @@ +object Test extends App { + import Macros._ + val xs = cons(1, nil) + println(xs) + val ys = cons("abc", xs) + println(ys) +} \ No newline at end of file diff --git a/test/files/run/macro-undetparams-implicitval.check b/test/files/run/macro-undetparams-implicitval.check new file mode 100644 index 0000000000..352a2e6480 --- /dev/null +++ b/test/files/run/macro-undetparams-implicitval.check @@ -0,0 +1 @@ +GroundTypeTag[Nothing] diff --git a/test/files/run/macro-undetparams-implicitval.flags b/test/files/run/macro-undetparams-implicitval.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-undetparams-implicitval.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-undetparams-implicitval/Test.scala b/test/files/run/macro-undetparams-implicitval/Test.scala new file mode 100644 index 0000000000..5278295451 --- /dev/null +++ b/test/files/run/macro-undetparams-implicitval/Test.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[T: TypeTag] = println(implicitly[TypeTag[T]]) + foo +} \ No newline at end of file diff --git a/test/files/run/macro-undetparams-macroitself.check b/test/files/run/macro-undetparams-macroitself.check new file mode 100644 index 0000000000..60c021a35b --- /dev/null +++ b/test/files/run/macro-undetparams-macroitself.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[String] diff --git a/test/files/run/macro-undetparams-macroitself.flags b/test/files/run/macro-undetparams-macroitself.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-undetparams-macroitself.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala b/test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala new file mode 100644 index 0000000000..9d65e8b0da --- /dev/null +++ b/test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala @@ -0,0 +1,7 @@ +import scala.reflect.makro.Context + +object Macros { + def impl[T: c.TypeTag](c: Context)(foo: c.Expr[T]): c.Expr[Unit] = c.reify { println(c.literal(implicitly[c.TypeTag[T]].toString).eval) } + + def foo[T](foo: T) = macro impl[T] +} \ No newline at end of file diff --git a/test/files/run/macro-undetparams-macroitself/Test_2.scala b/test/files/run/macro-undetparams-macroitself/Test_2.scala new file mode 100644 index 0000000000..1a93ff1304 --- /dev/null +++ b/test/files/run/macro-undetparams-macroitself/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + Macros.foo(42) + Macros.foo("42") +} \ No newline at end of file diff --git a/test/files/run/manifests.scala b/test/files/run/manifests.scala index 6b6ea80b34..2d64bf18a9 100644 --- a/test/files/run/manifests.scala +++ b/test/files/run/manifests.scala @@ -4,29 +4,29 @@ object Test val CO, IN, CONTRA = Value } import Variances.{ CO, IN, CONTRA } - + object SubtypeRelationship extends Enumeration { val NONE, SAME, SUB, SUPER = Value } import SubtypeRelationship.{ NONE, SAME, SUB, SUPER } - + class VarianceTester[T, U, CC[_]](expected: Variances.Value)( implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) { - - def elements = List(ev1 <:< ev2, ev2 <:< ev1) - def containers = List(ev3 <:< ev4, ev4 <:< ev3) + + def elements = List(ev1.tpe <:< ev2.tpe, ev2.tpe <:< ev1.tpe) + def containers = List(ev3.tpe <:< ev4.tpe, ev4.tpe <:< ev3.tpe) def isUnrelated = typeCompare[T, U] == NONE def isSame = typeCompare[T, U] == SAME def isSub = typeCompare[T, U] == SUB def isSuper = typeCompare[T, U] == SUPER - + def showsCovariance = (elements == containers) def showsContravariance = (elements == containers.reverse) def showsInvariance = containers forall (_ == isSame) def allContainerVariances = List(showsCovariance, showsInvariance, showsContravariance) - + def showsExpectedVariance = if (isUnrelated) allContainerVariances forall (_ == false) else if (isSame) allContainerVariances forall (_ == true) @@ -36,64 +36,57 @@ object Test case CONTRA => showsContravariance && !showsCovariance && !showsInvariance } } - + def showsCovariance[T, U, CC[_]](implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) = new VarianceTester[T, U, CC](CO) showsExpectedVariance def showsInvariance[T, U, CC[_]](implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) = new VarianceTester[T, U, CC](IN) showsExpectedVariance - + def showsContravariance[T, U, CC[_]](implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) = new VarianceTester[T, U, CC](CONTRA) showsExpectedVariance - - def typeCompare[T, U](implicit ev1: Manifest[T], ev2: Manifest[U]) = { - // checking types as well - if ((ev1 <:< ev2) != (ev1.tpe <:< ev2.tpe)) - println("Failed! " + ((ev1, ev2))) - - if ((ev2 <:< ev1) != (ev2.tpe <:< ev1.tpe)) - println("Failed! " + ((ev2, ev1))) - (ev1 <:< ev2, ev2 <:< ev1) match { + def typeCompare[T, U](implicit ev1: Manifest[T], ev2: Manifest[U]) = { + (ev1.tpe <:< ev2.tpe, ev2.tpe <:< ev1.tpe) match { case (true, true) => SAME case (true, false) => SUB case (false, true) => SUPER case (false, false) => NONE } } - + def assertAnyRef[T: Manifest] = List( - manifest[T] <:< manifest[Any], - manifest[T] <:< manifest[AnyRef], - !(manifest[T] <:< manifest[AnyVal]) + manifest[T].tpe <:< manifest[Any].tpe, + manifest[T].tpe <:< manifest[AnyRef].tpe, + !(manifest[T].tpe <:< manifest[AnyVal].tpe) ) foreach (assert(_, "assertAnyRef")) - + def assertAnyVal[T: Manifest] = List( - manifest[T] <:< manifest[Any], - !(manifest[T] <:< manifest[AnyRef]), - manifest[T] <:< manifest[AnyVal] + manifest[T].tpe <:< manifest[Any].tpe, + !(manifest[T].tpe <:< manifest[AnyRef].tpe), + manifest[T].tpe <:< manifest[AnyVal].tpe ) foreach (assert(_, "assertAnyVal")) - + def assertSameType[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == SAME, "assertSameType") def assertSuperType[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == SUPER, "assertSuperType") def assertSubType[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == SUB, "assertSubType") def assertNoRelationship[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == NONE, "assertNoRelationship") - + def testVariancesVia[T: Manifest, U: Manifest] = assert( - typeCompare[T, U] == SUB && + typeCompare[T, U] == SUB && showsCovariance[T, U, List] && showsInvariance[T, U, Set], "testVariancesVia" ) - + def runAllTests = { assertAnyVal[AnyVal] assertAnyVal[Unit] - assertAnyVal[Int] - assertAnyVal[Double] + assertAnyVal[Int] + assertAnyVal[Double] assertAnyVal[Boolean] assertAnyVal[Char] - + assertAnyRef[AnyRef] assertAnyRef[java.lang.Object] assertAnyRef[java.lang.Integer] @@ -103,7 +96,7 @@ object Test assertAnyRef[String] assertAnyRef[scala.List[String]] assertAnyRef[scala.List[_]] - + // variance doesn't work yet // testVariancesVia[String, Any] // testVariancesVia[String, AnyRef] @@ -111,11 +104,11 @@ object Test assertSubType[List[String], List[Any]] assertSubType[List[String], List[AnyRef]] assertNoRelationship[List[String], List[AnyVal]] - + assertSubType[List[Int], List[Any]] assertSubType[List[Int], List[AnyVal]] assertNoRelationship[List[Int], List[AnyRef]] - + // Nothing assertSubType[Nothing, Any] assertSubType[Nothing, AnyVal] @@ -124,7 +117,7 @@ object Test assertSubType[Nothing, List[String]] assertSubType[Nothing, Null] assertSameType[Nothing, Nothing] - + // Null assertSubType[Null, Any] assertNoRelationship[Null, AnyVal] @@ -133,7 +126,7 @@ object Test assertSubType[Null, List[String]] assertSameType[Null, Null] assertSuperType[Null, Nothing] - + // Any assertSameType[Any, Any] assertSuperType[Any, AnyVal] @@ -142,7 +135,7 @@ object Test assertSuperType[Any, List[String]] assertSuperType[Any, Null] assertSuperType[Any, Nothing] - + // Misc unrelated types assertNoRelationship[Unit, AnyRef] assertNoRelationship[Unit, Int] diff --git a/test/files/run/primitive-sigs-2.check b/test/files/run/primitive-sigs-2.check index feb0619525..761aa1ca72 100644 --- a/test/files/run/primitive-sigs-2.check +++ b/test/files/run/primitive-sigs-2.check @@ -1,7 +1,7 @@ -T -List(A, char, class java.lang.Object) -a -public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.Manifest) -public float[] Arr.arr3(float[][]) -public scala.collection.immutable.List Arr.arr2(java.lang.Character[]) -public scala.collection.immutable.List Arr.arr1(int[]) +T +List(A, char, class java.lang.Object) +a +public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.api.TypeTags.scala.reflect.api.TypeTags$GroundTypeTag) +public float[] Arr.arr3(float[][]) +public scala.collection.immutable.List Arr.arr2(java.lang.Character[]) +public scala.collection.immutable.List Arr.arr1(int[]) diff --git a/test/files/run/reify_ann1a.check b/test/files/run/reify_ann1a.check index 66dce778a8..a3944ae1ee 100644 --- a/test/files/run/reify_ann1a.check +++ b/test/files/run/reify_ann1a.check @@ -1,30 +1,30 @@ -{ - @new ann(immutable.this.List.apply[String]("1a")) @new ann(immutable.this.List.apply[String]("1b")) class C[@new ann(immutable.this.List.apply[String]("2a")) @new ann(immutable.this.List.apply[String]("2b")) T] extends scala.AnyRef { - @new ann(immutable.this.List.apply[String]("3a")) @new ann(immutable.this.List.apply[String]("3b")) private[this] val x: T @ann(immutable.this.List.apply[String]("4a")) @ann(immutable.this.List.apply[String]("4b")) = _; - def (@new ann(immutable.this.List.apply[String]("3a")) @new ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4a")) @ann(immutable.this.List.apply[String]("4b"))) = { - super.(); - () - }; - @new ann(immutable.this.List.apply[String]("5a")) @new ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = { - @new ann(immutable.this.List.apply[String]("7a")) @new ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.$plus(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a"))); - val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a"))); - r.$plus(s) - } - }; - () -} -{ - @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T] extends scala.AnyRef { - @ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _; - def (@ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a"))): C[T] = { - C.super.(); - () - }; - @ann(immutable.this.List.apply[String]("5a")) @ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = { - @ann(immutable.this.List.apply[String]("7a")) @ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.+(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a"))); - val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a"))); - r.+(s) - } - }; - () -} +{ + @new ann(immutable.this.List.apply("1a")) @new ann(immutable.this.List.apply("1b")) class C[@new ann(immutable.this.List.apply("2a")) @new ann(immutable.this.List.apply("2b")) T >: Nothing <: Any] extends Object { + @new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) private[this] val x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b")) = _; + def (@new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b"))) = { + super.(); + () + }; + @new ann(immutable.this.List.apply("5a")) @new ann(immutable.this.List.apply("5b")) def f(x: Int @ann(immutable.this.List.apply("6a")) @ann(immutable.this.List.apply("6b"))) = { + @new ann(immutable.this.List.apply("7a")) @new ann(immutable.this.List.apply("7b")) val r = x.$plus(3): @ann(immutable.this.List.apply("8a")): @ann(immutable.this.List.apply("8b")); + val s = (4: Int @ann(immutable.this.List.apply("9a")) @ann(immutable.this.List.apply("9b"))); + r.$plus(s) + } + }; + () +} +{ + @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T] extends Object { + @ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _; + def (@ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a"))): C[T] = { + C.super.(); + () + }; + @ann(immutable.this.List.apply[String]("5a")) @ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = { + @ann(immutable.this.List.apply[String]("7a")) @ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.+(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a"))); + val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a"))); + r.+(s) + } + }; + () +} diff --git a/test/files/run/reify_ann1a.scala b/test/files/run/reify_ann1a.scala index 1ca170904b..1f5d1daccd 100644 --- a/test/files/run/reify_ann1a.scala +++ b/test/files/run/reify_ann1a.scala @@ -1,14 +1,10 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ class ann(bar: List[String]) extends StaticAnnotation object Test extends App { // test 1: reify - val tree = scala.reflect.Code.lift{ + val tree = reify{ @ann(bar=List("1a")) @ann(bar=List("1b")) class C[@ann(bar=List("2a")) @ann(bar=List("2b")) T](@ann(bar=List("3a")) @ann(bar=List("3b")) x: T @ann(bar=List("4a")) @ann(bar=List("4b"))) { @ann(bar=List("5a")) @ann(bar=List("5b")) def f(x: Int @ann(bar=List("6a")) @ann(bar=List("6b"))) = { @ann(bar=List("7a")) @ann(bar=List("7b")) val r = (x + 3): @ann(bar=List("8a")) @ann(bar=List("8b")) @@ -20,8 +16,7 @@ object Test extends App { println(tree.toString) // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val ttree = toolbox.typeCheck(tree) println(ttree.toString) diff --git a/test/files/run/reify_ann1b.check b/test/files/run/reify_ann1b.check index 9bc65a422e..bae838f15f 100644 --- a/test/files/run/reify_ann1b.check +++ b/test/files/run/reify_ann1b.check @@ -1,30 +1,30 @@ -{ - @new ann(bar = "1a") @new ann(bar = "1b") class C[@new ann(bar = "2a") @new ann(bar = "2b") T] extends scala.AnyRef { - @new ann(bar = "3a") @new ann(bar = "3b") private[this] val x: T @ann(bar = "4a") @ann(bar = "4b") = _; - def (@new ann(bar = "3a") @new ann(bar = "3b") x: T @ann(bar = "4a") @ann(bar = "4b")) = { - super.(); - () - }; - @new ann(bar = "5a") @new ann(bar = "5b") def f(x: Int @ann(bar = "6b") @ann(bar = "6a")): Int = { - @new ann(bar = "7a") @new ann(bar = "7b") val r: Int @ann(bar = "8b") @ann(bar = "8a") = ((x.$plus(3): Int @ann(bar = "8a")): Int @ann(bar = "8b") @ann(bar = "8a")); - val s: Int @ann(bar = "9b") @ann(bar = "9a") = (4: Int @ann(bar = "9b") @ann(bar = "9a")); - r.$plus(s) - } - }; - () -} -{ - @ann(bar = "1a") @ann(bar = "1b") class C[@ann(bar = "2a") @ann(bar = "2b") T] extends scala.AnyRef { - @ann(bar = "3a") @ann(bar = "3b") private[this] val x: T @ann(bar = "4b") @ann(bar = "4a") = _; - def (@ann(bar = "3a") @ann(bar = "3b") x: T @ann(bar = "4b") @ann(bar = "4a")): C[T] = { - C.super.(); - () - }; - @ann(bar = "5a") @ann(bar = "5b") def f(x: Int @ann(bar = "6b") @ann(bar = "6a")): Int = { - @ann(bar = "7a") @ann(bar = "7b") val r: Int @ann(bar = "8b") @ann(bar = "8a") = ((x.+(3): Int @ann(bar = "8a")): Int @ann(bar = "8b") @ann(bar = "8a")); - val s: Int @ann(bar = "9b") @ann(bar = "9a") = (4: Int @ann(bar = "9b") @ann(bar = "9a")); - r.+(s) - } - }; - () -} +{ + @new ann(bar = "1a") @new ann(bar = "1b") class C[@new ann(bar = "2a") @new ann(bar = "2b") T >: Nothing <: Any] extends Object { + @new ann(bar = "3a") @new ann(bar = "3b") private[this] val x: T @ann(bar = "4a") @ann(bar = "4b") = _; + def (@new ann(bar = "3a") @new ann(bar = "3b") x: T @ann(bar = "4a") @ann(bar = "4b")) = { + super.(); + () + }; + @new ann(bar = "5a") @new ann(bar = "5b") def f(x: Int @ann(bar = "6a") @ann(bar = "6b")) = { + @new ann(bar = "7a") @new ann(bar = "7b") val r = x.$plus(3): @ann(bar = "8a"): @ann(bar = "8b"); + val s = (4: Int @ann(bar = "9a") @ann(bar = "9b")); + r.$plus(s) + } + }; + () +} +{ + @ann(bar = "1a") @ann(bar = "1b") class C[@ann(bar = "2a") @ann(bar = "2b") T] extends Object { + @ann(bar = "3a") @ann(bar = "3b") private[this] val x: T @ann(bar = "4b") @ann(bar = "4a") = _; + def (@ann(bar = "3a") @ann(bar = "3b") x: T @ann(bar = "4b") @ann(bar = "4a")): C[T] = { + C.super.(); + () + }; + @ann(bar = "5a") @ann(bar = "5b") def f(x: Int @ann(bar = "6b") @ann(bar = "6a")): Int = { + @ann(bar = "7a") @ann(bar = "7b") val r: Int @ann(bar = "8b") @ann(bar = "8a") = ((x.+(3): Int @ann(bar = "8a")): Int @ann(bar = "8b") @ann(bar = "8a")); + val s: Int @ann(bar = "9b") @ann(bar = "9a") = (4: Int @ann(bar = "9b") @ann(bar = "9a")); + r.+(s) + } + }; + () +} diff --git a/test/files/run/reify_ann1b.scala b/test/files/run/reify_ann1b.scala index 9bdc712227..13d861a15c 100644 --- a/test/files/run/reify_ann1b.scala +++ b/test/files/run/reify_ann1b.scala @@ -1,14 +1,10 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ class ann(bar: String) extends ClassfileAnnotation object Test extends App { // test 1: reify - val tree = scala.reflect.Code.lift{ + val tree = reify{ @ann(bar="1a") @ann(bar="1b") class C[@ann(bar="2a") @ann(bar="2b") T](@ann(bar="3a") @ann(bar="3b") x: T @ann(bar="4a") @ann(bar="4b")) { @ann(bar="5a") @ann(bar="5b") def f(x: Int @ann(bar="6a") @ann(bar="6b")) = { @ann(bar="7a") @ann(bar="7b") val r = (x + 3): @ann(bar="8a") @ann(bar="8b") @@ -20,8 +16,7 @@ object Test extends App { println(tree.toString) // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val ttree = toolbox.typeCheck(tree) println(ttree.toString) diff --git a/test/files/run/reify_ann2a.check b/test/files/run/reify_ann2a.check new file mode 100644 index 0000000000..5022c50ca8 --- /dev/null +++ b/test/files/run/reify_ann2a.check @@ -0,0 +1,44 @@ +{ + class ann extends StaticAnnotation { + private[this] val bar: List[String] = _; + def (bar: List[String]) = { + super.(); + () + } + }; + @new ann(immutable.this.List.apply("1a")) @new ann(immutable.this.List.apply("1b")) class C[@new ann(immutable.this.List.apply("2a")) @new ann(immutable.this.List.apply("2b")) T >: Nothing <: Any] extends Object { + @new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) private[this] val x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b")) = _; + def (@new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b"))) = { + super.(); + () + }; + @new ann(immutable.this.List.apply("5a")) @new ann(immutable.this.List.apply("5b")) def f(x: Int @ann(immutable.this.List.apply("6a")) @ann(immutable.this.List.apply("6b"))) = { + @new ann(immutable.this.List.apply("7a")) @new ann(immutable.this.List.apply("7b")) val r = x.$plus(3): @ann(immutable.this.List.apply("8a")): @ann(immutable.this.List.apply("8b")); + val s = (4: Int @ann(immutable.this.List.apply("9a")) @ann(immutable.this.List.apply("9b"))); + r.$plus(s) + } + }; + () +} +{ + class ann extends scala.annotation.Annotation with scala.annotation.StaticAnnotation { + private[this] val bar: List[String] = _; + def (bar: List[String]): ann = { + ann.super.(); + () + } + }; + @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T] extends Object { + @ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _; + def (@ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a"))): C[T] = { + C.super.(); + () + }; + @ann(immutable.this.List.apply[String]("5a")) @ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = { + @ann(immutable.this.List.apply[String]("7a")) @ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.+(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a"))); + val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a"))); + r.+(s) + } + }; + () +} diff --git a/test/files/run/reify_ann2a.scala b/test/files/run/reify_ann2a.scala new file mode 100644 index 0000000000..370abadba0 --- /dev/null +++ b/test/files/run/reify_ann2a.scala @@ -0,0 +1,25 @@ +import scala.reflect.mirror._ + +object Test extends App { + // test 1: reify + val tree = reify{ + class ann(bar: List[String]) extends StaticAnnotation + + @ann(bar=List("1a")) @ann(bar=List("1b")) class C[@ann(bar=List("2a")) @ann(bar=List("2b")) T](@ann(bar=List("3a")) @ann(bar=List("3b")) x: T @ann(bar=List("4a")) @ann(bar=List("4b"))) { + @ann(bar=List("5a")) @ann(bar=List("5b")) def f(x: Int @ann(bar=List("6a")) @ann(bar=List("6b"))) = { + @ann(bar=List("7a")) @ann(bar=List("7b")) val r = (x + 3): @ann(bar=List("8a")) @ann(bar=List("8b")) + val s = 4: Int @ann(bar=List("9a")) @ann(bar=List("9b")) + r + s + } + } + }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(tree) +} \ No newline at end of file diff --git a/test/files/run/reify_ann3.check b/test/files/run/reify_ann3.check new file mode 100644 index 0000000000..9452a9701e --- /dev/null +++ b/test/files/run/reify_ann3.check @@ -0,0 +1,21 @@ +{ + class Tree[A >: Nothing <: Any, B >: Nothing <: Any] extends Object { + @new inline @getter() final val key: A = _; + def (key: A) = { + super.(); + () + } + }; + () +} +{ + class Tree[A, B] extends Object { + final private[this] val key: A = _; + @inline @scala.annotation.meta.getter final def key: A = Tree.this.key; + def (key: A): Tree[A,B] = { + Tree.super.(); + () + } + }; + () +} diff --git a/test/files/run/reify_ann3.scala b/test/files/run/reify_ann3.scala new file mode 100644 index 0000000000..d65e641619 --- /dev/null +++ b/test/files/run/reify_ann3.scala @@ -0,0 +1,19 @@ +import scala.reflect.mirror._ +import scala.annotation._ +import scala.annotation.meta._ + +object Test extends App { + // test 1: reify + val tree = reify{ + class Tree[A, +B](@(inline @getter) final val key: A) + }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(tree) +} diff --git a/test/files/run/reify_ann4.check b/test/files/run/reify_ann4.check new file mode 100644 index 0000000000..406ee7bc08 --- /dev/null +++ b/test/files/run/reify_ann4.check @@ -0,0 +1,32 @@ +{ + class D extends StaticAnnotation { + def () = { + super.(); + () + } + }; + class C extends Object { + def () = { + super.(); + () + } + }; + val c1 = new C @D(); + () +} +{ + class D extends scala.annotation.Annotation with scala.annotation.StaticAnnotation { + def (): D = { + D.super.(); + () + } + }; + class C extends Object { + def (): C = { + C.super.(); + () + } + }; + val c1: C = new C @D(); + () +} diff --git a/test/files/run/reify_ann4.scala b/test/files/run/reify_ann4.scala new file mode 100644 index 0000000000..5655812689 --- /dev/null +++ b/test/files/run/reify_ann4.scala @@ -0,0 +1,23 @@ +import scala.reflect.mirror._ +import scala.annotation._ +import scala.annotation.meta._ + +object Test extends App { + // test 1: reify + val tree = reify{ + class D extends StaticAnnotation + class C + val c1 = new C @D + //val c2 = (new C) @D // illegal syntax + //val c3 = c1 @D // illegal syntax + }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(tree) +} diff --git a/test/files/run/reify_ann5.check b/test/files/run/reify_ann5.check new file mode 100644 index 0000000000..ecf08eebb2 --- /dev/null +++ b/test/files/run/reify_ann5.check @@ -0,0 +1,22 @@ +{ + class C extends Object { + @new inline @beanGetter() @new BeanProperty() val x: Int = _; + def (x: Int) = { + super.(); + () + } + }; + () +} +{ + class C extends Object { + @scala.beans.BeanProperty private[this] val x: Int = _; + def x: Int = C.this.x; + def (x: Int): C = { + C.super.(); + () + }; + @inline @scala.annotation.meta.beanGetter def getX(): Int = C.this.x + }; + () +} diff --git a/test/files/run/reify_ann5.scala b/test/files/run/reify_ann5.scala new file mode 100644 index 0000000000..aecc61de46 --- /dev/null +++ b/test/files/run/reify_ann5.scala @@ -0,0 +1,20 @@ +import scala.reflect.mirror._ +import scala.annotation._ +import scala.annotation.meta._ +import scala.beans._ + +object Test extends App { + // test 1: reify + val tree = reify{ + class C(@BeanProperty @(inline @beanGetter) val x: Int) + }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(tree) +} diff --git a/test/files/run/reify_anonymous.scala b/test/files/run/reify_anonymous.scala index af16f2f8fd..cd740f0190 100644 --- a/test/files/run/reify_anonymous.scala +++ b/test/files/run/reify_anonymous.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { println(new {def x = 2; def y = x * x}.y) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_classfileann_a.check b/test/files/run/reify_classfileann_a.check index 419d916907..685ecf5de6 100644 --- a/test/files/run/reify_classfileann_a.check +++ b/test/files/run/reify_classfileann_a.check @@ -1,18 +1,18 @@ -{ - @new ann(bar = "1", quux = Array("2", "3"), baz = new ann(bar = "4")) class C extends scala.AnyRef { - def () = { - super.(); - () - } - }; - () -} -{ - @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")) class C extends scala.AnyRef { - def (): C = { - C.super.(); - () - } - }; - () -} +{ + @new ann(bar = "1", quux = Array("2", "3"), baz = new ann(bar = "4")) class C extends Object { + def () = { + super.(); + () + } + }; + () +} +{ + @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")) class C extends Object { + def (): C = { + C.super.(); + () + } + }; + () +} diff --git a/test/files/run/reify_classfileann_a.scala b/test/files/run/reify_classfileann_a.scala index c77bd3b8a2..c3e7d8d2e9 100644 --- a/test/files/run/reify_classfileann_a.scala +++ b/test/files/run/reify_classfileann_a.scala @@ -1,21 +1,16 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation object Test extends App { // test 1: reify - val tree = scala.reflect.Code.lift{ + val tree = reify{ @ann(bar="1", quux=Array("2", "3"), baz = new ann(bar = "4")) class C }.tree println(tree.toString) // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val ttree = toolbox.typeCheck(tree) println(ttree.toString) diff --git a/test/files/run/reify_classfileann_b.check b/test/files/run/reify_classfileann_b.check new file mode 100644 index 0000000000..0aac9aeb2a --- /dev/null +++ b/test/files/run/reify_classfileann_b.check @@ -0,0 +1,20 @@ +{ + class C extends Object { + def () = { + super.(); + () + }; + def x: Int = 2: @ann(bar = "1",quux = Array("2", "3"),baz = new ann(bar = "4")) + }; + () +} +{ + class C extends Object { + def (): C = { + C.super.(); + () + }; + def x: Int = (2: Int(2) @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4"))) + }; + () +} diff --git a/test/files/run/reify_classfileann_b.scala b/test/files/run/reify_classfileann_b.scala new file mode 100644 index 0000000000..4e50494af3 --- /dev/null +++ b/test/files/run/reify_classfileann_b.scala @@ -0,0 +1,23 @@ +import scala.reflect.mirror._ + +class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation + +object Test extends App { + // test 1: reify + val tree = reify{ + class C { + def x: Int = { + 2: @ann(bar="1", quux=Array("2", "3"), baz = new ann(bar = "4")) + } + } + }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(tree) +} \ No newline at end of file diff --git a/test/files/run/reify_closure1.scala b/test/files/run/reify_closure1.scala index 7cb3aff17d..3f5c8a8724 100644 --- a/test/files/run/reify_closure1.scala +++ b/test/files/run/reify_closure1.scala @@ -1,15 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { def foo[T](ys: List[T]): Int => Int = { - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { x }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/files/run/reify_closure2a.scala b/test/files/run/reify_closure2a.scala index cf367aa63f..f5669a0e2c 100644 --- a/test/files/run/reify_closure2a.scala +++ b/test/files/run/reify_closure2a.scala @@ -1,15 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { def foo(y: Int): Int => Int = { - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { x + y }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/files/run/reify_closure3a.scala b/test/files/run/reify_closure3a.scala index d322b970b6..056a705d7d 100644 --- a/test/files/run/reify_closure3a.scala +++ b/test/files/run/reify_closure3a.scala @@ -1,17 +1,14 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { def foo(y: Int): Int => Int = { def y1 = y - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { x + y1 }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/files/run/reify_closure4a.scala b/test/files/run/reify_closure4a.scala index bbedd7e092..a63d20e561 100644 --- a/test/files/run/reify_closure4a.scala +++ b/test/files/run/reify_closure4a.scala @@ -1,17 +1,14 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { def foo(y: Int): Int => Int = { val y1 = y - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { x + y1 }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/files/run/reify_closure5a.scala b/test/files/run/reify_closure5a.scala index 193e18103a..2e8b413f4c 100644 --- a/test/files/run/reify_closure5a.scala +++ b/test/files/run/reify_closure5a.scala @@ -1,19 +1,18 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - def foo[T](ys: List[T]): Int => Int = { - val fun = reflect.Code.lift{(x: Int) => { + def foo[T: TypeTag](ys: List[T]): Int => Int = { + val fun = reify{(x: Int) => { x + ys.length }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } - println(foo(List(1, 2, 3))(10)) - println(foo(List(1, 2, 3, 4))(10)) + var fun1 = foo(List(1, 2, 3)) + println(fun1(10)) + var fun2 = foo(List(1, 2, 3, 4)) + println(fun2(10)) } diff --git a/test/files/run/reify_closure6.scala b/test/files/run/reify_closure6.scala index 6aff83cb94..2cbd4ce819 100644 --- a/test/files/run/reify_closure6.scala +++ b/test/files/run/reify_closure6.scala @@ -1,13 +1,11 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { var q = 0 - def foo[T](ys: List[T]): Int => Int = { + def foo[T: TypeTag](ys: List[T]): Int => Int = { val z = 1 var y = 0 - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { y += 1 q += 1 println("q = " + q) @@ -15,13 +13,14 @@ object Test extends App { x + ys.length * z + q + y }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } - println("first invocation = " + foo(List(1, 2, 3))(10)) - println("second invocation = " + foo(List(1, 2, 3, 4))(10)) + val fun1 = foo(List(1, 2, 3)) + println("first invocation = " + fun1(10)) + val fun2 = foo(List(1, 2, 3, 4)) + println("second invocation = " + fun2(10)) println("q after second invocation = " + q) } \ No newline at end of file diff --git a/test/files/run/reify_closure7.scala b/test/files/run/reify_closure7.scala index 46002d8d6c..b9f87dbdeb 100644 --- a/test/files/run/reify_closure7.scala +++ b/test/files/run/reify_closure7.scala @@ -1,14 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { var q = 0 var clo: Int => Int = null - def foo[T](ys: List[T]): Int => Int = { + def foo[T: TypeTag](ys: List[T]): Int => Int = { val z = 1 var y = 0 - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { y += 1 q += 1 println("q = " + q) @@ -17,8 +15,7 @@ object Test extends App { }} if (clo == null) { - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) clo = dyn.asInstanceOf[Int => Int] } @@ -26,6 +23,8 @@ object Test extends App { clo } - println("first invocation = " + foo(List(1, 2, 3))(10)) - println("second invocation = " + foo(List(1, 2, 3, 4))(10)) + val fun1 = foo(List(1, 2, 3)) + println("first invocation = " + fun1(10)) + val fun2 = foo(List(1, 2, 3, 4)) + println("second invocation = " + fun2(10)) } diff --git a/test/files/run/reify_closure8a.scala b/test/files/run/reify_closure8a.scala index 805d8ff855..9de121b42f 100644 --- a/test/files/run/reify_closure8a.scala +++ b/test/files/run/reify_closure8a.scala @@ -1,15 +1,11 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { class Foo(val y: Int) { - def fun = lift{y} + def fun = reify{y} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(10).fun.tree) val foo = dyn.asInstanceOf[Int] println(foo) diff --git a/test/files/run/reify_closure8b.check b/test/files/run/reify_closure8b.check new file mode 100644 index 0000000000..e0ec7d2c8f --- /dev/null +++ b/test/files/run/reify_closure8b.check @@ -0,0 +1,3 @@ +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective compilation has failed: + +value y is not a member of Test.Foo diff --git a/test/files/run/reify_closure8b.scala b/test/files/run/reify_closure8b.scala new file mode 100644 index 0000000000..431da3230e --- /dev/null +++ b/test/files/run/reify_closure8b.scala @@ -0,0 +1,18 @@ +import scala.reflect.mirror._ + +object Test extends App { + // will fail because y is a private field + // reification doesn't magically make unavailable stuff available + class Foo(y: Int) { + def fun = reify{y} + } + + try { + val dyn = mkToolBox().runExpr(new Foo(10).fun.tree) + val foo = dyn.asInstanceOf[Int] + println(foo) + } catch { + case ex: Throwable => + println(ex) + } +} diff --git a/test/files/run/reify_closures10.scala b/test/files/run/reify_closures10.scala index b6ec8e8911..0ccce77a94 100644 --- a/test/files/run/reify_closures10.scala +++ b/test/files/run/reify_closures10.scala @@ -1,14 +1,10 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { val x = 2 val y = 3 - val code = lift{println(x + y); x + y} + val code = reify{println(x + y); x + y} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(toolbox.runExpr(code.tree)) } diff --git a/test/files/run/reify_complex.scala b/test/files/run/reify_complex.scala index 0d9aeb28c5..ecc25ffca5 100644 --- a/test/files/run/reify_complex.scala +++ b/test/files/run/reify_complex.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class Complex(val re: Double, val im: Double) { def + (that: Complex) = new Complex(re + that.re, im + that.im) @@ -22,9 +20,5 @@ object Test extends App { } val x = new Complex(2, 1); val y = new Complex(1, 3) println(x + y) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_extendbuiltins.scala b/test/files/run/reify_extendbuiltins.scala index 0aaec7cdf2..f95e9ab6ec 100644 --- a/test/files/run/reify_extendbuiltins.scala +++ b/test/files/run/reify_extendbuiltins.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { def fact(n: Int): BigInt = if (n == 0) 1 else fact(n-1) * n class Factorizer(n: Int) { @@ -12,9 +10,5 @@ object Test extends App { implicit def int2fact(n: Int) = new Factorizer(n) println("10! = " + (10!)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_for1.scala b/test/files/run/reify_for1.scala index d1b60d878b..9d1e32f7e5 100644 --- a/test/files/run/reify_for1.scala +++ b/test/files/run/reify_for1.scala @@ -1,15 +1,9 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val sumOfSquares1 = (for (i <- 1 to 100; if (i % 3 == 0)) yield Math.pow(i, 2)).sum val sumOfSquares2 = (1 to 100).filter(_ % 3 == 0).map(Math.pow(_, 2)).sum assert(sumOfSquares1 == sumOfSquares2) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_fors.scala b/test/files/run/reify_fors.scala index 27ee85d18b..635fce049e 100644 --- a/test/files/run/reify_fors.scala +++ b/test/files/run/reify_fors.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object Persons { /** A list of persons. To create a list, we use Predef.List * which takes a variable number of arguments and constructs @@ -98,9 +96,5 @@ object Test extends App { val ys = List(2.0, 1.0, 3.0) println("scalProd(" + xs + ", " + ys +") = " + scalProd(xs, ys)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_generic.scala b/test/files/run/reify_generic.scala index 6a4ff148c4..7033c4e237 100644 --- a/test/files/run/reify_generic.scala +++ b/test/files/run/reify_generic.scala @@ -1,14 +1,8 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val product = List(1, 2, 3).head * List[Any](4, 2, 0).head.asInstanceOf[Int] println(product) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_generic2.scala b/test/files/run/reify_generic2.scala index 9413f41eb5..8f9def318e 100644 --- a/test/files/run/reify_generic2.scala +++ b/test/files/run/reify_generic2.scala @@ -1,15 +1,9 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C val product = List(new C, new C).length * List[C](new C, new C).length println(product) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_getter.scala b/test/files/run/reify_getter.scala index 33f36888a7..8bae293e72 100644 --- a/test/files/run/reify_getter.scala +++ b/test/files/run/reify_getter.scala @@ -1,18 +1,15 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { class C { val x = 2 } new C().x - }; + } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val evaluated = toolbox.runExpr(code.tree) println("evaluated = " + evaluated) } diff --git a/test/files/run/reify_implicits.scala b/test/files/run/reify_implicits.scala index 953eabe6c2..60971c3cfb 100644 --- a/test/files/run/reify_implicits.scala +++ b/test/files/run/reify_implicits.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { implicit def arrayWrapper[A : ClassManifest](x: Array[A]) = new { def sort(p: (A, A) => Boolean) = { @@ -12,9 +10,5 @@ object Test extends App { } val x = Array(2, 3, 1, 4) println("x = "+ x.sort((x: Int, y: Int) => x < y).toList) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_inheritance.scala b/test/files/run/reify_inheritance.scala index 78a64c264e..dd86c355a3 100644 --- a/test/files/run/reify_inheritance.scala +++ b/test/files/run/reify_inheritance.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C { def x = 2 def y = x * x @@ -14,9 +12,5 @@ object Test extends App { } println(new D().y * new C().x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_inner1.scala b/test/files/run/reify_inner1.scala index 546fe36d16..ea77ece6df 100644 --- a/test/files/run/reify_inner1.scala +++ b/test/files/run/reify_inner1.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C { class D { val x = 2 @@ -13,9 +11,5 @@ object Test extends App { val outer = new C() val inner = new outer.D() println(inner.x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_inner2.scala b/test/files/run/reify_inner2.scala index 613614b989..67c403f7e5 100644 --- a/test/files/run/reify_inner2.scala +++ b/test/files/run/reify_inner2.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C { object D { val x = 2 @@ -13,9 +11,5 @@ object Test extends App { val outer = new C() val inner = outer.D println(inner.x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_inner3.scala b/test/files/run/reify_inner3.scala index e9fb636dce..ad401d81da 100644 --- a/test/files/run/reify_inner3.scala +++ b/test/files/run/reify_inner3.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object C { class D { val x = 2 @@ -13,9 +11,5 @@ object Test extends App { val outer = C val inner = new outer.D println(inner.x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_inner4.scala b/test/files/run/reify_inner4.scala index 33870b0983..140c8e9ed4 100644 --- a/test/files/run/reify_inner4.scala +++ b/test/files/run/reify_inner4.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object C { object D { val x = 2 @@ -13,9 +11,5 @@ object Test extends App { val outer = C val inner = outer.D println(inner.x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_maps.scala b/test/files/run/reify_maps.scala index d3d95ffa24..3fcc21892f 100644 --- a/test/files/run/reify_maps.scala +++ b/test/files/run/reify_maps.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val colors = Map("red" -> 0xFF0000, "turquoise" -> 0x00FFFF, "black" -> 0x000000, @@ -17,9 +15,5 @@ object Test extends App { "Unknown color: " + name } ) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_metalevel_breach_+0_refers_to_1.check b/test/files/run/reify_metalevel_breach_+0_refers_to_1.check new file mode 100644 index 0000000000..5bfed17f8e --- /dev/null +++ b/test/files/run/reify_metalevel_breach_+0_refers_to_1.check @@ -0,0 +1 @@ +evaluated = 2 \ No newline at end of file diff --git a/test/files/run/reify_metalevel_breach_+0_refers_to_1.scala b/test/files/run/reify_metalevel_breach_+0_refers_to_1.scala new file mode 100644 index 0000000000..fe23bc8438 --- /dev/null +++ b/test/files/run/reify_metalevel_breach_+0_refers_to_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = reify{ + val x = 2 + val inner = reify{x} + inner.eval + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check new file mode 100644 index 0000000000..5bfed17f8e --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check @@ -0,0 +1 @@ +evaluated = 2 \ No newline at end of file diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala new file mode 100644 index 0000000000..5d98a38592 --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + val x = 2 + val outer = reify{reify{x}} + val code = reify{outer.eval.eval} + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check new file mode 100644 index 0000000000..5bfed17f8e --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check @@ -0,0 +1 @@ +evaluated = 2 \ No newline at end of file diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala new file mode 100644 index 0000000000..ca31d83acd --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + val x = 2 + val code = reify{ + { + val inner = reify{reify{x}} + inner.eval + }.eval + } + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_1.check b/test/files/run/reify_metalevel_breach_-1_refers_to_1.check new file mode 100644 index 0000000000..5bfed17f8e --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_1.check @@ -0,0 +1 @@ +evaluated = 2 \ No newline at end of file diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_1.scala b/test/files/run/reify_metalevel_breach_-1_refers_to_1.scala new file mode 100644 index 0000000000..56d85c6ba1 --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = reify{ + val x = 2 + val inner = reify{reify{x}} + inner.eval.eval + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_nested_inner_refers_to_global.check b/test/files/run/reify_nested_inner_refers_to_global.check new file mode 100644 index 0000000000..7ff4c83d37 --- /dev/null +++ b/test/files/run/reify_nested_inner_refers_to_global.check @@ -0,0 +1 @@ +evaluated = 2 diff --git a/test/files/run/reify_nested_inner_refers_to_global.scala b/test/files/run/reify_nested_inner_refers_to_global.scala new file mode 100644 index 0000000000..14899bcf99 --- /dev/null +++ b/test/files/run/reify_nested_inner_refers_to_global.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = { + val x = 2 + reify{ + reify{x}.eval + } + } + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_nested_inner_refers_to_local.check b/test/files/run/reify_nested_inner_refers_to_local.check new file mode 100644 index 0000000000..5bfed17f8e --- /dev/null +++ b/test/files/run/reify_nested_inner_refers_to_local.check @@ -0,0 +1 @@ +evaluated = 2 \ No newline at end of file diff --git a/test/files/run/reify_nested_inner_refers_to_local.scala b/test/files/run/reify_nested_inner_refers_to_local.scala new file mode 100644 index 0000000000..fd56585f72 --- /dev/null +++ b/test/files/run/reify_nested_inner_refers_to_local.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = reify{ + val x = 2 + reify{x}.eval + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_nested_outer_refers_to_global.check b/test/files/run/reify_nested_outer_refers_to_global.check new file mode 100644 index 0000000000..7ff4c83d37 --- /dev/null +++ b/test/files/run/reify_nested_outer_refers_to_global.check @@ -0,0 +1 @@ +evaluated = 2 diff --git a/test/files/run/reify_nested_outer_refers_to_global.scala b/test/files/run/reify_nested_outer_refers_to_global.scala new file mode 100644 index 0000000000..f34e4fe04b --- /dev/null +++ b/test/files/run/reify_nested_outer_refers_to_global.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = { + val x = 2 + val outer = reify{x} + reify{ + val x = 42 + outer.eval + }; + } + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_nested_outer_refers_to_local.check b/test/files/run/reify_nested_outer_refers_to_local.check new file mode 100644 index 0000000000..7ff4c83d37 --- /dev/null +++ b/test/files/run/reify_nested_outer_refers_to_local.check @@ -0,0 +1 @@ +evaluated = 2 diff --git a/test/files/run/reify_nested_outer_refers_to_local.scala b/test/files/run/reify_nested_outer_refers_to_local.scala new file mode 100644 index 0000000000..e16c851d8d --- /dev/null +++ b/test/files/run/reify_nested_outer_refers_to_local.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + val outer = { + val x = 2 + reify{x} + } + val code = reify{ + val x = 42 + outer.eval + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_newimpl_01.check b/test/files/run/reify_newimpl_01.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_01.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_01.scala b/test/files/run/reify_newimpl_01.scala new file mode 100644 index 0000000000..f7539a15b0 --- /dev/null +++ b/test/files/run/reify_newimpl_01.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 2 + val code = reify { + x + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_02.check b/test/files/run/reify_newimpl_02.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_02.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_02.scala b/test/files/run/reify_newimpl_02.scala new file mode 100644 index 0000000000..2c085efa04 --- /dev/null +++ b/test/files/run/reify_newimpl_02.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var x = 2 + val code = reify { + x + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_03.check b/test/files/run/reify_newimpl_03.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_03.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_03.scala b/test/files/run/reify_newimpl_03.scala new file mode 100644 index 0000000000..361cfc50bb --- /dev/null +++ b/test/files/run/reify_newimpl_03.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val code = reify { + val x = 2 + reify{x}.eval + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_04.check b/test/files/run/reify_newimpl_04.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_04.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_04.scala b/test/files/run/reify_newimpl_04.scala new file mode 100644 index 0000000000..d80a7c9ffd --- /dev/null +++ b/test/files/run/reify_newimpl_04.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val code = reify { + var x = 2 + reify{x}.eval + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_05.check b/test/files/run/reify_newimpl_05.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_05.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_05.scala b/test/files/run/reify_newimpl_05.scala new file mode 100644 index 0000000000..85c1711bdb --- /dev/null +++ b/test/files/run/reify_newimpl_05.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val code = reify { + var x = 2 + def y = x // forcibly captures x + reify{x}.eval + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_06.check b/test/files/run/reify_newimpl_06.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_06.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_06.scala b/test/files/run/reify_newimpl_06.scala new file mode 100644 index 0000000000..257b54167a --- /dev/null +++ b/test/files/run/reify_newimpl_06.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C(val y: Int) { + val code = reify { + reify{y}.eval + } + } + + println(new C(2).code.eval) +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_09.check b/test/files/run/reify_newimpl_09.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_09.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_09.scala b/test/files/run/reify_newimpl_09.scala new file mode 100644 index 0000000000..2c81945a2a --- /dev/null +++ b/test/files/run/reify_newimpl_09.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + type T = Int + val code = reify { + List[T](2) + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_10.check b/test/files/run/reify_newimpl_10.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_10.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_10.scala b/test/files/run/reify_newimpl_10.scala new file mode 100644 index 0000000000..6e70b4d216 --- /dev/null +++ b/test/files/run/reify_newimpl_10.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + type T = Int + implicit val tt = implicitly[TypeTag[String]].asInstanceOf[TypeTag[T]] // this "mistake" is made for a reason! + val code = reify { + List[T](2) + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_11.check b/test/files/run/reify_newimpl_11.check new file mode 100644 index 0000000000..e2a8206132 --- /dev/null +++ b/test/files/run/reify_newimpl_11.check @@ -0,0 +1,2 @@ +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed: +unresolved free type variables (namely: T defined by C in reify_newimpl_11.scala:4:11). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types diff --git a/test/files/run/reify_newimpl_11.scala b/test/files/run/reify_newimpl_11.scala new file mode 100644 index 0000000000..4e91c7a457 --- /dev/null +++ b/test/files/run/reify_newimpl_11.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[T] { + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + try { + new C[Int] + } catch { + case ex: Throwable => + println(ex) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_12.check b/test/files/run/reify_newimpl_12.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_12.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_12.scala b/test/files/run/reify_newimpl_12.scala new file mode 100644 index 0000000000..433168ce28 --- /dev/null +++ b/test/files/run/reify_newimpl_12.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[T: TypeTag] { + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + new C[Int] +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_13.check b/test/files/run/reify_newimpl_13.check new file mode 100644 index 0000000000..7c47310cf2 --- /dev/null +++ b/test/files/run/reify_newimpl_13.check @@ -0,0 +1,2 @@ +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed: +unresolved free type variables (namely: T defined by C in reify_newimpl_13.scala:5:13). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types diff --git a/test/files/run/reify_newimpl_13.scala b/test/files/run/reify_newimpl_13.scala new file mode 100644 index 0000000000..dd1980b74f --- /dev/null +++ b/test/files/run/reify_newimpl_13.scala @@ -0,0 +1,19 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + class C[T] { + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + try { + new C[Int] + } catch { + case ex: Throwable => + println(ex) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_14.check b/test/files/run/reify_newimpl_14.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_14.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_14.scala b/test/files/run/reify_newimpl_14.scala new file mode 100644 index 0000000000..3f52f19cfb --- /dev/null +++ b/test/files/run/reify_newimpl_14.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + class C[T: TypeTag] { + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + new C[Int] + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_15.check b/test/files/run/reify_newimpl_15.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_15.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_15.scala b/test/files/run/reify_newimpl_15.scala new file mode 100644 index 0000000000..b707b2583d --- /dev/null +++ b/test/files/run/reify_newimpl_15.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C { + type T = Int + val code = reify { + List[T](2) + } + println(code.eval) + } + + new C +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_16.check b/test/files/run/reify_newimpl_16.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_16.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_16.scala b/test/files/run/reify_newimpl_16.scala new file mode 100644 index 0000000000..98fc15878c --- /dev/null +++ b/test/files/run/reify_newimpl_16.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + class C { + type T = Int + val code = reify { + List[T](2) + } + println(code.eval) + } + + new C + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_17.check b/test/files/run/reify_newimpl_17.check new file mode 100644 index 0000000000..0fb9ddfc2d --- /dev/null +++ b/test/files/run/reify_newimpl_17.check @@ -0,0 +1,2 @@ +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed: +unresolved free type variables (namely: U defined by C in reify_newimpl_17.scala:4:11). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types diff --git a/test/files/run/reify_newimpl_17.scala b/test/files/run/reify_newimpl_17.scala new file mode 100644 index 0000000000..331777fcfb --- /dev/null +++ b/test/files/run/reify_newimpl_17.scala @@ -0,0 +1,18 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[U] { + type T = U + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + try { + new C[Int] + } catch { + case ex: Throwable => + println(ex) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_18.check b/test/files/run/reify_newimpl_18.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_18.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_18.scala b/test/files/run/reify_newimpl_18.scala new file mode 100644 index 0000000000..704e54928a --- /dev/null +++ b/test/files/run/reify_newimpl_18.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[U: TypeTag] { + type T = U + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + new C[Int] +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_19.check b/test/files/run/reify_newimpl_19.check new file mode 100644 index 0000000000..32f9300f53 --- /dev/null +++ b/test/files/run/reify_newimpl_19.check @@ -0,0 +1,2 @@ +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed: +unresolved free type variables (namely: T defined by C in reify_newimpl_19.scala:5:10). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types diff --git a/test/files/run/reify_newimpl_19.scala b/test/files/run/reify_newimpl_19.scala new file mode 100644 index 0000000000..0ea8ae6992 --- /dev/null +++ b/test/files/run/reify_newimpl_19.scala @@ -0,0 +1,18 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C { + type T + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + try { + new C { val T = Int } + } catch { + case ex: Throwable => + println(ex) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_20.check b/test/files/run/reify_newimpl_20.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_20.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_20.scala b/test/files/run/reify_newimpl_20.scala new file mode 100644 index 0000000000..16895a449e --- /dev/null +++ b/test/files/run/reify_newimpl_20.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C { + type T + implicit val tt: TypeTag[T] = implicitly[TypeTag[Int]].asInstanceOf[TypeTag[T]] + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + new C { type T = String } // this "mistake" is made for a reason! +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_21.check b/test/files/run/reify_newimpl_21.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_21.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_21.scala b/test/files/run/reify_newimpl_21.scala new file mode 100644 index 0000000000..99f9ac9089 --- /dev/null +++ b/test/files/run/reify_newimpl_21.scala @@ -0,0 +1,18 @@ +import scala.reflect.mirror._ + +object Test extends App { + trait C { + type T + implicit val tt: TypeTag[T] + lazy val code = reify { + List[T](2.asInstanceOf[T]) + } + } + + class D extends C { + type T = String // this "mistake" is made for a reason! + override val tt: TypeTag[T] = implicitly[TypeTag[Int]].asInstanceOf[TypeTag[T]] + } + + println((new D).code.eval) +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_22.check b/test/files/run/reify_newimpl_22.check new file mode 100644 index 0000000000..51699cbc29 --- /dev/null +++ b/test/files/run/reify_newimpl_22.check @@ -0,0 +1,23 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.mirror._ +import scala.reflect.mirror._ + +scala> { + val x = 2 + val code = reify { + x + } + println(code.eval) +} +:13: free term: Ident(newTermName("x")) defined by res0 in :12:21 + val code = reify { + ^ +2 + +scala> + +scala> diff --git a/test/files/run/reify_newimpl_22.scala b/test/files/run/reify_newimpl_22.scala new file mode 100644 index 0000000000..a211ad360c --- /dev/null +++ b/test/files/run/reify_newimpl_22.scala @@ -0,0 +1,15 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-free-terms" + def code = """ +import scala.reflect.mirror._ +{ + val x = 2 + val code = reify { + x + } + println(code.eval) +} + """ +} diff --git a/test/files/run/reify_newimpl_23.check b/test/files/run/reify_newimpl_23.check new file mode 100644 index 0000000000..33d15190fb --- /dev/null +++ b/test/files/run/reify_newimpl_23.check @@ -0,0 +1,22 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.mirror._ +import scala.reflect.mirror._ + +scala> def foo[T]{ + val code = reify { + List[T]() + } + println(code.eval) +} +:11: free type: Ident(newTypeName("T")) defined by foo in :10:16 + val code = reify { + ^ +foo: [T]=> Unit + +scala> + +scala> diff --git a/test/files/run/reify_newimpl_23.scala b/test/files/run/reify_newimpl_23.scala new file mode 100644 index 0000000000..15da4e497e --- /dev/null +++ b/test/files/run/reify_newimpl_23.scala @@ -0,0 +1,14 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-free-types" + def code = """ +import scala.reflect.mirror._ +def foo[T]{ + val code = reify { + List[T]() + } + println(code.eval) +} + """ +} diff --git a/test/files/run/reify_newimpl_24.check b/test/files/run/reify_newimpl_24.check new file mode 100644 index 0000000000..66b18c790e --- /dev/null +++ b/test/files/run/reify_newimpl_24.check @@ -0,0 +1,24 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.mirror._ +import scala.reflect.mirror._ + +scala> { + val x = 2 + val code = reify { + val y = reify { x } + y.eval + } + println(code.eval) +} +:15: this splice cannot be resolved statically + y.eval + ^ +2 + +scala> + +scala> diff --git a/test/files/run/reify_newimpl_24.scala b/test/files/run/reify_newimpl_24.scala new file mode 100644 index 0000000000..7b21eeeb10 --- /dev/null +++ b/test/files/run/reify_newimpl_24.scala @@ -0,0 +1,16 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-runtime-splices" + def code = """ +import scala.reflect.mirror._ +{ + val x = 2 + val code = reify { + val y = reify { x } + y.eval + } + println(code.eval) +} + """ +} diff --git a/test/files/run/reify_newimpl_25.check b/test/files/run/reify_newimpl_25.check new file mode 100644 index 0000000000..31ece627e1 --- /dev/null +++ b/test/files/run/reify_newimpl_25.check @@ -0,0 +1,21 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.mirror._ +import scala.reflect.mirror._ + +scala> { + val x = "2" + val tt = implicitly[TypeTag[x.type]] + println(tt) +} +:13: free term: Ident(newTermName("x")) defined by res0 in :12:21 + val tt = implicitly[TypeTag[x.type]] + ^ +GroundTypeTag[x.type] + +scala> + +scala> diff --git a/test/files/run/reify_newimpl_25.scala b/test/files/run/reify_newimpl_25.scala new file mode 100644 index 0000000000..1f66f5e681 --- /dev/null +++ b/test/files/run/reify_newimpl_25.scala @@ -0,0 +1,13 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-free-terms" + def code = """ +import scala.reflect.mirror._ +{ + val x = "2" + val tt = implicitly[TypeTag[x.type]] + println(tt) +} + """ +} diff --git a/test/files/run/reify_newimpl_26.check b/test/files/run/reify_newimpl_26.check new file mode 100644 index 0000000000..68b0ee8c99 --- /dev/null +++ b/test/files/run/reify_newimpl_26.check @@ -0,0 +1,23 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.mirror._ +import scala.reflect.mirror._ + +scala> def foo[T]{ + val tt = implicitly[TypeTag[List[T]]] + println(tt) +} +:11: free type: Ident(newTypeName("T")) defined by foo in :10:16 + val tt = implicitly[TypeTag[List[T]]] + ^ +foo: [T]=> Unit + +scala> foo[Int] +GroundTypeTag[List[T]] + +scala> + +scala> diff --git a/test/files/run/reify_newimpl_26.scala b/test/files/run/reify_newimpl_26.scala new file mode 100644 index 0000000000..f2dd1bfc4e --- /dev/null +++ b/test/files/run/reify_newimpl_26.scala @@ -0,0 +1,13 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-free-types" + def code = """ +import scala.reflect.mirror._ +def foo[T]{ + val tt = implicitly[TypeTag[List[T]]] + println(tt) +} +foo[Int] + """ +} diff --git a/test/files/run/reify_newimpl_27.check b/test/files/run/reify_newimpl_27.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_27.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_27.scala b/test/files/run/reify_newimpl_27.scala new file mode 100644 index 0000000000..b3d6d5c865 --- /dev/null +++ b/test/files/run/reify_newimpl_27.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + object C { + type T = Int + val code = reify { + List[T](2) + } + println(code.eval) + } + + C +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_28.check b/test/files/run/reify_newimpl_28.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_28.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_28.scala b/test/files/run/reify_newimpl_28.scala new file mode 100644 index 0000000000..f7874b8548 --- /dev/null +++ b/test/files/run/reify_newimpl_28.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + object C { + type T = Int + val code = reify { + List[T](2) + } + println(code.eval) + } + + C + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_29.check b/test/files/run/reify_newimpl_29.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_29.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_29.scala b/test/files/run/reify_newimpl_29.scala new file mode 100644 index 0000000000..e32762f335 --- /dev/null +++ b/test/files/run/reify_newimpl_29.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C { + type T = Int + val code = reify { + List[C#T](2) + } + println(code.eval) + } + + new C +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_30.check b/test/files/run/reify_newimpl_30.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_30.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_30.scala b/test/files/run/reify_newimpl_30.scala new file mode 100644 index 0000000000..e4ba3221e1 --- /dev/null +++ b/test/files/run/reify_newimpl_30.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + class C { + type T = Int + val code = reify { + List[C#T](2) + } + println(code.eval) + } + + new C + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_31.check b/test/files/run/reify_newimpl_31.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_31.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_31.scala b/test/files/run/reify_newimpl_31.scala new file mode 100644 index 0000000000..20a851e32e --- /dev/null +++ b/test/files/run/reify_newimpl_31.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + object C { + type T = Int + val code = reify { + List[C.T](2) + } + println(code.eval) + } + + C +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_32.check b/test/files/run/reify_newimpl_32.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_32.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_32.scala b/test/files/run/reify_newimpl_32.scala new file mode 100644 index 0000000000..788486ec00 --- /dev/null +++ b/test/files/run/reify_newimpl_32.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + object C { + type T = Int + val code = reify { + List[C.T](2) + } + println(code.eval) + } + + C + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_33.check b/test/files/run/reify_newimpl_33.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_33.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_33.scala b/test/files/run/reify_newimpl_33.scala new file mode 100644 index 0000000000..84a8258256 --- /dev/null +++ b/test/files/run/reify_newimpl_33.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + object C { + type T = Int + val c = C + val code = reify { + List[c.T](2) + } + println(code.eval) + } + + C +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_34.check b/test/files/run/reify_newimpl_34.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_34.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_34.scala b/test/files/run/reify_newimpl_34.scala new file mode 100644 index 0000000000..5935ab385c --- /dev/null +++ b/test/files/run/reify_newimpl_34.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + object C { + type T = Int + lazy val c = C + val code = reify { + List[c.T](2) + } + println(code.eval) + } + + C + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_36.check b/test/files/run/reify_newimpl_36.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/reify_newimpl_36.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/reify_newimpl_36.scala b/test/files/run/reify_newimpl_36.scala new file mode 100644 index 0000000000..c76efce27a --- /dev/null +++ b/test/files/run/reify_newimpl_36.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 42 + def foo() = reify(reify(x)); + { + val x = 2 + val code1 = foo() + val code2 = code1.eval + println(code2.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_37.check b/test/files/run/reify_newimpl_37.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/reify_newimpl_37.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/reify_newimpl_37.scala b/test/files/run/reify_newimpl_37.scala new file mode 100644 index 0000000000..e83d35dbe1 --- /dev/null +++ b/test/files/run/reify_newimpl_37.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 42 + def foo() = reify(reify(reify(x))); + { + val x = 2 + val code1 = foo() + val code2 = code1.eval + val code3 = code2.eval + println(code3.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_38.check b/test/files/run/reify_newimpl_38.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/reify_newimpl_38.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/reify_newimpl_38.scala b/test/files/run/reify_newimpl_38.scala new file mode 100644 index 0000000000..70ef49ecf7 --- /dev/null +++ b/test/files/run/reify_newimpl_38.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 42 + def foo() = reify{ val y = x; reify(y) }; + { + val x = 2 + val code1 = foo() + val code2 = code1.eval + println(code2.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_39.check b/test/files/run/reify_newimpl_39.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/reify_newimpl_39.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/reify_newimpl_39.scala b/test/files/run/reify_newimpl_39.scala new file mode 100644 index 0000000000..faa45d917d --- /dev/null +++ b/test/files/run/reify_newimpl_39.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 42 + def foo() = reify{ val y = x; reify{ val z = y; reify(z) } }; + { + val x = 2 + val code1 = foo() + val code2 = code1.eval + val code3 = code2.eval + println(code3.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_40.check b/test/files/run/reify_newimpl_40.check new file mode 100644 index 0000000000..94c5a65fe0 --- /dev/null +++ b/test/files/run/reify_newimpl_40.check @@ -0,0 +1 @@ +74088 diff --git a/test/files/run/reify_newimpl_40.scala b/test/files/run/reify_newimpl_40.scala new file mode 100644 index 0000000000..a983a92324 --- /dev/null +++ b/test/files/run/reify_newimpl_40.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 42 + def foo() = reify{ val y = x; reify{ val z = y * x; reify(z * x) } }; + { + val x = 2 + val code1 = foo() + val code2 = code1.eval + val code3 = code2.eval + println(code3.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_41.check b/test/files/run/reify_newimpl_41.check new file mode 100644 index 0000000000..0b427f2ee6 --- /dev/null +++ b/test/files/run/reify_newimpl_41.check @@ -0,0 +1,3 @@ +42 +44 +43 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_41.scala b/test/files/run/reify_newimpl_41.scala new file mode 100644 index 0000000000..9aedccc98a --- /dev/null +++ b/test/files/run/reify_newimpl_41.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var _x = 42 + def x = { val x0 = _x; _x += 1; x0 } + var _y = 1 + def y = { val y0 = _y + _x; _y += y0; y0 } + val code = reify { + def foo = y // ensures that y is the first freevar we find + println(x) + println(y) + println(x) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_42.check b/test/files/run/reify_newimpl_42.check new file mode 100644 index 0000000000..0b427f2ee6 --- /dev/null +++ b/test/files/run/reify_newimpl_42.check @@ -0,0 +1,3 @@ +42 +44 +43 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_42.scala b/test/files/run/reify_newimpl_42.scala new file mode 100644 index 0000000000..1e21bd59bc --- /dev/null +++ b/test/files/run/reify_newimpl_42.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var _x = 42 + def x = { val x0 = _x; _x += 1; x0 } + var _y = 1 + def y = { val y0 = _y + _x; _y += y0; y0 } + val code = reify { + println(x) + println(y) + println(x) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_43.check b/test/files/run/reify_newimpl_43.check new file mode 100644 index 0000000000..7a754f414c --- /dev/null +++ b/test/files/run/reify_newimpl_43.check @@ -0,0 +1,2 @@ +1 +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_43.scala b/test/files/run/reify_newimpl_43.scala new file mode 100644 index 0000000000..962461db8b --- /dev/null +++ b/test/files/run/reify_newimpl_43.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var counter = 0 + lazy val x = { counter += 1; counter } + lazy val y = { counter += 1; counter } + val code = reify { + def foo = y // ensures that y is the first freevar we find + println(x) + println(y) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_44.check b/test/files/run/reify_newimpl_44.check new file mode 100644 index 0000000000..7a754f414c --- /dev/null +++ b/test/files/run/reify_newimpl_44.check @@ -0,0 +1,2 @@ +1 +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_44.scala b/test/files/run/reify_newimpl_44.scala new file mode 100644 index 0000000000..962461db8b --- /dev/null +++ b/test/files/run/reify_newimpl_44.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var counter = 0 + lazy val x = { counter += 1; counter } + lazy val y = { counter += 1; counter } + val code = reify { + def foo = y // ensures that y is the first freevar we find + println(x) + println(y) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_45.check b/test/files/run/reify_newimpl_45.check new file mode 100644 index 0000000000..6e14f71e26 --- /dev/null +++ b/test/files/run/reify_newimpl_45.check @@ -0,0 +1,2 @@ +List(free type T) +ima worx: 2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_45.scala b/test/files/run/reify_newimpl_45.scala new file mode 100644 index 0000000000..241b7d4bc3 --- /dev/null +++ b/test/files/run/reify_newimpl_45.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[T >: Null] { + val code = reify{val x: T = "2".asInstanceOf[T]; println("ima worx: %s".format(x)); x} + println(freeTypes(code)) + val T = freeTypes(code)(0) + mkToolBox().runExpr(code, Map(T -> definitions.StringClass.asType)) + } + + new C[String] +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_47.check b/test/files/run/reify_newimpl_47.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_47.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_47.scala b/test/files/run/reify_newimpl_47.scala new file mode 100644 index 0000000000..bd1bd1fe65 --- /dev/null +++ b/test/files/run/reify_newimpl_47.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + val outer = { + val x = 2 + reify{x} + } + + val code = reify{ + val x = 42 + outer.eval + } + + println(code.eval) +} diff --git a/test/files/run/reify_newimpl_48.check b/test/files/run/reify_newimpl_48.check new file mode 100644 index 0000000000..f11c82a4cb --- /dev/null +++ b/test/files/run/reify_newimpl_48.check @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_48.scala b/test/files/run/reify_newimpl_48.scala new file mode 100644 index 0000000000..1522509907 --- /dev/null +++ b/test/files/run/reify_newimpl_48.scala @@ -0,0 +1,20 @@ +import scala.reflect.mirror._ + +object Test extends App { + val outer1 = { + val x = 2 + reify{x} + } + + val outer2 = { + val x = 3 + reify{x} + } + + val code = reify{ + val x = 4 + x + outer1.eval + outer2.eval + } + + println(code.eval) +} diff --git a/test/files/run/reify_newimpl_49.check b/test/files/run/reify_newimpl_49.check new file mode 100644 index 0000000000..d8a621df00 --- /dev/null +++ b/test/files/run/reify_newimpl_49.check @@ -0,0 +1,3 @@ +3 +3 +5 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_49.scala b/test/files/run/reify_newimpl_49.scala new file mode 100644 index 0000000000..68d968e28b --- /dev/null +++ b/test/files/run/reify_newimpl_49.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var y = 1 + def x = { y += 2; y } + val code = reify { + def foo = y // ensures that y is the first freevar we find + println(x) + println(y) + println(x) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_50.check b/test/files/run/reify_newimpl_50.check new file mode 100644 index 0000000000..d8a621df00 --- /dev/null +++ b/test/files/run/reify_newimpl_50.check @@ -0,0 +1,3 @@ +3 +3 +5 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_50.scala b/test/files/run/reify_newimpl_50.scala new file mode 100644 index 0000000000..b81d72a4eb --- /dev/null +++ b/test/files/run/reify_newimpl_50.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var y = 1 + def x = { y += 2; y } + val code = reify { + println(x) + println(y) + println(x) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_51.check b/test/files/run/reify_newimpl_51.check new file mode 100644 index 0000000000..9a4ddeacd3 --- /dev/null +++ b/test/files/run/reify_newimpl_51.check @@ -0,0 +1,3 @@ +2 +1 +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_51.scala b/test/files/run/reify_newimpl_51.scala new file mode 100644 index 0000000000..ccbae2e160 --- /dev/null +++ b/test/files/run/reify_newimpl_51.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var counter = 0 + lazy val x = { counter += 1; counter } + lazy val y = { counter += 1; counter } + val code = reify { + def foo = y // ensures that y is the first freevar we find + val bar = reify { println(x * y) } + bar.eval + println(x) + println(y) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_52.check b/test/files/run/reify_newimpl_52.check new file mode 100644 index 0000000000..9359a2b211 --- /dev/null +++ b/test/files/run/reify_newimpl_52.check @@ -0,0 +1,3 @@ +2 +2 +1 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_52.scala b/test/files/run/reify_newimpl_52.scala new file mode 100644 index 0000000000..60b16d3618 --- /dev/null +++ b/test/files/run/reify_newimpl_52.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var counter = 0 + lazy val x = { counter += 1; counter } + lazy val y = { counter += 1; counter } + val code = reify { + def foo = y // ensures that y is the first freevar we find + val bar = reify { println(y * x) } + bar.eval + println(x) + println(y) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_printf.scala b/test/files/run/reify_printf.scala index cd6052bc5e..dc092c1a85 100644 --- a/test/files/run/reify_printf.scala +++ b/test/files/run/reify_printf.scala @@ -1,19 +1,15 @@ import java.io.{ ByteArrayOutputStream, PrintStream } -import scala.reflect.Code import scala.reflect.mirror._ import scala.reflect.api._ import scala.reflect.api.Trees import scala.reflect.internal.Types -import reflect.runtime.Mirror.ToolBox -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings import scala.util.matching.Regex object Test extends App { - val tree = tree_printf(Code.lift("hello %s").tree, Code.lift("world").tree) + val tree = tree_printf(reify("hello %s").tree, reify("world").tree) - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter, args mkString " ") + import scala.reflect.mirror._ + val toolbox = mkToolBox() val output = new ByteArrayOutputStream() Console.setOut(new PrintStream(output)) @@ -22,6 +18,7 @@ object Test extends App { assert(output.toString() == "hello world", output.toString() +" == hello world") /* + // upd. Oh, good old times, our very-very first experiments with macros :) macro def printf(format: String, params: Any*) : String = tree_printf(format: Tree, (params: Seq[Tree]): _*) */ diff --git a/test/files/run/reify_sort.scala b/test/files/run/reify_sort.scala index 5984a64967..0b373b358f 100644 --- a/test/files/run/reify_sort.scala +++ b/test/files/run/reify_sort.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { /** Nested methods can use and even update everything * visible in their scope (including local variables or * arguments of enclosing methods). @@ -48,9 +46,5 @@ object Test extends App { println(ar) sort(ar) println(ar) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_sort1.scala b/test/files/run/reify_sort1.scala index 6f365dea26..56125619e9 100644 --- a/test/files/run/reify_sort1.scala +++ b/test/files/run/reify_sort1.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { def sort(a: List[Int]): List[Int] = { if (a.length < 2) a @@ -18,9 +16,5 @@ object Test extends App { val xs = List(6, 2, 8, 5, 1) println(xs) println(sort(xs)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_this.scala b/test/files/run/reify_this.scala index ee1f116013..280d735ab6 100644 --- a/test/files/run/reify_this.scala +++ b/test/files/run/reify_this.scala @@ -1,30 +1,19 @@ -import scala.reflect._ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ trait Eval { - def eval(code: Code): Any = eval(code.tree) - - def eval(tree: Tree): Any = { - val settings = new Settings - val reporter = new ConsoleReporter(settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(tree) - } + def eval(tree: Expr[_]) = tree.eval } object Test extends App with Eval { // select a value from package - eval(lift{println("foo")}) - eval(lift{println((new Object).toString == (new Object).toString)}) + eval(reify{println("foo")}) + eval(reify{println((new Object).toString == (new Object).toString)}) // select a type from package - eval(lift{val x: Any = 2; println(x)}) - eval(lift{val x: Object = "bar"; println(x)}) + eval(reify{val x: Any = 2; println(x)}) + eval(reify{val x: Object = "bar"; println(x)}) // select a value from module val x = 2 - eval(lift{println(x)}) + eval(reify{println(x)}) } diff --git a/test/files/run/reify_timeofday.scala b/test/files/run/reify_timeofday.scala index 122d7a6d52..481ab04df5 100644 --- a/test/files/run/reify_timeofday.scala +++ b/test/files/run/reify_timeofday.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class DateError extends Exception /** Simulating properties in Scala @@ -39,9 +37,5 @@ object Test extends App { case de: DateError => println("DateError") case e: Exception => println("Exception") } - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_typerefs_1a.check b/test/files/run/reify_typerefs_1a.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_1a.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_1a.scala b/test/files/run/reify_typerefs_1a.scala new file mode 100644 index 0000000000..15d8d17835 --- /dev/null +++ b/test/files/run/reify_typerefs_1a.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +class Expression { + override def toString = "Expression" +} + +object Test extends App { + val code = reify { + List(new Expression, new Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_typerefs_1b.check b/test/files/run/reify_typerefs_1b.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_1b.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_1b.scala b/test/files/run/reify_typerefs_1b.scala new file mode 100644 index 0000000000..06ce1e35ac --- /dev/null +++ b/test/files/run/reify_typerefs_1b.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Expression { + override def toString = "Expression" +} + +object Test extends App { + val code = reify { + List(Expression, Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_typerefs_2a.check b/test/files/run/reify_typerefs_2a.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_2a.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_2a.scala b/test/files/run/reify_typerefs_2a.scala new file mode 100644 index 0000000000..d03efea222 --- /dev/null +++ b/test/files/run/reify_typerefs_2a.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +package foo { + class Expression { + override def toString = "Expression" + } +} + +object Test extends App { + val code = reify { + List(new foo.Expression, new foo.Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_typerefs_2b.check b/test/files/run/reify_typerefs_2b.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_2b.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_2b.scala b/test/files/run/reify_typerefs_2b.scala new file mode 100644 index 0000000000..3d9f7d61b8 --- /dev/null +++ b/test/files/run/reify_typerefs_2b.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +package foo { + object Expression { + override def toString = "Expression" + } +} + +object Test extends App { + val code = reify { + List(foo.Expression, foo.Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_typerefs_3a.check b/test/files/run/reify_typerefs_3a.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_3a.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_3a.scala b/test/files/run/reify_typerefs_3a.scala new file mode 100644 index 0000000000..4128073f60 --- /dev/null +++ b/test/files/run/reify_typerefs_3a.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object foo { + class Expression { + override def toString = "Expression" + } +} + +object Test extends App { + val code = reify { + List(new foo.Expression, new foo.Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_typerefs_3b.check b/test/files/run/reify_typerefs_3b.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_3b.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_3b.scala b/test/files/run/reify_typerefs_3b.scala new file mode 100644 index 0000000000..a7ede00c9c --- /dev/null +++ b/test/files/run/reify_typerefs_3b.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object foo { + object Expression { + override def toString = "Expression" + } +} + +object Test extends App { + val code = reify { + List(foo.Expression, foo.Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_varargs.scala b/test/files/run/reify_varargs.scala index 175cfb5db0..fe8f03b702 100644 --- a/test/files/run/reify_varargs.scala +++ b/test/files/run/reify_varargs.scala @@ -1,16 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val msg = java.text.MessageFormat.format( "On {1} there was {2} on planet {0}.", "Hoth", "the fifth of August", "a disturbance in the Force") println("Message="+msg) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check index 1e7b6f0cd8..b811a4a8c5 100644 --- a/test/files/run/repl-power.check +++ b/test/files/run/repl-power.check @@ -1,32 +1,32 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> :power -** Power User mode enabled - BEEP WHIR GYVE ** -** :phase has been set to 'typer'. ** -** scala.tools.nsc._ has been imported ** -** global._, definitions._ also imported ** -** Try :help, :vals, power. ** - -scala> // guarding against "error: reference to global is ambiguous" - -scala> global.emptyValDef // "it is imported twice in the same scope by ..." -res0: $r.global.emptyValDef.type = private val _ = _ - -scala> val tp = ArrayClass[scala.util.Random] // magic with manifests -tp: $r.global.Type = Array[scala.util.Random] - -scala> tp.memberType(Array_apply) // evidence -res1: $r.global.Type = (i: Int)scala.util.Random - -scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl -m: $r.treedsl.global.Match = -10 match { - case 5 => false - case _ => true -} - -scala> typed(m).tpe // typed is in scope -res2: $r.treedsl.global.Type = Boolean - -scala> +Type in expressions to have them evaluated. +Type :help for more information. + +scala> :power +** Power User mode enabled - BEEP WHIR GYVE ** +** :phase has been set to 'typer'. ** +** scala.tools.nsc._ has been imported ** +** global._, definitions._ also imported ** +** Try :help, :vals, power. ** + +scala> // guarding against "error: reference to global is ambiguous" + +scala> global.emptyValDef // "it is imported twice in the same scope by ..." +res0: $r.global.emptyValDef.type = private val _ = _ + +scala> val tp = ArrayClass[scala.util.Random] // magic with manifests +tp: $r.global.Type = Array[scala.util.Random] + +scala> tp.memberType(Array_apply) // evidence +res1: $r.global.Type = (i: Int)scala.util.Random + +scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl +m: $r.treedsl.global.Match = +10 match { + case 5 => false + case _ => true +} + +scala> typed(m).tpe // typed is in scope +res2: $r.treedsl.global.Type = Boolean + +scala> diff --git a/test/files/run/t1195.check b/test/files/run/t1195.check deleted file mode 100644 index d023bc91f7..0000000000 --- a/test/files/run/t1195.check +++ /dev/null @@ -1,6 +0,0 @@ -_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with scala.Product with scala.Serializable -Object with scala.Product with scala.Serializable -_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with scala.Product with scala.Serializable -Object with scala.Product with scala.Serializable diff --git a/test/files/run/t1195.check.temporarily.disabled b/test/files/run/t1195.check.temporarily.disabled new file mode 100644 index 0000000000..d023bc91f7 --- /dev/null +++ b/test/files/run/t1195.check.temporarily.disabled @@ -0,0 +1,6 @@ +_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with scala.Product with scala.Serializable +Object with scala.Product with scala.Serializable +_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with scala.Product with scala.Serializable +Object with scala.Product with scala.Serializable diff --git a/test/files/run/t1195.scala b/test/files/run/t1195.scala deleted file mode 100644 index 81ef5bdb0e..0000000000 --- a/test/files/run/t1195.scala +++ /dev/null @@ -1,26 +0,0 @@ -object Test { - def f() = { case class Bar(x: Int); Bar } - def g() = { case class Bar(x: Int); Bar(5) } - def h() = { case object Bar ; Bar } - - val f1 = f() - val g1 = g() - val h1 = h() - - def m[T: Manifest](x: T) = println(manifest[T]) - - def main(args: Array[String]): Unit = { - m(f) - m(g) - m(h) - m(f1) - m(g1) - m(h1) - } -} - -class A1[T] { - class B1[U] { - def f = { case class D(x: Int) extends A1[String] ; new D(5) } - } -} diff --git a/test/files/run/t1195.scala.temporarily.disabled b/test/files/run/t1195.scala.temporarily.disabled new file mode 100644 index 0000000000..81ef5bdb0e --- /dev/null +++ b/test/files/run/t1195.scala.temporarily.disabled @@ -0,0 +1,26 @@ +object Test { + def f() = { case class Bar(x: Int); Bar } + def g() = { case class Bar(x: Int); Bar(5) } + def h() = { case object Bar ; Bar } + + val f1 = f() + val g1 = g() + val h1 = h() + + def m[T: Manifest](x: T) = println(manifest[T]) + + def main(args: Array[String]): Unit = { + m(f) + m(g) + m(h) + m(f1) + m(g1) + m(h1) + } +} + +class A1[T] { + class B1[U] { + def f = { case class D(x: Int) extends A1[String] ; new D(5) } + } +} diff --git a/test/files/run/t3758.check b/test/files/run/t3758.check new file mode 100644 index 0000000000..9c6ab655a3 --- /dev/null +++ b/test/files/run/t3758.check @@ -0,0 +1,6 @@ +List(String) +List(Int) +List(Float) +List(String) +List(Int) +List(Float) diff --git a/test/files/run/t3758.scala b/test/files/run/t3758.scala index 18750b0a9c..10bfb5724b 100644 --- a/test/files/run/t3758.scala +++ b/test/files/run/t3758.scala @@ -1,10 +1,10 @@ object Test { def main(args: Array[String]): Unit = { - assert(classManifest[Array[String]].typeArguments contains classManifest[String]) - assert(classManifest[Array[Int]].typeArguments contains classManifest[Int]) - assert(classManifest[Array[Float]].typeArguments contains classManifest[Float]) - assert(manifest[Array[String]].typeArguments contains manifest[String]) - assert(manifest[Array[Int]].typeArguments contains manifest[Int]) - assert(manifest[Array[Float]].typeArguments contains manifest[Float]) + println(classManifest[Array[String]].tpe.typeArguments) + println(classManifest[Array[Int]].tpe.typeArguments) + println(classManifest[Array[Float]].tpe.typeArguments) + println(manifest[Array[String]].tpe.typeArguments) + println(manifest[Array[Int]].tpe.typeArguments) + println(manifest[Array[Float]].tpe.typeArguments) } } diff --git a/test/files/run/t4110.check b/test/files/run/t4110.check deleted file mode 100644 index 8b005989de..0000000000 --- a/test/files/run/t4110.check +++ /dev/null @@ -1,2 +0,0 @@ -Object with Test$A with Test$B -Object with Test$A with Test$B diff --git a/test/files/run/t4110.check.temporarily.disabled b/test/files/run/t4110.check.temporarily.disabled new file mode 100644 index 0000000000..8b005989de --- /dev/null +++ b/test/files/run/t4110.check.temporarily.disabled @@ -0,0 +1,2 @@ +Object with Test$A with Test$B +Object with Test$A with Test$B diff --git a/test/files/run/t4110.scala b/test/files/run/t4110.scala deleted file mode 100644 index 4bd377b73e..0000000000 --- a/test/files/run/t4110.scala +++ /dev/null @@ -1,11 +0,0 @@ -object Test extends App { - def inferredType[T : Manifest](v : T) = println(manifest[T]) - - trait A - trait B - - inferredType(new A with B) - - val name = new A with B - inferredType(name) -} \ No newline at end of file diff --git a/test/files/run/t4110.scala.temporarily.disabled b/test/files/run/t4110.scala.temporarily.disabled new file mode 100644 index 0000000000..4bd377b73e --- /dev/null +++ b/test/files/run/t4110.scala.temporarily.disabled @@ -0,0 +1,11 @@ +object Test extends App { + def inferredType[T : Manifest](v : T) = println(manifest[T]) + + trait A + trait B + + inferredType(new A with B) + + val name = new A with B + inferredType(name) +} \ No newline at end of file diff --git a/test/files/run/t5224.check b/test/files/run/t5224.check index 28bc75d4fd..c754f23551 100644 --- a/test/files/run/t5224.check +++ b/test/files/run/t5224.check @@ -1,9 +1,9 @@ -{ - @new Foo(bar = "qwe") class C extends scala.AnyRef { - def () = { - super.(); - () - } - }; - () -} +{ + @new Foo(bar = "qwe") class C extends Object { + def () = { + super.(); + () + } + }; + () +} diff --git a/test/files/run/t5224.scala b/test/files/run/t5224.scala index 2226a69a05..93b244e03e 100644 --- a/test/files/run/t5224.scala +++ b/test/files/run/t5224.scala @@ -1,9 +1,8 @@ -import scala.reflect._ -import scala.reflect.api._ +import scala.reflect.mirror._ class Foo(bar: String) extends ClassfileAnnotation object Test extends App { - val tree = scala.reflect.Code.lift{@Foo(bar = "qwe") class C}.tree + val tree = reify{@Foo(bar = "qwe") class C}.tree println(tree.toString) } \ No newline at end of file diff --git a/test/files/run/t5225_1.check b/test/files/run/t5225_1.check index 719da572c7..40db2468b1 100644 --- a/test/files/run/t5225_1.check +++ b/test/files/run/t5225_1.check @@ -1,4 +1,4 @@ -{ - @new transient() @new volatile() var x: Int = 2; - () -} +{ + @new transient() @new volatile() var x = 2; + () +} diff --git a/test/files/run/t5225_1.scala b/test/files/run/t5225_1.scala index a655b7dd71..5e1d3b1f17 100644 --- a/test/files/run/t5225_1.scala +++ b/test/files/run/t5225_1.scala @@ -1,7 +1,6 @@ -import scala.reflect._ -import scala.reflect.api._ +import scala.reflect.mirror._ object Test extends App { - val tree = scala.reflect.Code.lift{@transient @volatile var x = 2}.tree + val tree = reify{@transient @volatile var x = 2}.tree println(tree.toString) } \ No newline at end of file diff --git a/test/files/run/t5225_2.check b/test/files/run/t5225_2.check index c4f6b4761e..8cd2ddc1a4 100644 --- a/test/files/run/t5225_2.check +++ b/test/files/run/t5225_2.check @@ -1,4 +1,4 @@ -{ - def foo(@new cloneable() x: Int): String = ""; - () -} +{ + def foo(@new cloneable() x: Int) = ""; + () +} diff --git a/test/files/run/t5225_2.scala b/test/files/run/t5225_2.scala index 65ea9b2f73..4cab640fe8 100644 --- a/test/files/run/t5225_2.scala +++ b/test/files/run/t5225_2.scala @@ -1,7 +1,6 @@ -import scala.reflect._ -import scala.reflect.api._ +import scala.reflect.mirror._ object Test extends App { - val tree = scala.reflect.Code.lift{def foo(@cloneable x: Int) = ""}.tree + val tree = reify{def foo(@cloneable x: Int) = ""}.tree println(tree.toString) } \ No newline at end of file diff --git a/test/files/run/t5229_1.scala b/test/files/run/t5229_1.scala index d5af569656..273079a89d 100644 --- a/test/files/run/t5229_1.scala +++ b/test/files/run/t5229_1.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object C - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5229_2.scala b/test/files/run/t5229_2.scala index 07f9ac6b84..85bf78ba31 100644 --- a/test/files/run/t5229_2.scala +++ b/test/files/run/t5229_2.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { object C { val x = 2 } @@ -11,8 +9,7 @@ object Test extends App { println(C.x) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val evaluated = toolbox.runExpr(code.tree) println("evaluated = " + evaluated) } diff --git a/test/files/run/t5230.scala b/test/files/run/t5230.scala index d3106ca05c..e0632f591c 100644 --- a/test/files/run/t5230.scala +++ b/test/files/run/t5230.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { class C { val x = 2 } @@ -11,8 +9,7 @@ object Test extends App { println(new C().x) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val evaluated = toolbox.runExpr(code.tree) println("evaluated = " + evaluated) } diff --git a/test/files/run/t5258a.check b/test/files/run/t5258a.check deleted file mode 100644 index 4e0b2da04c..0000000000 --- a/test/files/run/t5258a.check +++ /dev/null @@ -1 +0,0 @@ -int \ No newline at end of file diff --git a/test/files/run/t5258a.scala b/test/files/run/t5258a.scala deleted file mode 100644 index 8cc4249e06..0000000000 --- a/test/files/run/t5258a.scala +++ /dev/null @@ -1,13 +0,0 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - val code = scala.reflect.Code.lift{ - println(classOf[Int]) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) -} \ No newline at end of file diff --git a/test/files/run/t5266_1.scala b/test/files/run/t5266_1.scala index 4262bc7a7b..ebb432be71 100644 --- a/test/files/run/t5266_1.scala +++ b/test/files/run/t5266_1.scala @@ -1,15 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { def x = 2 println(x) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val evaluated = toolbox.runExpr(code.tree) println("evaluated = " + evaluated) } \ No newline at end of file diff --git a/test/files/run/t5266_2.scala b/test/files/run/t5266_2.scala index d0f718dbd7..27c91c35a8 100644 --- a/test/files/run/t5266_2.scala +++ b/test/files/run/t5266_2.scala @@ -1,16 +1,13 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { def x = 2 def y = x println(y) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val evaluated = toolbox.runExpr(code.tree) println("evaluated = " + evaluated) } diff --git a/test/files/run/t5269.scala b/test/files/run/t5269.scala index cab99f17e6..9026090b29 100644 --- a/test/files/run/t5269.scala +++ b/test/files/run/t5269.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { trait Z { val z = 2 } @@ -13,9 +11,5 @@ object Test extends App { } new X().println() - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5270.scala b/test/files/run/t5270.scala index 934cc13dea..476b610148 100644 --- a/test/files/run/t5270.scala +++ b/test/files/run/t5270.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class Y { def y = 100 } @@ -17,9 +15,5 @@ object Test extends App { } new X().println() - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5271_1.check b/test/files/run/t5271_1.check index 9b956da17a..7a728e5164 100644 --- a/test/files/run/t5271_1.check +++ b/test/files/run/t5271_1.check @@ -1,11 +1,11 @@ -{ - case class C extends Object with Product with Serializable { - val foo : Int = _; - val bar : Int = _; - def (foo: Int, bar: Int) = { - super.(); - () - } - }; - () -} +{ + case class C extends Product with Serializable { + val foo: Int = _; + val bar: Int = _; + def (foo: Int, bar: Int) = { + super.(); + () + } + }; + () +} diff --git a/test/files/run/t5271_1.scala b/test/files/run/t5271_1.scala index fbc57aead7..5baa57c290 100644 --- a/test/files/run/t5271_1.scala +++ b/test/files/run/t5271_1.scala @@ -1,13 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { case class C(foo: Int, bar: Int) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(code.tree) } diff --git a/test/files/run/t5271_2.check b/test/files/run/t5271_2.check index 27297febb6..d8d6edeffc 100644 --- a/test/files/run/t5271_2.check +++ b/test/files/run/t5271_2.check @@ -1,12 +1,12 @@ -{ - case class C extends Object with Product with Serializable { - val foo : Int = _; - val bar : Int = _; - def (foo: Int, bar: Int) = { - super.(); - () - } - }; - val c = C.apply(2, 2); - scala.this.Predef.println(c.foo.$times(c.bar)) -} +{ + case class C extends Product with Serializable { + val foo: Int = _; + val bar: Int = _; + def (foo: Int, bar: Int) = { + super.(); + () + } + }; + val c = C.apply(2, 2); + scala.this.Predef.println(c.foo.$times(c.bar)) +} diff --git a/test/files/run/t5271_2.scala b/test/files/run/t5271_2.scala index 4bfc574e00..9820ebe692 100644 --- a/test/files/run/t5271_2.scala +++ b/test/files/run/t5271_2.scala @@ -1,15 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { case class C(foo: Int, bar: Int) val c = C(2, 2) println(c.foo * c.bar) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(code.tree) } diff --git a/test/files/run/t5271_3.check b/test/files/run/t5271_3.check index 9331c78959..1d4f47c5df 100644 --- a/test/files/run/t5271_3.check +++ b/test/files/run/t5271_3.check @@ -1,19 +1,19 @@ -{ - object C extends scala.AnyRef with Serializable { - def () = { - super.(); - () - }; - def qwe: Int = 4 - }; - case class C extends Object with Product with Serializable { - val foo : Int = _; - val bar : Int = _; - def (foo: Int, bar: Int) = { - super.(); - () - } - }; - val c = C.apply(2, 2); - scala.this.Predef.println(c.foo.$times(c.bar).$eq$eq(C.qwe)) -} +{ + object C extends Object { + def () = { + super.(); + () + }; + def qwe = 4 + }; + case class C extends Product with Serializable { + val foo: Int = _; + val bar: Int = _; + def (foo: Int, bar: Int) = { + super.(); + () + } + }; + val c = C.apply(2, 2); + scala.this.Predef.println(c.foo.$times(c.bar).$eq$eq(C.qwe)) +} diff --git a/test/files/run/t5271_3.scala b/test/files/run/t5271_3.scala index a085bdca4c..5fd94f4a2b 100644 --- a/test/files/run/t5271_3.scala +++ b/test/files/run/t5271_3.scala @@ -1,16 +1,13 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { object C { def qwe = 4 } case class C(foo: Int, bar: Int) val c = C(2, 2) println(c.foo * c.bar == C.qwe) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(code.tree) } diff --git a/test/files/run/t5271_4.scala b/test/files/run/t5271_4.scala index c253b1adca..e13a331d9c 100644 --- a/test/files/run/t5271_4.scala +++ b/test/files/run/t5271_4.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { case object C - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5272_1.scala b/test/files/run/t5272_1.scala index 882287f033..46472babf3 100644 --- a/test/files/run/t5272_1.scala +++ b/test/files/run/t5272_1.scala @@ -1,16 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { 2 match { case 2 => println("okay") case _ => println("not okay") } - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5272_2.scala b/test/files/run/t5272_2.scala index 48b6a670bb..f5bab44205 100644 --- a/test/files/run/t5272_2.scala +++ b/test/files/run/t5272_2.scala @@ -1,15 +1,9 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { 2 match { case x => println("okay" + x) } - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5273_1.scala b/test/files/run/t5273_1.scala index 80460a4ae6..1b491923b2 100644 --- a/test/files/run/t5273_1.scala +++ b/test/files/run/t5273_1.scala @@ -1,16 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { List(1, 2, 3) match { case foo :: bar :: _ => println(foo * bar) case _ => println("this is getting out of hand!") } - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5273_2a.scala b/test/files/run/t5273_2a.scala index a7a336d8a7..062ff79d11 100644 --- a/test/files/run/t5273_2a.scala +++ b/test/files/run/t5273_2a.scala @@ -1,14 +1,8 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val foo :: bar :: _ = List(1, 2, 3) println(foo * bar) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5273_2b.scala b/test/files/run/t5273_2b.scala index 85c40f0607..82f1de89f7 100644 --- a/test/files/run/t5273_2b.scala +++ b/test/files/run/t5273_2b.scala @@ -1,15 +1,9 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val RegexParser = """(.*) \d+([A-Z]+) \| (.*) \|.*""".r val RegexParser(name, shortname, value) = "American Dollar 1USD | 2,8567 | sometext" println("name = %s, shortname = %s, value = %s".format(name, shortname, value)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5274_1.scala b/test/files/run/t5274_1.scala index 74a5b81bcb..7ef332aa05 100644 --- a/test/files/run/t5274_1.scala +++ b/test/files/run/t5274_1.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { def factorial(n: BigInt): BigInt = if (n == 0) 1 else n * factorial(n-1) @@ -11,9 +9,5 @@ object Test extends App { println("50! = " + f50) println("49! = " + f49) println("50!/49! = " + (f50 / f49)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5274_2.scala b/test/files/run/t5274_2.scala index 5984a64967..0b373b358f 100644 --- a/test/files/run/t5274_2.scala +++ b/test/files/run/t5274_2.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { /** Nested methods can use and even update everything * visible in their scope (including local variables or * arguments of enclosing methods). @@ -48,9 +46,5 @@ object Test extends App { println(ar) sort(ar) println(ar) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5275.scala b/test/files/run/t5275.scala index 285d8a18a4..534672be3c 100644 --- a/test/files/run/t5275.scala +++ b/test/files/run/t5275.scala @@ -1,14 +1,8 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C(val foo: Int) println(new C(2).foo) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5276_1a.scala b/test/files/run/t5276_1a.scala index b717675824..a6e327c0e7 100644 --- a/test/files/run/t5276_1a.scala +++ b/test/files/run/t5276_1a.scala @@ -1,14 +1,8 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { lazy val x = 2 println(x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5276_1b.scala b/test/files/run/t5276_1b.scala index 1ff25504ca..1bc3e246c9 100644 --- a/test/files/run/t5276_1b.scala +++ b/test/files/run/t5276_1b.scala @@ -1,14 +1,8 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { implicit lazy val x = 2 println(implicitly[Int]) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5276_2a.scala b/test/files/run/t5276_2a.scala index af5ff2a565..cdd87ddc9e 100644 --- a/test/files/run/t5276_2a.scala +++ b/test/files/run/t5276_2a.scala @@ -1,17 +1,11 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C { lazy val x = 2 } println(new C().x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5276_2b.scala b/test/files/run/t5276_2b.scala index 63904b2898..2fac951731 100644 --- a/test/files/run/t5276_2b.scala +++ b/test/files/run/t5276_2b.scala @@ -1,18 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C { implicit lazy val x = 2 def y = implicitly[Int] } println(new C().y) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5277_1.scala b/test/files/run/t5277_1.scala index 0aaec7cdf2..f95e9ab6ec 100644 --- a/test/files/run/t5277_1.scala +++ b/test/files/run/t5277_1.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { def fact(n: Int): BigInt = if (n == 0) 1 else fact(n-1) * n class Factorizer(n: Int) { @@ -12,9 +10,5 @@ object Test extends App { implicit def int2fact(n: Int) = new Factorizer(n) println("10! = " + (10!)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5277_2.scala b/test/files/run/t5277_2.scala index 91ed55122a..5f1737f503 100644 --- a/test/files/run/t5277_2.scala +++ b/test/files/run/t5277_2.scala @@ -1,17 +1,11 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { def p(implicit i: Int) = print(i) implicit val v = 2 println(p) println(p(1)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5279.scala b/test/files/run/t5279.scala index cef58535d5..aab5588877 100644 --- a/test/files/run/t5279.scala +++ b/test/files/run/t5279.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { println(new Integer(10)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5334_1.scala b/test/files/run/t5334_1.scala index 9887bebf78..49dbea6b68 100644 --- a/test/files/run/t5334_1.scala +++ b/test/files/run/t5334_1.scala @@ -1,14 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { class C { override def toString = "C" } - new C + val ret = new C + ret.asInstanceOf[Object] }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(toolbox.runExpr(code.tree)) } diff --git a/test/files/run/t5334_2.scala b/test/files/run/t5334_2.scala index 775a05aaf7..c6a77158dd 100644 --- a/test/files/run/t5334_2.scala +++ b/test/files/run/t5334_2.scala @@ -1,14 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { class C { override def toString() = "C" } - List((new C, new C)) + val ret = List((new C, new C)) + ret.asInstanceOf[List[Any]] }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(toolbox.runExpr(code.tree)) } diff --git a/test/files/run/t5335.scala b/test/files/run/t5335.scala index 8e2ed59db6..a0fe6c5822 100644 --- a/test/files/run/t5335.scala +++ b/test/files/run/t5335.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { println(new {def x = 2}.x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5415.scala b/test/files/run/t5415.scala index 3db356da86..c6552f69b3 100644 --- a/test/files/run/t5415.scala +++ b/test/files/run/t5415.scala @@ -1,14 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import scala.reflect.runtime.Mirror.ToolBox - object Test extends App{ case class Queryable2[T]() { def filter(predicate: T => Boolean) = ??? } trait CoffeesTable{ def sales : Int } val q = Queryable2[CoffeesTable]() - val code = scala.reflect.Code.lift{q.filter(_.sales > 5)} + import scala.reflect.mirror._ + val code = reify{q.filter(_.sales > 5)} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val ttree = toolbox.typeCheck(code.tree) } diff --git a/test/files/run/t5419.check b/test/files/run/t5419.check index 7e6d739354..50751b168e 100644 --- a/test/files/run/t5419.check +++ b/test/files/run/t5419.check @@ -1 +1 @@ -(5: Int(5) @Foo) +5: @Foo.asInstanceOf[Int] diff --git a/test/files/run/t5419.scala b/test/files/run/t5419.scala index 695786e5c4..d65d8f38c8 100644 --- a/test/files/run/t5419.scala +++ b/test/files/run/t5419.scala @@ -1,9 +1,8 @@ -import scala.reflect._ -import scala.reflect.api._ +import scala.reflect.mirror._ class Foo extends StaticAnnotation object Test extends App { - val tree = scala.reflect.Code.lift{5: @Foo}.tree + val tree = reify{(5: @Foo).asInstanceOf[Int]}.tree println(tree.toString) } \ No newline at end of file diff --git a/test/files/run/t5423.scala b/test/files/run/t5423.scala index fc507c417b..645c8c7c1d 100644 --- a/test/files/run/t5423.scala +++ b/test/files/run/t5423.scala @@ -1,7 +1,4 @@ -import java.lang.Class import scala.reflect.mirror._ -import scala.reflect.runtime.Mirror.ToolBox -import scala.reflect.Code final class table extends StaticAnnotation @table class A diff --git a/test/files/run/toolbox_console_reporter.check b/test/files/run/toolbox_console_reporter.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/toolbox_console_reporter.scala b/test/files/run/toolbox_console_reporter.scala new file mode 100644 index 0000000000..fd244b40ec --- /dev/null +++ b/test/files/run/toolbox_console_reporter.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + // todo. cannot test this unfortunately, because ConsoleReporter grabs Console.out too early + // todo. and isn't affected by Console.setOut employed by partest to intercept output + + //val toolbox = mkToolBox(reporter = mkConsoleReporter(), options = "-deprecation") + //toolbox.runExpr(reify{ + // object Utils { + // @deprecated("test", "2.10.0") + // def foo { println("hello") } + // } + // + // Utils.foo + //}) +} diff --git a/test/files/run/toolbox_default_reporter_is_silent.check b/test/files/run/toolbox_default_reporter_is_silent.check new file mode 100644 index 0000000000..ef0493b275 --- /dev/null +++ b/test/files/run/toolbox_default_reporter_is_silent.check @@ -0,0 +1 @@ +hello diff --git a/test/files/run/toolbox_default_reporter_is_silent.scala b/test/files/run/toolbox_default_reporter_is_silent.scala new file mode 100644 index 0000000000..78606e2abc --- /dev/null +++ b/test/files/run/toolbox_default_reporter_is_silent.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + val toolbox = mkToolBox() + toolbox.runExpr(reify{ + object Utils { + @deprecated("test", "2.10.0") + def foo { println("hello") } + } + + Utils.foo + }) +} diff --git a/test/files/run/toolbox_silent_reporter.check b/test/files/run/toolbox_silent_reporter.check new file mode 100644 index 0000000000..2d05b1e3f8 --- /dev/null +++ b/test/files/run/toolbox_silent_reporter.check @@ -0,0 +1,4 @@ +hello +============compiler messages============ +Info(NoPosition,method foo in object Utils is deprecated: test,WARNING) +========================================= diff --git a/test/files/run/toolbox_silent_reporter.scala b/test/files/run/toolbox_silent_reporter.scala new file mode 100644 index 0000000000..7e9259946b --- /dev/null +++ b/test/files/run/toolbox_silent_reporter.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + val toolbox = mkToolBox(options = "-deprecation") + toolbox.runExpr(reify{ + object Utils { + @deprecated("test", "2.10.0") + def foo { println("hello") } + } + + Utils.foo + }) + println("============compiler messages============") + toolbox.reporter.infos.foreach(println(_)) + println("=========================================") +} \ No newline at end of file diff --git a/test/files/run/toolbox_typecheck_implicitsdisabled.check b/test/files/run/toolbox_typecheck_implicitsdisabled.check new file mode 100644 index 0000000000..4bc64530ab --- /dev/null +++ b/test/files/run/toolbox_typecheck_implicitsdisabled.check @@ -0,0 +1,5 @@ +{ + import scala.Predef._; + scala.Predef.any2ArrowAssoc[Int](1).->[Int](2) +} +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective typecheck has failed: value -> is not a member of Int diff --git a/test/files/run/toolbox_typecheck_implicitsdisabled.scala b/test/files/run/toolbox_typecheck_implicitsdisabled.scala new file mode 100644 index 0000000000..9d52e91f73 --- /dev/null +++ b/test/files/run/toolbox_typecheck_implicitsdisabled.scala @@ -0,0 +1,24 @@ +import scala.reflect.mirror._ + +object Test extends App { + val toolbox = mkToolBox() + + val tree1 = Block( + Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1))), + Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2)))) + ) + val ttree1 = toolbox.typeCheck(tree1, withImplicitViewsDisabled = false) + println(ttree1) + + try { + val tree2 = Block( + Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1))), + Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2)))) + ) + val ttree2 = toolbox.typeCheck(tree2, withImplicitViewsDisabled = true) + println(ttree2) + } catch { + case ex: Throwable => + println(ex) + } +} \ No newline at end of file diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.check b/test/files/run/toolbox_typecheck_macrosdisabled.check new file mode 100644 index 0000000000..fe2323ea06 --- /dev/null +++ b/test/files/run/toolbox_typecheck_macrosdisabled.check @@ -0,0 +1,5 @@ +{ + val $mr: mr.type = mr; + $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.GroundTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) +} +mr.reify[Int](2) diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.scala b/test/files/run/toolbox_typecheck_macrosdisabled.scala new file mode 100644 index 0000000000..7d2707d5e1 --- /dev/null +++ b/test/files/run/toolbox_typecheck_macrosdisabled.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object Test extends App { + val toolbox = mkToolBox() + val mrPkg = staticModule("scala.reflect.package") + val mrSym = selectTerm(mrPkg, "mirror") + val NullaryMethodType(mrTpe) = mrSym.typeSignature + val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror, null) + + val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) + val ttree1 = toolbox.typeCheck(tree1, withMacrosDisabled = false) + println(ttree1) + + val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) + val ttree2 = toolbox.typeCheck(tree2, withMacrosDisabled = true) + println(ttree2) +} diff --git a/test/files/run/treePrint.check b/test/files/run/treePrint.check deleted file mode 100644 index 3360815ac1..0000000000 --- a/test/files/run/treePrint.check +++ /dev/null @@ -1,5 +0,0 @@ -def foo = { - var q: Boolean = false; - val x = 5; - ((x == 5) || (!q)) || (true) -} diff --git a/test/files/run/treePrint.check.temporarily.disabled b/test/files/run/treePrint.check.temporarily.disabled new file mode 100644 index 0000000000..3360815ac1 --- /dev/null +++ b/test/files/run/treePrint.check.temporarily.disabled @@ -0,0 +1,5 @@ +def foo = { + var q: Boolean = false; + val x = 5; + ((x == 5) || (!q)) || (true) +} diff --git a/test/files/run/treePrint.scala b/test/files/run/treePrint.scala deleted file mode 100644 index e0332a705f..0000000000 --- a/test/files/run/treePrint.scala +++ /dev/null @@ -1,42 +0,0 @@ -/** Testing compact tree printers. - */ -object Test { - import scala.tools.nsc._ - import interpreter._ - import java.io.{ OutputStream, BufferedReader, StringReader, PrintWriter, Writer, OutputStreamWriter} - - val code = """ - def foo = { - var q: Boolean = false - val x = if (true) { - if (true) { - if (true) { - 5 - } - else if (true) { - 5 - } else { - 10 - } - } - else 20 - } - else 30 - - (x == 5) || !q || true - } - """ - - class NullOutputStream extends OutputStream { def write(b: Int) { } } - - def main(args: Array[String]) { - val settings = new Settings - settings.classpath.value = System.getProperty("java.class.path") - settings.Ycompacttrees.value = true - - val intp = new IMain(settings, new PrintWriter(new NullOutputStream)) - val power = new Power(intp, new ReplVals { }) - intp.interpret("""def initialize = "Have to interpret something or we get errors." """) - power trees code foreach println - } -} diff --git a/test/files/run/treePrint.scala.temporarily.disabled b/test/files/run/treePrint.scala.temporarily.disabled new file mode 100644 index 0000000000..e0332a705f --- /dev/null +++ b/test/files/run/treePrint.scala.temporarily.disabled @@ -0,0 +1,42 @@ +/** Testing compact tree printers. + */ +object Test { + import scala.tools.nsc._ + import interpreter._ + import java.io.{ OutputStream, BufferedReader, StringReader, PrintWriter, Writer, OutputStreamWriter} + + val code = """ + def foo = { + var q: Boolean = false + val x = if (true) { + if (true) { + if (true) { + 5 + } + else if (true) { + 5 + } else { + 10 + } + } + else 20 + } + else 30 + + (x == 5) || !q || true + } + """ + + class NullOutputStream extends OutputStream { def write(b: Int) { } } + + def main(args: Array[String]) { + val settings = new Settings + settings.classpath.value = System.getProperty("java.class.path") + settings.Ycompacttrees.value = true + + val intp = new IMain(settings, new PrintWriter(new NullOutputStream)) + val power = new Power(intp, new ReplVals { }) + intp.interpret("""def initialize = "Have to interpret something or we get errors." """) + power trees code foreach println + } +} diff --git a/test/files/run/typetags_core.check b/test/files/run/typetags_core.check new file mode 100644 index 0000000000..d1b71f0926 --- /dev/null +++ b/test/files/run/typetags_core.check @@ -0,0 +1,30 @@ +true +GroundTypeTag[Byte] +true +GroundTypeTag[Short] +true +GroundTypeTag[Char] +true +GroundTypeTag[Int] +true +GroundTypeTag[Long] +true +GroundTypeTag[Float] +true +GroundTypeTag[Double] +true +GroundTypeTag[Boolean] +true +GroundTypeTag[Unit] +true +GroundTypeTag[Any] +true +GroundTypeTag[Object] +true +GroundTypeTag[AnyVal] +true +GroundTypeTag[AnyRef] +true +GroundTypeTag[Null] +true +GroundTypeTag[Nothing] diff --git a/test/files/run/typetags_core.scala b/test/files/run/typetags_core.scala new file mode 100644 index 0000000000..883c54b9a8 --- /dev/null +++ b/test/files/run/typetags_core.scala @@ -0,0 +1,32 @@ +object Test extends App { + println(implicitly[TypeTag[Byte]] eq TypeTag.Byte) + println(implicitly[TypeTag[Byte]]) + println(implicitly[TypeTag[Short]] eq TypeTag.Short) + println(implicitly[TypeTag[Short]]) + println(implicitly[TypeTag[Char]] eq TypeTag.Char) + println(implicitly[TypeTag[Char]]) + println(implicitly[TypeTag[Int]] eq TypeTag.Int) + println(implicitly[TypeTag[Int]]) + println(implicitly[TypeTag[Long]] eq TypeTag.Long) + println(implicitly[TypeTag[Long]]) + println(implicitly[TypeTag[Float]] eq TypeTag.Float) + println(implicitly[TypeTag[Float]]) + println(implicitly[TypeTag[Double]] eq TypeTag.Double) + println(implicitly[TypeTag[Double]]) + println(implicitly[TypeTag[Boolean]] eq TypeTag.Boolean) + println(implicitly[TypeTag[Boolean]]) + println(implicitly[TypeTag[Unit]] eq TypeTag.Unit) + println(implicitly[TypeTag[Unit]]) + println(implicitly[TypeTag[Any]] eq TypeTag.Any) + println(implicitly[TypeTag[Any]]) + println(implicitly[TypeTag[Object]] eq TypeTag.Object) + println(implicitly[TypeTag[Object]]) + println(implicitly[TypeTag[AnyVal]] eq TypeTag.AnyVal) + println(implicitly[TypeTag[AnyVal]]) + println(implicitly[TypeTag[AnyRef]] eq TypeTag.AnyRef) + println(implicitly[TypeTag[AnyRef]]) + println(implicitly[TypeTag[Null]] eq TypeTag.Null) + println(implicitly[TypeTag[Null]]) + println(implicitly[TypeTag[Nothing]] eq TypeTag.Nothing) + println(implicitly[TypeTag[Nothing]]) +} \ No newline at end of file diff --git a/test/pending/neg/reify_packed.check b/test/pending/neg/reify_packed.check new file mode 100644 index 0000000000..adba330d56 --- /dev/null +++ b/test/pending/neg/reify_packed.check @@ -0,0 +1,4 @@ +reify_packed.scala:6: error: implementation restriction: cannot reify block of type List[_$1] that involves a type declared inside the block being reified. consider casting the return value to a suitable type. + reify { + ^ +one error found diff --git a/test/pending/neg/reify_packed.scala b/test/pending/neg/reify_packed.scala new file mode 100644 index 0000000000..0240f2a4b5 --- /dev/null +++ b/test/pending/neg/reify_packed.scala @@ -0,0 +1,10 @@ +object Test extends App { + reify { + class C { override def toString() = "C" } + val ret = List((new C, new C)) + ret.asInstanceOf[List[_]] + }; + + val toolbox = mkToolBox() + println(toolbox.runExpr(code.tree)) +} diff --git a/test/pending/run/macro-expand-default.flags b/test/pending/run/macro-expand-default.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-default.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-expand-default/Impls_1.scala b/test/pending/run/macro-expand-default/Impls_1.scala new file mode 100644 index 0000000000..fefe8fc4e2 --- /dev/null +++ b/test/pending/run/macro-expand-default/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = { + import c.mirror._ + val sum = Apply(Select(x.tree, newTermName("$minus")), List(y.tree)) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum)) + Expr[Unit](body) + } +} diff --git a/test/pending/run/macro-expand-default/Macros_Test_2.scala b/test/pending/run/macro-expand-default/Macros_Test_2.scala new file mode 100644 index 0000000000..92fe84d04a --- /dev/null +++ b/test/pending/run/macro-expand-default/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Test extends App { + def foo(x: Int = 2, y: Int = -40) = macro Impls.foo + foo(y = -40, x = 2) + foo(x = 2, y = -40) + foo(x = 100) + foo(y = 100) + foo() +} \ No newline at end of file diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound.check b/test/pending/run/macro-expand-implicit-macro-has-context-bound.check new file mode 100644 index 0000000000..ac4213d6e9 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound.check @@ -0,0 +1 @@ +43 \ No newline at end of file diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound.flags b/test/pending/run/macro-expand-implicit-macro-has-context-bound.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala new file mode 100644 index 0000000000..5c50576281 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U](c: Ctx)(x: c.Expr[U])(evidence: c.Expr[Numeric[U]]) = { + import c.mirror._ + val plusOne = Apply(Select(evidence.tree, newTermName("plus")), List(x.tree, Literal(Constant(1)))) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(plusOne)) + Expr[Unit](body) + } +} diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala new file mode 100644 index 0000000000..7d16b773a6 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[U: Numeric](x: U) = macro Impls.foo[U] + foo(42) +} \ No newline at end of file diff --git a/test/pending/run/macro-expand-named.flags b/test/pending/run/macro-expand-named.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-named.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-expand-named/Impls_1.scala b/test/pending/run/macro-expand-named/Impls_1.scala new file mode 100644 index 0000000000..fefe8fc4e2 --- /dev/null +++ b/test/pending/run/macro-expand-named/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = { + import c.mirror._ + val sum = Apply(Select(x.tree, newTermName("$minus")), List(y.tree)) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum)) + Expr[Unit](body) + } +} diff --git a/test/pending/run/macro-expand-named/Macros_Test_2.scala b/test/pending/run/macro-expand-named/Macros_Test_2.scala new file mode 100644 index 0000000000..abebcf8448 --- /dev/null +++ b/test/pending/run/macro-expand-named/Macros_Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + def foo(x: Int, y: Int) = macro Impls.foo + foo(y = -40, x = 2) + foo(x = 2, y = -40) +} \ No newline at end of file diff --git a/test/pending/run/macro-expand-tparams-prefix-e1.check b/test/pending/run/macro-expand-tparams-prefix-e1.check new file mode 100644 index 0000000000..4fa05a7678 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-e1.check @@ -0,0 +1,3 @@ +TypeTag(List[Int]) +TypeTag(String) +TypeTag(Boolean) diff --git a/test/pending/run/macro-expand-tparams-prefix-e1.flags b/test/pending/run/macro-expand-tparams-prefix-e1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-e1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala b/test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala new file mode 100644 index 0000000000..bc880fdf77 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + Block(List( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(()))) + } +} diff --git a/test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala b/test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala new file mode 100644 index 0000000000..5c863804d0 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + class D[T: TypeTag] { + class C[U: TypeTag] { + def foo[V] = macro Impls.foo[List[T], U, V] + foo[Boolean] + } + } + + val outer1 = new D[Int] + new outer1.C[String] +} \ No newline at end of file diff --git a/test/pending/run/macro-expand-tparams-prefix-f1.check b/test/pending/run/macro-expand-tparams-prefix-f1.check new file mode 100644 index 0000000000..d15226143a --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-f1.check @@ -0,0 +1,3 @@ +TypeTag(List[T]) +TypeTag(U) +TypeTag(Boolean) diff --git a/test/pending/run/macro-expand-tparams-prefix-f1.flags b/test/pending/run/macro-expand-tparams-prefix-f1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-f1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala b/test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala new file mode 100644 index 0000000000..bc880fdf77 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + Block(List( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(()))) + } +} diff --git a/test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala b/test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala new file mode 100644 index 0000000000..bc8e7ac75c --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + class D[T] { + class C[U] { + def foo[V] = macro Impls.foo[List[T], U, V] + foo[Boolean] + } + } + + val outer1 = new D[Int] + new outer1.C[String] +} \ No newline at end of file diff --git a/test/pending/run/macro-overload.check b/test/pending/run/macro-overload.check deleted file mode 100644 index 764f914e48..0000000000 --- a/test/pending/run/macro-overload.check +++ /dev/null @@ -1,4 +0,0 @@ -object-Int -object-String -class-Int -class-String \ No newline at end of file diff --git a/test/pending/run/macro-overload.flags b/test/pending/run/macro-overload.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/pending/run/macro-overload.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-overload/Macros_1.scala b/test/pending/run/macro-overload/Macros_1.scala deleted file mode 100644 index f24c69ea7b..0000000000 --- a/test/pending/run/macro-overload/Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Macros { - def macro bar(x: Int): Int = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("object-Int")))) - def macro bar(x: String): String = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("object-String")))) -} - -class Macros { - def macro bar(x: Int): Int = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("class-Int")))) - def macro bar(x: String): String = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("class-String")))) -} \ No newline at end of file diff --git a/test/pending/run/macro-overload/Test_2.scala b/test/pending/run/macro-overload/Test_2.scala deleted file mode 100644 index 75f6572e03..0000000000 --- a/test/pending/run/macro-overload/Test_2.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test extends App { - Macros.bar(2) - Macros.bar("2") - new Macros.bar(2) - new Macros.bar("2") -} \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-a.check b/test/pending/run/macro-quasiinvalidbody-a.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-a.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-a.flags b/test/pending/run/macro-quasiinvalidbody-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala b/test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala new file mode 100644 index 0000000000..0da37cd5c0 --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +trait Impls { + def impl(c: Ctx)(x: c.Expr[Any]) = x +} \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala b/test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala new file mode 100644 index 0000000000..04a43080bd --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros extends Impls { + def foo(x: Any) = macro impl +} + +object Test extends App { + import Macros._ + println(foo(42)) +} \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-b.check b/test/pending/run/macro-quasiinvalidbody-b.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-b.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-b.flags b/test/pending/run/macro-quasiinvalidbody-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala b/test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala new file mode 100644 index 0000000000..d84d04974f --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala @@ -0,0 +1,7 @@ +import scala.reflect.makro.{Context => Ctx} + +trait ImplContainer { + object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = x + } +} \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala b/test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala new file mode 100644 index 0000000000..82f88b62e4 --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros extends ImplContainer { + def foo(x: Any) = macro Impls.foo +} + +object Test extends App { + import Macros._ + println(foo(42)) +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-array.flags b/test/pending/run/macro-reify-array.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-reify-array.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-reify-array/Macros_1.scala b/test/pending/run/macro-reify-array/Macros_1.scala new file mode 100644 index 0000000000..af42321484 --- /dev/null +++ b/test/pending/run/macro-reify-array/Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo[T](s: String) = macro Impls.foo[T] + + object Impls { + def foo[T: c.TypeTag](c: Ctx)(s: c.Expr[T]) = c.reify { + Array(s.eval) + } + } +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-array/Test_2.scala b/test/pending/run/macro-reify-array/Test_2.scala new file mode 100644 index 0000000000..e40d5b40e0 --- /dev/null +++ b/test/pending/run/macro-reify-array/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val arr = Macros.foo("hello", "world") + println(arr.getClass) +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-eval-vs-value.flags b/test/pending/run/macro-reify-eval-vs-value.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-reify-eval-vs-value.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-reify-eval-vs-value/Macros_1.scala b/test/pending/run/macro-reify-eval-vs-value/Macros_1.scala new file mode 100644 index 0000000000..98dd93b0f8 --- /dev/null +++ b/test/pending/run/macro-reify-eval-vs-value/Macros_1.scala @@ -0,0 +1,25 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def fooEval(s: String) = macro Impls.fooEval + def fooValue(s: String) = macro Impls.fooValue + + object Impls { + def fooEval(c: Ctx)(s: c.Expr[String]) = c.reify { + println("hello " + s.eval) + println("hello " + s.eval) + } + + def fooValue(c: Ctx)(s: c.Expr[String]) = c.reify { + { + println("hello " + s.value) + def sayHello = println(s.value) + sayHello + } + println("hello " + s.eval); + { + println("hello " + s.eval) + } + } + } +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-eval-vs-value/Test_2.scala b/test/pending/run/macro-reify-eval-vs-value/Test_2.scala new file mode 100644 index 0000000000..8e62e6e0e7 --- /dev/null +++ b/test/pending/run/macro-reify-eval-vs-value/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + Macros.fooEval({ println("in ur logz"); "world"}) + println("======================") + Macros.fooValue({ println("i can has cheezburger?"); "world"}) +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check new file mode 100644 index 0000000000..7e4b000c52 --- /dev/null +++ b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check @@ -0,0 +1,2 @@ +TypeTag(List[Int]) +TypeTag(List[List[Int]]) diff --git a/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala new file mode 100644 index 0000000000..4b264d83af --- /dev/null +++ b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTagHK[C[_]: GroundTypeTag, T: GroundTypeTag] = { + println(implicitly[GroundTypeTag[C[T]]]) + println(implicitly[GroundTypeTag[List[C[T]]]]) + } + fooTypeTagHK[List, Int] +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagful-b.check b/test/pending/run/macro-reify-tagful-b.check new file mode 100644 index 0000000000..5bd9fe2156 --- /dev/null +++ b/test/pending/run/macro-reify-tagful-b.check @@ -0,0 +1 @@ +List(List(hello world)) diff --git a/test/pending/run/macro-reify-tagful-b.flags b/test/pending/run/macro-reify-tagful-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-reify-tagful-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagful-b/Macros_1.scala b/test/pending/run/macro-reify-tagful-b/Macros_1.scala new file mode 100644 index 0000000000..38b839330b --- /dev/null +++ b/test/pending/run/macro-reify-tagful-b/Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo[T](s: T) = macro Impls.foo[List[T]] + + object Impls { + def foo[T: c.TypeTag](c: Ctx)(s: c.Expr[T]) = c.reify { + List(s.eval) + } + } +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagful-b/Test_2.scala b/test/pending/run/macro-reify-tagful-b/Test_2.scala new file mode 100644 index 0000000000..142234901f --- /dev/null +++ b/test/pending/run/macro-reify-tagful-b/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val list: List[List[String]] = Macros.foo(List("hello world")) + println(list) +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagless-b.check b/test/pending/run/macro-reify-tagless-b.check new file mode 100644 index 0000000000..49acd94ad6 --- /dev/null +++ b/test/pending/run/macro-reify-tagless-b.check @@ -0,0 +1,3 @@ +error: macro must not return an expr that contains free type variables (namely: T). have you forgot to use c.TypeTag annotations for type parameters external to a reifee? + +java.lang.Error: reflective compilation has failed diff --git a/test/pending/run/macro-reify-tagless-b.flags b/test/pending/run/macro-reify-tagless-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-reify-tagless-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala b/test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..fac7ba5b98 --- /dev/null +++ b/test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo[T](s: T) = macro Impls.foo[List[T]] + + object Impls { + def foo[T](c: Ctx)(s: c.Expr[T]) = c.reify { + List(s.eval) + } + } +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagless-b/Test_2.scala b/test/pending/run/macro-reify-tagless-b/Test_2.scala new file mode 100644 index 0000000000..419ee42101 --- /dev/null +++ b/test/pending/run/macro-reify-tagless-b/Test_2.scala @@ -0,0 +1,11 @@ +object Test extends App { + //val list: List[String] = Macros.foo("hello world") + //println(list) + + import scala.reflect.mirror._ + val tpt = AppliedTypeTree(Ident(definitions.ListClass), List(Ident(definitions.StringClass))) + val rhs = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant("hello world")))) + val list = ValDef(NoMods, newTermName("list"), tpt, rhs) + val tree = Block(list, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name)))) + println(tree.eval) +} diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-notags.check b/test/pending/run/macro-reify-typetag-hktypeparams-notags.check new file mode 100644 index 0000000000..db8a19d5f7 --- /dev/null +++ b/test/pending/run/macro-reify-typetag-hktypeparams-notags.check @@ -0,0 +1,2 @@ +TypeTag(C[T]) +TypeTag(List[C[T]]) diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala b/test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala new file mode 100644 index 0000000000..9a370189a7 --- /dev/null +++ b/test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooNoTypeTagHK[C[_], T] = { + println(implicitly[TypeTag[C[T]]]) + println(implicitly[TypeTag[List[C[T]]]]) + } + fooNoTypeTagHK[List, Int] +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-tags.check b/test/pending/run/macro-reify-typetag-hktypeparams-tags.check new file mode 100644 index 0000000000..7e4b000c52 --- /dev/null +++ b/test/pending/run/macro-reify-typetag-hktypeparams-tags.check @@ -0,0 +1,2 @@ +TypeTag(List[Int]) +TypeTag(List[List[Int]]) diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala b/test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala new file mode 100644 index 0000000000..0358da9b0d --- /dev/null +++ b/test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTagHK[C[_]: TypeTag, T: TypeTag] = { + println(implicitly[TypeTag[C[T]]]) + println(implicitly[TypeTag[List[C[T]]]]) + } + fooTypeTagHK[List, Int] +} \ No newline at end of file diff --git a/test/pending/run/reify_addressbook.scala b/test/pending/run/reify_addressbook.scala index 54dd5545bd..7cb6dc08fd 100644 --- a/test/pending/run/reify_addressbook.scala +++ b/test/pending/run/reify_addressbook.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { case class Person(name: String, age: Int) /** An AddressBook takes a variable number of arguments @@ -62,9 +60,5 @@ object Test extends App { ; println(page) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_brainf_ck.scala b/test/pending/run/reify_brainf_ck.scala index 0034644b81..e4bcb257bd 100644 --- a/test/pending/run/reify_brainf_ck.scala +++ b/test/pending/run/reify_brainf_ck.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { import scala.annotation._ trait Func[T] { @@ -76,9 +74,5 @@ object Test extends App { <.#>+++++++++++[<+++++>-]<.>++++++++[<++ +>-]<.+++.------.--------.[-]>++++++++[<++++> -]<+.[-]++++++++++.""") - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_callccinterpreter.scala b/test/pending/run/reify_callccinterpreter.scala index 96ae9c5c17..0e23f75dcc 100644 --- a/test/pending/run/reify_callccinterpreter.scala +++ b/test/pending/run/reify_callccinterpreter.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { type Answer = Value; /** @@ -85,9 +83,5 @@ object Test extends App { println(test(term0)) println(test(term1)) println(test(term2)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_classfileann_b.check b/test/pending/run/reify_classfileann_b.check deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/pending/run/reify_classfileann_b.scala b/test/pending/run/reify_classfileann_b.scala deleted file mode 100644 index c31826377a..0000000000 --- a/test/pending/run/reify_classfileann_b.scala +++ /dev/null @@ -1,24 +0,0 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation - -object Test extends App { - // test 1: reify - val tree = scala.reflect.Code.lift{ - class C { - def x: Int = { - 2: @ann(bar="1", quux=Array("2", "3"), baz = new ann(bar = "4")) - } - } - }.tree - println(tree.toString) - - // test 2: import and compile - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(tree) -} \ No newline at end of file diff --git a/test/pending/run/reify_closure2b.scala b/test/pending/run/reify_closure2b.scala index b9c0063290..f9ed16d309 100644 --- a/test/pending/run/reify_closure2b.scala +++ b/test/pending/run/reify_closure2b.scala @@ -1,17 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { def foo(y: Int): Int => Int = { class Foo(y: Int) { - val fun = reflect.Code.lift{(x: Int) => { + val fun = reflect.mirror.reify{(x: Int) => { x + y }} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(y).fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/pending/run/reify_closure3b.scala b/test/pending/run/reify_closure3b.scala index 8f161dbff3..8ef0a60c66 100644 --- a/test/pending/run/reify_closure3b.scala +++ b/test/pending/run/reify_closure3b.scala @@ -1,19 +1,14 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { def foo(y: Int): Int => Int = { class Foo(y: Int) { def y1 = y - val fun = reflect.Code.lift{(x: Int) => { + val fun = reflect.mirror.reify{(x: Int) => { x + y1 }} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(y).fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/pending/run/reify_closure4b.scala b/test/pending/run/reify_closure4b.scala index 238795d4dd..9eeb01b459 100644 --- a/test/pending/run/reify_closure4b.scala +++ b/test/pending/run/reify_closure4b.scala @@ -1,19 +1,14 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { def foo(y: Int): Int => Int = { class Foo(y: Int) { val y1 = y - val fun = reflect.Code.lift{(x: Int) => { + val fun = reflect.mirror.reify{(x: Int) => { x + y1 }} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(y).fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/pending/run/reify_closure5b.scala b/test/pending/run/reify_closure5b.scala index bdb2583e8a..51f1ec318d 100644 --- a/test/pending/run/reify_closure5b.scala +++ b/test/pending/run/reify_closure5b.scala @@ -1,17 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { def foo[T](ys: List[T]): Int => Int = { class Foo[T](ys: List[T]) { - val fun = reflect.Code.lift{(x: Int) => { + val fun = reflect.mirror.reify{(x: Int) => { x + ys.length }} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(ys).fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/pending/run/reify_closure8b.check b/test/pending/run/reify_closure8b.check deleted file mode 100644 index 9a037142aa..0000000000 --- a/test/pending/run/reify_closure8b.check +++ /dev/null @@ -1 +0,0 @@ -10 \ No newline at end of file diff --git a/test/pending/run/reify_closure8b.scala b/test/pending/run/reify_closure8b.scala deleted file mode 100644 index 38031c217b..0000000000 --- a/test/pending/run/reify_closure8b.scala +++ /dev/null @@ -1,16 +0,0 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - class Foo(y: Int) { - def fun = lift{y} - } - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - val dyn = toolbox.runExpr(new Foo(10).fun.tree) - val foo = dyn.asInstanceOf[Int] - println(foo) -} diff --git a/test/pending/run/reify_closure9a.scala b/test/pending/run/reify_closure9a.scala index 185f4ffca1..1fc18cfa13 100644 --- a/test/pending/run/reify_closure9a.scala +++ b/test/pending/run/reify_closure9a.scala @@ -1,16 +1,11 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - +import scala.reflect.mirror._ object Test extends App { def foo(y: Int) = { class Foo(val y: Int) { - def fun = lift{y} + def fun = reify{y} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(y).fun.tree) dyn.asInstanceOf[Int] } diff --git a/test/pending/run/reify_closure9b.scala b/test/pending/run/reify_closure9b.scala index ad279fac6d..32b05d00ee 100644 --- a/test/pending/run/reify_closure9b.scala +++ b/test/pending/run/reify_closure9b.scala @@ -1,16 +1,11 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - +import scala.reflect.mirror._ object Test extends App { def foo(y: Int) = { class Foo(y: Int) { - def fun = lift{y} + def fun = reify{y} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(y).fun.tree) dyn.asInstanceOf[Int] } diff --git a/test/pending/run/reify_closures11.scala b/test/pending/run/reify_closures11.scala index 2c4177b8f2..ceb224c6d6 100644 --- a/test/pending/run/reify_closures11.scala +++ b/test/pending/run/reify_closures11.scala @@ -1,16 +1,11 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - +import scala.reflect.mirror._ object Test extends App { def fun() = { def z() = 2 - lift{z} + reify{z} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun().tree) val foo = dyn.asInstanceOf[Int] println(foo) diff --git a/test/pending/run/reify_csv.scala b/test/pending/run/reify_csv.scala index a6a616fab0..966521575c 100644 --- a/test/pending/run/reify_csv.scala +++ b/test/pending/run/reify_csv.scala @@ -1,6 +1,4 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { val csv = """ @@ -18,7 +16,7 @@ object Test extends App { val fields = csv.head.split(";").map{_.trim()}.toList println(fields) - val code = scala.reflect.Code.lift({ + reify({ object Csv { case class record(`phase name`: String, id: String, description: String) @@ -33,9 +31,5 @@ object Test extends App { } Csv.record.parse(csv) foreach println - }) - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }).eval } diff --git a/test/pending/run/reify_gadts.scala b/test/pending/run/reify_gadts.scala index 9feb7a5726..652a7d99d8 100644 --- a/test/pending/run/reify_gadts.scala +++ b/test/pending/run/reify_gadts.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { /* The syntax tree of a toy language */ abstract class Term[T] @@ -36,9 +34,5 @@ object Test extends App { } println( eval(If(IsZero(Lit(1)), Lit(41), Succ(Lit(41))))) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_lazyevaluation.scala b/test/pending/run/reify_lazyevaluation.scala index 0720a7c979..1a0c858914 100644 --- a/test/pending/run/reify_lazyevaluation.scala +++ b/test/pending/run/reify_lazyevaluation.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object lazyLib { /** Delay the evaluation of an expression until it is needed. */ @@ -56,9 +54,5 @@ object Test extends App { println("sl2 = " + sl2) println("sl2() = " + sl2()) println("sl2 = " + sl2) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_newimpl_07.scala b/test/pending/run/reify_newimpl_07.scala new file mode 100644 index 0000000000..13ca6bda8b --- /dev/null +++ b/test/pending/run/reify_newimpl_07.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + class C(val y: Int) { + val code = reify { + reify{y}.eval + } + } + + println(new C(2).code.eval) + } +} \ No newline at end of file diff --git a/test/pending/run/reify_newimpl_08.scala b/test/pending/run/reify_newimpl_08.scala new file mode 100644 index 0000000000..e2faa3c9af --- /dev/null +++ b/test/pending/run/reify_newimpl_08.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = reify { + class C(val y: Int) { + val code = reify { + reify{y}.eval + } + } + + new C(2).code.eval + } + + println(code.eval) +} \ No newline at end of file diff --git a/test/pending/run/reify_newimpl_35.scala b/test/pending/run/reify_newimpl_35.scala new file mode 100644 index 0000000000..5e1d163e9e --- /dev/null +++ b/test/pending/run/reify_newimpl_35.scala @@ -0,0 +1,10 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-free-types" + def code = """ +import scala.reflect.mirror._ +def foo[T: TypeTag] = reify{List[T]()} +println(foo) + """ +} diff --git a/test/pending/run/reify_newimpl_46.scala b/test/pending/run/reify_newimpl_46.scala new file mode 100644 index 0000000000..840d695e83 --- /dev/null +++ b/test/pending/run/reify_newimpl_46.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[T[_] >: Null] { + val code = reify{val x: T[String] = null; println("ima worx"); x} + println(freeTypes(code)) + val T = freeTypes(code)(0) + mkToolBox().runExpr(code, Map(T -> definitions.ListClass.asType)) + } + + new C[List] +} \ No newline at end of file diff --git a/test/pending/run/reify_newimpl_53.scala b/test/pending/run/reify_newimpl_53.scala new file mode 100644 index 0000000000..26645dea6a --- /dev/null +++ b/test/pending/run/reify_newimpl_53.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[T >: Null] { + val code = reify{ + val tt = implicitly[TypeTag[T]] + println("mah typetag is: %s".format(tt)) + } + println(freeTypes(code)) + val T = freeTypes(code)(0) + mkToolBox().runExpr(code, Map(T -> definitions.StringClass.asType)) + } + + new C[String] +} \ No newline at end of file diff --git a/test/pending/run/reify_properties.scala b/test/pending/run/reify_properties.scala index 265c344b8e..5cacc262ac 100644 --- a/test/pending/run/reify_properties.scala +++ b/test/pending/run/reify_properties.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { /** A mutable property whose getter and setter may be customized. */ case class Property[T](init: T) { private var value: T = init @@ -54,9 +52,5 @@ object Test extends App { println("user1: " + user1) println("user2: " + user2) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_simpleinterpreter.scala b/test/pending/run/reify_simpleinterpreter.scala index 4762afb3cc..2193edeea7 100644 --- a/test/pending/run/reify_simpleinterpreter.scala +++ b/test/pending/run/reify_simpleinterpreter.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { case class M[A](value: A) { def bind[B](k: A => M[B]): M[B] = k(value) def map[B](f: A => B): M[B] = bind(x => unitM(f(x))) @@ -73,9 +71,5 @@ object Test extends App { println(test(term0)) println(test(term1)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/t5258a.check b/test/pending/run/t5258a.check new file mode 100644 index 0000000000..4e0b2da04c --- /dev/null +++ b/test/pending/run/t5258a.check @@ -0,0 +1 @@ +int \ No newline at end of file diff --git a/test/pending/run/t5258a.scala b/test/pending/run/t5258a.scala new file mode 100644 index 0000000000..755d135468 --- /dev/null +++ b/test/pending/run/t5258a.scala @@ -0,0 +1,5 @@ +object Test extends App { + reify { + println(classOf[Int]) + }.eval +} \ No newline at end of file diff --git a/test/pending/run/t5258b.scala b/test/pending/run/t5258b.scala index 3a603095b3..8ad1ff114e 100644 --- a/test/pending/run/t5258b.scala +++ b/test/pending/run/t5258b.scala @@ -1,14 +1,6 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C println(classOf[C]) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } \ No newline at end of file diff --git a/test/pending/run/t5258c.scala b/test/pending/run/t5258c.scala index b0d16ba0b1..1f76391162 100644 --- a/test/pending/run/t5258c.scala +++ b/test/pending/run/t5258c.scala @@ -1,14 +1,6 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object E extends Enumeration { val foo, bar = Value } println(E.foo) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } \ No newline at end of file diff --git a/test/pending/run/t5271_1.scala b/test/pending/run/t5271_1.scala index afbd8fe465..fae64350e3 100644 --- a/test/pending/run/t5271_1.scala +++ b/test/pending/run/t5271_1.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { case class C(foo: Int, bar: Int) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/t5271_2.scala b/test/pending/run/t5271_2.scala index d85d945973..d25e1fe804 100644 --- a/test/pending/run/t5271_2.scala +++ b/test/pending/run/t5271_2.scala @@ -1,15 +1,9 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { case class C(foo: Int, bar: Int) val c = C(2, 2) println(c.foo * c.bar) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/t5271_3.scala b/test/pending/run/t5271_3.scala index 5a624de903..65a03ae323 100644 --- a/test/pending/run/t5271_3.scala +++ b/test/pending/run/t5271_3.scala @@ -1,16 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object C { def qwe = 4 } case class C(foo: Int, bar: Int) val c = C(2, 2) println(c.foo * c.bar == C.qwe) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/t5418.scala b/test/pending/run/t5418.scala index fe813cf5ae..9b0a954e47 100644 --- a/test/pending/run/t5418.scala +++ b/test/pending/run/t5418.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { new Object().getClass - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } \ No newline at end of file -- cgit v1.2.3 From 2c28680ca95c042c5b66de6c4b58c8367599cb44 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Apr 2012 18:08:46 -0700 Subject: Implementation of SIP 13 - implicit classes --- src/compiler/scala/reflect/internal/StdNames.scala | 4 + .../tools/nsc/typechecker/MethodSynthesis.scala | 89 ++++++++++++++-------- .../scala/tools/nsc/typechecker/Namers.scala | 16 ++-- .../scala/tools/nsc/typechecker/Typers.scala | 82 ++++++++++---------- .../scala/tools/nsc/typechecker/Unapplies.scala | 15 ++-- test/files/run/implicitclasses.scala | 10 +++ 6 files changed, 133 insertions(+), 83 deletions(-) create mode 100644 test/files/run/implicitclasses.scala diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 0cd3616ba9..dbd9bb4f50 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -101,6 +101,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val ROOT: NameType = "" val PACKAGE: NameType = "package" val SPECIALIZED_SUFFIX: NameType = "$sp" + val WRAPPER_SUFFIX: NameType = "$wrapper" // value types (and AnyRef) are all used as terms as well // as (at least) arguments to the @specialize annotation. @@ -535,6 +536,9 @@ trait StdNames extends NameManglers { self: SymbolTable => def moduleVarName(name: TermName): TermName = newTermNameCached("" + name + MODULE_VAR_SUFFIX) + def implicitWrapperName(name: TypeName): TermName = + newTermNameCached("" + name + WRAPPER_SUFFIX) + val ROOTPKG: TermName = "_root_" /** Base strings from which synthetic names are derived. */ diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 3d8c2ea564..e622ad7d4b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -155,28 +155,23 @@ trait MethodSynthesis { /** There are two key methods in here. * - * 1) enterGetterSetter is called from Namer with a ValDef which - * may need accessors. Some setup is performed. In general this - * creates symbols and enters them into the scope of the owner. + * 1) Enter methods such as enterGetterSetterare called + * from Namer with a tree which may generate further trees such as accessors or + * implicit wrappers. Some setup is performed. In general this creates symbols + * and enters them into the scope of the owner. * - * 2) finishGetterSetter is called from Typer when a Template is typed. + * 2) addDerivedTrees is called from Typer when a Template is typed. * It completes the job, returning a list of trees with their symbols - * set to those created in enterGetterSetter. Those trees then become + * set to those created in the enter methods. Those trees then become * part of the typed template. */ trait MethodSynth { self: Namer => import NamerErrorGen._ - - /** TODO - synthesize method. - */ - def enterImplicitClass(tree: ClassDef) { - /** e.g. - val ClassDef(mods, name, tparams, impl) = tree - val converter = ImplicitClassConverter(tree).createAndEnterSymbol() - ... - */ + + def enterImplicitWrapper(tree: ClassDef) { + ImplicitClassWrapper(tree).createAndEnterSymbol() } def enterGetterSetter(tree: ValDef) { @@ -203,7 +198,8 @@ trait MethodSynthesis { enterBeans(tree) } - def finishGetterSetter(typer: Typer, stat: Tree): List[Tree] = stat match { + + def addDerivedTrees(typer: Typer, stat: Tree): List[Tree] = stat match { case vd @ ValDef(mods, name, tpt, rhs) if !noFinishGetterSetter(vd) && !vd.symbol.isLazy => // If we don't save the annotations, they seem to wander off. val annotations = stat.symbol.initialize.annotations @@ -234,35 +230,59 @@ trait MethodSynthesis { field ::: standardAccessors(vd) ::: beanAccessors(vd) } + /** This trait assembles what's needed for synthesizing derived methods. + * Important: Typically, instances of this trait are created TWICE for each derived + * symbol; once form Namers in an enter method, and once from Typers in addDerivedTrees. + * So it's important that creating an instance of Derived does not have a side effect, + * or if it has a side effect, control that it is done only once. + */ trait Derived { - /** The tree from which we are deriving a synthetic member. */ + + /** The tree from which we are deriving a synthetic member. Typically, that's + * given as an argument of the instance. */ def tree: Tree + + /** The name of the method */ def name: TermName + + /** The flags that are retained from the original symbol */ + def flagsMask: Long + + /** The flags that the derived symbol has in addition to those retained from + * the original symbol*/ def flagsExtra: Long - - /** The tree, symbol, and type completer for the synthetic member. */ + + /** type completer for the synthetic member. + */ def completer(sym: Symbol): Type + + /** The derived symbol. It is assumed that this symbol already exists and has been + * entered in the parent scope when derivedSym is called */ def derivedSym: Symbol + + /** The definition tree of the derived symbol. */ def derivedTree: Tree } - + trait DerivedFromMemberDef extends Derived { def tree: MemberDef - + def enclClass: Symbol + // Final methods to make the rest easier to reason about. final def mods = tree.mods final def basisSym = tree.symbol - final def enclClass = basisSym.enclClass final def derivedFlags: Long = basisSym.flags & flagsMask | flagsExtra } - + trait DerivedFromClassDef extends DerivedFromMemberDef { def tree: ClassDef + final def enclClass = basisSym.owner.enclClass } trait DerivedFromValDef extends DerivedFromMemberDef { def tree: ValDef + final def enclClass = basisSym.enclClass /** Which meta-annotation is associated with this kind of entity. * Presently one of: field, getter, setter, beanGetter, beanSetter, param. @@ -334,15 +354,22 @@ trait MethodSynthesis { /** A synthetic method which performs the implicit conversion implied by * the declaration of an implicit class. Yet to be written. */ - case class ImplicitClassConverter(tree: ClassDef) extends DerivedFromClassDef { - def completer(sym: Symbol): Type = ??? - def derivedSym: Symbol = ??? - def derivedTree: DefDef = ??? - def flagsExtra: Long = ??? - def flagsMask: Long = ??? - def name: TermName = ??? - } - + case class ImplicitClassWrapper(tree: ClassDef) extends DerivedFromClassDef { + def completer(sym: Symbol): Type = ??? // not needed + def createAndEnterSymbol(): Symbol = enterSyntheticSym(derivedTree) + def derivedSym: Symbol = { + val result = enclClass.info decl name + assert(result != NoSymbol, "not found: "+name+" in "+enclClass+" "+enclClass.info.decls) + result + } + def derivedTree: DefDef = util.trace("derivedTree = ")( + factoryMeth(mods & flagsMask | flagsExtra, name, tree, symbolic = false) + ) + def flagsExtra: Long = METHOD | IMPLICIT + def flagsMask: Long = AccessFlags + def name: TermName = nme.implicitWrapperName(tree.name) + } + case class Getter(tree: ValDef) extends DerivedGetter { def name = tree.name def category = GetterTargetClass diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 2539091966..98f845f403 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -99,7 +99,7 @@ trait Namers extends MethodSynthesis { owner.unsafeTypeParams foreach (paramContext.scope enter _) newNamer(paramContext) } - + def enclosingNamerWithScope(scope: Scope) = { var cx = context while (cx != NoContext && cx.scope != scope) cx = cx.outer @@ -666,10 +666,12 @@ trait Namers extends MethodSynthesis { "If possible, define " + tree.symbol + " in " + owner.skipPackageObject + " instead." ) } - + // Suggested location only. - if (mods.isImplicit) - enterImplicitClass(tree) + if (mods.isImplicit) { + println("enter implicit wrapper "+tree+", owner = "+owner) + enterImplicitWrapper(tree) + } } // this logic is needed in case typer was interrupted half @@ -1404,10 +1406,10 @@ trait Namers extends MethodSynthesis { if (sym.isImplicit) { if (sym.isConstructor) fail(ImplicitConstr) - if (!sym.isTerm) - fail(ImplicitNotTerm) + if (!(sym.isTerm || (sym.isClass && !sym.isTrait))) + fail(ImplicitNotTermOrClass) if (sym.owner.isPackageClass) - fail(ImplicitTopObject) + fail(ImplicitAtToplevel) } if (sym.isClass) { if (sym.isAnyOverride && !sym.hasFlag(TRAIT)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f558e0afc7..9b09145dc3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1653,7 +1653,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val body = if (isPastTyper || reporter.hasErrors) templ.body - else templ.body flatMap rewrappingWrapperTrees(namer.finishGetterSetter(Typer.this, _)) + else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _)) val body1 = typedStats(body, templ.symbol) @@ -2474,54 +2474,53 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { || (looker.hasAccessorFlag && !accessed.hasAccessorFlag && accessed.isPrivate) ) - def checkNoDoubleDefsAndAddSynthetics(stats: List[Tree]): List[Tree] = { + def checkNoDoubleDefs(stats: List[Tree]): Unit = { val scope = if (inBlock) context.scope else context.owner.info.decls - var newStats = new ListBuffer[Tree] - var needsCheck = true - var moreToAdd = true - while (moreToAdd) { - val initSize = scope.size - var e = scope.elems - while ((e ne null) && e.owner == scope) { - - // check no double def - if (needsCheck) { - var e1 = scope.lookupNextEntry(e) - while ((e1 ne null) && e1.owner == scope) { - if (!accesses(e.sym, e1.sym) && !accesses(e1.sym, e.sym) && - (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe) || e.sym.isMacro && e1.sym.isMacro)) - // default getters are defined twice when multiple overloads have defaults. an - // error for this is issued in RefChecks.checkDefaultsInOverloaded - if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefault && - !e.sym.hasAnnotation(BridgeClass) && !e1.sym.hasAnnotation(BridgeClass)) { - log("Double definition detected:\n " + - ((e.sym.getClass, e.sym.info, e.sym.ownerChain)) + "\n " + - ((e1.sym.getClass, e1.sym.info, e1.sym.ownerChain))) - - DefDefinedTwiceError(e.sym, e1.sym) - scope.unlink(e1) // need to unlink to avoid later problems with lub; see #2779 - } - e1 = scope.lookupNextEntry(e1) + var e = scope.elems + while ((e ne null) && e.owner == scope) { + var e1 = scope.lookupNextEntry(e) + while ((e1 ne null) && e1.owner == scope) { + if (!accesses(e.sym, e1.sym) && !accesses(e1.sym, e.sym) && + (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe))) + // default getters are defined twice when multiple overloads have defaults. an + // error for this is issued in RefChecks.checkDefaultsInOverloaded + if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefaultFlag && + !e.sym.hasAnnotation(BridgeClass) && !e1.sym.hasAnnotation(BridgeClass)) { + log("Double definition detected:\n " + + ((e.sym.getClass, e.sym.info, e.sym.ownerChain)) + "\n " + + ((e1.sym.getClass, e1.sym.info, e1.sym.ownerChain))) + + DefDefinedTwiceError(e.sym, e1.sym) + scope.unlink(e1) // need to unlink to avoid later problems with lub; see #2779 } - } - - // add synthetics - context.unit.synthetics get e.sym foreach { tree => - newStats += typedStat(tree) // might add even more synthetics to the scope - context.unit.synthetics -= e.sym + e1 = scope.lookupNextEntry(e1) } - e = e.next } - needsCheck = false - // the type completer of a synthetic might add more synthetics. example: if the - // factory method of a case class (i.e. the constructor) has a default. - moreToAdd = initSize != scope.size + } + + def addSynthetics(stats: List[Tree]): List[Tree] = { + val scope = if (inBlock) context.scope else context.owner.info.decls + var newStats = new ListBuffer[Tree] + var moreToAdd = true + while (moreToAdd) { + val initElems = scope.elems + for (sym <- scope) + for (tree <- context.unit.synthetics get sym) { + newStats += typedStat(tree) // might add even more synthetics to the scope + context.unit.synthetics -= sym + } + // the type completer of a synthetic might add more synthetics. example: if the + // factory method of a case class (i.e. the constructor) has a default. + moreToAdd = scope.elems ne initElems } if (newStats.isEmpty) stats else { // put default getters next to the method they belong to, // same for companion objects. fixes #2489 and #4036. + // [Martin] This is pretty ugly. I think we could avoid + // this code by associating defaults and companion objects + // with the original tree instead of the new symbol. def matches(stat: Tree, synt: Tree) = (stat, synt) match { case (DefDef(_, statName, _, _, _, _), DefDef(mods, syntName, _, _, _, _)) => mods.hasDefaultFlag && syntName.toString.startsWith(statName.toString) @@ -2551,7 +2550,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } context.updateBuffer(statsErrors) if (phase.erasedTypes) stats1 - else checkNoDoubleDefsAndAddSynthetics(stats1) + else { + checkNoDoubleDefs(stats1) + addSynthetics(stats1) + } } def typedArg(arg: Tree, mode: Int, newmode: Int, pt: Type): Tree = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index 4f5b6868ae..1f79d8212d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -112,8 +112,8 @@ trait Unapplies extends ast.TreeDSL private def toIdent(x: DefTree) = Ident(x.name) setPos x.pos.focus - private def classType(cdef: ClassDef, tparams: List[TypeDef]): Tree = { - val tycon = REF(cdef.symbol) + private def classType(cdef: ClassDef, tparams: List[TypeDef], symbolic: Boolean = true): Tree = { + val tycon = if (symbolic) REF(cdef.symbol) else Ident(cdef.name) if (tparams.isEmpty) tycon else AppliedTypeTree(tycon, tparams map toIdent) } @@ -166,15 +166,20 @@ trait Unapplies extends ast.TreeDSL /** The apply method corresponding to a case class */ - def caseModuleApplyMeth(cdef: ClassDef): DefDef = { + def factoryMeth(mods: Modifiers, name: TermName, cdef: ClassDef, symbolic: Boolean): DefDef = { val tparams = cdef.tparams map copyUntypedInvariant val cparamss = constrParamss(cdef) + def classtpe = classType(cdef, tparams, symbolic) atPos(cdef.pos.focus)( - DefDef(caseMods, nme.apply, tparams, cparamss, classType(cdef, tparams), - New(classType(cdef, tparams), mmap(cparamss)(gen.paramToArg))) + DefDef(mods, name, tparams, cparamss, classtpe, + New(classtpe, mmap(cparamss)(gen.paramToArg))) ) } + /** The apply method corresponding to a case class + */ + def caseModuleApplyMeth(cdef: ClassDef): DefDef = factoryMeth(caseMods, nme.apply, cdef, symbolic = true) + /** The unapply method corresponding to a case class */ def caseModuleUnapplyMeth(cdef: ClassDef): DefDef = { diff --git a/test/files/run/implicitclasses.scala b/test/files/run/implicitclasses.scala new file mode 100644 index 0000000000..5c3ad588e6 --- /dev/null +++ b/test/files/run/implicitclasses.scala @@ -0,0 +1,10 @@ +object Test extends App { + + implicit class C(s: String) { + def nElems = s.length + } + + "abc".nElems + +} + -- cgit v1.2.3 From c297b97072cbeadad869338ff1b2e1c9955407a6 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Apr 2012 18:10:11 -0700 Subject: Implementation of SIP 13 take 2. --- src/compiler/scala/reflect/internal/StdNames.scala | 4 -- .../tools/nsc/typechecker/MethodSynthesis.scala | 53 +++++++++++++--------- .../scala/tools/nsc/typechecker/Namers.scala | 2 +- test/files/run/implicitclasses.scala | 2 +- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index dbd9bb4f50..0cd3616ba9 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -101,7 +101,6 @@ trait StdNames extends NameManglers { self: SymbolTable => val ROOT: NameType = "" val PACKAGE: NameType = "package" val SPECIALIZED_SUFFIX: NameType = "$sp" - val WRAPPER_SUFFIX: NameType = "$wrapper" // value types (and AnyRef) are all used as terms as well // as (at least) arguments to the @specialize annotation. @@ -536,9 +535,6 @@ trait StdNames extends NameManglers { self: SymbolTable => def moduleVarName(name: TermName): TermName = newTermNameCached("" + name + MODULE_VAR_SUFFIX) - def implicitWrapperName(name: TypeName): TermName = - newTermNameCached("" + name + WRAPPER_SUFFIX) - val ROOTPKG: TermName = "_root_" /** Base strings from which synthetic names are derived. */ diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index e622ad7d4b..097af5d456 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -65,7 +65,24 @@ trait MethodSynthesis { MethodType(params, symbols.last.typeConstructor) } - } + + /** The annotations amongst those found on the original symbol which + * should be propagated to this kind of accessor. + */ + def deriveAnnotations(initial: List[AnnotationInfo], category: Symbol, keepClean: Boolean): List[AnnotationInfo] = { + initial filter { ann => + // There are no meta-annotation arguments attached to `ann` + if (ann.metaAnnotations.isEmpty) { + // A meta-annotation matching `annotKind` exists on `ann`'s definition. + (ann.defaultTargets contains category) || + // `ann`'s definition has no meta-annotations, and `keepClean` is true. + (ann.defaultTargets.isEmpty && keepClean) + } + // There are meta-annotation arguments, and one of them matches `annotKind` + else ann.metaAnnotations exists (_ matches category) + } + } + } import synthesisUtil._ class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) { @@ -207,9 +224,18 @@ trait MethodSynthesis { map (acc => atPos(vd.pos.focus)(acc derive annotations)) filterNot (_ eq EmptyTree) ) + case cd @ ClassDef(mods, _, _, _) if mods.isImplicit => + val annotations = stat.symbol.initialize.annotations + // TODO: need to shuffle annotations between wrapper and class. + val wrapper = ImplicitClassWrapper(cd) + val meth = wrapper.derivedSym + val mdef = context.unit.synthetics(meth) + meth setAnnotations deriveAnnotations(annotations, MethodTargetClass, false) + cd.symbol setAnnotations deriveAnnotations(annotations, ClassTargetClass, true) + List(cd, mdef) case _ => List(stat) - } + } def standardAccessors(vd: ValDef): List[DerivedFromValDef] = ( if (vd.mods.isMutable && !vd.mods.isLazy) List(Getter(vd), Setter(vd)) @@ -306,22 +332,6 @@ trait MethodSynthesis { enterInScope(sym) sym setInfo completer(sym) } - /** The annotations amongst those found on the original symbol which - * should be propagated to this kind of accessor. - */ - private def deriveAnnotations(initial: List[AnnotationInfo]): List[AnnotationInfo] = { - initial filter { ann => - // There are no meta-annotation arguments attached to `ann` - if (ann.metaAnnotations.isEmpty) { - // A meta-annotation matching `annotKind` exists on `ann`'s definition. - (ann.defaultTargets contains category) || - // `ann`'s definition has no meta-annotations, and `keepClean` is true. - (ann.defaultTargets.isEmpty && keepClean) - } - // There are meta-annotation arguments, and one of them matches `annotKind` - else ann.metaAnnotations exists (_ matches category) - } - } private def logDerived(result: Tree): Tree = { debuglog("[+derived] " + ojoin(mods.flagString, basisSym.accurateKindString, basisSym.getterName.decode) + " (" + derivedSym + ")\n " + result) @@ -330,7 +340,7 @@ trait MethodSynthesis { } final def derive(initial: List[AnnotationInfo]): Tree = { validate() - derivedSym setAnnotations deriveAnnotations(initial) + derivedSym setAnnotations deriveAnnotations(initial, category, keepClean) logDerived(derivedTree) } } @@ -362,12 +372,11 @@ trait MethodSynthesis { assert(result != NoSymbol, "not found: "+name+" in "+enclClass+" "+enclClass.info.decls) result } - def derivedTree: DefDef = util.trace("derivedTree = ")( + def derivedTree: DefDef = factoryMeth(mods & flagsMask | flagsExtra, name, tree, symbolic = false) - ) def flagsExtra: Long = METHOD | IMPLICIT def flagsMask: Long = AccessFlags - def name: TermName = nme.implicitWrapperName(tree.name) + def name: TermName = tree.name.toTermName } case class Getter(tree: ValDef) extends DerivedGetter { diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 98f845f403..8a3bf71644 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -669,7 +669,7 @@ trait Namers extends MethodSynthesis { // Suggested location only. if (mods.isImplicit) { - println("enter implicit wrapper "+tree+", owner = "+owner) + log("enter implicit wrapper "+tree+", owner = "+owner) enterImplicitWrapper(tree) } } diff --git a/test/files/run/implicitclasses.scala b/test/files/run/implicitclasses.scala index 5c3ad588e6..886d4dede0 100644 --- a/test/files/run/implicitclasses.scala +++ b/test/files/run/implicitclasses.scala @@ -4,7 +4,7 @@ object Test extends App { def nElems = s.length } - "abc".nElems + assert("abc".nElems == 3) } -- cgit v1.2.3 From ca1bb43544f770be70926ce2924b6bde33fd054b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Apr 2012 20:39:54 -0700 Subject: Fixed duplicate method problem for implicit wrappers. --- src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 097af5d456..875c83969e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -230,6 +230,7 @@ trait MethodSynthesis { val wrapper = ImplicitClassWrapper(cd) val meth = wrapper.derivedSym val mdef = context.unit.synthetics(meth) + context.unit.synthetics -= meth meth setAnnotations deriveAnnotations(annotations, MethodTargetClass, false) cd.symbol setAnnotations deriveAnnotations(annotations, ClassTargetClass, true) List(cd, mdef) -- cgit v1.2.3 From 46d0d73f66111d5d31b9fd593972970d7e9056bb Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 12 Apr 2012 11:32:31 +0200 Subject: GroundTypeTag => ConcreteTypeTag --- lib/scala-compiler.jar.desired.sha1 | 2 +- lib/scala-library.jar.desired.sha1 | 2 +- .../scala/reflect/internal/Definitions.scala | 22 +-- src/compiler/scala/reflect/internal/StdNames.scala | 4 +- .../scala/reflect/makro/runtime/Reifiers.scala | 8 +- src/compiler/scala/reflect/reify/Errors.scala | 4 +- src/compiler/scala/reflect/reify/Reifiers.scala | 6 +- .../scala/reflect/reify/codegen/Types.scala | 20 +-- src/compiler/scala/reflect/reify/package.scala | 6 +- .../scala/tools/nsc/typechecker/Implicits.scala | 4 +- .../scala/tools/nsc/typechecker/Macros.scala | 2 +- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- src/library/scala/Predef.scala | 26 ++-- src/library/scala/reflect/ClassTags.scala | 15 +- src/library/scala/reflect/TagMaterialization.scala | 42 +++--- .../scala/reflect/api/StandardDefinitions.scala | 4 +- src/library/scala/reflect/api/TypeTags.scala | 153 +++++++++++---------- src/library/scala/reflect/makro/Aliases.scala | 4 +- src/library/scala/reflect/makro/Reifiers.scala | 2 +- .../scala/reflect/makro/internal/typeTagImpl.scala | 18 +-- src/library/scala/reflect/package.scala | 16 +-- ...o-reify-groundtypetag-hktypeparams-notags.check | 8 +- .../Test.scala | 4 +- ...cro-reify-groundtypetag-typeparams-notags.check | 8 +- .../Test.scala | 4 +- .../neg/macro-reify-groundtypetag-usetypetag.check | 8 +- .../Test.scala | 4 +- test/files/neg/t3507.check | 2 +- test/files/neg/t3692.check | 4 +- test/files/run/groundtypetags_core.check | 30 ++-- test/files/run/groundtypetags_core.scala | 60 ++++---- test/files/run/macro-expand-nullary-generic.check | 10 +- test/files/run/macro-expand-tparams-explicit.check | 2 +- test/files/run/macro-expand-tparams-implicit.check | 4 +- test/files/run/macro-expand-tparams-prefix-a.check | 8 +- test/files/run/macro-expand-tparams-prefix-b.check | 4 +- .../files/run/macro-expand-tparams-prefix-c1.check | 6 +- .../files/run/macro-expand-tparams-prefix-c2.check | 6 +- .../files/run/macro-expand-tparams-prefix-d1.check | 2 +- .../macro-reify-groundtypetag-notypeparams.check | 4 +- .../Test.scala | 4 +- ...macro-reify-groundtypetag-typeparams-tags.check | 4 +- .../Test.scala | 6 +- .../run/macro-reify-typetag-notypeparams.check | 4 +- .../macro-reify-typetag-typeparams-notags.check | 4 +- .../run/macro-reify-typetag-typeparams-tags.check | 4 +- .../run/macro-reify-typetag-usegroundtypetag.check | 4 +- .../Test.scala | 2 +- .../files/run/macro-typecheck-macrosdisabled.check | 2 +- test/files/run/macro-undetparams-consfromsls.check | 6 +- test/files/run/macro-undetparams-implicitval.check | 2 +- test/files/run/macro-undetparams-macroitself.check | 4 +- test/files/run/primitive-sigs-2.check | 2 +- test/files/run/reify_newimpl_25.check | 2 +- test/files/run/reify_newimpl_26.check | 2 +- .../run/toolbox_typecheck_macrosdisabled.check | 2 +- test/files/run/typetags_core.check | 30 ++-- .../Test.scala | 6 +- 58 files changed, 320 insertions(+), 310 deletions(-) diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index d74b6353d9..3f94b85db9 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -d2808836aef2cbee506f9b0b0e346c749cac9ad8 ?scala-compiler.jar +82af2cfc6a81ae12f39c55c9cf684c5ec01971d3 ?scala-compiler.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 78e9f0b593..bf1f4829f2 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -752baeeb4a01c7c50ac0dc6e0f59f5598696a223 ?scala-library.jar +6a58ca2e4398623145c179f4ce215bfb86a065c4 ?scala-library.jar diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index b1c822ed97..12b083b4f6 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -477,16 +477,16 @@ trait Definitions extends reflect.api.StandardDefinitions { def ExprValue = getMember(ExprClass, nme.value) lazy val ExprModule = getMember(getRequiredClass("scala.reflect.api.Exprs"), nme.Expr) - lazy val ClassTagClass = getRequiredClass("scala.reflect.ClassTag") - def ClassTagErasure = getMember(ClassTagClass, nme.erasure) - def ClassTagTpe = getMember(ClassTagClass, nme.tpe) - lazy val ClassTagModule = getRequiredModule("scala.reflect.ClassTag") - lazy val TypeTagsClass = getRequiredClass("scala.reflect.api.TypeTags") - lazy val TypeTagClass = getMember(TypeTagsClass, tpnme.TypeTag) - def TypeTagTpe = getMember(TypeTagClass, nme.tpe) - lazy val TypeTagModule = getMember(TypeTagsClass, nme.TypeTag) - lazy val GroundTypeTagClass = getMember(TypeTagsClass, tpnme.GroundTypeTag) - lazy val GroundTypeTagModule = getMember(TypeTagsClass, nme.GroundTypeTag) + lazy val ClassTagClass = getRequiredClass("scala.reflect.ClassTag") + def ClassTagErasure = getMember(ClassTagClass, nme.erasure) + def ClassTagTpe = getMember(ClassTagClass, nme.tpe) + lazy val ClassTagModule = getRequiredModule("scala.reflect.ClassTag") + lazy val TypeTagsClass = getRequiredClass("scala.reflect.api.TypeTags") + lazy val TypeTagClass = getMember(TypeTagsClass, tpnme.TypeTag) + def TypeTagTpe = getMember(TypeTagClass, nme.tpe) + lazy val TypeTagModule = getMember(TypeTagsClass, nme.TypeTag) + lazy val ConcreteTypeTagClass = getMember(TypeTagsClass, tpnme.ConcreteTypeTag) + lazy val ConcreteTypeTagModule = getMember(TypeTagsClass, nme.ConcreteTypeTag) lazy val MacroContextClass = getRequiredClass("scala.reflect.makro.Context") def MacroContextPrefix = getMember(MacroContextClass, nme.prefix) @@ -497,7 +497,7 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val MacroInternalPackage = getPackageObject("scala.reflect.makro.internal") def MacroInternal_materializeClassTag = getMember(MacroInternalPackage, nme.materializeClassTag) def MacroInternal_materializeTypeTag = getMember(MacroInternalPackage, nme.materializeTypeTag) - def MacroInternal_materializeGroundTypeTag = getMember(MacroInternalPackage, nme.materializeGroundTypeTag) + def MacroInternal_materializeConcreteTypeTag = getMember(MacroInternalPackage, nme.materializeConcreteTypeTag) lazy val ScalaSignatureAnnotation = getRequiredClass("scala.reflect.ScalaSignature") lazy val ScalaLongSignatureAnnotation = getRequiredClass("scala.reflect.ScalaLongSignature") diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index b72610f1e0..1666887133 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -126,7 +126,7 @@ trait StdNames extends NameManglers { self: SymbolTable => final val Symbol: NameType = "Symbol" final val ClassTag: NameType = "ClassTag" final val TypeTag : NameType = "TypeTag" - final val GroundTypeTag: NameType = "GroundTypeTag" + final val ConcreteTypeTag: NameType = "ConcreteTypeTag" // fictions we use as both types and terms final val ERROR: NameType = "" @@ -396,7 +396,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val map: NameType = "map" val materializeClassTag: NameType = "materializeClassTag" val materializeTypeTag: NameType = "materializeTypeTag" - val materializeGroundTypeTag: NameType = "materializeGroundTypeTag" + val materializeConcreteTypeTag: NameType = "materializeConcreteTypeTag" val mirror : NameType = "mirror" val moduleClass : NameType = "moduleClass" val name: NameType = "name" diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala index 826fa7153f..2488b06d6c 100644 --- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -21,16 +21,16 @@ trait Reifiers { def reifyTree(prefix: Tree, tree: Tree): Tree = reifyTopLevel(prefix, tree) - def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, noTypeVariablesInResult: Boolean = false): Tree = - reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, noTypeVariablesInResult) + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree = + reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, requireConcreteTypeTag) def unreifyTree(tree: Tree): Tree = Select(tree, definitions.ExprEval) - def reifyTopLevel(prefix: Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Tree = { + def reifyTopLevel(prefix: Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree = { // [Eugene] the plumbing is not very pretty, but anyways factoring out the reifier seems like a necessary step to me import scala.reflect.reify._ - val reifier = mkReifier(mirror)(callsiteTyper, prefix, reifee, dontSpliceAtTopLevel, requireGroundTypeTag) + val reifier = mkReifier(mirror)(callsiteTyper, prefix, reifee, dontSpliceAtTopLevel, requireConcreteTypeTag) try { val result = reifier.reified diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala index 8bfe64621b..30c6c06c7b 100644 --- a/src/compiler/scala/reflect/reify/Errors.scala +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -33,8 +33,8 @@ trait Errors { throw new ReificationError(defaultErrorPosition, msg) } - def CannotReifyGroundTypeTagHavingUnresolvedTypeParameters(tpe: Type) = { - val msg = "cannot reify GroundTypeTag having unresolved type parameter %s".format(tpe) + def CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(tpe: Type) = { + val msg = "cannot reify ConcreteTypeTag having unresolved type parameter %s".format(tpe) throw new ReificationError(defaultErrorPosition, msg) } diff --git a/src/compiler/scala/reflect/reify/Reifiers.scala b/src/compiler/scala/reflect/reify/Reifiers.scala index 6854710949..16c26734b2 100644 --- a/src/compiler/scala/reflect/reify/Reifiers.scala +++ b/src/compiler/scala/reflect/reify/Reifiers.scala @@ -21,7 +21,7 @@ abstract class Reifier extends Phases val prefix: Tree val reifee: Any val dontSpliceAtTopLevel: Boolean - val requireGroundTypeTag: Boolean + val requireConcreteTypeTag: Boolean /** * For ``reifee'' and other reification parameters, generate a tree of the form @@ -74,7 +74,7 @@ abstract class Reifier extends Phases val manifestedType = typer.packedType(tree, NoSymbol) val manifestedRtype = reifyType(manifestedType) - val tagModule = if (definitelyGround) GroundTypeTagModule else TypeTagModule + val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule var typeTagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) var exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType))) Apply(Apply(exprCtor, List(rtree)), List(Apply(typeTagCtor, List(manifestedRtype)))) @@ -85,7 +85,7 @@ abstract class Reifier extends Phases val rtree = reify(tpe) val manifestedType = tpe - var tagModule = if (definitelyGround) GroundTypeTagModule else TypeTagModule + var tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule var ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) Apply(ctor, List(rtree)) diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala index 6f3a60a076..9bc113e8a4 100644 --- a/src/compiler/scala/reflect/reify/codegen/Types.scala +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -67,8 +67,8 @@ trait Types { private var spliceTypesEnabled = !dontSpliceAtTopLevel /** Keeps track of whether this reification contains abstract type parameters */ - var maybeGround = true - var definitelyGround = true + var maybeConcrete = true + var definitelyConcrete = true def eligibleForSplicing(tpe: Type): Boolean = { // [Eugene] is this comprehensive? @@ -88,7 +88,7 @@ trait Types { if (reifyDebug) println("splicing " + tpe) if (spliceTypesEnabled) { - var tagClass = if (requireGroundTypeTag) GroundTypeTagClass else TypeTagClass + var tagClass = if (requireConcreteTypeTag) ConcreteTypeTagClass else TypeTagClass val tagTpe = singleType(prefix.tpe, prefix.tpe member tagClass.name) // [Eugene] this should be enough for an abstract type, right? @@ -99,16 +99,16 @@ trait Types { // to find out the whereabouts of the error run scalac with -Ydebug if (reifyDebug) println("launching implicit search for %s.%s[%s]".format(prefix, tagClass.name, tpe)) val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] - typer.resolveTypeTag(positionBearer, prefix.tpe, tpe, requireGroundTypeTag) match { + typer.resolveTypeTag(positionBearer, prefix.tpe, tpe, requireConcreteTypeTag) match { case failure if failure.isEmpty => if (reifyDebug) println("implicit search was fruitless") - definitelyGround &= false - maybeGround &= false + definitelyConcrete &= false + maybeConcrete &= false EmptyTree case success => if (reifyDebug) println("implicit search has produced a result: " + success) - definitelyGround |= requireGroundTypeTag - maybeGround |= true + definitelyConcrete |= requireConcreteTypeTag + maybeConcrete |= true var splice = Select(success, nme.tpe) splice match { case InlinedTypeSplice(_, inlinedSymbolTable, tpe) => @@ -126,8 +126,8 @@ trait Types { if (reifyDebug) println("splicing has been cancelled: spliceTypesEnabled = false") } - if (requireGroundTypeTag) - CannotReifyGroundTypeTagHavingUnresolvedTypeParameters(tpe) + if (requireConcreteTypeTag) + CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(tpe) } spliceTypesEnabled = true diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index 7041fbf6ed..85cf92fe2f 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -3,12 +3,12 @@ package scala.reflect import scala.tools.nsc.Global package object reify { - def mkReifier(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Reifier { val mirror: global.type } = { + def mkReifier(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Reifier { val mirror: global.type } = { val typer1: typer.type = typer val prefix1: prefix.type = prefix val reifee1 = reifee val dontSpliceAtTopLevel1 = dontSpliceAtTopLevel - val requireGroundTypeTag1 = requireGroundTypeTag + val requireConcreteTypeTag1 = requireConcreteTypeTag new { val mirror: global.type = global @@ -16,7 +16,7 @@ package object reify { val prefix = prefix1 val reifee = reifee1 val dontSpliceAtTopLevel = dontSpliceAtTopLevel1 - val requireGroundTypeTag = requireGroundTypeTag1 + val requireConcreteTypeTag = requireConcreteTypeTag1 } with Reifier } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 8aa257983a..3a789b83b6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1099,11 +1099,11 @@ trait Implicits { } // these should be lazy, otherwise we wouldn't be able to compile scala-library with starr - private val TagSymbols = Set(ClassTagClass, TypeTagClass, GroundTypeTagClass) + private val TagSymbols = Set(ClassTagClass, TypeTagClass, ConcreteTypeTagClass) private val TagMaterializers = Map( ClassTagClass -> MacroInternal_materializeClassTag, TypeTagClass -> MacroInternal_materializeTypeTag, - GroundTypeTagClass -> MacroInternal_materializeGroundTypeTag + ConcreteTypeTagClass -> MacroInternal_materializeConcreteTypeTag ) def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 3b270a92ad..9608108a0d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -877,7 +877,7 @@ trait Macros { self: Analyzer => tpe }) map (tpe => { val ttag = TypeTag(tpe) - if (ttag.isGround) ttag.toGround else ttag + if (ttag.isConcrete) ttag.toConcrete else ttag }) argss = argss.dropRight(1) :+ (evidences ++ argss.last) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1b508a96fe..5d9b8ae94a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5020,7 +5020,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def resolveTypeTag(tree: Tree, pre: Type, tp: Type, full: Boolean): Tree = beforeTyper { inferImplicit( EmptyTree, - appliedType(singleType(pre, pre member (if (full) GroundTypeTagClass else TypeTagClass).name), List(tp)), + appliedType(singleType(pre, pre member (if (full) ConcreteTypeTagClass else TypeTagClass).name), List(tp)), /*reportAmbiguous =*/ true, /*isView =*/ false, /*context =*/ context, diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index d241d2ddc0..837ce96baa 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -103,12 +103,12 @@ object Predef extends LowPriorityImplicits { type ClassManifest[T] = scala.reflect.ClassManifest[T] @deprecated("OptManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0") type OptManifest[T] = scala.reflect.OptManifest[T] - @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") type Manifest[T] = scala.reflect.Manifest[T] @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") val ClassManifest = scala.reflect.ClassManifest // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies. - @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") lazy val Manifest = scala.reflect.Manifest // needs to be lazy, because requires scala.reflect.mirror instance @deprecated("NoManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0") lazy val NoManifest = scala.reflect.NoManifest // needs to be lazy, because requires scala.reflect.mirror instance @@ -118,20 +118,20 @@ object Predef extends LowPriorityImplicits { def optManifest[T](implicit m: OptManifest[T]) = m // Tag types and companions, and incantations for summoning - type ClassTag[T] = scala.reflect.ClassTag[T] - type TypeTag[T] = scala.reflect.TypeTag[T] - type GroundTypeTag[T] = scala.reflect.GroundTypeTag[T] - val ClassTag = scala.reflect.ClassTag // doesn't need to be lazy, because it's not a path-dependent type + type ClassTag[T] = scala.reflect.ClassTag[T] + type TypeTag[T] = scala.reflect.TypeTag[T] + type ConcreteTypeTag[T] = scala.reflect.ConcreteTypeTag[T] + val ClassTag = scala.reflect.ClassTag // doesn't need to be lazy, because it's not a path-dependent type // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies. - lazy val TypeTag = scala.reflect.TypeTag // needs to be lazy, because requires scala.reflect.mirror instance - lazy val GroundTypeTag = scala.reflect.GroundTypeTag + lazy val TypeTag = scala.reflect.TypeTag // needs to be lazy, because requires scala.reflect.mirror instance + lazy val ConcreteTypeTag = scala.reflect.ConcreteTypeTag // [Eugene to Martin] it's really tedious to type "implicitly[...]" all the time, so I'm reintroducing these shortcuts - def classTag[T](implicit ctag: ClassTag[T]) = ctag - def tag[T](implicit ttag: TypeTag[T]) = ttag - def typeTag[T](implicit ttag: TypeTag[T]) = ttag - def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag - def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag + def classTag[T](implicit ctag: ClassTag[T]) = ctag + def tag[T](implicit ttag: TypeTag[T]) = ttag + def typeTag[T](implicit ttag: TypeTag[T]) = ttag + def concreteTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag + def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag // Minor variations on identity functions def identity[A](x: A): A = x // @see `conforms` for the implicit version diff --git a/src/library/scala/reflect/ClassTags.scala b/src/library/scala/reflect/ClassTags.scala index 2833e7cc8e..cde6da5539 100644 --- a/src/library/scala/reflect/ClassTags.scala +++ b/src/library/scala/reflect/ClassTags.scala @@ -4,11 +4,20 @@ import java.lang.{ Class => jClass } import scala.reflect.{ mirror => rm } /** A `ClassTag[T]` wraps a Java class, which can be accessed via the `erasure` method. + * * This is useful in itself, but also enables very important use case. * Having this knowledge ClassTag can instantiate `Arrays` * in those cases where the element type is unknown at compile time. * Hence, ClassTag[T] conforms to the ArrayTag[T] trait. - */ + * + * If an implicit value of type u.ClassTag[T] is required, the compiler will make one up on demand. + * The implicitly created value contains in its erasure field the Java class that is the result of erasing type T. + * In that value, any occurrences of type parameters or abstract types U which come themselves with a ClassTag + * or a reflect.mirror.ConcreteTypeTag are represented by the type referenced by that tag. + * If the type T contains unresolved references to type parameters or abstract types, a static error results. + * + * A ConcreteTypeTag member of the reflect.mirror object is convertible to a ClassTag via an implicit conversion + * (this is not possible to do in all reflection universes because an operation that converts a type to a Java class might not be available). */ // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` // class tags, and all tags in general, should be as minimalistic as possible @annotation.implicitNotFound(msg = "No ClassTag available for ${T}") @@ -20,7 +29,7 @@ abstract case class ClassTag[T](erasure: jClass[_]) extends ArrayTag[T] { /** A Scala reflection type representing T. * For ClassTags this representation is lossy (in their case tpe is retrospectively constructed from erasure). - * For TypeTags and GroundTypeTags the representation is almost precise, because it uses reification + * For TypeTags and ConcreteTypeTags the representation is almost precise, because they use reification * (information is lost only when T refers to non-locatable symbols, which are then reified as free variables). */ def tpe: rm.Type = rm.classToType(erasure) @@ -153,6 +162,6 @@ class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) { @deprecated("Use `@scala.collection.mutable.ArrayBuilder` object instead", "2.10.0") def newArrayBuilder(): ArrayBuilder[T] = ArrayBuilder.make[T]()(ctag) - @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.GroundTypeTag` to capture and analyze type arguments", "2.10.0") + @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.ConcreteTypeTag` to capture and analyze type arguments", "2.10.0") def typeArguments: List[OptManifest[_]] = List() } \ No newline at end of file diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala index 991feb3bac..5918b6effc 100644 --- a/src/library/scala/reflect/TagMaterialization.scala +++ b/src/library/scala/reflect/TagMaterialization.scala @@ -18,13 +18,13 @@ object TagMaterialization { def materializeTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.TypeTag[T]] = { import c.mirror._ val tpe = implicitly[c.TypeTag[T]].tpe - c.materializeTypeTag(tpe, requireGroundTypeTag = false) + c.materializeTypeTag(tpe, requireConcreteTypeTag = false) } - def materializeGroundTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.GroundTypeTag[T]] = { + def materializeConcreteTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.ConcreteTypeTag[T]] = { import c.mirror._ val tpe = implicitly[c.TypeTag[T]].tpe - c.materializeTypeTag(tpe, requireGroundTypeTag = true) + c.materializeTypeTag(tpe, requireConcreteTypeTag = true) } private implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils @@ -52,17 +52,17 @@ object TagMaterialization { NothingClass.asType -> newTermName("Nothing"), NullClass.asType -> newTermName("Null")) - val ReflectPackage = staticModule("scala.reflect.package") - val Reflect_mirror = selectTerm(ReflectPackage, "mirror") - val ClassTagClass = staticClass("scala.reflect.ClassTag") - val ClassTagErasure = selectTerm(ClassTagClass, "erasure") - val ClassTagModule = staticModule("scala.reflect.ClassTag") - val TypeTagsClass = staticClass("scala.reflect.api.TypeTags") - val TypeTagClass = selectType(TypeTagsClass, "TypeTag") - val TypeTagTpe = selectTerm(TypeTagClass, "tpe") - val TypeTagModule = selectTerm(TypeTagsClass, "TypeTag") - val GroundTypeTagClass = selectType(TypeTagsClass, "GroundTypeTag") - val GroundTypeTagModule = selectTerm(TypeTagsClass, "GroundTypeTag") + val ReflectPackage = staticModule("scala.reflect.package") + val Reflect_mirror = selectTerm(ReflectPackage, "mirror") + val ClassTagClass = staticClass("scala.reflect.ClassTag") + val ClassTagErasure = selectTerm(ClassTagClass, "erasure") + val ClassTagModule = staticModule("scala.reflect.ClassTag") + val TypeTagsClass = staticClass("scala.reflect.api.TypeTags") + val TypeTagClass = selectType(TypeTagsClass, "TypeTag") + val TypeTagTpe = selectTerm(TypeTagClass, "tpe") + val TypeTagModule = selectTerm(TypeTagsClass, "TypeTag") + val ConcreteTypeTagClass = selectType(TypeTagsClass, "ConcreteTypeTag") + val ConcreteTypeTagModule = selectTerm(TypeTagsClass, "ConcreteTypeTag") def materializeClassTag(tpe: Type): Tree = { val prefix = gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror) @@ -70,8 +70,8 @@ object TagMaterialization { } def materializeClassTag(prefix: Tree, tpe: Type): Tree = { - val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, TypeTagClass, Nil), List(tpe))) - def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == GroundTypeTagModule)) + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) typetagInScope match { case success if !success.isEmpty && !typetagIsSynthetic(success) => val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) @@ -104,19 +104,19 @@ object TagMaterialization { } } - def materializeTypeTag(tpe: Type, requireGroundTypeTag: Boolean): Tree = { + def materializeTypeTag(tpe: Type, requireConcreteTypeTag: Boolean): Tree = { def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix - materializeTypeTag(prefix, tpe, requireGroundTypeTag) + materializeTypeTag(prefix, tpe, requireConcreteTypeTag) } - def materializeTypeTag(prefix: Tree, tpe: Type, requireGroundTypeTag: Boolean): Tree = { - val tagModule = if (requireGroundTypeTag) GroundTypeTagModule else TypeTagModule + def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { + val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule val result = tpe match { case coreTpe if coreTags contains coreTpe => Select(Select(prefix, tagModule.name), coreTags(coreTpe)) case _ => - try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireGroundTypeTag = requireGroundTypeTag) + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) catch { case ex: Throwable => // [Eugene] cannot pattern match on an abstract type, so had to do this diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala index b4fedbe055..e457bb73e0 100755 --- a/src/library/scala/reflect/api/StandardDefinitions.scala +++ b/src/library/scala/reflect/api/StandardDefinitions.scala @@ -113,8 +113,8 @@ trait StandardDefinitions { self: Universe => def ClassTagModule: Symbol def TypeTagClass: Symbol def TypeTagModule: Symbol - def GroundTypeTagClass: Symbol - def GroundTypeTagModule: Symbol + def ConcreteTypeTagClass: Symbol + def ConcreteTypeTagModule: Symbol /** Given a type T, returns the type corresponding to the VM's * representation: ClassClass's type constructor applied to `arg`. diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index a38c21a9d4..ed47620e13 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -14,14 +14,16 @@ import scala.reflect.{ mirror => rm } * TypeTags are much better integrated with reflection than manifests are, and are consequently much simpler. * * Type tags are organized in a hierarchy of two classes: - * [[scala.reflect.ClassTag]], [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#GroundTypeTag]]. - * A [[scala.reflect.ClassTag]] value wraps a Java class, which can be accessed via the erasure method. + * [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#ConcreteTypeTag]]. * A [[scala.reflect.api.Universe#TypeTag]] value wraps a full Scala type in its tpe field. - * A [[scala.reflect.api.Universe#GroundTypeTag]] value is a type tag that is guaranteed not to contain any references to type parameters or abstract types. + * A [[scala.reflect.api.Universe#ConcreteTypeTag]] value is a type tag that is guaranteed not to contain any references to type parameters or abstract types. + * + * It is also possible to capture Java classes by using a different kind of tag. + * A [[scala.reflect.ClassTag]] value wraps a Java class, which can be accessed via the erasure method. * * TypeTags correspond loosely to Manifests. More precisely: * The previous notion of a [[scala.reflect.ClassManifest]] corresponds to a scala.reflect.ClassTag, - * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.mirror.GroundTypeTag, + * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.mirror.ConcreteTypeTag, * Whereas scala.reflect.mirror.TypeTag is approximated by the previous notion of [[scala.reflect.OptManifest]]. * * Implicit in the contract for all Tag classes is that the reified type tpe represents the type parameter T. @@ -59,38 +61,34 @@ trait TypeTags { self: Universe => def sym = tpe.typeSymbol - def isGround = !isNotGround - def isNotGround = tpe exists (_.typeSymbol.isAbstractType) - - def toGround: GroundTypeTag[T] = { - assert(isGround, tpe) - GroundTypeTag[T](tpe) - } + def isConcrete = !isNotConcrete + def isNotConcrete = tpe exists (_.typeSymbol.isAbstractType) + def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe) override def toString = { - var prefix = if (isGround) "GroundTypeTag" else "TypeTag" + var prefix = if (isConcrete) "ConcreteTypeTag" else "TypeTag" if (prefix != this.productPrefix) prefix = "*" + prefix prefix + "[" + tpe + "]" } } object TypeTag { - val Byte : TypeTag[scala.Byte] = GroundTypeTag.Byte - val Short : TypeTag[scala.Short] = GroundTypeTag.Short - val Char : TypeTag[scala.Char] = GroundTypeTag.Char - val Int : TypeTag[scala.Int] = GroundTypeTag.Int - val Long : TypeTag[scala.Long] = GroundTypeTag.Long - val Float : TypeTag[scala.Float] = GroundTypeTag.Float - val Double : TypeTag[scala.Double] = GroundTypeTag.Double - val Boolean : TypeTag[scala.Boolean] = GroundTypeTag.Boolean - val Unit : TypeTag[scala.Unit] = GroundTypeTag.Unit - val Any : TypeTag[scala.Any] = GroundTypeTag.Any - val Object : TypeTag[java.lang.Object] = GroundTypeTag.Object - val AnyVal : TypeTag[scala.AnyVal] = GroundTypeTag.AnyVal - val AnyRef : TypeTag[scala.AnyRef] = GroundTypeTag.AnyRef - val Nothing : TypeTag[scala.Nothing] = GroundTypeTag.Nothing - val Null : TypeTag[scala.Null] = GroundTypeTag.Null - val String : TypeTag[java.lang.String] = GroundTypeTag.String + val Byte : TypeTag[scala.Byte] = ConcreteTypeTag.Byte + val Short : TypeTag[scala.Short] = ConcreteTypeTag.Short + val Char : TypeTag[scala.Char] = ConcreteTypeTag.Char + val Int : TypeTag[scala.Int] = ConcreteTypeTag.Int + val Long : TypeTag[scala.Long] = ConcreteTypeTag.Long + val Float : TypeTag[scala.Float] = ConcreteTypeTag.Float + val Double : TypeTag[scala.Double] = ConcreteTypeTag.Double + val Boolean : TypeTag[scala.Boolean] = ConcreteTypeTag.Boolean + val Unit : TypeTag[scala.Unit] = ConcreteTypeTag.Unit + val Any : TypeTag[scala.Any] = ConcreteTypeTag.Any + val Object : TypeTag[java.lang.Object] = ConcreteTypeTag.Object + val AnyVal : TypeTag[scala.AnyVal] = ConcreteTypeTag.AnyVal + val AnyRef : TypeTag[scala.AnyRef] = ConcreteTypeTag.AnyRef + val Nothing : TypeTag[scala.Nothing] = ConcreteTypeTag.Nothing + val Null : TypeTag[scala.Null] = ConcreteTypeTag.Null + val String : TypeTag[java.lang.String] = ConcreteTypeTag.String def apply[T](tpe: Type): TypeTag[T] = tpe match { @@ -115,64 +113,67 @@ trait TypeTags { self: Universe => } /** - * If an implicit value of type u.GroundTypeTag[T] is required, the compiler will make one up on demand following the same procedure as for TypeTags. + * If an implicit value of type u.ConcreteTypeTag[T] is required, the compiler will make one up on demand following the same procedure as for TypeTags. * However, if the resulting type still contains references to type parameters or abstract types, a static error results. * * @see [[scala.reflect.api.TypeTags]] */ - @annotation.implicitNotFound(msg = "No GroundTypeTag available for ${T}") - class GroundTypeTag[T](tpe: Type) extends TypeTag[T](tpe) { - assert(isGround, tpe) - override def productPrefix = "GroundTypeTag" + @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}") + class ConcreteTypeTag[T](tpe: Type) extends TypeTag[T](tpe) { + // it's unsafe to use assert here, because we might run into deadlocks with Predef + // also see comments in ClassTags.scala + //assert(isConcrete, tpe) + if (isNotConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind)) + override def productPrefix = "ConcreteTypeTag" } - object GroundTypeTag { - val Byte : GroundTypeTag[scala.Byte] = new GroundTypeTag[scala.Byte](ByteTpe) { private def readResolve() = GroundTypeTag.Byte } - val Short : GroundTypeTag[scala.Short] = new GroundTypeTag[scala.Short](ShortTpe) { private def readResolve() = GroundTypeTag.Short } - val Char : GroundTypeTag[scala.Char] = new GroundTypeTag[scala.Char](CharTpe) { private def readResolve() = GroundTypeTag.Char } - val Int : GroundTypeTag[scala.Int] = new GroundTypeTag[scala.Int](IntTpe) { private def readResolve() = GroundTypeTag.Int } - val Long : GroundTypeTag[scala.Long] = new GroundTypeTag[scala.Long](LongTpe) { private def readResolve() = GroundTypeTag.Long } - val Float : GroundTypeTag[scala.Float] = new GroundTypeTag[scala.Float](FloatTpe) { private def readResolve() = GroundTypeTag.Float } - val Double : GroundTypeTag[scala.Double] = new GroundTypeTag[scala.Double](DoubleTpe) { private def readResolve() = GroundTypeTag.Double } - val Boolean : GroundTypeTag[scala.Boolean] = new GroundTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = GroundTypeTag.Boolean } - val Unit : GroundTypeTag[scala.Unit] = new GroundTypeTag[scala.Unit](UnitTpe) { private def readResolve() = GroundTypeTag.Unit } - val Any : GroundTypeTag[scala.Any] = new GroundTypeTag[scala.Any](AnyTpe) { private def readResolve() = GroundTypeTag.Any } - val Object : GroundTypeTag[java.lang.Object] = new GroundTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = GroundTypeTag.Object } - val AnyVal : GroundTypeTag[scala.AnyVal] = new GroundTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = GroundTypeTag.AnyVal } - val AnyRef : GroundTypeTag[scala.AnyRef] = new GroundTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = GroundTypeTag.AnyRef } - val Nothing : GroundTypeTag[scala.Nothing] = new GroundTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = GroundTypeTag.Nothing } - val Null : GroundTypeTag[scala.Null] = new GroundTypeTag[scala.Null](NullTpe) { private def readResolve() = GroundTypeTag.Null } - val String : GroundTypeTag[java.lang.String] = new GroundTypeTag[java.lang.String](StringTpe) { private def readResolve() = GroundTypeTag.String } - - def apply[T](tpe: Type): GroundTypeTag[T] = + object ConcreteTypeTag { + val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe) { private def readResolve() = ConcreteTypeTag.Byte } + val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe) { private def readResolve() = ConcreteTypeTag.Short } + val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe) { private def readResolve() = ConcreteTypeTag.Char } + val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe) { private def readResolve() = ConcreteTypeTag.Int } + val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe) { private def readResolve() = ConcreteTypeTag.Long } + val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe) { private def readResolve() = ConcreteTypeTag.Float } + val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe) { private def readResolve() = ConcreteTypeTag.Double } + val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = ConcreteTypeTag.Boolean } + val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe) { private def readResolve() = ConcreteTypeTag.Unit } + val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe) { private def readResolve() = ConcreteTypeTag.Any } + val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = ConcreteTypeTag.Object } + val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = ConcreteTypeTag.AnyVal } + val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = ConcreteTypeTag.AnyRef } + val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = ConcreteTypeTag.Nothing } + val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe) { private def readResolve() = ConcreteTypeTag.Null } + val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe) { private def readResolve() = ConcreteTypeTag.String } + + def apply[T](tpe: Type): ConcreteTypeTag[T] = tpe match { - case ByteTpe => GroundTypeTag.Byte.asInstanceOf[GroundTypeTag[T]] - case ShortTpe => GroundTypeTag.Short.asInstanceOf[GroundTypeTag[T]] - case CharTpe => GroundTypeTag.Char.asInstanceOf[GroundTypeTag[T]] - case IntTpe => GroundTypeTag.Int.asInstanceOf[GroundTypeTag[T]] - case LongTpe => GroundTypeTag.Long.asInstanceOf[GroundTypeTag[T]] - case FloatTpe => GroundTypeTag.Float.asInstanceOf[GroundTypeTag[T]] - case DoubleTpe => GroundTypeTag.Double.asInstanceOf[GroundTypeTag[T]] - case BooleanTpe => GroundTypeTag.Boolean.asInstanceOf[GroundTypeTag[T]] - case UnitTpe => GroundTypeTag.Unit.asInstanceOf[GroundTypeTag[T]] - case AnyTpe => GroundTypeTag.Any.asInstanceOf[GroundTypeTag[T]] - case ObjectTpe => GroundTypeTag.Object.asInstanceOf[GroundTypeTag[T]] - case AnyValTpe => GroundTypeTag.AnyVal.asInstanceOf[GroundTypeTag[T]] - case AnyRefTpe => GroundTypeTag.AnyRef.asInstanceOf[GroundTypeTag[T]] - case NothingTpe => GroundTypeTag.Nothing.asInstanceOf[GroundTypeTag[T]] - case NullTpe => GroundTypeTag.Null.asInstanceOf[GroundTypeTag[T]] - case StringTpe => GroundTypeTag.String.asInstanceOf[GroundTypeTag[T]] - case _ => new GroundTypeTag[T](tpe) {} + case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]] + case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]] + case CharTpe => ConcreteTypeTag.Char.asInstanceOf[ConcreteTypeTag[T]] + case IntTpe => ConcreteTypeTag.Int.asInstanceOf[ConcreteTypeTag[T]] + case LongTpe => ConcreteTypeTag.Long.asInstanceOf[ConcreteTypeTag[T]] + case FloatTpe => ConcreteTypeTag.Float.asInstanceOf[ConcreteTypeTag[T]] + case DoubleTpe => ConcreteTypeTag.Double.asInstanceOf[ConcreteTypeTag[T]] + case BooleanTpe => ConcreteTypeTag.Boolean.asInstanceOf[ConcreteTypeTag[T]] + case UnitTpe => ConcreteTypeTag.Unit.asInstanceOf[ConcreteTypeTag[T]] + case AnyTpe => ConcreteTypeTag.Any.asInstanceOf[ConcreteTypeTag[T]] + case ObjectTpe => ConcreteTypeTag.Object.asInstanceOf[ConcreteTypeTag[T]] + case AnyValTpe => ConcreteTypeTag.AnyVal.asInstanceOf[ConcreteTypeTag[T]] + case AnyRefTpe => ConcreteTypeTag.AnyRef.asInstanceOf[ConcreteTypeTag[T]] + case NothingTpe => ConcreteTypeTag.Nothing.asInstanceOf[ConcreteTypeTag[T]] + case NullTpe => ConcreteTypeTag.Null.asInstanceOf[ConcreteTypeTag[T]] + case StringTpe => ConcreteTypeTag.String.asInstanceOf[ConcreteTypeTag[T]] + case _ => new ConcreteTypeTag[T](tpe) {} } - def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isGround) Some(ttag.tpe) else None + def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None - implicit def toClassTag[T](ttag: rm.GroundTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure)) + implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure)) - implicit def toDeprecatedManifestApis[T](ttag: rm.GroundTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) + implicit def toDeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) // this class should not be used directly in client code - class DeprecatedManifestApis[T](ttag: rm.GroundTypeTag[T]) extends DeprecatedClassManifestApis[T](toClassTag(ttag)) { + class DeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]) extends DeprecatedClassManifestApis[T](toClassTag(ttag)) { @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") def <:<(that: Manifest[_]): Boolean = ttag.tpe <:< that.tpe @@ -180,7 +181,7 @@ trait TypeTags { self: Universe => def >:>(that: Manifest[_]): Boolean = that <:< ttag @deprecated("Use `tpe` to analyze the type arguments", "2.10.0") - override def typeArguments: List[Manifest[_]] = ttag.tpe.typeArguments map (targ => rm.GroundTypeTag(targ)) + override def typeArguments: List[Manifest[_]] = ttag.tpe.typeArguments map (targ => rm.ConcreteTypeTag(targ)) } } @@ -188,6 +189,6 @@ trait TypeTags { self: Universe => // moved to Context, since rm.tags have their own incantations in Predef, and these guys are only useful in macros // def tag[T](implicit ttag: TypeTag[T]) = ttag // def typeTag[T](implicit ttag: TypeTag[T]) = ttag -// def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag -// def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag +// def concreteTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag +// def concreteTypeTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag } \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Aliases.scala b/src/library/scala/reflect/makro/Aliases.scala index e8b847600c..38b1065a40 100644 --- a/src/library/scala/reflect/makro/Aliases.scala +++ b/src/library/scala/reflect/makro/Aliases.scala @@ -21,6 +21,6 @@ trait Aliases { /** incantations for summoning tags */ def tag[T](implicit ttag: TypeTag[T]) = ttag def typeTag[T](implicit ttag: TypeTag[T]) = ttag - def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag - def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag + def concreteTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag + def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag } diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala index 9bd25cf0f8..d690df6aee 100644 --- a/src/library/scala/reflect/makro/Reifiers.scala +++ b/src/library/scala/reflect/makro/Reifiers.scala @@ -46,7 +46,7 @@ trait Reifiers { * The produced tree will be bound to the mirror specified by ``prefix'' (also see ``reflectMirrorPrefix''). * For more information and examples see the documentation for ``Context.reifyTree'' and ``Universe.reify''. */ - def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Tree + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree /** Undoes reification of a tree. * diff --git a/src/library/scala/reflect/makro/internal/typeTagImpl.scala b/src/library/scala/reflect/makro/internal/typeTagImpl.scala index 6c49ef45de..de404ff39f 100644 --- a/src/library/scala/reflect/makro/internal/typeTagImpl.scala +++ b/src/library/scala/reflect/makro/internal/typeTagImpl.scala @@ -16,14 +16,14 @@ package object internal { /** This method is required by the compiler and should not be used in client code. */ def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.TypeTag[T]] = - c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireGroundTypeTag = false))(c.TypeTag.Nothing) + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireConcreteTypeTag = false))(c.TypeTag.Nothing) /** This method is required by the compiler and should not be used in client code. */ - def materializeGroundTypeTag[T](u: Universe): u.GroundTypeTag[T] = macro materializeGroundTypeTag_impl[T] + def materializeConcreteTypeTag[T](u: Universe): u.ConcreteTypeTag[T] = macro materializeConcreteTypeTag_impl[T] /** This method is required by the compiler and should not be used in client code. */ - def materializeGroundTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.GroundTypeTag[T]] = - c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireGroundTypeTag = true))(c.TypeTag.Nothing) + def materializeConcreteTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.ConcreteTypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireConcreteTypeTag = true))(c.TypeTag.Nothing) /** This method is required by the compiler and should not be used in client code. */ private[scala] implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils @@ -54,8 +54,8 @@ package internal { NullClass.asType -> newTermName("Null")) def materializeClassTag(prefix: Tree, tpe: Type): Tree = { - val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, TypeTagClass, Nil), List(tpe))) - def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == GroundTypeTagModule)) + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) typetagInScope match { case success if !success.isEmpty && !typetagIsSynthetic(success) => val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) @@ -88,14 +88,14 @@ package internal { } } - def materializeTypeTag(prefix: Tree, tpe: Type, requireGroundTypeTag: Boolean): Tree = { - val tagModule = if (requireGroundTypeTag) GroundTypeTagModule else TypeTagModule + def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { + val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule val result = tpe match { case coreTpe if coreTags contains coreTpe => Select(Select(prefix, tagModule.name), coreTags(coreTpe)) case _ => - try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireGroundTypeTag = requireGroundTypeTag) + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) catch { case ex: Throwable => // [Eugene] cannot pattern match on an abstract type, so had to do this diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 7a8267e689..1738642932 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -43,21 +43,21 @@ package object reflect { type ClassManifest[T] = ClassTag[T] @deprecated("OptManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") type OptManifest[T] = TypeTag[T] - @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") - type Manifest[T] = GroundTypeTag[T] + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") + type Manifest[T] = ConcreteTypeTag[T] @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") val ClassManifest = ClassTag - @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") - lazy val Manifest = GroundTypeTag + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") + lazy val Manifest = ConcreteTypeTag @deprecated("NoManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.definitions.NothingClass.asType) with Serializable // ClassTag class is defined separately from the mirror - type TypeTag[T] = scala.reflect.mirror.TypeTag[T] - type GroundTypeTag[T] = scala.reflect.mirror.GroundTypeTag[T] + type TypeTag[T] = scala.reflect.mirror.TypeTag[T] + type ConcreteTypeTag[T] = scala.reflect.mirror.ConcreteTypeTag[T] // ClassTag object is defined separately from the mirror - lazy val TypeTag = scala.reflect.mirror.TypeTag - lazy val GroundTypeTag = scala.reflect.mirror.GroundTypeTag + lazy val TypeTag = scala.reflect.mirror.TypeTag + lazy val ConcreteTypeTag = scala.reflect.mirror.ConcreteTypeTag } diff --git a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check index d9c390ba25..39e90f827e 100644 --- a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check +++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check @@ -1,7 +1,7 @@ -Test.scala:5: error: No GroundTypeTag available for C[T] - println(implicitly[GroundTypeTag[C[T]]]) +Test.scala:5: error: No ConcreteTypeTag available for C[T] + println(implicitly[ConcreteTypeTag[C[T]]]) ^ -Test.scala:6: error: No GroundTypeTag available for List[C[T]] - println(implicitly[GroundTypeTag[List[C[T]]]]) +Test.scala:6: error: No ConcreteTypeTag available for List[C[T]] + println(implicitly[ConcreteTypeTag[List[C[T]]]]) ^ two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala index d5ee61b91d..1302999da6 100644 --- a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala +++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala @@ -2,8 +2,8 @@ import scala.reflect.mirror._ object Test extends App { def fooNoTypeTagHK[C[_], T] = { - println(implicitly[GroundTypeTag[C[T]]]) - println(implicitly[GroundTypeTag[List[C[T]]]]) + println(implicitly[ConcreteTypeTag[C[T]]]) + println(implicitly[ConcreteTypeTag[List[C[T]]]]) } fooNoTypeTagHK[List, Int] } \ No newline at end of file diff --git a/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check index c678a2a313..164ca3543f 100644 --- a/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check +++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check @@ -1,7 +1,7 @@ -Test.scala:5: error: No GroundTypeTag available for T - println(implicitly[GroundTypeTag[T]]) +Test.scala:5: error: No ConcreteTypeTag available for T + println(implicitly[ConcreteTypeTag[T]]) ^ -Test.scala:6: error: No GroundTypeTag available for List[T] - println(implicitly[GroundTypeTag[List[T]]]) +Test.scala:6: error: No ConcreteTypeTag available for List[T] + println(implicitly[ConcreteTypeTag[List[T]]]) ^ two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala b/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala index 98bdf6d67f..d2276ce333 100644 --- a/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala +++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala @@ -2,8 +2,8 @@ import scala.reflect.mirror._ object Test extends App { def fooNoTypeTag[T] = { - println(implicitly[GroundTypeTag[T]]) - println(implicitly[GroundTypeTag[List[T]]]) + println(implicitly[ConcreteTypeTag[T]]) + println(implicitly[ConcreteTypeTag[List[T]]]) } fooNoTypeTag[Int] } \ No newline at end of file diff --git a/test/files/neg/macro-reify-groundtypetag-usetypetag.check b/test/files/neg/macro-reify-groundtypetag-usetypetag.check index c678a2a313..164ca3543f 100644 --- a/test/files/neg/macro-reify-groundtypetag-usetypetag.check +++ b/test/files/neg/macro-reify-groundtypetag-usetypetag.check @@ -1,7 +1,7 @@ -Test.scala:5: error: No GroundTypeTag available for T - println(implicitly[GroundTypeTag[T]]) +Test.scala:5: error: No ConcreteTypeTag available for T + println(implicitly[ConcreteTypeTag[T]]) ^ -Test.scala:6: error: No GroundTypeTag available for List[T] - println(implicitly[GroundTypeTag[List[T]]]) +Test.scala:6: error: No ConcreteTypeTag available for List[T] + println(implicitly[ConcreteTypeTag[List[T]]]) ^ two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala b/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala index 507d03a390..d82cdc33e9 100644 --- a/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala +++ b/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala @@ -2,8 +2,8 @@ import scala.reflect.mirror._ object Test extends App { def fooTypeTag[T: TypeTag] = { - println(implicitly[GroundTypeTag[T]]) - println(implicitly[GroundTypeTag[List[T]]]) + println(implicitly[ConcreteTypeTag[T]]) + println(implicitly[ConcreteTypeTag[List[T]]]) } fooTypeTag[Int] } \ No newline at end of file diff --git a/test/files/neg/t3507.check b/test/files/neg/t3507.check index 6b6df6ba76..71bf295039 100644 --- a/test/files/neg/t3507.check +++ b/test/files/neg/t3507.check @@ -1,4 +1,4 @@ -t3507.scala:13: error: No GroundTypeTag available for _1.b.c.type +t3507.scala:13: error: No ConcreteTypeTag available for _1.b.c.type mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier ^ one error found diff --git a/test/files/neg/t3692.check b/test/files/neg/t3692.check index ec67e76bb4..d83abd31e2 100644 --- a/test/files/neg/t3692.check +++ b/test/files/neg/t3692.check @@ -1,7 +1,7 @@ -t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.GroundTypeTag` instead +t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.ConcreteTypeTag` instead private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = { ^ -t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.GroundTypeTag` instead +t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.ConcreteTypeTag` instead private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = { ^ t3692.scala:15: error: unreachable code diff --git a/test/files/run/groundtypetags_core.check b/test/files/run/groundtypetags_core.check index d1b71f0926..62fcb481ae 100644 --- a/test/files/run/groundtypetags_core.check +++ b/test/files/run/groundtypetags_core.check @@ -1,30 +1,30 @@ true -GroundTypeTag[Byte] +ConcreteTypeTag[Byte] true -GroundTypeTag[Short] +ConcreteTypeTag[Short] true -GroundTypeTag[Char] +ConcreteTypeTag[Char] true -GroundTypeTag[Int] +ConcreteTypeTag[Int] true -GroundTypeTag[Long] +ConcreteTypeTag[Long] true -GroundTypeTag[Float] +ConcreteTypeTag[Float] true -GroundTypeTag[Double] +ConcreteTypeTag[Double] true -GroundTypeTag[Boolean] +ConcreteTypeTag[Boolean] true -GroundTypeTag[Unit] +ConcreteTypeTag[Unit] true -GroundTypeTag[Any] +ConcreteTypeTag[Any] true -GroundTypeTag[Object] +ConcreteTypeTag[Object] true -GroundTypeTag[AnyVal] +ConcreteTypeTag[AnyVal] true -GroundTypeTag[AnyRef] +ConcreteTypeTag[AnyRef] true -GroundTypeTag[Null] +ConcreteTypeTag[Null] true -GroundTypeTag[Nothing] +ConcreteTypeTag[Nothing] diff --git a/test/files/run/groundtypetags_core.scala b/test/files/run/groundtypetags_core.scala index d779e3fc7e..8b81a0c795 100644 --- a/test/files/run/groundtypetags_core.scala +++ b/test/files/run/groundtypetags_core.scala @@ -1,32 +1,32 @@ object Test extends App { - println(implicitly[GroundTypeTag[Byte]] eq GroundTypeTag.Byte) - println(implicitly[GroundTypeTag[Byte]]) - println(implicitly[GroundTypeTag[Short]] eq GroundTypeTag.Short) - println(implicitly[GroundTypeTag[Short]]) - println(implicitly[GroundTypeTag[Char]] eq GroundTypeTag.Char) - println(implicitly[GroundTypeTag[Char]]) - println(implicitly[GroundTypeTag[Int]] eq GroundTypeTag.Int) - println(implicitly[GroundTypeTag[Int]]) - println(implicitly[GroundTypeTag[Long]] eq GroundTypeTag.Long) - println(implicitly[GroundTypeTag[Long]]) - println(implicitly[GroundTypeTag[Float]] eq GroundTypeTag.Float) - println(implicitly[GroundTypeTag[Float]]) - println(implicitly[GroundTypeTag[Double]] eq GroundTypeTag.Double) - println(implicitly[GroundTypeTag[Double]]) - println(implicitly[GroundTypeTag[Boolean]] eq GroundTypeTag.Boolean) - println(implicitly[GroundTypeTag[Boolean]]) - println(implicitly[GroundTypeTag[Unit]] eq GroundTypeTag.Unit) - println(implicitly[GroundTypeTag[Unit]]) - println(implicitly[GroundTypeTag[Any]] eq GroundTypeTag.Any) - println(implicitly[GroundTypeTag[Any]]) - println(implicitly[GroundTypeTag[Object]] eq GroundTypeTag.Object) - println(implicitly[GroundTypeTag[Object]]) - println(implicitly[GroundTypeTag[AnyVal]] eq GroundTypeTag.AnyVal) - println(implicitly[GroundTypeTag[AnyVal]]) - println(implicitly[GroundTypeTag[AnyRef]] eq GroundTypeTag.AnyRef) - println(implicitly[GroundTypeTag[AnyRef]]) - println(implicitly[GroundTypeTag[Null]] eq GroundTypeTag.Null) - println(implicitly[GroundTypeTag[Null]]) - println(implicitly[GroundTypeTag[Nothing]] eq GroundTypeTag.Nothing) - println(implicitly[GroundTypeTag[Nothing]]) + println(implicitly[ConcreteTypeTag[Byte]] eq ConcreteTypeTag.Byte) + println(implicitly[ConcreteTypeTag[Byte]]) + println(implicitly[ConcreteTypeTag[Short]] eq ConcreteTypeTag.Short) + println(implicitly[ConcreteTypeTag[Short]]) + println(implicitly[ConcreteTypeTag[Char]] eq ConcreteTypeTag.Char) + println(implicitly[ConcreteTypeTag[Char]]) + println(implicitly[ConcreteTypeTag[Int]] eq ConcreteTypeTag.Int) + println(implicitly[ConcreteTypeTag[Int]]) + println(implicitly[ConcreteTypeTag[Long]] eq ConcreteTypeTag.Long) + println(implicitly[ConcreteTypeTag[Long]]) + println(implicitly[ConcreteTypeTag[Float]] eq ConcreteTypeTag.Float) + println(implicitly[ConcreteTypeTag[Float]]) + println(implicitly[ConcreteTypeTag[Double]] eq ConcreteTypeTag.Double) + println(implicitly[ConcreteTypeTag[Double]]) + println(implicitly[ConcreteTypeTag[Boolean]] eq ConcreteTypeTag.Boolean) + println(implicitly[ConcreteTypeTag[Boolean]]) + println(implicitly[ConcreteTypeTag[Unit]] eq ConcreteTypeTag.Unit) + println(implicitly[ConcreteTypeTag[Unit]]) + println(implicitly[ConcreteTypeTag[Any]] eq ConcreteTypeTag.Any) + println(implicitly[ConcreteTypeTag[Any]]) + println(implicitly[ConcreteTypeTag[Object]] eq ConcreteTypeTag.Object) + println(implicitly[ConcreteTypeTag[Object]]) + println(implicitly[ConcreteTypeTag[AnyVal]] eq ConcreteTypeTag.AnyVal) + println(implicitly[ConcreteTypeTag[AnyVal]]) + println(implicitly[ConcreteTypeTag[AnyRef]] eq ConcreteTypeTag.AnyRef) + println(implicitly[ConcreteTypeTag[AnyRef]]) + println(implicitly[ConcreteTypeTag[Null]] eq ConcreteTypeTag.Null) + println(implicitly[ConcreteTypeTag[Null]]) + println(implicitly[ConcreteTypeTag[Nothing]] eq ConcreteTypeTag.Nothing) + println(implicitly[ConcreteTypeTag[Nothing]]) } \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-generic.check b/test/files/run/macro-expand-nullary-generic.check index 34a453cd3a..6dfe04af12 100644 --- a/test/files/run/macro-expand-nullary-generic.check +++ b/test/files/run/macro-expand-nullary-generic.check @@ -1,6 +1,6 @@ -it works GroundTypeTag[Int] -it works GroundTypeTag[Int] -it works GroundTypeTag[Int] -it works GroundTypeTag[Int] -it works GroundTypeTag[Int] +it works ConcreteTypeTag[Int] +it works ConcreteTypeTag[Int] +it works ConcreteTypeTag[Int] +it works ConcreteTypeTag[Int] +it works ConcreteTypeTag[Int] kkthxbai diff --git a/test/files/run/macro-expand-tparams-explicit.check b/test/files/run/macro-expand-tparams-explicit.check index 54da026aa8..5670e27c4e 100644 --- a/test/files/run/macro-expand-tparams-explicit.check +++ b/test/files/run/macro-expand-tparams-explicit.check @@ -1 +1 @@ -GroundTypeTag[Int] +ConcreteTypeTag[Int] diff --git a/test/files/run/macro-expand-tparams-implicit.check b/test/files/run/macro-expand-tparams-implicit.check index 60c021a35b..e57fc1217b 100644 --- a/test/files/run/macro-expand-tparams-implicit.check +++ b/test/files/run/macro-expand-tparams-implicit.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[String] +ConcreteTypeTag[Int] +ConcreteTypeTag[String] diff --git a/test/files/run/macro-expand-tparams-prefix-a.check b/test/files/run/macro-expand-tparams-prefix-a.check index 1447c2478f..922be1a6dd 100644 --- a/test/files/run/macro-expand-tparams-prefix-a.check +++ b/test/files/run/macro-expand-tparams-prefix-a.check @@ -1,4 +1,4 @@ -GroundTypeTag[Int] -GroundTypeTag[Int] -GroundTypeTag[String] -GroundTypeTag[Boolean] +ConcreteTypeTag[Int] +ConcreteTypeTag[Int] +ConcreteTypeTag[String] +ConcreteTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-b.check b/test/files/run/macro-expand-tparams-prefix-b.check index c7ec594b92..a336bb51ec 100644 --- a/test/files/run/macro-expand-tparams-prefix-b.check +++ b/test/files/run/macro-expand-tparams-prefix-b.check @@ -1,2 +1,2 @@ -GroundTypeTag[Boolean] GroundTypeTag[Int] -GroundTypeTag[Boolean] GroundTypeTag[String] +ConcreteTypeTag[Boolean] ConcreteTypeTag[Int] +ConcreteTypeTag[Boolean] ConcreteTypeTag[String] diff --git a/test/files/run/macro-expand-tparams-prefix-c1.check b/test/files/run/macro-expand-tparams-prefix-c1.check index fac58e9516..87f295aa49 100644 --- a/test/files/run/macro-expand-tparams-prefix-c1.check +++ b/test/files/run/macro-expand-tparams-prefix-c1.check @@ -1,3 +1,3 @@ -GroundTypeTag[Int] -GroundTypeTag[String] -GroundTypeTag[Boolean] +ConcreteTypeTag[Int] +ConcreteTypeTag[String] +ConcreteTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-c2.check b/test/files/run/macro-expand-tparams-prefix-c2.check index fac58e9516..87f295aa49 100644 --- a/test/files/run/macro-expand-tparams-prefix-c2.check +++ b/test/files/run/macro-expand-tparams-prefix-c2.check @@ -1,3 +1,3 @@ -GroundTypeTag[Int] -GroundTypeTag[String] -GroundTypeTag[Boolean] +ConcreteTypeTag[Int] +ConcreteTypeTag[String] +ConcreteTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-d1.check b/test/files/run/macro-expand-tparams-prefix-d1.check index f78ddea4f3..ca7a220475 100644 --- a/test/files/run/macro-expand-tparams-prefix-d1.check +++ b/test/files/run/macro-expand-tparams-prefix-d1.check @@ -1,3 +1,3 @@ TypeTag[T] TypeTag[U] -GroundTypeTag[Boolean] +ConcreteTypeTag[Boolean] diff --git a/test/files/run/macro-reify-groundtypetag-notypeparams.check b/test/files/run/macro-reify-groundtypetag-notypeparams.check index 24612cd4b7..d75b3c72b2 100644 --- a/test/files/run/macro-reify-groundtypetag-notypeparams.check +++ b/test/files/run/macro-reify-groundtypetag-notypeparams.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[List[Int]] +ConcreteTypeTag[Int] +ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala b/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala index 3aa40251ec..d2f8fab5ec 100644 --- a/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala +++ b/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ object Test extends App { - println(implicitly[GroundTypeTag[Int]]) - println(implicitly[GroundTypeTag[List[Int]]]) + println(implicitly[ConcreteTypeTag[Int]]) + println(implicitly[ConcreteTypeTag[List[Int]]]) } \ No newline at end of file diff --git a/test/files/run/macro-reify-groundtypetag-typeparams-tags.check b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check index 24612cd4b7..d75b3c72b2 100644 --- a/test/files/run/macro-reify-groundtypetag-typeparams-tags.check +++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[List[Int]] +ConcreteTypeTag[Int] +ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala b/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala index 21735c10d5..6d7eab5f9a 100644 --- a/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala +++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala @@ -1,9 +1,9 @@ import scala.reflect.mirror._ object Test extends App { - def fooTypeTag[T: GroundTypeTag] = { - println(implicitly[GroundTypeTag[T]]) - println(implicitly[GroundTypeTag[List[T]]]) + def fooTypeTag[T: ConcreteTypeTag] = { + println(implicitly[ConcreteTypeTag[T]]) + println(implicitly[ConcreteTypeTag[List[T]]]) } fooTypeTag[Int] } \ No newline at end of file diff --git a/test/files/run/macro-reify-typetag-notypeparams.check b/test/files/run/macro-reify-typetag-notypeparams.check index 24612cd4b7..d75b3c72b2 100644 --- a/test/files/run/macro-reify-typetag-notypeparams.check +++ b/test/files/run/macro-reify-typetag-notypeparams.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[List[Int]] +ConcreteTypeTag[Int] +ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-typeparams-notags.check b/test/files/run/macro-reify-typetag-typeparams-notags.check index 3da30c71ba..af4877e205 100644 --- a/test/files/run/macro-reify-typetag-typeparams-notags.check +++ b/test/files/run/macro-reify-typetag-typeparams-notags.check @@ -1,2 +1,2 @@ -GroundTypeTag[T] -GroundTypeTag[List[T]] +ConcreteTypeTag[T] +ConcreteTypeTag[List[T]] diff --git a/test/files/run/macro-reify-typetag-typeparams-tags.check b/test/files/run/macro-reify-typetag-typeparams-tags.check index 24612cd4b7..d75b3c72b2 100644 --- a/test/files/run/macro-reify-typetag-typeparams-tags.check +++ b/test/files/run/macro-reify-typetag-typeparams-tags.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[List[Int]] +ConcreteTypeTag[Int] +ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag.check b/test/files/run/macro-reify-typetag-usegroundtypetag.check index 24612cd4b7..d75b3c72b2 100644 --- a/test/files/run/macro-reify-typetag-usegroundtypetag.check +++ b/test/files/run/macro-reify-typetag-usegroundtypetag.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[List[Int]] +ConcreteTypeTag[Int] +ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala b/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala index c9b210f35a..de235f51cc 100644 --- a/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala +++ b/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala @@ -1,7 +1,7 @@ import scala.reflect.mirror._ object Test extends App { - def fooTypeTag[T: GroundTypeTag] = { + def fooTypeTag[T: ConcreteTypeTag] = { println(implicitly[TypeTag[T]]) println(implicitly[TypeTag[List[T]]]) } diff --git a/test/files/run/macro-typecheck-macrosdisabled.check b/test/files/run/macro-typecheck-macrosdisabled.check index 9760c117a7..b432a539fc 100644 --- a/test/files/run/macro-typecheck-macrosdisabled.check +++ b/test/files/run/macro-typecheck-macrosdisabled.check @@ -1,5 +1,5 @@ { val $mr: reflect.mirror.type = scala.reflect.`package`.mirror; - $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.GroundTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) + $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.ConcreteTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) } mr.reify[Int](2) diff --git a/test/files/run/macro-undetparams-consfromsls.check b/test/files/run/macro-undetparams-consfromsls.check index 6bf9bcca5a..49e9140d5a 100644 --- a/test/files/run/macro-undetparams-consfromsls.check +++ b/test/files/run/macro-undetparams-consfromsls.check @@ -1,5 +1,5 @@ -A = GroundTypeTag[Int] -B = GroundTypeTag[Nothing] +A = ConcreteTypeTag[Int] +B = ConcreteTypeTag[Nothing] List(1) -A = GroundTypeTag[Any] +A = ConcreteTypeTag[Any] List(abc, 1) diff --git a/test/files/run/macro-undetparams-implicitval.check b/test/files/run/macro-undetparams-implicitval.check index 352a2e6480..6c2b601aa5 100644 --- a/test/files/run/macro-undetparams-implicitval.check +++ b/test/files/run/macro-undetparams-implicitval.check @@ -1 +1 @@ -GroundTypeTag[Nothing] +ConcreteTypeTag[Nothing] diff --git a/test/files/run/macro-undetparams-macroitself.check b/test/files/run/macro-undetparams-macroitself.check index 60c021a35b..e57fc1217b 100644 --- a/test/files/run/macro-undetparams-macroitself.check +++ b/test/files/run/macro-undetparams-macroitself.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[String] +ConcreteTypeTag[Int] +ConcreteTypeTag[String] diff --git a/test/files/run/primitive-sigs-2.check b/test/files/run/primitive-sigs-2.check index 761aa1ca72..1b6e24ed20 100644 --- a/test/files/run/primitive-sigs-2.check +++ b/test/files/run/primitive-sigs-2.check @@ -1,7 +1,7 @@ T List(A, char, class java.lang.Object) a -public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.api.TypeTags.scala.reflect.api.TypeTags$GroundTypeTag) +public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.api.TypeTags.scala.reflect.api.TypeTags$ConcreteTypeTag) public float[] Arr.arr3(float[][]) public scala.collection.immutable.List Arr.arr2(java.lang.Character[]) public scala.collection.immutable.List Arr.arr1(int[]) diff --git a/test/files/run/reify_newimpl_25.check b/test/files/run/reify_newimpl_25.check index 31ece627e1..37ff83c9ee 100644 --- a/test/files/run/reify_newimpl_25.check +++ b/test/files/run/reify_newimpl_25.check @@ -14,7 +14,7 @@ scala> { :13: free term: Ident(newTermName("x")) defined by res0 in :12:21 val tt = implicitly[TypeTag[x.type]] ^ -GroundTypeTag[x.type] +ConcreteTypeTag[x.type] scala> diff --git a/test/files/run/reify_newimpl_26.check b/test/files/run/reify_newimpl_26.check index 68b0ee8c99..bfbf1d653d 100644 --- a/test/files/run/reify_newimpl_26.check +++ b/test/files/run/reify_newimpl_26.check @@ -16,7 +16,7 @@ scala> def foo[T]{ foo: [T]=> Unit scala> foo[Int] -GroundTypeTag[List[T]] +ConcreteTypeTag[List[T]] scala> diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.check b/test/files/run/toolbox_typecheck_macrosdisabled.check index fe2323ea06..cf2420bc17 100644 --- a/test/files/run/toolbox_typecheck_macrosdisabled.check +++ b/test/files/run/toolbox_typecheck_macrosdisabled.check @@ -1,5 +1,5 @@ { val $mr: mr.type = mr; - $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.GroundTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) + $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.ConcreteTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) } mr.reify[Int](2) diff --git a/test/files/run/typetags_core.check b/test/files/run/typetags_core.check index d1b71f0926..62fcb481ae 100644 --- a/test/files/run/typetags_core.check +++ b/test/files/run/typetags_core.check @@ -1,30 +1,30 @@ true -GroundTypeTag[Byte] +ConcreteTypeTag[Byte] true -GroundTypeTag[Short] +ConcreteTypeTag[Short] true -GroundTypeTag[Char] +ConcreteTypeTag[Char] true -GroundTypeTag[Int] +ConcreteTypeTag[Int] true -GroundTypeTag[Long] +ConcreteTypeTag[Long] true -GroundTypeTag[Float] +ConcreteTypeTag[Float] true -GroundTypeTag[Double] +ConcreteTypeTag[Double] true -GroundTypeTag[Boolean] +ConcreteTypeTag[Boolean] true -GroundTypeTag[Unit] +ConcreteTypeTag[Unit] true -GroundTypeTag[Any] +ConcreteTypeTag[Any] true -GroundTypeTag[Object] +ConcreteTypeTag[Object] true -GroundTypeTag[AnyVal] +ConcreteTypeTag[AnyVal] true -GroundTypeTag[AnyRef] +ConcreteTypeTag[AnyRef] true -GroundTypeTag[Null] +ConcreteTypeTag[Null] true -GroundTypeTag[Nothing] +ConcreteTypeTag[Nothing] diff --git a/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala index 4b264d83af..ef70a66f1a 100644 --- a/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala +++ b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala @@ -1,9 +1,9 @@ import scala.reflect.mirror._ object Test extends App { - def fooTypeTagHK[C[_]: GroundTypeTag, T: GroundTypeTag] = { - println(implicitly[GroundTypeTag[C[T]]]) - println(implicitly[GroundTypeTag[List[C[T]]]]) + def fooTypeTagHK[C[_]: ConcreteTypeTag, T: ConcreteTypeTag] = { + println(implicitly[ConcreteTypeTag[C[T]]]) + println(implicitly[ConcreteTypeTag[List[C[T]]]]) } fooTypeTagHK[List, Int] } \ No newline at end of file -- cgit v1.2.3 From f9e8a8c13ff6f75f330766ae6e0febe431fc4b12 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 12 Apr 2012 15:19:27 +0100 Subject: Disabling failing tests. I turn them over to the responsible parties. Iulian knows about the deadlock test; for philipp I presume, 07:10:29 [partest] concurrent-future.scala:97: error: not found: type FutureTimeoutException 07:10:29 [partest] throw new FutureTimeoutException(null) 07:10:29 [partest] ^ 07:10:29 [partest] one error found --- test/disabled/jvm/concurrent-future.check | 16 + test/disabled/jvm/concurrent-future.scala | 122 +++ test/disabled/presentation/shutdown-deadlock.check | 3 + .../shutdown-deadlock/ShutdownDeadlockTest.scala | 45 + .../shutdown-deadlock/src/arrays.scala | 937 +++++++++++++++++++++ test/files/jvm/concurrent-future.check | 16 - test/files/jvm/concurrent-future.scala | 122 --- test/files/presentation/shutdown-deadlock.check | 3 - .../shutdown-deadlock/ShutdownDeadlockTest.scala | 45 - .../shutdown-deadlock/src/arrays.scala | 937 --------------------- 10 files changed, 1123 insertions(+), 1123 deletions(-) create mode 100644 test/disabled/jvm/concurrent-future.check create mode 100644 test/disabled/jvm/concurrent-future.scala create mode 100644 test/disabled/presentation/shutdown-deadlock.check create mode 100644 test/disabled/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala create mode 100644 test/disabled/presentation/shutdown-deadlock/src/arrays.scala delete mode 100644 test/files/jvm/concurrent-future.check delete mode 100644 test/files/jvm/concurrent-future.scala delete mode 100644 test/files/presentation/shutdown-deadlock.check delete mode 100644 test/files/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala delete mode 100644 test/files/presentation/shutdown-deadlock/src/arrays.scala diff --git a/test/disabled/jvm/concurrent-future.check b/test/disabled/jvm/concurrent-future.check new file mode 100644 index 0000000000..c55e824818 --- /dev/null +++ b/test/disabled/jvm/concurrent-future.check @@ -0,0 +1,16 @@ +test1: hai world +test1: kthxbye +test2: hai world +test2: awsum thx +test2: kthxbye +test3: hai world +test4: hai world +test4: kthxbye +test5: hai world +test5: kthxbye +test6: hai world +test6: kthxbye +test7: hai world +test7: kthxbye +test8: hai world +test8: im in yr loop diff --git a/test/disabled/jvm/concurrent-future.scala b/test/disabled/jvm/concurrent-future.scala new file mode 100644 index 0000000000..b44d054219 --- /dev/null +++ b/test/disabled/jvm/concurrent-future.scala @@ -0,0 +1,122 @@ + + + +import scala.concurrent._ + + + +object Test extends App { + + def once(body: (() => Unit) => Unit) { + val sv = new SyncVar[Boolean] + body(() => sv put true) + sv.take() + } + + def output(num: Int, msg: String) { + println("test" + num + ": " + msg) + } + + def testOnSuccess(): Unit = once { + done => + val f = future { + output(1, "hai world") + } + f onSuccess { case _ => + output(1, "kthxbye") + done() + } + } + + def testOnSuccessWhenCompleted(): Unit = once { + done => + val f = future { + output(2, "hai world") + } + f onSuccess { case _ => + output(2, "awsum thx") + f onSuccess { case _ => + output(2, "kthxbye") + done() + } + } + } + + def testOnSuccessWhenFailed(): Unit = once { + done => + val f = future[Unit] { + output(3, "hai world") + done() + throw new Exception + } + f onSuccess { case _ => + output(3, "onoes") + } + } + + def testOnFailure(): Unit = once { + done => + val f = future[Unit] { + output(4, "hai world") + throw new Exception + } + f onSuccess { case _ => + output(4, "onoes") + done() + } + f onFailure { case _ => + output(4, "kthxbye") + done() + } + } + + def testOnFailureWhenSpecialThrowable(num: Int, cause: Throwable): Unit = once { + done => + val f = future[Unit] { + output(num, "hai world") + throw cause + } + f onSuccess { case _ => + output(num, "onoes") + done() + } + f onFailure { + case e: ExecutionException if (e.getCause == cause) => + output(num, "kthxbye") + done() + case _ => + output(num, "onoes") + done() + } + } + + def testOnFailureWhenFutureTimeoutException(): Unit = once { + done => + val f = future[Unit] { + output(8, "hai world") + throw new FutureTimeoutException(null) + } + f onSuccess { case _ => + output(8, "onoes") + done() + } + f onFailure { + case e: FutureTimeoutException => + output(8, "im in yr loop") + done() + case other => + output(8, "onoes: " + other) + done() + } + } + + testOnSuccess() + testOnSuccessWhenCompleted() + testOnSuccessWhenFailed() + testOnFailure() + testOnFailureWhenSpecialThrowable(5, new Error) + testOnFailureWhenSpecialThrowable(6, new scala.util.control.ControlThrowable { }) + testOnFailureWhenSpecialThrowable(7, new InterruptedException) + testOnFailureWhenFutureTimeoutException() + +} diff --git a/test/disabled/presentation/shutdown-deadlock.check b/test/disabled/presentation/shutdown-deadlock.check new file mode 100644 index 0000000000..ddcb4ff59b --- /dev/null +++ b/test/disabled/presentation/shutdown-deadlock.check @@ -0,0 +1,3 @@ +reload: arrays.scala +reload: arrays.scala +No timeouts diff --git a/test/disabled/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala b/test/disabled/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala new file mode 100644 index 0000000000..cef9d2a5ed --- /dev/null +++ b/test/disabled/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala @@ -0,0 +1,45 @@ +import scala.tools.nsc.interactive._ +import tests._ + +object Test extends InteractiveTest { + val Reps = 30 + import compiler._ + + def askSomething(): Response[Tree] = { + // println("*") + Thread.sleep(50) + ask { compiler.askStructure(true)(sourceFiles.head, _) } + } + + def fireAsks() { + val jobs1 = for (i <- 1 until Reps) yield { + if (i % 10 == 0) { + askReload(sourceFiles) + } + askSomething + } + + for ((j, i) <- jobs1.zipWithIndex) { + j.get(40000) match { + case None => + println(i + ": TIMEOUT") + exit(1) // no need to delay the test any longer + case r => + } + } + compiler.askShutdown() + + println("No timeouts") + } + + override def main(args: Array[String]) { + new Thread("Asking") { + override def run() { + fireAsks() + } + }.start() + + Thread.sleep(800) + compiler.askShutdown() + } +} \ No newline at end of file diff --git a/test/disabled/presentation/shutdown-deadlock/src/arrays.scala b/test/disabled/presentation/shutdown-deadlock/src/arrays.scala new file mode 100644 index 0000000000..ecebc78a6f --- /dev/null +++ b/test/disabled/presentation/shutdown-deadlock/src/arrays.scala @@ -0,0 +1,937 @@ +//############################################################################ +// Arrays +//############################################################################ + +//############################################################################ + +object Test { + + //########################################################################## + // Types + + type Strings = List[String] + type Map = scala.collection.Map[Int, Any] + type HashMap = scala.collection.mutable.HashMap[Int, Any] + type TreeMap = scala.collection.immutable.TreeMap[Int, Any] + + //########################################################################## + // Identity Functions + + def id_Ta_T[T <: Any ](x: T): T = x; + def id_Tr_T[T <: AnyRef ](x: T): T = x; + def id_To_T[T <: Object ](x: T): T = x; + + def id_Ta_a[T <: Any ](x: T): Any = x; + def id_Tr_a[T <: AnyRef ](x: T): Any = x; + def id_To_a[T <: Object ](x: T): Any = x; + + def id_Tr_r[T <: AnyRef ](x: T): AnyRef = x; + def id_To_r[T <: Object ](x: T): AnyRef = x; + + def id_To_o[T <: Object ](x: T): Object = x; + + def id_TSa_T [S <: Any , T <: Array[S]](x: T): T = x; + def id_TSv_T [S <: AnyVal , T <: Array[S]](x: T): T = x; + def id_TSr_T [S <: AnyRef , T <: Array[S]](x: T): T = x; + def id_TSo_T [S <: Object , T <: Array[S]](x: T): T = x; + def id_TSm_T [S <: Map , T <: Array[S]](x: T): T = x; + def id_TSn_T [S <: Strings, T <: Array[S]](x: T): T = x; + + def id_TSa_Ss[S <: Any , T <: Array[S]](x: T): Array[S] = x; + def id_TSv_Ss[S <: AnyVal , T <: Array[S]](x: T): Array[S] = x; + def id_TSr_Ss[S <: AnyRef , T <: Array[S]](x: T): Array[S] = x; + def id_TSo_Ss[S <: Object , T <: Array[S]](x: T): Array[S] = x; + def id_TSm_Ss[S <: Map , T <: Array[S]](x: T): Array[S] = x; + def id_TSn_Ss[S <: Strings, T <: Array[S]](x: T): Array[S] = x; + + def id_TSa_a [S <: Any , T <: Array[S]](x: T): Any = x; + def id_TSv_a [S <: AnyVal , T <: Array[S]](x: T): Any = x; + def id_TSr_a [S <: AnyRef , T <: Array[S]](x: T): Any = x; + def id_TSo_a [S <: Object , T <: Array[S]](x: T): Any = x; + def id_TSm_a [S <: Map , T <: Array[S]](x: T): Any = x; + def id_TSn_a [S <: Strings, T <: Array[S]](x: T): Any = x; + + def id_TSa_r [S <: Any , T <: Array[S]](x: T): AnyRef = x; + def id_TSv_r [S <: AnyVal , T <: Array[S]](x: T): AnyRef = x; + def id_TSr_r [S <: AnyRef , T <: Array[S]](x: T): AnyRef = x; + def id_TSo_r [S <: Object , T <: Array[S]](x: T): AnyRef = x; + def id_TSm_r [S <: Map , T <: Array[S]](x: T): AnyRef = x; + def id_TSn_r [S <: Strings, T <: Array[S]](x: T): AnyRef = x; + + def id_TSa_o [S <: Any , T <: Array[S]](x: T): Object = x; + def id_TSv_o [S <: AnyVal , T <: Array[S]](x: T): Object = x; + def id_TSr_o [S <: AnyRef , T <: Array[S]](x: T): Object = x; + def id_TSo_o [S <: Object , T <: Array[S]](x: T): Object = x; + def id_TSm_o [S <: Map , T <: Array[S]](x: T): Object = x; + def id_TSn_o [S <: Strings, T <: Array[S]](x: T): Object = x; + + def id_Sas_Ss[S <: Any ](xs: Array[S]): Array[S] = xs; + def id_Svs_Ss[S <: AnyVal ](xs: Array[S]): Array[S] = xs; + def id_Srs_Ss[S <: AnyRef ](xs: Array[S]): Array[S] = xs; + def id_Sos_Ss[S <: Object ](xs: Array[S]): Array[S] = xs; + def id_Sms_Ss[S <: Map ](xs: Array[S]): Array[S] = xs; + def id_Sns_Ss[S <: Strings](xs: Array[S]): Array[S] = xs; + + def id_Sas_a [S <: Any ](xs: Array[S]): Any = xs; + def id_Svs_a [S <: AnyVal ](xs: Array[S]): Any = xs; + def id_Srs_a [S <: AnyRef ](xs: Array[S]): Any = xs; + def id_Sos_a [S <: Object ](xs: Array[S]): Any = xs; + def id_Sms_a [S <: Map ](xs: Array[S]): Any = xs; + def id_Sns_a [S <: Strings](xs: Array[S]): Any = xs; + + def id_Sas_r [S <: Any ](xs: Array[S]): AnyRef = xs; + def id_Svs_r [S <: AnyVal ](xs: Array[S]): AnyRef = xs; + def id_Srs_r [S <: AnyRef ](xs: Array[S]): AnyRef = xs; + def id_Sos_r [S <: Object ](xs: Array[S]): AnyRef = xs; + def id_Sms_r [S <: Map ](xs: Array[S]): AnyRef = xs; + def id_Sns_r [S <: Strings](xs: Array[S]): AnyRef = xs; + + def id_Sas_o [S <: Any ](xs: Array[S]): Object = xs; + def id_Svs_o [S <: AnyVal ](xs: Array[S]): Object = xs; + def id_Srs_o [S <: AnyRef ](xs: Array[S]): Object = xs; + def id_Sos_o [S <: Object ](xs: Array[S]): Object = xs; + def id_Sms_o [S <: Map ](xs: Array[S]): Object = xs; + def id_Sns_o [S <: Strings](xs: Array[S]): Object = xs; + + //########################################################################## + // Generic Checks + + type Check[T] = Array[T] => Unit; + + var checks: Int = 0; + + def check(test0: Boolean, actual: Any, expected: Any) { + val test1: Boolean = actual == expected; + if (!test0 || !test1) { + val s0 = if (test0) "ok" else "KO"; + val s1 = if (test1) "ok" else "KO"; + val s2 = actual.toString(); + val s3 = expected.toString(); + error(s0 + " - " + s1 + ": " + s2 + " != " + s3); + } + checks += 1 + } + + def check_Ta[T <: Any ](xs: Array[T], l: Int, x0: T, c: Check[T]) { + check(xs.length == l, xs.length, l); + check(xs(0) == x0, xs(0), x0); + c(xs); + } + + def check_Tv[T <: AnyVal ](xs: Array[T], l: Int, x0: T, c: Check[T]) { + check(xs.length == l, xs.length, l); + check(xs(0) == x0, xs(0), x0); + check_Ta(xs, l, x0, c); + c(xs); + } + + def check_Tr[T <: AnyRef ](xs: Array[T], l: Int, x0: T, c: Check[T]) { + check(xs.length == l, xs.length, l); + check(xs(0) == x0, xs(0), x0); + check_Ta(xs, l, x0, c); + c(xs); + } + + def check_To[T <: Object ](xs: Array[T], l: Int, x0: T, c: Check[T]) { + check(xs.length == l, xs.length, l); + check(xs(0) == x0, xs(0), x0); + check_Ta(xs, l, x0, c); + check_Tr(xs, l, x0, c); + c(xs); + } + + def check_Tm[T <: Map ](xs: Array[T], l: Int, x0: T, c: Check[T]) { + check(xs.length == l, xs.length, l) + check(xs(0) == x0, xs(0), x0) + check_Ta(xs, l, x0, c) + check_Tr(xs, l, x0, c) + check_To(xs, l, x0, c) + c(xs) + } + + def check_Tn[T <: Strings](xs: Array[T], l: Int, x0: T, c: Check[T]) { + check(xs.length == l, xs.length, l) + check(xs(0) == x0, xs(0), x0) + check_Ta(xs, l, x0, c) + check_Tr(xs, l, x0, c) + check_To(xs, l, x0, c) + c(xs) + } + + def checkT2368() { + val arr = Array(1, 2, 3) + arr(0) += 1 + assert(arr(0) == 2) + } + + //########################################################################## + // Values + + val u0: Unit = (); + val u1: Unit = (); + + val z0: Boolean = false; + val z1: Boolean = true; + + val b0: Byte = Byte.MinValue; + val b1: Byte = 1; + val b2: Byte = Byte.MaxValue; + + val s0: Short = Short.MinValue; + val s1: Short = 2; + val s2: Short = Short.MaxValue; + + val c0: Char = Char.MinValue; + val c1: Char = '3'; + val c2: Char = Char.MaxValue; + + val i0: Int = Int.MinValue; + val i1: Int = 4; + val i2: Int = Int.MinValue; + + val l0: Long = Long.MinValue; + val l1: Int = 5; + val l2: Long = Long.MaxValue; + + val f0: Float = Float.MinValue; + val f1: Int = 6; + val f2: Float = Float.MaxValue; + + val d0: Double = Double.MinValue; + val d1: Int = 7; + val d2: Double = Double.MaxValue; + + val a0: Unit = (); + val a1: Boolean = false; + val a2: Int = 0; + val a3: Null = null; + val a4: String = "a-z"; + val a5: Symbol = 'token; + val a6: HashMap = new HashMap(); + val a7: TreeMap = scala.collection.immutable.TreeMap.empty[Int, Any]; + val a8: Strings = List("a", "z"); + + val v0: Unit = (); + val v1: Boolean = false; + val v2: Int = 0; + val v3: Long = l2; + val v4: Float = f2; + val v5: Double = d2; + + val r0: Null = a3; + val r1: String = a4; + val r2: Symbol = a5; + val r3: HashMap = a6; + val r4: TreeMap = a7; + val r5: Strings = a8; + + val o0: Null = r0; + val o1: String = r1; + val o2: Symbol = r2; + val o3: HashMap = r3; + val o4: TreeMap = r4; + val o5: Strings = r5; + + val m0: Null = r0; + val m1: HashMap = r3; + val m2: TreeMap = r4; + + val n0: Null = r0; + val n1: Strings = r5; + val n2: Nil.type= Nil; + + //########################################################################## + // Specific Checks + + def ucheck(xs: Array[Unit ]): Unit = { + check(xs.length == 2, xs.length, 2); + check(xs(0) == u0, xs(0), u0); + check(xs(1) == u1, xs(1), u1); + } + + def zcheck(xs: Array[Boolean]): Unit = { + check(xs.length == 2, xs.length, 2); + check(xs(0) == z0, xs(0), z0); + check(xs(1) == z1, xs(1), z1); + } + + def bcheck(xs: Array[Byte ]): Unit = { + check(xs.length == 3, xs.length, 3); + check(xs(0) == b0, xs(0), b0); + check(xs(1) == b1, xs(1), b1); + check(xs(2) == b2, xs(2), b2); + } + + def scheck(xs: Array[Short ]): Unit = { + check(xs.length == 3, xs.length, 3); + check(xs(0) == s0, xs(0), s0); + check(xs(1) == s1, xs(1), s1); + check(xs(2) == s2, xs(2), s2); + } + + def ccheck(xs: Array[Char ]): Unit = { + check(xs.length == 3, xs.length, 3); + check(xs(0) == c0, xs(0), c0); + check(xs(1) == c1, xs(1), c1); + check(xs(2) == c2, xs(2), c2); + } + + def icheck(xs: Array[Int ]): Unit = { + check(xs.length == 3, xs.length, 3); + check(xs(0) == i0, xs(0), i0); + check(xs(1) == i1, xs(1), i1); + check(xs(2) == i2, xs(2), i2); + } + + def lcheck(xs: Array[Long ]): Unit = { + check(xs.length == 3, xs.length, 3); + check(xs(0) == l0, xs(0), l0); + check(xs(1) == l1, xs(1), l1: Long); // !!! : Long + check(xs(2) == l2, xs(2), l2); + } + + def fcheck(xs: Array[Float ]): Unit = { + check(xs.length == 3, xs.length, 3); + check(xs(0) == f0, xs(0), f0); + check(xs(1) == f1, xs(1), f1: Float); // !!! : Float + check(xs(2) == f2, xs(2), f2); + } + + def dcheck(xs: Array[Double ]): Unit = { + check(xs.length == 3, xs.length, 3); + check(xs(0) == d0, xs(0), d0); + check(xs(1) == d1, xs(1), d1: Double); // !!! : Double + check(xs(2) == d2, xs(2), d2); + } + + def rcheck(xs: Array[AnyRef ]): Unit = { + check(xs.length == 6, xs.length, 6); + check(xs(0) == r0, xs(0), r0); + check(xs(1) == r1, xs(1), r1); + check(xs(2) == r2, xs(2), r2); + check(xs(3) == r3, xs(3), r3); + check(xs(4) == r4, xs(4), r4); + check(xs(5) == r5, xs(5), r5); + } + + def ocheck(xs: Array[Object ]): Unit = { + check(xs.length == 6, xs.length, 6); + check(xs(0) == o0, xs(0), o0); + check(xs(1) == o1, xs(1), o1); + check(xs(2) == o2, xs(2), o2); + check(xs(3) == o3, xs(3), o3); + check(xs(4) == o4, xs(4), o4); + check(xs(5) == o5, xs(5), o5); + } + + def mcheck(xs: Array[Map ]): Unit = { + check(xs.length == 3, xs.length, 3); + check(xs(0) == m0, xs(0), m0); + check(xs(1) == m1, xs(1), m1); + check(xs(2) == m2, xs(2), m2); + } + + def ncheck(xs: Array[Strings]) { + check(xs.length == 3, xs.length, 3) + check(xs(0) == n0, xs(0), n0) + check(xs(1) == n1, xs(1), n1) + check(xs(2) == n2, xs(2), n2) + } + + //########################################################################## + // Miscellaneous checks + + def checkZip { + val zipped = Array("a", "b", "c").zip(Array(1, 2)) + val expected = Array(("a",1), ("b",2)) + check(zipped sameElements expected, zipped.toList, expected.toList) + } + + def checkConcat { // ticket #713 + val x1 = Array.concat(Array(1, 2), Array(3, 4)) + val y1 = Array(1, 2, 3, 4) + check(x1 sameElements y1, x1.toList, y1.toList) + } + + //########################################################################## + // Arrays + + val uarray: Array[Unit ] = Array(u0, u1); + val zarray: Array[Boolean] = Array(z0, z1); + val barray: Array[Byte ] = Array(b0, b1, b2); + val sarray: Array[Short ] = Array(s0, s1, s2); + val carray: Array[Char ] = Array(c0, c1, c2); + val iarray: Array[Int ] = Array(i0, i1, i2); + val larray: Array[Long ] = Array(l0, l1, l2); + val farray: Array[Float ] = Array(f0, f1, f2); + val darray: Array[Double ] = Array(d0, d1, d2); + val rarray: Array[AnyRef ] = Array(r0, r1, r2, r4, r4, r5); + val oarray: Array[Object ] = Array(o0, o1, o2, o4, o4, o5); + val marray: Array[Map ] = Array(m0, m1, m2); + val narray: Array[Strings] = Array(n0, n1, n2); + + //########################################################################## + // Main + + def main(args: Array[String]): Unit = { + + //###################################################################### + + ucheck(uarray); + zcheck(zarray); + bcheck(barray); + scheck(sarray); + ccheck(carray); + icheck(iarray); + lcheck(larray); + fcheck(farray); + dcheck(darray); + rcheck(rarray); + ocheck(oarray); + mcheck(marray); + ncheck(narray); + + //###################################################################### + + ucheck(id_Ta_T(uarray)); + zcheck(id_Ta_T(zarray)); + bcheck(id_Ta_T(barray)); + scheck(id_Ta_T(sarray)); + ccheck(id_Ta_T(carray)); + icheck(id_Ta_T(iarray)); + lcheck(id_Ta_T(larray)); + fcheck(id_Ta_T(farray)); + dcheck(id_Ta_T(darray)); + rcheck(id_Ta_T(rarray)); + ocheck(id_Ta_T(oarray)); + mcheck(id_Ta_T(marray)); + ncheck(id_Ta_T(narray)); + + ucheck(id_Tr_T(uarray)); + zcheck(id_Tr_T(zarray)); + bcheck(id_Tr_T(barray)); + scheck(id_Tr_T(sarray)); + ccheck(id_Tr_T(carray)); + icheck(id_Tr_T(iarray)); + lcheck(id_Tr_T(larray)); + fcheck(id_Tr_T(farray)); + dcheck(id_Tr_T(darray)); + rcheck(id_Tr_T(rarray)); + ocheck(id_Tr_T(oarray)); + mcheck(id_Tr_T(marray)); + ncheck(id_Tr_T(narray)); + + ucheck(id_To_T(uarray)); + zcheck(id_To_T(zarray)); + bcheck(id_To_T(barray)); + scheck(id_To_T(sarray)); + ccheck(id_To_T(carray)); + icheck(id_To_T(iarray)); + lcheck(id_To_T(larray)); + fcheck(id_To_T(farray)); + dcheck(id_To_T(darray)); + rcheck(id_To_T(rarray)); + ocheck(id_To_T(oarray)); + mcheck(id_To_T(marray)); + ncheck(id_To_T(narray)); + + ucheck(id_Ta_a(uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_Ta_a(zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_Ta_a(barray).asInstanceOf[Array[Byte ]]); + scheck(id_Ta_a(sarray).asInstanceOf[Array[Short ]]); + ccheck(id_Ta_a(carray).asInstanceOf[Array[Char ]]); + icheck(id_Ta_a(iarray).asInstanceOf[Array[Int ]]); + lcheck(id_Ta_a(larray).asInstanceOf[Array[Long ]]); + fcheck(id_Ta_a(farray).asInstanceOf[Array[Float ]]); + dcheck(id_Ta_a(darray).asInstanceOf[Array[Double ]]); + rcheck(id_Ta_a(rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_Ta_a(oarray).asInstanceOf[Array[Object ]]); + mcheck(id_Ta_a(marray).asInstanceOf[Array[Map ]]); + ncheck(id_Ta_a(narray).asInstanceOf[Array[Strings]]); + + ucheck(id_Tr_a(uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_Tr_a(zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_Tr_a(barray).asInstanceOf[Array[Byte ]]); + scheck(id_Tr_a(sarray).asInstanceOf[Array[Short ]]); + ccheck(id_Tr_a(carray).asInstanceOf[Array[Char ]]); + icheck(id_Tr_a(iarray).asInstanceOf[Array[Int ]]); + lcheck(id_Tr_a(larray).asInstanceOf[Array[Long ]]); + fcheck(id_Tr_a(farray).asInstanceOf[Array[Float ]]); + dcheck(id_Tr_a(darray).asInstanceOf[Array[Double ]]); + rcheck(id_Tr_a(rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_Tr_a(oarray).asInstanceOf[Array[Object ]]); + mcheck(id_Tr_a(marray).asInstanceOf[Array[Map ]]); + ncheck(id_Tr_a(narray).asInstanceOf[Array[Strings]]); + + ucheck(id_To_a(uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_To_a(zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_To_a(barray).asInstanceOf[Array[Byte ]]); + scheck(id_To_a(sarray).asInstanceOf[Array[Short ]]); + ccheck(id_To_a(carray).asInstanceOf[Array[Char ]]); + icheck(id_To_a(iarray).asInstanceOf[Array[Int ]]); + lcheck(id_To_a(larray).asInstanceOf[Array[Long ]]); + fcheck(id_To_a(farray).asInstanceOf[Array[Float ]]); + dcheck(id_To_a(darray).asInstanceOf[Array[Double ]]); + rcheck(id_To_a(rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_To_a(oarray).asInstanceOf[Array[Object ]]); + mcheck(id_To_a(marray).asInstanceOf[Array[Map ]]); + ncheck(id_To_a(narray).asInstanceOf[Array[Strings]]); + + ucheck(id_Tr_r(uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_Tr_r(zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_Tr_r(barray).asInstanceOf[Array[Byte ]]); + scheck(id_Tr_r(sarray).asInstanceOf[Array[Short ]]); + ccheck(id_Tr_r(carray).asInstanceOf[Array[Char ]]); + icheck(id_Tr_r(iarray).asInstanceOf[Array[Int ]]); + lcheck(id_Tr_r(larray).asInstanceOf[Array[Long ]]); + fcheck(id_Tr_r(farray).asInstanceOf[Array[Float ]]); + dcheck(id_Tr_r(darray).asInstanceOf[Array[Double ]]); + rcheck(id_Tr_r(rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_Tr_r(oarray).asInstanceOf[Array[Object ]]); + mcheck(id_Tr_r(marray).asInstanceOf[Array[Map ]]); + ncheck(id_Tr_r(narray).asInstanceOf[Array[Strings]]); + + ucheck(id_To_r(uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_To_r(zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_To_r(barray).asInstanceOf[Array[Byte ]]); + scheck(id_To_r(sarray).asInstanceOf[Array[Short ]]); + ccheck(id_To_r(carray).asInstanceOf[Array[Char ]]); + icheck(id_To_r(iarray).asInstanceOf[Array[Int ]]); + lcheck(id_To_r(larray).asInstanceOf[Array[Long ]]); + fcheck(id_To_r(farray).asInstanceOf[Array[Float ]]); + dcheck(id_To_r(darray).asInstanceOf[Array[Double ]]); + rcheck(id_To_r(rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_To_r(oarray).asInstanceOf[Array[Object ]]); + mcheck(id_To_r(marray).asInstanceOf[Array[Map ]]); + ncheck(id_To_r(narray).asInstanceOf[Array[Strings]]); + + ucheck(id_To_o(uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_To_o(zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_To_o(barray).asInstanceOf[Array[Byte ]]); + scheck(id_To_o(sarray).asInstanceOf[Array[Short ]]); + ccheck(id_To_o(carray).asInstanceOf[Array[Char ]]); + icheck(id_To_o(iarray).asInstanceOf[Array[Int ]]); + lcheck(id_To_o(larray).asInstanceOf[Array[Long ]]); + fcheck(id_To_o(farray).asInstanceOf[Array[Float ]]); + dcheck(id_To_o(darray).asInstanceOf[Array[Double ]]); + rcheck(id_To_o(rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_To_o(oarray).asInstanceOf[Array[Object ]]); + mcheck(id_To_o(marray).asInstanceOf[Array[Map ]]); + ncheck(id_To_o(narray).asInstanceOf[Array[Strings]]); + + //###################################################################### + + ucheck(id_TSa_T [Unit , Array[Unit ]](uarray)); + zcheck(id_TSa_T [Boolean, Array[Boolean]](zarray)); + bcheck(id_TSa_T [Byte , Array[Byte ]](barray)); + scheck(id_TSa_T [Short , Array[Short ]](sarray)); + ccheck(id_TSa_T [Char , Array[Char ]](carray)); + icheck(id_TSa_T [Int , Array[Int ]](iarray)); + lcheck(id_TSa_T [Long , Array[Long ]](larray)); + fcheck(id_TSa_T [Float , Array[Float ]](farray)); + dcheck(id_TSa_T [Double , Array[Double ]](darray)); + rcheck(id_TSa_T [AnyRef , Array[AnyRef ]](rarray)); + ocheck(id_TSa_T [Object , Array[Object ]](oarray)); + mcheck(id_TSa_T [Map , Array[Map ]](marray)); + ncheck(id_TSa_T [Strings, Array[Strings]](narray)); + + ucheck(id_TSv_T [Unit , Array[Unit ]](uarray)); + zcheck(id_TSv_T [Boolean, Array[Boolean]](zarray)); + bcheck(id_TSv_T [Byte , Array[Byte ]](barray)); + scheck(id_TSv_T [Short , Array[Short ]](sarray)); + ccheck(id_TSv_T [Char , Array[Char ]](carray)); + icheck(id_TSv_T [Int , Array[Int ]](iarray)); + lcheck(id_TSv_T [Long , Array[Long ]](larray)); + fcheck(id_TSv_T [Float , Array[Float ]](farray)); + dcheck(id_TSv_T [Double , Array[Double ]](darray)); + + rcheck(id_TSr_T [AnyRef , Array[AnyRef ]](rarray)); + ocheck(id_TSr_T [Object , Array[Object ]](oarray)); + mcheck(id_TSr_T [Map , Array[Map ]](marray)); + ncheck(id_TSr_T [Strings, Array[Strings]](narray)); + + rcheck(id_TSo_T [AnyRef , Array[AnyRef ]](rarray)); + ocheck(id_TSo_T [Object , Array[Object ]](oarray)); + mcheck(id_TSo_T [Map , Array[Map ]](marray)); + ncheck(id_TSo_T [Strings, Array[Strings]](narray)); + + mcheck(id_TSm_T [Map , Array[Map ]](marray)); + + ncheck(id_TSn_T [Strings, Array[Strings]](narray)); + + //###################################################################### + + ucheck(id_TSa_Ss[Unit , Array[Unit ]](uarray)); + zcheck(id_TSa_Ss[Boolean, Array[Boolean]](zarray)); + bcheck(id_TSa_Ss[Byte , Array[Byte ]](barray)); + scheck(id_TSa_Ss[Short , Array[Short ]](sarray)); + ccheck(id_TSa_Ss[Char , Array[Char ]](carray)); + icheck(id_TSa_Ss[Int , Array[Int ]](iarray)); + lcheck(id_TSa_Ss[Long , Array[Long ]](larray)); + fcheck(id_TSa_Ss[Float , Array[Float ]](farray)); + dcheck(id_TSa_Ss[Double , Array[Double ]](darray)); + rcheck(id_TSa_Ss[AnyRef , Array[AnyRef ]](rarray)); + ocheck(id_TSa_Ss[Object , Array[Object ]](oarray)); + mcheck(id_TSa_Ss[Map , Array[Map ]](marray)); + ncheck(id_TSa_Ss[Strings, Array[Strings]](narray)); + + ucheck(id_TSv_Ss[Unit , Array[Unit ]](uarray)); + zcheck(id_TSv_Ss[Boolean, Array[Boolean]](zarray)); + bcheck(id_TSv_Ss[Byte , Array[Byte ]](barray)); + scheck(id_TSv_Ss[Short , Array[Short ]](sarray)); + ccheck(id_TSv_Ss[Char , Array[Char ]](carray)); + icheck(id_TSv_Ss[Int , Array[Int ]](iarray)); + lcheck(id_TSv_Ss[Long , Array[Long ]](larray)); + fcheck(id_TSv_Ss[Float , Array[Float ]](farray)); + dcheck(id_TSv_Ss[Double , Array[Double ]](darray)); + + rcheck(id_TSr_Ss[AnyRef , Array[AnyRef ]](rarray)); + ocheck(id_TSr_Ss[Object , Array[Object ]](oarray)); + mcheck(id_TSr_Ss[Map , Array[Map ]](marray)); + ncheck(id_TSr_Ss[Strings, Array[Strings]](narray)); + + rcheck(id_TSo_Ss[AnyRef , Array[AnyRef ]](rarray)); + ocheck(id_TSo_Ss[Object , Array[Object ]](oarray)); + mcheck(id_TSo_Ss[Map , Array[Map ]](marray)); + ncheck(id_TSo_Ss[Strings, Array[Strings]](narray)); + + mcheck(id_TSm_Ss[Map , Array[Map ]](marray)); + + ncheck(id_TSn_Ss[Strings, Array[Strings]](narray)); + + //###################################################################### + + ucheck(id_TSa_a [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSa_a [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSa_a [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSa_a [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSa_a [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSa_a [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSa_a [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSa_a [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSa_a [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + rcheck(id_TSa_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSa_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSa_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSa_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + ucheck(id_TSv_a [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSv_a [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSv_a [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSv_a [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSv_a [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSv_a [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSv_a [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSv_a [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSv_a [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + + rcheck(id_TSr_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSr_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSr_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSr_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + rcheck(id_TSo_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSo_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSo_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSo_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + mcheck(id_TSm_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + + ncheck(id_TSn_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + //###################################################################### + + ucheck(id_TSa_r [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSa_r [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSa_r [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSa_r [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSa_r [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSa_r [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSa_r [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSa_r [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSa_r [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + rcheck(id_TSa_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSa_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSa_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSa_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + ucheck(id_TSv_r [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSv_r [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSv_r [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSv_r [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSv_r [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSv_r [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSv_r [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSv_r [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSv_r [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + + rcheck(id_TSr_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSr_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSr_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSr_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + rcheck(id_TSo_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSo_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSo_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSo_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + mcheck(id_TSm_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + + ncheck(id_TSn_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + //###################################################################### + + ucheck(id_TSa_o [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSa_o [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSa_o [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSa_o [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSa_o [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSa_o [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSa_o [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSa_o [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSa_o [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + rcheck(id_TSa_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSa_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSa_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSa_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + ucheck(id_TSv_o [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSv_o [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSv_o [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSv_o [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSv_o [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSv_o [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSv_o [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSv_o [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSv_o [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + + rcheck(id_TSr_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSr_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSr_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSr_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + rcheck(id_TSo_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSo_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSo_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSo_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + mcheck(id_TSm_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + + ncheck(id_TSn_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + //###################################################################### + + ucheck(id_Sas_Ss[Unit ](uarray)); + zcheck(id_Sas_Ss[Boolean](zarray)); + bcheck(id_Sas_Ss[Byte ](barray)); + scheck(id_Sas_Ss[Short ](sarray)); + ccheck(id_Sas_Ss[Char ](carray)); + icheck(id_Sas_Ss[Int ](iarray)); + lcheck(id_Sas_Ss[Long ](larray)); + fcheck(id_Sas_Ss[Float ](farray)); + dcheck(id_Sas_Ss[Double ](darray)); + rcheck(id_Sas_Ss[AnyRef ](rarray)); + ocheck(id_Sas_Ss[Object ](oarray)); + mcheck(id_Sas_Ss[Map ](marray)); + ncheck(id_Sas_Ss[Strings](narray)); + + ucheck(id_Svs_Ss[Unit ](uarray)); + zcheck(id_Svs_Ss[Boolean](zarray)); + bcheck(id_Svs_Ss[Byte ](barray)); + scheck(id_Svs_Ss[Short ](sarray)); + ccheck(id_Svs_Ss[Char ](carray)); + icheck(id_Svs_Ss[Int ](iarray)); + lcheck(id_Svs_Ss[Long ](larray)); + fcheck(id_Svs_Ss[Float ](farray)); + dcheck(id_Svs_Ss[Double ](darray)); + + rcheck(id_Srs_Ss[AnyRef ](rarray)); + ocheck(id_Srs_Ss[Object ](oarray)); + mcheck(id_Srs_Ss[Map ](marray)); + ncheck(id_Srs_Ss[Strings](narray)); + + rcheck(id_Sos_Ss[AnyRef ](rarray)); + ocheck(id_Sos_Ss[Object ](oarray)); + mcheck(id_Sos_Ss[Map ](marray)); + ncheck(id_Sos_Ss[Strings](narray)); + + mcheck(id_Sms_Ss[Map ](marray)); + + ncheck(id_Sns_Ss[Strings](narray)); + + //###################################################################### + + ucheck(id_TSa_a [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSa_a [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSa_a [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSa_a [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSa_a [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSa_a [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSa_a [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSa_a [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSa_a [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + rcheck(id_TSa_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSa_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSa_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSa_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + ucheck(id_TSv_a [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSv_a [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSv_a [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSv_a [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSv_a [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSv_a [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSv_a [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSv_a [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSv_a [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + + rcheck(id_TSr_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSr_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSr_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSr_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + rcheck(id_TSo_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSo_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSo_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSo_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + mcheck(id_TSm_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + + ncheck(id_TSn_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + //###################################################################### + + ucheck(id_TSa_r [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSa_r [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSa_r [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSa_r [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSa_r [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSa_r [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSa_r [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSa_r [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSa_r [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + rcheck(id_TSa_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSa_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSa_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSa_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + ucheck(id_TSv_r [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSv_r [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSv_r [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSv_r [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSv_r [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSv_r [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSv_r [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSv_r [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSv_r [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + + rcheck(id_TSr_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSr_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSr_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSr_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + rcheck(id_TSo_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSo_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSo_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSo_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + mcheck(id_TSm_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + + ncheck(id_TSn_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + //###################################################################### + + ucheck(id_TSa_o [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSa_o [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSa_o [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSa_o [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSa_o [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSa_o [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSa_o [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSa_o [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSa_o [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + rcheck(id_TSa_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSa_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSa_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSa_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + ucheck(id_TSv_o [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); + zcheck(id_TSv_o [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); + bcheck(id_TSv_o [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); + scheck(id_TSv_o [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); + ccheck(id_TSv_o [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); + icheck(id_TSv_o [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); + lcheck(id_TSv_o [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); + fcheck(id_TSv_o [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); + dcheck(id_TSv_o [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); + + rcheck(id_TSr_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSr_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSr_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSr_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + rcheck(id_TSo_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); + ocheck(id_TSo_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); + mcheck(id_TSo_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + ncheck(id_TSo_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + mcheck(id_TSm_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); + + ncheck(id_TSn_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); + + //###################################################################### + + check_Ta(uarray, 2, u0, ucheck) + check_Ta(zarray, 2, z0, zcheck) + check_Ta(barray, 3, b0, bcheck) + check_Ta(sarray, 3, s0, scheck) + check_Ta(carray, 3, c0, ccheck) + check_Ta(iarray, 3, i0, icheck) + check_Ta(larray, 3, l0, lcheck) + check_Ta(farray, 3, f0, fcheck) + check_Ta(darray, 3, d0, dcheck) + check_Ta(rarray, 6, r0, rcheck) + check_Ta(oarray, 6, o0, ocheck) + check_Ta(marray, 3, m0, mcheck) + check_Ta(narray, 3, n0, ncheck) + + check_Tv(uarray, 2, u0, ucheck) + check_Tv(zarray, 2, z0, zcheck) + check_Tv(barray, 3, b0, bcheck) + check_Tv(sarray, 3, s0, scheck) + check_Tv(carray, 3, c0, ccheck) + check_Tv(iarray, 3, i0, icheck) + check_Tv(larray, 3, l0, lcheck) + check_Tv(farray, 3, f0, fcheck) + check_Tv(darray, 3, d0, dcheck) + + check_Tr(rarray, 6, r0, rcheck) + check_Tr(oarray, 6, o0, ocheck) + check_Tr(marray, 3, m0, mcheck) + check_Tr(narray, 3, n0, ncheck) + + check_To(rarray, 6, r0, rcheck) + check_To(oarray, 6, o0, ocheck) + check_To(marray, 3, m0, mcheck) + check_To(narray, 3, n0, ncheck) + + check_Tm(marray, 3, m0, mcheck) + + check_Tn(narray, 3, n0, ncheck) + + //###################################################################### + + checkZip + checkConcat + checkT2368() + + //###################################################################### + + println("checks: " + checks) + + //###################################################################### + } + + //########################################################################## +} + diff --git a/test/files/jvm/concurrent-future.check b/test/files/jvm/concurrent-future.check deleted file mode 100644 index c55e824818..0000000000 --- a/test/files/jvm/concurrent-future.check +++ /dev/null @@ -1,16 +0,0 @@ -test1: hai world -test1: kthxbye -test2: hai world -test2: awsum thx -test2: kthxbye -test3: hai world -test4: hai world -test4: kthxbye -test5: hai world -test5: kthxbye -test6: hai world -test6: kthxbye -test7: hai world -test7: kthxbye -test8: hai world -test8: im in yr loop diff --git a/test/files/jvm/concurrent-future.scala b/test/files/jvm/concurrent-future.scala deleted file mode 100644 index b44d054219..0000000000 --- a/test/files/jvm/concurrent-future.scala +++ /dev/null @@ -1,122 +0,0 @@ - - - -import scala.concurrent._ - - - -object Test extends App { - - def once(body: (() => Unit) => Unit) { - val sv = new SyncVar[Boolean] - body(() => sv put true) - sv.take() - } - - def output(num: Int, msg: String) { - println("test" + num + ": " + msg) - } - - def testOnSuccess(): Unit = once { - done => - val f = future { - output(1, "hai world") - } - f onSuccess { case _ => - output(1, "kthxbye") - done() - } - } - - def testOnSuccessWhenCompleted(): Unit = once { - done => - val f = future { - output(2, "hai world") - } - f onSuccess { case _ => - output(2, "awsum thx") - f onSuccess { case _ => - output(2, "kthxbye") - done() - } - } - } - - def testOnSuccessWhenFailed(): Unit = once { - done => - val f = future[Unit] { - output(3, "hai world") - done() - throw new Exception - } - f onSuccess { case _ => - output(3, "onoes") - } - } - - def testOnFailure(): Unit = once { - done => - val f = future[Unit] { - output(4, "hai world") - throw new Exception - } - f onSuccess { case _ => - output(4, "onoes") - done() - } - f onFailure { case _ => - output(4, "kthxbye") - done() - } - } - - def testOnFailureWhenSpecialThrowable(num: Int, cause: Throwable): Unit = once { - done => - val f = future[Unit] { - output(num, "hai world") - throw cause - } - f onSuccess { case _ => - output(num, "onoes") - done() - } - f onFailure { - case e: ExecutionException if (e.getCause == cause) => - output(num, "kthxbye") - done() - case _ => - output(num, "onoes") - done() - } - } - - def testOnFailureWhenFutureTimeoutException(): Unit = once { - done => - val f = future[Unit] { - output(8, "hai world") - throw new FutureTimeoutException(null) - } - f onSuccess { case _ => - output(8, "onoes") - done() - } - f onFailure { - case e: FutureTimeoutException => - output(8, "im in yr loop") - done() - case other => - output(8, "onoes: " + other) - done() - } - } - - testOnSuccess() - testOnSuccessWhenCompleted() - testOnSuccessWhenFailed() - testOnFailure() - testOnFailureWhenSpecialThrowable(5, new Error) - testOnFailureWhenSpecialThrowable(6, new scala.util.control.ControlThrowable { }) - testOnFailureWhenSpecialThrowable(7, new InterruptedException) - testOnFailureWhenFutureTimeoutException() - -} diff --git a/test/files/presentation/shutdown-deadlock.check b/test/files/presentation/shutdown-deadlock.check deleted file mode 100644 index ddcb4ff59b..0000000000 --- a/test/files/presentation/shutdown-deadlock.check +++ /dev/null @@ -1,3 +0,0 @@ -reload: arrays.scala -reload: arrays.scala -No timeouts diff --git a/test/files/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala b/test/files/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala deleted file mode 100644 index cef9d2a5ed..0000000000 --- a/test/files/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala +++ /dev/null @@ -1,45 +0,0 @@ -import scala.tools.nsc.interactive._ -import tests._ - -object Test extends InteractiveTest { - val Reps = 30 - import compiler._ - - def askSomething(): Response[Tree] = { - // println("*") - Thread.sleep(50) - ask { compiler.askStructure(true)(sourceFiles.head, _) } - } - - def fireAsks() { - val jobs1 = for (i <- 1 until Reps) yield { - if (i % 10 == 0) { - askReload(sourceFiles) - } - askSomething - } - - for ((j, i) <- jobs1.zipWithIndex) { - j.get(40000) match { - case None => - println(i + ": TIMEOUT") - exit(1) // no need to delay the test any longer - case r => - } - } - compiler.askShutdown() - - println("No timeouts") - } - - override def main(args: Array[String]) { - new Thread("Asking") { - override def run() { - fireAsks() - } - }.start() - - Thread.sleep(800) - compiler.askShutdown() - } -} \ No newline at end of file diff --git a/test/files/presentation/shutdown-deadlock/src/arrays.scala b/test/files/presentation/shutdown-deadlock/src/arrays.scala deleted file mode 100644 index ecebc78a6f..0000000000 --- a/test/files/presentation/shutdown-deadlock/src/arrays.scala +++ /dev/null @@ -1,937 +0,0 @@ -//############################################################################ -// Arrays -//############################################################################ - -//############################################################################ - -object Test { - - //########################################################################## - // Types - - type Strings = List[String] - type Map = scala.collection.Map[Int, Any] - type HashMap = scala.collection.mutable.HashMap[Int, Any] - type TreeMap = scala.collection.immutable.TreeMap[Int, Any] - - //########################################################################## - // Identity Functions - - def id_Ta_T[T <: Any ](x: T): T = x; - def id_Tr_T[T <: AnyRef ](x: T): T = x; - def id_To_T[T <: Object ](x: T): T = x; - - def id_Ta_a[T <: Any ](x: T): Any = x; - def id_Tr_a[T <: AnyRef ](x: T): Any = x; - def id_To_a[T <: Object ](x: T): Any = x; - - def id_Tr_r[T <: AnyRef ](x: T): AnyRef = x; - def id_To_r[T <: Object ](x: T): AnyRef = x; - - def id_To_o[T <: Object ](x: T): Object = x; - - def id_TSa_T [S <: Any , T <: Array[S]](x: T): T = x; - def id_TSv_T [S <: AnyVal , T <: Array[S]](x: T): T = x; - def id_TSr_T [S <: AnyRef , T <: Array[S]](x: T): T = x; - def id_TSo_T [S <: Object , T <: Array[S]](x: T): T = x; - def id_TSm_T [S <: Map , T <: Array[S]](x: T): T = x; - def id_TSn_T [S <: Strings, T <: Array[S]](x: T): T = x; - - def id_TSa_Ss[S <: Any , T <: Array[S]](x: T): Array[S] = x; - def id_TSv_Ss[S <: AnyVal , T <: Array[S]](x: T): Array[S] = x; - def id_TSr_Ss[S <: AnyRef , T <: Array[S]](x: T): Array[S] = x; - def id_TSo_Ss[S <: Object , T <: Array[S]](x: T): Array[S] = x; - def id_TSm_Ss[S <: Map , T <: Array[S]](x: T): Array[S] = x; - def id_TSn_Ss[S <: Strings, T <: Array[S]](x: T): Array[S] = x; - - def id_TSa_a [S <: Any , T <: Array[S]](x: T): Any = x; - def id_TSv_a [S <: AnyVal , T <: Array[S]](x: T): Any = x; - def id_TSr_a [S <: AnyRef , T <: Array[S]](x: T): Any = x; - def id_TSo_a [S <: Object , T <: Array[S]](x: T): Any = x; - def id_TSm_a [S <: Map , T <: Array[S]](x: T): Any = x; - def id_TSn_a [S <: Strings, T <: Array[S]](x: T): Any = x; - - def id_TSa_r [S <: Any , T <: Array[S]](x: T): AnyRef = x; - def id_TSv_r [S <: AnyVal , T <: Array[S]](x: T): AnyRef = x; - def id_TSr_r [S <: AnyRef , T <: Array[S]](x: T): AnyRef = x; - def id_TSo_r [S <: Object , T <: Array[S]](x: T): AnyRef = x; - def id_TSm_r [S <: Map , T <: Array[S]](x: T): AnyRef = x; - def id_TSn_r [S <: Strings, T <: Array[S]](x: T): AnyRef = x; - - def id_TSa_o [S <: Any , T <: Array[S]](x: T): Object = x; - def id_TSv_o [S <: AnyVal , T <: Array[S]](x: T): Object = x; - def id_TSr_o [S <: AnyRef , T <: Array[S]](x: T): Object = x; - def id_TSo_o [S <: Object , T <: Array[S]](x: T): Object = x; - def id_TSm_o [S <: Map , T <: Array[S]](x: T): Object = x; - def id_TSn_o [S <: Strings, T <: Array[S]](x: T): Object = x; - - def id_Sas_Ss[S <: Any ](xs: Array[S]): Array[S] = xs; - def id_Svs_Ss[S <: AnyVal ](xs: Array[S]): Array[S] = xs; - def id_Srs_Ss[S <: AnyRef ](xs: Array[S]): Array[S] = xs; - def id_Sos_Ss[S <: Object ](xs: Array[S]): Array[S] = xs; - def id_Sms_Ss[S <: Map ](xs: Array[S]): Array[S] = xs; - def id_Sns_Ss[S <: Strings](xs: Array[S]): Array[S] = xs; - - def id_Sas_a [S <: Any ](xs: Array[S]): Any = xs; - def id_Svs_a [S <: AnyVal ](xs: Array[S]): Any = xs; - def id_Srs_a [S <: AnyRef ](xs: Array[S]): Any = xs; - def id_Sos_a [S <: Object ](xs: Array[S]): Any = xs; - def id_Sms_a [S <: Map ](xs: Array[S]): Any = xs; - def id_Sns_a [S <: Strings](xs: Array[S]): Any = xs; - - def id_Sas_r [S <: Any ](xs: Array[S]): AnyRef = xs; - def id_Svs_r [S <: AnyVal ](xs: Array[S]): AnyRef = xs; - def id_Srs_r [S <: AnyRef ](xs: Array[S]): AnyRef = xs; - def id_Sos_r [S <: Object ](xs: Array[S]): AnyRef = xs; - def id_Sms_r [S <: Map ](xs: Array[S]): AnyRef = xs; - def id_Sns_r [S <: Strings](xs: Array[S]): AnyRef = xs; - - def id_Sas_o [S <: Any ](xs: Array[S]): Object = xs; - def id_Svs_o [S <: AnyVal ](xs: Array[S]): Object = xs; - def id_Srs_o [S <: AnyRef ](xs: Array[S]): Object = xs; - def id_Sos_o [S <: Object ](xs: Array[S]): Object = xs; - def id_Sms_o [S <: Map ](xs: Array[S]): Object = xs; - def id_Sns_o [S <: Strings](xs: Array[S]): Object = xs; - - //########################################################################## - // Generic Checks - - type Check[T] = Array[T] => Unit; - - var checks: Int = 0; - - def check(test0: Boolean, actual: Any, expected: Any) { - val test1: Boolean = actual == expected; - if (!test0 || !test1) { - val s0 = if (test0) "ok" else "KO"; - val s1 = if (test1) "ok" else "KO"; - val s2 = actual.toString(); - val s3 = expected.toString(); - error(s0 + " - " + s1 + ": " + s2 + " != " + s3); - } - checks += 1 - } - - def check_Ta[T <: Any ](xs: Array[T], l: Int, x0: T, c: Check[T]) { - check(xs.length == l, xs.length, l); - check(xs(0) == x0, xs(0), x0); - c(xs); - } - - def check_Tv[T <: AnyVal ](xs: Array[T], l: Int, x0: T, c: Check[T]) { - check(xs.length == l, xs.length, l); - check(xs(0) == x0, xs(0), x0); - check_Ta(xs, l, x0, c); - c(xs); - } - - def check_Tr[T <: AnyRef ](xs: Array[T], l: Int, x0: T, c: Check[T]) { - check(xs.length == l, xs.length, l); - check(xs(0) == x0, xs(0), x0); - check_Ta(xs, l, x0, c); - c(xs); - } - - def check_To[T <: Object ](xs: Array[T], l: Int, x0: T, c: Check[T]) { - check(xs.length == l, xs.length, l); - check(xs(0) == x0, xs(0), x0); - check_Ta(xs, l, x0, c); - check_Tr(xs, l, x0, c); - c(xs); - } - - def check_Tm[T <: Map ](xs: Array[T], l: Int, x0: T, c: Check[T]) { - check(xs.length == l, xs.length, l) - check(xs(0) == x0, xs(0), x0) - check_Ta(xs, l, x0, c) - check_Tr(xs, l, x0, c) - check_To(xs, l, x0, c) - c(xs) - } - - def check_Tn[T <: Strings](xs: Array[T], l: Int, x0: T, c: Check[T]) { - check(xs.length == l, xs.length, l) - check(xs(0) == x0, xs(0), x0) - check_Ta(xs, l, x0, c) - check_Tr(xs, l, x0, c) - check_To(xs, l, x0, c) - c(xs) - } - - def checkT2368() { - val arr = Array(1, 2, 3) - arr(0) += 1 - assert(arr(0) == 2) - } - - //########################################################################## - // Values - - val u0: Unit = (); - val u1: Unit = (); - - val z0: Boolean = false; - val z1: Boolean = true; - - val b0: Byte = Byte.MinValue; - val b1: Byte = 1; - val b2: Byte = Byte.MaxValue; - - val s0: Short = Short.MinValue; - val s1: Short = 2; - val s2: Short = Short.MaxValue; - - val c0: Char = Char.MinValue; - val c1: Char = '3'; - val c2: Char = Char.MaxValue; - - val i0: Int = Int.MinValue; - val i1: Int = 4; - val i2: Int = Int.MinValue; - - val l0: Long = Long.MinValue; - val l1: Int = 5; - val l2: Long = Long.MaxValue; - - val f0: Float = Float.MinValue; - val f1: Int = 6; - val f2: Float = Float.MaxValue; - - val d0: Double = Double.MinValue; - val d1: Int = 7; - val d2: Double = Double.MaxValue; - - val a0: Unit = (); - val a1: Boolean = false; - val a2: Int = 0; - val a3: Null = null; - val a4: String = "a-z"; - val a5: Symbol = 'token; - val a6: HashMap = new HashMap(); - val a7: TreeMap = scala.collection.immutable.TreeMap.empty[Int, Any]; - val a8: Strings = List("a", "z"); - - val v0: Unit = (); - val v1: Boolean = false; - val v2: Int = 0; - val v3: Long = l2; - val v4: Float = f2; - val v5: Double = d2; - - val r0: Null = a3; - val r1: String = a4; - val r2: Symbol = a5; - val r3: HashMap = a6; - val r4: TreeMap = a7; - val r5: Strings = a8; - - val o0: Null = r0; - val o1: String = r1; - val o2: Symbol = r2; - val o3: HashMap = r3; - val o4: TreeMap = r4; - val o5: Strings = r5; - - val m0: Null = r0; - val m1: HashMap = r3; - val m2: TreeMap = r4; - - val n0: Null = r0; - val n1: Strings = r5; - val n2: Nil.type= Nil; - - //########################################################################## - // Specific Checks - - def ucheck(xs: Array[Unit ]): Unit = { - check(xs.length == 2, xs.length, 2); - check(xs(0) == u0, xs(0), u0); - check(xs(1) == u1, xs(1), u1); - } - - def zcheck(xs: Array[Boolean]): Unit = { - check(xs.length == 2, xs.length, 2); - check(xs(0) == z0, xs(0), z0); - check(xs(1) == z1, xs(1), z1); - } - - def bcheck(xs: Array[Byte ]): Unit = { - check(xs.length == 3, xs.length, 3); - check(xs(0) == b0, xs(0), b0); - check(xs(1) == b1, xs(1), b1); - check(xs(2) == b2, xs(2), b2); - } - - def scheck(xs: Array[Short ]): Unit = { - check(xs.length == 3, xs.length, 3); - check(xs(0) == s0, xs(0), s0); - check(xs(1) == s1, xs(1), s1); - check(xs(2) == s2, xs(2), s2); - } - - def ccheck(xs: Array[Char ]): Unit = { - check(xs.length == 3, xs.length, 3); - check(xs(0) == c0, xs(0), c0); - check(xs(1) == c1, xs(1), c1); - check(xs(2) == c2, xs(2), c2); - } - - def icheck(xs: Array[Int ]): Unit = { - check(xs.length == 3, xs.length, 3); - check(xs(0) == i0, xs(0), i0); - check(xs(1) == i1, xs(1), i1); - check(xs(2) == i2, xs(2), i2); - } - - def lcheck(xs: Array[Long ]): Unit = { - check(xs.length == 3, xs.length, 3); - check(xs(0) == l0, xs(0), l0); - check(xs(1) == l1, xs(1), l1: Long); // !!! : Long - check(xs(2) == l2, xs(2), l2); - } - - def fcheck(xs: Array[Float ]): Unit = { - check(xs.length == 3, xs.length, 3); - check(xs(0) == f0, xs(0), f0); - check(xs(1) == f1, xs(1), f1: Float); // !!! : Float - check(xs(2) == f2, xs(2), f2); - } - - def dcheck(xs: Array[Double ]): Unit = { - check(xs.length == 3, xs.length, 3); - check(xs(0) == d0, xs(0), d0); - check(xs(1) == d1, xs(1), d1: Double); // !!! : Double - check(xs(2) == d2, xs(2), d2); - } - - def rcheck(xs: Array[AnyRef ]): Unit = { - check(xs.length == 6, xs.length, 6); - check(xs(0) == r0, xs(0), r0); - check(xs(1) == r1, xs(1), r1); - check(xs(2) == r2, xs(2), r2); - check(xs(3) == r3, xs(3), r3); - check(xs(4) == r4, xs(4), r4); - check(xs(5) == r5, xs(5), r5); - } - - def ocheck(xs: Array[Object ]): Unit = { - check(xs.length == 6, xs.length, 6); - check(xs(0) == o0, xs(0), o0); - check(xs(1) == o1, xs(1), o1); - check(xs(2) == o2, xs(2), o2); - check(xs(3) == o3, xs(3), o3); - check(xs(4) == o4, xs(4), o4); - check(xs(5) == o5, xs(5), o5); - } - - def mcheck(xs: Array[Map ]): Unit = { - check(xs.length == 3, xs.length, 3); - check(xs(0) == m0, xs(0), m0); - check(xs(1) == m1, xs(1), m1); - check(xs(2) == m2, xs(2), m2); - } - - def ncheck(xs: Array[Strings]) { - check(xs.length == 3, xs.length, 3) - check(xs(0) == n0, xs(0), n0) - check(xs(1) == n1, xs(1), n1) - check(xs(2) == n2, xs(2), n2) - } - - //########################################################################## - // Miscellaneous checks - - def checkZip { - val zipped = Array("a", "b", "c").zip(Array(1, 2)) - val expected = Array(("a",1), ("b",2)) - check(zipped sameElements expected, zipped.toList, expected.toList) - } - - def checkConcat { // ticket #713 - val x1 = Array.concat(Array(1, 2), Array(3, 4)) - val y1 = Array(1, 2, 3, 4) - check(x1 sameElements y1, x1.toList, y1.toList) - } - - //########################################################################## - // Arrays - - val uarray: Array[Unit ] = Array(u0, u1); - val zarray: Array[Boolean] = Array(z0, z1); - val barray: Array[Byte ] = Array(b0, b1, b2); - val sarray: Array[Short ] = Array(s0, s1, s2); - val carray: Array[Char ] = Array(c0, c1, c2); - val iarray: Array[Int ] = Array(i0, i1, i2); - val larray: Array[Long ] = Array(l0, l1, l2); - val farray: Array[Float ] = Array(f0, f1, f2); - val darray: Array[Double ] = Array(d0, d1, d2); - val rarray: Array[AnyRef ] = Array(r0, r1, r2, r4, r4, r5); - val oarray: Array[Object ] = Array(o0, o1, o2, o4, o4, o5); - val marray: Array[Map ] = Array(m0, m1, m2); - val narray: Array[Strings] = Array(n0, n1, n2); - - //########################################################################## - // Main - - def main(args: Array[String]): Unit = { - - //###################################################################### - - ucheck(uarray); - zcheck(zarray); - bcheck(barray); - scheck(sarray); - ccheck(carray); - icheck(iarray); - lcheck(larray); - fcheck(farray); - dcheck(darray); - rcheck(rarray); - ocheck(oarray); - mcheck(marray); - ncheck(narray); - - //###################################################################### - - ucheck(id_Ta_T(uarray)); - zcheck(id_Ta_T(zarray)); - bcheck(id_Ta_T(barray)); - scheck(id_Ta_T(sarray)); - ccheck(id_Ta_T(carray)); - icheck(id_Ta_T(iarray)); - lcheck(id_Ta_T(larray)); - fcheck(id_Ta_T(farray)); - dcheck(id_Ta_T(darray)); - rcheck(id_Ta_T(rarray)); - ocheck(id_Ta_T(oarray)); - mcheck(id_Ta_T(marray)); - ncheck(id_Ta_T(narray)); - - ucheck(id_Tr_T(uarray)); - zcheck(id_Tr_T(zarray)); - bcheck(id_Tr_T(barray)); - scheck(id_Tr_T(sarray)); - ccheck(id_Tr_T(carray)); - icheck(id_Tr_T(iarray)); - lcheck(id_Tr_T(larray)); - fcheck(id_Tr_T(farray)); - dcheck(id_Tr_T(darray)); - rcheck(id_Tr_T(rarray)); - ocheck(id_Tr_T(oarray)); - mcheck(id_Tr_T(marray)); - ncheck(id_Tr_T(narray)); - - ucheck(id_To_T(uarray)); - zcheck(id_To_T(zarray)); - bcheck(id_To_T(barray)); - scheck(id_To_T(sarray)); - ccheck(id_To_T(carray)); - icheck(id_To_T(iarray)); - lcheck(id_To_T(larray)); - fcheck(id_To_T(farray)); - dcheck(id_To_T(darray)); - rcheck(id_To_T(rarray)); - ocheck(id_To_T(oarray)); - mcheck(id_To_T(marray)); - ncheck(id_To_T(narray)); - - ucheck(id_Ta_a(uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_Ta_a(zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_Ta_a(barray).asInstanceOf[Array[Byte ]]); - scheck(id_Ta_a(sarray).asInstanceOf[Array[Short ]]); - ccheck(id_Ta_a(carray).asInstanceOf[Array[Char ]]); - icheck(id_Ta_a(iarray).asInstanceOf[Array[Int ]]); - lcheck(id_Ta_a(larray).asInstanceOf[Array[Long ]]); - fcheck(id_Ta_a(farray).asInstanceOf[Array[Float ]]); - dcheck(id_Ta_a(darray).asInstanceOf[Array[Double ]]); - rcheck(id_Ta_a(rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_Ta_a(oarray).asInstanceOf[Array[Object ]]); - mcheck(id_Ta_a(marray).asInstanceOf[Array[Map ]]); - ncheck(id_Ta_a(narray).asInstanceOf[Array[Strings]]); - - ucheck(id_Tr_a(uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_Tr_a(zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_Tr_a(barray).asInstanceOf[Array[Byte ]]); - scheck(id_Tr_a(sarray).asInstanceOf[Array[Short ]]); - ccheck(id_Tr_a(carray).asInstanceOf[Array[Char ]]); - icheck(id_Tr_a(iarray).asInstanceOf[Array[Int ]]); - lcheck(id_Tr_a(larray).asInstanceOf[Array[Long ]]); - fcheck(id_Tr_a(farray).asInstanceOf[Array[Float ]]); - dcheck(id_Tr_a(darray).asInstanceOf[Array[Double ]]); - rcheck(id_Tr_a(rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_Tr_a(oarray).asInstanceOf[Array[Object ]]); - mcheck(id_Tr_a(marray).asInstanceOf[Array[Map ]]); - ncheck(id_Tr_a(narray).asInstanceOf[Array[Strings]]); - - ucheck(id_To_a(uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_To_a(zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_To_a(barray).asInstanceOf[Array[Byte ]]); - scheck(id_To_a(sarray).asInstanceOf[Array[Short ]]); - ccheck(id_To_a(carray).asInstanceOf[Array[Char ]]); - icheck(id_To_a(iarray).asInstanceOf[Array[Int ]]); - lcheck(id_To_a(larray).asInstanceOf[Array[Long ]]); - fcheck(id_To_a(farray).asInstanceOf[Array[Float ]]); - dcheck(id_To_a(darray).asInstanceOf[Array[Double ]]); - rcheck(id_To_a(rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_To_a(oarray).asInstanceOf[Array[Object ]]); - mcheck(id_To_a(marray).asInstanceOf[Array[Map ]]); - ncheck(id_To_a(narray).asInstanceOf[Array[Strings]]); - - ucheck(id_Tr_r(uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_Tr_r(zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_Tr_r(barray).asInstanceOf[Array[Byte ]]); - scheck(id_Tr_r(sarray).asInstanceOf[Array[Short ]]); - ccheck(id_Tr_r(carray).asInstanceOf[Array[Char ]]); - icheck(id_Tr_r(iarray).asInstanceOf[Array[Int ]]); - lcheck(id_Tr_r(larray).asInstanceOf[Array[Long ]]); - fcheck(id_Tr_r(farray).asInstanceOf[Array[Float ]]); - dcheck(id_Tr_r(darray).asInstanceOf[Array[Double ]]); - rcheck(id_Tr_r(rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_Tr_r(oarray).asInstanceOf[Array[Object ]]); - mcheck(id_Tr_r(marray).asInstanceOf[Array[Map ]]); - ncheck(id_Tr_r(narray).asInstanceOf[Array[Strings]]); - - ucheck(id_To_r(uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_To_r(zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_To_r(barray).asInstanceOf[Array[Byte ]]); - scheck(id_To_r(sarray).asInstanceOf[Array[Short ]]); - ccheck(id_To_r(carray).asInstanceOf[Array[Char ]]); - icheck(id_To_r(iarray).asInstanceOf[Array[Int ]]); - lcheck(id_To_r(larray).asInstanceOf[Array[Long ]]); - fcheck(id_To_r(farray).asInstanceOf[Array[Float ]]); - dcheck(id_To_r(darray).asInstanceOf[Array[Double ]]); - rcheck(id_To_r(rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_To_r(oarray).asInstanceOf[Array[Object ]]); - mcheck(id_To_r(marray).asInstanceOf[Array[Map ]]); - ncheck(id_To_r(narray).asInstanceOf[Array[Strings]]); - - ucheck(id_To_o(uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_To_o(zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_To_o(barray).asInstanceOf[Array[Byte ]]); - scheck(id_To_o(sarray).asInstanceOf[Array[Short ]]); - ccheck(id_To_o(carray).asInstanceOf[Array[Char ]]); - icheck(id_To_o(iarray).asInstanceOf[Array[Int ]]); - lcheck(id_To_o(larray).asInstanceOf[Array[Long ]]); - fcheck(id_To_o(farray).asInstanceOf[Array[Float ]]); - dcheck(id_To_o(darray).asInstanceOf[Array[Double ]]); - rcheck(id_To_o(rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_To_o(oarray).asInstanceOf[Array[Object ]]); - mcheck(id_To_o(marray).asInstanceOf[Array[Map ]]); - ncheck(id_To_o(narray).asInstanceOf[Array[Strings]]); - - //###################################################################### - - ucheck(id_TSa_T [Unit , Array[Unit ]](uarray)); - zcheck(id_TSa_T [Boolean, Array[Boolean]](zarray)); - bcheck(id_TSa_T [Byte , Array[Byte ]](barray)); - scheck(id_TSa_T [Short , Array[Short ]](sarray)); - ccheck(id_TSa_T [Char , Array[Char ]](carray)); - icheck(id_TSa_T [Int , Array[Int ]](iarray)); - lcheck(id_TSa_T [Long , Array[Long ]](larray)); - fcheck(id_TSa_T [Float , Array[Float ]](farray)); - dcheck(id_TSa_T [Double , Array[Double ]](darray)); - rcheck(id_TSa_T [AnyRef , Array[AnyRef ]](rarray)); - ocheck(id_TSa_T [Object , Array[Object ]](oarray)); - mcheck(id_TSa_T [Map , Array[Map ]](marray)); - ncheck(id_TSa_T [Strings, Array[Strings]](narray)); - - ucheck(id_TSv_T [Unit , Array[Unit ]](uarray)); - zcheck(id_TSv_T [Boolean, Array[Boolean]](zarray)); - bcheck(id_TSv_T [Byte , Array[Byte ]](barray)); - scheck(id_TSv_T [Short , Array[Short ]](sarray)); - ccheck(id_TSv_T [Char , Array[Char ]](carray)); - icheck(id_TSv_T [Int , Array[Int ]](iarray)); - lcheck(id_TSv_T [Long , Array[Long ]](larray)); - fcheck(id_TSv_T [Float , Array[Float ]](farray)); - dcheck(id_TSv_T [Double , Array[Double ]](darray)); - - rcheck(id_TSr_T [AnyRef , Array[AnyRef ]](rarray)); - ocheck(id_TSr_T [Object , Array[Object ]](oarray)); - mcheck(id_TSr_T [Map , Array[Map ]](marray)); - ncheck(id_TSr_T [Strings, Array[Strings]](narray)); - - rcheck(id_TSo_T [AnyRef , Array[AnyRef ]](rarray)); - ocheck(id_TSo_T [Object , Array[Object ]](oarray)); - mcheck(id_TSo_T [Map , Array[Map ]](marray)); - ncheck(id_TSo_T [Strings, Array[Strings]](narray)); - - mcheck(id_TSm_T [Map , Array[Map ]](marray)); - - ncheck(id_TSn_T [Strings, Array[Strings]](narray)); - - //###################################################################### - - ucheck(id_TSa_Ss[Unit , Array[Unit ]](uarray)); - zcheck(id_TSa_Ss[Boolean, Array[Boolean]](zarray)); - bcheck(id_TSa_Ss[Byte , Array[Byte ]](barray)); - scheck(id_TSa_Ss[Short , Array[Short ]](sarray)); - ccheck(id_TSa_Ss[Char , Array[Char ]](carray)); - icheck(id_TSa_Ss[Int , Array[Int ]](iarray)); - lcheck(id_TSa_Ss[Long , Array[Long ]](larray)); - fcheck(id_TSa_Ss[Float , Array[Float ]](farray)); - dcheck(id_TSa_Ss[Double , Array[Double ]](darray)); - rcheck(id_TSa_Ss[AnyRef , Array[AnyRef ]](rarray)); - ocheck(id_TSa_Ss[Object , Array[Object ]](oarray)); - mcheck(id_TSa_Ss[Map , Array[Map ]](marray)); - ncheck(id_TSa_Ss[Strings, Array[Strings]](narray)); - - ucheck(id_TSv_Ss[Unit , Array[Unit ]](uarray)); - zcheck(id_TSv_Ss[Boolean, Array[Boolean]](zarray)); - bcheck(id_TSv_Ss[Byte , Array[Byte ]](barray)); - scheck(id_TSv_Ss[Short , Array[Short ]](sarray)); - ccheck(id_TSv_Ss[Char , Array[Char ]](carray)); - icheck(id_TSv_Ss[Int , Array[Int ]](iarray)); - lcheck(id_TSv_Ss[Long , Array[Long ]](larray)); - fcheck(id_TSv_Ss[Float , Array[Float ]](farray)); - dcheck(id_TSv_Ss[Double , Array[Double ]](darray)); - - rcheck(id_TSr_Ss[AnyRef , Array[AnyRef ]](rarray)); - ocheck(id_TSr_Ss[Object , Array[Object ]](oarray)); - mcheck(id_TSr_Ss[Map , Array[Map ]](marray)); - ncheck(id_TSr_Ss[Strings, Array[Strings]](narray)); - - rcheck(id_TSo_Ss[AnyRef , Array[AnyRef ]](rarray)); - ocheck(id_TSo_Ss[Object , Array[Object ]](oarray)); - mcheck(id_TSo_Ss[Map , Array[Map ]](marray)); - ncheck(id_TSo_Ss[Strings, Array[Strings]](narray)); - - mcheck(id_TSm_Ss[Map , Array[Map ]](marray)); - - ncheck(id_TSn_Ss[Strings, Array[Strings]](narray)); - - //###################################################################### - - ucheck(id_TSa_a [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSa_a [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSa_a [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSa_a [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSa_a [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSa_a [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSa_a [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSa_a [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSa_a [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - rcheck(id_TSa_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSa_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSa_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSa_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - ucheck(id_TSv_a [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSv_a [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSv_a [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSv_a [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSv_a [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSv_a [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSv_a [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSv_a [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSv_a [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - - rcheck(id_TSr_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSr_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSr_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSr_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - rcheck(id_TSo_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSo_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSo_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSo_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - mcheck(id_TSm_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - - ncheck(id_TSn_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - //###################################################################### - - ucheck(id_TSa_r [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSa_r [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSa_r [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSa_r [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSa_r [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSa_r [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSa_r [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSa_r [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSa_r [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - rcheck(id_TSa_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSa_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSa_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSa_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - ucheck(id_TSv_r [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSv_r [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSv_r [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSv_r [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSv_r [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSv_r [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSv_r [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSv_r [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSv_r [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - - rcheck(id_TSr_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSr_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSr_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSr_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - rcheck(id_TSo_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSo_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSo_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSo_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - mcheck(id_TSm_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - - ncheck(id_TSn_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - //###################################################################### - - ucheck(id_TSa_o [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSa_o [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSa_o [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSa_o [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSa_o [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSa_o [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSa_o [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSa_o [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSa_o [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - rcheck(id_TSa_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSa_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSa_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSa_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - ucheck(id_TSv_o [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSv_o [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSv_o [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSv_o [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSv_o [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSv_o [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSv_o [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSv_o [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSv_o [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - - rcheck(id_TSr_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSr_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSr_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSr_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - rcheck(id_TSo_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSo_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSo_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSo_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - mcheck(id_TSm_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - - ncheck(id_TSn_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - //###################################################################### - - ucheck(id_Sas_Ss[Unit ](uarray)); - zcheck(id_Sas_Ss[Boolean](zarray)); - bcheck(id_Sas_Ss[Byte ](barray)); - scheck(id_Sas_Ss[Short ](sarray)); - ccheck(id_Sas_Ss[Char ](carray)); - icheck(id_Sas_Ss[Int ](iarray)); - lcheck(id_Sas_Ss[Long ](larray)); - fcheck(id_Sas_Ss[Float ](farray)); - dcheck(id_Sas_Ss[Double ](darray)); - rcheck(id_Sas_Ss[AnyRef ](rarray)); - ocheck(id_Sas_Ss[Object ](oarray)); - mcheck(id_Sas_Ss[Map ](marray)); - ncheck(id_Sas_Ss[Strings](narray)); - - ucheck(id_Svs_Ss[Unit ](uarray)); - zcheck(id_Svs_Ss[Boolean](zarray)); - bcheck(id_Svs_Ss[Byte ](barray)); - scheck(id_Svs_Ss[Short ](sarray)); - ccheck(id_Svs_Ss[Char ](carray)); - icheck(id_Svs_Ss[Int ](iarray)); - lcheck(id_Svs_Ss[Long ](larray)); - fcheck(id_Svs_Ss[Float ](farray)); - dcheck(id_Svs_Ss[Double ](darray)); - - rcheck(id_Srs_Ss[AnyRef ](rarray)); - ocheck(id_Srs_Ss[Object ](oarray)); - mcheck(id_Srs_Ss[Map ](marray)); - ncheck(id_Srs_Ss[Strings](narray)); - - rcheck(id_Sos_Ss[AnyRef ](rarray)); - ocheck(id_Sos_Ss[Object ](oarray)); - mcheck(id_Sos_Ss[Map ](marray)); - ncheck(id_Sos_Ss[Strings](narray)); - - mcheck(id_Sms_Ss[Map ](marray)); - - ncheck(id_Sns_Ss[Strings](narray)); - - //###################################################################### - - ucheck(id_TSa_a [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSa_a [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSa_a [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSa_a [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSa_a [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSa_a [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSa_a [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSa_a [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSa_a [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - rcheck(id_TSa_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSa_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSa_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSa_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - ucheck(id_TSv_a [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSv_a [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSv_a [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSv_a [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSv_a [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSv_a [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSv_a [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSv_a [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSv_a [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - - rcheck(id_TSr_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSr_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSr_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSr_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - rcheck(id_TSo_a [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSo_a [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSo_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSo_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - mcheck(id_TSm_a [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - - ncheck(id_TSn_a [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - //###################################################################### - - ucheck(id_TSa_r [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSa_r [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSa_r [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSa_r [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSa_r [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSa_r [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSa_r [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSa_r [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSa_r [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - rcheck(id_TSa_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSa_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSa_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSa_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - ucheck(id_TSv_r [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSv_r [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSv_r [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSv_r [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSv_r [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSv_r [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSv_r [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSv_r [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSv_r [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - - rcheck(id_TSr_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSr_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSr_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSr_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - rcheck(id_TSo_r [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSo_r [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSo_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSo_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - mcheck(id_TSm_r [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - - ncheck(id_TSn_r [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - //###################################################################### - - ucheck(id_TSa_o [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSa_o [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSa_o [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSa_o [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSa_o [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSa_o [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSa_o [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSa_o [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSa_o [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - rcheck(id_TSa_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSa_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSa_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSa_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - ucheck(id_TSv_o [Unit , Array[Unit ]](uarray).asInstanceOf[Array[Unit ]]); - zcheck(id_TSv_o [Boolean, Array[Boolean]](zarray).asInstanceOf[Array[Boolean]]); - bcheck(id_TSv_o [Byte , Array[Byte ]](barray).asInstanceOf[Array[Byte ]]); - scheck(id_TSv_o [Short , Array[Short ]](sarray).asInstanceOf[Array[Short ]]); - ccheck(id_TSv_o [Char , Array[Char ]](carray).asInstanceOf[Array[Char ]]); - icheck(id_TSv_o [Int , Array[Int ]](iarray).asInstanceOf[Array[Int ]]); - lcheck(id_TSv_o [Long , Array[Long ]](larray).asInstanceOf[Array[Long ]]); - fcheck(id_TSv_o [Float , Array[Float ]](farray).asInstanceOf[Array[Float ]]); - dcheck(id_TSv_o [Double , Array[Double ]](darray).asInstanceOf[Array[Double ]]); - - rcheck(id_TSr_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSr_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSr_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSr_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - rcheck(id_TSo_o [AnyRef , Array[AnyRef ]](rarray).asInstanceOf[Array[AnyRef ]]); - ocheck(id_TSo_o [Object , Array[Object ]](oarray).asInstanceOf[Array[Object ]]); - mcheck(id_TSo_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - ncheck(id_TSo_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - mcheck(id_TSm_o [Map , Array[Map ]](marray).asInstanceOf[Array[Map ]]); - - ncheck(id_TSn_o [Strings, Array[Strings]](narray).asInstanceOf[Array[Strings]]); - - //###################################################################### - - check_Ta(uarray, 2, u0, ucheck) - check_Ta(zarray, 2, z0, zcheck) - check_Ta(barray, 3, b0, bcheck) - check_Ta(sarray, 3, s0, scheck) - check_Ta(carray, 3, c0, ccheck) - check_Ta(iarray, 3, i0, icheck) - check_Ta(larray, 3, l0, lcheck) - check_Ta(farray, 3, f0, fcheck) - check_Ta(darray, 3, d0, dcheck) - check_Ta(rarray, 6, r0, rcheck) - check_Ta(oarray, 6, o0, ocheck) - check_Ta(marray, 3, m0, mcheck) - check_Ta(narray, 3, n0, ncheck) - - check_Tv(uarray, 2, u0, ucheck) - check_Tv(zarray, 2, z0, zcheck) - check_Tv(barray, 3, b0, bcheck) - check_Tv(sarray, 3, s0, scheck) - check_Tv(carray, 3, c0, ccheck) - check_Tv(iarray, 3, i0, icheck) - check_Tv(larray, 3, l0, lcheck) - check_Tv(farray, 3, f0, fcheck) - check_Tv(darray, 3, d0, dcheck) - - check_Tr(rarray, 6, r0, rcheck) - check_Tr(oarray, 6, o0, ocheck) - check_Tr(marray, 3, m0, mcheck) - check_Tr(narray, 3, n0, ncheck) - - check_To(rarray, 6, r0, rcheck) - check_To(oarray, 6, o0, ocheck) - check_To(marray, 3, m0, mcheck) - check_To(narray, 3, n0, ncheck) - - check_Tm(marray, 3, m0, mcheck) - - check_Tn(narray, 3, n0, ncheck) - - //###################################################################### - - checkZip - checkConcat - checkT2368() - - //###################################################################### - - println("checks: " + checks) - - //###################################################################### - } - - //########################################################################## -} - -- cgit v1.2.3 From 535c8d73c9a870c3b03bbd25be31cfe7c7ed9fe7 Mon Sep 17 00:00:00 2001 From: Vojin Jovanovic Date: Thu, 12 Apr 2012 16:28:35 +0200 Subject: Moving Duration DSL to a separate package. Reverting to Java 6 time units. Review by: @phaller --- src/library/scala/concurrent/util/Duration.scala | 174 ++++++++------------- .../concurrent/util/duration/Classifier.scala | 9 ++ .../util/duration/NumericMultiplication.scala | 18 +++ .../scala/concurrent/util/duration/package.scala | 30 ++++ 4 files changed, 121 insertions(+), 110 deletions(-) create mode 100644 src/library/scala/concurrent/util/duration/Classifier.scala create mode 100644 src/library/scala/concurrent/util/duration/NumericMultiplication.scala create mode 100644 src/library/scala/concurrent/util/duration/package.scala diff --git a/src/library/scala/concurrent/util/Duration.scala b/src/library/scala/concurrent/util/Duration.scala index 33d034da76..6ee1696d39 100644 --- a/src/library/scala/concurrent/util/Duration.scala +++ b/src/library/scala/concurrent/util/Duration.scala @@ -8,51 +8,6 @@ import java.util.concurrent.TimeUnit import TimeUnit._ import java.lang.{ Double ⇒ JDouble } -object DurationImplicits { - trait Classifier[C] { - type R - def convert(d: FiniteDuration): R - } - - object span - implicit object spanConvert extends Classifier[span.type] { - type R = FiniteDuration - def convert(d: FiniteDuration) = d - } - - object fromNow - implicit object fromNowConvert extends Classifier[fromNow.type] { - type R = Deadline - def convert(d: FiniteDuration) = Deadline.now + d - } - - implicit def intToDurationInt(n: Int) = new DurationInt(n) - implicit def longToDurationLong(n: Long) = new DurationLong(n) - implicit def doubleToDurationDouble(d: Double) = new DurationDouble(d) - - implicit def pairIntToDuration(p: (Int, TimeUnit)) = Duration(p._1, p._2) - implicit def pairLongToDuration(p: (Long, TimeUnit)) = Duration(p._1, p._2) - implicit def durationToPair(d: Duration) = (d.length, d.unit) - - /* - * Avoid reflection based invocation by using non-duck type - */ - class IntMult(i: Int) { - def *(d: Duration) = d * i - } - implicit def intMult(i: Int) = new IntMult(i) - - class LongMult(l: Long) { - def *(d: Duration) = d * l - } - implicit def longMult(l: Long) = new LongMult(l) - - class DoubleMult(f: Double) { - def *(d: Duration) = d * f - } - implicit def doubleMult(f: Double) = new DoubleMult(f) -} - case class Deadline private (time: Duration) { def +(other: Duration): Deadline = copy(time = time + other) def -(other: Duration): Deadline = copy(time = time - other) @@ -71,10 +26,7 @@ object Duration { def apply(length: Long, unit: TimeUnit): FiniteDuration = new FiniteDuration(length, unit) def apply(length: Double, unit: TimeUnit): FiniteDuration = fromNanos(unit.toNanos(1) * length) - def apply(length: Long, unit: String): FiniteDuration = { - val (mult, timeUnit) = Duration.timeUnit(unit) - new FiniteDuration(length * mult, timeUnit) - } + def apply(length: Long, unit: String): FiniteDuration = new FiniteDuration(length, Duration.timeUnit(unit)) /** * Construct a Duration by parsing a String. In case of a format error, a @@ -117,11 +69,11 @@ object Duration { def unapply(s: String): Option[Duration] = s match { case RE(length, d, h, m, s, ms, mus, ns) ⇒ if (d ne null) - Some(Duration(JDouble.parseDouble(length) * 86400, SECONDS)) + Some(Duration(JDouble.parseDouble(length), DAYS)) else if (h ne null) - Some(Duration(JDouble.parseDouble(length) * 3600, SECONDS)) + Some(Duration(JDouble.parseDouble(length), HOURS)) else if (m ne null) - Some(Duration(JDouble.parseDouble(length) * 60, SECONDS)) + Some(Duration(JDouble.parseDouble(length), MINUTES)) else if (s ne null) Some(Duration(JDouble.parseDouble(length), SECONDS)) else if (ms ne null) @@ -142,11 +94,11 @@ object Duration { def fromNanos(nanos: Long): FiniteDuration = { if (nanos % 86400000000000L == 0) { - Duration(nanos / 1000000000L, SECONDS) - } else if (nanos % 1000000000L == 0) { - Duration(nanos / 1000000000L, SECONDS) - } else if (nanos % 1000000000L == 0) { - Duration(nanos / 1000000000L, SECONDS) + Duration(nanos / 86400000000000L, DAYS) + } else if (nanos % 3600000000000L == 0) { + Duration(nanos / 3600000000000L, HOURS) + } else if (nanos % 60000000000L == 0) { + Duration(nanos / 60000000000L, MINUTES) } else if (nanos % 1000000000L == 0) { Duration(nanos / 1000000000L, SECONDS) } else if (nanos % 1000000L == 0) { @@ -161,14 +113,14 @@ object Duration { /** * Parse TimeUnit from string representation. */ - protected[util] def timeUnit(unit: String): (Long, TimeUnit) = unit.toLowerCase match { - case "d" | "day" | "days" ⇒ (86400, SECONDS) - case "h" | "hour" | "hours" ⇒ (3600, SECONDS) - case "min" | "minute" | "minutes" ⇒ (60, SECONDS) - case "s" | "sec" | "second" | "seconds" ⇒ (1, SECONDS) - case "ms" | "milli" | "millis" | "millisecond" | "milliseconds" ⇒ (1, MILLISECONDS) - case "µs" | "micro" | "micros" | "microsecond" | "microseconds" ⇒ (1, MICROSECONDS) - case "ns" | "nano" | "nanos" | "nanosecond" | "nanoseconds" ⇒ (1, NANOSECONDS) + protected[util] def timeUnit(unit: String): TimeUnit = unit.toLowerCase match { + case "d" | "day" | "days" ⇒ DAYS + case "h" | "hour" | "hours" ⇒ HOURS + case "min" | "minute" | "minutes" ⇒ MINUTES + case "s" | "sec" | "second" | "seconds" ⇒ SECONDS + case "ms" | "milli" | "millis" | "millisecond" | "milliseconds" ⇒ MILLISECONDS + case "µs" | "micro" | "micros" | "microsecond" | "microseconds" ⇒ MICROSECONDS + case "ns" | "nano" | "nanos" | "nanosecond" | "nanoseconds" ⇒ NANOSECONDS } val Zero: FiniteDuration = new FiniteDuration(0, NANOSECONDS) @@ -328,13 +280,9 @@ object FiniteDuration { def compare(a: FiniteDuration, b: FiniteDuration) = a compare b } - def apply(length: Long, unit: TimeUnit) = - new FiniteDuration(length, unit) + def apply(length: Long, unit: TimeUnit) = new FiniteDuration(length, unit) - def apply(length: Long, unit: String) = { - val (mult, timeUnit) = Duration.timeUnit(unit) - new FiniteDuration(length * mult, timeUnit) - } + def apply(length: Long, unit: String) = new FiniteDuration(length, Duration.timeUnit(unit)) } @@ -351,6 +299,12 @@ class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration { def toUnit(u: TimeUnit) = long2double(toNanos) / NANOSECONDS.convert(1, u) override def toString = this match { + case Duration(1, DAYS) ⇒ "1 day" + case Duration(x, DAYS) ⇒ x + " days" + case Duration(1, HOURS) ⇒ "1 hour" + case Duration(x, HOURS) ⇒ x + " hours" + case Duration(1, MINUTES) ⇒ "1 minute" + case Duration(x, MINUTES) ⇒ x + " minutes" case Duration(1, SECONDS) ⇒ "1 second" case Duration(x, SECONDS) ⇒ x + " seconds" case Duration(1, MILLISECONDS) ⇒ "1 millisecond" @@ -404,7 +358,7 @@ class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration { } class DurationInt(n: Int) { - import DurationImplicits.Classifier + import duration.Classifier def nanoseconds = Duration(n, NANOSECONDS) def nanos = Duration(n, NANOSECONDS) @@ -424,14 +378,14 @@ class DurationInt(n: Int) { def seconds = Duration(n, SECONDS) def second = Duration(n, SECONDS) - def minutes = Duration(n * 60, SECONDS) - def minute = Duration(n * 60, SECONDS) + def minutes = Duration(n, MINUTES) + def minute = Duration(n, MINUTES) - def hours = Duration(n * 3600, SECONDS) - def hour = Duration(n * 3600, SECONDS) + def hours = Duration(n, HOURS) + def hour = Duration(n, HOURS) - def days = Duration(n * 86400, SECONDS) - def day = Duration(n * 86400, SECONDS) + def days = Duration(n, DAYS) + def day = Duration(n, DAYS) def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS)) def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS)) @@ -451,18 +405,18 @@ class DurationInt(n: Int) { def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS)) def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS)) - def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS)) - def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS)) + def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES)) + def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES)) - def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS)) - def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS)) + def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS)) + def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS)) - def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS)) - def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS)) + def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS)) + def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS)) } class DurationLong(n: Long) { - import DurationImplicits.Classifier + import duration.Classifier def nanoseconds = Duration(n, NANOSECONDS) def nanos = Duration(n, NANOSECONDS) @@ -482,14 +436,14 @@ class DurationLong(n: Long) { def seconds = Duration(n, SECONDS) def second = Duration(n, SECONDS) - def minutes = Duration(n * 60, SECONDS) - def minute = Duration(n * 60, SECONDS) + def minutes = Duration(n, MINUTES) + def minute = Duration(n, MINUTES) - def hours = Duration(n * 3600, SECONDS) - def hour = Duration(n * 3600, SECONDS) + def hours = Duration(n, HOURS) + def hour = Duration(n, HOURS) - def days = Duration(n * 86400, SECONDS) - def day = Duration(n * 86400, SECONDS) + def days = Duration(n, DAYS) + def day = Duration(n, DAYS) def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS)) def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS)) @@ -509,18 +463,18 @@ class DurationLong(n: Long) { def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS)) def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS)) - def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS)) - def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS)) + def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES)) + def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES)) - def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS)) - def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS)) + def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS)) + def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS)) - def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS)) - def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS)) + def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS)) + def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS)) } class DurationDouble(d: Double) { - import DurationImplicits.Classifier + import duration.Classifier def nanoseconds = Duration(d, NANOSECONDS) def nanos = Duration(d, NANOSECONDS) @@ -540,14 +494,14 @@ class DurationDouble(d: Double) { def seconds = Duration(d, SECONDS) def second = Duration(d, SECONDS) - def minutes = Duration(d * 60, SECONDS) - def minute = Duration(d * 60, SECONDS) + def minutes = Duration(d, MINUTES) + def minute = Duration(d, MINUTES) - def hours = Duration(d * 3600, SECONDS) - def hour = Duration(d * 3600, SECONDS) + def hours = Duration(d, HOURS) + def hour = Duration(d, HOURS) - def days = Duration(d * 86400, SECONDS) - def day = Duration(d * 86400, SECONDS) + def days = Duration(d, DAYS) + def day = Duration(d, DAYS) def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, NANOSECONDS)) def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, NANOSECONDS)) @@ -567,12 +521,12 @@ class DurationDouble(d: Double) { def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, SECONDS)) def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, SECONDS)) - def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 60, SECONDS)) - def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 60, SECONDS)) + def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MINUTES)) + def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MINUTES)) - def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 3600, SECONDS)) - def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 3600, SECONDS)) + def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, HOURS)) + def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, HOURS)) - def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 86400, SECONDS)) - def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 86400, SECONDS)) + def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, DAYS)) + def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, DAYS)) } diff --git a/src/library/scala/concurrent/util/duration/Classifier.scala b/src/library/scala/concurrent/util/duration/Classifier.scala new file mode 100644 index 0000000000..10faf0a5ce --- /dev/null +++ b/src/library/scala/concurrent/util/duration/Classifier.scala @@ -0,0 +1,9 @@ +package scala.concurrent.util.duration + +import scala.concurrent.util.{ FiniteDuration } + +trait Classifier[C] { + type R + def convert(d: FiniteDuration): R +} + diff --git a/src/library/scala/concurrent/util/duration/NumericMultiplication.scala b/src/library/scala/concurrent/util/duration/NumericMultiplication.scala new file mode 100644 index 0000000000..94c58fb8c2 --- /dev/null +++ b/src/library/scala/concurrent/util/duration/NumericMultiplication.scala @@ -0,0 +1,18 @@ +package scala.concurrent.util.duration + +import scala.concurrent.util.{ Duration } + +/* + * Avoid reflection based invocation by using non-duck type + */ +protected[duration] class IntMult(i: Int) { + def *(d: Duration) = d * i +} + +protected[duration] class LongMult(i: Long) { + def *(d: Duration) = d * i +} + +protected[duration] class DoubleMult(f: Double) { + def *(d: Duration) = d * f +} diff --git a/src/library/scala/concurrent/util/duration/package.scala b/src/library/scala/concurrent/util/duration/package.scala new file mode 100644 index 0000000000..25625054ee --- /dev/null +++ b/src/library/scala/concurrent/util/duration/package.scala @@ -0,0 +1,30 @@ +package scala.concurrent.util + +import java.util.concurrent.TimeUnit + +package object duration { + + object span + implicit object spanConvert extends Classifier[span.type] { + type R = FiniteDuration + def convert(d: FiniteDuration) = d + } + + object fromNow + implicit object fromNowConvert extends Classifier[fromNow.type] { + type R = Deadline + def convert(d: FiniteDuration) = Deadline.now + d + } + + implicit def intToDurationInt(n: Int) = new DurationInt(n) + implicit def longToDurationLong(n: Long) = new DurationLong(n) + implicit def doubleToDurationDouble(d: Double) = new DurationDouble(d) + + implicit def pairIntToDuration(p: (Int, TimeUnit)) = Duration(p._1, p._2) + implicit def pairLongToDuration(p: (Long, TimeUnit)) = Duration(p._1, p._2) + implicit def durationToPair(d: Duration) = (d.length, d.unit) + + implicit def intMult(i: Int) = new IntMult(i) + implicit def longMult(l: Long) = new LongMult(l) + implicit def doubleMult(f: Double) = new DoubleMult(f) +} \ No newline at end of file -- cgit v1.2.3 From 6e7382b5da213ca56bde1b1ad9e48f94b24de172 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 12 Apr 2012 16:15:43 +0100 Subject: New starr with implicit classes and macros. --- lib/scala-compiler.jar.desired.sha1 | 2 +- lib/scala-library-src.jar.desired.sha1 | 2 +- lib/scala-library.jar.desired.sha1 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index 3f94b85db9..3d5a0edfd5 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -82af2cfc6a81ae12f39c55c9cf684c5ec01971d3 ?scala-compiler.jar +52e6cc393c953df8c6cbe710f8d62dce6cd1f671 ?scala-compiler.jar diff --git a/lib/scala-library-src.jar.desired.sha1 b/lib/scala-library-src.jar.desired.sha1 index 51704e29c9..0ea32125f5 100644 --- a/lib/scala-library-src.jar.desired.sha1 +++ b/lib/scala-library-src.jar.desired.sha1 @@ -1 +1 @@ -d407ee67fa7e0d79e8e5786fb32ea7c9bdf5b088 ?scala-library-src.jar +b85bc62675c2262a75ddcdd4df2dfc0ea0ddc2dd ?scala-library-src.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index bf1f4829f2..028ef2fae2 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -6a58ca2e4398623145c179f4ce215bfb86a065c4 ?scala-library.jar +569b35836872765f0b96a6477d7c37a257cc62e7 ?scala-library.jar -- cgit v1.2.3 From 39a88f5680c3a16bf7ca856683989a2f5481bf69 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 12 Apr 2012 18:20:54 +0100 Subject: Revert "Enabled continuations plugin by default." This reverts commit da35106f81a5c24e78ff51c95e10052ad4f23b18. --- build.xml | 6 +++--- .../plugin/scala/tools/selectivecps/CPSUtils.scala | 2 +- .../scala/tools/selectivecps/SelectiveCPSPlugin.scala | 19 +++++++++++-------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/build.xml b/build.xml index 29c84cd610..de58ed8909 100644 --- a/build.xml +++ b/build.xml @@ -826,7 +826,7 @@ QUICK BUILD (QUICK) @@ -1363,7 +1363,7 @@ BOOTSTRAPPING BUILD (STRAP) @@ -1937,7 +1937,7 @@ BOOTRAPING TEST AND TEST SUITE + scalacopts="${scalac.args.optimise} -Xplugin-require:continuations -P:continuations:enable"> diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala index 67ea6e15f0..6f5284f75f 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala @@ -9,7 +9,7 @@ trait CPSUtils { import global._ import definitions._ - var cpsEnabled = true + var cpsEnabled = false val verbose: Boolean = System.getProperty("cpsVerbose", "false") == "true" def vprintln(x: =>Any): Unit = if (verbose) println(x) diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala index eb18f03748..8a500d6c4d 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala @@ -26,6 +26,7 @@ class SelectiveCPSPlugin(val global: Global) extends Plugin { override val runsBefore = List("uncurry") } + val components = List[PluginComponent](anfPhase, cpsPhase) val checker = new CPSAnnotationChecker { @@ -42,17 +43,19 @@ class SelectiveCPSPlugin(val global: Global) extends Plugin { } // TODO: require -enabled command-line flag + override def processOptions(options: List[String], error: String => Unit) = { - var enabled = true - options foreach { - case "enable" => enabled = true - case "disable" => enabled = false - case option => error("Option not understood: "+option) + var enabled = false + for (option <- options) { + if (option == "enable") { + enabled = true + } else { + error("Option not understood: "+option) + } } setEnabled(enabled) } - override val optionsHelp: Option[String] = { - Some(" -P:continuations:disable Disable continuations plugin") - } + override val optionsHelp: Option[String] = + Some(" -P:continuations:enable Enable continuations") } -- cgit v1.2.3 From 27a978ab89a7e5036e55e072f7a5d09d8ea817e6 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 12 Apr 2012 18:34:08 +0100 Subject: Reconfigure build.xml so -Xmacros isn't lost. For future reference, -Dscalac.args is how unknown things pass arbitrary parameters to scalac, so you don't want to put anything there you don't expect to lose. --- build.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.xml b/build.xml index de58ed8909..51fffd79d0 100644 --- a/build.xml +++ b/build.xml @@ -170,7 +170,7 @@ PROPERTIES - + @@ -314,12 +314,13 @@ INITIALISATION + - + -- cgit v1.2.3 From cfc4757a580c537425857ff849f3dc106d924092 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 12 Apr 2012 21:58:55 +0200 Subject: fixes petty macro tests --- .../scala/tools/nsc/typechecker/Typers.scala | 4 +- ...cro-deprecate-dont-touch-backquotedidents.check | 22 +++--- ...cro-deprecate-dont-touch-backquotedidents.flags | 1 + ...cro-deprecate-dont-touch-backquotedidents.scala | 56 ++++++++++++++++ .../Macros_Bind_12.scala | 6 -- .../Macros_Class_4.scala | 3 - .../Macros_Class_5.scala | 3 - .../Macros_Def_13.scala | 3 - .../Macros_Object_6.scala | 3 - .../Macros_Object_7.scala | 3 - .../Macros_Package_10.scala | 3 - .../Macros_Package_11.scala | 3 - .../Macros_Trait_8.scala | 3 - .../Macros_Trait_9.scala | 3 - .../Macros_Type_3.scala | 3 - .../Macros_Val_1.scala | 3 - .../Macros_Var_2.scala | 3 - .../Main.scala | 2 - test/files/neg/macro-deprecate-idents.check | 78 ++++++++++------------ test/files/neg/macro-deprecate-idents.flags | 1 + test/files/neg/macro-deprecate-idents.scala | 56 ++++++++++++++++ .../macro-deprecate-idents/Macros_Bind_12.scala | 6 -- .../macro-deprecate-idents/Macros_Class_4.scala | 3 - .../macro-deprecate-idents/Macros_Class_5.scala | 3 - .../neg/macro-deprecate-idents/Macros_Def_13.scala | 3 - .../macro-deprecate-idents/Macros_Object_6.scala | 3 - .../macro-deprecate-idents/Macros_Object_7.scala | 3 - .../macro-deprecate-idents/Macros_Package_10.scala | 3 - .../macro-deprecate-idents/Macros_Package_11.scala | 3 - .../macro-deprecate-idents/Macros_Trait_8.scala | 3 - .../macro-deprecate-idents/Macros_Trait_9.scala | 3 - .../neg/macro-deprecate-idents/Macros_Type_3.scala | 3 - .../neg/macro-deprecate-idents/Macros_Val_1.scala | 3 - .../neg/macro-deprecate-idents/Macros_Var_2.scala | 3 - test/files/neg/macro-deprecate-idents/Main.scala | 2 - test/files/neg/macro-keyword-bind.check | 7 ++ test/files/neg/macro-keyword-bind.flags | 1 + test/files/neg/macro-keyword-bind.scala | 6 ++ test/files/neg/macro-keyword-class1.check | 4 ++ test/files/neg/macro-keyword-class1.flags | 1 + test/files/neg/macro-keyword-class1.scala | 3 + test/files/neg/macro-keyword-class2.check | 4 ++ test/files/neg/macro-keyword-class2.flags | 1 + test/files/neg/macro-keyword-class2.scala | 3 + test/files/neg/macro-keyword-object1.check | 4 ++ test/files/neg/macro-keyword-object1.flags | 1 + test/files/neg/macro-keyword-object1.scala | 3 + test/files/neg/macro-keyword-object2.check | 4 ++ test/files/neg/macro-keyword-object2.flags | 1 + test/files/neg/macro-keyword-object2.scala | 3 + test/files/neg/macro-keyword-package1.check | 4 ++ test/files/neg/macro-keyword-package1.flags | 1 + test/files/neg/macro-keyword-package1.scala | 3 + test/files/neg/macro-keyword-package2.check | 4 ++ test/files/neg/macro-keyword-package2.flags | 1 + test/files/neg/macro-keyword-package2.scala | 3 + test/files/neg/macro-keyword-trait1.check | 4 ++ test/files/neg/macro-keyword-trait1.flags | 1 + test/files/neg/macro-keyword-trait1.scala | 3 + test/files/neg/macro-keyword-trait2.check | 4 ++ test/files/neg/macro-keyword-trait2.flags | 1 + test/files/neg/macro-keyword-trait2.scala | 3 + test/files/neg/macro-keyword-type.check | 4 ++ test/files/neg/macro-keyword-type.flags | 1 + test/files/neg/macro-keyword-type.scala | 3 + test/files/neg/macro-keyword-val.check | 7 ++ test/files/neg/macro-keyword-val.flags | 1 + test/files/neg/macro-keyword-val.scala | 3 + test/files/neg/macro-keyword-var.check | 7 ++ test/files/neg/macro-keyword-var.flags | 1 + test/files/neg/macro-keyword-var.scala | 3 + test/files/neg/macro-keyword.check | 49 -------------- test/files/neg/macro-keyword.flags | 1 - test/files/neg/macro-keyword/Macros_Bind_12.scala | 6 -- test/files/neg/macro-keyword/Macros_Class_4.scala | 3 - test/files/neg/macro-keyword/Macros_Class_5.scala | 3 - test/files/neg/macro-keyword/Macros_Def_13.scala | 3 - test/files/neg/macro-keyword/Macros_Object_6.scala | 3 - test/files/neg/macro-keyword/Macros_Object_7.scala | 3 - .../neg/macro-keyword/Macros_Package_10.scala | 3 - .../neg/macro-keyword/Macros_Package_11.scala | 3 - test/files/neg/macro-keyword/Macros_Trait_8.scala | 3 - test/files/neg/macro-keyword/Macros_Trait_9.scala | 3 - test/files/neg/macro-keyword/Macros_Type_3.scala | 3 - test/files/neg/macro-keyword/Macros_Val_1.scala | 3 - test/files/neg/macro-keyword/Macros_Var_2.scala | 3 - 86 files changed, 270 insertions(+), 236 deletions(-) create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents.flags create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala create mode 100644 test/files/neg/macro-deprecate-idents.flags create mode 100644 test/files/neg/macro-deprecate-idents.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Class_4.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Class_5.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Def_13.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Object_6.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Object_7.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Package_10.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Package_11.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Type_3.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Val_1.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Macros_Var_2.scala delete mode 100644 test/files/neg/macro-deprecate-idents/Main.scala create mode 100644 test/files/neg/macro-keyword-bind.check create mode 100644 test/files/neg/macro-keyword-bind.flags create mode 100644 test/files/neg/macro-keyword-bind.scala create mode 100644 test/files/neg/macro-keyword-class1.check create mode 100644 test/files/neg/macro-keyword-class1.flags create mode 100644 test/files/neg/macro-keyword-class1.scala create mode 100644 test/files/neg/macro-keyword-class2.check create mode 100644 test/files/neg/macro-keyword-class2.flags create mode 100644 test/files/neg/macro-keyword-class2.scala create mode 100644 test/files/neg/macro-keyword-object1.check create mode 100644 test/files/neg/macro-keyword-object1.flags create mode 100644 test/files/neg/macro-keyword-object1.scala create mode 100644 test/files/neg/macro-keyword-object2.check create mode 100644 test/files/neg/macro-keyword-object2.flags create mode 100644 test/files/neg/macro-keyword-object2.scala create mode 100644 test/files/neg/macro-keyword-package1.check create mode 100644 test/files/neg/macro-keyword-package1.flags create mode 100644 test/files/neg/macro-keyword-package1.scala create mode 100644 test/files/neg/macro-keyword-package2.check create mode 100644 test/files/neg/macro-keyword-package2.flags create mode 100644 test/files/neg/macro-keyword-package2.scala create mode 100644 test/files/neg/macro-keyword-trait1.check create mode 100644 test/files/neg/macro-keyword-trait1.flags create mode 100644 test/files/neg/macro-keyword-trait1.scala create mode 100644 test/files/neg/macro-keyword-trait2.check create mode 100644 test/files/neg/macro-keyword-trait2.flags create mode 100644 test/files/neg/macro-keyword-trait2.scala create mode 100644 test/files/neg/macro-keyword-type.check create mode 100644 test/files/neg/macro-keyword-type.flags create mode 100644 test/files/neg/macro-keyword-type.scala create mode 100644 test/files/neg/macro-keyword-val.check create mode 100644 test/files/neg/macro-keyword-val.flags create mode 100644 test/files/neg/macro-keyword-val.scala create mode 100644 test/files/neg/macro-keyword-var.check create mode 100644 test/files/neg/macro-keyword-var.flags create mode 100644 test/files/neg/macro-keyword-var.scala delete mode 100644 test/files/neg/macro-keyword.check delete mode 100644 test/files/neg/macro-keyword.flags delete mode 100644 test/files/neg/macro-keyword/Macros_Bind_12.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Class_4.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Class_5.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Def_13.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Object_6.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Object_7.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Package_10.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Package_11.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Trait_8.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Trait_9.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Type_3.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Val_1.scala delete mode 100644 test/files/neg/macro-keyword/Macros_Var_2.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 76ea68442f..2b7c8e8304 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2745,7 +2745,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val lencmp = compareLengths(args, formals) def checkNotMacro() = { - if (fun.symbol != null && fun.symbol.filter(sym => sym != null && sym.isTermMacro) != NoSymbol) + if (fun.symbol != null && fun.symbol.filter(sym => sym != null && sym.isTermMacro && !sym.isErroneous) != NoSymbol) duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun)) } @@ -4574,7 +4574,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // A: solely for robustness reasons. this mechanism might change in the future, which might break unprotected code val expr1 = context.withMacrosDisabled(typed1(expr, mode, pt)) expr1 match { - case macroDef if macroDef.symbol.isTermMacro => + case macroDef if macroDef.symbol != null && macroDef.symbol.isTermMacro && !macroDef.symbol.isErroneous => MacroEtaError(expr1) case _ => typedEta(checkDead(expr1)) diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check index c97be5d9f6..25df9a6a4a 100644 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check @@ -1,14 +1,10 @@ -Macros_Package_10.scala:1: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. -package `macro` +macro-deprecate-dont-touch-backquotedidents.scala:37: error: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro` { ^ -Macros_Package_10.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. -package `macro`.bar - ^ -Macros_Package_11.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. -package `macro`.foo - ^ -Main.scala:2: error: Unmatched closing brace '}' ignored here -} -^ -three warnings found -one error found +macro-deprecate-dont-touch-backquotedidents.scala:38: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + package `macro`.bar { + ^ +macro-deprecate-dont-touch-backquotedidents.scala:43: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + package `macro`.foo { + ^ +three errors found diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.flags b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.scala new file mode 100644 index 0000000000..dee2f1de3b --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.scala @@ -0,0 +1,56 @@ +object Test1 { + val `macro` = ??? +} + +object Test2 { + var `macro` = ??? +} + +object Test3 { + type `macro` = Int +} + +package test4 { + class `macro` +} + +object Test5 { + class `macro` +} + +package test6 { + object `macro` +} + +object Test7 { + object `macro` +} + +package test8 { + trait `macro` +} + +object Test9 { + trait `macro` +} + +package `macro` { + package `macro`.bar { + } +} + +package foo { + package `macro`.foo { + } +} + +object Test12 { + val Some(`macro`) = Some(42) + `macro` match { + case `macro` => println(`macro`) + } +} + +object Test13 { + def `macro` = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala deleted file mode 100644 index 97c07b04a0..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test12 { - val Some(`macro`) = Some(42) - `macro` match { - case `macro` => println(`macro`) - } -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala deleted file mode 100644 index f0037b5f82..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test4 - -class `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala deleted file mode 100644 index a6d0903cbb..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test5 { - class `macro` -} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala deleted file mode 100644 index 6af8e1d65e..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test13 { - def `macro` = 2 -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala deleted file mode 100644 index 29dab017d2..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test6 - -object `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala deleted file mode 100644 index 6cbcac55ca..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test7 { - object `macro` -} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala deleted file mode 100644 index 4985d6691e..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala +++ /dev/null @@ -1,3 +0,0 @@ -package `macro` - -package `macro`.bar \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala deleted file mode 100644 index 35ed610637..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala +++ /dev/null @@ -1,3 +0,0 @@ -package foo - -package `macro`.foo diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala deleted file mode 100644 index 7895cf9a43..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test8 - -trait `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala deleted file mode 100644 index 90ba2207b7..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test9 { - trait `macro` -} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala deleted file mode 100644 index 7a2196c9cd..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test3 { - type `macro` = Int -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala deleted file mode 100644 index 9ad08b8ba0..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test1 { - val `macro` = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala deleted file mode 100644 index 4fbe152e76..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test2 { - var `macro` = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala deleted file mode 100644 index f5278d9e7e..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala +++ /dev/null @@ -1,2 +0,0 @@ -object Test extends App -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents.check b/test/files/neg/macro-deprecate-idents.check index 5fa1dc84d0..bd685fc7b9 100644 --- a/test/files/neg/macro-deprecate-idents.check +++ b/test/files/neg/macro-deprecate-idents.check @@ -1,50 +1,46 @@ -Macros_Bind_12.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. - val Some(macro) = Some(42) - ^ -Macros_Bind_12.scala:4: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. - case macro => println(macro) - ^ -Macros_Class_4.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. -class macro +macro-deprecate-idents.scala:2: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + val macro = ??? ^ -Macros_Class_5.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. - class macro - ^ -Macros_Def_13.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. - def macro = 2 +macro-deprecate-idents.scala:6: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + var macro = ??? ^ -Macros_Object_6.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. -object macro +macro-deprecate-idents.scala:10: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + type macro = Int ^ -Macros_Object_7.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. - object macro - ^ -Macros_Package_10.scala:1: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. -package macro +macro-deprecate-idents.scala:14: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + class macro ^ -Macros_Package_10.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. -package macro.bar +macro-deprecate-idents.scala:18: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + class macro ^ -Macros_Package_11.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. -package macro.foo +macro-deprecate-idents.scala:22: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + object macro + ^ +macro-deprecate-idents.scala:26: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + object macro + ^ +macro-deprecate-idents.scala:30: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + trait macro ^ -Macros_Trait_8.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. -trait macro - ^ -Macros_Trait_9.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +macro-deprecate-idents.scala:34: error: in future versions of Scala "macro" will be a keyword. consider using a different name. trait macro ^ -Macros_Type_3.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. - type macro = Int - ^ -Macros_Val_1.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. - val macro = ??? - ^ -Macros_Var_2.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. - var macro = ??? +macro-deprecate-idents.scala:37: error: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro { + ^ +macro-deprecate-idents.scala:38: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + package macro.bar { + ^ +macro-deprecate-idents.scala:43: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + package macro.foo { + ^ +macro-deprecate-idents.scala:48: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + val Some(macro) = Some(42) + ^ +macro-deprecate-idents.scala:50: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + case macro => println(macro) + ^ +macro-deprecate-idents.scala:55: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + def macro = 2 ^ -Main.scala:2: error: Unmatched closing brace '}' ignored here -} -^ -15 warnings found -one error found +15 errors found diff --git a/test/files/neg/macro-deprecate-idents.flags b/test/files/neg/macro-deprecate-idents.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/neg/macro-deprecate-idents.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents.scala b/test/files/neg/macro-deprecate-idents.scala new file mode 100644 index 0000000000..23c398e341 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents.scala @@ -0,0 +1,56 @@ +object Test1 { + val macro = ??? +} + +object Test2 { + var macro = ??? +} + +object Test3 { + type macro = Int +} + +package test4 { + class macro +} + +object Test5 { + class macro +} + +package test6 { + object macro +} + +object Test7 { + object macro +} + +package test8 { + trait macro +} + +object Test9 { + trait macro +} + +package macro { + package macro.bar { + } +} + +package foo { + package macro.foo { + } +} + +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} + +object Test13 { + def macro = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala b/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala deleted file mode 100644 index a3b1553348..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test12 { - val Some(macro) = Some(42) - macro match { - case macro => println(macro) - } -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala b/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala deleted file mode 100644 index 8635d1f4f6..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test4 - -class macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala b/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala deleted file mode 100644 index af24a489d0..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test5 { - class macro -} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala b/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala deleted file mode 100644 index f4e25bfdfc..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test13 { - def macro = 2 -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala b/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala deleted file mode 100644 index 66eb494e6b..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test6 - -object macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala b/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala deleted file mode 100644 index 6f5b9ceacd..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test7 { - object macro -} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala b/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala deleted file mode 100644 index 52d3fbabf6..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala +++ /dev/null @@ -1,3 +0,0 @@ -package macro - -package macro.bar \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala b/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala deleted file mode 100644 index a68ebd935f..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala +++ /dev/null @@ -1,3 +0,0 @@ -package foo - -package macro.foo diff --git a/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala b/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala deleted file mode 100644 index e32d4c1385..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test8 - -trait macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala b/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala deleted file mode 100644 index 243a54abe6..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test9 { - trait macro -} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala b/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala deleted file mode 100644 index 30e523bcaf..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test3 { - type macro = Int -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala b/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala deleted file mode 100644 index 96f57acb30..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test1 { - val macro = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala b/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala deleted file mode 100644 index a79dda6dc2..0000000000 --- a/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test2 { - var macro = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Main.scala b/test/files/neg/macro-deprecate-idents/Main.scala deleted file mode 100644 index f5278d9e7e..0000000000 --- a/test/files/neg/macro-deprecate-idents/Main.scala +++ /dev/null @@ -1,2 +0,0 @@ -object Test extends App -} \ No newline at end of file diff --git a/test/files/neg/macro-keyword-bind.check b/test/files/neg/macro-keyword-bind.check new file mode 100644 index 0000000000..1f74cfe5cd --- /dev/null +++ b/test/files/neg/macro-keyword-bind.check @@ -0,0 +1,7 @@ +macro-keyword-bind.scala:2: error: illegal start of simple pattern + val Some(macro) = Some(42) + ^ +macro-keyword-bind.scala:6: error: ')' expected but '}' found. +} +^ +two errors found diff --git a/test/files/neg/macro-keyword-bind.flags b/test/files/neg/macro-keyword-bind.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-bind.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-bind.scala b/test/files/neg/macro-keyword-bind.scala new file mode 100644 index 0000000000..a3b1553348 --- /dev/null +++ b/test/files/neg/macro-keyword-bind.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword-class1.check b/test/files/neg/macro-keyword-class1.check new file mode 100644 index 0000000000..d8983180ef --- /dev/null +++ b/test/files/neg/macro-keyword-class1.check @@ -0,0 +1,4 @@ +macro-keyword-class1.scala:3: error: identifier expected but 'macro' found. +class macro + ^ +one error found diff --git a/test/files/neg/macro-keyword-class1.flags b/test/files/neg/macro-keyword-class1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-class1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-class1.scala b/test/files/neg/macro-keyword-class1.scala new file mode 100644 index 0000000000..8635d1f4f6 --- /dev/null +++ b/test/files/neg/macro-keyword-class1.scala @@ -0,0 +1,3 @@ +package test4 + +class macro diff --git a/test/files/neg/macro-keyword-class2.check b/test/files/neg/macro-keyword-class2.check new file mode 100644 index 0000000000..0e4d11bcc4 --- /dev/null +++ b/test/files/neg/macro-keyword-class2.check @@ -0,0 +1,4 @@ +macro-keyword-class2.scala:2: error: identifier expected but 'macro' found. + class macro + ^ +one error found diff --git a/test/files/neg/macro-keyword-class2.flags b/test/files/neg/macro-keyword-class2.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-class2.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-class2.scala b/test/files/neg/macro-keyword-class2.scala new file mode 100644 index 0000000000..af24a489d0 --- /dev/null +++ b/test/files/neg/macro-keyword-class2.scala @@ -0,0 +1,3 @@ +object Test5 { + class macro +} diff --git a/test/files/neg/macro-keyword-object1.check b/test/files/neg/macro-keyword-object1.check new file mode 100644 index 0000000000..cfbd06ffd6 --- /dev/null +++ b/test/files/neg/macro-keyword-object1.check @@ -0,0 +1,4 @@ +macro-keyword-object1.scala:3: error: identifier expected but 'macro' found. +object macro + ^ +one error found diff --git a/test/files/neg/macro-keyword-object1.flags b/test/files/neg/macro-keyword-object1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-object1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-object1.scala b/test/files/neg/macro-keyword-object1.scala new file mode 100644 index 0000000000..66eb494e6b --- /dev/null +++ b/test/files/neg/macro-keyword-object1.scala @@ -0,0 +1,3 @@ +package test6 + +object macro diff --git a/test/files/neg/macro-keyword-object2.check b/test/files/neg/macro-keyword-object2.check new file mode 100644 index 0000000000..ede31f13e5 --- /dev/null +++ b/test/files/neg/macro-keyword-object2.check @@ -0,0 +1,4 @@ +macro-keyword-object2.scala:2: error: identifier expected but 'macro' found. + object macro + ^ +one error found diff --git a/test/files/neg/macro-keyword-object2.flags b/test/files/neg/macro-keyword-object2.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-object2.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-object2.scala b/test/files/neg/macro-keyword-object2.scala new file mode 100644 index 0000000000..6f5b9ceacd --- /dev/null +++ b/test/files/neg/macro-keyword-object2.scala @@ -0,0 +1,3 @@ +object Test7 { + object macro +} diff --git a/test/files/neg/macro-keyword-package1.check b/test/files/neg/macro-keyword-package1.check new file mode 100644 index 0000000000..22c1e11ded --- /dev/null +++ b/test/files/neg/macro-keyword-package1.check @@ -0,0 +1,4 @@ +macro-keyword-package1.scala:1: error: identifier expected but 'macro' found. +package macro + ^ +one error found diff --git a/test/files/neg/macro-keyword-package1.flags b/test/files/neg/macro-keyword-package1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-package1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-package1.scala b/test/files/neg/macro-keyword-package1.scala new file mode 100644 index 0000000000..52d3fbabf6 --- /dev/null +++ b/test/files/neg/macro-keyword-package1.scala @@ -0,0 +1,3 @@ +package macro + +package macro.bar \ No newline at end of file diff --git a/test/files/neg/macro-keyword-package2.check b/test/files/neg/macro-keyword-package2.check new file mode 100644 index 0000000000..0cb542a85d --- /dev/null +++ b/test/files/neg/macro-keyword-package2.check @@ -0,0 +1,4 @@ +macro-keyword-package2.scala:3: error: identifier expected but 'macro' found. +package macro.foo + ^ +one error found diff --git a/test/files/neg/macro-keyword-package2.flags b/test/files/neg/macro-keyword-package2.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-package2.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-package2.scala b/test/files/neg/macro-keyword-package2.scala new file mode 100644 index 0000000000..a68ebd935f --- /dev/null +++ b/test/files/neg/macro-keyword-package2.scala @@ -0,0 +1,3 @@ +package foo + +package macro.foo diff --git a/test/files/neg/macro-keyword-trait1.check b/test/files/neg/macro-keyword-trait1.check new file mode 100644 index 0000000000..9586a62e08 --- /dev/null +++ b/test/files/neg/macro-keyword-trait1.check @@ -0,0 +1,4 @@ +macro-keyword-trait1.scala:3: error: identifier expected but 'macro' found. +trait macro + ^ +one error found diff --git a/test/files/neg/macro-keyword-trait1.flags b/test/files/neg/macro-keyword-trait1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-trait1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-trait1.scala b/test/files/neg/macro-keyword-trait1.scala new file mode 100644 index 0000000000..e32d4c1385 --- /dev/null +++ b/test/files/neg/macro-keyword-trait1.scala @@ -0,0 +1,3 @@ +package test8 + +trait macro diff --git a/test/files/neg/macro-keyword-trait2.check b/test/files/neg/macro-keyword-trait2.check new file mode 100644 index 0000000000..40aa764378 --- /dev/null +++ b/test/files/neg/macro-keyword-trait2.check @@ -0,0 +1,4 @@ +macro-keyword-trait2.scala:2: error: identifier expected but 'macro' found. + trait macro + ^ +one error found diff --git a/test/files/neg/macro-keyword-trait2.flags b/test/files/neg/macro-keyword-trait2.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-trait2.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-trait2.scala b/test/files/neg/macro-keyword-trait2.scala new file mode 100644 index 0000000000..243a54abe6 --- /dev/null +++ b/test/files/neg/macro-keyword-trait2.scala @@ -0,0 +1,3 @@ +object Test9 { + trait macro +} diff --git a/test/files/neg/macro-keyword-type.check b/test/files/neg/macro-keyword-type.check new file mode 100644 index 0000000000..4a7481114c --- /dev/null +++ b/test/files/neg/macro-keyword-type.check @@ -0,0 +1,4 @@ +macro-keyword-type.scala:2: error: identifier expected but 'macro' found. + type macro = Int + ^ +one error found diff --git a/test/files/neg/macro-keyword-type.flags b/test/files/neg/macro-keyword-type.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-type.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-type.scala b/test/files/neg/macro-keyword-type.scala new file mode 100644 index 0000000000..30e523bcaf --- /dev/null +++ b/test/files/neg/macro-keyword-type.scala @@ -0,0 +1,3 @@ +object Test3 { + type macro = Int +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword-val.check b/test/files/neg/macro-keyword-val.check new file mode 100644 index 0000000000..0dc4c030a9 --- /dev/null +++ b/test/files/neg/macro-keyword-val.check @@ -0,0 +1,7 @@ +macro-keyword-val.scala:2: error: illegal start of simple pattern + val macro = ??? + ^ +macro-keyword-val.scala:3: error: '=' expected but '}' found. +} +^ +two errors found diff --git a/test/files/neg/macro-keyword-val.flags b/test/files/neg/macro-keyword-val.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-val.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-val.scala b/test/files/neg/macro-keyword-val.scala new file mode 100644 index 0000000000..96f57acb30 --- /dev/null +++ b/test/files/neg/macro-keyword-val.scala @@ -0,0 +1,3 @@ +object Test1 { + val macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword-var.check b/test/files/neg/macro-keyword-var.check new file mode 100644 index 0000000000..96d02e0052 --- /dev/null +++ b/test/files/neg/macro-keyword-var.check @@ -0,0 +1,7 @@ +macro-keyword-var.scala:2: error: illegal start of simple pattern + var macro = ??? + ^ +macro-keyword-var.scala:3: error: '=' expected but '}' found. +} +^ +two errors found diff --git a/test/files/neg/macro-keyword-var.flags b/test/files/neg/macro-keyword-var.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword-var.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-var.scala b/test/files/neg/macro-keyword-var.scala new file mode 100644 index 0000000000..a79dda6dc2 --- /dev/null +++ b/test/files/neg/macro-keyword-var.scala @@ -0,0 +1,3 @@ +object Test2 { + var macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword.check b/test/files/neg/macro-keyword.check deleted file mode 100644 index fd63db951c..0000000000 --- a/test/files/neg/macro-keyword.check +++ /dev/null @@ -1,49 +0,0 @@ -Macros_Bind_12.scala:2: error: illegal start of simple pattern - val Some(macro) = Some(42) - ^ -Macros_Bind_12.scala:6: error: ')' expected but '}' found. -} -^ -Macros_Class_4.scala:3: error: identifier expected but 'macro' found. -class macro - ^ -Macros_Class_5.scala:2: error: identifier expected but 'macro' found. - class macro - ^ -Macros_Def_13.scala:2: error: identifier expected but 'macro' found. - def macro = 2 - ^ -Macros_Object_6.scala:3: error: identifier expected but 'macro' found. -object macro - ^ -Macros_Object_7.scala:2: error: identifier expected but 'macro' found. - object macro - ^ -Macros_Package_10.scala:1: error: identifier expected but 'macro' found. -package macro - ^ -Macros_Package_11.scala:3: error: identifier expected but 'macro' found. -package macro.foo - ^ -Macros_Trait_8.scala:3: error: identifier expected but 'macro' found. -trait macro - ^ -Macros_Trait_9.scala:2: error: identifier expected but 'macro' found. - trait macro - ^ -Macros_Type_3.scala:2: error: identifier expected but 'macro' found. - type macro = Int - ^ -Macros_Val_1.scala:2: error: illegal start of simple pattern - val macro = ??? - ^ -Macros_Val_1.scala:3: error: '=' expected but '}' found. -} -^ -Macros_Var_2.scala:2: error: illegal start of simple pattern - var macro = ??? - ^ -Macros_Var_2.scala:3: error: '=' expected but '}' found. -} -^ -16 errors found diff --git a/test/files/neg/macro-keyword.flags b/test/files/neg/macro-keyword.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Bind_12.scala b/test/files/neg/macro-keyword/Macros_Bind_12.scala deleted file mode 100644 index a3b1553348..0000000000 --- a/test/files/neg/macro-keyword/Macros_Bind_12.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test12 { - val Some(macro) = Some(42) - macro match { - case macro => println(macro) - } -} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Class_4.scala b/test/files/neg/macro-keyword/Macros_Class_4.scala deleted file mode 100644 index 8635d1f4f6..0000000000 --- a/test/files/neg/macro-keyword/Macros_Class_4.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test4 - -class macro diff --git a/test/files/neg/macro-keyword/Macros_Class_5.scala b/test/files/neg/macro-keyword/Macros_Class_5.scala deleted file mode 100644 index af24a489d0..0000000000 --- a/test/files/neg/macro-keyword/Macros_Class_5.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test5 { - class macro -} diff --git a/test/files/neg/macro-keyword/Macros_Def_13.scala b/test/files/neg/macro-keyword/Macros_Def_13.scala deleted file mode 100644 index f4e25bfdfc..0000000000 --- a/test/files/neg/macro-keyword/Macros_Def_13.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test13 { - def macro = 2 -} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Object_6.scala b/test/files/neg/macro-keyword/Macros_Object_6.scala deleted file mode 100644 index 66eb494e6b..0000000000 --- a/test/files/neg/macro-keyword/Macros_Object_6.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test6 - -object macro diff --git a/test/files/neg/macro-keyword/Macros_Object_7.scala b/test/files/neg/macro-keyword/Macros_Object_7.scala deleted file mode 100644 index 6f5b9ceacd..0000000000 --- a/test/files/neg/macro-keyword/Macros_Object_7.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test7 { - object macro -} diff --git a/test/files/neg/macro-keyword/Macros_Package_10.scala b/test/files/neg/macro-keyword/Macros_Package_10.scala deleted file mode 100644 index 52d3fbabf6..0000000000 --- a/test/files/neg/macro-keyword/Macros_Package_10.scala +++ /dev/null @@ -1,3 +0,0 @@ -package macro - -package macro.bar \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Package_11.scala b/test/files/neg/macro-keyword/Macros_Package_11.scala deleted file mode 100644 index a68ebd935f..0000000000 --- a/test/files/neg/macro-keyword/Macros_Package_11.scala +++ /dev/null @@ -1,3 +0,0 @@ -package foo - -package macro.foo diff --git a/test/files/neg/macro-keyword/Macros_Trait_8.scala b/test/files/neg/macro-keyword/Macros_Trait_8.scala deleted file mode 100644 index e32d4c1385..0000000000 --- a/test/files/neg/macro-keyword/Macros_Trait_8.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test8 - -trait macro diff --git a/test/files/neg/macro-keyword/Macros_Trait_9.scala b/test/files/neg/macro-keyword/Macros_Trait_9.scala deleted file mode 100644 index 243a54abe6..0000000000 --- a/test/files/neg/macro-keyword/Macros_Trait_9.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test9 { - trait macro -} diff --git a/test/files/neg/macro-keyword/Macros_Type_3.scala b/test/files/neg/macro-keyword/Macros_Type_3.scala deleted file mode 100644 index 30e523bcaf..0000000000 --- a/test/files/neg/macro-keyword/Macros_Type_3.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test3 { - type macro = Int -} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Val_1.scala b/test/files/neg/macro-keyword/Macros_Val_1.scala deleted file mode 100644 index 96f57acb30..0000000000 --- a/test/files/neg/macro-keyword/Macros_Val_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test1 { - val macro = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Var_2.scala b/test/files/neg/macro-keyword/Macros_Var_2.scala deleted file mode 100644 index a79dda6dc2..0000000000 --- a/test/files/neg/macro-keyword/Macros_Var_2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test2 { - var macro = ??? -} \ No newline at end of file -- cgit v1.2.3 From f1c6714e22e70ecba2aa595bf592b916be82deb4 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 12 Apr 2012 20:35:05 +0100 Subject: Fix for SI-5535. --- .../scala/tools/nsc/interpreter/MemberHandlers.scala | 2 +- test/files/run/t5535.check | 20 ++++++++++++++++++++ test/files/run/t5535.scala | 10 ++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 test/files/run/t5535.check create mode 100644 test/files/run/t5535.scala diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala index 68bfeafbc6..099034fe97 100644 --- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala +++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala @@ -120,7 +120,7 @@ trait MemberHandlers { private def vparamss = member.vparamss private def isMacro = member.mods.hasFlag(scala.reflect.internal.Flags.MACRO) // true if not a macro and 0-arity - override def definesValue = !isMacro && (vparamss.isEmpty || vparamss.head.isEmpty) + override def definesValue = !isMacro && (vparamss.isEmpty || vparamss.head.isEmpty && vparamss.tail.isEmpty) override def resultExtractionCode(req: Request) = if (mods.isPublic) codegenln(name, ": ", req.typeOf(name)) else "" } diff --git a/test/files/run/t5535.check b/test/files/run/t5535.check new file mode 100644 index 0000000000..8da9829b78 --- /dev/null +++ b/test/files/run/t5535.check @@ -0,0 +1,20 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> def h()(i: Int) = 1 + i +h: ()(i: Int)Int + +scala> println(h()(5)) +6 + +scala> val f = h() _ +f: Int => Int = + +scala> println(f(10)) +11 + +scala> + +scala> diff --git a/test/files/run/t5535.scala b/test/files/run/t5535.scala new file mode 100644 index 0000000000..7bc12f3470 --- /dev/null +++ b/test/files/run/t5535.scala @@ -0,0 +1,10 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = """ +def h()(i: Int) = 1 + i +println(h()(5)) +val f = h() _ +println(f(10)) + """ +} -- cgit v1.2.3 From 08505bd4ec1216be7913607b84e54942f9153329 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 12 Apr 2012 20:57:11 +0100 Subject: Workaround for SI-5583. Somehow type args to be applied arrive in the specialized subclass where type args are no longer applicable. Log and discard. --- .../tools/nsc/transform/SpecializeTypes.scala | 22 +++++++++++++++------- test/files/run/t5583.check | 20 ++++++++++++++++++++ test/files/run/t5583.scala | 11 +++++++++++ 3 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 test/files/run/t5583.check create mode 100644 test/files/run/t5583.scala diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 12d2513756..b85ae26cf1 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1327,7 +1327,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } else super.transform(tree) - case TypeApply(Select(qual, name), targs) + case TypeApply(sel @ Select(qual, name), targs) if (!specializedTypeVars(symbol.info).isEmpty && name != nme.CONSTRUCTOR) => debuglog("checking typeapp for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe) val qual1 = transform(qual) @@ -1341,14 +1341,22 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val residualTargs = symbol.info.typeParams zip targs collect { case (tvar, targ) if !env.contains(tvar) || !isPrimitiveValueClass(env(tvar).typeSymbol) => targ } + if (specMember.info.typeParams.isEmpty) { + // See SI-5583. Don't know why it happens now if it didn't before. + if (residualTargs.nonEmpty) + log("!!! Type args to be applied, but symbol says no parameters: " + ((specMember.defString, residualTargs))) - ifDebug(assert(residualTargs.length == specMember.info.typeParams.length, - "residual: %s, tparams: %s, env: %s".format(residualTargs, symbol.info.typeParams, env)) - ) + localTyper.typed(sel) + } + else { + ifDebug(assert(residualTargs.length == specMember.info.typeParams.length, + "residual: %s, tparams: %s, env: %s".format(residualTargs, specMember.info.typeParams, env)) + ) - val tree1 = gen.mkTypeApply(Select(qual1, specMember), residualTargs) - debuglog("rewrote " + tree + " to " + tree1) - localTyper.typedOperator(atPos(tree.pos)(tree1)) // being polymorphic, it must be a method + val tree1 = gen.mkTypeApply(Select(qual1, specMember), residualTargs) + debuglog("rewrote " + tree + " to " + tree1) + localTyper.typedOperator(atPos(tree.pos)(tree1)) // being polymorphic, it must be a method + } case None => super.transform(tree) } diff --git a/test/files/run/t5583.check b/test/files/run/t5583.check new file mode 100644 index 0000000000..39b969fbe7 --- /dev/null +++ b/test/files/run/t5583.check @@ -0,0 +1,20 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> var s = 0 +s: Int = 0 + +scala> for (i <- 1 to 10) {s += i} + +scala> for (i <- 1 to 10) {s += i} + +scala> for (i <- 1 to 10) {s += i} + +scala> println(s) +165 + +scala> + +scala> diff --git a/test/files/run/t5583.scala b/test/files/run/t5583.scala new file mode 100644 index 0000000000..8561a5946f --- /dev/null +++ b/test/files/run/t5583.scala @@ -0,0 +1,11 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = """ +var s = 0 +for (i <- 1 to 10) {s += i} +for (i <- 1 to 10) {s += i} +for (i <- 1 to 10) {s += i} +println(s) + """ +} -- cgit v1.2.3 From 90960a13840a0b64590d70c49234e71668834f87 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 12 Apr 2012 21:37:51 +0100 Subject: Workaround for SI-5657. Changes to error handling have had unfortunate effects on the repl. Disabling things which used to work to suppress new failures. --- src/compiler/scala/reflect/internal/SymbolTable.scala | 7 +++++++ src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala | 5 +++++ src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index ffc8178528..5ed37c04ad 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -52,6 +52,13 @@ abstract class SymbolTable extends api.Universe /** Overridden when we know more about what was happening during a failure. */ def supplementErrorMessage(msg: String): String = msg + + private[scala] def printCaller[T](msg: String)(result: T) = { + Console.err.println(msg + ": " + result) + Console.err.println("Called from:") + (new Throwable).getStackTrace.drop(2).take(15).foreach(Console.err.println) + result + } private[scala] def printResult[T](msg: String)(result: T) = { Console.err.println(msg + ": " + result) diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala index f9c1907696..a86462ad5f 100644 --- a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala +++ b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala @@ -287,7 +287,12 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput } // chasing down results which won't parse + // This used to work fine, now it reports a type error before any + // exception gets to us. See SI-5657. Don't have time to deal with + // it, so disabling everything. def execute(line: String): Option[ExecResult] = { + return None // disabled + val parsed = Parsed(line) def noDotOrSlash = line forall (ch => ch != '.' && ch != '/') diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala b/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala index 8c589eba60..0c26aa8b28 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala @@ -27,6 +27,12 @@ trait ReplConfig { try Console println msg catch { case x: AssertionError => Console.println("Assertion error printing debugging output: " + x) } + private[nsc] def repldbgex(ex: Throwable): Unit = { + if (isReplDebug) { + echo("Caught/suppressing: " + ex) + ex.printStackTrace + } + } private[nsc] def repldbg(msg: => String) = if (isReplDebug) echo(msg) private[nsc] def repltrace(msg: => String) = if (isReplTrace) echo(msg) private[nsc] def replinfo(msg: => String) = if (isReplInfo) echo(msg) -- cgit v1.2.3 From 004a54ca46ddb0fda6e28c02bc4bc20ccf5601b0 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 12 Apr 2012 23:07:21 +0200 Subject: fixes petty macro tests --- test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala | 2 +- test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala index cbd6232073..fa50ac4f73 100644 --- a/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala +++ b/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala @@ -1,4 +1,4 @@ object Test extends App { import Macros._ - foo(42) + foo(42, 100) } \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala index cbd6232073..fa50ac4f73 100644 --- a/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala +++ b/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala @@ -1,4 +1,4 @@ object Test extends App { import Macros._ - foo(42) + foo(42, 100) } \ No newline at end of file -- cgit v1.2.3 From dea848c7f5746c9ee7bbdea06b94253d653d8eae Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 12 Apr 2012 18:35:49 -0400 Subject: Cache consistency checks for starr binary repo. --- tools/binary-repo-lib.sh | 53 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/tools/binary-repo-lib.sh b/tools/binary-repo-lib.sh index 4c5497e803..09d0af1d50 100755 --- a/tools/binary-repo-lib.sh +++ b/tools/binary-repo-lib.sh @@ -88,12 +88,22 @@ pushJarFile() { # rm $jar } +getJarSha() { + local jar=$1 + if [[ ! -f "$jar" ]]; then + echo "" + else + shastring=$(sha1sum "$jar") + echo "${shastring:0:$(expr index "$shastring" " ")-1}" + fi +} + # Tests whether or not the .desired.sha1 hash matches a given file. # Arugment 1 - The jar file to test validity. # Returns: Empty string on failure, "OK" on success. isJarFileValid() { local jar=$1 - if [[ ! -f $jar ]]; then + if [[ ! -f "$jar" ]]; then echo "" else local jar_dir=$(dirname $jar) @@ -131,6 +141,27 @@ pushJarFiles() { fi } + +checkJarSha() { + local jar=$1 + local sha=$2 + local testsha=$(getJarSha "$jar") + if test "$sha" == "$testsha"; then + echo "OK" + fi +} + +makeCacheLocation() { + local uri=$1 + local sha=$2 + local cache_loc="$cache_dir/$uri" + local cdir=$(dirname $cache_loc) + if [[ ! -d "$cdir" ]]; then + mkdir -p "$cdir" + fi + echo "$cache_loc" +} + # Pulls a single binary artifact from a remote repository. # Argument 1 - The uri to the file that should be downloaded. # Argument 2 - SHA of the file... @@ -138,16 +169,19 @@ pushJarFiles() { pullJarFileToCache() { local uri=$1 local sha=$2 - local cache_loc=$cache_dir/$uri - local cdir=$(dirname $cache_loc) - if [[ ! -d $cdir ]]; then - mkdir -p $cdir - fi + local cache_loc="$(makeCacheLocation $uri)" # TODO - Check SHA of local cache is accurate. - if [[ ! -f $cache_loc ]]; then + if test -f "$cache_loc" && test "$(checkJarSha "$cache_loc" "$sha")" != "OK"; then + echo "Found bad cached file: $cache_loc" + rm -f "$cache_loc" + fi + if [[ ! -f "$cache_loc" ]]; then curlDownload $cache_loc ${remote_urlbase}/${uri} + if test "$(checkJarSha "$cache_loc" "$sha")" != "OK"; then + echo "Trouble downloading $uri. Please try pull-binary-libs again when your internet connection is stable." + exit 2 + fi fi - echo "$cache_loc" } # Pulls a single binary artifact from a remote repository. @@ -162,7 +196,8 @@ pullJarFile() { local version=${sha1% ?$jar_name} local remote_uri=${version}/${jar#$basedir/} echo "Resolving [${remote_uri}]" - local cached_file=$(pullJarFileToCache $remote_uri $version) + pullJarFileToCache $remote_uri $version + local cached_file=$(makeCacheLocation $remote_uri) cp $cached_file $jar } -- cgit v1.2.3 From 983f414dd32752ff2dbca5a4637b0978b31d35a7 Mon Sep 17 00:00:00 2001 From: Dominik Gruntz Date: Fri, 13 Apr 2012 00:51:39 +0200 Subject: SI-5510: string interpolation: parser no longer hangs on unclosed string --- .../scala/tools/nsc/ast/parser/Scanners.scala | 10 ++++++++-- test/files/neg/t5510.check | 19 +++++++++++++++++++ test/files/neg/t5510.scala | 7 +++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 test/files/neg/t5510.check create mode 100644 test/files/neg/t5510.scala diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 81d81a4fb7..ce38f034cf 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -231,6 +231,12 @@ trait Scanners extends ScannersCommon { lastOffset -= 1 } if (inStringInterpolation) fetchStringPart() else fetchToken() + if(token == ERROR) { + if (inMultiLineInterpolation) + sepRegions = sepRegions.tail.tail + else if (inStringInterpolation) + sepRegions = sepRegions.tail + } } else { this copyFrom next next.token = EMPTY @@ -328,7 +334,7 @@ trait Scanners extends ScannersCommon { putChar(ch) nextChar() getIdentRest() - if (ch == '"' && token == IDENTIFIER && settings.Xexperimental.value) + if (ch == '"' && token == IDENTIFIER) token = INTERPOLATIONID case '<' => // is XMLSTART? val last = if (charOffset >= 2) buf(charOffset - 2) else ' ' @@ -697,7 +703,7 @@ trait Scanners extends ScannersCommon { do { putChar(ch) nextRawChar() - } while (Character.isUnicodeIdentifierPart(ch)) + } while (ch != SU && Character.isUnicodeIdentifierPart(ch)) next.token = IDENTIFIER next.name = newTermName(cbuf.toString) cbuf.clear() diff --git a/test/files/neg/t5510.check b/test/files/neg/t5510.check new file mode 100644 index 0000000000..f74e424dc4 --- /dev/null +++ b/test/files/neg/t5510.check @@ -0,0 +1,19 @@ +t5510.scala:2: error: unclosed string literal + val s1 = s"xxx + ^ +t5510.scala:3: error: unclosed string literal + val s2 = s"xxx $x + ^ +t5510.scala:4: error: unclosed string literal + val s3 = s"xxx $$ + ^ +t5510.scala:5: error: unclosed string literal + val s4 = ""s" + ^ +t5510.scala:6: error: unclosed multi-line string literal + val s5 = ""s""" $s1 $s2 s" + ^ +t5510.scala:7: error: Missing closing brace `}' assumed here +} + ^ +6 errors found diff --git a/test/files/neg/t5510.scala b/test/files/neg/t5510.scala new file mode 100644 index 0000000000..12630eb2cd --- /dev/null +++ b/test/files/neg/t5510.scala @@ -0,0 +1,7 @@ +object Test { + val s1 = s"xxx + val s2 = s"xxx $x + val s3 = s"xxx $$ + val s4 = ""s" + val s5 = ""s""" $s1 $s2 s" +} -- cgit v1.2.3 From 87551417850823f5ccde31995a596e004def139d Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 13 Apr 2012 00:36:16 +0100 Subject: Adjustment to recent fix. Try not to break files/specialized/spec-hlists.scala along the way. --- src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index b85ae26cf1..8d08888a1f 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1341,11 +1341,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val residualTargs = symbol.info.typeParams zip targs collect { case (tvar, targ) if !env.contains(tvar) || !isPrimitiveValueClass(env(tvar).typeSymbol) => targ } - if (specMember.info.typeParams.isEmpty) { - // See SI-5583. Don't know why it happens now if it didn't before. - if (residualTargs.nonEmpty) - log("!!! Type args to be applied, but symbol says no parameters: " + ((specMember.defString, residualTargs))) - + // See SI-5583. Don't know why it happens now if it didn't before. + if (specMember.info.typeParams.isEmpty && residualTargs.nonEmpty) { + log("!!! Type args to be applied, but symbol says no parameters: " + ((specMember.defString, residualTargs))) localTyper.typed(sel) } else { -- cgit v1.2.3 From a7a1e3a1959f26c9b44b40b328ef217b4ebdbaba Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 12 Apr 2012 18:56:20 -0700 Subject: Various improvements to SIP 18 diagnostics. Made scala library and compiler feature clean. --- src/compiler/scala/reflect/internal/Names.scala | 1 + src/compiler/scala/reflect/internal/StdNames.scala | 4 ++- .../scala/reflect/internal/SymbolTable.scala | 2 ++ src/compiler/scala/reflect/internal/Symbols.scala | 20 ++++++++--- src/compiler/scala/reflect/internal/Trees.scala | 4 +-- src/compiler/scala/reflect/internal/Types.scala | 15 +++++---- .../scala/reflect/reify/phases/Calculate.scala | 8 ++--- .../scala/tools/nsc/CompilationUnits.scala | 6 ++-- src/compiler/scala/tools/nsc/Global.scala | 28 +++++++++++----- .../scala/tools/nsc/ast/TreeBrowsers.scala | 1 + src/compiler/scala/tools/nsc/ast/TreeDSL.scala | 1 + .../scala/tools/nsc/ast/parser/Parsers.scala | 3 +- .../scala/tools/nsc/ast/parser/Scanners.scala | 23 +++++++------ .../tools/nsc/ast/parser/SymbolicXMLBuilder.scala | 1 + .../scala/tools/nsc/ast/parser/Tokens.scala | 3 +- .../scala/tools/nsc/doc/Uncompilable.scala | 1 + .../tools/nsc/doc/model/IndexModelFactory.scala | 3 +- .../scala/tools/nsc/interactive/BuildManager.scala | 1 + .../scala/tools/nsc/interactive/Global.scala | 1 + .../scala/tools/nsc/interpreter/ILoop.scala | 1 + .../scala/tools/nsc/interpreter/IMain.scala | 6 ++-- .../scala/tools/nsc/interpreter/LoopCommands.scala | 1 + .../tools/nsc/interpreter/MemberHandlers.scala | 1 + .../scala/tools/nsc/interpreter/NamedParam.scala | 3 +- .../scala/tools/nsc/interpreter/Phased.scala | 1 + .../scala/tools/nsc/interpreter/Power.scala | 1 + .../scala/tools/nsc/interpreter/ReplTokens.scala | 1 + .../scala/tools/nsc/interpreter/ReplVals.scala | 2 ++ .../scala/tools/nsc/interpreter/package.scala | 2 ++ .../tools/nsc/interpreter/session/package.scala | 1 + src/compiler/scala/tools/nsc/io/File.scala | 1 + src/compiler/scala/tools/nsc/io/Jar.scala | 1 + src/compiler/scala/tools/nsc/io/Path.scala | 1 + src/compiler/scala/tools/nsc/io/Pickler.scala | 6 ++-- src/compiler/scala/tools/nsc/io/package.scala | 3 +- .../scala/tools/nsc/javac/JavaParsers.scala | 1 + .../scala/tools/nsc/javac/JavaScanners.scala | 1 + .../scala/tools/nsc/matching/MatchSupport.scala | 3 +- src/compiler/scala/tools/nsc/matching/Matrix.scala | 3 +- .../tools/nsc/settings/AestheticSettings.scala | 1 + .../scala/tools/nsc/settings/ScalaSettings.scala | 5 +-- .../tools/nsc/settings/StandardScalaSettings.scala | 1 + .../scala/tools/nsc/symtab/SymbolTrackers.scala | 1 + .../scala/tools/nsc/symtab/clr/TypeParser.scala | 1 + .../scala/tools/nsc/typechecker/Macros.scala | 4 +-- .../tools/nsc/typechecker/MethodSynthesis.scala | 3 +- .../scala/tools/nsc/typechecker/Typers.scala | 39 +++++++++++----------- .../scala/tools/nsc/util/CommandLineParser.scala | 3 +- .../scala/tools/nsc/util/Exceptional.scala | 1 + .../scala/tools/nsc/util/ScalaClassLoader.scala | 2 ++ src/library/scala/Either.scala | 17 ++++++---- src/library/scala/LowPriorityImplicits.scala | 1 + src/library/scala/Option.scala | 3 ++ src/library/scala/Predef.scala | 1 + .../scala/collection/IterableViewLike.scala | 1 + src/library/scala/collection/TraversableOnce.scala | 12 ++++--- .../scala/collection/TraversableViewLike.scala | 1 + .../scala/collection/convert/DecorateAsJava.scala | 2 ++ .../scala/collection/convert/DecorateAsScala.scala | 1 + .../scala/collection/convert/WrapAsJava.scala | 1 + .../scala/collection/convert/WrapAsScala.scala | 1 + .../generic/ClassManifestTraversableFactory.scala | 2 ++ .../scala/collection/generic/GenMapFactory.scala | 1 + .../scala/collection/generic/GenSeqFactory.scala | 1 + .../scala/collection/generic/GenSetFactory.scala | 1 + .../collection/generic/GenTraversableFactory.scala | 2 ++ .../generic/GenericClassManifestCompanion.scala | 1 + .../GenericClassManifestTraversableTemplate.scala | 1 + .../collection/generic/GenericCompanion.scala | 1 + .../generic/GenericOrderedCompanion.scala | 1 + .../GenericOrderedTraversableTemplate.scala | 3 +- .../collection/generic/GenericParCompanion.scala | 1 + .../collection/generic/GenericParTemplate.scala | 1 + .../collection/generic/GenericSeqCompanion.scala | 1 + .../collection/generic/GenericSetTemplate.scala | 2 +- .../generic/GenericTraversableTemplate.scala | 1 + .../collection/generic/ImmutableMapFactory.scala | 2 ++ .../collection/generic/ImmutableSetFactory.scala | 1 + .../generic/ImmutableSortedMapFactory.scala | 2 ++ .../generic/ImmutableSortedSetFactory.scala | 4 ++- .../scala/collection/generic/MapFactory.scala | 1 + .../collection/generic/MutableMapFactory.scala | 1 + .../collection/generic/MutableSetFactory.scala | 1 + .../generic/MutableSortedSetFactory.scala | 1 + .../generic/OrderedTraversableFactory.scala | 4 +-- .../scala/collection/generic/ParFactory.scala | 1 + .../scala/collection/generic/ParMapFactory.scala | 1 + .../scala/collection/generic/ParSetFactory.scala | 1 + .../scala/collection/generic/SeqFactory.scala | 1 + .../scala/collection/generic/SetFactory.scala | 1 + .../collection/generic/SortedMapFactory.scala | 1 + .../collection/generic/SortedSetFactory.scala | 1 + .../collection/generic/TraversableFactory.scala | 1 + .../scala/collection/immutable/Stream.scala | 1 + .../scala/collection/mutable/IndexedSeqView.scala | 1 + .../collection/parallel/ParIterableLike.scala | 1 + .../collection/parallel/ParIterableViewLike.scala | 1 + .../scala/collection/parallel/package.scala | 1 + .../scala/concurrent/ConcurrentPackageObject.scala | 2 +- src/library/scala/concurrent/Future.scala | 1 + .../scala/concurrent/FutureTaskRunner.scala | 2 ++ src/library/scala/concurrent/JavaConversions.scala | 1 + src/library/scala/concurrent/TaskRunner.scala | 2 ++ .../scala/concurrent/ThreadPoolRunner.scala | 1 + src/library/scala/concurrent/ThreadRunner.scala | 1 + src/library/scala/concurrent/util/Duration.scala | 1 + src/library/scala/io/Codec.scala | 1 + src/library/scala/math/BigDecimal.scala | 1 + src/library/scala/math/BigInt.scala | 1 + src/library/scala/math/Fractional.scala | 2 ++ src/library/scala/math/Integral.scala | 2 ++ src/library/scala/math/Numeric.scala | 2 ++ src/library/scala/math/Ordered.scala | 2 ++ src/library/scala/math/Ordering.scala | 1 + src/library/scala/reflect/ClassTags.scala | 3 +- src/library/scala/reflect/TagMaterialization.scala | 3 +- src/library/scala/reflect/api/Exprs.scala | 3 ++ src/library/scala/reflect/api/TypeTags.scala | 3 +- src/library/scala/reflect/api/Universe.scala | 1 + src/library/scala/reflect/makro/Context.scala | 2 ++ .../scala/reflect/makro/internal/typeTagImpl.scala | 2 ++ src/library/scala/sys/BooleanProp.scala | 2 ++ src/library/scala/sys/SystemProperties.scala | 2 ++ src/library/scala/sys/process/Process.scala | 1 + src/library/scala/testing/Show.scala | 8 ++--- src/library/scala/util/Random.scala | 1 + src/library/scala/util/control/Exception.scala | 2 ++ src/library/scala/util/parsing/ast/Binders.scala | 1 + .../parsing/combinator/ImplicitConversions.scala | 2 ++ .../util/parsing/combinator/PackratParsers.scala | 1 + .../scala/util/parsing/combinator/Parsers.scala | 1 + .../util/parsing/combinator/RegexParsers.scala | 1 + .../syntactical/StandardTokenParsers.scala | 1 + .../combinator/syntactical/StdTokenParsers.scala | 1 + src/library/scala/xml/NodeSeq.scala | 1 + src/library/scala/xml/Utility.scala | 3 ++ 136 files changed, 275 insertions(+), 111 deletions(-) diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala index 5f38374f20..d2b55d9d39 100644 --- a/src/compiler/scala/reflect/internal/Names.scala +++ b/src/compiler/scala/reflect/internal/Names.scala @@ -8,6 +8,7 @@ package internal import scala.io.Codec import java.security.MessageDigest +import language.implicitConversions /** The class Names ... * diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 1666887133..3679daa9a2 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -9,12 +9,13 @@ package internal import scala.collection.immutable import NameTransformer.MODULE_SUFFIX_STRING import annotation.switch +import language.implicitConversions trait StdNames extends NameManglers { self: SymbolTable => def encode(str: String): TermName = newTermNameCached(NameTransformer.encode(str)) - implicit def lowerTermNames(n: TermName): String = "" + n + implicit def lowerTermNames(n: TermName): String = n.toString // implicit def stringToTermName(s: String): TermName = newTermName(s) @@ -56,6 +57,7 @@ trait StdNames extends NameManglers { self: SymbolTable => final val RETURNkw: TermName = kw("return") final val SEALEDkw: TermName = kw("sealed") final val SUPERkw: TermName = kw("super") + final val THENkw: TermName = kw("then") final val THISkw: TermName = kw("this") final val THROWkw: TermName = kw("throw") final val TRAITkw: TermName = kw("trait") diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index ffc8178528..9f67c5aa01 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -260,6 +260,8 @@ abstract class SymbolTable extends api.Universe import java.lang.ref.WeakReference import scala.runtime.ScalaRunTime.stringOf + import language.reflectiveCalls + // We can allow ourselves a structural type, these methods // amount to a few calls per run at most. This does suggest // a "Clearable" trait may be useful. diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index fc94e96acd..78d0ebbc67 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -850,6 +850,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isStructuralRefinement: Boolean = (isClass || isType || isModule) && info.normalize/*.underlying*/.isStructuralRefinement + /** Is this a term symbol only defined in a refinement (so that it needs + * to be accessed by reflection)? + */ + def isOnlyRefinementMember: Boolean = + isTerm && // type members are not affected + owner.isRefinementClass && // owner must be a refinement class + (owner.info decl name) == this && // symbol must be explicitly declared in the refinement (not synthesized from glb) + allOverriddenSymbols.isEmpty && // symbol must not override a symbol in a base class + !isConstant // symbol must not be a constant. Question: Can we exclude @inline methods as well? + final def isStructuralRefinementMember = owner.isStructuralRefinement && isPossibleInRefinement && isPublic final def isPossibleInRefinement = !isConstructor && !isOverridingSymbol @@ -1751,7 +1761,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => } else owner.enclosingTopLevelClass /** Is this symbol defined in the same scope and compilation unit as `that` symbol? */ - def isCoDefinedWith(that: Symbol) = ( + def isCoDefinedWith(that: Symbol) = { + import language.reflectiveCalls (this.rawInfo ne NoType) && (this.effectiveOwner == that.effectiveOwner) && { !this.effectiveOwner.isPackageClass || @@ -1770,7 +1781,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => false } } - ) + } /** The internal representation of classes and objects: * @@ -3093,10 +3104,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => if (settings.debug.value) printStackTrace() } - case class InvalidCompanions(sym1: Symbol, sym2: Symbol) extends Throwable( + case class InvalidCompanions(sym1: Symbol, sym2: Symbol) extends Throwable({ + import language.reflectiveCalls "Companions '" + sym1 + "' and '" + sym2 + "' must be defined in same file:\n" + " Found in " + sym1.sourceFile.canonicalPath + " and " + sym2.sourceFile.canonicalPath - ) { + }) { override def toString = getMessage } diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index 0d7e68aee3..0413fd9896 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -103,9 +103,7 @@ trait Trees extends api.Trees { self: SymbolTable => // --- extension methods -------------------------------------------------------- - implicit def treeOps(tree: Tree): TreeOps = new TreeOps(tree) - - class TreeOps(tree: Tree) { + implicit class TreeOps(tree: Tree) { def isErroneous = (tree.tpe ne null) && tree.tpe.isErroneous def isTyped = (tree.tpe ne null) && !tree.tpe.isErroneous diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 797b5db127..c13a33a6fc 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -712,7 +712,9 @@ trait Types extends api.Types { self: SymbolTable => /** Returns all parts of this type which satisfy predicate `p` */ def filter(p: Type => Boolean): List[Type] = new FilterTypeCollector(p) collect this - def withFilter(p: Type => Boolean) = new FilterTypeCollector(p) { + def withFilter(p: Type => Boolean) = new FilterMapForeach(p) + + class FilterMapForeach(p: Type => Boolean) extends FilterTypeCollector(p){ def foreach[U](f: Type => U): Unit = collect(Type.this) foreach f def map[T](f: Type => T): List[T] = collect(Type.this) map f } @@ -2538,12 +2540,11 @@ trait Types extends api.Types { self: SymbolTable => val qset = quantified.toSet underlying match { case TypeRef(_, sym, args) => - sameLength(args, quantified) && { - args forall { arg => - qset(arg.typeSymbol) && - (!checkBounds || !qset.exists(arg.typeSymbol.info.bounds contains _)) - } - } + def isQuantified(tpe: Type) = tpe exists (t => quantified contains t.typeSymbol) + val (wildcardArgs, otherArgs) = args partition (arg => qset contains arg.typeSymbol) + wildcardArgs.distinct == wildcardArgs && + !(otherArgs exists (arg => isQuantified(arg))) && + !(wildcardArgs exists (arg => isQuantified(arg.typeSymbol.info.bounds))) case _ => false } } diff --git a/src/compiler/scala/reflect/reify/phases/Calculate.scala b/src/compiler/scala/reflect/reify/phases/Calculate.scala index 59a36f0ba4..e4f3fce407 100644 --- a/src/compiler/scala/reflect/reify/phases/Calculate.scala +++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala @@ -8,14 +8,12 @@ trait Calculate { import definitions._ import treeInfo._ - implicit def sym2richSym(sym: Symbol): RichSymbol = new RichSymbol(sym) - class RichSymbol(sym: Symbol) { + implicit class RichSymbol(sym: Symbol) { def metalevel: Int = { assert(sym != NoSymbol); localSymbols.getOrElse(sym, 0) } def isLocalToReifee = (localSymbols contains sym) // [Eugene] how do I account for local skolems? } - implicit def tpe2richTpe(tpe: Type): RichType = new RichType(tpe) - class RichType(tpe: Type) { + implicit class RichType(tpe: Type) { def isLocalToReifee = tpe != null && (tpe exists (tp => (localSymbols contains tp.typeSymbol) || (localSymbols contains tp.termSymbol))) } @@ -58,4 +56,4 @@ trait Calculate { super.traverse(tree) } } -} \ No newline at end of file +} diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index 27722a99c9..92a0efff1e 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -88,12 +88,10 @@ trait CompilationUnits { self: Global => reporter.warning(pos, msg) def deprecationWarning(pos: Position, msg: String) = - if (opt.deprecation) warning(pos, msg) - else currentRun.deprecationWarnings ::= ((pos, msg)) + currentRun.deprecationWarnings.warn(pos, msg) def uncheckedWarning(pos: Position, msg: String) = - if (opt.unchecked) warning(pos, msg) - else currentRun.uncheckedWarnings ::= ((pos, msg)) + currentRun.uncheckedWarnings.warn(pos, msg) def incompleteInputError(pos: Position, msg:String) = reporter.incompleteInputError(pos, msg) diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index b7d7f5d16f..228496515b 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -938,6 +938,17 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S inform("[running phase " + ph.name + " on " + currentRun.size + " compilation units]") } + /** Collects for certain classes of warnings during this run. */ + class ConditionalWarning(what: String, option: Settings#BooleanSetting) { + val warnings = new mutable.ListBuffer[(Position, String)] + def warn(pos: Position, msg: String) = + if (option.value) reporter.warning(pos, msg) + else warnings += ((pos, msg)) + def summarize() = + if (option.isDefault && warnings.nonEmpty) + reporter.warning(NoPosition, "there were %d %s warnings; re-run with %s for details".format(warnings.size, what, option.name)) + } + /** A Run is a single execution of the compiler on a sets of units */ class Run { @@ -949,9 +960,12 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S /** The currently compiled unit; set from GlobalPhase */ var currentUnit: CompilationUnit = NoCompilationUnit - /** Counts for certain classes of warnings during this run. */ - var deprecationWarnings: List[(Position, String)] = Nil - var uncheckedWarnings: List[(Position, String)] = Nil + val deprecationWarnings = new ConditionalWarning("deprecation", settings.deprecation) + val uncheckedWarnings = new ConditionalWarning("unchecked", settings.unchecked) + val featureWarnings = new ConditionalWarning("feature", settings.feature) + val allConditionalWarnings = List(deprecationWarnings, uncheckedWarnings, featureWarnings) + + var reportedFeature = Set[Symbol]() /** A flag whether macro expansions failed */ var macroExpansionFailed = false @@ -1241,12 +1255,8 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S } } else { - def warn(count: Int, what: String, option: Settings#BooleanSetting) = ( - if (option.isDefault && count > 0) - warning("there were %d %s warnings; re-run with %s for details".format(count, what, option.name)) - ) - warn(deprecationWarnings.size, "deprecation", settings.deprecation) - warn(uncheckedWarnings.size, "unchecked", settings.unchecked) + allConditionalWarnings foreach (_.summarize) + if (macroExpansionFailed) warning("some macros could not be expanded and code fell back to overridden methods;"+ "\nrecompiling with generated classfiles on the classpath might help.") diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala index 3302c11127..b4beb231ab 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala @@ -18,6 +18,7 @@ import scala.concurrent.Lock import scala.text._ import symtab.Flags._ import symtab.SymbolTable +import language.implicitConversions /** * Tree browsers can show the AST in a graphical and interactive diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala index 2b75925d9a..283bdecf26 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala @@ -9,6 +9,7 @@ package ast import PartialFunction._ import symtab.Flags +import language.implicitConversions /** A DSL for generating scala code. The goal is that the * code generating code should look a lot like the code it diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 978640b4a5..431f0593b9 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2490,7 +2490,8 @@ self => blockExpr() } else { accept(EQUALS) - if (settings.Xmacros.value && in.token == MACRO) { + if (settings.Xmacros.value && in.token == MACRO || // [Martin] Xmacros can be retired now + in.token == IDENTIFIER && in.name == nme.MACROkw) { in.nextToken() newmods |= Flags.MACRO } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 81d81a4fb7..fa63ea33d0 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -119,6 +119,16 @@ trait Scanners extends ScannersCommon { cbuf.clear() } + /** Convert name to token */ + private def name2token(name: Name) = { + val idx = name.start - kwOffset + if (idx >= 0 && idx < kwArray.length) { + val token = kwArray(idx) + if (token == IDENTIFIER) deprecationWarning(name+" is now a reserved word; usage as an identifier is deprecated") + token + } else IDENTIFIER + } + /** Clear buffer and set string */ private def setStrVal() { strVal = cbuf.toString @@ -1124,9 +1134,9 @@ trait Scanners extends ScannersCommon { nme.VIEWBOUNDkw -> VIEWBOUND, nme.SUPERTYPEkw -> SUPERTYPE, nme.HASHkw -> HASH, - nme.ATkw -> AT - ) ++ - (if (settings.Xmacros.value) List(nme.MACROkw -> MACRO) else List()) + nme.ATkw -> AT, + nme.MACROkw -> IDENTIFIER, + nme.THENkw -> IDENTIFIER) private var kwOffset: Int = -1 private val kwArray: Array[Int] = { @@ -1137,13 +1147,6 @@ trait Scanners extends ScannersCommon { final val token2name = allKeywords map (_.swap) toMap - /** Convert name to token */ - final def name2token(name: Name) = { - val idx = name.start - kwOffset - if (idx >= 0 && idx < kwArray.length) kwArray(idx) - else IDENTIFIER - } - // Token representation ---------------------------------------------------- /** Returns the string representation of given token. */ diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala index 849437e4ff..0f2a3e0395 100755 --- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala @@ -11,6 +11,7 @@ import xml.{ EntityRef, Text } import xml.XML.{ xmlns } import symtab.Flags.MUTABLE import scala.tools.util.StringOps.splitWhere +import language.implicitConversions /** This class builds instance of `Tree` that represent XML. * diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala index e17bbf5e46..a4a062609b 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala @@ -110,7 +110,8 @@ object Tokens extends Tokens { final val MATCH = 58 final val FORSOME = 59 final val LAZY = 61 - final val MACRO = 62 + final val MACRO = 62 // not yet used in 2.10 + final val THEN = 63 // not yet used in 2.10 def isKeyword(code: Int) = code >= IF && code <= LAZY diff --git a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala b/src/compiler/scala/tools/nsc/doc/Uncompilable.scala index 9b29ebd745..e9e243171e 100644 --- a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala +++ b/src/compiler/scala/tools/nsc/doc/Uncompilable.scala @@ -5,6 +5,7 @@ package scala.tools.nsc package doc +import language.implicitConversions /** Some glue between DocParser (which reads source files which can't be compiled) * and the scaladoc model. diff --git a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala index ef3c2beffb..6392de22ff 100755 --- a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala @@ -8,6 +8,7 @@ package doc package model import scala.collection._ +import language.reflectiveCalls object IndexModelFactory { @@ -15,7 +16,7 @@ object IndexModelFactory { lazy val firstLetterIndex: Map[Char, SymbolMap] = { - val result = new mutable.HashMap[Char,SymbolMap] { + object result extends mutable.HashMap[Char,SymbolMap] { /* Owner template ordering */ implicit def orderingSet = math.Ordering.String.on { x: MemberEntity => x.name.toLowerCase } diff --git a/src/compiler/scala/tools/nsc/interactive/BuildManager.scala b/src/compiler/scala/tools/nsc/interactive/BuildManager.scala index 2ef34cdd96..0f89236861 100644 --- a/src/compiler/scala/tools/nsc/interactive/BuildManager.scala +++ b/src/compiler/scala/tools/nsc/interactive/BuildManager.scala @@ -13,6 +13,7 @@ import util.FakePos import dependencies._ import io.AbstractFile +import language.implicitConversions trait BuildManager { diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 7233b11701..ec73af4dca 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -19,6 +19,7 @@ import scala.tools.nsc.io.Pickler._ import scala.tools.nsc.typechecker.DivergentImplicit import scala.annotation.tailrec import symtab.Flags.{ACCESSOR, PARAMACCESSOR} +import language.implicitConversions /** The main class of the presentation compiler in an interactive environment such as an IDE */ diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index 108d4377a8..bf386d8a12 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -23,6 +23,7 @@ import scala.reflect.NameTransformer._ import util.ScalaClassLoader import ScalaClassLoader._ import scala.tools.util._ +import language.{implicitConversions, existentials} /** The Scala interactive shell. It provides a read-eval-print loop * around the Interpreter class. diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index c0f7d8412a..43e01bebfd 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -24,6 +24,7 @@ import scala.collection.{ mutable, immutable } import scala.util.control.Exception.{ ultimately } import IMain._ import java.util.concurrent.Future +import language.implicitConversions /** directory to save .class files to */ private class ReplVirtualDirectory(out: JPrintWriter) extends VirtualDirectory("(memory)", None) { @@ -203,8 +204,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends }).toList } - implicit def installReplTypeOps(tp: Type): ReplTypeOps = new ReplTypeOps(tp) - class ReplTypeOps(tp: Type) { + implicit class ReplTypeOps(tp: Type) { def orElse(other: => Type): Type = if (tp ne NoType) tp else other def andAlso(fn: Type => Type): Type = if (tp eq NoType) tp else fn(tp) } @@ -825,7 +825,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends } def lastWarnings: List[(Position, String)] = ( if (lastRun == null) Nil - else removeDupWarnings(lastRun.deprecationWarnings.reverse) ++ lastRun.uncheckedWarnings.reverse + else removeDupWarnings(lastRun.allConditionalWarnings flatMap (_.warnings)) ) private var lastRun: Run = _ private def evalMethod(name: String) = evalClass.getMethods filter (_.getName == name) match { diff --git a/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala b/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala index 9469baa4e2..3520a60ee5 100644 --- a/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala +++ b/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala @@ -8,6 +8,7 @@ package interpreter import collection.{ mutable, immutable } import mutable.ListBuffer +import language.implicitConversions class ProcessResult(val line: String) { import sys.process._ diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala index 68bfeafbc6..d617215452 100644 --- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala +++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala @@ -9,6 +9,7 @@ package interpreter import scala.collection.{ mutable, immutable } import scala.PartialFunction.cond import scala.reflect.internal.Chars +import language.implicitConversions trait MemberHandlers { val intp: IMain diff --git a/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala b/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala index e92888d89b..e2b1bf34d6 100644 --- a/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala +++ b/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala @@ -7,6 +7,7 @@ package scala.tools.nsc package interpreter import NamedParam._ +import language.implicitConversions trait NamedParamCreator { protected def freshName: () => String @@ -43,4 +44,4 @@ trait NamedParam { def tpe: String def value: Any override def toString = name + ": " + tpe -} \ No newline at end of file +} diff --git a/src/compiler/scala/tools/nsc/interpreter/Phased.scala b/src/compiler/scala/tools/nsc/interpreter/Phased.scala index d164d1cbb0..f39c025a86 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Phased.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Phased.scala @@ -7,6 +7,7 @@ package scala.tools.nsc package interpreter import scala.collection.{ mutable, immutable } +import language.implicitConversions /** Mix this into an object and use it as a phasing * swiss army knife. diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index cc06100f5f..ecf9dd219b 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Power.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala @@ -13,6 +13,7 @@ import session.{ History } import scala.io.Codec import java.net.{ URL, MalformedURLException } import io.{ Path } +import language.implicitConversions /** Collecting some power mode examples. diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplTokens.scala b/src/compiler/scala/tools/nsc/interpreter/ReplTokens.scala index 1c7b256c33..e63fabf151 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplTokens.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplTokens.scala @@ -9,6 +9,7 @@ package interpreter import util.{ BatchSourceFile, Indenter } import scala.tools.nsc.ast.parser.Tokens._ import java.lang.Integer.toOctalString +import language.{implicitConversions, existentials} /** This began as an attempt at a completely minimal * pretty printer for a token stream, but as it turns out diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala index e293c0fed9..8b891e0010 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala @@ -6,6 +6,8 @@ package scala.tools.nsc package interpreter +import language.implicitConversions + /** A class which the repl utilizes to expose predefined objects. * The base implementation is empty; the standard repl implementation * is StdReplVals. diff --git a/src/compiler/scala/tools/nsc/interpreter/package.scala b/src/compiler/scala/tools/nsc/interpreter/package.scala index e78e92c8f8..e35b4e3103 100644 --- a/src/compiler/scala/tools/nsc/interpreter/package.scala +++ b/src/compiler/scala/tools/nsc/interpreter/package.scala @@ -5,6 +5,8 @@ package scala.tools.nsc +import language.implicitConversions + /** The main REPL related classes and values are as follows. * In addition to standard compiler classes Global and Settings, there are: * diff --git a/src/compiler/scala/tools/nsc/interpreter/session/package.scala b/src/compiler/scala/tools/nsc/interpreter/session/package.scala index 8fbba2f05e..4e5b08c8cb 100644 --- a/src/compiler/scala/tools/nsc/interpreter/session/package.scala +++ b/src/compiler/scala/tools/nsc/interpreter/session/package.scala @@ -5,6 +5,7 @@ package scala.tools.nsc package interpreter +import language.implicitConversions /** Files having to do with the state of a repl session: * lines of text entered, types and terms defined, etc. diff --git a/src/compiler/scala/tools/nsc/io/File.scala b/src/compiler/scala/tools/nsc/io/File.scala index cc512493d9..06cb20e4ac 100644 --- a/src/compiler/scala/tools/nsc/io/File.scala +++ b/src/compiler/scala/tools/nsc/io/File.scala @@ -15,6 +15,7 @@ import java.io.{ BufferedInputStream, BufferedOutputStream, IOException, PrintStream, PrintWriter, Closeable => JCloseable } import java.nio.channels.{ Channel, FileChannel } import scala.io.Codec +import language.{reflectiveCalls, implicitConversions} object File { def pathSeparator = java.io.File.pathSeparator diff --git a/src/compiler/scala/tools/nsc/io/Jar.scala b/src/compiler/scala/tools/nsc/io/Jar.scala index bbed5a9e20..b322df986c 100644 --- a/src/compiler/scala/tools/nsc/io/Jar.scala +++ b/src/compiler/scala/tools/nsc/io/Jar.scala @@ -11,6 +11,7 @@ import java.util.jar._ import collection.JavaConverters._ import Attributes.Name import util.ClassPath +import language.implicitConversions // Attributes.Name instances: // diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala index a1b8e5e4d5..b8cf15bfcf 100644 --- a/src/compiler/scala/tools/nsc/io/Path.scala +++ b/src/compiler/scala/tools/nsc/io/Path.scala @@ -11,6 +11,7 @@ import java.io.{ BufferedInputStream, BufferedOutputStream, RandomAccessFile } import java.net.{ URI, URL } import scala.util.Random.alphanumeric +import language.implicitConversions /** An abstraction for filesystem paths. The differences between * Path, File, and Directory are primarily to communicate intent. diff --git a/src/compiler/scala/tools/nsc/io/Pickler.scala b/src/compiler/scala/tools/nsc/io/Pickler.scala index 80b6e086da..86c7ca7b9a 100644 --- a/src/compiler/scala/tools/nsc/io/Pickler.scala +++ b/src/compiler/scala/tools/nsc/io/Pickler.scala @@ -3,6 +3,7 @@ package scala.tools.nsc.io import annotation.unchecked import Lexer._ import java.io.Writer +import language.implicitConversions /** An abstract class for writing and reading Scala objects to and * from a legible representation. The presesentation follows the following grammar: @@ -168,14 +169,11 @@ object Pickler { case class ~[+S, +T](fst: S, snd: T) /** A wrapper class to be able to use `~` s an infix method */ - class TildeDecorator[S](x: S) { + implicit class TildeDecorator[S](x: S) { /** Infix method that forms a `~`-pair. */ def ~ [T](y: T): S ~ T = new ~ (x, y) } - /** An implicit wrapper that adds `~` as a method to any value. */ - implicit def tildeDecorator[S](x: S): TildeDecorator[S] = new TildeDecorator(x) - /** A converter from binary functions to functions over `~`-pairs */ implicit def fromTilde[T1, T2, R](f: (T1, T2) => R): T1 ~ T2 => R = { case x1 ~ x2 => f(x1, x2) } diff --git a/src/compiler/scala/tools/nsc/io/package.scala b/src/compiler/scala/tools/nsc/io/package.scala index 88679e6dce..8ea14e7f8b 100644 --- a/src/compiler/scala/tools/nsc/io/package.scala +++ b/src/compiler/scala/tools/nsc/io/package.scala @@ -8,6 +8,7 @@ package scala.tools.nsc import java.util.concurrent.{ Future, Callable } import java.util.{ Timer, TimerTask } import java.util.jar.{ Attributes } +import language.implicitConversions package object io { type JManifest = java.util.jar.Manifest @@ -41,4 +42,4 @@ package object io { alarm.schedule(tt, seconds * 1000) alarm } -} \ No newline at end of file +} diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 06b06c50a6..ca3f3ff635 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -12,6 +12,7 @@ import scala.tools.nsc.util.OffsetPosition import scala.collection.mutable.ListBuffer import symtab.Flags import JavaTokens._ +import language.implicitConversions trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { val global : Global diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala index 45b63b0ca0..d47756e757 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala @@ -10,6 +10,7 @@ import scala.tools.nsc.util._ import scala.reflect.internal.Chars._ import JavaTokens._ import scala.annotation.switch +import language.implicitConversions // Todo merge these better with Scanners trait JavaScanners extends ast.parser.ScannersCommon { diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala index 371f4bc4d8..05bd4966df 100644 --- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala +++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala @@ -29,11 +29,10 @@ trait MatchSupport extends ast.TreeDSL { self: ParallelMatching => object Types { import definitions._ - implicit def enrichType(x: Type): RichType = new RichType(x) val subrangeTypes = Set(ByteClass, ShortClass, CharClass, IntClass) - class RichType(undecodedTpe: Type) { + implicit class RichType(undecodedTpe: Type) { def tpe = decodedEqualsType(undecodedTpe) def isAnyRef = tpe <:< AnyRefClass.tpe diff --git a/src/compiler/scala/tools/nsc/matching/Matrix.scala b/src/compiler/scala/tools/nsc/matching/Matrix.scala index e1ff88557e..b29fac225a 100644 --- a/src/compiler/scala/tools/nsc/matching/Matrix.scala +++ b/src/compiler/scala/tools/nsc/matching/Matrix.scala @@ -9,6 +9,7 @@ package matching import transform.ExplicitOuter import symtab.Flags import scala.collection.mutable +import language.implicitConversions trait Matrix extends MatrixAdditions { self: ExplicitOuter with ParallelMatching => @@ -255,4 +256,4 @@ trait Matrix extends MatrixAdditions { recordSyntheticSym(owner.newVariable(n, pos, flagsLong) setInfo tpe) } } -} \ No newline at end of file +} diff --git a/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala b/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala index c010c6a3ea..2fdc3004d6 100644 --- a/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala @@ -23,6 +23,7 @@ trait AestheticSettings { def deprecation = settings.deprecation.value def experimental = settings.Xexperimental.value def fatalWarnings = settings.fatalWarnings.value + def feature = settings.feature.value def future = settings.future.value def logClasspath = settings.Ylogcp.value def printStats = settings.Ystatistics.value diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index a89aa88585..f7878cae71 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -11,6 +11,7 @@ package settings import annotation.elidable import scala.tools.util.PathResolver.Defaults import scala.collection.mutable +import language.{implicitConversions, existentials} trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings @@ -62,7 +63,7 @@ trait ScalaSettings extends AbsScalaSettings val classpath = PathSetting ("-classpath", "Specify where to find user class files.", defaultClasspath) withAbbreviation "-cp" val d = OutputSetting (outputDirs, ".") val nospecialization = BooleanSetting ("-no-specialization", "Ignore @specialize annotations.") - val feature = MultiStringSetting("-language", "feature", "Enable one or more language features.") + val language = MultiStringSetting("-language", "feature", "Enable one or more language features.") /** * -X "Advanced" settings @@ -204,7 +205,7 @@ trait ScalaSettings extends AbsScalaSettings val Xexperimental = BooleanSetting("-Xexperimental", "Enable experimental extensions.") enabling experimentalSettings // Feature extensions - val Xmacros = BooleanSetting("-Xmacros", "Enable macros.") + val Xmacros = BooleanSetting("-Xmacros", "Enable macros.") // [Martin] Can be retired now. val XmacroSettings = MultiStringSetting("-Xmacro-settings", "option", "Custom settings for macros.") val XmacroPrimaryClasspath = PathSetting("-Xmacro-primary-classpath", "Classpath to load macros implementations from, defaults to compilation classpath (aka \"library classpath\".", "") val XmacroFallbackClasspath = PathSetting("-Xmacro-fallback-classpath", "Classpath to load macros implementations from if they cannot be loaded from library classpath.", "") diff --git a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala index c5b477c7bd..a69b88a5df 100644 --- a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala @@ -32,6 +32,7 @@ trait StandardScalaSettings { val deprecation = BooleanSetting ("-deprecation", "Emit warning and location for usages of deprecated APIs.") val encoding = StringSetting ("-encoding", "encoding", "Specify character encoding used by source files.", Properties.sourceEncoding) val explaintypes = BooleanSetting ("-explaintypes", "Explain type errors in more detail.") + val feature = BooleanSetting ("-feature", "Emit warning and location for usages of features that should be imported explicitly.") val g = ChoiceSetting ("-g", "level", "Set level of generated debugging info.", List("none", "source", "line", "vars", "notailcalls"), "vars") val help = BooleanSetting ("-help", "Print a synopsis of standard options") val make = ChoiceSetting ("-make", "policy", "Recompilation detection policy", List("all", "changed", "immediate", "transitive", "transitivenocp"), "all") diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala index e62070a239..310753871f 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala @@ -7,6 +7,7 @@ package scala.tools.nsc package symtab import scala.collection.{ mutable, immutable } +import language.implicitConversions /** Printing the symbol graph (for those symbols attached to an AST node) * after each phase. diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala index 4b847fa94a..028d6f2484 100644 --- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala @@ -12,6 +12,7 @@ import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute, import scala.collection.{ mutable, immutable } import scala.reflect.internal.pickling.UnPickler import ch.epfl.lamp.compiler.msil.Type.TMVarUsage +import language.implicitConversions /** * @author Nikolay Mihaylov diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 9608108a0d..18636ecb05 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -183,9 +183,9 @@ trait Macros { self: Analyzer => def typedMacroBody(typer: Typer, ddef: DefDef): Tree = { import typer.context if (macroDebug) println("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos)) + typer.checkFeature(ddef.pos, MacrosFeature) - implicit def augmentString(s: String) = new AugmentedString(s) - class AugmentedString(s: String) { + implicit class AugmentedString(s: String) { def abbreviateCoreAliases: String = { // hack! var result = s result = result.replace("c.mirror.TypeTag", "c.TypeTag") diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index e1c12adbcc..9e06cbe0d3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -8,6 +8,7 @@ package typechecker import symtab.Flags._ import scala.collection.{ mutable, immutable } import scala.tools.util.StringOps.{ ojoin } +import language.higherKinds /** Logic related to method synthesis which involves cooperation between * Namer and Typer. @@ -377,7 +378,7 @@ trait MethodSynthesis { } def derivedTree: DefDef = factoryMeth(mods & flagsMask | flagsExtra, name, tree, symbolic = false) - def flagsExtra: Long = METHOD | IMPLICIT + def flagsExtra: Long = METHOD | IMPLICIT | SYNTHETIC def flagsMask: Long = AccessFlags def name: TermName = tree.name.toTermName } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 3a5abb4cea..0233974f6f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -737,24 +737,25 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (!isPastTyper) { val nestedOwners = featureTrait.owner.ownerChain.takeWhile(_ != languageFeatureModule.moduleClass).reverse - val featureName = (nestedOwners map (_ + ".")).mkString + featureTrait.name + val featureName = (nestedOwners map (_.name + ".")).mkString + featureTrait.name unit.toCheck += { () => - if (!(unit.checkedFeatures contains featureTrait)) { - def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, true, false, context) != SearchFailure - def hasOption = settings.feature.value contains featureName - if (!hasImport && !hasOption) { - val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) = - featureTrait getAnnotation LanguageFeatureClass - val req = if (required) "needs to" else "should" - val raw = featureDesc + " " + req + " be enabled by making\n" + - "the implicit value language." + featureName + " visible. This can be achieved by adding the import\n" + - "import language." + featureName + " or by setting the compiler option -language:" + featureName + ".\n" + + def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, true, false, context) != SearchFailure + def hasOption = settings.language.value contains featureName + if (!hasImport && !hasOption) { + val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) = + featureTrait getAnnotation LanguageFeatureClass + val req = if (required) "needs to" else "should" + var raw = featureDesc + " " + req + " be enabled\n" + + "by making the implicit value language." + featureName + " visible." + if (!(currentRun.reportedFeature contains featureTrait)) + raw += "\nThis can be achieved by adding the import clause 'import language." + featureName + "'\n" + + "or by setting the compiler option -language:" + featureName + ".\n" + "See the Scala docs for value scala.language." + featureName + "for a discussion\n" + "why the feature " + req + " be explicitly enabled." - val msg = raw replace ("#", construct) - if (required) unit.error(pos, msg) else unit.warning(pos, msg) - unit.checkedFeatures += featureTrait - } + currentRun.reportedFeature += featureTrait + val msg = raw replace ("#", construct) + if (required) unit.error(pos, msg) + else currentRun.featureWarnings.warn(pos, msg) } } } @@ -1972,9 +1973,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (meth.isStructuralRefinementMember) checkMethodStructuralCompatible(meth) - if (meth.isImplicit) meth.info.paramss match { + if (meth.isImplicit && !meth.isSynthetic) meth.info.paramss match { case List(param) :: _ if !param.isImplicit => - println("check implicit +"+meth+" "+isPastTyper) checkFeature(ddef.pos, ImplicitConversionsFeature, meth.toString) case _ => } @@ -4751,9 +4751,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else typedSelect(qual1, name) - val sym = tree1.symbol - if (sym != null && sym.isTerm && sym.owner.isRefinementClass && !sym.isConstant) - checkFeature(tree1.pos, ReflectiveCallsFeature, sym.toString) + if (tree1.symbol != null && tree1.symbol.isOnlyRefinementMember) + checkFeature(tree1.pos, ReflectiveCallsFeature, tree1.symbol.toString) if (qual1.symbol == RootPackage) treeCopy.Ident(tree1, name) else tree1 diff --git a/src/compiler/scala/tools/nsc/util/CommandLineParser.scala b/src/compiler/scala/tools/nsc/util/CommandLineParser.scala index 00fe49d36a..78bfd5e908 100644 --- a/src/compiler/scala/tools/nsc/util/CommandLineParser.scala +++ b/src/compiler/scala/tools/nsc/util/CommandLineParser.scala @@ -20,11 +20,10 @@ import scala.collection.mutable.ListBuffer */ trait ParserUtil extends Parsers { - class ParserPlus[+T](underlying: Parser[T]) { + protected implicit class ParserPlus[+T](underlying: Parser[T]) { def !~>[U](p: => Parser[U]): Parser[U] = (underlying ~! p) ^^ { case a~b => b } def <~![U](p: => Parser[U]): Parser[T] = (underlying ~! p) ^^ { case a~b => a } } - protected implicit def parser2parserPlus[T](p: Parser[T]): ParserPlus[T] = new ParserPlus(p) } case class CommandLine( diff --git a/src/compiler/scala/tools/nsc/util/Exceptional.scala b/src/compiler/scala/tools/nsc/util/Exceptional.scala index 667b7d15a6..7452aa1b67 100644 --- a/src/compiler/scala/tools/nsc/util/Exceptional.scala +++ b/src/compiler/scala/tools/nsc/util/Exceptional.scala @@ -5,6 +5,7 @@ import java.util.concurrent.ExecutionException import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException } import io.{ Sources, Fileish } import scala.tools.util.StringOps._ +import language.implicitConversions /** A simple throwable wrapper so it looks more like a parade of * glittering frame-shaped beauties than the other thing. diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala index fda713c5c6..700fe0c1a6 100644 --- a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala +++ b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala @@ -14,6 +14,8 @@ import java.net.URL import scala.reflect.ReflectionUtils.unwrapHandler import ScalaClassLoader._ import scala.util.control.Exception.{ catching } +import language.implicitConversions + // import Exceptional.unwrap trait HasClassPath { diff --git a/src/library/scala/Either.scala b/src/library/scala/Either.scala index e454cdf5ec..a5e1dc7fe7 100644 --- a/src/library/scala/Either.scala +++ b/src/library/scala/Either.scala @@ -10,6 +10,8 @@ package scala +import language.implicitConversions + /** Represents a value of one of two possible types (a disjoint union.) * Instances of Either are either an instance of [[scala.Left]] or [[scala.Right]]. * @@ -201,12 +203,6 @@ final case class Right[+A, +B](b: B) extends Either[A, B] { } object Either { - class MergeableEither[A](x: Either[A, A]) { - def merge: A = x match { - case Left(a) => a - case Right(a) => a - } - } /** * Allows use of a ``merge`` method to extract values from Either instances @@ -219,7 +215,14 @@ object Either { * r.merge: Seq[Int] // Vector(1) * }}} */ - implicit def either2mergeable[A](x: Either[A, A]): MergeableEither[A] = new MergeableEither(x) + implicit class MergeableEither[A](x: Either[A, A]) { + def merge: A = x match { + case Left(a) => a + case Right(a) => a + } + } + @deprecated("use MergeableEither instead", "2.10") + def either2mergeable[A](x: Either[A, A]): MergeableEither[A] = new MergeableEither(x) /** * Projects an `Either` into a `Left`. diff --git a/src/library/scala/LowPriorityImplicits.scala b/src/library/scala/LowPriorityImplicits.scala index 447a3c3819..491cd417a3 100644 --- a/src/library/scala/LowPriorityImplicits.scala +++ b/src/library/scala/LowPriorityImplicits.scala @@ -12,6 +12,7 @@ import scala.collection.{ mutable, immutable, generic } import mutable.WrappedArray import immutable.WrappedString import generic.CanBuildFrom +import language.implicitConversions /** The `LowPriorityImplicits` class provides implicit values that * are valid in all Scala compilation units without explicit qualification, diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala index 2d87ccb261..79ceff328e 100644 --- a/src/library/scala/Option.scala +++ b/src/library/scala/Option.scala @@ -9,6 +9,9 @@ package scala object Option { + + import language.implicitConversions + /** An implicit conversion that converts an option to an iterable value */ implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 837ce96baa..0954454e41 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -14,6 +14,7 @@ import mutable.ArrayOps import generic.CanBuildFrom import annotation.{ elidable, implicitNotFound } import annotation.elidable.ASSERTION +import language.{implicitConversions, existentials} /** The `Predef` object provides definitions that are accessible in all Scala * compilation units without explicit qualification. diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala index ce2daf08d4..c842475590 100644 --- a/src/library/scala/collection/IterableViewLike.scala +++ b/src/library/scala/collection/IterableViewLike.scala @@ -11,6 +11,7 @@ package scala.collection import generic._ import TraversableView.NoBuilder import immutable.Stream +import language.implicitConversions /** A template trait for non-strict views of iterable collections. * $iterableViewInfo diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index 62ea692b90..4bd32566e8 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -10,6 +10,7 @@ package scala.collection import mutable.{ Buffer, ListBuffer, ArrayBuffer } import annotation.unchecked.{ uncheckedVariance => uV } +import language.{implicitConversions, higherKinds} /** A template trait for collections which can be traversed either once only * or one or more times. @@ -358,8 +359,11 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { object TraversableOnce { - implicit def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T] - implicit def wrapTraversableOnce[A](trav: TraversableOnce[A]) = new MonadOps(trav) + @deprecated("use OnceCanBuildFrom instead") + def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T] + @deprecated("use MonadOps instead") + def wrapTraversableOnce[A](trav: TraversableOnce[A]) = new MonadOps(trav) + implicit def alternateImplicit[A](trav: TraversableOnce[A]) = new ForceImplicitAmbiguity implicit def flattenTraversableOnce[A, CC[_]](travs: TraversableOnce[CC[A]])(implicit ev: CC[A] => TraversableOnce[A]) = new FlattenOps[A](travs map ev) @@ -368,7 +372,7 @@ object TraversableOnce { * operates on Iterators so they can be treated uniformly along with the collections. * See scala.util.Random.shuffle for an example. */ - class OnceCanBuildFrom[A] extends generic.CanBuildFrom[TraversableOnce[A], A, TraversableOnce[A]] { + implicit class OnceCanBuildFrom[A] extends generic.CanBuildFrom[TraversableOnce[A], A, TraversableOnce[A]] { def newIterator = new ArrayBuffer[A] mapResult (_.iterator) /** Creates a new builder on request of a collection. @@ -394,7 +398,7 @@ object TraversableOnce { class ForceImplicitAmbiguity - class MonadOps[+A](trav: TraversableOnce[A]) { + implicit class MonadOps[+A](trav: TraversableOnce[A]) { def map[B](f: A => B): TraversableOnce[B] = trav.toIterator map f def flatMap[B](f: A => GenTraversableOnce[B]): TraversableOnce[B] = trav.toIterator flatMap f def withFilter(p: A => Boolean) = trav.toIterator filter p diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala index fbecad98fe..ac95aa6e27 100644 --- a/src/library/scala/collection/TraversableViewLike.scala +++ b/src/library/scala/collection/TraversableViewLike.scala @@ -12,6 +12,7 @@ import generic._ import mutable.{ Builder, ArrayBuffer } import TraversableView.NoBuilder import annotation.migration +import language.implicitConversions trait ViewMkString[+A] { self: Traversable[A] => diff --git a/src/library/scala/collection/convert/DecorateAsJava.scala b/src/library/scala/collection/convert/DecorateAsJava.scala index e05bfc41cd..bde13f2830 100644 --- a/src/library/scala/collection/convert/DecorateAsJava.scala +++ b/src/library/scala/collection/convert/DecorateAsJava.scala @@ -12,6 +12,8 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import Decorators._ import WrapAsJava._ +import language.implicitConversions + /** A collection of decorators that allow to convert between * Scala and Java collections using `asScala` and `asJava` methods. diff --git a/src/library/scala/collection/convert/DecorateAsScala.scala b/src/library/scala/collection/convert/DecorateAsScala.scala index 722f0b9af9..b170d8d139 100644 --- a/src/library/scala/collection/convert/DecorateAsScala.scala +++ b/src/library/scala/collection/convert/DecorateAsScala.scala @@ -12,6 +12,7 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import Decorators._ import WrapAsScala._ +import language.implicitConversions trait DecorateAsScala { /** diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala index cdec72b9fe..ecf91deb3a 100644 --- a/src/library/scala/collection/convert/WrapAsJava.scala +++ b/src/library/scala/collection/convert/WrapAsJava.scala @@ -11,6 +11,7 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import Wrappers._ +import language.implicitConversions trait WrapAsJava { /** diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala index 56e13b2105..14c64695ff 100644 --- a/src/library/scala/collection/convert/WrapAsScala.scala +++ b/src/library/scala/collection/convert/WrapAsScala.scala @@ -11,6 +11,7 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import Wrappers._ +import language.implicitConversions trait WrapAsScala { /** diff --git a/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala b/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala index e54ce9cdbf..e418ca623f 100644 --- a/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala +++ b/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala @@ -9,6 +9,8 @@ package scala.collection package generic +import language.higherKinds + /** A template for companion objects of `ClassManifestTraversable` and * subclasses thereof. * diff --git a/src/library/scala/collection/generic/GenMapFactory.scala b/src/library/scala/collection/generic/GenMapFactory.scala index d6f6978ead..b3faf0497b 100644 --- a/src/library/scala/collection/generic/GenMapFactory.scala +++ b/src/library/scala/collection/generic/GenMapFactory.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.{Builder, MapBuilder} +import language.higherKinds /** A template for companion objects of `Map` and subclasses thereof. * diff --git a/src/library/scala/collection/generic/GenSeqFactory.scala b/src/library/scala/collection/generic/GenSeqFactory.scala index ee6ecae3c2..3bd63c08b8 100644 --- a/src/library/scala/collection/generic/GenSeqFactory.scala +++ b/src/library/scala/collection/generic/GenSeqFactory.scala @@ -12,6 +12,7 @@ package scala.collection package generic import annotation.bridge +import language.higherKinds /** A template for companion objects of Seq and subclasses thereof. * diff --git a/src/library/scala/collection/generic/GenSetFactory.scala b/src/library/scala/collection/generic/GenSetFactory.scala index d83f248aff..caae8afa1c 100644 --- a/src/library/scala/collection/generic/GenSetFactory.scala +++ b/src/library/scala/collection/generic/GenSetFactory.scala @@ -12,6 +12,7 @@ package scala.collection package generic import mutable.Builder +import language.higherKinds /** A template for companion objects of `Set` and subclasses thereof. * diff --git a/src/library/scala/collection/generic/GenTraversableFactory.scala b/src/library/scala/collection/generic/GenTraversableFactory.scala index 34cbe1a7f2..f86fa3628a 100644 --- a/src/library/scala/collection/generic/GenTraversableFactory.scala +++ b/src/library/scala/collection/generic/GenTraversableFactory.scala @@ -10,6 +10,8 @@ package scala.collection package generic +import language.higherKinds + /** A template for companion objects of `Traversable` and subclasses thereof. * This class provides a set of operations to create `$Coll` objects. * It is typically inherited by companion objects of subclasses of `Traversable`. diff --git a/src/library/scala/collection/generic/GenericClassManifestCompanion.scala b/src/library/scala/collection/generic/GenericClassManifestCompanion.scala index 546e82fb4a..f357091361 100644 --- a/src/library/scala/collection/generic/GenericClassManifestCompanion.scala +++ b/src/library/scala/collection/generic/GenericClassManifestCompanion.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.Builder +import language.higherKinds /** This class represents companions of classes which require ClassManifests * for their element types. diff --git a/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala b/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala index 12b5a495f0..1a5db4bab2 100644 --- a/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala @@ -11,6 +11,7 @@ package generic import mutable.Builder import annotation.unchecked.uncheckedVariance +import language.higherKinds /** This trait represents collections classes which require class * manifests for their element types. diff --git a/src/library/scala/collection/generic/GenericCompanion.scala b/src/library/scala/collection/generic/GenericCompanion.scala index b36a1e297f..cf01cf5f08 100644 --- a/src/library/scala/collection/generic/GenericCompanion.scala +++ b/src/library/scala/collection/generic/GenericCompanion.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.Builder +import language.higherKinds /** A template class for companion objects of "regular" collection classes * represent an unconstrained higher-kinded type. Typically diff --git a/src/library/scala/collection/generic/GenericOrderedCompanion.scala b/src/library/scala/collection/generic/GenericOrderedCompanion.scala index c3baa28147..290dc435c8 100644 --- a/src/library/scala/collection/generic/GenericOrderedCompanion.scala +++ b/src/library/scala/collection/generic/GenericOrderedCompanion.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.Builder +import language.higherKinds /** This class represents companions of classes which require the ordered trait * for their element types. diff --git a/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala b/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala index 5cfc4666b3..6e04420315 100644 --- a/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala @@ -13,8 +13,7 @@ package generic import mutable.Builder import annotation.unchecked.uncheckedVariance - - +import language.higherKinds /** This trait represents collections classes which require * ordered element types. diff --git a/src/library/scala/collection/generic/GenericParCompanion.scala b/src/library/scala/collection/generic/GenericParCompanion.scala index 40fcfa31d0..93c166b7ba 100644 --- a/src/library/scala/collection/generic/GenericParCompanion.scala +++ b/src/library/scala/collection/generic/GenericParCompanion.scala @@ -11,6 +11,7 @@ package scala.collection.generic import scala.collection.parallel.Combiner import scala.collection.parallel.ParIterable import scala.collection.parallel.ParMap +import language.higherKinds /** A template class for companion objects of parallel collection classes. * They should be mixed in together with `GenericCompanion` type. diff --git a/src/library/scala/collection/generic/GenericParTemplate.scala b/src/library/scala/collection/generic/GenericParTemplate.scala index 430dcb9e29..fc1c3f5eaa 100644 --- a/src/library/scala/collection/generic/GenericParTemplate.scala +++ b/src/library/scala/collection/generic/GenericParTemplate.scala @@ -14,6 +14,7 @@ import scala.collection.parallel.ParMap import scala.collection.parallel.TaskSupport import annotation.unchecked.uncheckedVariance +import language.higherKinds /** A template trait for collections having a companion. * diff --git a/src/library/scala/collection/generic/GenericSeqCompanion.scala b/src/library/scala/collection/generic/GenericSeqCompanion.scala index 41e8d6dd39..4c0c34733c 100644 --- a/src/library/scala/collection/generic/GenericSeqCompanion.scala +++ b/src/library/scala/collection/generic/GenericSeqCompanion.scala @@ -11,6 +11,7 @@ package scala.collection package generic import annotation.bridge +import language.higherKinds trait GenericSeqCompanion[CC[X] <: Traversable[X]] extends GenericCompanion[CC] { diff --git a/src/library/scala/collection/generic/GenericSetTemplate.scala b/src/library/scala/collection/generic/GenericSetTemplate.scala index 6af6a36981..221bcfb379 100644 --- a/src/library/scala/collection/generic/GenericSetTemplate.scala +++ b/src/library/scala/collection/generic/GenericSetTemplate.scala @@ -8,7 +8,7 @@ package scala.collection package generic - +import language.higherKinds /** * @since 2.8 */ diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala index 6586434924..b26e07393c 100644 --- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala @@ -14,6 +14,7 @@ package generic import mutable.Builder import annotation.migration import annotation.unchecked.uncheckedVariance +import language.higherKinds /** A template class for companion objects of ``regular`` collection classes * that represent an unconstrained higher-kinded type. diff --git a/src/library/scala/collection/generic/ImmutableMapFactory.scala b/src/library/scala/collection/generic/ImmutableMapFactory.scala index bdb657f320..d893188e92 100644 --- a/src/library/scala/collection/generic/ImmutableMapFactory.scala +++ b/src/library/scala/collection/generic/ImmutableMapFactory.scala @@ -10,6 +10,8 @@ package scala.collection package generic +import language.higherKinds + /** A template for companion objects of `immutable.Map` and subclasses thereof. * @author Martin Odersky * @version 2.8 diff --git a/src/library/scala/collection/generic/ImmutableSetFactory.scala b/src/library/scala/collection/generic/ImmutableSetFactory.scala index e128be70a1..7bd5bf2ef8 100644 --- a/src/library/scala/collection/generic/ImmutableSetFactory.scala +++ b/src/library/scala/collection/generic/ImmutableSetFactory.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.{ Builder, SetBuilder } +import language.higherKinds abstract class ImmutableSetFactory[CC[X] <: immutable.Set[X] with SetLike[X, CC[X]]] extends SetFactory[CC] { diff --git a/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala b/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala index 89e19eed87..93aae0e355 100644 --- a/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala +++ b/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala @@ -11,6 +11,8 @@ package scala.collection package generic +import language.higherKinds + /** A template for companion objects of `SortedMap` and subclasses thereof. * * @since 2.8 diff --git a/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala b/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala index fe807d9fe6..67fb72270c 100644 --- a/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala +++ b/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala @@ -11,6 +11,8 @@ package scala.collection package generic +import language.higherKinds + /** A template for companion objects of `SortedSet` and subclasses thereof. * * @since 2.8 @@ -23,4 +25,4 @@ package generic * @define sortedSetCanBuildFromInfo * The standard `CanBuildFrom` instance for sorted sets */ -abstract class ImmutableSortedSetFactory[CC[A] <: immutable.SortedSet[A] with SortedSetLike[A, CC[A]]] extends SortedSetFactory[CC] \ No newline at end of file +abstract class ImmutableSortedSetFactory[CC[A] <: immutable.SortedSet[A] with SortedSetLike[A, CC[A]]] extends SortedSetFactory[CC] diff --git a/src/library/scala/collection/generic/MapFactory.scala b/src/library/scala/collection/generic/MapFactory.scala index a60e3032c1..e502c4067e 100644 --- a/src/library/scala/collection/generic/MapFactory.scala +++ b/src/library/scala/collection/generic/MapFactory.scala @@ -12,6 +12,7 @@ package generic import mutable.{Builder, MapBuilder} import annotation.bridge +import language.higherKinds /** A template for companion objects of `Map` and subclasses thereof. * diff --git a/src/library/scala/collection/generic/MutableMapFactory.scala b/src/library/scala/collection/generic/MutableMapFactory.scala index 076e41c9f8..8b38b4ddd5 100644 --- a/src/library/scala/collection/generic/MutableMapFactory.scala +++ b/src/library/scala/collection/generic/MutableMapFactory.scala @@ -12,6 +12,7 @@ package scala.collection package generic import mutable.Builder +import language.higherKinds /** A template for companion objects of `mutable.Map` and subclasses thereof. * @author Martin Odersky diff --git a/src/library/scala/collection/generic/MutableSetFactory.scala b/src/library/scala/collection/generic/MutableSetFactory.scala index 6130ef2042..f130489814 100644 --- a/src/library/scala/collection/generic/MutableSetFactory.scala +++ b/src/library/scala/collection/generic/MutableSetFactory.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.{ Builder, GrowingBuilder } +import language.higherKinds abstract class MutableSetFactory[CC[X] <: mutable.Set[X] with mutable.SetLike[X, CC[X]]] extends SetFactory[CC] { diff --git a/src/library/scala/collection/generic/MutableSortedSetFactory.scala b/src/library/scala/collection/generic/MutableSortedSetFactory.scala index cbbedc0231..b0dd23ee1a 100644 --- a/src/library/scala/collection/generic/MutableSortedSetFactory.scala +++ b/src/library/scala/collection/generic/MutableSortedSetFactory.scala @@ -10,6 +10,7 @@ package scala.collection package generic import scala.collection.mutable.{ Builder, GrowingBuilder } +import language.higherKinds /** * @define Coll mutable.SortedSet diff --git a/src/library/scala/collection/generic/OrderedTraversableFactory.scala b/src/library/scala/collection/generic/OrderedTraversableFactory.scala index 259e4123c4..92f166ae08 100644 --- a/src/library/scala/collection/generic/OrderedTraversableFactory.scala +++ b/src/library/scala/collection/generic/OrderedTraversableFactory.scala @@ -10,9 +10,7 @@ package scala.collection package generic - - - +import language.higherKinds abstract class OrderedTraversableFactory[CC[X] <: Traversable[X] with GenericOrderedTraversableTemplate[X, CC]] extends GenericOrderedCompanion[CC] { diff --git a/src/library/scala/collection/generic/ParFactory.scala b/src/library/scala/collection/generic/ParFactory.scala index 558024d45c..0829ba6616 100644 --- a/src/library/scala/collection/generic/ParFactory.scala +++ b/src/library/scala/collection/generic/ParFactory.scala @@ -10,6 +10,7 @@ package scala.collection.generic import scala.collection.parallel.ParIterable import scala.collection.parallel.Combiner +import language.higherKinds /** A template class for companion objects of `ParIterable` and subclasses * thereof. This class extends `TraversableFactory` and provides a set of diff --git a/src/library/scala/collection/generic/ParMapFactory.scala b/src/library/scala/collection/generic/ParMapFactory.scala index 2d89f79c13..c05ab73431 100644 --- a/src/library/scala/collection/generic/ParMapFactory.scala +++ b/src/library/scala/collection/generic/ParMapFactory.scala @@ -12,6 +12,7 @@ import scala.collection.parallel.ParMap import scala.collection.parallel.ParMapLike import scala.collection.parallel.Combiner import scala.collection.mutable.Builder +import language.higherKinds /** A template class for companion objects of `ParMap` and subclasses thereof. * This class extends `TraversableFactory` and provides a set of operations diff --git a/src/library/scala/collection/generic/ParSetFactory.scala b/src/library/scala/collection/generic/ParSetFactory.scala index c2cf971d73..30a36a734a 100644 --- a/src/library/scala/collection/generic/ParSetFactory.scala +++ b/src/library/scala/collection/generic/ParSetFactory.scala @@ -12,6 +12,7 @@ import collection.mutable.Builder import collection.parallel.Combiner import collection.parallel.ParSet import collection.parallel.ParSetLike +import language.higherKinds /** * @author Aleksandar Prokopec diff --git a/src/library/scala/collection/generic/SeqFactory.scala b/src/library/scala/collection/generic/SeqFactory.scala index 7bd92173ff..3f61de6ceb 100644 --- a/src/library/scala/collection/generic/SeqFactory.scala +++ b/src/library/scala/collection/generic/SeqFactory.scala @@ -10,6 +10,7 @@ package scala.collection package generic +import language.higherKinds /** A template for companion objects of Seq and subclasses thereof. * diff --git a/src/library/scala/collection/generic/SetFactory.scala b/src/library/scala/collection/generic/SetFactory.scala index 348743a120..fb99f83ebb 100644 --- a/src/library/scala/collection/generic/SetFactory.scala +++ b/src/library/scala/collection/generic/SetFactory.scala @@ -13,6 +13,7 @@ package generic import mutable.Builder import annotation.bridge +import language.higherKinds abstract class SetFactory[CC[X] <: Set[X] with SetLike[X, CC[X]]] extends GenSetFactory[CC] with GenericSeqCompanion[CC] { diff --git a/src/library/scala/collection/generic/SortedMapFactory.scala b/src/library/scala/collection/generic/SortedMapFactory.scala index 962a945037..f038c8b09b 100644 --- a/src/library/scala/collection/generic/SortedMapFactory.scala +++ b/src/library/scala/collection/generic/SortedMapFactory.scala @@ -12,6 +12,7 @@ package scala.collection package generic import mutable.{Builder, MapBuilder} +import language.higherKinds /** A template for companion objects of mutable.Map and subclasses thereof. * diff --git a/src/library/scala/collection/generic/SortedSetFactory.scala b/src/library/scala/collection/generic/SortedSetFactory.scala index 45340cf6c1..bb261803a9 100644 --- a/src/library/scala/collection/generic/SortedSetFactory.scala +++ b/src/library/scala/collection/generic/SortedSetFactory.scala @@ -12,6 +12,7 @@ package scala.collection package generic import mutable.{Builder, SetBuilder} +import language.higherKinds /** A template for companion objects of Set and subclasses thereof. * diff --git a/src/library/scala/collection/generic/TraversableFactory.scala b/src/library/scala/collection/generic/TraversableFactory.scala index e71de1252c..07da1bb5c2 100644 --- a/src/library/scala/collection/generic/TraversableFactory.scala +++ b/src/library/scala/collection/generic/TraversableFactory.scala @@ -11,6 +11,7 @@ package scala.collection package generic import annotation.bridge +import language.higherKinds /** A template for companion objects of `Traversable` and subclasses thereof. * This class provides a set of operations to create `$Coll` objects. diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 2eb2f8eb09..7ffb54680c 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -13,6 +13,7 @@ import generic._ import mutable.{Builder, StringBuilder, LazyBuilder, ListBuffer} import scala.annotation.tailrec import Stream.cons +import language.implicitConversions /** The class `Stream` implements lazy lists where elements * are only evaluated when they are needed. Here is an example: diff --git a/src/library/scala/collection/mutable/IndexedSeqView.scala b/src/library/scala/collection/mutable/IndexedSeqView.scala index 593af92255..a0de2ec8ad 100644 --- a/src/library/scala/collection/mutable/IndexedSeqView.scala +++ b/src/library/scala/collection/mutable/IndexedSeqView.scala @@ -14,6 +14,7 @@ package mutable import generic._ import TraversableView.NoBuilder +import language.implicitConversions /** A non-strict view of a mutable `IndexedSeq`. * $viewInfo diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala index 5551c04ce2..5bf338f560 100644 --- a/src/library/scala/collection/parallel/ParIterableLike.scala +++ b/src/library/scala/collection/parallel/ParIterableLike.scala @@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicBoolean import annotation.unchecked.uncheckedVariance import annotation.unchecked.uncheckedStable +import language.implicitConversions /** A template trait for parallel collections of type `ParIterable[T]`. diff --git a/src/library/scala/collection/parallel/ParIterableViewLike.scala b/src/library/scala/collection/parallel/ParIterableViewLike.scala index 536139c812..91eefc2aa5 100644 --- a/src/library/scala/collection/parallel/ParIterableViewLike.scala +++ b/src/library/scala/collection/parallel/ParIterableViewLike.scala @@ -18,6 +18,7 @@ import scala.collection.GenSeq import scala.collection.generic.{ CanBuildFrom, SliceInterval } import scala.collection.generic.CanCombineFrom import scala.collection.parallel.immutable.ParRange +import language.implicitConversions diff --git a/src/library/scala/collection/parallel/package.scala b/src/library/scala/collection/parallel/package.scala index 943e0208c7..e3124af12e 100644 --- a/src/library/scala/collection/parallel/package.scala +++ b/src/library/scala/collection/parallel/package.scala @@ -13,6 +13,7 @@ import scala.collection.generic.CanCombineFrom import scala.collection.parallel.mutable.ParArray import scala.collection.mutable.UnrolledBuffer import annotation.unchecked.uncheckedVariance +import language.implicitConversions /** Package object for parallel collections. */ diff --git a/src/library/scala/concurrent/ConcurrentPackageObject.scala b/src/library/scala/concurrent/ConcurrentPackageObject.scala index d185ade8a4..c6da343f3a 100644 --- a/src/library/scala/concurrent/ConcurrentPackageObject.scala +++ b/src/library/scala/concurrent/ConcurrentPackageObject.scala @@ -12,7 +12,7 @@ import java.util.concurrent.{ Executors, ExecutorService, ThreadFactory } import scala.concurrent.forkjoin.{ ForkJoinPool, ForkJoinWorkerThread } import scala.concurrent.util.Duration import ConcurrentPackageObject._ - +import language.implicitConversions /** This package object contains primitives for concurrent and parallel programming. diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 5bc9ad783f..01ce902c79 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -24,6 +24,7 @@ import scala.annotation.tailrec import scala.collection.mutable.Stack import scala.collection.mutable.Builder import scala.collection.generic.CanBuildFrom +import language.higherKinds diff --git a/src/library/scala/concurrent/FutureTaskRunner.scala b/src/library/scala/concurrent/FutureTaskRunner.scala index 75e6299ad9..9d6f8a7a88 100644 --- a/src/library/scala/concurrent/FutureTaskRunner.scala +++ b/src/library/scala/concurrent/FutureTaskRunner.scala @@ -8,6 +8,8 @@ package scala.concurrent +import language.{implicitConversions, higherKinds} + /** The `FutureTaskRunner trait is a base trait of task runners * that provide some sort of future abstraction. * diff --git a/src/library/scala/concurrent/JavaConversions.scala b/src/library/scala/concurrent/JavaConversions.scala index 127a0e0055..9b5e741549 100644 --- a/src/library/scala/concurrent/JavaConversions.scala +++ b/src/library/scala/concurrent/JavaConversions.scala @@ -9,6 +9,7 @@ package scala.concurrent import java.util.concurrent.{ExecutorService, Executor} +import language.implicitConversions /** The `JavaConversions` object provides implicit converstions supporting * interoperability between Scala and Java concurrency classes. diff --git a/src/library/scala/concurrent/TaskRunner.scala b/src/library/scala/concurrent/TaskRunner.scala index 500d79e07f..3180e9ce8a 100644 --- a/src/library/scala/concurrent/TaskRunner.scala +++ b/src/library/scala/concurrent/TaskRunner.scala @@ -8,6 +8,8 @@ package scala.concurrent +import language.{higherKinds, implicitConversions} + /** The `TaskRunner` trait... * * @author Philipp Haller diff --git a/src/library/scala/concurrent/ThreadPoolRunner.scala b/src/library/scala/concurrent/ThreadPoolRunner.scala index a3e0253634..fd6882348a 100644 --- a/src/library/scala/concurrent/ThreadPoolRunner.scala +++ b/src/library/scala/concurrent/ThreadPoolRunner.scala @@ -9,6 +9,7 @@ package scala.concurrent import java.util.concurrent.{ExecutorService, Callable, TimeUnit} +import language.implicitConversions /** The `ThreadPoolRunner` trait uses a `java.util.concurrent.ExecutorService` * to run submitted tasks. diff --git a/src/library/scala/concurrent/ThreadRunner.scala b/src/library/scala/concurrent/ThreadRunner.scala index 28fcf57df8..76be94aa6b 100644 --- a/src/library/scala/concurrent/ThreadRunner.scala +++ b/src/library/scala/concurrent/ThreadRunner.scala @@ -9,6 +9,7 @@ package scala.concurrent import java.lang.Thread +import language.implicitConversions /** The `ThreadRunner` trait... * diff --git a/src/library/scala/concurrent/util/Duration.scala b/src/library/scala/concurrent/util/Duration.scala index 33d034da76..3f7c44945b 100644 --- a/src/library/scala/concurrent/util/Duration.scala +++ b/src/library/scala/concurrent/util/Duration.scala @@ -7,6 +7,7 @@ package scala.concurrent.util import java.util.concurrent.TimeUnit import TimeUnit._ import java.lang.{ Double ⇒ JDouble } +import language.implicitConversions object DurationImplicits { trait Classifier[C] { diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala index d9cef0edb1..84cac88dcc 100644 --- a/src/library/scala/io/Codec.scala +++ b/src/library/scala/io/Codec.scala @@ -11,6 +11,7 @@ package scala.io import java.nio.charset.{ Charset, CharsetDecoder, CharsetEncoder, CharacterCodingException, CodingErrorAction => Action } import annotation.migration +import language.implicitConversions // Some notes about encodings for use in refining this implementation. // diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala index cb42b76b51..09f08b82cc 100644 --- a/src/library/scala/math/BigDecimal.scala +++ b/src/library/scala/math/BigDecimal.scala @@ -12,6 +12,7 @@ package scala.math import java.{ lang => jl } import java.math.{ MathContext, BigDecimal => BigDec } import scala.collection.immutable.NumericRange +import language.implicitConversions /** diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala index dbec30b2fe..ff52ca9bec 100644 --- a/src/library/scala/math/BigInt.scala +++ b/src/library/scala/math/BigInt.scala @@ -9,6 +9,7 @@ package scala.math import java.math.BigInteger +import language.implicitConversions /** * @author Martin Odersky diff --git a/src/library/scala/math/Fractional.scala b/src/library/scala/math/Fractional.scala index de09b184e0..0686569c16 100644 --- a/src/library/scala/math/Fractional.scala +++ b/src/library/scala/math/Fractional.scala @@ -8,6 +8,8 @@ package scala.math +import language.implicitConversions + /** * @since 2.8 */ diff --git a/src/library/scala/math/Integral.scala b/src/library/scala/math/Integral.scala index bb364a79b4..4b4de28228 100644 --- a/src/library/scala/math/Integral.scala +++ b/src/library/scala/math/Integral.scala @@ -10,6 +10,8 @@ package scala.math +import language.implicitConversions + /** * @since 2.8 */ diff --git a/src/library/scala/math/Numeric.scala b/src/library/scala/math/Numeric.scala index ff88e0ff4d..1f4e3c9865 100644 --- a/src/library/scala/math/Numeric.scala +++ b/src/library/scala/math/Numeric.scala @@ -8,6 +8,8 @@ package scala.math +import language.implicitConversions + /** * @since 2.8 */ diff --git a/src/library/scala/math/Ordered.scala b/src/library/scala/math/Ordered.scala index b76030718f..80addea7f3 100644 --- a/src/library/scala/math/Ordered.scala +++ b/src/library/scala/math/Ordered.scala @@ -8,6 +8,8 @@ package scala.math +import language.implicitConversions + /** A trait for data that have a single, natural ordering. See * [[scala.math.Ordering]] before using this trait for * more information about whether to use [[scala.math.Ordering]] instead. diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala index 8fc74a9d5d..ab685815a1 100644 --- a/src/library/scala/math/Ordering.scala +++ b/src/library/scala/math/Ordering.scala @@ -9,6 +9,7 @@ package scala.math import java.util.Comparator +import language.{implicitConversions, higherKinds} /** Ordering is a trait whose instances each represent a strategy for sorting * instances of a type. diff --git a/src/library/scala/reflect/ClassTags.scala b/src/library/scala/reflect/ClassTags.scala index cde6da5539..7138837f0d 100644 --- a/src/library/scala/reflect/ClassTags.scala +++ b/src/library/scala/reflect/ClassTags.scala @@ -2,6 +2,7 @@ package scala.reflect import java.lang.{ Class => jClass } import scala.reflect.{ mirror => rm } +import language.{implicitConversions, existentials} /** A `ClassTag[T]` wraps a Java class, which can be accessed via the `erasure` method. * @@ -164,4 +165,4 @@ class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) { @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.ConcreteTypeTag` to capture and analyze type arguments", "2.10.0") def typeArguments: List[OptManifest[_]] = List() -} \ No newline at end of file +} diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala index 5918b6effc..aede00020f 100644 --- a/src/library/scala/reflect/TagMaterialization.scala +++ b/src/library/scala/reflect/TagMaterialization.scala @@ -2,6 +2,7 @@ package scala.reflect import api.Universe import makro.Context +import language.implicitConversions // todo. unfortunately, current type inferencer doesn't infer type parameters of implicit values // this means that during macro expansion these macros will get Nothing instead of real T @@ -151,4 +152,4 @@ object TagMaterialization { c.abort(c.enclosingPosition, "No %s available for %s".format(tagModule.name, tpe)) } } -} \ No newline at end of file +} diff --git a/src/library/scala/reflect/api/Exprs.scala b/src/library/scala/reflect/api/Exprs.scala index 8c3f12783b..ff89a1cd48 100644 --- a/src/library/scala/reflect/api/Exprs.scala +++ b/src/library/scala/reflect/api/Exprs.scala @@ -5,6 +5,7 @@ package scala.reflect package api +import language.implicitConversions trait Exprs { self: Universe => @@ -38,10 +39,12 @@ trait Exprs { self: Universe => // and turns off typechecking whenever it's involved // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo + // [Martin] I have some doubts whether it's god to have implicit conversions. implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree)(TypeTag.Nothing) implicit def expr2tree(expr: Expr[_]): Tree = expr.tree // [Eugene] good idea? + // [Martin] probably not. implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree } diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index ed47620e13..4ffabe1c36 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -7,6 +7,7 @@ package scala.reflect package api import scala.reflect.{ mirror => rm } +import language.implicitConversions /** * Type tags encapsulate a representation of type T. @@ -191,4 +192,4 @@ trait TypeTags { self: Universe => // def typeTag[T](implicit ttag: TypeTag[T]) = ttag // def concreteTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag // def concreteTypeTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag -} \ No newline at end of file +} diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala index 60abd267cb..d1f546608e 100755 --- a/src/library/scala/reflect/api/Universe.scala +++ b/src/library/scala/reflect/api/Universe.scala @@ -1,5 +1,6 @@ package scala.reflect package api +import language.experimental.macros abstract class Universe extends Symbols with FreeVars diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala index 96a41377b3..5ce801e2e6 100644 --- a/src/library/scala/reflect/makro/Context.scala +++ b/src/library/scala/reflect/makro/Context.scala @@ -1,5 +1,7 @@ package scala.reflect.makro +import language.experimental.macros + // todo. introduce context hierarchy // the most lightweight context should just expose the stuff from the SIP // the full context should include all traits from scala.reflect.makro (and probably reside in scala-compiler.jar) diff --git a/src/library/scala/reflect/makro/internal/typeTagImpl.scala b/src/library/scala/reflect/makro/internal/typeTagImpl.scala index de404ff39f..db658fd637 100644 --- a/src/library/scala/reflect/makro/internal/typeTagImpl.scala +++ b/src/library/scala/reflect/makro/internal/typeTagImpl.scala @@ -1,6 +1,8 @@ package scala.reflect.makro import scala.reflect.api.Universe +import language.implicitConversions +import language.experimental.macros /** This package is required by the compiler and should not be used in client code. */ package object internal { diff --git a/src/library/scala/sys/BooleanProp.scala b/src/library/scala/sys/BooleanProp.scala index e940990785..45fc6f5897 100644 --- a/src/library/scala/sys/BooleanProp.scala +++ b/src/library/scala/sys/BooleanProp.scala @@ -8,6 +8,8 @@ package scala.sys +import language.implicitConversions + /** A few additional conveniences for Boolean properties. */ trait BooleanProp extends Prop[Boolean] { diff --git a/src/library/scala/sys/SystemProperties.scala b/src/library/scala/sys/SystemProperties.scala index 52e0ac230b..4853da3495 100644 --- a/src/library/scala/sys/SystemProperties.scala +++ b/src/library/scala/sys/SystemProperties.scala @@ -11,6 +11,8 @@ package scala.sys import scala.collection.{ mutable, Iterator } import scala.collection.JavaConverters._ import java.security.AccessControlException +import language.implicitConversions + /** A bidirectional map wrapping the java System properties. * Changes to System properties will be immediately visible in the map, diff --git a/src/library/scala/sys/process/Process.scala b/src/library/scala/sys/process/Process.scala index c2a61af936..d56c6f2c9d 100644 --- a/src/library/scala/sys/process/Process.scala +++ b/src/library/scala/sys/process/Process.scala @@ -11,6 +11,7 @@ package process import processInternal._ import ProcessBuilder._ +import language.implicitConversions /** Represents a process that is running or has finished running. * It may be a compound process with several underlying native processes (such as `a #&& b`). diff --git a/src/library/scala/testing/Show.scala b/src/library/scala/testing/Show.scala index 7570bf705c..5ab46b8985 100644 --- a/src/library/scala/testing/Show.scala +++ b/src/library/scala/testing/Show.scala @@ -27,17 +27,17 @@ package scala.testing */ trait Show { - /** The result class of wrapper `symApply`. + /** An implicit definition that adds an apply method to Symbol which forwards to `test`. * Prints out diagnostics of method applications. */ - class SymApply(f: Symbol) { + implicit class SymApply(f: Symbol) { def apply[A](args: A*) { println(test(f, args: _*)) } } - /** An implicit definition that adds an apply method to Symbol which forwards to `test`. */ - implicit def symApply(sym: Symbol) = new SymApply(sym) + @deprecated("use SymApply instead", "2.10") + def symApply(sym: Symbol): SymApply = new SymApply(sym) /** Apply method with name of given symbol `f` to given arguments and return * a result diagnostics. diff --git a/src/library/scala/util/Random.scala b/src/library/scala/util/Random.scala index 62cba1fc5b..b5dc3486ae 100644 --- a/src/library/scala/util/Random.scala +++ b/src/library/scala/util/Random.scala @@ -11,6 +11,7 @@ package scala.util import collection.mutable.ArrayBuffer import collection.generic.CanBuildFrom import scala.collection.immutable.{ List, Stream } +import language.{implicitConversions, higherKinds} /** * @author Stephane Micheloud diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala index 20a179a884..1cae8088f5 100644 --- a/src/library/scala/util/control/Exception.scala +++ b/src/library/scala/util/control/Exception.scala @@ -10,6 +10,8 @@ package scala.util.control import collection.immutable.List import java.lang.reflect.InvocationTargetException +import language.implicitConversions + /** Classes representing the components of exception handling. * Each class is independently composable. Some example usages: diff --git a/src/library/scala/util/parsing/ast/Binders.scala b/src/library/scala/util/parsing/ast/Binders.scala index 0646f57064..09ad5ce2ab 100644 --- a/src/library/scala/util/parsing/ast/Binders.scala +++ b/src/library/scala/util/parsing/ast/Binders.scala @@ -10,6 +10,7 @@ package scala.util.parsing.ast import scala.collection.AbstractIterable import scala.collection.mutable +import language.implicitConversions //DISCLAIMER: this code is highly experimental! diff --git a/src/library/scala/util/parsing/combinator/ImplicitConversions.scala b/src/library/scala/util/parsing/combinator/ImplicitConversions.scala index e993628e88..270ac680a9 100644 --- a/src/library/scala/util/parsing/combinator/ImplicitConversions.scala +++ b/src/library/scala/util/parsing/combinator/ImplicitConversions.scala @@ -9,6 +9,8 @@ package scala.util.parsing.combinator +import language.implicitConversions + /** This object contains implicit conversions that come in handy when using the `^^` combinator. * * Refer to [[scala.util.parsing.combinator.Parsers]] to construct an AST from the concrete syntax. diff --git a/src/library/scala/util/parsing/combinator/PackratParsers.scala b/src/library/scala/util/parsing/combinator/PackratParsers.scala index ea856efc3a..9516df0093 100644 --- a/src/library/scala/util/parsing/combinator/PackratParsers.scala +++ b/src/library/scala/util/parsing/combinator/PackratParsers.scala @@ -11,6 +11,7 @@ package scala.util.parsing.combinator import scala.util.parsing.combinator._ import scala.util.parsing.input.{ Reader, Position } import scala.collection.mutable +import language.implicitConversions /** * `PackratParsers` is a component that extends the parser combinators diff --git a/src/library/scala/util/parsing/combinator/Parsers.scala b/src/library/scala/util/parsing/combinator/Parsers.scala index 9aaf0aeb54..e5458f89af 100644 --- a/src/library/scala/util/parsing/combinator/Parsers.scala +++ b/src/library/scala/util/parsing/combinator/Parsers.scala @@ -12,6 +12,7 @@ import scala.util.parsing.input._ import scala.collection.mutable.ListBuffer import scala.annotation.tailrec import annotation.migration +import language.implicitConversions // TODO: better error handling (labelling like parsec's ) diff --git a/src/library/scala/util/parsing/combinator/RegexParsers.scala b/src/library/scala/util/parsing/combinator/RegexParsers.scala index 86eecd03c4..d685329ef1 100644 --- a/src/library/scala/util/parsing/combinator/RegexParsers.scala +++ b/src/library/scala/util/parsing/combinator/RegexParsers.scala @@ -13,6 +13,7 @@ import java.util.regex.Pattern import scala.util.matching.Regex import scala.util.parsing.input._ import scala.collection.immutable.PagedSeq +import language.implicitConversions /** The ''most important'' differences between `RegexParsers` and * [[scala.util.parsing.combinator.Parsers]] are: diff --git a/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala b/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala index e494a69cf0..215b8b792f 100644 --- a/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala +++ b/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala @@ -13,6 +13,7 @@ package syntactical import token._ import lexical.StdLexical +import language.implicitConversions /** This component provides primitive parsers for the standard tokens defined in `StdTokens`. * diff --git a/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala b/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala index 0901f9bbd0..7aa6178df9 100644 --- a/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala +++ b/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala @@ -14,6 +14,7 @@ package syntactical import token._ import scala.collection.mutable +import language.implicitConversions /** This component provides primitive parsers for the standard tokens defined in `StdTokens`. * diff --git a/src/library/scala/xml/NodeSeq.scala b/src/library/scala/xml/NodeSeq.scala index ff5618645f..7404e25021 100644 --- a/src/library/scala/xml/NodeSeq.scala +++ b/src/library/scala/xml/NodeSeq.scala @@ -11,6 +11,7 @@ package scala.xml import collection.{ mutable, immutable, generic, SeqLike, AbstractSeq } import mutable.{ Builder, ListBuffer } import generic.{ CanBuildFrom } +import language.implicitConversions /** This object ... * diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala index 9f944c0e92..214f4e667b 100755 --- a/src/library/scala/xml/Utility.scala +++ b/src/library/scala/xml/Utility.scala @@ -10,6 +10,7 @@ package scala.xml import scala.collection.mutable import parsing.XhtmlEntities +import language.implicitConversions /** * The `Utility` object provides utility functions for processing instances @@ -20,6 +21,8 @@ import parsing.XhtmlEntities object Utility extends AnyRef with parsing.TokenTests { final val SU = '\u001A' + // [Martin] This looks dubious. We don't convert StringBuilders to + // Strings anywhere else, why do it here? implicit def implicitSbToString(sb: StringBuilder) = sb.toString() // helper for the extremely oft-repeated sequence of creating a -- cgit v1.2.3 From 20cd7cc077491ad4da4aace7376fddc2c05f4186 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 13 Apr 2012 03:23:54 +0100 Subject: Fix for failing test. --- test/files/neg/t5510.check | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/files/neg/t5510.check b/test/files/neg/t5510.check index f74e424dc4..60da3bed40 100644 --- a/test/files/neg/t5510.check +++ b/test/files/neg/t5510.check @@ -13,7 +13,7 @@ t5510.scala:5: error: unclosed string literal t5510.scala:6: error: unclosed multi-line string literal val s5 = ""s""" $s1 $s2 s" ^ -t5510.scala:7: error: Missing closing brace `}' assumed here +t5510.scala:7: error: '}' expected but eof found. } - ^ + ^ 6 errors found -- cgit v1.2.3 From 1c89ab72339fee8767869585f28811d5e2e437b1 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 12 Apr 2012 23:47:59 -0700 Subject: Enabling postfix ops feature warning, and working on libs to avoid them. --- src/compiler/scala/tools/nsc/CompileSocket.scala | 4 ++-- src/compiler/scala/tools/nsc/CompilerCommand.scala | 2 +- src/compiler/scala/tools/nsc/GenericRunnerSettings.scala | 2 +- src/compiler/scala/tools/nsc/Global.scala | 1 + src/compiler/scala/tools/nsc/PhaseAssembly.scala | 1 + src/compiler/scala/tools/nsc/Phases.scala | 1 + src/compiler/scala/tools/nsc/ast/NodePrinters.scala | 1 + src/compiler/scala/tools/nsc/ast/TreeGen.scala | 1 + src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 2 +- src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 2 +- src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala | 1 + src/compiler/scala/tools/nsc/backend/icode/GenICode.scala | 1 + src/compiler/scala/tools/nsc/backend/icode/Members.scala | 2 +- src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala | 2 +- .../tools/nsc/backend/icode/analysis/CopyPropagation.scala | 4 ++-- .../scala/tools/nsc/backend/icode/analysis/Liveness.scala | 2 +- src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala | 1 + src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 1 + src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala | 1 + .../scala/tools/nsc/backend/opt/DeadCodeElimination.scala | 2 +- .../scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala | 2 +- src/compiler/scala/tools/nsc/backend/opt/Inliners.scala | 2 +- src/compiler/scala/tools/nsc/doc/Settings.scala | 1 + src/compiler/scala/tools/nsc/doc/Uncompilable.scala | 1 + src/compiler/scala/tools/nsc/doc/html/page/Template.scala | 1 + src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala | 4 ++-- .../scala/tools/nsc/doc/model/comment/CommentFactory.scala | 1 + src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala | 2 +- src/compiler/scala/tools/nsc/interpreter/package.scala | 2 ++ src/compiler/scala/tools/nsc/io/package.scala | 2 ++ src/compiler/scala/tools/nsc/matching/MatchSupport.scala | 1 + src/compiler/scala/tools/nsc/matching/ParallelMatching.scala | 1 + src/compiler/scala/tools/nsc/matching/PatternBindings.scala | 3 ++- src/compiler/scala/tools/nsc/plugins/Plugin.scala | 2 +- src/compiler/scala/tools/nsc/plugins/Plugins.scala | 4 ++-- src/compiler/scala/tools/nsc/settings/AbsSettings.scala | 2 +- src/compiler/scala/tools/nsc/settings/MutableSettings.scala | 2 +- src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala | 1 + src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala | 2 +- src/compiler/scala/tools/nsc/transform/CleanUp.scala | 1 + src/compiler/scala/tools/nsc/transform/Erasure.scala | 2 +- src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala | 2 +- src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala | 2 +- src/compiler/scala/tools/nsc/transform/Mixin.scala | 4 ++-- src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala | 1 + src/compiler/scala/tools/nsc/transform/UnCurry.scala | 1 + src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 4 ++-- src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 8 ++++---- src/compiler/scala/tools/nsc/typechecker/Infer.scala | 6 +++--- src/compiler/scala/tools/nsc/typechecker/Macros.scala | 4 ++-- src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 2 +- .../scala/tools/nsc/typechecker/PatMatVirtualiser.scala | 5 +++-- src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 3 ++- .../scala/tools/nsc/typechecker/SyntheticMethods.scala | 4 ++-- src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 10 ++++++---- src/compiler/scala/tools/nsc/typechecker/Unapplies.scala | 2 +- src/compiler/scala/tools/nsc/util/ClassPath.scala | 4 ++-- src/compiler/scala/tools/nsc/util/package.scala | 2 ++ src/library/scala/Enumeration.scala | 7 +++---- src/library/scala/collection/DefaultMap.scala | 2 +- src/library/scala/collection/GenSeqLike.scala | 6 +++--- src/library/scala/collection/IterableLike.scala | 2 +- src/library/scala/collection/SeqLike.scala | 4 ++-- src/library/scala/collection/SeqProxyLike.scala | 2 +- src/library/scala/collection/TraversableLike.scala | 4 ++-- src/library/scala/collection/TraversableOnce.scala | 2 +- src/library/scala/collection/TraversableViewLike.scala | 2 +- .../scala/collection/generic/GenTraversableFactory.scala | 2 +- src/library/scala/collection/immutable/ListSet.scala | 4 ++-- src/library/scala/collection/immutable/Stream.scala | 2 +- src/library/scala/collection/immutable/StringLike.scala | 2 +- src/library/scala/collection/immutable/TrieIterator.scala | 2 +- src/library/scala/collection/mutable/ArrayOps.scala | 2 +- src/library/scala/collection/mutable/LinkedHashSet.scala | 2 +- src/library/scala/collection/mutable/StringBuilder.scala | 2 +- src/library/scala/io/BytePickle.scala | 2 +- src/library/scala/io/Source.scala | 2 +- src/library/scala/math/BigDecimal.scala | 2 +- src/library/scala/reflect/api/Trees.scala | 2 +- src/library/scala/runtime/ScalaRunTime.scala | 4 ++-- src/library/scala/util/Random.scala | 2 +- src/library/scala/util/automata/BaseBerrySethi.scala | 2 +- src/library/scala/util/automata/NondetWordAutom.scala | 4 ++-- src/library/scala/util/automata/SubsetConstruction.scala | 2 +- src/library/scala/util/automata/WordBerrySethi.scala | 6 +++--- .../scala/util/parsing/combinator/lexical/Lexical.scala | 2 +- .../scala/util/parsing/combinator/testing/RegexTest.scala | 1 + src/library/scala/xml/Elem.scala | 2 +- src/library/scala/xml/MetaData.scala | 2 +- src/library/scala/xml/NodeSeq.scala | 2 +- src/library/scala/xml/Utility.scala | 2 +- src/library/scala/xml/dtd/ContentModel.scala | 4 ++-- src/library/scala/xml/parsing/ConstructingParser.scala | 4 ++-- 94 files changed, 133 insertions(+), 102 deletions(-) diff --git a/src/compiler/scala/tools/nsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/CompileSocket.scala index a0c39f71fb..a4a8e1fd11 100644 --- a/src/compiler/scala/tools/nsc/CompileSocket.scala +++ b/src/compiler/scala/tools/nsc/CompileSocket.scala @@ -93,7 +93,7 @@ class CompileSocket extends CompileOutputCommon { /** Start a new server. */ private def startNewServer(vmArgs: String) = { - val cmd = serverCommand(vmArgs split " " toSeq) + val cmd = serverCommand((vmArgs split " ").toSeq) info("[Executing command: %s]" format cmd.mkString(" ")) // Hiding inadequate daemonized implementation from public API for now @@ -206,7 +206,7 @@ class CompileSocket extends CompileOutputCommon { Thread sleep 100 ff.length } - if (Iterator continually check take 50 find (_ > 0) isEmpty) { + if ((Iterator continually check take 50 find (_ > 0)).isEmpty) { ff.delete() fatal("Unable to establish connection to server.") } diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala index 54bc218912..4c8a27083a 100644 --- a/src/compiler/scala/tools/nsc/CompilerCommand.scala +++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala @@ -47,7 +47,7 @@ class CompilerCommand(arguments: List[String], val settings: Settings) { /** Creates a help message for a subset of options based on cond */ def createUsageMsg(cond: Setting => Boolean): String = { val baseList = (settings.visibleSettings filter cond).toList sortBy (_.name) - val width = baseList map (_.helpSyntax.length) max + val width = (baseList map (_.helpSyntax.length)).max def format(s: String) = ("%-" + width + "s") format s def helpStr(s: Setting) = { val str = format(s.helpSyntax) + " " + s.helpDescription diff --git a/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala b/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala index b9e9a14adf..f91cb854c6 100644 --- a/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala +++ b/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala @@ -8,7 +8,7 @@ package scala.tools.nsc import scala.tools.util.PathResolver class GenericRunnerSettings(error: String => Unit) extends Settings(error) { - def classpathURLs = new PathResolver(this) asURLs + def classpathURLs = new PathResolver(this).asURLs val howtorun = ChoiceSetting( diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 228496515b..0f9f7df548 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -31,6 +31,7 @@ import backend.{ ScalaPrimitives, Platform, MSILPlatform, JavaPlatform } import backend.jvm.GenJVM import backend.opt.{ Inliners, InlineExceptionHandlers, ClosureElimination, DeadCodeElimination } import backend.icode.analysis._ +import language.postfixOps class Global(var currentSettings: Settings, var reporter: NscReporter) extends SymbolTable with ClassLoaders diff --git a/src/compiler/scala/tools/nsc/PhaseAssembly.scala b/src/compiler/scala/tools/nsc/PhaseAssembly.scala index a627b982b6..a9e029e485 100644 --- a/src/compiler/scala/tools/nsc/PhaseAssembly.scala +++ b/src/compiler/scala/tools/nsc/PhaseAssembly.scala @@ -8,6 +8,7 @@ package scala.tools.nsc import java.io.{ BufferedWriter, FileWriter } import scala.collection.mutable +import language.postfixOps /** * PhaseAssembly diff --git a/src/compiler/scala/tools/nsc/Phases.scala b/src/compiler/scala/tools/nsc/Phases.scala index d18495458c..1fa576afb6 100644 --- a/src/compiler/scala/tools/nsc/Phases.scala +++ b/src/compiler/scala/tools/nsc/Phases.scala @@ -7,6 +7,7 @@ package scala.tools.nsc import symtab.Flags import util.TableDef +import language.postfixOps object Phases { val MaxPhases = 64 diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala index c79ca1206e..108c8fcbfa 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -8,6 +8,7 @@ package ast import compat.Platform.EOL import symtab.Flags._ +import language.postfixOps /** The object `nodePrinter` converts the internal tree * representation to a string. diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index 19d1e0a51a..e566384713 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -9,6 +9,7 @@ package ast import scala.collection.mutable.ListBuffer import symtab.Flags._ import symtab.SymbolTable +import language.postfixOps /** XXX to resolve: TreeGen only assumes global is a SymbolTable, but * TreeDSL at the moment expects a Global. Can we get by with SymbolTable? diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 431f0593b9..ef11427677 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2625,7 +2625,7 @@ self => val contextBoundBuf = new ListBuffer[Tree] val tparams = typeParamClauseOpt(name, contextBoundBuf) classContextBounds = contextBoundBuf.toList - val tstart = in.offset :: classContextBounds.map(_.pos.startOrPoint) min; + val tstart = (in.offset :: classContextBounds.map(_.pos.startOrPoint)).min if (!classContextBounds.isEmpty && mods.isTrait) { syntaxError("traits cannot have type parameters with context bounds `: ...' nor view bounds `<% ...'", false) classContextBounds = List() diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index fa63ea33d0..c75e806b2a 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -1145,7 +1145,7 @@ trait Scanners extends ScannersCommon { arr } - final val token2name = allKeywords map (_.swap) toMap + final val token2name = (allKeywords map (_.swap)).toMap // Token representation ---------------------------------------------------- diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala index 4f3b0bf951..dcbabd6517 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala @@ -11,6 +11,7 @@ import scala.collection.{ mutable, immutable } import mutable.{ ListBuffer, ArrayBuffer } import util.{ Position, NoPosition } import backend.icode.analysis.ProgramPoint +import language.postfixOps trait BasicBlocks { self: ICodes => diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index ec303d76ee..ff58de5f12 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -13,6 +13,7 @@ import scala.collection.mutable.{ ListBuffer, Buffer } import scala.tools.nsc.symtab._ import scala.annotation.switch import PartialFunction._ +import language.postfixOps /** This class ... * diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 36651541b2..71795a02aa 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -44,7 +44,7 @@ trait Members { def blocksList: List[BasicBlock] = blocks.toList def instructions = blocksList flatMap (_.iterator) def blockCount = blocks.size - def instructionCount = blocks map (_.length) sum + def instructionCount = (blocks map (_.length)).sum def touched = _touched def touched_=(b: Boolean): Unit = { diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala index 7ad7cadd92..f61f78ebb2 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala @@ -44,7 +44,7 @@ trait TypeKinds { self: ICodes => } /** Reverse map for toType */ private lazy val reversePrimitiveMap: Map[TypeKind, Symbol] = - primitiveTypeMap map (_.swap) toMap + (primitiveTypeMap map (_.swap)).toMap /** This class represents a type kind. Type kinds * represent the types that the VM know (or the ICode diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala index f5be82a776..4427da92c8 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala @@ -566,8 +566,8 @@ abstract class CopyPropagation { method.blocks map { b => "\nIN(%s):\t Bindings: %s".format(b.label, in(b).bindings) + "\nIN(%s):\t Stack: %s".format(b.label, in(b).stack) - } mkString - ) + } + ).mkString } /* class CopyAnalysis */ } diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala index 49f5b51d51..5f261ba05e 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala @@ -97,6 +97,6 @@ abstract class Liveness { } } override def toString() = - method.blocks map (b => "\nlive-in(%s)=%s\nlive-out(%s)=%s".format(b, in(b), b, out(b))) mkString + (method.blocks map (b => "\nlive-in(%s)=%s\nlive-out(%s)=%s".format(b, in(b), b, out(b)))).mkString } /* Liveness analysis */ } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala index c217869a48..0bc41b51bb 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala @@ -13,6 +13,7 @@ import scala.tools.nsc.util.ScalaClassLoader import scala.tools.util.JavapClass import java.util.jar.{ JarEntry, JarOutputStream, Attributes } import Attributes.Name +import language.postfixOps /** For the last mile: turning generated bytecode in memory into * something you can use. Has implementations for writing to class diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index c04be1721e..f7898f2aa2 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -19,6 +19,7 @@ import JAccessFlags._ import JObjectType.{ JAVA_LANG_STRING, JAVA_LANG_OBJECT } import java.util.jar.{ JarEntry, JarOutputStream } import scala.tools.nsc.io.AbstractFile +import language.postfixOps /** This class ... * diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index 98c1fc2f63..66e7becb12 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -15,6 +15,7 @@ import scala.tools.nsc.symtab._ import ch.epfl.lamp.compiler.msil.{Type => MsilType, _} import ch.epfl.lamp.compiler.msil.emit._ import ch.epfl.lamp.compiler.msil.util.PECustomMod +import language.postfixOps abstract class GenMSIL extends SubComponent { import global._ diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index 95c371fa8b..d4ee9b6b48 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -82,7 +82,7 @@ abstract class DeadCodeElimination extends SubComponent { mark sweep(m) accessedLocals = accessedLocals.distinct - if (m.locals diff accessedLocals nonEmpty) { + if ((m.locals diff accessedLocals).nonEmpty) { log("Removed dead locals: " + (m.locals diff accessedLocals)) m.locals = accessedLocals.reverse } diff --git a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala index ec137203bf..0d47352215 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala @@ -360,7 +360,7 @@ abstract class InlineExceptionHandlers extends SubComponent { val caughtException = toTypeKind(caughtClass.tpe) // copy the exception handler code once again, dropping the LOAD_EXCEPTION val copy = handler.code.newBlock - copy.emitOnly(handler.iterator drop dropCount toSeq: _*) + copy.emitOnly((handler.iterator drop dropCount).toSeq: _*) // extend the handlers of the handler to the copy for (parentHandler <- handler.method.exh ; if parentHandler covers handler) { diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index dfe9081ee5..cf51a5b926 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -854,7 +854,7 @@ abstract class Inliners extends SubComponent { def lookupIMethod(meth: Symbol, receiver: Symbol): Option[IMethod] = { def tryParent(sym: Symbol) = icodes icode sym flatMap (_ lookupMethod meth) - receiver.info.baseClasses.iterator map tryParent find (_.isDefined) flatten + (receiver.info.baseClasses.iterator map tryParent find (_.isDefined)).flatten } } /* class Inliner */ } /* class Inliners */ diff --git a/src/compiler/scala/tools/nsc/doc/Settings.scala b/src/compiler/scala/tools/nsc/doc/Settings.scala index 45a2ad78b4..5d3fc6c044 100644 --- a/src/compiler/scala/tools/nsc/doc/Settings.scala +++ b/src/compiler/scala/tools/nsc/doc/Settings.scala @@ -8,6 +8,7 @@ package doc import java.io.File import java.lang.System +import language.postfixOps /** An extended version of compiler settings, with additional Scaladoc-specific options. * @param error A function that prints a string to the appropriate error stream. */ diff --git a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala b/src/compiler/scala/tools/nsc/doc/Uncompilable.scala index e9e243171e..573952a2e3 100644 --- a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala +++ b/src/compiler/scala/tools/nsc/doc/Uncompilable.scala @@ -6,6 +6,7 @@ package scala.tools.nsc package doc import language.implicitConversions +import language.postfixOps /** Some glue between DocParser (which reads source files which can't be compiled) * and the scaladoc model. diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala index f059b5c0cb..2ebd83fd99 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -10,6 +10,7 @@ package page import model._ import scala.xml.{ NodeSeq, Text, UnprefixedAttribute } +import language.postfixOps class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage { diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 670c9bbb3b..78796231eb 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -674,9 +674,9 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { nameBuffer append '⇒' appendType0(result) /* Polymorphic types */ - case PolyType(tparams, result) => assert(tparams nonEmpty) + case PolyType(tparams, result) => assert(tparams.nonEmpty) // throw new Error("Polymorphic type '" + tpe + "' cannot be printed as a type") - def typeParamsToString(tps: List[Symbol]): String = if(tps isEmpty) "" else + def typeParamsToString(tps: List[Symbol]): String = if (tps.isEmpty) "" else tps.map{tparam => tparam.varianceString + tparam.name + typeParamsToString(tparam.typeParams) }.mkString("[", ", ", "]") diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala index bc5cd4a958..e6bc76f676 100644 --- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala @@ -13,6 +13,7 @@ import scala.collection._ import scala.util.matching.Regex import scala.annotation.switch import util.{NoPosition, Position} +import language.postfixOps /** The comment parser transforms raw comment strings into `Comment` objects. * Call `parse` to run the parser. Note that the parser is stateless and diff --git a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala index 34a0a4abb6..e2dcc48709 100644 --- a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala +++ b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala @@ -79,7 +79,7 @@ trait ScratchPadMaker { self: Global => addSandbox(stat) } else { val resName = nextRes() - val dispResName = resName filter ('$' !=) + val dispResName = resName filter ('$' != _) patches += Patch(stat.pos.start, "val " + resName + " = ") addSandbox(stat) toPrint += resultString(nameType(dispResName, stat.tpe), resName) diff --git a/src/compiler/scala/tools/nsc/interpreter/package.scala b/src/compiler/scala/tools/nsc/interpreter/package.scala index e35b4e3103..7d2610e3c8 100644 --- a/src/compiler/scala/tools/nsc/interpreter/package.scala +++ b/src/compiler/scala/tools/nsc/interpreter/package.scala @@ -35,6 +35,8 @@ package object interpreter extends ReplConfig with ReplStrings { val IR = Results + implicit def postfixOps = language.postfixOps // make all postfix ops in this package compile without warning + private[interpreter] implicit def javaCharSeqCollectionToScala(xs: JCollection[_ <: CharSequence]): List[String] = { import collection.JavaConverters._ xs.asScala.toList map ("" + _) diff --git a/src/compiler/scala/tools/nsc/io/package.scala b/src/compiler/scala/tools/nsc/io/package.scala index 8ea14e7f8b..52e6de0bed 100644 --- a/src/compiler/scala/tools/nsc/io/package.scala +++ b/src/compiler/scala/tools/nsc/io/package.scala @@ -11,6 +11,8 @@ import java.util.jar.{ Attributes } import language.implicitConversions package object io { + implicit def postfixOps = language.postfixOps // make all postfix ops in this package compile without warning + type JManifest = java.util.jar.Manifest type JFile = java.io.File diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala index 05bd4966df..249f754e8f 100644 --- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala +++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala @@ -10,6 +10,7 @@ import transform.ExplicitOuter import ast.{ TreePrinters, Trees } import java.io.{ StringWriter, PrintWriter } import annotation.elidable +import language.postfixOps /** Ancillary bits of ParallelMatching which are better off * out of the way. diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index 43aad9f591..7346d9c59f 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -14,6 +14,7 @@ import transform.ExplicitOuter import symtab.Flags import mutable.ListBuffer import annotation.elidable +import language.postfixOps trait ParallelMatching extends ast.TreeDSL with MatchSupport diff --git a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala index 56297f0195..b2a721c586 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala @@ -8,6 +8,7 @@ package matching import transform.ExplicitOuter import PartialFunction._ +import language.postfixOps trait PatternBindings extends ast.TreeDSL { @@ -133,4 +134,4 @@ trait PatternBindings extends ast.TreeDSL } val NoBinding: Bindings = new Bindings(Nil) -} \ No newline at end of file +} diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala index 9254ec8628..48c4a9b5b3 100644 --- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala +++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala @@ -138,7 +138,7 @@ object Plugin { } yield entry)).distinct val loader = loaderFor(alljars) - alljars map (loadFrom(_, loader)) flatten + (alljars map (loadFrom(_, loader))).flatten } /** Instantiate a plugin class, given the class and diff --git a/src/compiler/scala/tools/nsc/plugins/Plugins.scala b/src/compiler/scala/tools/nsc/plugins/Plugins.scala index da913a1601..ba042b7b78 100644 --- a/src/compiler/scala/tools/nsc/plugins/Plugins.scala +++ b/src/compiler/scala/tools/nsc/plugins/Plugins.scala @@ -70,7 +70,7 @@ trait Plugins { } } - val plugs = pick(roughPluginsList, Set(), phasesSet map (_.phaseName) toSet) + val plugs = pick(roughPluginsList, Set(), (phasesSet map (_.phaseName)).toSet) /** Verify requirements are present. */ for (req <- settings.require.value ; if !(plugs exists (_.name == req))) @@ -112,5 +112,5 @@ trait Plugins { def pluginOptionsHelp: String = (for (plug <- roughPluginsList ; help <- plug.optionsHelp) yield { "\nOptions for plugin '%s':\n%s\n".format(plug.name, help) - }) mkString + }).mkString } diff --git a/src/compiler/scala/tools/nsc/settings/AbsSettings.scala b/src/compiler/scala/tools/nsc/settings/AbsSettings.scala index 9cea935a63..c1dad2da82 100644 --- a/src/compiler/scala/tools/nsc/settings/AbsSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/AbsSettings.scala @@ -35,7 +35,7 @@ trait AbsSettings extends scala.reflect.internal.settings.AbsSettings { case s: AbsSettings => this.userSetSettings == s.userSetSettings case _ => false } - override def toString() = "Settings {\n%s}\n" format (userSetSettings map (" " + _ + "\n") mkString) + override def toString() = "Settings {\n%s}\n" format (userSetSettings map (" " + _ + "\n")).mkString def toConciseString = userSetSettings.mkString("(", " ", ")") def checkDependencies = diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index ea12300785..a52e3b8bbe 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -136,7 +136,7 @@ class MutableSettings(val errorFn: String => Unit) val (p, args) = StringOps.splitWhere(s, _ == ':', true) getOrElse (return None) // any non-Nil return value means failure and we return s unmodified - tryToSetIfExists(p, args split "," toList, (s: Setting) => s.tryToSetColon _) + tryToSetIfExists(p, (args split ",").toList, (s: Setting) => s.tryToSetColon _) } // if arg is of form -Xfoo or -Xfoo bar (name = "-Xfoo") diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala index 310753871f..3cf5cc2f54 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala @@ -8,6 +8,7 @@ package symtab import scala.collection.{ mutable, immutable } import language.implicitConversions +import language.postfixOps /** Printing the symbol graph (for those symbols attached to an AST node) * after each phase. diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index edbe6df472..52648380ec 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -149,7 +149,7 @@ abstract class Pickler extends SubComponent { putChildren(sym, children.toList sortBy (_.sealedSortName)) } - for (annot <- sym.annotations filter (ann => ann.isStatic && !ann.isErroneous) reverse) + for (annot <- (sym.annotations filter (ann => ann.isStatic && !ann.isErroneous)).reverse) putAnnotation(sym, annot) } else if (sym != NoSymbol) { diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index eea87c8ba6..fd15d92e37 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -9,6 +9,7 @@ package transform import symtab._ import Flags._ import scala.collection._ +import language.postfixOps abstract class CleanUp extends Transform with ast.TreeDSL { import global._ diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index e2ce3b62b4..bdf2f2883f 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -210,7 +210,7 @@ abstract class Erasure extends AddInterfaces } else parents ) - ps map boxedSig mkString + (ps map boxedSig).mkString } def boxedSig(tp: Type) = jsig(tp, primitiveOK = false) def boundsSig(bounds: List[Type]) = traceSig("boundsSig", bounds) { diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 16c7c3c3ff..8daad8a2ac 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -357,7 +357,7 @@ abstract class ExplicitOuter extends InfoTransform */ def mixinOuterAccessorDef(mixinClass: Symbol): Tree = { val outerAcc = outerAccessor(mixinClass) overridingSymbol currentClass - def mixinPrefix = currentClass.thisType baseType mixinClass prefix; + def mixinPrefix = (currentClass.thisType baseType mixinClass).prefix assert(outerAcc != NoSymbol, "No outer accessor for inner mixin " + mixinClass + " in " + currentClass) // I added the mixinPrefix.typeArgs.nonEmpty condition to address the // crash in SI-4970. I feel quite sure this can be improved. diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 3515c1d521..007457ef7b 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -50,7 +50,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { val index = alts indexOf imeth assert(index >= 0, alts+" does not contain "+imeth) def altName(index: Int) = newTermName("extension"+index+"$"+imeth.name) - altName(index) #:: ((0 until alts.length).toStream filter (index !=) map altName) + altName(index) #:: ((0 until alts.length).toStream filter (index != _) map altName) case tpe => assert(tpe != NoType, imeth.name+" not found in "+imeth.owner+"'s decls: "+imeth.owner.info.decls) Stream(newTermName("extension$"+imeth.name)) diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 0e4975c04c..19f32a5411 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -123,7 +123,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { */ private def rebindSuper(base: Symbol, member: Symbol, mixinClass: Symbol): Symbol = afterPickler { - var bcs = base.info.baseClasses.dropWhile(mixinClass !=).tail + var bcs = base.info.baseClasses.dropWhile(mixinClass != _).tail var sym: Symbol = NoSymbol debuglog("starting rebindsuper " + base + " " + member + ":" + member.tpe + " " + mixinClass + " " + base.info.baseClasses + "/" + bcs) @@ -778,7 +778,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { val fields0 = usedBits(cl) if (requiredBitmaps(fields0) < bitmapNum) { - val fields1 = cl.info.decls filter isNonLocalFieldWithBitmap size; + val fields1 = (cl.info.decls filter isNonLocalFieldWithBitmap).size return { if (requiredBitmaps(fields0 + fields1) >= bitmapNum) Some(bitmapFor(cl, offset, valSym, false)) diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 12d2513756..617a811a76 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -8,6 +8,7 @@ package transform import scala.tools.nsc.symtab.Flags import scala.collection.{ mutable, immutable } +import language.postfixOps /** Specialize code on types. * diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 11f06a0541..1d2206bc3d 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -8,6 +8,7 @@ package transform import symtab.Flags._ import scala.collection.{ mutable, immutable } +import language.postfixOps /* */ /** - uncurry all symbol and tree types (@see UnCurryPhase) -- this includes normalizing all proper types. diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index edc69be827..96cd7dde59 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -483,7 +483,7 @@ trait ContextErrors { val keep = missing take 3 map (_.name) ".\nUnspecified value parameter%s %s".format( if (missing.tail.isEmpty) "" else "s", - if (missing drop 3 nonEmpty) (keep :+ "...").mkString(", ") + if ((missing drop 3).nonEmpty) (keep :+ "...").mkString(", ") else keep.mkString("", ", ", ".") ) } @@ -644,7 +644,7 @@ trait ContextErrors { private def applyErrorMsg(tree: Tree, msg: String, argtpes: List[Type], pt: Type) = { def asParams(xs: List[Any]) = xs.mkString("(", ", ", ")") - def resType = if (pt isWildcard) "" else " with expected result type " + pt + def resType = if (pt.isWildcard) "" else " with expected result type " + pt def allTypes = (alternatives(tree) flatMap (_.paramTypes)) ++ argtpes :+ pt def locals = alternatives(tree) flatMap (_.typeParams) diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 3a789b83b6..a6d05ec48e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -689,7 +689,7 @@ trait Implicits { def comesBefore(sym: Symbol, owner: Symbol) = { val ownerPos = owner.pos.pointOrElse(Int.MaxValue) sym.pos.pointOrElse(0) < ownerPos && ( - if (sym hasAccessorFlag) { + if (sym.hasAccessorFlag) { val symAcc = sym.accessed // #3373 symAcc.pos.pointOrElse(0) < ownerPos && !(owner.ownerChain exists (o => (o eq sym) || (o eq symAcc))) // probably faster to iterate only once, don't feel like duplicating hasTransOwner for this case @@ -809,7 +809,7 @@ trait Implicits { /** Returns all eligible ImplicitInfos and their SearchResults in a map. */ - def findAll() = eligible map (info => (info, typedImplicit(info, false))) toMap + def findAll() = (eligible map (info => (info, typedImplicit(info, false)))).toMap /** Returns the SearchResult of the best match. */ @@ -1210,7 +1210,7 @@ trait Implicits { // where `X` refers to a type parameter of `sym` def check(sym: Symbol): Option[String] = sym.getAnnotation(ImplicitNotFoundClass).flatMap(_.stringArg(0) match { - case Some(m) => new Message(sym, m) validate + case Some(m) => new Message(sym, m).validate case None => Some("Missing argument `msg` on implicitNotFound annotation.") }) @@ -1235,7 +1235,7 @@ trait Implicits { val decls = typeParamNames.toSet (refs &~ decls) match { - case s if s isEmpty => None + case s if s.isEmpty => None case unboundNames => val singular = unboundNames.size == 1 Some("The type parameter"+( if(singular) " " else "s " )+ unboundNames.mkString(", ") + diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 98b8d7673e..2efedfb717 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -446,7 +446,7 @@ trait Infer { type Result = collection.mutable.LinkedHashMap[Symbol, Option[Type]] def unapply(m: Result): Some[(List[Symbol], List[Type])] = Some(toLists( - m collect {case (p, Some(a)) => (p, a)} unzip )) + (m collect {case (p, Some(a)) => (p, a)}).unzip )) object Undets { def unapply(m: Result): Some[(List[Symbol], List[Type], List[Symbol])] = Some(toLists{ @@ -766,7 +766,7 @@ trait Infer { isAsSpecific(res, ftpe2) case mt: MethodType if mt.isImplicit => isAsSpecific(ftpe1.resultType, ftpe2) - case MethodType(params, _) if params nonEmpty => + case MethodType(params, _) if params.nonEmpty => var argtpes = params map (_.tpe) if (isVarArgsList(params) && isVarArgsList(ftpe2.params)) argtpes = argtpes map (argtpe => @@ -776,7 +776,7 @@ trait Infer { isAsSpecific(PolyType(tparams, res), ftpe2) case PolyType(tparams, mt: MethodType) if mt.isImplicit => isAsSpecific(PolyType(tparams, mt.resultType), ftpe2) - case PolyType(_, MethodType(params, _)) if params nonEmpty => + case PolyType(_, MethodType(params, _)) if params.nonEmpty => isApplicable(List(), ftpe2, params map (_.tpe), WildcardType) // case NullaryMethodType(res) => // isAsSpecific(res, ftpe2) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 18636ecb05..6996dc6836 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -543,14 +543,14 @@ trait Macros { self: Analyzer => val implCtxParam = if (implParamss.length > 0 && implParamss(0).length > 0) implParamss(0)(0) else null def implParamToDefParam(implParam: Symbol): Symbol = { - val indices = (implParamss drop 1 zipWithIndex) map { case (implParams, index) => (index, implParams indexOf implParam) } filter (_._2 != -1) headOption; + val indices = (((implParamss drop 1).zipWithIndex) map { case (implParams, index) => (index, implParams indexOf implParam) } filter (_._2 != -1)).headOption val defParam = indices flatMap { case (plistIndex, pIndex) => if (defParamss.length <= plistIndex) None else if (defParamss(plistIndex).length <= pIndex) None else Some(defParamss(plistIndex)(pIndex)) } - defParam orNull + defParam.orNull } class UnsigmaTypeMap extends TypeMap { diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 4d84bf4af2..be269cf4b2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -48,7 +48,7 @@ trait NamesDefaults { self: Analyzer => /** @param pos maps indices from new to old (!) */ def reorderArgsInv[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = { val argsArray = args.toArray - argsArray.indices map (i => argsArray(pos(i))) toList + (argsArray.indices map (i => argsArray(pos(i)))).toList } /** returns `true` if every element is equal to its index */ diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index aff8368f75..e8e65071af 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -8,6 +8,7 @@ package typechecker import symtab._ import Flags.{MUTABLE, METHOD, LABEL, SYNTHETIC} +import language.postfixOps /** Translate pattern matching into method calls (these methods form a zero-plus monad), similar in spirit to how for-comprehensions are compiled. * @@ -157,12 +158,12 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer => (caseScrutSym, propagateSubstitution(translateCase(caseScrutSym, pt)(caseDef), EmptySubstitution)) } - for(cases <- emitTypeSwitch(bindersAndCases, pt) toList; + for(cases <- emitTypeSwitch(bindersAndCases, pt).toList; if cases forall treeInfo.isCatchCase; // must check again, since it's not guaranteed -- TODO: can we eliminate this? e.g., a type test could test for a trait or a non-trivial prefix, which are not handled by the back-end cse <- cases) yield fixerUpper(matchOwner, pos)(cse).asInstanceOf[CaseDef] } - val catches = if (swatches nonEmpty) swatches else { + val catches = if (swatches.nonEmpty) swatches else { val scrutSym = freshSym(pos, pureType(ThrowableClass.tpe)) val casesNoSubstOnly = caseDefs map { caseDef => (propagateSubstitution(translateCase(scrutSym, pt)(caseDef), EmptySubstitution))} diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index ad727d4082..af75c75156 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -10,6 +10,7 @@ import symtab.Flags._ import collection.{ mutable, immutable } import transform.InfoTransform import scala.collection.mutable.ListBuffer +import language.postfixOps /**

* Post-attribution checking and transformation. @@ -358,7 +359,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R /** Is the intersection between given two lists of overridden symbols empty? */ def intersectionIsEmpty(syms1: List[Symbol], syms2: List[Symbol]) = - !(syms1 exists (syms2 contains)) + !(syms1 exists (syms2 contains _)) if (typesOnly) checkOverrideTypes() else { diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index da87d38ab0..868c236ee9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -50,7 +50,7 @@ trait SyntheticMethods extends ast.TreeDSL { import synthesizer._ if (clazz0 == AnyValClass || isPrimitiveValueClass(clazz0)) return { - if (clazz0.info member nme.getClass_ isDeferred) { + if ((clazz0.info member nme.getClass_).isDeferred) { // XXX dummy implementation for now val getClassMethod = createMethod(nme.getClass_, getClassReturnType(clazz.tpe))(_ => NULL) deriveTemplate(templ)(_ :+ getClassMethod) @@ -303,7 +303,7 @@ trait SyntheticMethods extends ast.TreeDSL { lb += logResult("case accessor new")(newAcc) } - lb ++= templ.body ++= synthesize() toList + (lb ++= templ.body ++= synthesize()).toList } if (phase.id > currentRun.typerPhase.id) templ diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index 8895905ca7..45d916c633 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -28,7 +28,7 @@ abstract class TreeCheckers extends Analyzer { } } - private def classstr(x: AnyRef) = x.getClass.getName split """\\.|\\$""" last; + private def classstr(x: AnyRef) = (x.getClass.getName split """\\.|\\$""").last private def typestr(x: Type) = " (tpe = " + x + ")" private def treestr(t: Tree) = t + " [" + classstr(t) + "]" + typestr(t.tpe) private def ownerstr(s: Symbol) = "'" + s + "'" + s.locationString diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 0233974f6f..b1cbc53044 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -750,7 +750,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (!(currentRun.reportedFeature contains featureTrait)) raw += "\nThis can be achieved by adding the import clause 'import language." + featureName + "'\n" + "or by setting the compiler option -language:" + featureName + ".\n" + - "See the Scala docs for value scala.language." + featureName + "for a discussion\n" + + "See the Scala docs for value scala.language." + featureName + " for a discussion\n" + "why the feature " + req + " be explicitly enabled." currentRun.reportedFeature += featureTrait val msg = raw replace ("#", construct) @@ -805,7 +805,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { protected def adapt(tree: Tree, mode: Int, pt: Type, original: Tree = EmptyTree): Tree = { def adaptToImplicitMethod(mt: MethodType): Tree = { - if (context.undetparams nonEmpty) { // (9) -- should revisit dropped condition `(mode & POLYmode) == 0` + if (context.undetparams.nonEmpty) { // (9) -- should revisit dropped condition `(mode & POLYmode) == 0` // dropped so that type args of implicit method are inferred even if polymorphic expressions are allowed // needed for implicits in 2.8 collection library -- maybe once #3346 is fixed, we can reinstate the condition? context.undetparams = inferExprInstance(tree, context.extractUndetparams(), pt, @@ -2157,7 +2157,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { var body1: Tree = typed(cdef.body, pt) val contextWithTypeBounds = context.nextEnclosing(_.tree.isInstanceOf[CaseDef]) - if (contextWithTypeBounds.savedTypeBounds nonEmpty) { + if (contextWithTypeBounds.savedTypeBounds.nonEmpty) { body1.tpe = contextWithTypeBounds restoreTypeBounds body1.tpe // insert a cast if something typechecked under the GADT constraints, @@ -4188,7 +4188,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { result match { // could checkAccessible (called by makeAccessible) potentially have skipped checking a type application in qual? - case SelectFromTypeTree(qual@TypeTree(), name) if qual.tpe.typeArgs nonEmpty => // TODO: somehow the new qual is not checked in refchecks + case SelectFromTypeTree(qual@TypeTree(), name) if qual.tpe.typeArgs.nonEmpty => // TODO: somehow the new qual is not checked in refchecks treeCopy.SelectFromTypeTree( result, (TypeTreeWithDeferredRefCheck(){ () => val tp = qual.tpe; val sym = tp.typeSymbolDirect @@ -4751,6 +4751,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else typedSelect(qual1, name) + if (tree.isInstanceOf[PostfixSelect]) + checkFeature(tree.pos, PostfixOpsFeature, name.decode) if (tree1.symbol != null && tree1.symbol.isOnlyRefinementMember) checkFeature(tree1.pos, ReflectiveCallsFeature, tree1.symbol.toString) diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index 1f79d8212d..1ebcea4a07 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -200,7 +200,7 @@ trait Unapplies extends ast.TreeDSL def caseClassCopyMeth(cdef: ClassDef): Option[DefDef] = { def isDisallowed(vd: ValDef) = isRepeatedParamType(vd.tpt) || isByNameParamType(vd.tpt) val cparamss = constrParamss(cdef) - val flat = cparamss flatten + val flat = cparamss.flatten if (cdef.symbol.hasAbstractFlag || (flat exists isDisallowed)) None else { diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 11d7db5180..5dd9ce0e02 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -29,7 +29,7 @@ object ClassPath { def infoFor[T](value: T) = info(value.getClass) def info[T](clazz: Class[T]) = new ClassAndJarInfo()(ClassManifest[T](clazz)) def info[T: ClassManifest] = new ClassAndJarInfo[T] - def locate[T: ClassManifest] = info[T] rootClasspath + def locate[T: ClassManifest] = info[T].rootClasspath def locateJar[T: ClassManifest] = info[T].rootPossibles find (x => isJarOrZip(x)) map (x => File(x)) def locateDir[T: ClassManifest] = info[T].rootPossibles find (_.isDirectory) map (_.toDirectory) @@ -373,7 +373,7 @@ extends ClassPath[T] { this(entries.toIndexedSeq, context) def name = entries.head.name - def asURLs = entries flatMap (_.asURLs) toList + def asURLs = (entries flatMap (_.asURLs)).toList lazy val sourcepaths: IndexedSeq[AbstractFile] = entries flatMap (_.sourcepaths) override def origin = Some(entries map (x => x.origin getOrElse x.name) mkString ("Merged(", ", ", ")")) diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala index 88e6c51e9f..1336cca3c5 100644 --- a/src/compiler/scala/tools/nsc/util/package.scala +++ b/src/compiler/scala/tools/nsc/util/package.scala @@ -9,6 +9,8 @@ import java.io.{ OutputStream, PrintStream, ByteArrayOutputStream, PrintWriter, package object util { + implicit def postfixOps = language.postfixOps // make all postfix ops in this package compile without warning + // forwarder for old code that builds against 2.9 and 2.10 val Chars = scala.reflect.internal.Chars diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index dc67d32ba0..ea0d20957d 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -70,10 +70,9 @@ abstract class Enumeration (initial: Int) extends Serializable { /** The name of this enumeration. */ - override def toString = ( - (getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.' last) - split Pattern.quote(NAME_JOIN_STRING) last - ) + override def toString = + ((getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.').last split + Pattern.quote(NAME_JOIN_STRING)).last /** The mapping from the integer used to identify values to the actual * values. */ diff --git a/src/library/scala/collection/DefaultMap.scala b/src/library/scala/collection/DefaultMap.scala index 3af535bdaa..d00414751a 100644 --- a/src/library/scala/collection/DefaultMap.scala +++ b/src/library/scala/collection/DefaultMap.scala @@ -41,7 +41,7 @@ trait DefaultMap[A, +B] extends Map[A, B] { self => */ override def - (key: A): Map[A, B] = { val b = newBuilder - b ++= this filter (key !=) + b ++= this filter (key != _) b.result } } diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala index 755abcd2bf..71316cefc9 100644 --- a/src/library/scala/collection/GenSeqLike.scala +++ b/src/library/scala/collection/GenSeqLike.scala @@ -142,7 +142,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal * $mayNotTerminateInf * */ - def indexOf[B >: A](elem: B, from: Int): Int = indexWhere(elem ==, from) + def indexOf[B >: A](elem: B, from: Int): Int = indexWhere(elem == _, from) /** Finds index of last occurrence of some value in this $coll. * @@ -157,7 +157,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal * $willNotTerminateInf * */ - def lastIndexOf[B >: A](elem: B): Int = lastIndexWhere(elem ==) + def lastIndexOf[B >: A](elem: B): Int = lastIndexWhere(elem == _) /** Finds index of last occurrence of some value in this $coll before or at a given end index. * @@ -170,7 +170,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal * @usecase def lastIndexOf(elem: A, end: Int): Int * @inheritdoc */ - def lastIndexOf[B >: A](elem: B, end: Int): Int = lastIndexWhere(elem ==, end) + def lastIndexOf[B >: A](elem: B, end: Int): Int = lastIndexWhere(elem == _, end) /** Finds index of last element satisfying some predicate. * diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala index fb6d154952..3c4ad0612a 100644 --- a/src/library/scala/collection/IterableLike.scala +++ b/src/library/scala/collection/IterableLike.scala @@ -134,7 +134,7 @@ self => it.next i += 1 } - b ++= it result + (b ++= it).result } override /*TraversableLike*/ def takeWhile(p: A => Boolean): Repr = { diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index fd1d42d7e9..ced99e897f 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -185,7 +185,7 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ private[this] def init() = { val m = mutable.HashMap[A, Int]() - val (es, is) = thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2) unzip + val (es, is) = (thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2)).unzip (es.toBuffer, is.toArray) } @@ -240,7 +240,7 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ val m = mutable.HashMap[A, Int]() // e => (e, weight(e)) - val (es, is) = thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2) unzip + val (es, is) = (thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2)).unzip val cs = new Array[Int](m.size) is foreach (i => cs(i) += 1) val ns = new Array[Int](cs.length) diff --git a/src/library/scala/collection/SeqProxyLike.scala b/src/library/scala/collection/SeqProxyLike.scala index ce32ba97c2..3783ef771f 100644 --- a/src/library/scala/collection/SeqProxyLike.scala +++ b/src/library/scala/collection/SeqProxyLike.scala @@ -36,7 +36,7 @@ trait SeqProxyLike[+A, +Repr <: SeqLike[A, Repr] with Seq[A]] extends SeqLike[A, override def indexOf[B >: A](elem: B): Int = self.indexOf(elem) override def indexOf[B >: A](elem: B, from: Int): Int = self.indexOf(elem, from) override def lastIndexOf[B >: A](elem: B): Int = self.lastIndexOf(elem) - override def lastIndexOf[B >: A](elem: B, end: Int): Int = self.lastIndexWhere(elem ==, end) + override def lastIndexOf[B >: A](elem: B, end: Int): Int = self.lastIndexWhere(elem == _, end) override def lastIndexWhere(p: A => Boolean): Int = self.lastIndexWhere(p, length - 1) override def lastIndexWhere(p: A => Boolean, end: Int): Int = self.lastIndexWhere(p) override def reverse: Repr = self.reverse diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index 1f5beb5109..a4f36d20c7 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -487,7 +487,7 @@ trait TraversableLike[+A, +Repr] extends Any if (n <= 0) { val b = newBuilder b.sizeHint(this) - b ++= thisCollection result + (b ++= thisCollection).result } else sliceWithKnownDelta(n, Int.MaxValue, -n) @@ -775,6 +775,6 @@ trait TraversableLike[+A, +Repr] extends Any // A helper for tails and inits. private def iterateUntilEmpty(f: Traversable[A @uV] => Traversable[A @uV]): Iterator[Repr] = { val it = Iterator.iterate(thisCollection)(f) takeWhile (x => !x.isEmpty) - it ++ Iterator(Nil) map (newBuilder ++= _ result) + it ++ Iterator(Nil) map (x => (newBuilder ++= x).result) } } diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index 4bd32566e8..e68ef9e4de 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -240,7 +240,7 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { def toTraversable: Traversable[A] - def toList: List[A] = new ListBuffer[A] ++= seq toList + def toList: List[A] = (new ListBuffer[A] ++= seq).toList def toIterable: Iterable[A] = toStream diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala index ac95aa6e27..ad5e3d3240 100644 --- a/src/library/scala/collection/TraversableViewLike.scala +++ b/src/library/scala/collection/TraversableViewLike.scala @@ -19,7 +19,7 @@ trait ViewMkString[+A] { // It is necessary to use thisSeq rather than toSeq to avoid cycles in the // eager evaluation of vals in transformed view subclasses, see #4558. - protected[this] def thisSeq: Seq[A] = new ArrayBuffer[A] ++= self result + protected[this] def thisSeq: Seq[A] = (new ArrayBuffer[A] ++= self).result // Have to overload all three to work around #4299. The overload // is because mkString should force a view but toString should not. diff --git a/src/library/scala/collection/generic/GenTraversableFactory.scala b/src/library/scala/collection/generic/GenTraversableFactory.scala index f86fa3628a..f233a40d35 100644 --- a/src/library/scala/collection/generic/GenTraversableFactory.scala +++ b/src/library/scala/collection/generic/GenTraversableFactory.scala @@ -73,7 +73,7 @@ abstract class GenTraversableFactory[CC[X] <: GenTraversable[X] with GenericTrav val b = newBuilder[A] // At present we're using IndexedSeq as a proxy for "has a cheap size method". if (xss forall (_.isInstanceOf[IndexedSeq[_]])) - b.sizeHint(xss map (_.size) sum) + b.sizeHint(xss.map(_.size).sum) for (xs <- xss.seq) b ++= xs b.result diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala index 47e3245117..b71071d3c0 100644 --- a/src/library/scala/collection/immutable/ListSet.scala +++ b/src/library/scala/collection/immutable/ListSet.scala @@ -33,7 +33,7 @@ object ListSet extends ImmutableSetFactory[ListSet] { */ class ListSetBuilder[Elem](initial: ListSet[Elem]) extends Builder[Elem, ListSet[Elem]] { def this() = this(empty[Elem]) - protected val elems = new mutable.ListBuffer[Elem] ++= initial reverse + protected val elems = (new mutable.ListBuffer[Elem] ++= initial).reverse protected val seen = new mutable.HashSet[Elem] ++= initial def +=(x: Elem): this.type = { @@ -100,7 +100,7 @@ class ListSet[A] extends AbstractSet[A] */ override def ++(xs: GenTraversableOnce[A]): ListSet[A] = if (xs.isEmpty) this - else new ListSet.ListSetBuilder(this) ++= xs.seq result + else (new ListSet.ListSetBuilder(this) ++= xs.seq).result @bridge def ++(xs: TraversableOnce[A]): ListSet[A] = ++(xs: GenTraversableOnce[A]): ListSet[A] diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 7ffb54680c..2df4ed70c7 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -822,7 +822,7 @@ self => */ override def distinct: Stream[A] = if (isEmpty) this - else cons(head, tail.filter(head !=).distinct) + else cons(head, tail.filter(head != _).distinct) /** Returns a new sequence of given length containing the elements of this * sequence followed by zero or more occurrences of given elements. diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index fc4e7bf0a8..06f09f359f 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -60,7 +60,7 @@ self => val end = until min length if (start >= end) newBuilder.result - else newBuilder ++= toString.substring(start, end) result + else (newBuilder ++= toString.substring(start, end)).result } /** Return the current string concatenated `n` times. diff --git a/src/library/scala/collection/immutable/TrieIterator.scala b/src/library/scala/collection/immutable/TrieIterator.scala index c77334b732..ead1a8c744 100644 --- a/src/library/scala/collection/immutable/TrieIterator.scala +++ b/src/library/scala/collection/immutable/TrieIterator.scala @@ -75,7 +75,7 @@ private[collection] abstract class TrieIterator[+T](elems: Array[Iterable[T]]) e } private[this] def iteratorWithSize(arr: Array[Iterable[T]]): (Iterator[T], Int) = - (newIterator(arr), arr map (_.size) sum) + (newIterator(arr), arr.map(_.size).sum) private[this] def arrayToIterators(arr: Array[Iterable[T]]): SplitIterators = { val (fst, snd) = arr.splitAt(arr.length / 2) diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index 3e7b8071be..875030ade0 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -65,7 +65,7 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza */ def flatten[U, To](implicit asTrav: T => collection.Traversable[U], m: ClassManifest[U]): Array[U] = { val b = Array.newBuilder[U] - b.sizeHint(map{case is: collection.IndexedSeq[_] => is.size case _ => 0} sum) + b.sizeHint(map{case is: collection.IndexedSeq[_] => is.size case _ => 0}.sum) for (xs <- this) b ++= asTrav(xs) b.result diff --git a/src/library/scala/collection/mutable/LinkedHashSet.scala b/src/library/scala/collection/mutable/LinkedHashSet.scala index f6d4915fef..d2815cf9de 100644 --- a/src/library/scala/collection/mutable/LinkedHashSet.scala +++ b/src/library/scala/collection/mutable/LinkedHashSet.scala @@ -82,7 +82,7 @@ class LinkedHashSet[A] extends AbstractSet[A] private def readObject(in: java.io.ObjectInputStream) { ordered = new ListBuffer[A] - init(in, ordered += ) + init(in, ordered += _) } } diff --git a/src/library/scala/collection/mutable/StringBuilder.scala b/src/library/scala/collection/mutable/StringBuilder.scala index d9ad58f054..08c881dbb8 100644 --- a/src/library/scala/collection/mutable/StringBuilder.scala +++ b/src/library/scala/collection/mutable/StringBuilder.scala @@ -404,7 +404,7 @@ final class StringBuilder(private val underlying: JavaStringBuilder) * @return the reversed StringBuilder */ @migration("`reverse` returns a new instance. Use `reverseContents` to update in place and return that StringBuilder itself.", "2.8.0") - override def reverse: StringBuilder = new StringBuilder(new JavaStringBuilder(underlying) reverse) + override def reverse: StringBuilder = new StringBuilder(new JavaStringBuilder(underlying).reverse) override def clone(): StringBuilder = new StringBuilder(new JavaStringBuilder(underlying)) diff --git a/src/library/scala/io/BytePickle.scala b/src/library/scala/io/BytePickle.scala index bec0cfb53f..3bb5ea9c2b 100644 --- a/src/library/scala/io/BytePickle.scala +++ b/src/library/scala/io/BytePickle.scala @@ -269,7 +269,7 @@ object BytePickle { } def string: SPU[String] = share(wrap( - (a: Array[Byte]) => Codec fromUTF8 a mkString, + (a: Array[Byte]) => (Codec fromUTF8 a).mkString, (s: String) => Codec toUTF8 s, bytearray )) diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala index 3cee0ace79..5e09e13680 100644 --- a/src/library/scala/io/Source.scala +++ b/src/library/scala/io/Source.scala @@ -188,7 +188,7 @@ abstract class Source extends Iterator[Char] { var nerrors = 0 var nwarnings = 0 - private def lineNum(line: Int): String = getLines() drop (line - 1) take 1 mkString + private def lineNum(line: Int): String = (getLines() drop (line - 1) take 1).mkString class LineIterator extends AbstractIterator[String] with Iterator[String] { private[this] val sb = new StringBuilder diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala index 09f08b82cc..74daa510ca 100644 --- a/src/library/scala/math/BigDecimal.scala +++ b/src/library/scala/math/BigDecimal.scala @@ -293,7 +293,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable { /** Returns the absolute value of this BigDecimal */ - def abs: BigDecimal = this.bigDecimal abs + def abs: BigDecimal = this.bigDecimal.abs /** Returns the sign of this BigDecimal, i.e. * -1 if it is less than 0, diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 01f948809c..6ddb2ea673 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -1519,7 +1519,7 @@ trait Trees { self: Universe => def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = stats mapConserve (stat => if (exprOwner != currentOwner && stat.isTerm) atOwner(exprOwner)(transform(stat)) - else transform(stat)) filter (EmptyTree !=) + else transform(stat)) filter (EmptyTree != _) def transformModifiers(mods: Modifiers): Modifiers = mods.mapAnnotations(transformTrees) diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index d06eba8f7d..7a932c21bc 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -329,14 +329,14 @@ object ScalaRunTime { case null => "null" case "" => "\"\"" case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x - case x if useOwnToString(x) => x toString + case x if useOwnToString(x) => x.toString case x: AnyRef if isArray(x) => arrayToString(x) case x: collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") - case x => x toString + case x => x.toString } // The try/catch is defense against iterables which aren't actually designed diff --git a/src/library/scala/util/Random.scala b/src/library/scala/util/Random.scala index b5dc3486ae..17c356801b 100644 --- a/src/library/scala/util/Random.scala +++ b/src/library/scala/util/Random.scala @@ -118,7 +118,7 @@ class Random(val self: java.util.Random) { swap(n - 1, k) } - bf(xs) ++= buf result + (bf(xs) ++= buf).result } /** Returns a Stream of pseudorandomly chosen alphanumeric characters, diff --git a/src/library/scala/util/automata/BaseBerrySethi.scala b/src/library/scala/util/automata/BaseBerrySethi.scala index 18f36f9496..c78b2d0790 100644 --- a/src/library/scala/util/automata/BaseBerrySethi.scala +++ b/src/library/scala/util/automata/BaseBerrySethi.scala @@ -78,7 +78,7 @@ abstract class BaseBerrySethi { * @return ... */ protected def compFollow1(fol1: Set[Int], r: RegExp): Set[Int] = r match { - case x: Alt => Set(x.rs reverseMap (compFollow1(fol1, _)) flatten: _*) + case x: Alt => Set((x.rs reverseMap (compFollow1(fol1, _))).flatten: _*) case x: Meta => compFollow1(fol1, x.r) case x: Star => compFollow1(fol1 ++ compFirst(x.r), x.r) case x: Sequ => diff --git a/src/library/scala/util/automata/NondetWordAutom.scala b/src/library/scala/util/automata/NondetWordAutom.scala index fbc05de7fd..b09e82ca11 100644 --- a/src/library/scala/util/automata/NondetWordAutom.scala +++ b/src/library/scala/util/automata/NondetWordAutom.scala @@ -50,8 +50,8 @@ abstract class NondetWordAutom[T <: AnyRef] { override def toString = { val finalString = Map(finalStates map (j => j -> finals(j)) : _*).toString - val deltaString = (0 until nstates) . - map (i => " %d->%s\n _>%s\n".format(i, delta(i), default(i))) mkString + val deltaString = (0 until nstates) + .map(i => " %d->%s\n _>%s\n".format(i, delta(i), default(i))).mkString "[NondetWordAutom nstates=%d finals=%s delta=\n%s".format(nstates, finalString, deltaString) } diff --git a/src/library/scala/util/automata/SubsetConstruction.scala b/src/library/scala/util/automata/SubsetConstruction.scala index 8049d10d88..81805fce2f 100644 --- a/src/library/scala/util/automata/SubsetConstruction.scala +++ b/src/library/scala/util/automata/SubsetConstruction.scala @@ -14,7 +14,7 @@ class SubsetConstruction[T <: AnyRef](val nfa: NondetWordAutom[T]) { import nfa.labels def selectTag(Q: immutable.BitSet, finals: Array[Int]) = - Q map finals filter (_ > 0) min + (Q map finals filter (_ > 0)).min def determinize: DetWordAutom[T] = { // for assigning numbers to bitsets diff --git a/src/library/scala/util/automata/WordBerrySethi.scala b/src/library/scala/util/automata/WordBerrySethi.scala index 84b78d8dd8..a7ad92e648 100644 --- a/src/library/scala/util/automata/WordBerrySethi.scala +++ b/src/library/scala/util/automata/WordBerrySethi.scala @@ -139,7 +139,7 @@ abstract class WordBerrySethi extends BaseBerrySethi { finals = finals.updated(0, finalTag) val delta1 = immutable.Map(deltaq.zipWithIndex map (_.swap): _*) - val finalsArr = 0 until pos map (k => finals.getOrElse(k, 0)) toArray // 0 == not final + val finalsArr = (0 until pos map (k => finals.getOrElse(k, 0))).toArray // 0 == not final val initialsArr = initials.toArray val deltaArr: Array[mutable.Map[_labelT, immutable.BitSet]] = @@ -147,7 +147,7 @@ abstract class WordBerrySethi extends BaseBerrySethi { mutable.HashMap(delta1(x).toSeq map { case (k, v) => k -> immutable.BitSet(v: _*) } : _*) }).toArray - val defaultArr = 0 until pos map (k => immutable.BitSet(defaultq(k): _*)) toArray + val defaultArr = (0 until pos map (k => immutable.BitSet(defaultq(k): _*))).toArray new NondetWordAutom[_labelT] { val nstates = pos @@ -161,4 +161,4 @@ abstract class WordBerrySethi extends BaseBerrySethi { automatonFrom(Sequ(z.asInstanceOf[this.lang._regexpT]), finalTag) } } -} \ No newline at end of file +} diff --git a/src/library/scala/util/parsing/combinator/lexical/Lexical.scala b/src/library/scala/util/parsing/combinator/lexical/Lexical.scala index 9979a420d6..6c3bc52c1a 100644 --- a/src/library/scala/util/parsing/combinator/lexical/Lexical.scala +++ b/src/library/scala/util/parsing/combinator/lexical/Lexical.scala @@ -32,7 +32,7 @@ abstract class Lexical extends Scanners with Tokens { def digit = elem("digit", _.isDigit) /** A character-parser that matches any character except the ones given in `cs` (and returns it).*/ - def chrExcept(cs: Char*) = elem("", ch => (cs forall (ch !=))) + def chrExcept(cs: Char*) = elem("", ch => (cs forall (ch != _))) /** A character-parser that matches a white-space character (and returns it).*/ def whitespaceChar = elem("space char", ch => ch <= ' ' && ch != EofCh) diff --git a/src/library/scala/util/parsing/combinator/testing/RegexTest.scala b/src/library/scala/util/parsing/combinator/testing/RegexTest.scala index 299736046e..255730e5db 100644 --- a/src/library/scala/util/parsing/combinator/testing/RegexTest.scala +++ b/src/library/scala/util/parsing/combinator/testing/RegexTest.scala @@ -3,6 +3,7 @@ package scala.util.parsing.combinator.testing import scala.util.parsing.combinator._ import scala.util.parsing.input._ +import language.postfixOps case class Ident(s: String) case class Number(n: Int) diff --git a/src/library/scala/xml/Elem.scala b/src/library/scala/xml/Elem.scala index 5b6b9f2bb9..f140fd1e07 100755 --- a/src/library/scala/xml/Elem.scala +++ b/src/library/scala/xml/Elem.scala @@ -107,5 +107,5 @@ extends Node with Serializable /** Returns concatenation of `text(n)` for each child `n`. */ - override def text = child map (_.text) mkString + override def text = (child map (_.text)).mkString } diff --git a/src/library/scala/xml/MetaData.scala b/src/library/scala/xml/MetaData.scala index c516747bae..b44a817499 100644 --- a/src/library/scala/xml/MetaData.scala +++ b/src/library/scala/xml/MetaData.scala @@ -167,7 +167,7 @@ extends AbstractIterable[MetaData] /** Returns a Map containing the attributes stored as key/value pairs. */ def asAttrMap: Map[String, String] = - iterator map (x => (x.prefixedKey, x.value.text)) toMap + (iterator map (x => (x.prefixedKey, x.value.text))).toMap /** returns Null or the next MetaData item */ def next: MetaData diff --git a/src/library/scala/xml/NodeSeq.scala b/src/library/scala/xml/NodeSeq.scala index 7404e25021..f0be338fcf 100644 --- a/src/library/scala/xml/NodeSeq.scala +++ b/src/library/scala/xml/NodeSeq.scala @@ -153,5 +153,5 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S override def toString(): String = theSeq.mkString - def text: String = this map (_.text) mkString + def text: String = (this map (_.text)).mkString } diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala index 214f4e667b..062a62e240 100755 --- a/src/library/scala/xml/Utility.scala +++ b/src/library/scala/xml/Utility.scala @@ -140,7 +140,7 @@ object Utility extends AnyRef with parsing.TokenTests { * @return `'''null'''` if `ref` was not a predefined entity. */ final def unescape(ref: String, s: StringBuilder): StringBuilder = - (unescMap get ref) map (s append _) orNull + ((unescMap get ref) map (s append _)).orNull /** * Returns a set of all namespaces used in a sequence of nodes diff --git a/src/library/scala/xml/dtd/ContentModel.scala b/src/library/scala/xml/dtd/ContentModel.scala index 1e9a3a4b58..a5d2a6bd7e 100644 --- a/src/library/scala/xml/dtd/ContentModel.scala +++ b/src/library/scala/xml/dtd/ContentModel.scala @@ -36,8 +36,8 @@ object ContentModel extends WordExp { def traverse(r: RegExp): Set[String] = r match { // !!! check for match translation problem case Letter(ElemName(name)) => Set(name) case Star( x @ _ ) => traverse( x ) // bug if x@_* - case Sequ( xs @ _* ) => Set(xs map traverse flatten: _*) - case Alt( xs @ _* ) => Set(xs map traverse flatten: _*) + case Sequ( xs @ _* ) => Set(xs flatMap traverse: _*) + case Alt( xs @ _* ) => Set(xs flatMap traverse: _*) } traverse(r) diff --git a/src/library/scala/xml/parsing/ConstructingParser.scala b/src/library/scala/xml/parsing/ConstructingParser.scala index 5571c9844d..471cde056e 100644 --- a/src/library/scala/xml/parsing/ConstructingParser.scala +++ b/src/library/scala/xml/parsing/ConstructingParser.scala @@ -16,10 +16,10 @@ import scala.io.Source object ConstructingParser { def fromFile(inp: File, preserveWS: Boolean) = - new ConstructingParser(Source.fromFile(inp), preserveWS) initialize + new ConstructingParser(Source.fromFile(inp), preserveWS).initialize def fromSource(inp: Source, preserveWS: Boolean) = - new ConstructingParser(inp, preserveWS) initialize + new ConstructingParser(inp, preserveWS).initialize } /** An xml parser. parses XML and invokes callback methods of a MarkupHandler. -- cgit v1.2.3 From 821229f7fe966f955ebfa87ed0d6ed3760d3f875 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 13 Apr 2012 01:11:41 +0200 Subject: Fixes https://scala-webapps.epfl.ch/jenkins/job/scala-checkin-rangpos/404/ --- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2b7c8e8304..2d1c62d347 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3483,7 +3483,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else tree original setType ann.tpe - original setPos tree.pos.focus TypeTree(tpe) setOriginal original setPos tree.pos.focus } @@ -3542,7 +3541,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { ann.tpe = arg1.tpe.withAnnotation(annotInfo) } val atype = ann.tpe - Typed(arg1, resultingTypeTree(atype)) setPos tree.pos.focus setType atype + Typed(arg1, resultingTypeTree(atype)) setPos tree.pos setType atype } } -- cgit v1.2.3 From 48b0a7360e8d0a7bbd7f8e1bbd3c3a239b5aaa16 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 13 Apr 2012 10:42:48 +0200 Subject: performance counters for macros expansions --- .../scala/tools/nsc/typechecker/Macros.scala | 299 +++++++++++---------- src/compiler/scala/tools/nsc/util/Statistics.scala | 55 ++-- 2 files changed, 183 insertions(+), 171 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 9608108a0d..be7db9a920 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -9,6 +9,7 @@ import scala.collection.mutable.ListBuffer import scala.compat.Platform.EOL import scala.reflect.makro.runtime.{Context => MacroContext} import scala.reflect.runtime.Mirror +import util.Statistics._ /** * Code to deal with macros, namely with: @@ -1002,159 +1003,165 @@ trait Macros { self: Analyzer => delayed += expandee -> (typer.context, undetparams) Delay(expandee) } else { - val macroDef = expandee.symbol - macroRuntime(macroDef) match { - case Some(runtime) => - val savedInfolevel = nodePrinters.infolevel - try { - // InfoLevel.Verbose examines and prints out infos of symbols - // by the means of this'es these symbols can climb up the lexical scope - // when these symbols will be examined by a node printer - // they will enumerate and analyze their children (ask for infos and tpes) - // if one of those children involves macro expansion, things might get nasty - // that's why I'm temporarily turning this behavior off - nodePrinters.infolevel = nodePrinters.InfoLevel.Quiet - val args = macroArgs(typer, expandee) - args match { - case Some(args) => - // adding stuff to openMacros is easy, but removing it is a nightmare - // it needs to be sprinkled over several different code locations - val (context: MacroContext) :: _ = args - openMacros = context :: openMacros - val expanded: MacroExpansionResult = try { - val prevNumErrors = reporter.ERROR.count - val expanded = runtime(args) - val currNumErrors = reporter.ERROR.count - if (currNumErrors != prevNumErrors) { - fail(typer, expandee) // errors have been reported by the macro itself - } else { - expanded match { - case expanded: Expr[_] => - if (macroDebug || macroCopypaste) { - if (macroDebug) println("original:") - println(expanded.tree) - println(showRaw(expanded.tree)) - } - - freeTerms(expanded.tree) foreach (fte => typer.context.error(expandee.pos, - ("macro expansion contains free term variable %s %s. "+ - "have you forgot to use eval when splicing this variable into a reifee? " + - "if you have troubles tracking free term variables, consider using -Xlog-free-terms").format(fte.name, fte.origin))) - freeTypes(expanded.tree) foreach (fty => typer.context.error(expandee.pos, - ("macro expansion contains free type variable %s %s. "+ - "have you forgot to use c.TypeTag annotation for this type parameter? " + - "if you have troubles tracking free type variables, consider using -Xlog-free-types").format(fty.name, fty.origin))) - - val currNumErrors = reporter.ERROR.count - if (currNumErrors != prevNumErrors) { - fail(typer, expandee) - } else { - // inherit the position from the first position-ful expandee in macro callstack - // this is essential for sane error messages - var tree = expanded.tree - var position = openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition) - tree = atPos(position.focus)(tree) - - // now macro expansion gets typechecked against the macro definition return type - // however, this happens in macroExpand, not here in macroExpand1 - Success(tree) - } - case expanded if expanded.isInstanceOf[Expr[_]] => - val msg = "macro must return a compiler-specific expr; returned value is Expr, but it doesn't belong to this compiler's universe" - fail(typer, expandee, msg) - case expanded => - val msg = "macro must return a compiler-specific expr; returned value is of class: %s".format(expanded.getClass) - fail(typer, expandee, msg) + val start = startTimer(macroExpandNanos) + incCounter(macroExpandCount) + try { + val macroDef = expandee.symbol + macroRuntime(macroDef) match { + case Some(runtime) => + val savedInfolevel = nodePrinters.infolevel + try { + // InfoLevel.Verbose examines and prints out infos of symbols + // by the means of this'es these symbols can climb up the lexical scope + // when these symbols will be examined by a node printer + // they will enumerate and analyze their children (ask for infos and tpes) + // if one of those children involves macro expansion, things might get nasty + // that's why I'm temporarily turning this behavior off + nodePrinters.infolevel = nodePrinters.InfoLevel.Quiet + val args = macroArgs(typer, expandee) + args match { + case Some(args) => + // adding stuff to openMacros is easy, but removing it is a nightmare + // it needs to be sprinkled over several different code locations + val (context: MacroContext) :: _ = args + openMacros = context :: openMacros + val expanded: MacroExpansionResult = try { + val prevNumErrors = reporter.ERROR.count + val expanded = runtime(args) + val currNumErrors = reporter.ERROR.count + if (currNumErrors != prevNumErrors) { + fail(typer, expandee) // errors have been reported by the macro itself + } else { + expanded match { + case expanded: Expr[_] => + if (macroDebug || macroCopypaste) { + if (macroDebug) println("original:") + println(expanded.tree) + println(showRaw(expanded.tree)) + } + + freeTerms(expanded.tree) foreach (fte => typer.context.error(expandee.pos, + ("macro expansion contains free term variable %s %s. "+ + "have you forgot to use eval when splicing this variable into a reifee? " + + "if you have troubles tracking free term variables, consider using -Xlog-free-terms").format(fte.name, fte.origin))) + freeTypes(expanded.tree) foreach (fty => typer.context.error(expandee.pos, + ("macro expansion contains free type variable %s %s. "+ + "have you forgot to use c.TypeTag annotation for this type parameter? " + + "if you have troubles tracking free type variables, consider using -Xlog-free-types").format(fty.name, fty.origin))) + + val currNumErrors = reporter.ERROR.count + if (currNumErrors != prevNumErrors) { + fail(typer, expandee) + } else { + // inherit the position from the first position-ful expandee in macro callstack + // this is essential for sane error messages + var tree = expanded.tree + var position = openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition) + tree = atPos(position.focus)(tree) + + // now macro expansion gets typechecked against the macro definition return type + // however, this happens in macroExpand, not here in macroExpand1 + Success(tree) + } + case expanded if expanded.isInstanceOf[Expr[_]] => + val msg = "macro must return a compiler-specific expr; returned value is Expr, but it doesn't belong to this compiler's universe" + fail(typer, expandee, msg) + case expanded => + val msg = "macro must return a compiler-specific expr; returned value is of class: %s".format(expanded.getClass) + fail(typer, expandee, msg) + } } + } catch { + case ex: Throwable => + openMacros = openMacros.tail + throw ex } - } catch { - case ex: Throwable => - openMacros = openMacros.tail - throw ex + if (!expanded.isInstanceOf[Success]) openMacros = openMacros.tail + expanded + case None => + fail(typer, expandee) // error has been reported by macroArgs + } + } catch { + case ex => + // [Eugene] any ideas about how to improve this one? + val realex = ReflectionUtils.unwrapThrowable(ex) + realex match { + case realex: reflect.makro.runtime.AbortMacroException => + if (macroDebug || macroCopypaste) println("macro expansion has failed: %s".format(realex.msg)) + fail(typer, expandee) // error has been reported by abort + case _ => + val message = { + try { + // the most reliable way of obtaining currently executing method + // http://stackoverflow.com/questions/442747/getting-the-name-of-the-current-executing-method + val currentMethodName = new Object(){}.getClass().getEnclosingMethod().getName + val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == currentMethodName) + if (relevancyThreshold == -1) None + else { + var relevantElements = realex.getStackTrace().take(relevancyThreshold + 1) + var framesTillReflectiveInvocationOfMacroImpl = relevantElements.reverse.indexWhere(_.isNativeMethod) + 1 + relevantElements = relevantElements dropRight framesTillReflectiveInvocationOfMacroImpl + + realex.setStackTrace(relevantElements) + val message = new java.io.StringWriter() + realex.printStackTrace(new java.io.PrintWriter(message)) + Some(EOL + message) + } + } catch { + // if the magic above goes boom, just fall back to uninformative, but better than nothing, getMessage + case ex: Throwable => + None + } + } getOrElse realex.getMessage + fail(typer, expandee, "exception during macro expansion: " + message) } - if (!expanded.isInstanceOf[Success]) openMacros = openMacros.tail - expanded - case None => - fail(typer, expandee) // error has been reported by macroArgs + } finally { + nodePrinters.infolevel = savedInfolevel + } + case None => + def notFound() = { + typer.context.error(expandee.pos, "macro implementation not found: " + macroDef.name + " " + + "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)\n" + + "if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath " + + "in the second phase pointing to the output of the first phase") + None } - } catch { - case ex => - // [Eugene] any ideas about how to improve this one? - val realex = ReflectionUtils.unwrapThrowable(ex) - realex match { - case realex: reflect.makro.runtime.AbortMacroException => - if (macroDebug || macroCopypaste) println("macro expansion has failed: %s".format(realex.msg)) - fail(typer, expandee) // error has been reported by abort + def fallBackToOverridden(tree: Tree): Option[Tree] = { + tree match { + case Select(qual, name) if (macroDef.isTermMacro) => + macroDef.allOverriddenSymbols match { + case first :: _ => + Some(Select(qual, name) setPos tree.pos setSymbol first) + case _ => + macroTrace("macro is not overridden: ")(tree) + notFound() + } + case Apply(fn, args) => + fallBackToOverridden(fn) match { + case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos) + case _ => None + } + case TypeApply(fn, args) => + fallBackToOverridden(fn) match { + case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos) + case _ => None + } case _ => - val message = { - try { - // the most reliable way of obtaining currently executing method - // http://stackoverflow.com/questions/442747/getting-the-name-of-the-current-executing-method - val currentMethodName = new Object(){}.getClass().getEnclosingMethod().getName - val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == currentMethodName) - if (relevancyThreshold == -1) None - else { - var relevantElements = realex.getStackTrace().take(relevancyThreshold + 1) - var framesTillReflectiveInvocationOfMacroImpl = relevantElements.reverse.indexWhere(_.isNativeMethod) + 1 - relevantElements = relevantElements dropRight framesTillReflectiveInvocationOfMacroImpl - - realex.setStackTrace(relevantElements) - val message = new java.io.StringWriter() - realex.printStackTrace(new java.io.PrintWriter(message)) - Some(EOL + message) - } - } catch { - // if the magic above goes boom, just fall back to uninformative, but better than nothing, getMessage - case ex: Throwable => - None - } - } getOrElse realex.getMessage - fail(typer, expandee, "exception during macro expansion: " + message) + macroTrace("unexpected tree in fallback: ")(tree) + notFound() } - } finally { - nodePrinters.infolevel = savedInfolevel - } - case None => - def notFound() = { - typer.context.error(expandee.pos, "macro implementation not found: " + macroDef.name + " " + - "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)\n" + - "if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath " + - "in the second phase pointing to the output of the first phase") - None - } - def fallBackToOverridden(tree: Tree): Option[Tree] = { - tree match { - case Select(qual, name) if (macroDef.isTermMacro) => - macroDef.allOverriddenSymbols match { - case first :: _ => - Some(Select(qual, name) setPos tree.pos setSymbol first) - case _ => - macroTrace("macro is not overridden: ")(tree) - notFound() - } - case Apply(fn, args) => - fallBackToOverridden(fn) match { - case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos) - case _ => None - } - case TypeApply(fn, args) => - fallBackToOverridden(fn) match { - case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos) - case _ => None - } - case _ => - macroTrace("unexpected tree in fallback: ")(tree) - notFound() } - } - fallBackToOverridden(expandee) match { - case Some(tree1) => - macroTrace("falling back to ")(tree1) - currentRun.macroExpansionFailed = true - Fallback(tree1) - case None => - fail(typer, expandee) - } + fallBackToOverridden(expandee) match { + case Some(tree1) => + macroTrace("falling back to ")(tree1) + currentRun.macroExpansionFailed = true + Fallback(tree1) + case None => + fail(typer, expandee) + } + } + } finally { + stopTimer(macroExpandNanos, start) } } } else { diff --git a/src/compiler/scala/tools/nsc/util/Statistics.scala b/src/compiler/scala/tools/nsc/util/Statistics.scala index d1cdd30dd8..61c7695911 100644 --- a/src/compiler/scala/tools/nsc/util/Statistics.scala +++ b/src/compiler/scala/tools/nsc/util/Statistics.scala @@ -57,6 +57,9 @@ class Statistics extends scala.reflect.internal.util.Statistics { val counter2: SubCounter = new SubCounter(subtypeCount) val timer1: Timer = new Timer val timer2: Timer = new Timer + + val macroExpandCount = new Counter + val macroExpandNanos = new Timer } object Statistics extends Statistics @@ -125,34 +128,36 @@ abstract class StatisticsInfo { inform("ms type-flow-analysis: " + analysis.timer.millis) if (phase.name == "typer") { - inform("time spent typechecking : "+showRelTyper(typerNanos)) - inform("time classfilereading : "+showRelTyper(classReadNanos)) - inform("time spent in implicits : "+showRelTyper(implicitNanos)) - inform(" successful in scope : "+showRelTyper(inscopeSucceedNanos)) - inform(" failed in scope : "+showRelTyper(inscopeFailNanos)) - inform(" successful of type : "+showRelTyper(oftypeSucceedNanos)) - inform(" failed of type : "+showRelTyper(oftypeFailNanos)) - inform(" assembling parts : "+showRelTyper(subtypeETNanos)) - inform(" matchesPT : "+showRelTyper(matchesPtNanos)) - inform("implicit cache hits : "+showRelative(implicitCacheHits.value + implicitCacheMisses.value)(implicitCacheHits.value)) - inform("time spent in failed : "+showRelTyper(failedSilentNanos)) - inform(" failed apply : "+showRelTyper(failedApplyNanos)) - inform(" failed op= : "+showRelTyper(failedOpEqNanos)) - inform("time spent ref scanning : "+showRelTyper(isReferencedNanos)) - inform("micros by tree node : "+showCounts(microsByType)) - inform("#visits by tree node : "+showCounts(visitsByType)) + inform("time spent typechecking : " + showRelTyper(typerNanos)) + inform("time classfilereading : " + showRelTyper(classReadNanos)) + inform("time spent in implicits : " + showRelTyper(implicitNanos)) + inform(" successful in scope : " + showRelTyper(inscopeSucceedNanos)) + inform(" failed in scope : " + showRelTyper(inscopeFailNanos)) + inform(" successful of type : " + showRelTyper(oftypeSucceedNanos)) + inform(" failed of type : " + showRelTyper(oftypeFailNanos)) + inform(" assembling parts : " + showRelTyper(subtypeETNanos)) + inform(" matchesPT : " + showRelTyper(matchesPtNanos)) + inform("implicit cache hits : " + showRelative(implicitCacheHits.value + implicitCacheMisses.value)(implicitCacheHits.value)) + inform("time spent in failed : " + showRelTyper(failedSilentNanos)) + inform(" failed apply : " + showRelTyper(failedApplyNanos)) + inform(" failed op= : " + showRelTyper(failedOpEqNanos)) + inform("time spent ref scanning : " + showRelTyper(isReferencedNanos)) + inform("micros by tree node : " + showCounts(microsByType)) + inform("#visits by tree node : " + showCounts(visitsByType)) val average = new ClassCounts for (c <- microsByType.keysIterator) average(c) = microsByType(c)/visitsByType(c) - inform("avg micros by tree node : "+showCounts(average)) - inform("time spent in <:< : "+showRelTyper(subtypeNanos)) - inform("time spent in findmember : "+showRelTyper(findMemberNanos)) - inform("time spent in asSeenFrom : "+showRelTyper(asSeenFromNanos)) - inform("#implicit searches : " + implicitSearchCount) + inform("avg micros by tree node : " + showCounts(average)) + inform("time spent in <:< : " + showRelTyper(subtypeNanos)) + inform("time spent in findmember : " + showRelTyper(findMemberNanos)) + inform("time spent in asSeenFrom : " + showRelTyper(asSeenFromNanos)) + inform("#implicit searches : " + implicitSearchCount) inform("#tried, plausible, matching, typed, found implicits: "+triedImplicits+", "+plausiblyCompatibleImplicits+", "+matchingImplicits+", "+typedImplicits+", "+foundImplicits) - inform("#implicit improves tests : " + improvesCount) - inform("#implicit improves cached: " + improvesCachedCount) - inform("#implicit inscope hits : " + inscopeImplicitHits) - inform("#implicit oftype hits : " + oftypeImplicitHits) + inform("#implicit improves tests : " + improvesCount) + inform("#implicit improves cached : " + improvesCachedCount) + inform("#implicit inscope hits : " + inscopeImplicitHits) + inform("#implicit oftype hits : " + oftypeImplicitHits) + inform("#macro expansions : " + macroExpandCount) + inform("#time spent in macroExpand : " + showRelTyper(macroExpandNanos)) } if (ctr1 != null) inform("#ctr1 : " + ctr1) -- cgit v1.2.3 From 355264f9d53c09182fe6f480319543dc914860d1 Mon Sep 17 00:00:00 2001 From: Vlad Ureche Date: Fri, 13 Apr 2012 11:55:35 +0200 Subject: Scaladoc feature that shows implicit conversions See https://github.com/VladUreche/scala/tree/feature/doc-implicits for the history. See https://scala-webapps.epfl.ch/jenkins/view/scaladoc/job/scaladoc-implicits-nightly/ for nightlies. Many thanks fly out to Adriaan for his help with implicit search! --- build.xml | 140 +++--- src/compiler/scala/reflect/internal/Types.scala | 39 +- src/compiler/scala/tools/ant/Scaladoc.scala | 70 ++- src/compiler/scala/tools/nsc/ast/DocComments.scala | 8 +- src/compiler/scala/tools/nsc/doc/DocFactory.scala | 6 +- src/compiler/scala/tools/nsc/doc/Settings.scala | 127 +++++- .../scala/tools/nsc/doc/Uncompilable.scala | 4 +- .../scala/tools/nsc/doc/html/HtmlFactory.scala | 3 + .../scala/tools/nsc/doc/html/HtmlPage.scala | 12 +- .../scala/tools/nsc/doc/html/page/Template.scala | 156 +++++-- .../nsc/doc/html/resource/lib/conversionbg.gif | Bin 0 -> 167 bytes .../doc/html/resource/lib/selected-implicits.png | Bin 0 -> 1150 bytes .../html/resource/lib/selected-right-implicits.png | Bin 0 -> 646 bytes .../tools/nsc/doc/html/resource/lib/template.css | 101 ++++- .../tools/nsc/doc/html/resource/lib/template.js | 104 +++-- .../scala/tools/nsc/doc/model/Entity.scala | 107 +++++ .../scala/tools/nsc/doc/model/ModelFactory.scala | 99 ++-- .../doc/model/ModelFactoryImplicitSupport.scala | 501 +++++++++++++++++++++ .../scala/tools/nsc/doc/model/TreeFactory.scala | 2 +- .../scala/tools/nsc/typechecker/Implicits.scala | 47 +- .../scala/tools/nsc/typechecker/Infer.scala | 2 +- src/library/scala/Array.scala | 13 + src/library/scala/Option.scala | 11 + src/library/scala/Tuple2.scala | 12 +- src/library/scala/Tuple3.scala | 13 +- .../scala/tools/partest/ScaladocModelTest.scala | 78 ++-- test/scaladoc/resources/implicits-base-res.scala | 143 ++++++ .../resources/implicits-chaining-res.scala | 48 ++ .../resources/implicits-elimination-res.scala | 9 + test/scaladoc/resources/implicits-scopes-res.scala | 51 +++ test/scaladoc/run/SI-5373.check | 2 +- test/scaladoc/run/SI-5373.scala | 6 +- test/scaladoc/run/implicits-base.check | 1 + test/scaladoc/run/implicits-base.scala | 179 ++++++++ test/scaladoc/run/implicits-chaining.check | 1 + test/scaladoc/run/implicits-chaining.scala | 64 +++ test/scaladoc/run/implicits-elimination.check | 1 + test/scaladoc/run/implicits-elimination.scala | 22 + test/scaladoc/run/implicits-scopes.check | 1 + test/scaladoc/run/implicits-scopes.scala | 76 ++++ test/scaladoc/scalacheck/CommentFactoryTest.scala | 5 +- 41 files changed, 2001 insertions(+), 263 deletions(-) create mode 100644 src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif create mode 100644 src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png create mode 100644 src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png create mode 100644 src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala create mode 100644 test/scaladoc/resources/implicits-base-res.scala create mode 100644 test/scaladoc/resources/implicits-chaining-res.scala create mode 100644 test/scaladoc/resources/implicits-elimination-res.scala create mode 100644 test/scaladoc/resources/implicits-scopes-res.scala create mode 100644 test/scaladoc/run/implicits-base.check create mode 100644 test/scaladoc/run/implicits-base.scala create mode 100644 test/scaladoc/run/implicits-chaining.check create mode 100644 test/scaladoc/run/implicits-chaining.scala create mode 100644 test/scaladoc/run/implicits-elimination.check create mode 100644 test/scaladoc/run/implicits-elimination.scala create mode 100644 test/scaladoc/run/implicits-scopes.check create mode 100644 test/scaladoc/run/implicits-scopes.scala diff --git a/build.xml b/build.xml index 51fffd79d0..1a0e85a6f0 100644 --- a/build.xml +++ b/build.xml @@ -8,10 +8,10 @@ SuperSabbus for Scala core, builds the scala library and compiler. It can also p - + - + @@ -34,20 +34,20 @@ END-USER TARGETS - + - + - + - + @@ -67,7 +67,7 @@ END-USER TARGETS - + @@ -81,7 +81,7 @@ END-USER TARGETS - + @@ -103,7 +103,7 @@ END-USER TARGETS - + @@ -144,7 +144,7 @@ END-USER TARGETS description="Requires forkjoin library to be rebuilt. Add this target before any other if class file format is incompatible."> - + @@ -159,7 +159,7 @@ PROPERTIES - + @@ -281,7 +281,7 @@ INITIALISATION - + @@ -337,7 +337,7 @@ INITIALISATION - + @@ -387,7 +387,7 @@ INITIALISATION - + - + @@ -660,7 +660,7 @@ QUICK BUILD (QUICK) classpath="${build-quick.dir}/classes/library" includes="**/*.java" target="1.5" source="1.5"> - + - + - + @@ -838,7 +838,7 @@ QUICK BUILD (QUICK) - + @@ -863,7 +863,7 @@ QUICK BUILD (QUICK) - + @@ -898,7 +898,7 @@ QUICK BUILD (QUICK) - + @@ -993,7 +993,7 @@ QUICK BUILD (QUICK) - + @@ -1009,9 +1009,9 @@ QUICK BUILD (QUICK) - + - + - + - + - + - + - + - + - + - + @@ -1194,9 +1194,9 @@ PACKED QUICK BUILD (PACK) - + - + @@ -1281,7 +1281,7 @@ BOOTSTRAPPING BUILD (STRAP) - + @@ -1375,7 +1375,7 @@ BOOTSTRAPPING BUILD (STRAP) - + - + - + @@ -1477,9 +1477,9 @@ BOOTSTRAPPING BUILD (STRAP) - + - + @@ -1495,7 +1495,7 @@ LIBRARIES (MSIL, FJBG maybe later) - + - + - + - + @@ -1530,7 +1530,7 @@ LIBRARIES (MSIL, FJBG maybe later) - + - + - + - + @@ -1575,7 +1575,7 @@ LIBRARIES (MSIL, FJBG maybe later) - + - + - + @@ -1602,7 +1602,7 @@ LIBRARIES (MSIL, FJBG maybe later) - + @@ -1610,7 +1610,7 @@ LIBRARIES (MSIL, FJBG maybe later) - + @@ -1640,7 +1640,7 @@ DOCUMENTATION - + @@ -1659,13 +1659,14 @@ DOCUMENTATION destdir="${build-docs.dir}/library" doctitle="Scala Standard Library API (Scaladoc)" docversion="${version.number}" - docfooter="epfl" + docfooter="epfl" docsourceurl="${scaladoc.url}€{FILE_PATH}.scala#L1" docUncompilable="${src.dir}/library-aux" sourcepath="${src.dir}" classpathref="pack.classpath" addparams="${scalac.args.all}" - docRootContent="${src.dir}/library/rootdoc.txt"> + docRootContent="${src.dir}/library/rootdoc.txt" + implicits="on" diagrams="on"> @@ -1746,7 +1747,8 @@ DOCUMENTATION classpathref="pack.classpath" srcdir="${src.dir}/compiler" docRootContent="${src.dir}/compiler/rootdoc.txt" - addparams="${scalac.args.all}"> + addparams="${scalac.args.all}" + implicits="on" diagrams="on"> @@ -1767,7 +1769,8 @@ DOCUMENTATION sourcepath="${src.dir}" classpathref="pack.classpath" srcdir="${src.dir}/jline/src/main/java" - addparams="${scalac.args.all}"> + addparams="${scalac.args.all}" + implicits="on" diagrams="on"> @@ -1790,7 +1793,8 @@ DOCUMENTATION sourcepath="${src.dir}" classpathref="pack.classpath" srcdir="${src.dir}/scalap" - addparams="${scalac.args.all}"> + addparams="${scalac.args.all}" + implicits="on" diagrams="on"> @@ -1811,7 +1815,8 @@ DOCUMENTATION sourcepath="${src.dir}" classpathref="pack.classpath" srcdir="${src.dir}/partest" - addparams="${scalac.args.all}"> + addparams="${scalac.args.all}" + implicits="on" diagrams="on"> @@ -1832,7 +1837,8 @@ DOCUMENTATION sourcepath="${src.dir}" classpathref="pack.classpath" srcdir="${src.dir}/continuations/plugin" - addparams="${scalac.args.all}"> + addparams="${scalac.args.all}" + implicits="on" diagrams="on"> @@ -1864,7 +1870,7 @@ BOOTRAPING TEST AND TEST SUITE - + @@ -2155,7 +2161,7 @@ STABLE REFERENCE (STARR) - + @@ -2170,7 +2176,7 @@ FORWARDED TARGETS FOR PACKAGING - + diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 73a8f5c55c..8bb1d5e2fa 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -917,8 +917,8 @@ trait Types extends api.Types { self: SymbolTable => /** A test whether a type contains any unification type variables. */ def isGround: Boolean = this match { - case TypeVar(_, constr) => - constr.instValid && constr.inst.isGround + case tv@TypeVar(_, _) => + tv.untouchable || (tv.instValid && tv.constr.inst.isGround) case TypeRef(pre, sym, args) => sym.isPackageClass || pre.isGround && (args forall (_.isGround)) case SingleType(pre, sym) => @@ -2677,14 +2677,15 @@ trait Types extends api.Types { self: SymbolTable => def unapply(tv: TypeVar): Some[(Type, TypeConstraint)] = Some((tv.origin, tv.constr)) def apply(origin: Type, constr: TypeConstraint): TypeVar = apply(origin, constr, Nil, Nil) def apply(tparam: Symbol): TypeVar = apply(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams) + def apply(tparam: Symbol, untouchable: Boolean): TypeVar = apply(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams, untouchable) /** This is the only place TypeVars should be instantiated. */ - def apply(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol]): TypeVar = { + def apply(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol], untouchable: Boolean = false): TypeVar = { val tv = ( - if (args.isEmpty && params.isEmpty) new TypeVar(origin, constr) - else if (args.size == params.size) new AppliedTypeVar(origin, constr, params zip args) - else if (args.isEmpty) new HKTypeVar(origin, constr, params) + if (args.isEmpty && params.isEmpty) new TypeVar(origin, constr, untouchable) + else if (args.size == params.size) new AppliedTypeVar(origin, constr, untouchable, params zip args) + else if (args.isEmpty) new HKTypeVar(origin, constr, untouchable, params) else throw new Error("Invalid TypeVar construction: " + ((origin, constr, args, params))) ) @@ -2712,8 +2713,9 @@ trait Types extends api.Types { self: SymbolTable => class HKTypeVar( _origin: Type, _constr: TypeConstraint, + _untouchable: Boolean, override val params: List[Symbol] - ) extends TypeVar(_origin, _constr) { + ) extends TypeVar(_origin, _constr, _untouchable) { require(params.nonEmpty, this) override def isHigherKinded = true @@ -2725,8 +2727,9 @@ trait Types extends api.Types { self: SymbolTable => class AppliedTypeVar( _origin: Type, _constr: TypeConstraint, + _untouchable: Boolean, zippedArgs: List[(Symbol, Type)] - ) extends TypeVar(_origin, _constr) { + ) extends TypeVar(_origin, _constr, _untouchable) { require(zippedArgs.nonEmpty, this) @@ -2749,7 +2752,8 @@ trait Types extends api.Types { self: SymbolTable => */ class TypeVar( val origin: Type, - val constr0: TypeConstraint + val constr0: TypeConstraint, + val untouchable: Boolean = false // by other typevars ) extends Type { override def params: List[Symbol] = Nil override def typeArgs: List[Type] = Nil @@ -2931,14 +2935,15 @@ trait Types extends api.Types { self: SymbolTable => // would be pointless. In this case, each check we perform causes us to lose specificity: in // the end the best we'll do is the least specific type we tested against, since the typevar // does not see these checks as "probes" but as requirements to fulfill. - // TODO: the `suspended` flag can be used to poke around with leaving a trace + // TODO: can the `suspended` flag be used to poke around without leaving a trace? // // So the strategy used here is to test first the type, then the direct parents, and finally // to fall back on the individual base types. This warrants eventual re-examination. // AM: I think we could use the `suspended` flag to avoid side-effecting during unification - if (suspended) // constraint accumulation is disabled + if (tp.isInstanceOf[TypeVar] && untouchable && !tp.asInstanceOf[TypeVar].untouchable) tp.asInstanceOf[TypeVar].registerBound(this, !isLowerBound, isNumericBound) + else if (suspended) // constraint accumulation is disabled checkSubtype(tp, origin) else if (constr.instValid) // type var is already set checkSubtype(tp, constr.inst) @@ -2962,7 +2967,8 @@ trait Types extends api.Types { self: SymbolTable => if(typeVarLHS) constr.inst =:= tp else tp =:= constr.inst - if (suspended) tp =:= origin + if (tp.isInstanceOf[TypeVar] && untouchable && !tp.asInstanceOf[TypeVar].untouchable) tp.asInstanceOf[TypeVar].registerTypeEquality(this, !typeVarLHS) + else if (suspended) tp =:= origin else if (constr.instValid) checkIsSameType(tp) else isRelatable(tp) && { val newInst = wildcardToTypeVarMap(tp) @@ -3036,7 +3042,7 @@ trait Types extends api.Types { self: SymbolTable => override def safeToString = ( if ((constr eq null) || (constr.inst eq null)) "TVar<" + originName + "=null>" else if (constr.inst ne NoType) "" + constr.inst - else "?" + levelString + originName + else (if(untouchable) "!?" else "?") + levelString + originName ) override def kind = "TypeVar" @@ -4733,7 +4739,7 @@ trait Types extends api.Types { self: SymbolTable => val sym1 = adaptToNewRun(sym.owner.thisType, sym) if (sym1 == sym) tp else ThisType(sym1) } catch { - case ex: MissingTypeControl => + case ex: MissingTypeControl => tp } case SingleType(pre, sym) => @@ -6044,8 +6050,9 @@ trait Types extends api.Types { self: SymbolTable => def stripType(tp: Type) = tp match { case ExistentialType(_, res) => res - case TypeVar(_, constr) => - if (constr.instValid) constr.inst + case tv@TypeVar(_, constr) => + if (tv.instValid) constr.inst + else if (tv.untouchable) tv else abort("trying to do lub/glb of typevar "+tp) case t => t } diff --git a/src/compiler/scala/tools/ant/Scaladoc.scala b/src/compiler/scala/tools/ant/Scaladoc.scala index c92474b33e..daa08ef8a7 100644 --- a/src/compiler/scala/tools/ant/Scaladoc.scala +++ b/src/compiler/scala/tools/ant/Scaladoc.scala @@ -75,6 +75,11 @@ class Scaladoc extends ScalaMatchingTask { */ object Flag extends PermissibleValue { val values = List("yes", "no", "on", "off") + def getBooleanValue(value: String, flagName: String): Boolean = + if (Flag.isPermissible(value)) + return ("yes".equals(value) || "on".equals(value)) + else + buildError("Unknown " + flagName + " flag '" + value + "'") } /** The directories that contain source files to compile. */ @@ -127,6 +132,25 @@ class Scaladoc extends ScalaMatchingTask { /** Instruct the ant task not to fail in the event of errors */ private var nofail: Boolean = false + /** Instruct the scaladoc tool to document implicit conversions */ + private var docImplicits: Boolean = false + + /** Instruct the scaladoc tool to document all (including impossible) implicit conversions */ + private var docImplicitsShowAll: Boolean = false + + /** Instruct the scaladoc tool to output implicits debugging information */ + private var docImplicitsDebug: Boolean = false + + /** Instruct the scaladoc tool to create diagrams */ + private var docDiagrams: Boolean = false + + /** Instruct the scaladoc tool to output diagram creation debugging information */ + private var docDiagramsDebug: Boolean = false + + /** Instruct the scaladoc tool to use the binary given to create diagrams */ + private var docDiagramsDotPath: Option[String] = None + + /*============================================================================*\ ** Properties setters ** \*============================================================================*/ @@ -361,12 +385,39 @@ class Scaladoc extends ScalaMatchingTask { * * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ - def setNoFail(input: String) { - if (Flag.isPermissible(input)) - nofail = "yes".equals(input) || "on".equals(input) - else - buildError("Unknown nofail flag '" + input + "'") - } + def setNoFail(input: String) = + nofail = Flag.getBooleanValue(input, "nofail") + + /** Set the `implicits` info attribute. + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setImplicits(input: String) = + docImplicits = Flag.getBooleanValue(input, "implicits") + + /** Set the `implicitsShowAll` info attribute to enable scaladoc to show all implicits, including those impossible to + * convert to from the default scope + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setImplicitsShowAll(input: String) = + docImplicitsShowAll = Flag.getBooleanValue(input, "implicitsShowAll") + + /** Set the `implicitsDebug` info attribute so scaladoc outputs implicit conversion debug information + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setImplicitsDebug(input: String) = + docImplicitsDebug = Flag.getBooleanValue(input, "implicitsDebug") + + /** Set the `diagrams` bit so Scaladoc adds diagrams to the documentation + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setDiagrams(input: String) = + docDiagrams = Flag.getBooleanValue(input, "diagrams") + + /** Set the `diagramsDebug` bit so Scaladoc outputs diagram building debug information + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setDiagramsDebug(input: String) = + docDiagramsDebug = Flag.getBooleanValue(input, "diagramsDebug") + + /** Set the `diagramsDotPath` attribute to the path where graphviz dot can be found (including the binary file name, + * eg: /usr/bin/dot) */ + def setDiagramsDotPath(input: String) = + docDiagramsDotPath = Some(input) /*============================================================================*\ ** Properties getters ** @@ -560,6 +611,13 @@ class Scaladoc extends ScalaMatchingTask { docSettings.deprecation.value = deprecation docSettings.unchecked.value = unchecked + docSettings.docImplicits.value = docImplicits + docSettings.docImplicitsDebug.value = docImplicitsDebug + docSettings.docImplicitsShowAll.value = docImplicitsShowAll + docSettings.docDiagrams.value = docDiagrams + docSettings.docDiagramsDebug.value = docDiagramsDebug + if(!docDiagramsDotPath.isEmpty) docSettings.docDiagramsDotPath.value = docDiagramsDotPath.get + if (!docgenerator.isEmpty) docSettings.docgenerator.value = docgenerator.get if (!docrootcontent.isEmpty) docSettings.docRootContent.value = docrootcontent.get.getAbsolutePath() log("Scaladoc params = '" + addParams + "'", Project.MSG_DEBUG) diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index ff4e2f3fb5..8e7eeed3cc 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -252,7 +252,7 @@ trait DocComments { self: Global => def replaceInheritdoc(childSection: String, parentSection: => String) = if (childSection.indexOf("@inheritdoc") == -1) childSection - else + else childSection.replaceAllLiterally("@inheritdoc", parentSection) def getParentSection(section: (Int, Int)): String = { @@ -275,9 +275,9 @@ trait DocComments { self: Global => } child.substring(section._1, section._1 + 7) match { - case param@("@param "|"@tparam"|"@throws") => + case param@("@param "|"@tparam"|"@throws") => sectionString(extractSectionParam(child, section), parentNamedParams(param.trim)) - case _ => + case _ => sectionString(extractSectionTag(child, section), parentTagMap) } } @@ -367,7 +367,7 @@ trait DocComments { self: Global => case vname => lookupVariable(vname, site) match { case Some(replacement) => replaceWith(replacement) - case None => reporter.warning(sym.pos, "Variable " + vname + " undefined in comment for " + sym) + case None => reporter.warning(sym.pos, "Variable " + vname + " undefined in comment for " + sym + " in " + site) } } } diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala index f32564f097..76a8b87ba7 100644 --- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala @@ -58,7 +58,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor case Right(sourceCode) => new compiler.Run() compileSources List(new BatchSourceFile("newSource", sourceCode)) } - + if (reporter.hasErrors) return None @@ -80,6 +80,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor val modelFactory = ( new { override val global: compiler.type = compiler } with model.ModelFactory(compiler, settings) + with model.ModelFactoryImplicitSupport with model.comment.CommentFactory with model.TreeFactory { override def templateShouldDocument(sym: compiler.Symbol) = @@ -89,7 +90,8 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor modelFactory.makeModel match { case Some(madeModel) => - println("model contains " + modelFactory.templatesCount + " documentable templates") + if (settings.reportModel) + println("model contains " + modelFactory.templatesCount + " documentable templates") Some(madeModel) case None => println("no documentable class found in compilation units") diff --git a/src/compiler/scala/tools/nsc/doc/Settings.scala b/src/compiler/scala/tools/nsc/doc/Settings.scala index 45a2ad78b4..3da87bf763 100644 --- a/src/compiler/scala/tools/nsc/doc/Settings.scala +++ b/src/compiler/scala/tools/nsc/doc/Settings.scala @@ -87,6 +87,38 @@ class Settings(error: String => Unit) extends scala.tools.nsc.Settings(error) { "" ) + val docImplicits = BooleanSetting ( + "-implicits", + "Document members inherited by implicit conversions." + ) + + val docImplicitsDebug = BooleanSetting ( + "-implicits-debug", + "Show debugging information for members inherited by implicit conversions." + ) + + val docImplicitsShowAll = BooleanSetting ( + "-implicits-show-all", + "Show members inherited by implicit conversions that are impossible in the default scope. " + + "(for example conversions that require Numeric[String] to be in scope)" + ) + + val docDiagrams = BooleanSetting ( + "-diagrams", + "Create inheritance diagrams for classes, traits and packages." + ) + + val docDiagramsDebug = BooleanSetting ( + "-diagrams-debug", + "Show debugging information for the diagram creation process." + ) + + val docDiagramsDotPath = PathSetting ( + "-diagrams-dot-path", + "The path to the dot executable used to generate the inheritance diagrams. Ex: /usr/bin/dot", + "dot" // by default, just pick up the system-wide dot + ) + // Somewhere slightly before r18708 scaladoc stopped building unless the // self-type check was suppressed. I hijacked the slotted-for-removal-anyway // suppress-vt-warnings option and renamed it for this purpose. @@ -94,9 +126,102 @@ class Settings(error: String => Unit) extends scala.tools.nsc.Settings(error) { // For improved help output. def scaladocSpecific = Set[Settings#Setting]( - docformat, doctitle, docfooter, docversion, docUncompilable, docsourceurl, docgenerator + docformat, doctitle, docfooter, docversion, docUncompilable, docsourceurl, docgenerator, docRootContent, useStupidTypes, + docDiagrams, docDiagramsDebug, docDiagramsDotPath, + docImplicits, docImplicitsDebug, docImplicitsShowAll ) val isScaladocSpecific: String => Boolean = scaladocSpecific map (_.name) override def isScaladoc = true + + // unset by the testsuite, we don't need to count the entities in the model + var reportModel = true + + /** + * This is the hardcoded area of Scaladoc. This is where "undesirable" stuff gets eliminated. I know it's not pretty, + * but ultimately scaladoc has to be useful. :) + */ + object hardcoded { + + /** The common context bounds and some humanly explanations. Feel free to add more explanations + * `.scala.package.Numeric` is the type class + * `tparam` is the name of the type parameter it gets (this only describes type classes with 1 type param) + * the function result should be a humanly-understandable description of the type class + */ + val knownTypeClasses: Map[String, String => String] = Map() + + (".scala.package.Numeric" -> ((tparam: String) => tparam + " is a numeric class, such as Int, Long, Float or Double")) + + (".scala.package.Integral" -> ((tparam: String) => tparam + " is an integral numeric class, such as Int or Long")) + + (".scala.package.Fractional" -> ((tparam: String) => tparam + " is a fractional numeric class, such as Float or Double")) + + (".scala.reflect.Manifest" -> ((tparam: String) => tparam + " is accompanied by a Manifest, which is a runtime representation of its type that survives erasure")) + + (".scala.reflect.ClassManifest" -> ((tparam: String) => tparam + " is accompanied by a ClassManifest, which is a runtime representation of its type that survives erasure")) + + (".scala.reflect.OptManifest" -> ((tparam: String) => tparam + " is accompanied by an OptManifest, which can be either a runtime representation of its type or the NoManifest, which means the runtime type is not available")) + + /** + * Set of classes to exclude from index and diagrams + * TODO: Should be configurable + */ + def isExcluded(qname: String) = { + ( ( qname.startsWith("scala.Tuple") || qname.startsWith("scala.Product") || + qname.startsWith("scala.Function") || qname.startsWith("scala.runtime.AbstractFunction") + ) && !( + qname == "scala.Tuple1" || qname == "scala.Tuple2" || + qname == "scala.Product" || qname == "scala.Product1" || qname == "scala.Product2" || + qname == "scala.Function" || qname == "scala.Function1" || qname == "scala.Function2" || + qname == "scala.runtime.AbstractFunction0" || qname == "scala.runtime.AbstractFunction1" || + qname == "scala.runtime.AbstractFunction2" + ) + ) + } + + /** Common conversion targets that affect any class in Scala */ + val commonConversionTargets = List( + "scala.Predef.any2stringfmt", + "scala.Predef.any2stringadd", + "scala.Predef.any2ArrowAssoc", + "scala.Predef.any2Ensuring") + + /** There's a reason all these are specialized by hand but documenting each of them is beyond the point */ + val arraySkipConversions = List( + "scala.Predef.refArrayOps", + "scala.Predef.intArrayOps", + "scala.Predef.doubleArrayOps", + "scala.Predef.longArrayOps", + "scala.Predef.floatArrayOps", + "scala.Predef.charArrayOps", + "scala.Predef.byteArrayOps", + "scala.Predef.shortArrayOps", + "scala.Predef.booleanArrayOps", + "scala.Predef.unitArrayOps", + "scala.LowPriorityImplicits.wrapRefArray", + "scala.LowPriorityImplicits.wrapIntArray", + "scala.LowPriorityImplicits.wrapDoubleArray", + "scala.LowPriorityImplicits.wrapLongArray", + "scala.LowPriorityImplicits.wrapFloatArray", + "scala.LowPriorityImplicits.wrapCharArray", + "scala.LowPriorityImplicits.wrapByteArray", + "scala.LowPriorityImplicits.wrapShortArray", + "scala.LowPriorityImplicits.wrapBooleanArray", + "scala.LowPriorityImplicits.wrapUnitArray", + "scala.LowPriorityImplicits.genericWrapArray") + + // included as names as here we don't have access to a Global with Definitions :( + def valueClassList = List("unit", "boolean", "byte", "short", "char", "int", "long", "float", "double") + def valueClassFilterPrefixes = List("scala.LowPriorityImplicits", "scala.Predef") + + /** Dirty, dirty, dirty hack: the value params conversions can all kick in -- and they are disambiguated by priority + * but showing priority in scaladoc would make no sense -- so we have to manually remove the conversions that we + * know will never get a chance to kick in. Anyway, DIRTY DIRTY DIRTY! */ + def valueClassFilter(value: String, conversionName: String): Boolean = { + val valueName = value.toLowerCase + val otherValues = valueClassList.filterNot(_ == valueName) + + for (prefix <- valueClassFilterPrefixes) + if (conversionName.startsWith(prefix)) + for (otherValue <- otherValues) + if (conversionName.startsWith(prefix + "." + otherValue)) + return false + + true + } + } } diff --git a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala b/src/compiler/scala/tools/nsc/doc/Uncompilable.scala index 9b29ebd745..dbeca46c25 100644 --- a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala +++ b/src/compiler/scala/tools/nsc/doc/Uncompilable.scala @@ -14,7 +14,7 @@ trait Uncompilable { val settings: Settings import global.{ reporter, inform, warning, newTypeName, newTermName, Symbol, Name, DocComment, NoSymbol } - import global.definitions.RootClass + import global.definitions.{ RootClass, AnyRefClass } private implicit def translateName(name: Global#Name) = if (name.isTypeName) newTypeName("" + name) else newTermName("" + name) @@ -32,7 +32,7 @@ trait Uncompilable { } def files = settings.uncompilableFiles def symbols = pairs map (_._1) - def templates = symbols filter (x => x.isClass || x.isTrait) toSet + def templates = symbols filter (x => x.isClass || x.isTrait || x == AnyRefClass/* which is now a type alias */) toSet def comments = { if (settings.debug.value || settings.verbose.value) inform("Found %d uncompilable files: %s".format(files.size, files mkString ", ")) diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala index 0116e02e0e..914824d523 100644 --- a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala @@ -71,6 +71,7 @@ class HtmlFactory(val universe: doc.Universe, index: doc.Index) { "signaturebg.gif", "signaturebg2.gif", "typebg.gif", + "conversionbg.gif", "valuemembersbg.gif", "navigation-li-a.png", @@ -80,6 +81,8 @@ class HtmlFactory(val universe: doc.Universe, index: doc.Index) { "selected.png", "selected2-right.png", "selected2.png", + "selected-right-implicits.png", + "selected-implicits.png", "unselected.png" ) diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala index 1544dafc69..e3da8bddea 100644 --- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala +++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala @@ -23,7 +23,7 @@ abstract class HtmlPage extends Page { thisPage => protected def title: String /** The page description */ - protected def description: String = + protected def description: String = // unless overwritten, will display the title in a spaced format, keeping - and . title.replaceAll("[^a-zA-Z0-9\\.\\-]+", " ").replaceAll("\\-+", " - ").replaceAll(" +", " ") @@ -164,15 +164,15 @@ abstract class HtmlPage extends Page { thisPage => } /** Returns the HTML code that represents the template in `tpl` as a hyperlinked name. */ - def templateToHtml(tpl: TemplateEntity) = tpl match { + def templateToHtml(tpl: TemplateEntity, name: String = null) = tpl match { case dTpl: DocTemplateEntity => if (hasPage(dTpl)) { - { dTpl.name } + { if (name eq null) dTpl.name else name } } else { - xml.Text(dTpl.name) + xml.Text(if (name eq null) dTpl.name else name) } case ndTpl: NoDocTemplate => - xml.Text(ndTpl.name) + xml.Text(if (name eq null) ndTpl.name else name) } /** Returns the HTML code that represents the templates in `tpls` as a list of hyperlinked names. */ @@ -192,6 +192,6 @@ abstract class HtmlPage extends Page { thisPage => else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && ety.companion.get.isTrait) "object_to_trait_big.png" else if (ety.isObject) "object_big.png" else if (ety.isPackage) "package_big.png" - else "class_big.png" // FIXME: an entity *should* fall into one of the above categories, but AnyRef is somehow not + else "class_big.png" // FIXME: an entity *should* fall into one of the above categories, but AnyRef is somehow not } diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala index f059b5c0cb..680957c64c 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -88,21 +88,42 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage

- { if (tpl.linearizationTemplates.isEmpty) NodeSeq.Empty else + { if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) NodeSeq.Empty else
Ordering
  1. Alphabetic
  2. By inheritance
} - { if (tpl.linearizationTemplates.isEmpty) NodeSeq.Empty else -
- Inherited -
  1. Hide All
  2. -
  3. Show all
-
    { - (tpl :: tpl.linearizationTemplates) map { wte =>
  1. { wte.name }
  2. } - }
-
+ { if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) NodeSeq.Empty else + { + if (!tpl.linearization.isEmpty) +
+ Inherited
+
+
    + { (tpl :: tpl.linearizationTemplates).map(wte =>
  1. { wte.name }
  2. ) } +
+
+ else NodeSeq.Empty + } ++ { + if (!tpl.conversions.isEmpty) +
+ Implicitly
+
+
    + { tpl.conversions.map(conv =>
  1. { "by " + conv.conversionShortName }
  2. ) } +
+
+ else NodeSeq.Empty + } ++ +
+ +
    +
  1. Hide All
  2. +
  3. Show all
  4. +
+ Learn more about member selection +
} {
@@ -152,23 +173,25 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
{ + // linearization NodeSeq fromSeq (for ((superTpl, superType) <- (tpl.linearizationTemplates zip tpl.linearizationTypes)) yield

Inherited from { - if (tpl.universe.settings.useStupidTypes.value) - superTpl match { - case dtpl: DocTemplateEntity => - val sig = signature(dtpl, false, true) \ "_" - sig - case tpl: TemplateEntity => - tpl.name - } - else - typeToHtml(superType, true) + typeToHtmlWithStupidTypes(tpl, superTpl, superType) }

) } + { + // implicitly inherited + NodeSeq fromSeq (for (conversion <- (tpl.conversions)) yield +
+

Inherited by implicit conversion { conversion.conversionShortName } from + { typeToHtml(tpl.resultType, true) } to { typeToHtml(conversion.targetType, true) } +

+
+ ) + }
@@ -219,11 +242,12 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage case d:MemberEntity with Def => defParamsToString(d) case _ => "" } + val memberComment = memberToCommentHtml(mbr, false)
  • + data-isabs={ mbr.isAbstract.toString } fullComment={ if(memberComment.isEmpty) "no" else "yes" }> { signature(mbr, false) } - { memberToCommentHtml(mbr, false) } + { memberComment }
  • } @@ -275,6 +299,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage

    { inlineToHtml(mbr.comment.get.short) }

    def memberToCommentBodyHtml(mbr: MemberEntity, isSelf: Boolean, isReduced: Boolean = false): NodeSeq = { + val memberComment = if (mbr.comment.isEmpty) NodeSeq.Empty else
    { commentToHtml(mbr.comment) }
    @@ -326,6 +351,45 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage } } + val implicitInformation = mbr.byConversion match { + case Some(conv) => +
    Implicit information
    ++ + { + val targetType = typeToHtml(conv.targetType, true) + val conversionMethod = conv.convertorMethod match { + case Left(member) => Text(member.name) + case Right(name) => Text(name) + } + + // strip off the package object endings, they make things harder to follow + val conversionOwnerQualifiedNane = conv.convertorOwner.qualifiedName.stripSuffix(".package") + val conversionOwner = templateToHtml(conv.convertorOwner, conversionOwnerQualifiedNane) + + val constraintText = conv.constraints match { + case Nil => + NodeSeq.Empty + case List(constraint) => + xml.Text("This conversion will take place only if ") ++ constraintToHtml(constraint) ++ xml.Text(".") + case List(constraint1, constraint2) => + xml.Text("This conversion will take place only if ") ++ constraintToHtml(constraint1) ++ + xml.Text(" and at the same time ") ++ constraintToHtml(constraint2) ++ xml.Text(".") + case constraints => +
    ++ "This conversion will take place only if all of the following constraints are met:" ++
    ++ { + var index = 0 + constraints map { constraint => xml.Text({ index += 1; index } + ". ") ++ constraintToHtml(constraint) ++
    } + } + } + +
    + This member is added by an implicit conversion from { typeToHtml(mbr.inTemplate.resultType, true) } to + { targetType } performed by method { conversionMethod } in { conversionOwner }. + { constraintText } +
    + } + case _ => + NodeSeq.Empty + } + // --- start attributes block vals val attributes: Seq[scala.xml.Node] = { val fvs: List[comment.Paragraph] = visibility(mbr).toList @@ -354,7 +418,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
    case _ => NodeSeq.Empty } - } + } val selfType: Seq[scala.xml.Node] = mbr match { case dtpl: DocTemplateEntity if (isSelf && !dtpl.selfType.isEmpty && !isReduced) => @@ -477,7 +541,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage } // end attributes block vals --- - val attributesInfo = attributes ++ definitionClasses ++ fullSignature ++ selfType ++ annotations ++ deprecation ++ migration ++ sourceLink ++ mainComment + val attributesInfo = implicitInformation ++ attributes ++ definitionClasses ++ fullSignature ++ selfType ++ annotations ++ deprecation ++ migration ++ sourceLink ++ mainComment val attributesBlock = if (attributesInfo.isEmpty) NodeSeq.Empty @@ -561,12 +625,13 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage { + val nameClass = if (mbr.byConversion.isDefined) "implicit" else "name" val nameHtml = { val value = if (mbr.isConstructor) tpl.name else mbr.name val span = if (mbr.deprecation.isDefined) - { value } + { value } else - { value } + { value } val encoded = scala.reflect.NameTransformer.encode(value) if (encoded != value) { span % new UnprefixedAttribute("title", @@ -765,4 +830,43 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage case _ => inl.toString } + private def typeToHtmlWithStupidTypes(tpl: TemplateEntity, superTpl: TemplateEntity, superType: TypeEntity): NodeSeq = + if (tpl.universe.settings.useStupidTypes.value) + superTpl match { + case dtpl: DocTemplateEntity => + val sig = signature(dtpl, false, true) \ "_" + sig + case tpl: TemplateEntity => + Text(tpl.name) + } + else + typeToHtml(superType, true) + + private def constraintToHtml(constraint: Constraint): NodeSeq = constraint match { + case ktcc: KnownTypeClassConstraint => + xml.Text(ktcc.typeExplanation(ktcc.typeParamName) + " (" + ktcc.typeParamName + ": ") ++ + templateToHtml(ktcc.typeClassEntity) ++ xml.Text(")") + case tcc: TypeClassConstraint => + xml.Text(tcc.typeParamName + " is ") ++ + + context-bounded ++ xml.Text(" by " + tcc.typeClassEntity.qualifiedName + " (" + tcc.typeParamName + ": ") ++ + templateToHtml(tcc.typeClassEntity) ++ xml.Text(")") + case impl: ImplicitInScopeConstraint => + xml.Text("an implicit value of type ") ++ typeToHtml(impl.implicitType, true) ++ xml.Text(" is in scope") + case eq: EqualTypeParamConstraint => + xml.Text(eq.typeParamName + " is " + eq.rhs.name + " (" + eq.typeParamName + " =:= ") ++ + typeToHtml(eq.rhs, true) ++ xml.Text(")") + case bt: BoundedTypeParamConstraint => + xml.Text(bt.typeParamName + " is a superclass of " + bt.lowerBound.name + " and a subclass of " + + bt.upperBound.name + " (" + bt.typeParamName + " >: ") ++ + typeToHtml(bt.lowerBound, true) ++ xml.Text(" <: ") ++ + typeToHtml(bt.upperBound, true) ++ xml.Text(")") + case lb: LowerBoundedTypeParamConstraint => + xml.Text(lb.typeParamName + " is a superclass of " + lb.lowerBound.name + " (" + lb.typeParamName + " >: ") ++ + typeToHtml(lb.lowerBound, true) ++ xml.Text(")") + case ub: UpperBoundedTypeParamConstraint => + xml.Text(ub.typeParamName + " is a subclass of " + ub.upperBound.name + " (" + ub.typeParamName + " <: ") ++ + typeToHtml(ub.upperBound, true) ++ xml.Text(")") + } + } diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif b/src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif new file mode 100644 index 0000000000..4be145d0af Binary files /dev/null and b/src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif differ diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png b/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png new file mode 100644 index 0000000000..bc29efb3e6 Binary files /dev/null and b/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png differ diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png b/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png new file mode 100644 index 0000000000..8313f4975b Binary files /dev/null and b/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png differ diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css index 6fb83c133e..5a1779bba5 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css +++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css @@ -106,7 +106,7 @@ a[href]:hover { font-size: 24pt; text-shadow: black 0px 2px 0px; /* text-shadow: black 0px 0px 0px;*/ -text-decoration: none; +text-decoration: none; } #definition #owner { @@ -162,7 +162,7 @@ text-decoration: none; padding-left: 15px; background: url("arrow-right.png") no-repeat 0 3px transparent; } - + .toggleContainer.open .toggle { background: url("arrow-down.png") no-repeat 0 3px transparent; } @@ -205,6 +205,11 @@ dl.attributes > dt { font-style: italic; } +dl.attributes > dt.implicit { + font-weight: bold; + color: darkgreen; +} + dl.attributes > dd { display: block; padding-left: 10em; @@ -241,6 +246,17 @@ dl.attributes > dd { color: white; } +#inheritedMembers > div.conversion > h3 { + background: #dadada url("conversionbg.gif") repeat-x bottom left; /* gray */ + height: 17px; + font-style: italic; + font-size: 12pt; +} + +#inheritedMembers > div.conversion > h3 * { + color: white; +} + /* Member cells */ div.members > ol { @@ -310,10 +326,21 @@ div.members > ol > li:last-child { font-weight: bold; } -.signature .symbol .params .implicit { +.signature .symbol > .implicit { + display: inline-block; + font-weight: bold; + text-decoration: underline; + color: darkgreen; +} + +.signature .symbol .params > .implicit { font-style: italic; } +.signature .symbol .implicit.deprecated { + text-decoration: line-through; +} + .signature .symbol .name.deprecated { text-decoration: line-through; } @@ -369,15 +396,15 @@ div.members > ol > li:last-child { .cmt {} .cmt p { - margin: 0.7em 0; + margin: 0.7em 0; } .cmt p:first-child { - margin-top: 0; + margin-top: 0; } .cmt p:last-child { - margin-bottom: 0; + margin-bottom: 0; } .cmt h3, @@ -539,7 +566,7 @@ div.fullcommenttop .block { margin-bottom: 5px } -div.fullcomment div.block ol li p, +div.fullcomment div.block ol li p, div.fullcomment div.block ol li { display:inline } @@ -583,10 +610,10 @@ div.fullcomment dl.paramcmts > dd { /* Members filter tool */ #textfilter { - position: relative; - display: block; + position: relative; + display: block; height: 20px; - margin-bottom: 5px; + margin-bottom: 5px; } #textfilter > .pre { @@ -600,7 +627,7 @@ div.fullcomment dl.paramcmts > dd { } #textfilter > .input { - display: block; + display: block; position: absolute; top: 0; right: 20px; @@ -608,10 +635,10 @@ div.fullcomment dl.paramcmts > dd { } #textfilter > .input > input { - height: 20px; - padding: 1px; - font-weight: bold; - color: #000000; + height: 20px; + padding: 1px; + font-weight: bold; + color: #000000; background: #ffffff url("filterboxbarbg.png") repeat-x top left; width: 100%; } @@ -660,6 +687,13 @@ div.fullcomment dl.paramcmts > dd { display: inline-block; } +#mbrsel > div > a { + position:relative; + top: -8px; + font-size: 11px; + text-shadow: #ffffff 0 1px 0; +} + #mbrsel > div > ol#linearization { display: table; margin-left: 70px; @@ -683,9 +717,32 @@ div.fullcomment dl.paramcmts > dd { text-shadow: #ffffff 0 1px 0; } +#mbrsel > div > ol#implicits { + display: table; + margin-left: 70px; +} + +#mbrsel > div > ol#implicits > li.in { + text-decoration: none; + float: left; + padding-right: 10px; + margin-right: 5px; + background: url(selected-right-implicits.png) no-repeat; + background-position: right 0px; +} + +#mbrsel > div > ol#implicits > li.in > span{ + color: #404040; + float: left; + padding: 1px 0 1px 10px; + background: url(selected-implicits.png) no-repeat; + background-position: 0px 0px; + text-shadow: #ffffff 0 1px 0; +} + #mbrsel > div > ol > li { /* padding: 3px 10px;*/ - line-height: 16pt; + line-height: 16pt; display: inline-block; cursor: pointer; } @@ -709,10 +766,10 @@ div.fullcomment dl.paramcmts > dd { } #mbrsel > div > ol > li.out { - text-decoration: none; - float: left; - padding-right: 10px; - margin-right: 5px; + text-decoration: none; + float: left; + padding-right: 10px; + margin-right: 5px; } #mbrsel > div > ol > li.out > span{ @@ -739,10 +796,10 @@ div.fullcomment dl.paramcmts > dd { #mbrsel .showall { color: #4C4C4C; line-height: 16px; - font-weight: bold; + font-weight: bold; } #mbrsel .showall span { color: #4C4C4C; - font-weight: bold; + font-weight: bold; }*/ \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js index 3cdd9a7f27..fd5a981cb0 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js +++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js @@ -2,21 +2,23 @@ // code by Gilles Dubochet with contributions by Pedro Furlanetto $(document).ready(function(){ - var isHiddenClass; - if (document.title == 'scala.AnyRef') { - isHiddenClass = function (name) { - return name == 'scala.Any'; - }; - } else { - isHiddenClass = function (name) { - return name == 'scala.Any' || name == 'scala.AnyRef'; - }; - } + var isHiddenClass = function (name) { + return name == 'scala.Any' || + name == 'scala.AnyRef' || + name == 'scala.Predef.any2stringfmt' || + name == 'scala.Predef.any2stringadd' || + name == 'scala.Predef.any2ArrowAssoc' || + name == 'scala.Predef.any2Ensuring' + }; + + $("#linearization li:gt(0)").filter(function(){ + return isHiddenClass($(this).attr("name")); + }).removeClass("in").addClass("out"); - $("#linearization li").filter(function(){ + $("#implicits li").filter(function(){ return isHiddenClass($(this).attr("name")); }).removeClass("in").addClass("out"); - + // Pre-filter members filter(); @@ -54,17 +56,38 @@ $(document).ready(function(){ }; filter(); }); - $("#ancestors > ol > li.hideall").click(function() { + + $("#implicits li").click(function(){ + if ($(this).hasClass("in")) { + $(this).removeClass("in"); + $(this).addClass("out"); + } + else if ($(this).hasClass("out")) { + $(this).removeClass("out"); + $(this).addClass("in"); + }; + filter(); + }); + + $("#mbrsel > div[id=ancestors] > ol > li.hideall").click(function() { $("#linearization li.in").removeClass("in").addClass("out"); $("#linearization li:first").removeClass("out").addClass("in"); + $("#implicits li.in").removeClass("in").addClass("out"); filter(); }) - $("#ancestors > ol > li.showall").click(function() { - var filtered = + $("#mbrsel > div[id=ancestors] > ol > li.showall").click(function() { + var filteredLinearization = $("#linearization li.out").filter(function() { return ! isHiddenClass($(this).attr("name")); }); - filtered.removeClass("out").addClass("in"); + filteredLinearization.removeClass("out").addClass("in"); + + var filteredImplicits = + $("#implicits li.out").filter(function() { + return ! isHiddenClass($(this).attr("name")); + }); + filteredImplicits.removeClass("out").addClass("in"); + filter(); }); $("#visbl > ol > li.public").click(function() { @@ -108,8 +131,10 @@ $(document).ready(function(){ }); /* Add toggle arrows */ - var docAllSigs = $("#template li").has(".fullcomment").find(".signature"); - + //var docAllSigs = $("#template li").has(".fullcomment").find(".signature"); + // trying to speed things up a little bit + var docAllSigs = $("#template li[fullComment=yes] .signature"); + function commentToggleFct(signature){ var parent = signature.parent(); var shortComment = $(".shortcomment", parent); @@ -129,7 +154,7 @@ $(document).ready(function(){ docAllSigs.click(function() { commentToggleFct($(this)); }); - + /* Linear super types and known subclasses */ function toggleShowContentFct(outerElement){ var content = $(".hiddenContent", outerElement); @@ -148,20 +173,22 @@ $(document).ready(function(){ $(".toggleContainer").click(function() { toggleShowContentFct($(this)); }); - + // Set parent window title windowTitle(); }); function orderAlpha() { $("#template > div.parent").hide(); - $("#ancestors").show(); + $("#template > div.conversion").hide(); + $("#mbrsel > div[id=ancestors]").show(); filter(); }; function orderInherit() { $("#template > div.parent").show(); - $("#ancestors").hide(); + $("#template > div.conversion").show(); + $("#mbrsel > div[id=ancestors]").hide(); filter(); }; @@ -177,6 +204,9 @@ function initInherit() { $("#inheritedMembers > div.parent").each(function(){ parents[$(this).attr("name")] = $(this); }); + $("#inheritedMembers > div.conversion").each(function(){ + parents[$(this).attr("name")] = $(this); + }); $("#types > ol > li").each(function(){ var mbr = $(this); this.mbrText = mbr.find("> .fullcomment .cmt").text(); @@ -216,6 +246,9 @@ function initInherit() { $("#inheritedMembers > div.parent").each(function() { if ($("> div.members", this).length == 0) { $(this).remove(); }; }); + $("#inheritedMembers > div.conversion").each(function() { + if ($("> div.members", this).length == 0) { $(this).remove(); }; + }); }; function filter(scrollToMember) { @@ -224,13 +257,17 @@ function filter(scrollToMember) { var queryRegExp = new RegExp(query, "i"); var privateMembersHidden = $("#visbl > ol > li.public").hasClass("in"); var orderingAlphabetic = $("#order > ol > li.alpha").hasClass("in"); - var hiddenSuperclassElements = orderingAlphabetic ? $("#linearization > li.out") : $("#linearization > li:gt(0)"); - var hiddenSuperclasses = hiddenSuperclassElements.map(function() { + var hiddenSuperclassElementsLinearization = orderingAlphabetic ? $("#linearization > li.out") : $("#linearization > li:gt(0)"); + var hiddenSuperclassesLinearization = hiddenSuperclassElementsLinearization.map(function() { + return $(this).attr("name"); + }).get(); + var hiddenSuperclassElementsImplicits = orderingAlphabetic ? $("#implicits > li.out") : $("#implicits > li"); + var hiddenSuperclassesImplicits = hiddenSuperclassElementsImplicits.map(function() { return $(this).attr("name"); }).get(); var hideInheritedMembers; - + if(orderingAlphabetic) { $("#inheritedMembers").hide(); hideInheritedMembers = true; @@ -242,9 +279,10 @@ function filter(scrollToMember) { $("#allMembers > .members").each(filterFunc); hideInheritedMembers = false; $("#inheritedMembers > .parent > .members").each(filterFunc); + $("#inheritedMembers > .conversion > .members").each(filterFunc); } - + function filterFunc() { var membersVisible = false; var members = $(this); @@ -262,12 +300,18 @@ function filter(scrollToMember) { ownerIndex = name.lastIndexOf("."); } var owner = name.slice(0, ownerIndex); - for (var i = 0; i < hiddenSuperclasses.length; i++) { - if (hiddenSuperclasses[i] == owner) { + for (var i = 0; i < hiddenSuperclassesLinearization.length; i++) { + if (hiddenSuperclassesLinearization[i] == owner) { mbr.hide(); return; } - } + }; + for (var i = 0; i < hiddenSuperclassesImplicits.length; i++) { + if (hiddenSuperclassesImplicits[i] == owner) { + mbr.hide(); + return; + } + }; } if (query && !(queryRegExp.test(name) || queryRegExp.test(this.mbrText))) { mbr.hide(); @@ -276,7 +320,7 @@ function filter(scrollToMember) { mbr.show(); membersVisible = true; }); - + if (membersVisible) members.show(); else diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/compiler/scala/tools/nsc/doc/model/Entity.scala index 6eb14a4907..6488847049 100644 --- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala +++ b/src/compiler/scala/tools/nsc/doc/model/Entity.scala @@ -167,6 +167,8 @@ trait MemberEntity extends Entity { /** Whether this member is abstract. */ def isAbstract: Boolean + /** If this member originates from an implicit conversion, we set the implicit information to the correct origin */ + def byConversion: Option[ImplicitConversion] } object MemberEntity { // Oh contravariance, contravariance, wherefore art thou contravariance? @@ -246,6 +248,8 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity { * other entity of the pair is the companion. */ def companion: Option[DocTemplateEntity] + /** The implicit conversions this template (class or trait, objects and packages are not affected) */ + def conversions: List[ImplicitConversion] } @@ -413,3 +417,106 @@ trait Annotation extends Entity { def arguments: List[ValueArgument] } + +/** A trait that signals the member results from an implicit conversion */ +trait ImplicitConversion { + + /** The source of the implicit conversion*/ + def source: DocTemplateEntity + + /** The result type after the conversion */ + def targetType: TypeEntity + + /** The entity for the method that performed the conversion, if it's documented (or just its name, otherwise) */ + def convertorMethod: Either[MemberEntity, String] + + /** A short name of the convertion */ + def conversionShortName: String + + /** A qualified name uniquely identifying the convertion (currently: the conversion method's qualified name) */ + def conversionQualifiedName: String + + /** The entity that performed the conversion */ + def convertorOwner: TemplateEntity + + /** The constraints that the transformations puts on the type parameters */ + def constraints: List[Constraint] + + /** The members inherited by this implicit conversion */ + def members: List[MemberEntity] +} + +/** A trait that encapsulates a constraint necessary for implicit conversion */ +trait Constraint { + // /** The implicit conversion during which this constraint appears */ + // def conversion: ImplicitConversion +} + +/** A constraint involving a type parameter which must be in scope */ +trait ImplicitInScopeConstraint extends Constraint { + /** The type of the implicit value required */ + def implicitType: TypeEntity + + /** toString for debugging */ + override def toString = "an implicit _: " + implicitType.name + " must be in scope" +} + +trait TypeClassConstraint extends ImplicitInScopeConstraint with TypeParamConstraint { + /** Type class name */ + def typeClassEntity: TemplateEntity + + /** toString for debugging */ + override def toString = typeParamName + " is a class of type " + typeClassEntity.qualifiedName + " (" + + typeParamName + ": " + typeClassEntity.name + ")" +} + +trait KnownTypeClassConstraint extends TypeClassConstraint { + /** Type explanation, takes the type parameter name and generates the explanation */ + def typeExplanation: (String) => String + + /** toString for debugging */ + override def toString = typeExplanation(typeParamName) + " (" + typeParamName + ": " + typeClassEntity.name + ")" +} + +/** A constraint involving a type parameter */ +trait TypeParamConstraint extends Constraint { + /** The type parameter involved */ + def typeParamName: String +} + +trait EqualTypeParamConstraint extends TypeParamConstraint { + /** The rhs */ + def rhs: TypeEntity + /** toString for debugging */ + override def toString = typeParamName + " is " + rhs.name + " (" + typeParamName + " =:= " + rhs.name + ")" +} + +trait BoundedTypeParamConstraint extends TypeParamConstraint { + /** The lower bound */ + def lowerBound: TypeEntity + + /** The upper bound */ + def upperBound: TypeEntity + + /** toString for debugging */ + override def toString = typeParamName + " is a superclass of " + lowerBound.name + " and a subclass of " + + upperBound.name + " (" + typeParamName + " >: " + lowerBound.name + " <: " + upperBound.name + ")" +} + +trait LowerBoundedTypeParamConstraint extends TypeParamConstraint { + /** The lower bound */ + def lowerBound: TypeEntity + + /** toString for debugging */ + override def toString = typeParamName + " is a superclass of " + lowerBound.name + " (" + typeParamName + " >: " + + lowerBound.name + ")" +} + +trait UpperBoundedTypeParamConstraint extends TypeParamConstraint { + /** The lower bound */ + def upperBound: TypeEntity + + /** toString for debugging */ + override def toString = typeParamName + " is a subclass of " + upperBound.name + " (" + typeParamName + " <: " + + upperBound.name + ")" +} \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 670c9bbb3b..f295e4d211 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -17,7 +17,7 @@ import model.{ RootPackage => RootPackageEntity } /** This trait extracts all required information for documentation from compilation units */ class ModelFactory(val global: Global, val settings: doc.Settings) { - thisFactory: ModelFactory with CommentFactory with TreeFactory => + thisFactory: ModelFactory with ModelFactoryImplicitSupport with CommentFactory with TreeFactory => import global._ import definitions.{ ObjectClass, RootPackage, EmptyPackage, NothingClass, AnyClass, AnyValClass, AnyRefClass } @@ -95,7 +95,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { def isDocTemplate = false } - abstract class MemberImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity { + abstract class MemberImpl(sym: Symbol, implConv: ImplicitConversionImpl = null, inTpl: => DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity { lazy val comment = if (inTpl == null) None else thisFactory.comment(sym, inTpl) override def inTemplate = inTpl @@ -128,7 +128,14 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { if (sym.isImplicit) fgs += Paragraph(Text("implicit")) if (sym.isSealed) fgs += Paragraph(Text("sealed")) if (!sym.isTrait && (sym hasFlag Flags.ABSTRACT)) fgs += Paragraph(Text("abstract")) - if (!sym.isTrait && (sym hasFlag Flags.DEFERRED)) fgs += Paragraph(Text("abstract")) + /* Resetting the DEFERRED flag is a little trick here for refined types: (example from scala.collections) + * {{{ + * implicit def traversable2ops[T](t: collection.GenTraversableOnce[T]) = new TraversableOps[T] { + * def isParallel = ... + * }}} + * the type the method returns is TraversableOps, which has all-abstract symbols. But in reality, it couldn't have + * any abstract terms, otherwise it would fail compilation. So we reset the DEFERRED flag. */ + if (!sym.isTrait && (sym hasFlag Flags.DEFERRED) && (implConv eq null)) fgs += Paragraph(Text("abstract")) if (!sym.isModule && (sym hasFlag Flags.FINAL)) fgs += Paragraph(Text("final")) fgs.toList } @@ -162,7 +169,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { case NullaryMethodType(res) => resultTpe(res) case _ => tpe } - makeTypeInTemplateContext(resultTpe(sym.tpe), inTemplate, sym) + val tpe = if (implConv eq null) sym.tpe else implConv.toType memberInfo sym + makeTypeInTemplateContext(resultTpe(tpe), inTemplate, sym) } def isDef = false def isVal = false @@ -173,15 +181,17 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { def isAliasType = false def isAbstractType = false def isAbstract = - ((!sym.isTrait && ((sym hasFlag Flags.ABSTRACT) || (sym hasFlag Flags.DEFERRED))) || + // for the explanation of implConv == null see comment on flags + ((!sym.isTrait && ((sym hasFlag Flags.ABSTRACT) || (sym hasFlag Flags.DEFERRED)) && (implConv == null)) || sym.isAbstractClass || sym.isAbstractType) && !sym.isSynthetic def isTemplate = false + def byConversion = if (implConv ne null) Some(implConv) else None } /** The instantiation of `TemplateImpl` triggers the creation of the following entities: * All ancestors of the template and all non-package members. */ - abstract class DocTemplateImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends MemberImpl(sym, inTpl) with TemplateImpl with HigherKindedImpl with DocTemplateEntity { + abstract class DocTemplateImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends MemberImpl(sym, null, inTpl) with TemplateImpl with HigherKindedImpl with DocTemplateEntity { //if (inTpl != null) println("mbr " + sym + " in " + (inTpl.toRoot map (_.sym)).mkString(" > ")) if (settings.verbose.value) inform("Creating doc template for " + sym) @@ -245,16 +255,20 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { } def subClasses = if (subClassesCache == null) Nil else subClassesCache.toList - protected lazy val memberSyms = + val conversions = if (settings.docImplicits.value) makeImplicitConversions(sym, this) else Nil + + lazy val memberSyms = // Only this class's constructors are part of its members, inherited constructors are not. sym.info.members.filter(s => localShouldDocument(s) && (!s.isConstructor || s.owner == sym) && !isPureBridge(sym) ) - val members = memberSyms flatMap (makeMember(_, this)) - val templates = members collect { case c: DocTemplateEntity => c } - val methods = members collect { case d: Def => d } - val values = members collect { case v: Val => v } - val abstractTypes = members collect { case t: AbstractType => t } - val aliasTypes = members collect { case t: AliasType => t } + val members = (memberSyms.flatMap(makeMember(_, null, this))) ::: + (conversions.flatMap((_.members))) // also take in the members from implicit conversions + + val templates = members collect { case c: DocTemplateEntity => c } + val methods = members collect { case d: Def => d } + val values = members collect { case v: Val => v } + val abstractTypes = members collect { case t: AbstractType => t } + val aliasTypes = members collect { case t: AliasType => t } override def isTemplate = true def isDocTemplate = true def companion = sym.companionSymbol match { @@ -273,18 +287,22 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { abstract class RootPackageImpl(sym: Symbol) extends PackageImpl(sym, null) with RootPackageEntity - abstract class NonTemplateMemberImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends MemberImpl(sym, inTpl) with NonTemplateMemberEntity { + abstract class NonTemplateMemberImpl(sym: Symbol, implConv: ImplicitConversionImpl, inTpl: => DocTemplateImpl) extends MemberImpl(sym, implConv, inTpl) with NonTemplateMemberEntity { override def qualifiedName = optimize(inTemplate.qualifiedName + "#" + name) - lazy val definitionName = optimize(inDefinitionTemplates.head.qualifiedName + "#" + name) + lazy val definitionName = + if (implConv == null) optimize(inDefinitionTemplates.head.qualifiedName + "#" + name) + else optimize(implConv.conversionQualifiedName + "#" + name) def isUseCase = sym.isSynthetic def isBridge = sym.isBridge } - abstract class NonTemplateParamMemberImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends NonTemplateMemberImpl(sym, inTpl) { - def valueParams = - sym.paramss map { ps => (ps.zipWithIndex) map { case (p, i) => + abstract class NonTemplateParamMemberImpl(sym: Symbol, implConv: ImplicitConversionImpl, inTpl: => DocTemplateImpl) extends NonTemplateMemberImpl(sym, implConv, inTpl) { + def valueParams = { + val info = if (implConv eq null) sym.info else implConv.toType memberInfo sym + info.paramss map { ps => (ps.zipWithIndex) map { case (p, i) => if (p.nameString contains "$") makeValueParam(p, inTpl, optimize("arg" + i)) else makeValueParam(p, inTpl) }} + } } abstract class ParameterImpl(sym: Symbol, inTpl: => TemplateImpl) extends EntityImpl(sym, inTpl) with ParameterEntity { @@ -356,7 +374,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { override def qualifiedName = "_root_" override def inheritedFrom = Nil override def isRootPackage = true - override protected lazy val memberSyms = + override lazy val memberSyms = (bSym.info.members ++ EmptyPackage.info.members) filter { s => s != EmptyPackage && s != RootPackage } @@ -454,18 +472,19 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { } /** */ - def makeMember(aSym: Symbol, inTpl: => DocTemplateImpl): List[MemberImpl] = { + // TODO: Should be able to override the type + def makeMember(aSym: Symbol, implConv: ImplicitConversionImpl, inTpl: => DocTemplateImpl): List[MemberImpl] = { def makeMember0(bSym: Symbol, _useCaseOf: Option[MemberImpl]): Option[MemberImpl] = { if (bSym.isGetter && bSym.isLazy) - Some(new NonTemplateMemberImpl(bSym, inTpl) with Val { + Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with Val { override lazy val comment = // The analyser does not duplicate the lazy val's DocDef when it introduces its accessor. thisFactory.comment(bSym.accessed, inTpl) // This hack should be removed after analyser is fixed. override def isLazyVal = true override def useCaseOf = _useCaseOf }) else if (bSym.isGetter && bSym.accessed.isMutable) - Some(new NonTemplateMemberImpl(bSym, inTpl) with Val { + Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with Val { override def isVar = true override def useCaseOf = _useCaseOf }) @@ -481,36 +500,36 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { } else bSym } - Some(new NonTemplateParamMemberImpl(cSym, inTpl) with HigherKindedImpl with Def { + Some(new NonTemplateParamMemberImpl(cSym, implConv, inTpl) with HigherKindedImpl with Def { override def isDef = true override def useCaseOf = _useCaseOf }) } - else if (bSym.isConstructor) - Some(new NonTemplateParamMemberImpl(bSym, inTpl) with Constructor { + else if (bSym.isConstructor && (implConv == null)) + Some(new NonTemplateParamMemberImpl(bSym, implConv, inTpl) with Constructor { override def isConstructor = true def isPrimary = sym.isPrimaryConstructor override def useCaseOf = _useCaseOf }) else if (bSym.isGetter) // Scala field accessor or Java field - Some(new NonTemplateMemberImpl(bSym, inTpl) with Val { + Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with Val { override def isVal = true override def useCaseOf = _useCaseOf }) else if (bSym.isAbstractType) - Some(new NonTemplateMemberImpl(bSym, inTpl) with TypeBoundsImpl with HigherKindedImpl with AbstractType { + Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with TypeBoundsImpl with HigherKindedImpl with AbstractType { override def isAbstractType = true override def useCaseOf = _useCaseOf }) - else if (bSym.isAliasType) - Some(new NonTemplateMemberImpl(bSym, inTpl) with HigherKindedImpl with AliasType { + else if (bSym.isAliasType && bSym != AnyRefClass) + Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with HigherKindedImpl with AliasType { override def isAliasType = true def alias = makeTypeInTemplateContext(sym.tpe.dealias, inTpl, sym) override def useCaseOf = _useCaseOf }) else if (bSym.isPackage) inTpl match { case inPkg: PackageImpl => makePackage(bSym, inPkg) } - else if ((bSym.isClass || bSym.isModule) && templateShouldDocument(bSym)) + else if ((bSym.isClass || bSym.isModule || bSym == AnyRefClass) && templateShouldDocument(bSym)) Some(makeDocTemplate(bSym, inTpl)) else None @@ -520,16 +539,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { Nil else { val allSyms = useCases(aSym, inTpl.sym) map { case (bSym, bComment, bPos) => - docComments.put(bSym, DocComment(bComment, bPos)) // put the comment in the list, don't parse it yet, closes SI-4898 + docComments.put(bSym, DocComment(bComment, bPos)) // put the comment in the list, don't parse it yet, closes SI-4898 bSym } val member = makeMember0(aSym, None) - if (allSyms.isEmpty) - member.toList - else - // Use cases replace the original definitions - SI-5054 - allSyms flatMap { makeMember0(_, member) } + if (allSyms.isEmpty) + member.toList + else + // Use cases replace the original definitions - SI-5054 + allSyms flatMap { makeMember0(_, member) } } } @@ -639,9 +658,9 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { // nameBuffer append stripPrefixes.foldLeft(pre.prefixString)(_ stripPrefix _) // } val bSym = normalizeTemplate(aSym) - if (bSym.isNonClassType) + if (bSym.isNonClassType) { nameBuffer append bSym.decodedName - else { + } else { val tpl = makeTemplate(bSym) val pos0 = nameBuffer.length refBuffer += pos0 -> (tpl, tpl.name.length) @@ -692,8 +711,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { } def templateShouldDocument(aSym: Symbol): Boolean = { - // TODO: document sourceless entities (e.g., Any, etc), based on a new Setting to be added - (aSym.isPackageClass || (aSym.sourceFile != null)) && localShouldDocument(aSym) && + // TODO: document sourceless entities (e.g., Any, etc), based on a new Setting to be added + (aSym.isPackageClass || (aSym.sourceFile != null)) && localShouldDocument(aSym) && ( aSym.owner == NoSymbol || templateShouldDocument(aSym.owner) ) && !isEmptyJavaObject(aSym) } diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala new file mode 100644 index 0000000000..23bef02bed --- /dev/null +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -0,0 +1,501 @@ +/* NSC -- new Scala compiler -- Copyright 2007-2012 LAMP/EPFL + * + * This trait finds implicit conversions for a class in the default scope and creates scaladoc entries for each of them. + * + * @author Vlad Ureche + * @author Adriaan Moors + */ + +package scala.tools.nsc +package doc +package model + +import comment._ + +import scala.collection._ +import scala.util.matching.Regex + +import symtab.Flags +import io._ + +import model.{ RootPackage => RootPackageEntity } + +/** + * This trait finds implicit conversions for a class in the default scope and creates scaladoc entries for each of them. + * + * Let's take this as an example: + * {{{ + * object Test { + * class A + * + * class B { + * def foo = 1 + * } + * + * class C extends B { + * def bar = 2 + * class implicit + * } + * + * D def conv(a: A) = new C + * } + * }}} + * + * Overview: + * - scaladoc-ing the above classes, `A` will get two more methods: foo and bar, over its default methods + * - the nested classes (specifically `D` above), abstract types, type aliases and constructor members are not added to + * `A` (see makeMember0 in ModelFactory, last 3 cases) + * - the members added by implicit conversion are always listed under the implicit conversion, not under the class they + * actually come from (`foo` will be listed as coming from the implicit conversion to `C` instead of `B`) - see + * `definitionName` in MemberImpl + * + * Internals: + * TODO: Give an overview here + */ +trait ModelFactoryImplicitSupport { + thisFactory: ModelFactory with CommentFactory with TreeFactory => + + import global._ + import global.analyzer._ + import global.definitions._ + import settings.hardcoded + + // debugging: + val DEBUG: Boolean = settings.docImplicitsDebug.value + val ERROR: Boolean = true // currently we show all errors + @inline final def debug(msg: => String) = if (DEBUG) println(msg) + @inline final def error(msg: => String) = if (ERROR) println(msg) + + /** This is a flag that indicates whether to eliminate implicits that cannot be satisfied within the current scope. + * For example, if an implicit conversion requires that there is a Numeric[T] in scope: + * {{{ + * class A[T] + * class B extends A[Int] + * class C extends A[String] + * implicit def pimpA[T: Numeric](a: A[T]): D + * }}} + * For B, no constraints are generated as Numeric[Int] is already in the default scope. On the other hand, for the + * conversion from C to D, depending on -implicits-show-all, the conversion can: + * - not be generated at all, since there's no Numeric[String] in scope (if ran without -implicits-show-all) + * - generated with a *weird* constraint, Numeric[String] as the user might add it by hand (if flag is enabled) + */ + val implicitsShowAll: Boolean = settings.docImplicitsShowAll.value + class ImplicitNotFound(tpe: Type) extends Exception("No implicit of type " + tpe + " found in scope.") + + /* ============== IMPLEMENTATION PROVIDING ENTITY TYPES ============== */ + + class ImplicitConversionImpl( + val sym: Symbol, + val convSym: Symbol, + val toType: Type, + val constrs: List[Constraint], + inTpl: => DocTemplateImpl) + extends ImplicitConversion { + + def source: DocTemplateEntity = inTpl + + def targetType: TypeEntity = makeType(toType, inTpl) + + def convertorOwner: TemplateEntity = + if (convSym != NoSymbol) + makeTemplate(convSym.owner) + else { + error("Scaladoc implicits: Implicit conversion from " + sym.tpe + " to " + toType + " done by " + convSym + " = NoSymbol!") + makeRootPackage.get // surely the root package was created :) + } + + def convertorMethod: Either[MemberEntity, String] = { + var convertor: MemberEntity = null + + convertorOwner match { + case doc: DocTemplateImpl => + val convertors = members.collect { case m: MemberImpl if m.sym == convSym => m } + if (convertors.length == 1) + convertor = convertors.head + case _ => + } + if (convertor ne null) + Left(convertor) + else + Right(convSym.nameString) + } + + def conversionShortName = convSym.nameString + + def conversionQualifiedName = convertorOwner.qualifiedName + "." + convSym.nameString + + lazy val constraints: List[Constraint] = constrs + + val members: List[MemberEntity] = { + // Obtain the members inherited by the implicit conversion + var memberSyms = toType.members.filter(implicitShouldDocument(_)) + val existingMembers = sym.info.members + + // Debugging part :) + debug(sym.nameString + "\n" + "=" * sym.nameString.length()) + debug(" * conversion " + convSym + " from " + sym.tpe + " to " + toType) + + // Members inherited by implicit conversions cannot override actual members + memberSyms = memberSyms.filterNot((sym1: Symbol) => + existingMembers.exists(sym2 => sym1.name == sym2.name && + isSameType(toType.memberInfo(sym1), sym.info.memberInfo(sym2)))) + + debug(" -> full type: " + toType) + if (constraints.length != 0) { + debug(" -> constraints: ") + constraints foreach { constr => debug(" - " + constr) } + } + debug(" -> members:") + memberSyms foreach (sym => debug(" - "+ sym.decodedName +" : " + sym.info)) + debug("") + + memberSyms.flatMap((makeMember(_, this, inTpl))) + } + } + + /* ============== MAKER METHODS ============== */ + + /** + * Make the implicit conversion objects + * + * A word about the scope of the implicit conversions: currently we look at a very basic context composed of the + * default Scala imports (Predef._ for example) and the companion object of the current class, if one exists. In the + * future we might want to extend this to more complex scopes. + */ + def makeImplicitConversions(sym: Symbol, inTpl: => DocTemplateImpl): List[ImplicitConversion] = + // Nothing and Null are somewhat special -- they can be transformed by any implicit conversion available in scope. + // But we don't want that, so we'll simply refuse to find implicit conversions on for Nothing and Null + if (!(sym.isClass || sym.isTrait || sym == AnyRefClass) || sym == NothingClass || sym == NullClass) Nil + else { + var context: global.analyzer.Context = global.analyzer.rootContext(NoCompilationUnit) + + val results = global.analyzer.allViewsFrom(sym.tpe, context, sym.typeParams) + var conversions = results.flatMap(result => makeImplicitConversion(sym, result._1, result._2, context, inTpl)) + conversions = conversions.filterNot(_.members.isEmpty) + + // Filter out specialized conversions from array + if (sym == ArrayClass) + conversions = conversions.filterNot((conv: ImplicitConversion) => + hardcoded.arraySkipConversions.contains(conv.conversionQualifiedName)) + + // Filter out non-sensical conversions from value types + if (isScalaValueType(sym.tpe)) + conversions = conversions.filter((ic: ImplicitConversion) => + hardcoded.valueClassFilter(sym.nameString, ic.conversionQualifiedName)) + + // Put the class-specific conversions in front + val (ownConversions, commonConversions) = + conversions.partition(conv => !hardcoded.commonConversionTargets.contains(conv.conversionQualifiedName)) + + ownConversions ::: commonConversions + } + + /** makeImplicitConversion performs the heavier lifting to get the implicit listing: + * - for each possible conversion function (also called view) + * * figures out the final result of the view (to what is our class transformed?) + * * figures out the necessary constraints on the type parameters (such as T <: Int) and the context (such as Numeric[T]) + * * lists all inherited members + * + * What? in details: + * - say we start from a class A[T1, T2, T3, T4] + * - we have an implicit function (view) in scope: + * def pimpA[T3 <: Long, T4](a: A[Int, Foo[Bar[X]], T3, T4])(implicit ev1: Manifest[T4], ev2: Numeric[T4]): PimpedA + * - A is converted to PimpedA ONLY if a couple of constraints are satisfied: + * * T1 must be equal to Int + * * T2 must be equal to Foo[Bar[X]] + * * T3 must be upper bounded by Long + * * there must be evidence of Numeric[T4] and a Mainfest[T4] within scope + * - the final type is PimpedA and A therefore inherits a couple of members from pimpedA + * + * How? + * some notes: + * - Scala's type inference will want to solve all type parameters down to actual types, but we only want constraints + * to maintain generality + * - therefore, allViewsFrom wraps type parameters into "untouchable" type variables that only gather constraints, + * but are never solved down to a type + * - these must be reverted back to the type parameters and the constraints must be extracted and simplified (this is + * done by the uniteConstraints and boundedTParamsConstraints. Be sure to check them out + * - we also need to transform implicit parameters in the view's signature into constraints, such that Numeric[T4] + * appears as a constraint + */ + def makeImplicitConversion(sym: Symbol, result: SearchResult, constrs: List[TypeConstraint], context: Context, inTpl: => DocTemplateImpl): List[ImplicitConversion] = + if (result.tree == EmptyTree) Nil + else { + // `result` will contain the type of the view (= implicit conversion method) + // the search introduces untouchable type variables, but we want to get back to type parameters + val viewFullType = result.tree.tpe + // set the previously implicit parameters to being explicit + + val (viewSimplifiedType, viewImplicitTypes) = removeImplicitParameters(viewFullType) + + // TODO: Isolate this corner case :) - Predef.<%< and put it in the testsuite + if (viewSimplifiedType.params.length != 1) { + // This is known to be caused by the `<%<` object in Predef: + // {{{ + // sealed abstract class <%<[-From, +To] extends (From => To) with Serializable + // object <%< { + // implicit def conformsOrViewsAs[A <% B, B]: A <%< B = new (A <%< B) {def apply(x: A) = x} + // } + // }}} + // so we just won't generate an implicit conversion for implicit methods that only take implicit parameters + return Nil + } + + // type the view application so we get the exact type of the result (not the formal type) + val viewTree = result.tree.setType(viewSimplifiedType) + val appliedTree = new ApplyImplicitView(viewTree, List(Ident("") setType viewTree.tpe.paramTypes.head)) + val appliedTreeTyped: Tree = { + val newContext = context.makeImplicit(context.ambiguousErrors) + val newTyper = global.analyzer.newTyper(newContext) + newTyper.silent(_.typed(appliedTree, global.analyzer.EXPRmode, WildcardType), false) match { + + case global.analyzer.SilentResultValue(t: Tree) => t + case global.analyzer.SilentTypeError(err) => + global.reporter.warning(sym.pos, err.toString) + return Nil + } + } + + // now we have the final type: + val toType = wildcardToNothing(typeVarToOriginOrWildcard(appliedTreeTyped.tpe.finalResultType)) + + try { + // Transform bound constraints into scaladoc constraints + val implParamConstraints = makeImplicitConstraints(viewImplicitTypes, sym, context, inTpl) + val boundsConstraints = makeBoundedConstraints(sym.typeParams, constrs, inTpl) + // TODO: no substitution constraints appear in the library and compiler scaladoc. Maybe they can be removed? + val substConstraints = makeSubstitutionConstraints(result.subst, inTpl) + val constraints = implParamConstraints ::: boundsConstraints ::: substConstraints + + List(new ImplicitConversionImpl(sym, result.tree.symbol, toType, constraints, inTpl)) + } catch { + case i: ImplicitNotFound => + //println(" Eliminating: " + toType) + Nil + } + } + + def makeImplicitConstraints(types: List[Type], sym: Symbol, context: Context, inTpl: => DocTemplateImpl): List[Constraint] = + types.flatMap((tpe:Type) => { + // TODO: Before creating constraints, map typeVarToOriginOrWildcard on the implicitTypes + val implType = typeVarToOriginOrWildcard(tpe) + val qualifiedName = implType.typeSymbol.ownerChain.reverse.map(_.nameString).mkString(".") + + var available: Option[Boolean] = None + + // see: https://groups.google.com/forum/?hl=en&fromgroups#!topic/scala-internals/gm_fr0RKzC4 + // + // println(implType + " => " + implType.isTrivial) + // var tpes: List[Type] = List(implType) + // while (!tpes.isEmpty) { + // val tpe = tpes.head + // tpes = tpes.tail + // tpe match { + // case TypeRef(pre, sym, args) => + // tpes = pre :: args ::: tpes + // println(tpe + " => " + tpe.isTrivial) + // case _ => + // println(tpe + " (of type" + tpe.getClass + ") => " + tpe.isTrivial) + // } + // } + // println("\n") + + // look for type variables in the type. If there are none, we can decide if the implicit is there or not + if (implType.isTrivial) { + try { + context.flushBuffer() /* any errors here should not prevent future findings */ + // TODO: Not sure this is the right thing to do -- seems similar to what scalac should be doing + val context2 = context.make(context.unit, context.tree, sym.owner, context.scope, context.imports) + val search = inferImplicit(EmptyTree, tpe, false, false, context2, false) + context.flushBuffer() /* any errors here should not prevent future findings */ + + available = Some(search.tree != EmptyTree) + } catch { + case _ => + } + } + + available match { + case Some(true) => + Nil + case Some(false) if (!implicitsShowAll) => + // if -implicits-show-all is not set, we get rid of impossible conversions (such as Numeric[String]) + throw new ImplicitNotFound(implType) + case _ => + val typeParamNames = sym.typeParams.map(_.name) + + // TODO: This is maybe the worst hack I ever did - it's as dirty as hell, but it seems to work, so until I + // learn more about symbols, it'll have to do. + implType match { + case TypeRef(pre, sym, List(TypeRef(NoPrefix, targ, Nil))) if (typeParamNames contains targ.name) => + hardcoded.knownTypeClasses.get(qualifiedName) match { + case Some(explanation) => + List(new KnownTypeClassConstraint { + val typeParamName = targ.nameString + val typeExplanation = explanation + val typeClassEntity = makeTemplate(sym) + val implicitType: TypeEntity = makeType(implType, inTpl) + }) + case None => + List(new TypeClassConstraint { + val typeParamName = targ.nameString + val typeClassEntity = makeTemplate(sym) + val implicitType: TypeEntity = makeType(implType, inTpl) + }) + } + case _ => + List(new ImplicitInScopeConstraint{ + val implicitType: TypeEntity = makeType(implType, inTpl) + }) + } + } + }) + + def makeSubstitutionConstraints(subst: TreeTypeSubstituter, inTpl: => DocTemplateImpl): List[Constraint] = + (subst.from zip subst.to) map { + case (from, to) => + new EqualTypeParamConstraint { + error("Scaladoc implicits: Unexpected type substitution constraint from: " + from + " to: " + to) + val typeParamName = from.toString + val rhs = makeType(to, inTpl) + } + } + + def makeBoundedConstraints(tparams: List[Symbol], constrs: List[TypeConstraint], inTpl: => DocTemplateImpl): List[Constraint] = + (tparams zip constrs) flatMap { + case (tparam, constr) => { + uniteConstraints(constr) match { + case (loBounds, upBounds) => (loBounds filter (_ != NothingClass.tpe), upBounds filter (_ != AnyClass.tpe)) match { + case (Nil, Nil) => + Nil + case (List(lo), List(up)) if (lo == up) => + List(new EqualTypeParamConstraint { + val typeParamName = tparam.nameString + val rhs = makeType(lo, inTpl) + }) + case (List(lo), List(up)) => + List(new BoundedTypeParamConstraint { + val typeParamName = tparam.nameString + val lowerBound = makeType(lo, inTpl) + val upperBound = makeType(up, inTpl) + }) + case (List(lo), Nil) => + List(new LowerBoundedTypeParamConstraint { + val typeParamName = tparam.nameString + val lowerBound = makeType(lo, inTpl) + }) + case (Nil, List(up)) => + List(new UpperBoundedTypeParamConstraint { + val typeParamName = tparam.nameString + val upperBound = makeType(up, inTpl) + }) + case other => + // this is likely an error on the lub/glb side + error("Scaladoc implicits: Error computing lub/glb for: " + (tparam, constr) + ":\n" + other) + Nil + } + } + } + } + + /** + * uniteConstraints takes a TypeConstraint instance and simplifies the constraints inside + * + * Normally TypeConstraint contains multiple lower and upper bounds, and we want to reduce this to a lower and an + * upper bound. Here are a couple of catches we need to be aware of: + * - before finding a view (implicit method in scope that maps class A[T1,T2,.. Tn] to something else) the type + * parameters are transformed into "untouchable" type variables so that type inference does not attempt to + * fully solve them down to a type but rather constrains them on both sides just enough for the view to be + * applicable -- now, we want to transform those type variables back to the original type parameters + * - some of the bounds fail type inference and therefore refer to Nothing => when performing unification (lub, glb) + * they start looking ugly => we (unsoundly) transform Nothing to WildcardType so we fool the unification algorithms + * into thinking there's nothing there + * - we don't want the wildcard types surviving the unification so we replace them back to Nothings + */ + def uniteConstraints(constr: TypeConstraint): (List[Type], List[Type]) = + try { + (List(wildcardToNothing(lub(constr.loBounds map typeVarToOriginOrWildcard))), + List(wildcardToNothing(glb(constr.hiBounds map typeVarToOriginOrWildcard)))) + } catch { + // does this actually ever happen? (probably when type vars occur in the bounds) + case x: Throwable => (constr.loBounds.distinct, constr.hiBounds.distinct) + } + + /** + * Make implicits explicit - Not used curently + */ + object implicitToExplicit extends TypeMap { + def apply(tp: Type): Type = mapOver(tp) match { + case MethodType(params, resultType) => + MethodType(params.map(param => if (param.isImplicit) param.cloneSymbol.resetFlag(Flags.IMPLICIT) else param), resultType) + case other => + other + } + } + + /** + * removeImplicitParameters transforms implicit parameters from the view result type into constraints and + * returns the simplified type of the view + * + * for the example view: + * implicit def pimpMyClass[T](a: MyClass[T])(implicit ev: Numeric[T]): PimpedMyClass[T] + * the implicit view result type is: + * (a: MyClass[T])(implicit ev: Numeric[T]): PimpedMyClass[T] + * and the simplified type will be: + * MyClass[T] => PimpedMyClass[T] + */ + def removeImplicitParameters(viewType: Type): (Type, List[Type]) = { + + val params = viewType.paramss.flatten + val (normalParams, implParams) = params.partition(!_.isImplicit) + val simplifiedType = MethodType(normalParams, viewType.finalResultType) + val implicitTypes = implParams.map(_.tpe) + + (simplifiedType, implicitTypes) + } + + /** + * typeVarsToOriginOrWildcard transforms the "untouchable" type variables into either their origins (the original + * type parameters) or into wildcard types if nothing matches + */ + object typeVarToOriginOrWildcard extends TypeMap { + def apply(tp: Type): Type = mapOver(tp) match { + case tv: TypeVar => + if (tv.constr.inst.typeSymbol == NothingClass) + WildcardType + else + tv.origin //appliedType(tv.origin.typeConstructor, tv.typeArgs map this) + case other => + if (other.typeSymbol == NothingClass) + WildcardType + else + other + } + } + + /** + * wildcardToNothing transforms wildcard types back to Nothing + */ + object wildcardToNothing extends TypeMap { + def apply(tp: Type): Type = mapOver(tp) match { + case WildcardType => + NothingClass.tpe + case other => + other + } + } + + /** implicitShouldDocument decides whether a member inherited by implicit conversion should be documented */ + def implicitShouldDocument(aSym: Symbol): Boolean = { + // We shouldn't document: + // - constructors + // - common methods (in Any, AnyRef, Object) as they are automatically removed + // - private and protected members (not accessible following an implicit conversion) + // - members starting with _ (usually reserved for internal stuff) + localShouldDocument(aSym) && (!aSym.isConstructor) && (aSym.owner != ObjectClass) && + (aSym.owner != AnyClass) && (aSym.owner != AnyRefClass) && + (!aSym.isProtected) && (!aSym.isPrivate) && (!aSym.name.startsWith("_")) && + (aSym.isMethod || aSym.isGetter || aSym.isSetter) && + (aSym.nameString != "getClass") + } +} \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala b/src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala index 988f2e0ba9..f948d53c8b 100755 --- a/src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala @@ -52,7 +52,7 @@ trait TreeFactory { thisTreeFactory: ModelFactory with TreeFactory => if (asym.isSetter) asym = asym.getter(asym.owner) makeTemplate(asym.owner) match { case docTmpl: DocTemplateImpl => - val mbrs: List[MemberImpl] = makeMember(asym,docTmpl) + val mbrs: List[MemberImpl] = makeMember(asym, null, docTmpl) mbrs foreach { mbr => refs += ((start, (mbr,end))) } case _ => } diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 3a789b83b6..2de86c67bf 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -94,6 +94,27 @@ trait Implicits { result } + /** Find all views from type `tp` (in which `tpars` are free) + * + * Note that the trees in the search results in the returned list share the same type variables. + * Ignore their constr field! The list of type constraints returned along with each tree specifies the constraints that + * must be met by the corresponding type parameter in `tpars` (for the returned implicit view to be valid). + * + * @arg tp from-type for the implicit conversion + * @arg context search implicits here + * @arg tpars symbols that should be considered free type variables + * (implicit search should not try to solve them, just track their constraints) + */ + def allViewsFrom(tp: Type, context: Context, tpars: List[Symbol]): List[(SearchResult, List[TypeConstraint])] = { + // my untouchable typevars are better than yours (they can't be constrained by them) + val tvars = tpars map (TypeVar.apply(_, untouchable = true)) + val tpSubsted = tp.subst(tpars, tvars) + + val search = new ImplicitSearch(EmptyTree, functionType(List(tpSubsted), AnyClass.tpe), true, context.makeImplicit(false)) + + search.allImplicitsPoly(tvars) + } + private final val sizeLimit = 50000 private type Infos = List[ImplicitInfo] private type Infoss = List[List[ImplicitInfo]] @@ -369,7 +390,7 @@ trait Implicits { private def typedImplicit(info: ImplicitInfo, ptChecked: Boolean): SearchResult = { (context.openImplicits find { case (tp, tree1) => tree1.symbol == tree.symbol && dominates(pt, tp)}) match { case Some(pending) => - // println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams) //@MDEBUG + //println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams) //@MDEBUG throw DivergentImplicit case None => try { @@ -378,7 +399,7 @@ trait Implicits { typedImplicit0(info, ptChecked) } catch { case ex: DivergentImplicit => - // println("DivergentImplicit for pt:"+ pt +", open implicits:"+context.openImplicits) //@MDEBUG + //println("DivergentImplicit for pt:"+ pt +", open implicits:"+context.openImplicits) //@MDEBUG if (context.openImplicits.tail.isEmpty) { if (!(pt.isErroneous)) DivergingImplicitExpansionError(tree, pt, info.sym)(context) @@ -510,7 +531,7 @@ trait Implicits { private def typedImplicit0(info: ImplicitInfo, ptChecked: Boolean): SearchResult = { incCounter(plausiblyCompatibleImplicits) - printTyping( + printTyping ( ptBlock("typedImplicit0", "info.name" -> info.name, "ptChecked" -> ptChecked, @@ -1202,6 +1223,26 @@ trait Implicits { def search(iss: Infoss, isLocal: Boolean) = applicableInfos(iss, isLocal).values (search(context.implicitss, true) ++ search(implicitsOfExpectedType, false)).toList.filter(_.tree ne EmptyTree) } + + // find all implicits for some type that contains type variables + // collect the constraints that result from typing each implicit + def allImplicitsPoly(tvars: List[TypeVar]): List[(SearchResult, List[TypeConstraint])] = { + def resetTVars() = tvars foreach { _.constr = new TypeConstraint } + + def eligibleInfos(iss: Infoss, isLocal: Boolean) = new ImplicitComputation(iss, if (isLocal) util.HashSet[Name](512) else null).eligible + val allEligibleInfos = (eligibleInfos(context.implicitss, true) ++ eligibleInfos(implicitsOfExpectedType, false)).toList + + allEligibleInfos flatMap { ii => + // each ImplicitInfo contributes a distinct set of constraints (generated indirectly by typedImplicit) + // thus, start each type var off with a fresh for every typedImplicit + resetTVars() + // any previous errors should not affect us now + context.flushBuffer() + val res = typedImplicit(ii, false) + if (res.tree ne EmptyTree) List((res, tvars map (_.constr))) + else Nil + } + } } object ImplicitNotFoundMsg { diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 98b8d7673e..d2fe106b14 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -83,7 +83,7 @@ trait Infer { def apply(tp: Type): Type = tp match { case WildcardType | BoundedWildcardType(_) | NoType => throw new NoInstance("undetermined type") - case tv @ TypeVar(origin, constr) => + case tv @ TypeVar(origin, constr) if !tv.untouchable => if (constr.inst == NoType) { throw new DeferredNoInstance(() => "no unique instantiation of type variable " + origin + " could be found") diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala index 99c54ce58c..5b8ebde308 100644 --- a/src/library/scala/Array.scala +++ b/src/library/scala/Array.scala @@ -467,6 +467,19 @@ object Array extends FallbackArrayBuilding { * @version 1.0 * @see [[http://www.scala-lang.org/docu/files/collections-api/collections_38.html#anchor "The Scala 2.8 Collections' API"]] * section on `Array` by Martin Odersky for more information. + * @define coll array + * @define Coll Array + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is either `Array[B]` if a ClassManifest is available for B or `ArraySeq[B]` otherwise. + * @define zipthatinfo $thatinfo + * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current + * representation type `Repr` and the new element type `B`. */ final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable { diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala index 2d87ccb261..68ea67ca00 100644 --- a/src/library/scala/Option.scala +++ b/src/library/scala/Option.scala @@ -79,6 +79,17 @@ object Option { * @define option [[scala.Option]] * @define p `p` * @define f `f` + * @define coll option + * @define Coll Option + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + * @define thatinfo the class of the returned collection. In the standard library configuration, `That` is `Iterable[B]` + * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current + * representation type `Repr` and the new element type `B`. */ sealed abstract class Option[+A] extends Product with Serializable { self => diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index b1befca4fa..37ab564c3c 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -23,7 +23,7 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s extends Product2[T1, T2] { override def toString() = "(" + _1 + "," + _2 + ")" - + /** Swaps the elements of this `Tuple`. * @return a new Tuple where the first element is the second element of this Tuple and the * second element is the first element of this Tuple. @@ -54,6 +54,16 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]): Zipped[Repr1, El1, Repr2, El2] = new Zipped[Repr1, El1, Repr2, El2](_1, _2) + /** + * @define coll zipped + * @define Coll Zipped + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + */ class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2]) { // coll2: ILike for filter def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = { val b = cbf(coll1.repr) diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index 0d5399308b..cd5ee23757 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -24,7 +24,7 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3) extends Product3[T1, T2, T3] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + ")" - + @deprecated("Use `zipped` instead.", "2.9.0") def zip[Repr1, El1, El2, El3, To](implicit w1: T1 => TLike[El1, Repr1], @@ -53,6 +53,17 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3) w3: T3 => ILike[El3, Repr3]): Zipped[Repr1, El1, Repr2, El2, Repr3, El3] = new Zipped[Repr1, El1, Repr2, El2, Repr3, El3](_1, _2, _3) + /** + * @define coll zipped + * @define Coll Zipped + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + * @define thatInfo The class of the returned collection. + */ class Zipped[+Repr1, +El1, +Repr2, +El2, +Repr3, +El3](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2], coll3: ILike[El3, Repr3]) { diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala index 2eb026ceee..142f2baea5 100644 --- a/src/partest/scala/tools/partest/ScaladocModelTest.scala +++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala @@ -21,10 +21,10 @@ import scala.tools.nsc.reporters.ConsoleReporter import scala.tools.nsc.doc.model._ import scala.tools.partest.ScaladocModelTest - object Test extends ScaladocModelTest { + object Test extends ScaladocModelTest { - def code = """ ... """ - def scaladocSettings = "" + override def code = """ ... """ // or override def resourceFile = ".scala" (from test/scaladoc/resources) + def scaladocSettings = " ... " def testModel(rootPackage: Package) = { // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) import access._ @@ -39,10 +39,22 @@ abstract class ScaladocModelTest extends DirectTest { /** Override this to give scaladoc command line parameters */ def scaladocSettings: String - + /** Override this to test the model */ def testModel(root: Package): Unit + /** Override to feed a file in resources to scaladoc*/ + def resourceFile: String = null + + /** Override to feed code into scaladoc */ + override def code = + if (resourceFile ne null) + io.File(resourcePath + "/" + resourceFile).slurp() + else + sys.error("Scaladoc Model Test: You need to give a file or some code to feed to scaladoc!") + + def resourcePath = io.Directory(sys.props("partest.cwd") + "/../resources") + // Implementation follows: override def extraSettings: String = "-usejavacp" @@ -50,15 +62,15 @@ abstract class ScaladocModelTest extends DirectTest { // redirect err to out, for logging val prevErr = System.err System.setErr(System.out) - + try { // 1 - compile with scaladoc and get the model out - val args = scaladocSettings.split(" ") - val universe = model(args:_*).getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")}) + val universe = model.getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")}) // 2 - check the model generated testModel(universe.rootPackage) + println("Done.") } catch { - case e => + case e => println(e) e.printStackTrace } @@ -66,51 +78,46 @@ abstract class ScaladocModelTest extends DirectTest { System.setErr(prevErr) } + private[this] var settings: Settings = null + // create a new scaladoc compiler - def newDocFactory(args: String*): DocFactory = { - val settings = new Settings(_ => ()) - val command = new ScalaDoc.Command((CommandLineParser tokenize extraSettings) ++ args.toList, settings) + def newDocFactory: DocFactory = { + settings = new Settings(_ => ()) + settings.reportModel = false // yaay, no more "model contains X documentable templates"! + val args = extraSettings + " " + scaladocSettings + val command = new ScalaDoc.Command((CommandLineParser tokenize (args)), settings) val docFact = new DocFactory(new ConsoleReporter(settings), settings) docFact } // compile with scaladoc and output the result - def model(args: String*): Option[Universe] = newDocFactory(args: _*).makeUniverse(Right(code)) + def model: Option[Universe] = newDocFactory.makeUniverse(Right(code)) // so we don't get the newSettings warning - override def isDebug = false + override def isDebug = false // finally, enable easy navigation inside the entities object access { - // Make it easy to access things class TemplateAccess(tpl: DocTemplateEntity) { - def _class(name: String): DocTemplateEntity = getTheFirst(_classes(name), tpl.qualifiedName + ".class(" + name + ")") - def _classes(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).flatMap({ case c: Class => List(c)}) + def _classes(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case c: Class => c}) def _trait(name: String): DocTemplateEntity = getTheFirst(_traits(name), tpl.qualifiedName + ".trait(" + name + ")") - def _traits(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).flatMap({ case t: Trait => List(t)}) + def _traits(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case t: Trait => t}) def _object(name: String): DocTemplateEntity = getTheFirst(_objects(name), tpl.qualifiedName + ".object(" + name + ")") - def _objects(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).flatMap({ case o: Object => List(o)}) + def _objects(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case o: Object => o}) def _method(name: String): Def = getTheFirst(_methods(name), tpl.qualifiedName + ".method(" + name + ")") def _methods(name: String): List[Def] = tpl.methods.filter(_.name == name) - + def _value(name: String): Val = getTheFirst(_values(name), tpl.qualifiedName + ".value(" + name + ")") def _values(name: String): List[Val] = tpl.values.filter(_.name == name) - def getTheFirst[T](list: List[T], expl: String): T = { - if (list.length == 1) - list.head - else if (list.length == 0) - sys.error("Error getting " + expl + ": No such element. All elements in list: [" + list.mkString(", ") + "]") - else - sys.error("Error getting " + expl + ": " + list.length + " elements with this name. " + - "All elements in list: [" + list.mkString(", ") + "]") - } + def _conversion(name: String): ImplicitConversion = getTheFirst(_conversions(name), tpl.qualifiedName + ".conversion(" + name + ")") + def _conversions(name: String): List[ImplicitConversion] = tpl.conversions.filter(_.conversionQualifiedName == name) } class PackageAccess(pack: Package) extends TemplateAccess(pack) { @@ -118,7 +125,22 @@ abstract class ScaladocModelTest extends DirectTest { def _packages(name: String): List[Package] = pack.packages.filter(_.name == name) } + class MemberAccess(mbrs: WithMembers) { + def _member(name: String): MemberEntity = getTheFirst(_members(name), mbrs.toString + ".member(" + name + ")") + def _members(name: String): List[MemberEntity] = mbrs.members.filter(_.name == name) + } + + type WithMembers = { def members: List[MemberEntity]; def toString: String } /* DocTemplates and ImplicitConversions */ + implicit def templateAccess(tpl: DocTemplateEntity) = new TemplateAccess(tpl) implicit def packageAccess(pack: Package) = new PackageAccess(pack) + implicit def membersAccess(mbrs: WithMembers) = new MemberAccess(mbrs) + + def getTheFirst[T](list: List[T], expl: String): T = list.length match { + case 1 => list.head + case 0 => sys.error("Error getting " + expl + ": No such element.") + case _ => sys.error("Error getting " + expl + ": " + list.length + " elements with this name. " + + "All elements in list: [" + list.mkString(", ") + "]") + } } } diff --git a/test/scaladoc/resources/implicits-base-res.scala b/test/scaladoc/resources/implicits-base-res.scala new file mode 100644 index 0000000000..db7ca4fa51 --- /dev/null +++ b/test/scaladoc/resources/implicits-base-res.scala @@ -0,0 +1,143 @@ +/** + * Test scaladoc implicits - the bread and butter of the testsuite :) + */ +package scala.test.scaladoc.implicits.base + +class Foo[T] +class Bar[T] +trait MyNumeric[R] + +/** Class A + * - tests the complete type inference + * - the following inherited methods should appear: + * {{{ + * def convToGtColonDoubleA: Double // pimpA3: with a constraint that T <: Double + * def convToIntA: Int // pimpA2: with a constraint that T = Int + * def convToManifestA: T // pimpA7: with 2 constraints: T: Manifest and T <: Double + * def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope + * def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope + * def convToPimpedA: Bar[Foo[T]] // pimpA5: no constraints + * def convToPimpedA: S // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar + * def convToTraversableOps: T // pimpA7: with 2 constraints: T: Manifest and T <: Double + * // should not be abstract! + * }}} + */ +class A[T] { + /** This should prevent the implicitly inherited `def convToPimpedA: T` from `pimpA0` from showing up */ + def convToPimpedA: T = sys.error("Let's check it out!") +} +/** Companion object with implicit transformations */ +object A { + implicit def pimpA0[V](a: A[V]) = new PimpedA(a) + implicit def pimpA1[ZBUR: Numeric](a: A[ZBUR]) = new NumericA[ZBUR](a) + implicit def pimpA2(a: A[Int]) = new IntA(a) + implicit def pimpA3(a: A[T] forSome { type T <: Double }) = new GtColonDoubleA(a) + implicit def pimpA4[S](a: A[Foo[Bar[S]]])(implicit foo: Foo[S], bar: Bar[S]): PimpedA[S] = sys.error("not implemented") + implicit def pimpA5[Z](a: A[Z]): PimpedA[Bar[Foo[Z]]] = sys.error("not implemented") + implicit def pimpA6[Z: MyNumeric](a: A[Z]) = new MyNumericA[Z](a) + // TODO: Add H <: Double and see why it crashes for C and D -- context bounds, need to check! + implicit def pimpA7[H <: Double : Manifest](a: A[H]) = new ManifestA[H](a) with MyTraversableOps[H] { def convToTraversableOps: H = sys.error("no") } +} + + +/** Class B + * - tests the existential type solving + * - the following inherited methods should appear: + * {{{ + * def convToGtColonDoubleA: Double // pimpA3: no constraints + * def convToManifestA: Double // pimpA7: no constraints + * def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope + * def convToNumericA: Double // pimpA1: no constraintsd + * def convToPimpedA: Bar[Foo[Double]] // pimpA5: no constraints + * def convToTraversableOps: Double // pimpA7: no constraints + * // should not be abstract! + * }}} + */ +class B extends A[Double] +object B extends A + + +/** Class C + * - tests asSeenFrom + * - the following inherited methods should appear: + * {{{ + * def convToIntA: Int // pimpA2: no constraints + * def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope + * def convToNumericA: Int // pimpA1: no constraints + * def convToPimpedA: Bar[Foo[Int]] // pimpA5: no constraints + * }}} + */ +class C extends A[Int] +object C extends A + + +/** Class D + * - tests implicit elimination + * - the following inherited methods should appear: + * {{{ + * def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope + * def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope + * def convToPimpedA: Bar[Foo[String]] // pimpA5: no constraints + * }}} + */ +class D extends A[String] +/** Companion object with implicit transformations */ +object D extends A + + +/** PimpedA class
    + * - tests simple inheritance and asSeenFrom + * - A, B and C should be implicitly converted to this */ +class PimpedA[V](a: A[V]) { + /** The convToPimpedA: V documentation... */ + def convToPimpedA: V = sys.error("Not implemented") +} + +/** NumericA class
    + * - tests the implicit conversion between parametric and fixed types + * - A, B and C should be implicitly converted to this */ +class NumericA[U: Numeric](a: A[U]) { + /** The convToNumericA: U documentation... */ + def convToNumericA: U = implicitly[Numeric[U]].zero +} + +/** IntA class
    + * - tests the interaction between implicit conversion and specific types + * - A and C should be implicitly converted to this */ +class IntA(a: A[Int]) { + /** The convToIntA: Int documentation... */ + def convToIntA: Int = 0 +} + +/** GtColonDoubleA class
    + * - tests the interaction between implicit conversion and existential types + * - A and B should be implicitly converted to this */ +class GtColonDoubleA(a: A[T] forSome { type T <: Double }) { + /** The convToGtColonDoubleA: Double documentation... */ + def convToGtColonDoubleA: Double = 0 +} + +/** MyNumericA class
    + * - tests the implicit conversion between parametric and fixed types + * - A should be implicitly converted to this */ +class MyNumericA[U: MyNumeric](a: A[U]) { + /** The convToMyNumericA: U documentation... */ + def convToMyNumericA: U = sys.error("dunno") +} + +/** ManifestA class
    + * - tests the manifest recognition + * - A, B, C, D should be implicitly converted to this */ +class ManifestA[W: Manifest](a: A[W]) { + /** The convToManifestA: W documentation... */ + def convToManifestA: W = sys.error("dunno") +} + +/** MyTraversableOps class
    + * - checks if any abstract members are added - should not happen! + */ +trait MyTraversableOps[S] { + /** The convToTraversableOps: S documentation... */ + def convToTraversableOps: S +} + diff --git a/test/scaladoc/resources/implicits-chaining-res.scala b/test/scaladoc/resources/implicits-chaining-res.scala new file mode 100644 index 0000000000..b20c8f846c --- /dev/null +++ b/test/scaladoc/resources/implicits-chaining-res.scala @@ -0,0 +1,48 @@ +/** + * Testing scaladoc implicits chaining + */ +package scala.test.scaladoc.implicits { + + // the classes involved + case class Z[U](a: U) + case class Intermediate[T, U](t: T, u: U) + class Implicit1[T](b: Implicit2[T]) + class Implicit2[T](c: Implicit3[T]) + class Implicit3[T](/* and so on */) + + object chaining { + + // the base conversion + implicit def convertToZ[T](a: A[T])(implicit b: Implicit1[T]): Z[A[T]] = Z(a) + + // and the implicit chaining, don't you just love it? :D + // implicit1, with one alternative + implicit def implicit1[T <: Intermediate[_, _]](implicit b: Implicit2[T]) = new Implicit1[T](b) + // implicit2, with two alternatives + implicit def implicit2alt1[T <: Intermediate[_ <: String, _]](implicit c: Implicit3[T]) = new Implicit2[T](c) + implicit def implicit2alt2[T <: Intermediate[_ <: Double, _]](implicit c: Implicit3[T]) = new Implicit2[T](c) + // implicit3, with two alternatives + implicit def implicit3alt1[T <: Intermediate[_, _ <: Int]] = new Implicit3[T]() + implicit def implicit3alt2[T <: Intermediate[_ <: Double, _ <: AnyRef],X] = new Implicit3[T]() + + // and our targets + /** conversion here, with constraints */ + class A[T]() + /** conversion here, no constraints */ + class B extends A[Intermediate[String, Int]] + /** no conversion */ + class C extends A[Intermediate[String, String]] + /** conversion here, no constraints */ + class D extends A[Intermediate[Double, Int]] + /** conversion here, no constraints */ + class E extends A[Intermediate[Double, String]] + /** no conversion */ + class F extends A[Intermediate[String, Double]] + + object scalacTest { + (new B).a + (new D).a + (new E).a + } + } +} diff --git a/test/scaladoc/resources/implicits-elimination-res.scala b/test/scaladoc/resources/implicits-elimination-res.scala new file mode 100644 index 0000000000..68743aee06 --- /dev/null +++ b/test/scaladoc/resources/implicits-elimination-res.scala @@ -0,0 +1,9 @@ +/** + * Testing scaladoc implicits elimination + */ +package scala.test.scaladoc.implicits.elimination { + /** No conversion, as B doesn't bring any member */ + class A + class B { class C; trait V; type T; } + object A { implicit def toB(a: A): B = null } +} diff --git a/test/scaladoc/resources/implicits-scopes-res.scala b/test/scaladoc/resources/implicits-scopes-res.scala new file mode 100644 index 0000000000..4e55c3e388 --- /dev/null +++ b/test/scaladoc/resources/implicits-scopes-res.scala @@ -0,0 +1,51 @@ +/** + * Testing scaladoc implicit scopes - looking for implicits in the right places + */ +package scala.test.scaladoc.implicits.scopes + +// TEST1 - In package object +package object test1 { + implicit def toB(a: A): B = null +} +package test1 { + class A + class B { def b = "" } +} + +// TEST2 - In enclosing package - doesn't seem to work even in scalac +package object test2 { + import classes._ + implicit def toB(a: A): B = null +} +package test2 { + package classes { + class A + class B { def b = "" } + object test { /* (new A).b won't compile */ } + } +} + +// TEST3 - In companion object +package test3 { + class A + object A { implicit def toB(a: A): B = null } + class B { def b = "" } +} + +// TEST4 - Nested type's companion object +package test4 { + class U[V] + class S + object S { implicit def toB(a: A): B = null } + class A extends U[S] + class B { def b = "" } +} + +// TEST5 - In scope +package test5 { + object scope { + class A + class B { def b = "" } + implicit def toB(a: A): B = null + } +} diff --git a/test/scaladoc/run/SI-5373.check b/test/scaladoc/run/SI-5373.check index c55eb001cf..619c56180b 100644 --- a/test/scaladoc/run/SI-5373.check +++ b/test/scaladoc/run/SI-5373.check @@ -1 +1 @@ -model contains 6 documentable templates +Done. diff --git a/test/scaladoc/run/SI-5373.scala b/test/scaladoc/run/SI-5373.scala index af433a1844..0062abbb2a 100644 --- a/test/scaladoc/run/SI-5373.scala +++ b/test/scaladoc/run/SI-5373.scala @@ -1,9 +1,9 @@ import scala.tools.nsc.doc.model._ import scala.tools.partest.ScaladocModelTest -object Test extends ScaladocModelTest { +object Test extends ScaladocModelTest { - def code = """ + override def code = """ import scala.annotation.bridge package scala.test { @@ -23,7 +23,7 @@ object Test extends ScaladocModelTest { // no need for special settings def scaladocSettings = "" - + def testModel(rootPackage: Package) = { // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) import access._ diff --git a/test/scaladoc/run/implicits-base.check b/test/scaladoc/run/implicits-base.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-base.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-base.scala b/test/scaladoc/run/implicits-base.scala new file mode 100644 index 0000000000..a0dd2071d7 --- /dev/null +++ b/test/scaladoc/run/implicits-base.scala @@ -0,0 +1,179 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-base-res.scala" + + // start implicits + def scaladocSettings = "-implicits -implicits-show-all" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // SEE THE test/resources/implicits-base-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("base") + var conv: ImplicitConversion = null + +//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val A = base._class("A") + + // the method pimped on by pimpA0 should be shadowed by the method in class A + assert(A._conversions(A.qualifiedName + ".pimpA0").isEmpty) + + // def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope + conv = A._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToNumericA").resultType.name == "T") + + // def convToIntA: Int // pimpA2: with a constraint that T = Int + conv = A._conversion(A.qualifiedName + ".pimpA2") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToIntA").resultType.name == "Int") + + // def convToGtColonDoubleA: Double // pimpA3: with a constraint that T <: Double + conv = A._conversion(A.qualifiedName + ".pimpA3") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") + + // def convToPimpedA: S // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar + conv = A._conversion(A.qualifiedName + ".pimpA4") + assert(conv.members.length == 1) + assert(conv.constraints.length == 3) + assert(conv._member("convToPimpedA").resultType.name == "S") + + // def convToPimpedA: Bar[Foo[T]] // pimpA5: no constraints + conv = A._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[T]]") + + // def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope + conv = A._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "T") + + // def convToManifestA: T // pimpA7: with 2 constraints: T: Manifest and T <: Double + // def convToTraversableOps: T // pimpA7: with 2 constraints: T: Manifest and T <: Double + // should not be abstract! + conv = A._conversion(A.qualifiedName + ".pimpA7") + assert(conv.members.length == 2) + assert(conv.constraints.length == 2) + assert(conv._member("convToManifestA").resultType.name == "T") + assert(conv._member("convToTraversableOps").resultType.name == "T") + assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1) + +//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val B = base._class("B") + + // these conversions should not affect B + assert(B._conversions(A.qualifiedName + ".pimpA0").isEmpty) + assert(B._conversions(A.qualifiedName + ".pimpA2").isEmpty) + assert(B._conversions(A.qualifiedName + ".pimpA4").isEmpty) + + // def convToNumericA: Double // pimpA1: no constraintsd + conv = B._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToNumericA").resultType.name == "Double") + + // def convToGtColonDoubleA: Double // pimpA3: no constraints + conv = B._conversion(A.qualifiedName + ".pimpA3") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") + + // def convToPimpedA: Bar[Foo[Double]] // pimpA5: no constraints + conv = B._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Double]]") + + // def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope + conv = B._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "Double") + + // def convToManifestA: Double // pimpA7: no constraints + // def convToTraversableOps: Double // pimpA7: no constraints + // // should not be abstract! + conv = B._conversion(A.qualifiedName + ".pimpA7") + assert(conv.members.length == 2) + assert(conv.constraints.length == 0) + assert(conv._member("convToManifestA").resultType.name == "Double") + assert(conv._member("convToTraversableOps").resultType.name == "Double") + assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1) + +//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val C = base._class("C") + + // these conversions should not affect C + assert(C._conversions(A.qualifiedName + ".pimpA0").isEmpty) + assert(C._conversions(A.qualifiedName + ".pimpA3").isEmpty) + assert(C._conversions(A.qualifiedName + ".pimpA4").isEmpty) + assert(C._conversions(A.qualifiedName + ".pimpA7").isEmpty) + + // def convToNumericA: Int // pimpA1: no constraints + conv = C._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToNumericA").resultType.name == "Int") + + // def convToIntA: Int // pimpA2: no constraints + conv = C._conversion(A.qualifiedName + ".pimpA2") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToIntA").resultType.name == "Int") + + // def convToPimpedA: Bar[Foo[Int]] // pimpA5: no constraints + conv = C._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Int]]") + + // def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope + conv = C._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "Int") + +//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val D = base._class("D") + + // these conversions should not affect D + assert(D._conversions(A.qualifiedName + ".pimpA0").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA2").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA3").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA4").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA7").isEmpty) + + // def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope + conv = D._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToNumericA").resultType.name == "String") + + // def convToPimpedA: Bar[Foo[String]] // pimpA5: no constraints + conv = D._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[String]]") + + // def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope + conv = D._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "String") + } +} \ No newline at end of file diff --git a/test/scaladoc/run/implicits-chaining.check b/test/scaladoc/run/implicits-chaining.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-chaining.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-chaining.scala b/test/scaladoc/run/implicits-chaining.scala new file mode 100644 index 0000000000..96e288b204 --- /dev/null +++ b/test/scaladoc/run/implicits-chaining.scala @@ -0,0 +1,64 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-chaining-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("chaining") + var conv: ImplicitConversion = null + +//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val A = base._class("A") + + conv = A._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + +//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val B = base._class("B") + + conv = B._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + +//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val C = base._class("C") + + assert(C._conversions(base.qualifiedName + ".convertToZ").isEmpty) + +//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val D = base._class("D") + + conv = D._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + +//// class E /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val E = base._class("E") + + conv = E._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + +//// class F /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val F = base._class("F") + + assert(F._conversions(base.qualifiedName + ".convertToZ").isEmpty) + } +} \ No newline at end of file diff --git a/test/scaladoc/run/implicits-elimination.check b/test/scaladoc/run/implicits-elimination.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-elimination.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-elimination.scala b/test/scaladoc/run/implicits-elimination.scala new file mode 100644 index 0000000000..71319f9f47 --- /dev/null +++ b/test/scaladoc/run/implicits-elimination.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-elimination-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // SEE THE test/resources/implicits-elimination-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("elimination") + val A = base._class("A") + + assert(A._conversions(A.qualifiedName + ".toB").isEmpty) + } +} \ No newline at end of file diff --git a/test/scaladoc/run/implicits-scopes.check b/test/scaladoc/run/implicits-scopes.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-scopes.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-scopes.scala b/test/scaladoc/run/implicits-scopes.scala new file mode 100644 index 0000000000..7fb41e1ae8 --- /dev/null +++ b/test/scaladoc/run/implicits-scopes.scala @@ -0,0 +1,76 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-scopes-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + var conv: ImplicitConversion = null + + // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("scopes") + +//// test1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest1 = { + val test1 = base._package("test1") + val A = test1._class("A") + + conv = A._conversion(test1.qualifiedName + ".package.toB") // the .package means it's the package object + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + +//// test2 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest2 = { + val test2 = base._package("test2") + val classes = test2._package("classes") + val A = classes._class("A") + + assert(A._conversions(test2.qualifiedName + ".toB").isEmpty) + } + +//// test3 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest3 = { + val test3 = base._package("test3") + val A = test3._class("A") + + conv = A._conversion(A.qualifiedName + ".toB") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + +//// test4 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest4 = { + val test4 = base._package("test4") + val A = test4._class("A") + val S = test4._object("S") + + conv = A._conversion(S.qualifiedName + ".toB") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + +//// test5 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest5 = { + val test5 = base._package("test5") + val scope = test5._object("scope") + val A = scope._class("A") + + conv = A._conversion(scope.qualifiedName + ".toB") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + } +} \ No newline at end of file diff --git a/test/scaladoc/scalacheck/CommentFactoryTest.scala b/test/scaladoc/scalacheck/CommentFactoryTest.scala index 69c314a64c..68ca68efdd 100644 --- a/test/scaladoc/scalacheck/CommentFactoryTest.scala +++ b/test/scaladoc/scalacheck/CommentFactoryTest.scala @@ -3,11 +3,12 @@ import org.scalacheck.Prop._ import scala.tools.nsc.Global import scala.tools.nsc.doc +import scala.tools.nsc.doc.model._ import scala.tools.nsc.doc.model.comment._ class Factory(val g: Global, val s: doc.Settings) extends doc.model.ModelFactory(g, s) { - thisFactory: Factory with CommentFactory with doc.model.TreeFactory => + thisFactory: Factory with ModelFactoryImplicitSupport with CommentFactory with doc.model.TreeFactory => def strip(c: Comment): Option[Inline] = { c.body match { @@ -28,7 +29,7 @@ object Test extends Properties("CommentFactory") { val settings = new doc.Settings((str: String) => {}) val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings) val g = new Global(settings, reporter) - (new Factory(g, settings) with CommentFactory with doc.model.TreeFactory) + (new Factory(g, settings) with ModelFactoryImplicitSupport with CommentFactory with doc.model.TreeFactory) } def parse(src: String, dst: Inline) = { -- cgit v1.2.3 From 4b95f21060078af1ae7037ce2e6cfc4c1a5a155d Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 13 Apr 2012 10:57:41 +0100 Subject: Introducing some whitespace before colons. Maybe helping -Xcheckinit along too. --- src/compiler/scala/reflect/internal/StdNames.scala | 7 ------- src/library/scala/reflect/api/StandardNames.scala | 15 +++++---------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 1666887133..04f67a3196 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -268,8 +268,6 @@ trait StdNames extends NameManglers { self: SymbolTable => case _ => newTermName("x$" + i) } - // [Eugene to Paul] see comments in StandardNames.scala to find out why's this here - val QQQ = ??? val ??? = encode("???") val wrapRefArray: NameType = "wrapRefArray" @@ -641,14 +639,9 @@ trait StdNames extends NameManglers { self: SymbolTable => val ZOR = encode("||") // unary operators - // [Eugene to Paul] see comments in StandardNames.scala to find out why's this here - val UNARY_TILDE = UNARY_~ val UNARY_~ = encode("unary_~") - val UNARY_PLUS = UNARY_+ val UNARY_+ = encode("unary_+") - val UNARY_MINUS = UNARY_- val UNARY_- = encode("unary_-") - val UNARY_NOT = UNARY_! val UNARY_! = encode("unary_!") // Grouped here so Cleanup knows what tests to perform. diff --git a/src/library/scala/reflect/api/StandardNames.scala b/src/library/scala/reflect/api/StandardNames.scala index bfc165f613..d2110ede75 100644 --- a/src/library/scala/reflect/api/StandardNames.scala +++ b/src/library/scala/reflect/api/StandardNames.scala @@ -93,18 +93,13 @@ trait StandardNames { self: Universe => val ZOR: TermName // [Eugene] this doesn't compile. why?! -// val UNARY_~: TermName -// val UNARY_+: TermName -// val UNARY_-: TermName -// val UNARY_!: TermName - val UNARY_TILDE: TermName - val UNARY_PLUS: TermName - val UNARY_MINUS: TermName - val UNARY_NOT: TermName + val UNARY_~ : TermName + val UNARY_+ : TermName + val UNARY_- : TermName + val UNARY_! : TermName // [Eugene] this doesn't compile. why?! -// val ???: TermName - val QQQ: TermName + val ??? : TermName val MODULE_SUFFIX_NAME: TermName val NAME_JOIN_NAME: TermName -- cgit v1.2.3 From 13d3fe99a0ad0032e23c72466c5f4931131cbdb1 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 13 Apr 2012 11:21:03 +0100 Subject: Portability changes to binary-repo-lib.sh. --- tools/binary-repo-lib.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/binary-repo-lib.sh b/tools/binary-repo-lib.sh index 09d0af1d50..a22747520c 100755 --- a/tools/binary-repo-lib.sh +++ b/tools/binary-repo-lib.sh @@ -92,9 +92,15 @@ getJarSha() { local jar=$1 if [[ ! -f "$jar" ]]; then echo "" - else + elif which sha1sum 2>/dev/null >/dev/null; then shastring=$(sha1sum "$jar") - echo "${shastring:0:$(expr index "$shastring" " ")-1}" + echo "$shastring" | sed 's/ .*//' + elif which shasum 2>/dev/null >/dev/null; then + shastring=$(shasum "$jar") + echo "$shastring" | sed 's/ .*//' + else + shastring=$(openssl sha1 "$jar") + echo "$shastring" | sed 's/^.*= //' fi } -- cgit v1.2.3 From 5d42159cec3ac04310c35500cd9e01419b0fb587 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 13 Apr 2012 12:14:26 +0100 Subject: Touching the untouchable. extempore thinks polymorphism beats boolean constructor parameters any day of the week. --- src/compiler/scala/reflect/internal/Types.scala | 77 +++++++++++++++------- .../scala/tools/nsc/typechecker/Implicits.scala | 2 +- 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 8bb1d5e2fa..3f0d5c9c67 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -915,14 +915,10 @@ trait Types extends api.Types { self: SymbolTable => */ def directObjectString = safeToString - /** A test whether a type contains any unification type variables. */ + /** A test whether a type contains any unification type variables. + * Overridden with custom logic except where trivially true. + */ def isGround: Boolean = this match { - case tv@TypeVar(_, _) => - tv.untouchable || (tv.instValid && tv.constr.inst.isGround) - case TypeRef(pre, sym, args) => - sym.isPackageClass || pre.isGround && (args forall (_.isGround)) - case SingleType(pre, sym) => - sym.isPackageClass || pre.isGround case ThisType(_) | NoPrefix | WildcardType | NoType | ErrorType | ConstantType(_) => true case _ => @@ -1258,6 +1254,8 @@ trait Types extends api.Types { self: SymbolTable => */ abstract case class SingleType(pre: Type, sym: Symbol) extends SingletonType { override val isTrivial: Boolean = pre.isTrivial + override def isGround = sym.isPackageClass || pre.isGround + // override def isNullable = underlying.isNullable override def isNotNull = underlying.isNotNull private[reflect] var underlyingCache: Type = NoType @@ -2143,6 +2141,11 @@ trait Types extends api.Types { self: SymbolTable => } } + override def isGround = ( + sym.isPackageClass + || pre.isGround && args.forall(_.isGround) + ) + def etaExpand: Type = { // must initialise symbol, see test/files/pos/ticket0137.scala val tpars = initializedTypeParams @@ -2675,22 +2678,35 @@ trait Types extends api.Types { self: SymbolTable => else new TypeConstraint } def unapply(tv: TypeVar): Some[(Type, TypeConstraint)] = Some((tv.origin, tv.constr)) + def untouchable(tparam: Symbol): TypeVar = createTypeVar(tparam, untouchable = true) + def apply(tparam: Symbol): TypeVar = createTypeVar(tparam, untouchable = false) def apply(origin: Type, constr: TypeConstraint): TypeVar = apply(origin, constr, Nil, Nil) - def apply(tparam: Symbol): TypeVar = apply(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams) - def apply(tparam: Symbol, untouchable: Boolean): TypeVar = apply(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams, untouchable) + def apply(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol]): TypeVar = + createTypeVar(origin, constr, args, params, untouchable = false) /** This is the only place TypeVars should be instantiated. */ - def apply(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol], untouchable: Boolean = false): TypeVar = { + private def createTypeVar(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol], untouchable: Boolean): TypeVar = { val tv = ( - if (args.isEmpty && params.isEmpty) new TypeVar(origin, constr, untouchable) - else if (args.size == params.size) new AppliedTypeVar(origin, constr, untouchable, params zip args) - else if (args.isEmpty) new HKTypeVar(origin, constr, untouchable, params) + if (args.isEmpty && params.isEmpty) { + if (untouchable) new TypeVar(origin, constr) with UntouchableTypeVar + else new TypeVar(origin, constr) + } + else if (args.size == params.size) { + if (untouchable) new AppliedTypeVar(origin, constr, params zip args) with UntouchableTypeVar + else new AppliedTypeVar(origin, constr, params zip args) + } + else if (args.isEmpty) { + if (untouchable) new HKTypeVar(origin, constr, params) with UntouchableTypeVar + else new HKTypeVar(origin, constr, params) + } else throw new Error("Invalid TypeVar construction: " + ((origin, constr, args, params))) ) trace("create", "In " + tv.originLocation)(tv) } + private def createTypeVar(tparam: Symbol, untouchable: Boolean): TypeVar = + createTypeVar(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams, untouchable) } /** Repack existential types, otherwise they sometimes get unpacked in the @@ -2713,9 +2729,8 @@ trait Types extends api.Types { self: SymbolTable => class HKTypeVar( _origin: Type, _constr: TypeConstraint, - _untouchable: Boolean, override val params: List[Symbol] - ) extends TypeVar(_origin, _constr, _untouchable) { + ) extends TypeVar(_origin, _constr) { require(params.nonEmpty, this) override def isHigherKinded = true @@ -2727,9 +2742,8 @@ trait Types extends api.Types { self: SymbolTable => class AppliedTypeVar( _origin: Type, _constr: TypeConstraint, - _untouchable: Boolean, zippedArgs: List[(Symbol, Type)] - ) extends TypeVar(_origin, _constr, _untouchable) { + ) extends TypeVar(_origin, _constr) { require(zippedArgs.nonEmpty, this) @@ -2740,6 +2754,23 @@ trait Types extends api.Types { self: SymbolTable => zippedArgs map { case (p, a) => p.name + "=" + a } mkString (origin + "[", ", ", "]") ) } + + trait UntouchableTypeVar extends TypeVar { + override def untouchable = true + override def isGround = true + override def registerTypeEquality(tp: Type, typeVarLHS: Boolean) = tp match { + case t: TypeVar if !t.untouchable => + t.registerTypeEquality(this, !typeVarLHS) + case _ => + super.registerTypeEquality(tp, typeVarLHS) + } + override def registerBound(tp: Type, isLowerBound: Boolean, isNumericBound: Boolean = false): Boolean = tp match { + case t: TypeVar if !t.untouchable => + t.registerBound(this, !isLowerBound, isNumericBound) + case _ => + super.registerBound(tp, isLowerBound, isNumericBound) + } + } /** A class representing a type variable: not used after phase `typer`. * @@ -2752,9 +2783,9 @@ trait Types extends api.Types { self: SymbolTable => */ class TypeVar( val origin: Type, - val constr0: TypeConstraint, - val untouchable: Boolean = false // by other typevars + val constr0: TypeConstraint ) extends Type { + def untouchable = false // by other typevars override def params: List[Symbol] = Nil override def typeArgs: List[Type] = Nil override def isHigherKinded = false @@ -2767,6 +2798,7 @@ trait Types extends api.Types { self: SymbolTable => */ var constr = constr0 def instValid = constr.instValid + override def isGround = instValid && constr.inst.isGround /** The variable's skolemization level */ val level = skolemizationLevel @@ -2941,9 +2973,7 @@ trait Types extends api.Types { self: SymbolTable => // to fall back on the individual base types. This warrants eventual re-examination. // AM: I think we could use the `suspended` flag to avoid side-effecting during unification - - if (tp.isInstanceOf[TypeVar] && untouchable && !tp.asInstanceOf[TypeVar].untouchable) tp.asInstanceOf[TypeVar].registerBound(this, !isLowerBound, isNumericBound) - else if (suspended) // constraint accumulation is disabled + if (suspended) // constraint accumulation is disabled checkSubtype(tp, origin) else if (constr.instValid) // type var is already set checkSubtype(tp, constr.inst) @@ -2967,8 +2997,7 @@ trait Types extends api.Types { self: SymbolTable => if(typeVarLHS) constr.inst =:= tp else tp =:= constr.inst - if (tp.isInstanceOf[TypeVar] && untouchable && !tp.asInstanceOf[TypeVar].untouchable) tp.asInstanceOf[TypeVar].registerTypeEquality(this, !typeVarLHS) - else if (suspended) tp =:= origin + if (suspended) tp =:= origin else if (constr.instValid) checkIsSameType(tp) else isRelatable(tp) && { val newInst = wildcardToTypeVarMap(tp) diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 2de86c67bf..eb8bef3b58 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -107,7 +107,7 @@ trait Implicits { */ def allViewsFrom(tp: Type, context: Context, tpars: List[Symbol]): List[(SearchResult, List[TypeConstraint])] = { // my untouchable typevars are better than yours (they can't be constrained by them) - val tvars = tpars map (TypeVar.apply(_, untouchable = true)) + val tvars = tpars map (TypeVar untouchable _) val tpSubsted = tp.subst(tpars, tvars) val search = new ImplicitSearch(EmptyTree, functionType(List(tpSubsted), AnyClass.tpe), true, context.makeImplicit(false)) -- cgit v1.2.3 From 020043c3a6e19718175cbbfe76cedab8db7e0498 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 13 Apr 2012 14:06:52 +0100 Subject: Small cleanup in typeref toString --- src/compiler/scala/reflect/internal/Types.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 3f0d5c9c67..c6b320b444 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -2238,10 +2238,10 @@ trait Types extends api.Types { self: SymbolTable => parentsString(thisInfo.parents) + refinementString else rest ) - private def customToString = this match { - case TypeRef(_, RepeatedParamClass, arg :: _) => arg + "*" - case TypeRef(_, ByNameParamClass, arg :: _) => "=> " + arg - case _ => + private def customToString = sym match { + case RepeatedParamClass => args.head + "*" + case ByNameParamClass => "=> " + args.head + case _ => def targs = normalize.typeArgs if (isFunctionType(this)) { -- cgit v1.2.3 From 381c0e12bf5a72df6f3b3ac8eaca1cac28263154 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 13 Apr 2012 08:59:30 -0700 Subject: Added missing objects. --- src/library/scala/language.scala | 25 +++++++++++++++++++++++++ src/library/scala/languageFeature.scala | 30 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/library/scala/language.scala create mode 100644 src/library/scala/languageFeature.scala diff --git a/src/library/scala/language.scala b/src/library/scala/language.scala new file mode 100644 index 0000000000..907adb5f72 --- /dev/null +++ b/src/library/scala/language.scala @@ -0,0 +1,25 @@ +package scala + +object language { + + import languageFeature._ + + implicit val dynamics: dynamics = ??? + + implicit val postfixOps: postfixOps = ??? + + implicit val reflectiveCalls: reflectiveCalls = ??? + + implicit val implicitConversions: implicitConversions = ??? + + implicit val higherKinds: higherKinds = ??? + + implicit val existentials: existentials = ??? + + object experimental { + + import languageFeature.experimental._ + + implicit val macros: macros = ??? + } +} diff --git a/src/library/scala/languageFeature.scala b/src/library/scala/languageFeature.scala new file mode 100644 index 0000000000..c990f714c1 --- /dev/null +++ b/src/library/scala/languageFeature.scala @@ -0,0 +1,30 @@ +package scala + +import annotation.meta + +object languageFeature { + + @meta.languageFeature("extension of type scala.Dynamic", true) + sealed trait dynamics + + @meta.languageFeature("postfix operator #", false) + sealed trait postfixOps + + @meta.languageFeature("reflective access of structural type member #", false) + sealed trait reflectiveCalls + + @meta.languageFeature("implicit conversion #", false) + sealed trait implicitConversions + + @meta.languageFeature("higher-kinded type", false) + sealed trait higherKinds + + @meta.languageFeature("#, which cannot be expressed by wildcards, ", false) + sealed trait existentials + + object experimental { + @meta.languageFeature("macro definition", true) + sealed trait macros + } +} + -- cgit v1.2.3 From 593112ed56b46da182c7b216264f921c5780ae24 Mon Sep 17 00:00:00 2001 From: Simon Ochsenreither Date: Fri, 13 Apr 2012 18:29:18 +0200 Subject: Adds test and check files for SI-5666. Covers common non-newable types. --- test/files/neg/t5666.check | 37 +++++++++++++++++++++++++++++++++++++ test/files/neg/t5666.scala | 14 ++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 test/files/neg/t5666.check create mode 100644 test/files/neg/t5666.scala diff --git a/test/files/neg/t5666.check b/test/files/neg/t5666.check new file mode 100644 index 0000000000..1be51d0138 --- /dev/null +++ b/test/files/neg/t5666.check @@ -0,0 +1,37 @@ +t5666.scala:2: error: class Any is abstract; cannot be instantiated + new Any + ^ +t5666.scala:3: error: trait AnyVal is abstract; cannot be instantiated + new AnyVal + ^ +t5666.scala:4: error: Double does not have a constructor + new Double + ^ +t5666.scala:5: error: Float does not have a constructor + new Float + ^ +t5666.scala:6: error: Long does not have a constructor + new Long + ^ +t5666.scala:7: error: Int does not have a constructor + new Int + ^ +t5666.scala:8: error: Char does not have a constructor + new Char + ^ +t5666.scala:9: error: Short does not have a constructor + new Short + ^ +t5666.scala:10: error: Byte does not have a constructor + new Byte + ^ +t5666.scala:11: error: Boolean does not have a constructor + new Boolean + ^ +t5666.scala:12: error: Unit does not have a constructor + new Unit + ^ +t5666.scala:13: error: trait Nothing is abstract; cannot be instantiated + new Nothing + ^ +12 errors found diff --git a/test/files/neg/t5666.scala b/test/files/neg/t5666.scala new file mode 100644 index 0000000000..ffaeaacdaf --- /dev/null +++ b/test/files/neg/t5666.scala @@ -0,0 +1,14 @@ +object t5666 { + new Any + new AnyVal + new Double + new Float + new Long + new Int + new Char + new Short + new Byte + new Boolean + new Unit + new Nothing +} \ No newline at end of file -- cgit v1.2.3 From 2286d7b43180f3018a041163dc0cfa951c0397a4 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 30 Mar 2012 10:12:40 +0200 Subject: implement SIP Type Dynamic --- src/compiler/scala/reflect/internal/StdNames.scala | 3 + src/compiler/scala/reflect/internal/Symbols.scala | 2 +- src/compiler/scala/reflect/internal/TreeInfo.scala | 15 +++ .../scala/tools/nsc/typechecker/Typers.scala | 121 ++++++++++++++++++--- test/files/run/applydynamic_sip.check | 22 ++++ test/files/run/applydynamic_sip.scala | 58 ++++++++++ 6 files changed, 207 insertions(+), 14 deletions(-) create mode 100644 test/files/run/applydynamic_sip.check create mode 100644 test/files/run/applydynamic_sip.scala diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 1666887133..696921237b 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -325,6 +325,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val append: NameType = "append" val apply: NameType = "apply" val applyDynamic: NameType = "applyDynamic" + val applyDynamicNamed: NameType = "applyDynamicNamed" val applyOrElse: NameType = "applyOrElse" val args : NameType = "args" val argv : NameType = "argv" @@ -426,6 +427,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val runtime: NameType = "runtime" val sameElements: NameType = "sameElements" val scala_ : NameType = "scala" + val selectDynamic: NameType = "selectDynamic" val selectOverloadedMethod: NameType = "selectOverloadedMethod" val selectTerm: NameType = "selectTerm" val selectType: NameType = "selectType" @@ -455,6 +457,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val unapplySeq: NameType = "unapplySeq" val unbox: NameType = "unbox" val update: NameType = "update" + val updateDynamic: NameType = "updateDynamic" val value: NameType = "value" val valueOf : NameType = "valueOf" val values : NameType = "values" diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index fc94e96acd..e29e267584 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -1874,7 +1874,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => site.nonPrivateMemberAdmitting(name, admit).filter(sym => !sym.isTerm || (site.memberType(this) matches site.memberType(sym))) - /** The symbol overridden by this symbol in given class `ofclazz`. + /** The symbol, in class `ofclazz`, that is overridden by this symbol. * * @param ofclazz is a base class of this symbol's owner. */ diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index ed22cad730..a8cca1625f 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -532,6 +532,21 @@ abstract class TreeInfo { } } + def isApplyDynamicName(name: Name) = (name == nme.updateDynamic) || (name == nme.selectDynamic) || (name == nme.applyDynamic) || (name == nme.applyDynamicNamed) + + class DynamicApplicationExtractor(nameTest: Name => Boolean) { + def unapply(tree: Tree) = tree match { + case Apply(TypeApply(Select(qual, oper), _), List(Literal(Constant(name)))) if nameTest(oper) => Some((qual, name)) + case Apply(Select(qual, oper), List(Literal(Constant(name)))) if nameTest(oper) => Some((qual, name)) + case Apply(Ident(oper), List(Literal(Constant(name)))) if nameTest(oper) => Some((EmptyTree, name)) + case _ => None + } + } + object DynamicUpdate extends DynamicApplicationExtractor(_ == nme.updateDynamic) + object DynamicApplication extends DynamicApplicationExtractor(isApplyDynamicName) + object DynamicApplicationNamed extends DynamicApplicationExtractor(_ == nme.applyDynamicNamed) + + // domain-specific extractors for reification import definitions._ diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2b7c8e8304..305e30aeee 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -675,7 +675,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } if (tree.tpe.isInstanceOf[MethodType] && pre.isStable && sym.tpe.params.isEmpty && (isStableContext(tree, mode, pt) || sym.isModule)) - tree.setType(MethodType(List(), singleType(pre, sym))) + tree.setType(MethodType(List(), singleType(pre, sym))) // TODO: should this be a NullaryMethodType? else tree } @@ -2817,7 +2817,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { (args exists isNamed) || // uses a named argument isNamedApplyBlock(fun)) { // fun was transformed to a named apply block => // integrate this application into the block - tryNamesDefaults + if (dyna.isApplyDynamicNamed(fun)) dyna.typedNamedApply(tree, fun, args, mode, pt) + else tryNamesDefaults } else { val tparams = context.extractUndetparams() if (tparams.isEmpty) { // all type params are defined @@ -3438,7 +3439,100 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case ErrorType => setError(treeCopy.TypeApply(tree, fun, args)) case _ => - TypedApplyDoesNotTakeTpeParametersError(tree, fun) + fun match { + // drop the application for an applyDynamic or selectDynamic call since it has been pushed down + case treeInfo.DynamicApplication(_, _) => fun + case _ => TypedApplyDoesNotTakeTpeParametersError(tree, fun) + } + } + + object dyna { + import treeInfo.{isApplyDynamicName, DynamicUpdate, DynamicApplicationNamed} + + def acceptsApplyDynamic(tp: Type) = tp.typeSymbol isNonBottomSubClass DynamicClass + + /** Returns `Some(t)` if `name` can be selected dynamically on `qual`, `None` if not. + * `t` specifies the type to be passed to the applyDynamic/selectDynamic call (unless it is NoType) + * NOTE: currently either returns None or Some(NoType) (scala-virtualized extends this to Some(t) for selections on staged Structs) + */ + def acceptsApplyDynamicWithType(qual: Tree, name: Name): Option[Type] = + // don't selectDynamic selectDynamic, do select dynamic at unknown type, + // in scala-virtualized, we may return a Some(tp) where tp ne NoType + if (!isApplyDynamicName(name) && acceptsApplyDynamic(qual.tpe.widen)) Some(NoType) + else None + + def isDynamicallyUpdatable(tree: Tree) = tree match { + case DynamicUpdate(qual, name) => + // if the qualifier is a Dynamic, that's all we need to know + acceptsApplyDynamic(qual.tpe) + case _ => false + } + + def isApplyDynamicNamed(fun: Tree): Boolean = fun match { + case DynamicApplicationNamed(qual, _) if acceptsApplyDynamic(qual.tpe.widen) => true + case _ => false + // look deeper? + // val methPart = treeInfo.methPart(fun) + // println("methPart of "+ fun +" is "+ methPart) + // if (methPart ne fun) isApplyDynamicNamed(methPart) + // else false + } + + def typedNamedApply(orig: Tree, fun: Tree, args: List[Tree], mode: Int, pt: Type): Tree = { + def argToBinding(arg: Tree): Tree = arg match { + case AssignOrNamedArg(Ident(name), rhs) => gen.mkTuple(List(CODE.LIT(name.toString), rhs)) + case _ => gen.mkTuple(List(CODE.LIT(""), arg)) + } + typed(treeCopy.Apply(orig, fun, args map argToBinding), mode, pt) + } + + /** Translate selection that does not typecheck according to the normal rules into a selectDynamic/applyDynamic. + * + * foo.method("blah") ~~> foo.applyDynamic("method")("blah") + * foo.method(x = "blah") ~~> foo.applyDynamicNamed("method")(("x", "blah")) + * foo.varia = 10 ~~> foo.updateDynamic("varia")(10) + * foo.field ~~> foo.selectDynamic("field") + * foo.arr(10) = 13 ~~> foo.selectDynamic("arr").update(10, 13) + * + * what if we want foo.field == foo.selectDynamic("field") == 1, but `foo.field = 10` == `foo.selectDynamic("field").update(10)` == () + * what would the signature for selectDynamic be? (hint: it needs to depend on whether an update call is coming or not) + * + * need to distinguish selectDynamic and applyDynamic somehow: the former must return the selected value, the latter must accept an apply or an update + * - could have only selectDynamic and pass it a boolean whether more is to come, + * so that it can either return the bare value or something that can handle the apply/update + * HOWEVER that makes it hard to return unrelated values for the two cases + * --> selectDynamic's return type is now dependent on the boolean flag whether more is to come + * - simplest solution: have two method calls + * + */ + def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] = + acceptsApplyDynamicWithType(qual, name) map { tp => + // tp eq NoType => can call xxxDynamic, but not passing any type args (unless specified explicitly by the user) + // in scala-virtualized, when not NoType, tp is passed as type argument (for selection on a staged Struct) + + // strip off type application -- we're not doing much with outer, so don't bother preserving cxTree's attributes etc + val (outer, explicitTargs) = cxTree match { + case TypeApply(fun, targs) => (fun, targs) + case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs) + case t => (t, Nil) + } + + // note: context.tree includes at most one Apply node + // thus, we can't use it to detect we're going to receive named args in expressions such as: + // qual.sel(a)(a2, arg2 = "a2") + val oper = outer match { + case Apply(`tree`, as) => if (as collectFirst {case AssignOrNamedArg(lhs, rhs) =>} nonEmpty) + nme.applyDynamicNamed + else nme.applyDynamic + case Assign(`tree`, _) => nme.updateDynamic + case _ => nme.selectDynamic + } + + val dynSel = Select(qual, oper) + val tappSel = if (explicitTargs nonEmpty) TypeApply(dynSel, explicitTargs) else dynSel + + atPos(qual.pos)(Apply(tappSel, List(Literal(Constant(name.decode))))) + } } @inline final def deindentTyping() = context.typingIndentLevel -= 2 @@ -3612,10 +3706,17 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case _ => } } +// if (varsym.isVariable || +// // setter-rewrite has been done above, so rule out methods here, but, wait a minute, why are we assigning to non-variables after erasure?! +// (phase.erasedTypes && varsym.isValue && !varsym.isMethod)) { if (varsym.isVariable || varsym.isValue && phase.erasedTypes) { val rhs1 = typed(rhs, EXPRmode | BYVALmode, lhs1.tpe) treeCopy.Assign(tree, lhs1, checkDead(rhs1)) setType UnitClass.tpe } + else if(dyna.isDynamicallyUpdatable(lhs1)) { + val rhs1 = typed(rhs, EXPRmode | BYVALmode, WildcardType) + typed1(Apply(lhs1, List(rhs1)), mode, pt) + } else fail() } @@ -4078,16 +4179,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } // try to expand according to Dynamic rules. - - if (settings.Xexperimental.value && (qual.tpe.widen.typeSymbol isNonBottomSubClass DynamicClass)) { - var dynInvoke = Apply(Select(qual, nme.applyDynamic), List(Literal(Constant(name.decode)))) - context.tree match { - case Apply(tree1, args) if tree1 eq tree => - ; - case _ => - dynInvoke = Apply(dynInvoke, List()) - } - return typed1(util.trace("dynatype: ")(dynInvoke), mode, pt) + dyna.mkInvoke(context.tree, tree, qual, name) match { + case Some(invocation) => + return typed1(invocation, mode, pt) + case _ => } if (settings.debug.value) { diff --git a/test/files/run/applydynamic_sip.check b/test/files/run/applydynamic_sip.check new file mode 100644 index 0000000000..d94db4417e --- /dev/null +++ b/test/files/run/applydynamic_sip.check @@ -0,0 +1,22 @@ +qual.applyDynamic(sel)() +qual.applyDynamic(sel)(a) +qual.applyDynamic(sel)(a) +.apply(a2) +qual.applyDynamic(sel)(a) +qual.applyDynamic(sel)(a) +.apply(a2) +qual.applyDynamicNamed(sel)((arg,a)) +qual.applyDynamicNamed(sel)((arg,a)) +qual.applyDynamicNamed(sel)((,a), (arg2,a2)) +qual.updateDynamic(sel)(expr) +qual.selectDynamic(sel) +qual.selectDynamic(sel) +qual.selectDynamic(sel) +.update(1, expr) +qual.selectDynamic(sel) +.update(expr) +qual.selectDynamic(sel) +.apply(1) +qual.selectDynamic(sel) +.apply +.update(1, 1) diff --git a/test/files/run/applydynamic_sip.scala b/test/files/run/applydynamic_sip.scala new file mode 100644 index 0000000000..7150517530 --- /dev/null +++ b/test/files/run/applydynamic_sip.scala @@ -0,0 +1,58 @@ +object Test extends App { + object stubUpdate { + def update(as: Any*) = println(".update"+as.toList.mkString("(",", ", ")")) + } + + object stub { + def apply = {println(".apply"); stubUpdate} + def apply(as: Any*) = println(".apply"+as.toList.mkString("(",", ", ")")) + def update(as: Any*) = println(".update"+as.toList.mkString("(",", ", ")")) + } + class MyDynamic extends Dynamic { + def applyDynamic[T](n: String)(as: Any*) = {println("qual.applyDynamic("+ n +")"+ as.toList.mkString("(",", ", ")")); stub} + def applyDynamicNamed[T](n: String)(as: (String, Any)*) = {println("qual.applyDynamicNamed("+ n +")"+ as.toList.mkString("(",", ", ")")); stub} + def selectDynamic[T](n: String) = {println("qual.selectDynamic("+ n +")"); stub} + def updateDynamic(n: String)(x: Any): Unit = {println("qual.updateDynamic("+ n +")("+ x +")")} + } + val qual = new MyDynamic + val expr = "expr" + val a = "a" + val a2 = "a2" + type T = String + + // If qual.sel is followed by a potential type argument list [Ts] and an argument list (arg1, …, argn) where none of the arguments argi are named: + // qual.applyDynamic(“sel”)(arg1, …, argn) + qual.sel() + qual.sel(a) + // qual.sel(a, a2: _*) -- should not accept varargs? + qual.sel(a)(a2) + qual.sel[T](a) + qual.sel[T](a)(a2) + + // If qual.sel is followed by a potential type argument list [Ts] + // and a non-empty named argument list (x1 = arg1, …, xn = argn) where some name prefixes xi = might be missing: + // qual.applyDynamicNamed(“sel”)(xs1 -> arg1, …, xsn -> argn) + qual.sel(arg = a) + qual.sel[T](arg = a) + qual.sel(a, arg2 = "a2") + // qual.sel(a)(a2, arg2 = "a2") + // qual.sel[T](a)(a2, arg2 = "a2") + // qual.sel(arg = a, a2: _*) + // qual.sel(arg, arg2 = "a2", a2: _*) + + // If qual.sel appears immediately on the left-hand side of an assigment + // qual.updateDynamic(“sel”)(expr) + qual.sel = expr + + // If qual.sel, possibly applied to type arguments, but is + // not applied to explicit value arguments, + // nor immediately followed by an assignment operator: + // qual.selectDynamic[Ts](“sel”) + qual.sel + qual.sel[T] + + qual.sel(1) = expr // parser turns this into qual.sel.update(1, expr) + qual.sel() = expr // parser turns this into qual.sel.update(expr) + qual.sel.apply(1) + qual.sel.apply(1) = 1 +} \ No newline at end of file -- cgit v1.2.3 From e29681b95a215e8edf9e0f272d2a76aadac14fff Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Wed, 4 Apr 2012 14:49:08 +0200 Subject: rule out sequence arg to applyDynamic --- .../scala/tools/nsc/typechecker/ContextErrors.scala | 3 +++ src/compiler/scala/tools/nsc/typechecker/Typers.scala | 18 +++++++++++++----- test/files/neg/applydynamic_sip.check | 10 ++++++++++ test/files/neg/applydynamic_sip.scala | 10 ++++++++++ test/files/run/applydynamic_sip.scala | 4 ++-- 5 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 test/files/neg/applydynamic_sip.check create mode 100644 test/files/neg/applydynamic_sip.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index edc69be827..38fbcf4ef4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -504,6 +504,9 @@ trait ContextErrors { def ApplyWithoutArgsError(tree: Tree, fun: Tree) = NormalTypeError(tree, fun.tpe+" does not take parameters") + def DynamicVarArgUnsupported(tree: Tree, name: String) = + issueNormalTypeError(tree, name+ " does not support passing a vararg parameter") + //checkClassType def TypeNotAStablePrefixError(tpt: Tree, pre: Type) = { issueNormalTypeError(tpt, "type "+pre+" is not a stable prefix") diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 305e30aeee..0da118403d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3517,15 +3517,23 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case t => (t, Nil) } + @inline def hasNamedArg(as: List[Tree]) = as collectFirst {case AssignOrNamedArg(lhs, rhs) =>} nonEmpty + // note: context.tree includes at most one Apply node // thus, we can't use it to detect we're going to receive named args in expressions such as: // qual.sel(a)(a2, arg2 = "a2") val oper = outer match { - case Apply(`tree`, as) => if (as collectFirst {case AssignOrNamedArg(lhs, rhs) =>} nonEmpty) - nme.applyDynamicNamed - else nme.applyDynamic - case Assign(`tree`, _) => nme.updateDynamic - case _ => nme.selectDynamic + case Apply(`tree`, as) => + val oper = + if (hasNamedArg(as)) nme.applyDynamicNamed + else nme.applyDynamic + // not supported: foo.bar(a1,..., an: _*) + if (treeInfo.isWildcardStarArgList(as)) { + DynamicVarArgUnsupported(tree, oper) + return Some(setError(tree)) + } else oper + case Assign(`tree`, _) => nme.updateDynamic + case _ => nme.selectDynamic } val dynSel = Select(qual, oper) diff --git a/test/files/neg/applydynamic_sip.check b/test/files/neg/applydynamic_sip.check new file mode 100644 index 0000000000..8845f68a52 --- /dev/null +++ b/test/files/neg/applydynamic_sip.check @@ -0,0 +1,10 @@ +applydynamic_sip.scala:7: error: applyDynamic does not support passing a vararg parameter + qual.sel(a, a2: _*) + ^ +applydynamic_sip.scala:8: error: applyDynamicNamed does not support passing a vararg parameter + qual.sel(arg = a, a2: _*) + ^ +applydynamic_sip.scala:9: error: applyDynamicNamed does not support passing a vararg parameter + qual.sel(arg, arg2 = "a2", a2: _*) + ^ +three errors found diff --git a/test/files/neg/applydynamic_sip.scala b/test/files/neg/applydynamic_sip.scala new file mode 100644 index 0000000000..362461577b --- /dev/null +++ b/test/files/neg/applydynamic_sip.scala @@ -0,0 +1,10 @@ +object Test extends App { + val qual: Dynamic = ??? + val expr = "expr" + val a = "a" + val a2 = "a2" + + qual.sel(a, a2: _*) + qual.sel(arg = a, a2: _*) + qual.sel(arg, arg2 = "a2", a2: _*) +} \ No newline at end of file diff --git a/test/files/run/applydynamic_sip.scala b/test/files/run/applydynamic_sip.scala index 7150517530..57cb4349f7 100644 --- a/test/files/run/applydynamic_sip.scala +++ b/test/files/run/applydynamic_sip.scala @@ -29,9 +29,9 @@ object Test extends App { qual.sel[T](a) qual.sel[T](a)(a2) - // If qual.sel is followed by a potential type argument list [Ts] + // If qual.sel is followed by a potential type argument list [Ts] // and a non-empty named argument list (x1 = arg1, …, xn = argn) where some name prefixes xi = might be missing: - // qual.applyDynamicNamed(“sel”)(xs1 -> arg1, …, xsn -> argn) + // qual.applyDynamicNamed(“sel”)(xs1 -> arg1, …, xsn -> argn) qual.sel(arg = a) qual.sel[T](arg = a) qual.sel(a, arg2 = "a2") -- cgit v1.2.3 From d5c27ed09d695cd8ed465d14d832a397ddbcd52c Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 5 Apr 2012 14:41:34 +0200 Subject: parse patterns, not exprs in interpolatedString's holes --- .../scala/tools/nsc/ast/parser/Parsers.scala | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index daabfae6b3..1280ef6937 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -70,6 +70,9 @@ trait ParsersCommon extends ScannersCommon { @inline final def inBracesOrNil[T](body: => List[T]): List[T] = inBracesOrError(body, Nil) @inline final def inBracesOrUnit[T](body: => Tree): Tree = inBracesOrError(body, Literal(Constant())) + @inline final def dropAnyBraces[T](body: => T): T = + if (in.token == LBRACE) inBraces(body) + else body @inline final def inBrackets[T](body: => T): T = { accept(LBRACKET) @@ -1106,7 +1109,7 @@ self => * }}} * @note The returned tree does not yet have a position */ - def literal(isNegated: Boolean = false): Tree = { + def literal(isNegated: Boolean = false, inPattern: Boolean = false): Tree = { def finish(value: Any): Tree = { val t = Literal(Constant(value)) in.nextToken() @@ -1115,7 +1118,7 @@ self => if (in.token == SYMBOLLIT) Apply(scalaDot(nme.Symbol), List(finish(in.strVal))) else if (in.token == INTERPOLATIONID) - interpolatedString() + interpolatedString(inPattern) else finish(in.token match { case CHARLIT => in.charVal case INTLIT => in.intVal(isNegated).toInt @@ -1141,7 +1144,7 @@ self => } } - private def interpolatedString(): Tree = atPos(in.offset) { + private def interpolatedString(inPattern: Boolean = false): Tree = atPos(in.offset) { val start = in.offset val interpolator = in.name @@ -1151,8 +1154,11 @@ self => while (in.token == STRINGPART) { partsBuf += literal() exprBuf += { - if (in.token == IDENTIFIER) atPos(in.offset)(Ident(ident())) - else expr() + if (inPattern) dropAnyBraces(pattern()) + else { + if (in.token == IDENTIFIER) atPos(in.offset)(Ident(ident())) + else expr() + } } } if (in.token == STRINGLIT) partsBuf += literal() @@ -1850,7 +1856,7 @@ self => case INTLIT | LONGLIT | FLOATLIT | DOUBLELIT => t match { case Ident(nme.MINUS) => - return atPos(start) { literal(isNegated = true) } + return atPos(start) { literal(isNegated = true, inPattern = true) } case _ => } case _ => @@ -1868,7 +1874,7 @@ self => atPos(start, start) { Ident(nme.WILDCARD) } case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | STRINGLIT | INTERPOLATIONID | SYMBOLLIT | TRUE | FALSE | NULL => - atPos(start) { literal() } + atPos(start) { literal(inPattern = true) } case LPAREN => atPos(start)(makeParens(noSeq.patterns())) case XMLSTART => -- cgit v1.2.3 From b92eb70113a03fe989a57482f6308fefadf74137 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 5 Apr 2012 15:27:55 +0200 Subject: enable implicit enrichment when typing patterns --- .../scala/tools/nsc/typechecker/Contexts.scala | 25 ++++++++++++++++++-- .../scala/tools/nsc/typechecker/Typers.scala | 27 +++++++++++++++++++--- test/files/run/virtpatmat_stringinterp.check | 1 + test/files/run/virtpatmat_stringinterp.flags | 1 + test/files/run/virtpatmat_stringinterp.scala | 13 +++++++++++ 5 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 test/files/run/virtpatmat_stringinterp.check create mode 100644 test/files/run/virtpatmat_stringinterp.flags create mode 100644 test/files/run/virtpatmat_stringinterp.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index fe1c90fe67..e2d4efab83 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -67,6 +67,7 @@ trait Contexts { self: Analyzer => val c = sc.make(unit, tree, sc.owner, sc.scope, sc.imports) if (erasedTypes) c.setThrowErrors() else c.setReportErrors() c.implicitsEnabled = !erasedTypes + c.enrichmentEnabled = c.implicitsEnabled c } @@ -106,7 +107,7 @@ trait Contexts { self: Analyzer => var depth: Int = 0 var imports: List[ImportInfo] = List() // currently visible imports var openImplicits: List[(Type,Tree)] = List() // types for which implicit arguments - // are currently searched + // are currently searched // for a named application block (Tree) the corresponding NamedApplyInfo var namedApplyBlockInfo: Option[(Tree, NamedApplyInfo)] = None var prefix: Type = NoPrefix @@ -120,6 +121,7 @@ trait Contexts { self: Analyzer => var diagnostic: List[String] = Nil // these messages are printed when issuing an error var implicitsEnabled = false var macrosEnabled = true + var enrichmentEnabled = false // to selectively allow enrichment in patterns, where other kinds of implicit conversions are not allowed var checking = false var retyping = false @@ -192,8 +194,25 @@ trait Contexts { self: Analyzer => def withImplicitsDisabled[T](op: => T): T = { val saved = implicitsEnabled implicitsEnabled = false + val savedP = enrichmentEnabled + enrichmentEnabled = false try op - finally implicitsEnabled = saved + finally { + implicitsEnabled = saved + enrichmentEnabled = savedP + } + } + + def withImplicitsDisabledAllowEnrichment[T](op: => T): T = { + val saved = implicitsEnabled + implicitsEnabled = false + val savedP = enrichmentEnabled + enrichmentEnabled = true + try op + finally { + implicitsEnabled = saved + enrichmentEnabled = savedP + } } def withMacrosEnabled[T](op: => T): T = { @@ -246,6 +265,7 @@ trait Contexts { self: Analyzer => c.typingIndentLevel = typingIndentLevel c.implicitsEnabled = this.implicitsEnabled c.macrosEnabled = this.macrosEnabled + c.enrichmentEnabled = this.enrichmentEnabled c.checking = this.checking c.retyping = this.retyping c.openImplicits = this.openImplicits @@ -298,6 +318,7 @@ trait Contexts { self: Analyzer => def makeImplicit(reportAmbiguousErrors: Boolean) = { val c = makeSilent(reportAmbiguousErrors) c.implicitsEnabled = false + c.enrichmentEnabled = false c } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2b7c8e8304..a6a670f163 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1171,7 +1171,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { && !qtpe.typeSymbol.isBottomClass && qtpe != WildcardType && !qual.isInstanceOf[ApplyImplicitView] // don't chain views - && context.implicitsEnabled + && (context.implicitsEnabled || context.enrichmentEnabled) // Elaborating `context.implicitsEnabled`: // don't try to adapt a top-level type that's the subject of an implicit search // this happens because, if isView, typedImplicit tries to apply the "current" implicit value to @@ -4063,7 +4063,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } else { member(qual, name) } - if (sym == NoSymbol && name != nme.CONSTRUCTOR && (mode & EXPRmode) != 0) { + + // symbol not found? --> try to convert implicitly to a type that does have the required member + // added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an xml member to StringContext, which in turn has an unapply[Seq] method) + if (sym == NoSymbol && name != nme.CONSTRUCTOR && (mode & (EXPRmode | PATTERNmode)) != 0) { val qual1 = if (member(qual, name) != NoSymbol) qual else adaptToMemberWithArgs(tree, qual, name, mode, true, true) @@ -4071,6 +4074,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (qual1 ne qual) return typed(treeCopy.Select(tree, qual1, name), mode, pt) } + if (!reallyExists(sym)) { if (context.owner.enclosingTopLevelClass.isJavaDefined && name.isTypeName) { val tree1 = atPos(tree.pos) { gen.convertToSelectFromType(qual, name) } @@ -4806,6 +4810,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { ptLine("typing %s: pt = %s".format(ptTree(tree), pt), "undetparams" -> context.undetparams, "implicitsEnabled" -> context.implicitsEnabled, + "enrichmentEnabled" -> context.enrichmentEnabled, + "mode" -> modeString(mode), "silent" -> context.bufferErrors, "context.owner" -> context.owner ) @@ -4909,7 +4915,22 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // We disable implicits because otherwise some constructs will // type check which should not. The pattern matcher does not // perform implicit conversions in an attempt to consummate a match. - context.withImplicitsDisabled(typed(tree, PATTERNmode, pt)) + + // on the one hand, + // "abc" match { case Seq('a', 'b', 'c') => true } + // should be ruled out statically, otherwise this is a runtime + // error both because there is an implicit from String to Seq + // (even though such implicits are not used by the matcher) and + // because the typer is fine with concluding that "abc" might + // be of type "String with Seq[T]" and thus eligible for a call + // to unapplySeq. + + // on the other hand, we want to be able to use implicits to add members retro-actively (e.g., add xml to StringContext) + + // as a compromise, context.enrichmentEnabled tells adaptToMember to go ahead and enrich, + // but arbitrary conversions (in adapt) are disabled + // TODO: can we achieve the pattern matching bit of the string interpolation SIP without this? + context.withImplicitsDisabledAllowEnrichment(typed(tree, PATTERNmode, pt)) } /** Types a (fully parameterized) type tree */ diff --git a/test/files/run/virtpatmat_stringinterp.check b/test/files/run/virtpatmat_stringinterp.check new file mode 100644 index 0000000000..7927f4f2d9 --- /dev/null +++ b/test/files/run/virtpatmat_stringinterp.check @@ -0,0 +1 @@ +Node(1) diff --git a/test/files/run/virtpatmat_stringinterp.flags b/test/files/run/virtpatmat_stringinterp.flags new file mode 100644 index 0000000000..0612c4f8ff --- /dev/null +++ b/test/files/run/virtpatmat_stringinterp.flags @@ -0,0 +1 @@ +-Xexperimental -Yvirtpatmat \ No newline at end of file diff --git a/test/files/run/virtpatmat_stringinterp.scala b/test/files/run/virtpatmat_stringinterp.scala new file mode 100644 index 0000000000..213712f17a --- /dev/null +++ b/test/files/run/virtpatmat_stringinterp.scala @@ -0,0 +1,13 @@ +object Test extends App { + case class Node(x: Int) + + implicit def sc2xml(sc: StringContext): XMLContext = new XMLContext(sc) + class XMLContext(sc: StringContext) { + object xml { + def unapplySeq(xml: Node): Option[Seq[Node]] = Some(List(Node(1))) + } + } + + val x: Node = Node(0) + x match { case xml"""""" => println(a) } +} \ No newline at end of file -- cgit v1.2.3 From beae7735b845c680331fd68004d52e681fe3b8d1 Mon Sep 17 00:00:00 2001 From: Simon Ochsenreither Date: Fri, 13 Apr 2012 18:59:35 +0200 Subject: Improved formatting/display of documentation. Made the primary constructors private to prevent them from appearing in ScalaDoc. --- src/compiler/scala/tools/cmd/gen/AnyVals.scala | 48 +++--- src/library/scala/Boolean.scala | 4 +- src/library/scala/Byte.scala | 206 ++++++++++++------------- src/library/scala/Char.scala | 206 ++++++++++++------------- src/library/scala/Double.scala | 162 +++++++++---------- src/library/scala/Float.scala | 162 +++++++++---------- src/library/scala/Int.scala | 206 ++++++++++++------------- src/library/scala/Long.scala | 206 ++++++++++++------------- src/library/scala/Short.scala | 206 ++++++++++++------------- src/library/scala/Unit.scala | 4 +- 10 files changed, 705 insertions(+), 705 deletions(-) diff --git a/src/compiler/scala/tools/cmd/gen/AnyVals.scala b/src/compiler/scala/tools/cmd/gen/AnyVals.scala index 0869350dd3..85f0d65d6b 100644 --- a/src/compiler/scala/tools/cmd/gen/AnyVals.scala +++ b/src/compiler/scala/tools/cmd/gen/AnyVals.scala @@ -19,15 +19,15 @@ trait AnyValReps { def unaryOps = { val ops = List( Op("+", "/**\n" + - " * @return this value, unmodified\n" + + " * Returns this value, unmodified.\n" + " */"), Op("-", "/**\n" + - " * @return the negation of this value\n" + + " * Returns the negation of this value.\n" + " */")) if(isCardinal) Op("~", "/**\n" + - " * @return the bitwise negation of this value\n" + + " * Returns the bitwise negation of this value.\n" + " * @example {{{\n" + " * ~5 == -6\n" + " * // in binary: ~00000101 ==\n" + @@ -41,7 +41,7 @@ trait AnyValReps { if (isCardinal) List( Op("|", "/**\n" + - " * @return the bitwise OR of this value and x\n" + + " * Returns the bitwise OR of this value and `x`.\n" + " * @example {{{\n" + " * (0xf0 | 0xaa) == 0xfa\n" + " * // in binary: 11110000\n" + @@ -51,7 +51,7 @@ trait AnyValReps { " * }}}\n" + " */"), Op("&", "/**\n" + - " * @return the bitwise AND of this value and x\n" + + " * Returns the bitwise AND of this value and `x`.\n" + " * @example {{{\n" + " * (0xf0 & 0xaa) == 0xa0\n" + " * // in binary: 11110000\n" + @@ -61,7 +61,7 @@ trait AnyValReps { " * }}}\n" + " */"), Op("^", "/**\n" + - " * @return the bitwise XOR of this value and x\n" + + " * Returns the bitwise XOR of this value and `x`.\n" + " * @example {{{\n" + " * (0xf0 ^ 0xaa) == 0x5a\n" + " * // in binary: 11110000\n" + @@ -76,13 +76,13 @@ trait AnyValReps { if (isCardinal) List( Op("<<", "/**\n" + - " * @return this value bit-shifted left by the specified number of bits,\n" + + " * Returns this value bit-shifted left by the specified number of bits,\n" + " * filling in the new right bits with zeroes.\n" + " * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}\n" + " */"), Op(">>>", "/**\n" + - " * @return this value bit-shifted right by the specified number of bits,\n" + + " * Returns this value bit-shifted right by the specified number of bits,\n" + " * filling the new left bits with zeroes.\n" + " * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}\n" + " * @example {{{\n" + @@ -93,7 +93,7 @@ trait AnyValReps { " */"), Op(">>", "/**\n" + - " * @return this value bit-shifted left by the specified number of bits,\n" + + " * Returns this value bit-shifted left by the specified number of bits,\n" + " * filling in the right bits with the same value as the left-most bit of this.\n" + " * The effect of this is to retain the sign of the value.\n" + " * @example {{{\n" + @@ -105,19 +105,19 @@ trait AnyValReps { else Nil def comparisonOps = List( - Op("==", "/**\n * @return `true` if this value is equal x, `false` otherwise\n */"), - Op("!=", "/**\n * @return `true` if this value is not equal to x, `false` otherwise\n */"), - Op("<", "/**\n * @return `true` if this value is less than x, `false` otherwise\n */"), - Op("<=", "/**\n * @return `true` if this value is less than or equal to x, `false` otherwise\n */"), - Op(">", "/**\n * @return `true` if this value is greater than x, `false` otherwise\n */"), - Op(">=", "/**\n * @return `true` if this value is greater than or equal to x, `false` otherwise\n */")) + Op("==", "/**\n * Returns `true` if this value is equal to x, `false` otherwise.\n */"), + Op("!=", "/**\n * Returns `true` if this value is not equal to x, `false` otherwise.\n */"), + Op("<", "/**\n * Returns `true` if this value is less than x, `false` otherwise.\n */"), + Op("<=", "/**\n * Returns `true` if this value is less than or equal to x, `false` otherwise.\n */"), + Op(">", "/**\n * Returns `true` if this value is greater than x, `false` otherwise.\n */"), + Op(">=", "/**\n * Returns `true` if this value is greater than or equal to x, `false` otherwise.\n */")) def otherOps = List( - Op("+", "/**\n * @return the sum of this value and x\n */"), - Op("-", "/**\n * @return the difference of this value and x\n */"), - Op("*", "/**\n * @return the product of this value and x\n */"), - Op("/", "/**\n * @return the quotient of this value and x\n */"), - Op("%", "/**\n * @return the remainder of the division of this value by x\n */")) + Op("+", "/**\n * Returns the sum of this value and `x`.\n */"), + Op("-", "/**\n * Returns the difference of this value and `x`.\n */"), + Op("*", "/**\n * Returns the product of this value and `x`.\n */"), + Op("/", "/**\n * Returns the quotient of this value and `x`.\n */"), + Op("%", "/**\n * Returns the remainder of the division of this value by `x`.\n */")) // Given two numeric value types S and T , the operation type of S and T is defined as follows: // If both S and T are subrange types then the operation type of S and T is Int. @@ -224,8 +224,8 @@ trait AnyValReps { def classDoc = interpolate(classDocTemplate) def objectDoc = "" def mkImports = "" - def mkClass = assemble("final class", "AnyVal", classLines) + "\n" - def mkObject = assemble("object", "AnyValCompanion", objectLines) + "\n" + def mkClass = assemble("final class", "private", "AnyVal", classLines) + "\n" + def mkObject = assemble("object", "", "AnyValCompanion", objectLines) + "\n" def make() = List[String]( headerTemplate, mkImports, @@ -235,8 +235,8 @@ trait AnyValReps { mkObject ) mkString "" - def assemble(what: String, parent: String, lines: List[String]): String = { - val decl = "%s %s extends %s ".format(what, name, parent) + def assemble(what: String, ctor: String, parent: String, lines: List[String]): String = { + val decl = "%s %s %s extends %s ".format(what, name, ctor, parent) val body = if (lines.isEmpty) "{ }\n\n" else lines map indent mkString ("{\n", "\n", "\n}\n") decl + body diff --git a/src/library/scala/Boolean.scala b/src/library/scala/Boolean.scala index 5078e59d28..edb82b33fe 100644 --- a/src/library/scala/Boolean.scala +++ b/src/library/scala/Boolean.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Boolean]] => [[scala.runtime.RichBoolean]] * which provides useful non-primitive operations. */ -final class Boolean extends AnyVal { +final class Boolean private extends AnyVal { /** * Negates a Boolean expression. * @@ -110,7 +110,7 @@ final class Boolean extends AnyVal { override def getClass(): Class[Boolean] = sys.error("stub") } -object Boolean extends AnyValCompanion { +object Boolean extends AnyValCompanion { /** Transform a value type into a boxed reference type. * diff --git a/src/library/scala/Byte.scala b/src/library/scala/Byte.scala index f9c5f6003e..38861752c6 100644 --- a/src/library/scala/Byte.scala +++ b/src/library/scala/Byte.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Byte]] => [[scala.runtime.RichByte]] * which provides useful non-primitive operations. */ -final class Byte extends AnyVal { +final class Byte private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,7 +27,7 @@ final class Byte extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return the bitwise negation of this value + * Returns the bitwise negation of this value. * @example {{{ * ~5 == -6 * // in binary: ~00000101 == @@ -36,30 +36,30 @@ final class Byte extends AnyVal { */ def unary_~ : Int = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Int = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Int = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -70,7 +70,7 @@ final class Byte extends AnyVal { */ def >>>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -81,7 +81,7 @@ final class Byte extends AnyVal { */ def >>>(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -92,7 +92,7 @@ final class Byte extends AnyVal { */ def >>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -104,181 +104,181 @@ final class Byte extends AnyVal { def >>(x: Long): Int = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -289,7 +289,7 @@ final class Byte extends AnyVal { */ def |(x: Byte): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -300,7 +300,7 @@ final class Byte extends AnyVal { */ def |(x: Short): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -311,7 +311,7 @@ final class Byte extends AnyVal { */ def |(x: Char): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -322,7 +322,7 @@ final class Byte extends AnyVal { */ def |(x: Int): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -334,7 +334,7 @@ final class Byte extends AnyVal { def |(x: Long): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -345,7 +345,7 @@ final class Byte extends AnyVal { */ def &(x: Byte): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -356,7 +356,7 @@ final class Byte extends AnyVal { */ def &(x: Short): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -367,7 +367,7 @@ final class Byte extends AnyVal { */ def &(x: Char): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -378,7 +378,7 @@ final class Byte extends AnyVal { */ def &(x: Int): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -390,7 +390,7 @@ final class Byte extends AnyVal { def &(x: Long): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -401,7 +401,7 @@ final class Byte extends AnyVal { */ def ^(x: Byte): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -412,7 +412,7 @@ final class Byte extends AnyVal { */ def ^(x: Short): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -423,7 +423,7 @@ final class Byte extends AnyVal { */ def ^(x: Char): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -434,7 +434,7 @@ final class Byte extends AnyVal { */ def ^(x: Int): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -446,154 +446,154 @@ final class Byte extends AnyVal { def ^(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Byte] = sys.error("stub") } -object Byte extends AnyValCompanion { +object Byte extends AnyValCompanion { /** The smallest value representable as a Byte. */ final val MinValue = java.lang.Byte.MIN_VALUE diff --git a/src/library/scala/Char.scala b/src/library/scala/Char.scala index 3d459782cd..4504abfd73 100644 --- a/src/library/scala/Char.scala +++ b/src/library/scala/Char.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Char]] => [[scala.runtime.RichChar]] * which provides useful non-primitive operations. */ -final class Char extends AnyVal { +final class Char private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,7 +27,7 @@ final class Char extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return the bitwise negation of this value + * Returns the bitwise negation of this value. * @example {{{ * ~5 == -6 * // in binary: ~00000101 == @@ -36,30 +36,30 @@ final class Char extends AnyVal { */ def unary_~ : Int = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Int = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Int = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -70,7 +70,7 @@ final class Char extends AnyVal { */ def >>>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -81,7 +81,7 @@ final class Char extends AnyVal { */ def >>>(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -92,7 +92,7 @@ final class Char extends AnyVal { */ def >>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -104,181 +104,181 @@ final class Char extends AnyVal { def >>(x: Long): Int = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -289,7 +289,7 @@ final class Char extends AnyVal { */ def |(x: Byte): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -300,7 +300,7 @@ final class Char extends AnyVal { */ def |(x: Short): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -311,7 +311,7 @@ final class Char extends AnyVal { */ def |(x: Char): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -322,7 +322,7 @@ final class Char extends AnyVal { */ def |(x: Int): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -334,7 +334,7 @@ final class Char extends AnyVal { def |(x: Long): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -345,7 +345,7 @@ final class Char extends AnyVal { */ def &(x: Byte): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -356,7 +356,7 @@ final class Char extends AnyVal { */ def &(x: Short): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -367,7 +367,7 @@ final class Char extends AnyVal { */ def &(x: Char): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -378,7 +378,7 @@ final class Char extends AnyVal { */ def &(x: Int): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -390,7 +390,7 @@ final class Char extends AnyVal { def &(x: Long): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -401,7 +401,7 @@ final class Char extends AnyVal { */ def ^(x: Byte): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -412,7 +412,7 @@ final class Char extends AnyVal { */ def ^(x: Short): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -423,7 +423,7 @@ final class Char extends AnyVal { */ def ^(x: Char): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -434,7 +434,7 @@ final class Char extends AnyVal { */ def ^(x: Int): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -446,154 +446,154 @@ final class Char extends AnyVal { def ^(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Char] = sys.error("stub") } -object Char extends AnyValCompanion { +object Char extends AnyValCompanion { /** The smallest value representable as a Char. */ final val MinValue = java.lang.Character.MIN_VALUE diff --git a/src/library/scala/Double.scala b/src/library/scala/Double.scala index 01414265c4..bb659b963a 100644 --- a/src/library/scala/Double.scala +++ b/src/library/scala/Double.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Double]] => [[scala.runtime.RichDouble]] * which provides useful non-primitive operations. */ -final class Double extends AnyVal { +final class Double private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,339 +27,339 @@ final class Double extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Double = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Double = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Double] = sys.error("stub") } -object Double extends AnyValCompanion { +object Double extends AnyValCompanion { /** The smallest positive value greater than 0.0d which is * representable as a Double. */ diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala index ff5b3cb112..3352c89aa1 100644 --- a/src/library/scala/Float.scala +++ b/src/library/scala/Float.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Float]] => [[scala.runtime.RichFloat]] * which provides useful non-primitive operations. */ -final class Float extends AnyVal { +final class Float private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,339 +27,339 @@ final class Float extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Float = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Float = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Float] = sys.error("stub") } -object Float extends AnyValCompanion { +object Float extends AnyValCompanion { /** The smallest positive value greater than 0.0f which is * representable as a Float. */ diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala index 316bbced2d..6cf3e97c63 100644 --- a/src/library/scala/Int.scala +++ b/src/library/scala/Int.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Int]] => [[scala.runtime.RichInt]] * which provides useful non-primitive operations. */ -final class Int extends AnyVal { +final class Int private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,7 +27,7 @@ final class Int extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return the bitwise negation of this value + * Returns the bitwise negation of this value. * @example {{{ * ~5 == -6 * // in binary: ~00000101 == @@ -36,30 +36,30 @@ final class Int extends AnyVal { */ def unary_~ : Int = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Int = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Int = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -70,7 +70,7 @@ final class Int extends AnyVal { */ def >>>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -81,7 +81,7 @@ final class Int extends AnyVal { */ def >>>(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -92,7 +92,7 @@ final class Int extends AnyVal { */ def >>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -104,181 +104,181 @@ final class Int extends AnyVal { def >>(x: Long): Int = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -289,7 +289,7 @@ final class Int extends AnyVal { */ def |(x: Byte): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -300,7 +300,7 @@ final class Int extends AnyVal { */ def |(x: Short): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -311,7 +311,7 @@ final class Int extends AnyVal { */ def |(x: Char): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -322,7 +322,7 @@ final class Int extends AnyVal { */ def |(x: Int): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -334,7 +334,7 @@ final class Int extends AnyVal { def |(x: Long): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -345,7 +345,7 @@ final class Int extends AnyVal { */ def &(x: Byte): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -356,7 +356,7 @@ final class Int extends AnyVal { */ def &(x: Short): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -367,7 +367,7 @@ final class Int extends AnyVal { */ def &(x: Char): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -378,7 +378,7 @@ final class Int extends AnyVal { */ def &(x: Int): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -390,7 +390,7 @@ final class Int extends AnyVal { def &(x: Long): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -401,7 +401,7 @@ final class Int extends AnyVal { */ def ^(x: Byte): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -412,7 +412,7 @@ final class Int extends AnyVal { */ def ^(x: Short): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -423,7 +423,7 @@ final class Int extends AnyVal { */ def ^(x: Char): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -434,7 +434,7 @@ final class Int extends AnyVal { */ def ^(x: Int): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -446,154 +446,154 @@ final class Int extends AnyVal { def ^(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Int] = sys.error("stub") } -object Int extends AnyValCompanion { +object Int extends AnyValCompanion { /** The smallest value representable as a Int. */ final val MinValue = java.lang.Integer.MIN_VALUE diff --git a/src/library/scala/Long.scala b/src/library/scala/Long.scala index ce8618c22a..d316b28035 100644 --- a/src/library/scala/Long.scala +++ b/src/library/scala/Long.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Long]] => [[scala.runtime.RichLong]] * which provides useful non-primitive operations. */ -final class Long extends AnyVal { +final class Long private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,7 +27,7 @@ final class Long extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return the bitwise negation of this value + * Returns the bitwise negation of this value. * @example {{{ * ~5 == -6 * // in binary: ~00000101 == @@ -36,30 +36,30 @@ final class Long extends AnyVal { */ def unary_~ : Long = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Long = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Long = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Int): Long = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Long): Long = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -70,7 +70,7 @@ final class Long extends AnyVal { */ def >>>(x: Int): Long = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -81,7 +81,7 @@ final class Long extends AnyVal { */ def >>>(x: Long): Long = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -92,7 +92,7 @@ final class Long extends AnyVal { */ def >>(x: Int): Long = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -104,181 +104,181 @@ final class Long extends AnyVal { def >>(x: Long): Long = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -289,7 +289,7 @@ final class Long extends AnyVal { */ def |(x: Byte): Long = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -300,7 +300,7 @@ final class Long extends AnyVal { */ def |(x: Short): Long = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -311,7 +311,7 @@ final class Long extends AnyVal { */ def |(x: Char): Long = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -322,7 +322,7 @@ final class Long extends AnyVal { */ def |(x: Int): Long = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -334,7 +334,7 @@ final class Long extends AnyVal { def |(x: Long): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -345,7 +345,7 @@ final class Long extends AnyVal { */ def &(x: Byte): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -356,7 +356,7 @@ final class Long extends AnyVal { */ def &(x: Short): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -367,7 +367,7 @@ final class Long extends AnyVal { */ def &(x: Char): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -378,7 +378,7 @@ final class Long extends AnyVal { */ def &(x: Int): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -390,7 +390,7 @@ final class Long extends AnyVal { def &(x: Long): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -401,7 +401,7 @@ final class Long extends AnyVal { */ def ^(x: Byte): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -412,7 +412,7 @@ final class Long extends AnyVal { */ def ^(x: Short): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -423,7 +423,7 @@ final class Long extends AnyVal { */ def ^(x: Char): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -434,7 +434,7 @@ final class Long extends AnyVal { */ def ^(x: Int): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -446,154 +446,154 @@ final class Long extends AnyVal { def ^(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Long] = sys.error("stub") } -object Long extends AnyValCompanion { +object Long extends AnyValCompanion { /** The smallest value representable as a Long. */ final val MinValue = java.lang.Long.MIN_VALUE diff --git a/src/library/scala/Short.scala b/src/library/scala/Short.scala index 5664c3b44c..b92a02152a 100644 --- a/src/library/scala/Short.scala +++ b/src/library/scala/Short.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Short]] => [[scala.runtime.RichShort]] * which provides useful non-primitive operations. */ -final class Short extends AnyVal { +final class Short private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,7 +27,7 @@ final class Short extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return the bitwise negation of this value + * Returns the bitwise negation of this value. * @example {{{ * ~5 == -6 * // in binary: ~00000101 == @@ -36,30 +36,30 @@ final class Short extends AnyVal { */ def unary_~ : Int = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Int = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Int = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -70,7 +70,7 @@ final class Short extends AnyVal { */ def >>>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -81,7 +81,7 @@ final class Short extends AnyVal { */ def >>>(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -92,7 +92,7 @@ final class Short extends AnyVal { */ def >>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -104,181 +104,181 @@ final class Short extends AnyVal { def >>(x: Long): Int = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -289,7 +289,7 @@ final class Short extends AnyVal { */ def |(x: Byte): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -300,7 +300,7 @@ final class Short extends AnyVal { */ def |(x: Short): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -311,7 +311,7 @@ final class Short extends AnyVal { */ def |(x: Char): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -322,7 +322,7 @@ final class Short extends AnyVal { */ def |(x: Int): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -334,7 +334,7 @@ final class Short extends AnyVal { def |(x: Long): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -345,7 +345,7 @@ final class Short extends AnyVal { */ def &(x: Byte): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -356,7 +356,7 @@ final class Short extends AnyVal { */ def &(x: Short): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -367,7 +367,7 @@ final class Short extends AnyVal { */ def &(x: Char): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -378,7 +378,7 @@ final class Short extends AnyVal { */ def &(x: Int): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -390,7 +390,7 @@ final class Short extends AnyVal { def &(x: Long): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -401,7 +401,7 @@ final class Short extends AnyVal { */ def ^(x: Byte): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -412,7 +412,7 @@ final class Short extends AnyVal { */ def ^(x: Short): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -423,7 +423,7 @@ final class Short extends AnyVal { */ def ^(x: Char): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -434,7 +434,7 @@ final class Short extends AnyVal { */ def ^(x: Int): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -446,154 +446,154 @@ final class Short extends AnyVal { def ^(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Short] = sys.error("stub") } -object Short extends AnyValCompanion { +object Short extends AnyValCompanion { /** The smallest value representable as a Short. */ final val MinValue = java.lang.Short.MIN_VALUE diff --git a/src/library/scala/Unit.scala b/src/library/scala/Unit.scala index f6ed0121ab..3da5c083d4 100644 --- a/src/library/scala/Unit.scala +++ b/src/library/scala/Unit.scala @@ -16,11 +16,11 @@ package scala * runtime system. A method with return type `Unit` is analogous to a Java * method which is declared `void`. */ -final class Unit extends AnyVal { +final class Unit private extends AnyVal { override def getClass(): Class[Unit] = sys.error("stub") } -object Unit extends AnyValCompanion { +object Unit extends AnyValCompanion { /** Transform a value type into a boxed reference type. * -- cgit v1.2.3 From cc764e944817628cbca3f7b5a195cdb495ca8f38 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 13 Apr 2012 12:40:59 -0700 Subject: Added languageFeature annotation (was missing before). Resolved problem with late loading of nested classes in Definitions. Resolved handling of deprecated idents `then` and `macro`. Massaged test flags. --- .../scala/reflect/internal/Definitions.scala | 30 ++++++--- .../scala/tools/nsc/ast/parser/Parsers.scala | 75 +++------------------- .../scala/tools/nsc/ast/parser/Scanners.scala | 38 +++++++---- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- .../scala/annotation/meta/languageFeature.scala | 13 ++++ test/files/neg/macro-argtype-mismatch.flags | 2 +- test/files/neg/macro-basic-mamdmi.flags | 2 +- test/files/neg/macro-cyclic.flags | 2 +- test/files/neg/macro-invalidimpl-a.flags | 2 +- test/files/neg/macro-invalidimpl-b.flags | 2 +- test/files/neg/macro-invalidimpl-c.flags | 2 +- test/files/neg/macro-invalidimpl-d.flags | 2 +- test/files/neg/macro-invalidimpl-e.flags | 2 +- test/files/neg/macro-invalidimpl-f.flags | 2 +- test/files/neg/macro-invalidimpl-g.flags | 2 +- test/files/neg/macro-invalidimpl-h.flags | 2 +- test/files/neg/macro-invalidret-nontree.flags | 2 +- .../neg/macro-invalidret-nonuniversetree.flags | 2 +- test/files/neg/macro-invalidshape-a.flags | 2 +- test/files/neg/macro-invalidshape-b.flags | 2 +- test/files/neg/macro-invalidshape-c.flags | 2 +- test/files/neg/macro-invalidshape-d.flags | 2 +- .../neg/macro-invalidsig-context-bounds.flags | 2 +- test/files/neg/macro-invalidsig-ctx-badargc.flags | 2 +- test/files/neg/macro-invalidsig-ctx-badtype.flags | 2 +- .../neg/macro-invalidsig-ctx-badvarargs.flags | 2 +- test/files/neg/macro-invalidsig-ctx-noctx.flags | 2 +- .../neg/macro-invalidsig-implicit-params.flags | 2 +- .../neg/macro-invalidsig-params-badargc.flags | 2 +- .../neg/macro-invalidsig-params-badtype.flags | 2 +- .../neg/macro-invalidsig-params-badvarargs.flags | 2 +- .../neg/macro-invalidsig-params-namemismatch.flags | 2 +- .../neg/macro-invalidsig-tparams-badtype.flags | 2 +- .../neg/macro-invalidsig-tparams-bounds-a.flags | 2 +- .../neg/macro-invalidsig-tparams-bounds-b.flags | 2 +- .../neg/macro-invalidsig-tparams-notparams-a.flags | 2 +- .../neg/macro-invalidsig-tparams-notparams-b.flags | 2 +- .../neg/macro-invalidsig-tparams-notparams-c.flags | 2 +- test/files/neg/macro-invalidusage-badargs.flags | 2 +- test/files/neg/macro-invalidusage-badbounds.flags | 2 +- test/files/neg/macro-invalidusage-badtargs.flags | 2 +- .../neg/macro-invalidusage-methodvaluesyntax.flags | 2 +- test/files/neg/macro-keyword.flags | 2 +- test/files/neg/macro-noexpand.flags | 2 +- test/files/neg/macro-noncompilertree.flags | 2 +- test/files/neg/macro-nontree.flags | 2 +- test/files/neg/macro-nontypeablebody.flags | 2 +- ...verride-macro-overrides-abstract-method-a.flags | 2 +- ...verride-macro-overrides-abstract-method-b.flags | 2 +- .../macro-override-method-overrides-macro.flags | 2 +- test/files/pos/hkarray.flags | 2 +- test/files/pos/t1439.flags | 2 +- test/files/run/macro-abort-fresh.flags | 2 +- test/files/run/macro-basic-ma-md-mi.flags | 2 +- test/files/run/macro-basic-ma-mdmi.flags | 2 +- test/files/run/macro-basic-mamd-mi.flags | 2 +- test/files/run/macro-bodyexpandstoimpl.flags | 2 +- test/files/run/macro-declared-in-annotation.flags | 2 +- test/files/run/macro-declared-in-anonymous.flags | 2 +- test/files/run/macro-declared-in-block.flags | 2 +- test/files/run/macro-declared-in-class-class.flags | 2 +- .../files/run/macro-declared-in-class-object.flags | 2 +- test/files/run/macro-declared-in-class.flags | 2 +- .../run/macro-declared-in-default-param.flags | 2 +- .../run/macro-declared-in-implicit-class.flags | 2 +- test/files/run/macro-declared-in-method.flags | 2 +- .../files/run/macro-declared-in-object-class.flags | 2 +- .../run/macro-declared-in-object-object.flags | 2 +- test/files/run/macro-declared-in-object.flags | 2 +- .../run/macro-declared-in-package-object.flags | 2 +- test/files/run/macro-declared-in-refinement.flags | 2 +- test/files/run/macro-declared-in-trait.flags | 2 +- test/files/run/macro-def-infer-return-type-a.flags | 2 +- test/files/run/macro-def-infer-return-type-b.flags | 2 +- test/files/run/macro-def-infer-return-type-c.flags | 2 +- test/files/run/macro-def-path-dependent-a.flags | 2 +- test/files/run/macro-def-path-dependent-b.flags | 2 +- test/files/run/macro-def-path-dependent-c.flags | 2 +- test/files/run/macro-def-path-dependent-d.flags | 2 +- .../macro-expand-implicit-macro-has-implicit.flags | 2 +- .../macro-expand-implicit-macro-is-implicit.flags | 2 +- .../run/macro-expand-implicit-macro-is-val.flags | 2 +- .../run/macro-expand-implicit-macro-is-view.flags | 2 +- .../files/run/macro-expand-multiple-arglists.flags | 2 +- test/files/run/macro-expand-nullary-generic.flags | 2 +- .../run/macro-expand-nullary-nongeneric.flags | 2 +- test/files/run/macro-expand-overload.flags | 2 +- test/files/run/macro-expand-override.flags | 2 +- test/files/run/macro-expand-recursive.flags | 2 +- test/files/run/macro-expand-tparams-bounds-a.flags | 2 +- test/files/run/macro-expand-tparams-bounds-b.flags | 2 +- test/files/run/macro-expand-tparams-explicit.flags | 2 +- test/files/run/macro-expand-tparams-implicit.flags | 2 +- .../run/macro-expand-tparams-only-in-impl.flags | 2 +- test/files/run/macro-expand-tparams-optional.flags | 2 +- test/files/run/macro-expand-tparams-prefix-a.flags | 2 +- test/files/run/macro-expand-tparams-prefix-b.flags | 2 +- .../files/run/macro-expand-tparams-prefix-c1.flags | 2 +- .../files/run/macro-expand-tparams-prefix-c2.flags | 2 +- .../files/run/macro-expand-tparams-prefix-d1.flags | 2 +- ...pand-varargs-explicit-over-nonvarargs-bad.flags | 2 +- ...and-varargs-explicit-over-nonvarargs-good.flags | 2 +- ...acro-expand-varargs-explicit-over-varargs.flags | 2 +- ...o-expand-varargs-implicit-over-nonvarargs.flags | 2 +- ...acro-expand-varargs-implicit-over-varargs.flags | 2 +- test/files/run/macro-impl-default-params.flags | 2 +- test/files/run/macro-impl-rename-context.flags | 2 +- ...-invalidret-doesnt-conform-to-def-rettype.flags | 2 +- ...invalidret-doesnt-conform-to-impl-rettype.flags | 2 +- test/files/run/macro-invalidret-nontypeable.flags | 2 +- test/files/run/macro-invalidusage-badret.flags | 2 +- .../macro-invalidusage-partialapplication.flags | 2 +- test/files/run/macro-openmacros.flags | 2 +- test/files/run/macro-quasiinvalidbody-c.flags | 2 +- test/files/run/macro-range.flags | 2 +- .../run/macro-reflective-ma-normal-mdmi.flags | 2 +- test/files/run/macro-reify-basic.flags | 2 +- test/files/run/macro-reify-eval-eval.flags | 2 +- .../files/run/macro-reify-eval-outside-reify.flags | 2 +- test/files/run/macro-reify-freevars.flags | 2 +- test/files/run/macro-reify-nested-a.flags | 2 +- test/files/run/macro-reify-nested-b.flags | 2 +- .../files/run/macro-reify-ref-to-packageless.flags | 2 +- test/files/run/macro-reify-tagful-a.flags | 2 +- test/files/run/macro-reify-tagless-a.flags | 2 +- test/files/run/macro-reify-unreify.flags | 2 +- .../run/macro-reify-value-outside-reify.flags | 2 +- test/files/run/macro-rettype-mismatch.flags | 2 +- test/files/run/macro-settings.flags | 2 +- test/files/run/macro-sip19-revised.flags | 2 +- test/files/run/macro-sip19.flags | 2 +- .../run/macro-typecheck-implicitsdisabled.flags | 2 +- .../files/run/macro-typecheck-macrosdisabled.flags | 2 +- test/files/run/macro-undetparams-consfromsls.flags | 2 +- test/files/run/macro-undetparams-implicitval.flags | 2 +- test/files/run/macro-undetparams-macroitself.flags | 2 +- 136 files changed, 200 insertions(+), 220 deletions(-) create mode 100644 src/library/scala/annotation/meta/languageFeature.scala diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 6689a9dbb8..72fca5da12 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -924,17 +924,18 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val ClassTargetClass = getMetaAnnotation("companionClass") lazy val ObjectTargetClass = getMetaAnnotation("companionObject") lazy val MethodTargetClass = getMetaAnnotation("companionMethod") // TODO: module, moduleClass? package, packageObject? - lazy val LanguageFeatureClass = getMetaAnnotation("languageFeature") + lazy val LanguageFeatureAnnot = getMetaAnnotation("languageFeature") // Language features lazy val languageFeatureModule = getRequiredModule("scala.languageFeature") - lazy val MacrosFeature = getRequiredClass("scala.languageFeature.experimental.macros") - lazy val DynamicsFeature = getRequiredClass("scala.languageFeature.dynamics") - lazy val PostfixOpsFeature = getRequiredClass("scala.languageFeature.postfixOps") - lazy val ReflectiveCallsFeature = getRequiredClass("scala.languageFeature.reflectiveCalls") - lazy val ImplicitConversionsFeature = getRequiredClass("scala.languageFeature.implicitConversions") - lazy val HigherKindsFeature = getRequiredClass("scala.languageFeature.higherKinds") - lazy val ExistentialsFeature = getRequiredClass("scala.languageFeature.existentials") + lazy val experimentalModule = getMember(languageFeatureModule, newTermName("experimental")) + lazy val MacrosFeature = getLanguageFeature("macros", experimentalModule) + lazy val DynamicsFeature = getLanguageFeature("dynamics") + lazy val PostfixOpsFeature = getLanguageFeature("postfixOps") + lazy val ReflectiveCallsFeature = getLanguageFeature("reflectiveCalls") + lazy val ImplicitConversionsFeature = getLanguageFeature("implicitConversions") + lazy val HigherKindsFeature = getLanguageFeature("higherKinds") + lazy val ExistentialsFeature = getLanguageFeature("existentials") private def getMetaAnnotation(name: String) = getRequiredClass("scala.annotation.meta." + name) def isMetaAnnotation(sym: Symbol): Boolean = metaAnnotations(sym) || ( @@ -986,6 +987,9 @@ trait Definitions extends reflect.api.StandardDefinitions { try getModule(fullname.toTermName) catch { case _: MissingRequirementError => NoSymbol } + def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule) = + 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)) @@ -1005,7 +1009,13 @@ trait Definitions extends reflect.api.StandardDefinitions { def getMember(owner: Symbol, name: Name): Symbol = { getMemberIfDefined(owner, name) orElse { - throw new FatalError(owner + " does not have a member " + name) + if (phase.flatClasses && name.isTypeName && !owner.isPackageObjectOrClass) { + val pkg = owner.owner + val flatname = nme.flattenedName(owner.name, name) + getMember(pkg, flatname) + } else { + throw new FatalError(owner + " does not have a member " + name) + } } } def getMemberIfDefined(owner: Symbol, name: Name): Symbol = @@ -1022,7 +1032,7 @@ trait Definitions extends reflect.api.StandardDefinitions { } def getDeclIfDefined(owner: Symbol, name: Name): Symbol = owner.info.nonPrivateDecl(name) - + def packageExists(packageName: String): Boolean = getModuleIfDefined(packageName).isPackage diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index ef11427677..65225b185b 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1773,21 +1773,7 @@ self => */ def pattern2(): Tree = { val nameOffset = in.offset - def warnIfMacro(tree: Tree): Unit = { - def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) - warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") - tree match { - case _: BackQuotedIdent => - ; - case Ident(name) => - check(name) - case _ => - ; - } - } - val p = pattern3() - warnIfMacro(p) if (in.token != AT) p else p match { @@ -2463,8 +2449,6 @@ self => val nameOffset = in.offset val isBackquoted = in.token == BACKQUOTED_IDENT val name = ident() - if (name.toString == nme.MACROkw.toString && !isBackquoted) - warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") funDefRest(start, nameOffset, mods, name) } } @@ -2480,7 +2464,7 @@ self => val vparamss = paramClauses(name, contextBoundBuf.toList, false) newLineOptWhenFollowedBy(LBRACE) var restype = fromWithinReturnType(typedOpt()) - val rhs = + val rhs = if (isStatSep || in.token == RBRACE) { if (restype.isEmpty) restype = scalaUnitConstr newmods |= Flags.DEFERRED @@ -2489,11 +2473,15 @@ self => restype = scalaUnitConstr blockExpr() } else { - accept(EQUALS) - if (settings.Xmacros.value && in.token == MACRO || // [Martin] Xmacros can be retired now - in.token == IDENTIFIER && in.name == nme.MACROkw) { - in.nextToken() - newmods |= Flags.MACRO + if (in.token == EQUALS) { + in.nextTokenAllow(nme.MACROkw) + if (settings.Xmacros.value && in.token == MACRO || // [Martin] Xmacros can be retired now + in.token == IDENTIFIER && in.name == nme.MACROkw) { + in.nextToken() + newmods |= Flags.MACRO + } + } else { + accept(EQUALS) } expr() } @@ -2556,8 +2544,6 @@ self => val nameOffset = in.offset val isBackquoted = in.token == BACKQUOTED_IDENT val name = identForType() - if (name.toString == nme.MACROkw.toString && !isBackquoted) - warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") // @M! a type alias as well as an abstract type may declare type parameters val tparams = typeParamClauseOpt(name, null) in.token match { @@ -2617,9 +2603,6 @@ self => val nameOffset = in.offset val isBackquoted = in.token == BACKQUOTED_IDENT val name = identForType() - if (name.toString == nme.MACROkw.toString && !isBackquoted) - warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") - atPos(start, if (name == tpnme.ERROR) start else nameOffset) { savingClassContextBounds { val contextBoundBuf = new ListBuffer[Tree] @@ -2661,8 +2644,6 @@ self => val nameOffset = in.offset val isBackquoted = in.token == BACKQUOTED_IDENT val name = ident() - if (name.toString == nme.MACROkw.toString && !isBackquoted) - warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") val tstart = in.offset atPos(start, if (name == nme.ERROR) start else nameOffset) { val mods1 = if (in.token == SUBTYPE) mods | Flags.DEFERRED else mods @@ -2841,24 +2822,7 @@ self => */ def packaging(start: Int): Tree = { val nameOffset = in.offset - def warnIfMacro(tree: Tree): Unit = { - def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) - warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") - tree match { - case _: BackQuotedIdent => - ; - case Ident(name) => - check(name) - case Select(qual, name) => - warnIfMacro(qual) - check(name) - case _ => - ; - } - } - val pkg = pkgQualId() - warnIfMacro(pkg) val stats = inBracesOrNil(topStatSeq()) makePackaging(start, pkg, stats) } @@ -3061,27 +3025,8 @@ self => } } else { val nameOffset = in.offset - def warnIfMacro(tree: Tree): Unit = { - def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) - warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") - tree match { - // [Eugene] pkgQualId never returns BackQuotedIdents - // this means that we'll get spurious warnings even if we wrap macro package name in backquotes - case _: BackQuotedIdent => - ; - case Ident(name) => - check(name) - case Select(qual, name) => - warnIfMacro(qual) - check(name) - case _ => - ; - } - } - in.flushDoc val pkg = pkgQualId() - warnIfMacro(pkg) if (in.token == EOF) { ts += makePackaging(start, pkg, List()) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index c75e806b2a..105db805d8 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -113,20 +113,19 @@ trait Scanners extends ScannersCommon { } /** Clear buffer and set name and token */ - private def finishNamed() { + private def finishNamed(idtoken: Int = IDENTIFIER) { name = newTermName(cbuf.toString) - token = name2token(name) - cbuf.clear() - } - - /** Convert name to token */ - private def name2token(name: Name) = { + token = idtoken val idx = name.start - kwOffset if (idx >= 0 && idx < kwArray.length) { - val token = kwArray(idx) - if (token == IDENTIFIER) deprecationWarning(name+" is now a reserved word; usage as an identifier is deprecated") - token - } else IDENTIFIER + token = kwArray(idx) + if (token == IDENTIFIER) { + if (idtoken == IDENTIFIER && allowIdent != name) + deprecationWarning(name+" is now a reserved word; usage as an identifier is deprecated") + token = idtoken + } + } + cbuf.clear() } /** Clear buffer and set string */ @@ -200,6 +199,20 @@ trait Scanners extends ScannersCommon { off } + /** Allow an otherwise deprecated ident here */ + private var allowIdent: Name = nme.EMPTY + + /** Get next token, and allow the otherwise deprecated ident `name` */ + def nextTokenAllow(name: Name) = { + val prev = allowIdent + allowIdent = name + try { + nextToken() + } finally { + allowIdent = prev + } + } + /** Produce next token, filling TokenData fields of Scanner. */ def nextToken() { @@ -572,9 +585,8 @@ trait Scanners extends ScannersCommon { getLitChars('`') if (ch == '`') { nextChar() - finishNamed() + finishNamed(BACKQUOTED_IDENT) if (name.length == 0) syntaxError("empty quoted identifier") - token = BACKQUOTED_IDENT } else syntaxError("unclosed quoted identifier") } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index b1cbc53044..1425cd4755 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -743,7 +743,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def hasOption = settings.language.value contains featureName if (!hasImport && !hasOption) { val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) = - featureTrait getAnnotation LanguageFeatureClass + featureTrait getAnnotation LanguageFeatureAnnot val req = if (required) "needs to" else "should" var raw = featureDesc + " " + req + " be enabled\n" + "by making the implicit value language." + featureName + " visible." diff --git a/src/library/scala/annotation/meta/languageFeature.scala b/src/library/scala/annotation/meta/languageFeature.scala new file mode 100644 index 0000000000..23acc01b51 --- /dev/null +++ b/src/library/scala/annotation/meta/languageFeature.scala @@ -0,0 +1,13 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ +package scala.annotation.meta + +/** + * An annotation giving particulars for a language feature in object `scala.language`. + */ +final class languageFeature(feature: String, enableRequired: Boolean) extends annotation.StaticAnnotation diff --git a/test/files/neg/macro-argtype-mismatch.flags b/test/files/neg/macro-argtype-mismatch.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-argtype-mismatch.flags +++ b/test/files/neg/macro-argtype-mismatch.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-basic-mamdmi.flags b/test/files/neg/macro-basic-mamdmi.flags index 06a7b31f11..5e5dd6ce79 100644 --- a/test/files/neg/macro-basic-mamdmi.flags +++ b/test/files/neg/macro-basic-mamdmi.flags @@ -1 +1 @@ --Xmacros +-language:experimental.macros diff --git a/test/files/neg/macro-cyclic.flags b/test/files/neg/macro-cyclic.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-cyclic.flags +++ b/test/files/neg/macro-cyclic.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-a.flags b/test/files/neg/macro-invalidimpl-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-a.flags +++ b/test/files/neg/macro-invalidimpl-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-b.flags b/test/files/neg/macro-invalidimpl-b.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-b.flags +++ b/test/files/neg/macro-invalidimpl-b.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c.flags b/test/files/neg/macro-invalidimpl-c.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-c.flags +++ b/test/files/neg/macro-invalidimpl-c.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d.flags b/test/files/neg/macro-invalidimpl-d.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-d.flags +++ b/test/files/neg/macro-invalidimpl-d.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-e.flags b/test/files/neg/macro-invalidimpl-e.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-e.flags +++ b/test/files/neg/macro-invalidimpl-e.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-f.flags b/test/files/neg/macro-invalidimpl-f.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-f.flags +++ b/test/files/neg/macro-invalidimpl-f.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-g.flags b/test/files/neg/macro-invalidimpl-g.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-g.flags +++ b/test/files/neg/macro-invalidimpl-g.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-h.flags b/test/files/neg/macro-invalidimpl-h.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-h.flags +++ b/test/files/neg/macro-invalidimpl-h.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nontree.flags b/test/files/neg/macro-invalidret-nontree.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidret-nontree.flags +++ b/test/files/neg/macro-invalidret-nontree.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nonuniversetree.flags b/test/files/neg/macro-invalidret-nonuniversetree.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidret-nonuniversetree.flags +++ b/test/files/neg/macro-invalidret-nonuniversetree.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-a.flags b/test/files/neg/macro-invalidshape-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidshape-a.flags +++ b/test/files/neg/macro-invalidshape-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-b.flags b/test/files/neg/macro-invalidshape-b.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidshape-b.flags +++ b/test/files/neg/macro-invalidshape-b.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-c.flags b/test/files/neg/macro-invalidshape-c.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidshape-c.flags +++ b/test/files/neg/macro-invalidshape-c.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d.flags b/test/files/neg/macro-invalidshape-d.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidshape-d.flags +++ b/test/files/neg/macro-invalidshape-d.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-context-bounds.flags b/test/files/neg/macro-invalidsig-context-bounds.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-context-bounds.flags +++ b/test/files/neg/macro-invalidsig-context-bounds.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badargc.flags b/test/files/neg/macro-invalidsig-ctx-badargc.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-ctx-badargc.flags +++ b/test/files/neg/macro-invalidsig-ctx-badargc.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badtype.flags b/test/files/neg/macro-invalidsig-ctx-badtype.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-ctx-badtype.flags +++ b/test/files/neg/macro-invalidsig-ctx-badtype.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs.flags b/test/files/neg/macro-invalidsig-ctx-badvarargs.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-ctx-badvarargs.flags +++ b/test/files/neg/macro-invalidsig-ctx-badvarargs.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-noctx.flags b/test/files/neg/macro-invalidsig-ctx-noctx.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-ctx-noctx.flags +++ b/test/files/neg/macro-invalidsig-ctx-noctx.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-implicit-params.flags b/test/files/neg/macro-invalidsig-implicit-params.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-implicit-params.flags +++ b/test/files/neg/macro-invalidsig-implicit-params.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badargc.flags b/test/files/neg/macro-invalidsig-params-badargc.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-params-badargc.flags +++ b/test/files/neg/macro-invalidsig-params-badargc.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badtype.flags b/test/files/neg/macro-invalidsig-params-badtype.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-params-badtype.flags +++ b/test/files/neg/macro-invalidsig-params-badtype.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badvarargs.flags b/test/files/neg/macro-invalidsig-params-badvarargs.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-params-badvarargs.flags +++ b/test/files/neg/macro-invalidsig-params-badvarargs.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-namemismatch.flags b/test/files/neg/macro-invalidsig-params-namemismatch.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-params-namemismatch.flags +++ b/test/files/neg/macro-invalidsig-params-namemismatch.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-badtype.flags b/test/files/neg/macro-invalidsig-tparams-badtype.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-tparams-badtype.flags +++ b/test/files/neg/macro-invalidsig-tparams-badtype.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a.flags b/test/files/neg/macro-invalidsig-tparams-bounds-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-tparams-bounds-a.flags +++ b/test/files/neg/macro-invalidsig-tparams-bounds-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b.flags b/test/files/neg/macro-invalidsig-tparams-bounds-b.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-tparams-bounds-b.flags +++ b/test/files/neg/macro-invalidsig-tparams-bounds-b.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a.flags b/test/files/neg/macro-invalidsig-tparams-notparams-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-tparams-notparams-a.flags +++ b/test/files/neg/macro-invalidsig-tparams-notparams-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b.flags b/test/files/neg/macro-invalidsig-tparams-notparams-b.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-tparams-notparams-b.flags +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c.flags b/test/files/neg/macro-invalidsig-tparams-notparams-c.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidsig-tparams-notparams-c.flags +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badargs.flags b/test/files/neg/macro-invalidusage-badargs.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidusage-badargs.flags +++ b/test/files/neg/macro-invalidusage-badargs.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badbounds.flags b/test/files/neg/macro-invalidusage-badbounds.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidusage-badbounds.flags +++ b/test/files/neg/macro-invalidusage-badbounds.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badtargs.flags b/test/files/neg/macro-invalidusage-badtargs.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidusage-badtargs.flags +++ b/test/files/neg/macro-invalidusage-badtargs.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax.flags b/test/files/neg/macro-invalidusage-methodvaluesyntax.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-invalidusage-methodvaluesyntax.flags +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-keyword.flags b/test/files/neg/macro-keyword.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-keyword.flags +++ b/test/files/neg/macro-keyword.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-noexpand.flags b/test/files/neg/macro-noexpand.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-noexpand.flags +++ b/test/files/neg/macro-noexpand.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-noncompilertree.flags b/test/files/neg/macro-noncompilertree.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-noncompilertree.flags +++ b/test/files/neg/macro-noncompilertree.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-nontree.flags b/test/files/neg/macro-nontree.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-nontree.flags +++ b/test/files/neg/macro-nontree.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-nontypeablebody.flags b/test/files/neg/macro-nontypeablebody.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-nontypeablebody.flags +++ b/test/files/neg/macro-nontypeablebody.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags b/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags b/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-override-method-overrides-macro.flags b/test/files/neg/macro-override-method-overrides-macro.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/neg/macro-override-method-overrides-macro.flags +++ b/test/files/neg/macro-override-method-overrides-macro.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/pos/hkarray.flags b/test/files/pos/hkarray.flags index e8fb65d50c..e745d8bbe3 100644 --- a/test/files/pos/hkarray.flags +++ b/test/files/pos/hkarray.flags @@ -1 +1 @@ --Xfatal-warnings \ No newline at end of file +-Xfatal-warnings -language:higherKinds \ No newline at end of file diff --git a/test/files/pos/t1439.flags b/test/files/pos/t1439.flags index 779916d58f..830f024342 100644 --- a/test/files/pos/t1439.flags +++ b/test/files/pos/t1439.flags @@ -1 +1 @@ --unchecked -Xfatal-warnings \ No newline at end of file +-unchecked -Xfatal-warnings -language:higher-kinds \ No newline at end of file diff --git a/test/files/run/macro-abort-fresh.flags b/test/files/run/macro-abort-fresh.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-abort-fresh.flags +++ b/test/files/run/macro-abort-fresh.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-md-mi.flags b/test/files/run/macro-basic-ma-md-mi.flags index 06a7b31f11..5e5dd6ce79 100644 --- a/test/files/run/macro-basic-ma-md-mi.flags +++ b/test/files/run/macro-basic-ma-md-mi.flags @@ -1 +1 @@ --Xmacros +-language:experimental.macros diff --git a/test/files/run/macro-basic-ma-mdmi.flags b/test/files/run/macro-basic-ma-mdmi.flags index 06a7b31f11..5e5dd6ce79 100644 --- a/test/files/run/macro-basic-ma-mdmi.flags +++ b/test/files/run/macro-basic-ma-mdmi.flags @@ -1 +1 @@ --Xmacros +-language:experimental.macros diff --git a/test/files/run/macro-basic-mamd-mi.flags b/test/files/run/macro-basic-mamd-mi.flags index 06a7b31f11..5e5dd6ce79 100644 --- a/test/files/run/macro-basic-mamd-mi.flags +++ b/test/files/run/macro-basic-mamd-mi.flags @@ -1 +1 @@ --Xmacros +-language:experimental.macros diff --git a/test/files/run/macro-bodyexpandstoimpl.flags b/test/files/run/macro-bodyexpandstoimpl.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-bodyexpandstoimpl.flags +++ b/test/files/run/macro-bodyexpandstoimpl.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation.flags b/test/files/run/macro-declared-in-annotation.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-annotation.flags +++ b/test/files/run/macro-declared-in-annotation.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-anonymous.flags b/test/files/run/macro-declared-in-anonymous.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-anonymous.flags +++ b/test/files/run/macro-declared-in-anonymous.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-block.flags b/test/files/run/macro-declared-in-block.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-block.flags +++ b/test/files/run/macro-declared-in-block.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-class.flags b/test/files/run/macro-declared-in-class-class.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-class-class.flags +++ b/test/files/run/macro-declared-in-class-class.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-object.flags b/test/files/run/macro-declared-in-class-object.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-class-object.flags +++ b/test/files/run/macro-declared-in-class-object.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class.flags b/test/files/run/macro-declared-in-class.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-class.flags +++ b/test/files/run/macro-declared-in-class.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-default-param.flags b/test/files/run/macro-declared-in-default-param.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-default-param.flags +++ b/test/files/run/macro-declared-in-default-param.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-implicit-class.flags b/test/files/run/macro-declared-in-implicit-class.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-implicit-class.flags +++ b/test/files/run/macro-declared-in-implicit-class.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-method.flags b/test/files/run/macro-declared-in-method.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-method.flags +++ b/test/files/run/macro-declared-in-method.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-class.flags b/test/files/run/macro-declared-in-object-class.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-object-class.flags +++ b/test/files/run/macro-declared-in-object-class.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-object.flags b/test/files/run/macro-declared-in-object-object.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-object-object.flags +++ b/test/files/run/macro-declared-in-object-object.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object.flags b/test/files/run/macro-declared-in-object.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-object.flags +++ b/test/files/run/macro-declared-in-object.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-package-object.flags b/test/files/run/macro-declared-in-package-object.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-package-object.flags +++ b/test/files/run/macro-declared-in-package-object.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-refinement.flags b/test/files/run/macro-declared-in-refinement.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-refinement.flags +++ b/test/files/run/macro-declared-in-refinement.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-trait.flags b/test/files/run/macro-declared-in-trait.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-trait.flags +++ b/test/files/run/macro-declared-in-trait.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a.flags b/test/files/run/macro-def-infer-return-type-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-def-infer-return-type-a.flags +++ b/test/files/run/macro-def-infer-return-type-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b.flags b/test/files/run/macro-def-infer-return-type-b.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-def-infer-return-type-b.flags +++ b/test/files/run/macro-def-infer-return-type-b.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c.flags b/test/files/run/macro-def-infer-return-type-c.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-def-infer-return-type-c.flags +++ b/test/files/run/macro-def-infer-return-type-c.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-a.flags b/test/files/run/macro-def-path-dependent-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-def-path-dependent-a.flags +++ b/test/files/run/macro-def-path-dependent-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-b.flags b/test/files/run/macro-def-path-dependent-b.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-def-path-dependent-b.flags +++ b/test/files/run/macro-def-path-dependent-b.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-c.flags b/test/files/run/macro-def-path-dependent-c.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-def-path-dependent-c.flags +++ b/test/files/run/macro-def-path-dependent-c.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d.flags b/test/files/run/macro-def-path-dependent-d.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-def-path-dependent-d.flags +++ b/test/files/run/macro-def-path-dependent-d.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit.flags b/test/files/run/macro-expand-implicit-macro-has-implicit.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-implicit-macro-has-implicit.flags +++ b/test/files/run/macro-expand-implicit-macro-has-implicit.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit.flags b/test/files/run/macro-expand-implicit-macro-is-implicit.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-implicit-macro-is-implicit.flags +++ b/test/files/run/macro-expand-implicit-macro-is-implicit.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-val.flags b/test/files/run/macro-expand-implicit-macro-is-val.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-implicit-macro-is-val.flags +++ b/test/files/run/macro-expand-implicit-macro-is-val.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-view.flags b/test/files/run/macro-expand-implicit-macro-is-view.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-implicit-macro-is-view.flags +++ b/test/files/run/macro-expand-implicit-macro-is-view.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-multiple-arglists.flags b/test/files/run/macro-expand-multiple-arglists.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-multiple-arglists.flags +++ b/test/files/run/macro-expand-multiple-arglists.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-generic.flags b/test/files/run/macro-expand-nullary-generic.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-nullary-generic.flags +++ b/test/files/run/macro-expand-nullary-generic.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-nongeneric.flags b/test/files/run/macro-expand-nullary-nongeneric.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-nullary-nongeneric.flags +++ b/test/files/run/macro-expand-nullary-nongeneric.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-overload.flags b/test/files/run/macro-expand-overload.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-overload.flags +++ b/test/files/run/macro-expand-overload.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-override.flags b/test/files/run/macro-expand-override.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-override.flags +++ b/test/files/run/macro-expand-override.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-recursive.flags b/test/files/run/macro-expand-recursive.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-recursive.flags +++ b/test/files/run/macro-expand-recursive.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-a.flags b/test/files/run/macro-expand-tparams-bounds-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-bounds-a.flags +++ b/test/files/run/macro-expand-tparams-bounds-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-b.flags b/test/files/run/macro-expand-tparams-bounds-b.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-bounds-b.flags +++ b/test/files/run/macro-expand-tparams-bounds-b.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-explicit.flags b/test/files/run/macro-expand-tparams-explicit.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-explicit.flags +++ b/test/files/run/macro-expand-tparams-explicit.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-implicit.flags b/test/files/run/macro-expand-tparams-implicit.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-implicit.flags +++ b/test/files/run/macro-expand-tparams-implicit.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-only-in-impl.flags b/test/files/run/macro-expand-tparams-only-in-impl.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-only-in-impl.flags +++ b/test/files/run/macro-expand-tparams-only-in-impl.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-optional.flags b/test/files/run/macro-expand-tparams-optional.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-optional.flags +++ b/test/files/run/macro-expand-tparams-optional.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a.flags b/test/files/run/macro-expand-tparams-prefix-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-prefix-a.flags +++ b/test/files/run/macro-expand-tparams-prefix-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b.flags b/test/files/run/macro-expand-tparams-prefix-b.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-prefix-b.flags +++ b/test/files/run/macro-expand-tparams-prefix-b.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1.flags b/test/files/run/macro-expand-tparams-prefix-c1.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-prefix-c1.flags +++ b/test/files/run/macro-expand-tparams-prefix-c1.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2.flags b/test/files/run/macro-expand-tparams-prefix-c2.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-prefix-c2.flags +++ b/test/files/run/macro-expand-tparams-prefix-c2.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1.flags b/test/files/run/macro-expand-tparams-prefix-d1.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-tparams-prefix-d1.flags +++ b/test/files/run/macro-expand-tparams-prefix-d1.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs.flags b/test/files/run/macro-expand-varargs-explicit-over-varargs.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-varargs-explicit-over-varargs.flags +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs.flags b/test/files/run/macro-expand-varargs-implicit-over-varargs.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-expand-varargs-implicit-over-varargs.flags +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-impl-default-params.flags b/test/files/run/macro-impl-default-params.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-impl-default-params.flags +++ b/test/files/run/macro-impl-default-params.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-impl-rename-context.flags b/test/files/run/macro-impl-rename-context.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-impl-rename-context.flags +++ b/test/files/run/macro-impl-rename-context.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags +++ b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-invalidret-nontypeable.flags b/test/files/run/macro-invalidret-nontypeable.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-invalidret-nontypeable.flags +++ b/test/files/run/macro-invalidret-nontypeable.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-badret.flags b/test/files/run/macro-invalidusage-badret.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-invalidusage-badret.flags +++ b/test/files/run/macro-invalidusage-badret.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-partialapplication.flags b/test/files/run/macro-invalidusage-partialapplication.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-invalidusage-partialapplication.flags +++ b/test/files/run/macro-invalidusage-partialapplication.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-openmacros.flags b/test/files/run/macro-openmacros.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-openmacros.flags +++ b/test/files/run/macro-openmacros.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-quasiinvalidbody-c.flags b/test/files/run/macro-quasiinvalidbody-c.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-quasiinvalidbody-c.flags +++ b/test/files/run/macro-quasiinvalidbody-c.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-range.flags b/test/files/run/macro-range.flags index 06a7b31f11..5e5dd6ce79 100644 --- a/test/files/run/macro-range.flags +++ b/test/files/run/macro-range.flags @@ -1 +1 @@ --Xmacros +-language:experimental.macros diff --git a/test/files/run/macro-reflective-ma-normal-mdmi.flags b/test/files/run/macro-reflective-ma-normal-mdmi.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reflective-ma-normal-mdmi.flags +++ b/test/files/run/macro-reflective-ma-normal-mdmi.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-basic.flags b/test/files/run/macro-reify-basic.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-basic.flags +++ b/test/files/run/macro-reify-basic.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-eval.flags b/test/files/run/macro-reify-eval-eval.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-eval-eval.flags +++ b/test/files/run/macro-reify-eval-eval.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-outside-reify.flags b/test/files/run/macro-reify-eval-outside-reify.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-eval-outside-reify.flags +++ b/test/files/run/macro-reify-eval-outside-reify.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-freevars.flags b/test/files/run/macro-reify-freevars.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-freevars.flags +++ b/test/files/run/macro-reify-freevars.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-a.flags b/test/files/run/macro-reify-nested-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-nested-a.flags +++ b/test/files/run/macro-reify-nested-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-b.flags b/test/files/run/macro-reify-nested-b.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-nested-b.flags +++ b/test/files/run/macro-reify-nested-b.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-ref-to-packageless.flags b/test/files/run/macro-reify-ref-to-packageless.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-ref-to-packageless.flags +++ b/test/files/run/macro-reify-ref-to-packageless.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-tagful-a.flags b/test/files/run/macro-reify-tagful-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-tagful-a.flags +++ b/test/files/run/macro-reify-tagful-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-tagless-a.flags b/test/files/run/macro-reify-tagless-a.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-tagless-a.flags +++ b/test/files/run/macro-reify-tagless-a.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-unreify.flags b/test/files/run/macro-reify-unreify.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-unreify.flags +++ b/test/files/run/macro-reify-unreify.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-reify-value-outside-reify.flags b/test/files/run/macro-reify-value-outside-reify.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-reify-value-outside-reify.flags +++ b/test/files/run/macro-reify-value-outside-reify.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-rettype-mismatch.flags b/test/files/run/macro-rettype-mismatch.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-rettype-mismatch.flags +++ b/test/files/run/macro-rettype-mismatch.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-settings.flags b/test/files/run/macro-settings.flags index cdc7512197..15479e30b8 100644 --- a/test/files/run/macro-settings.flags +++ b/test/files/run/macro-settings.flags @@ -1 +1 @@ --Xmacros -Xmacro-settings:hello=1 \ No newline at end of file +-language:experimental.macros -Xmacro-settings:hello=1 \ No newline at end of file diff --git a/test/files/run/macro-sip19-revised.flags b/test/files/run/macro-sip19-revised.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-sip19-revised.flags +++ b/test/files/run/macro-sip19-revised.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-sip19.flags b/test/files/run/macro-sip19.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-sip19.flags +++ b/test/files/run/macro-sip19.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-typecheck-implicitsdisabled.flags b/test/files/run/macro-typecheck-implicitsdisabled.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-typecheck-implicitsdisabled.flags +++ b/test/files/run/macro-typecheck-implicitsdisabled.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-typecheck-macrosdisabled.flags b/test/files/run/macro-typecheck-macrosdisabled.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-typecheck-macrosdisabled.flags +++ b/test/files/run/macro-typecheck-macrosdisabled.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-undetparams-consfromsls.flags b/test/files/run/macro-undetparams-consfromsls.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-undetparams-consfromsls.flags +++ b/test/files/run/macro-undetparams-consfromsls.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-undetparams-implicitval.flags b/test/files/run/macro-undetparams-implicitval.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-undetparams-implicitval.flags +++ b/test/files/run/macro-undetparams-implicitval.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-undetparams-macroitself.flags b/test/files/run/macro-undetparams-macroitself.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/files/run/macro-undetparams-macroitself.flags +++ b/test/files/run/macro-undetparams-macroitself.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file -- cgit v1.2.3 From 1d0610840bb7409f0da084d3cc94e4110dd2e2c4 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 13 Apr 2012 23:15:25 +0100 Subject: Renamed seven files. Hey everyone, if classnames don't match filenames, ant will recompile said file on every run until the end of time. Still here, ant is. --- .../makro/runtime/AbortMacroException.scala | 6 + .../scala/reflect/makro/runtime/Errors.scala | 6 - src/compiler/scala/reflect/reify/Reifier.scala | 154 +++++++++++++++++++ src/compiler/scala/reflect/reify/Reifiers.scala | 154 ------------------- .../scala/concurrent/util/duration/IntMult.scala | 18 +++ .../util/duration/NumericMultiplication.scala | 18 --- src/library/scala/reflect/ArrayTag.scala | 19 +++ src/library/scala/reflect/ArrayTags.scala | 19 --- src/library/scala/reflect/ClassTag.scala | 167 +++++++++++++++++++++ src/library/scala/reflect/ClassTags.scala | 167 --------------------- src/library/scala/reflect/api/Attachment.scala | 16 ++ src/library/scala/reflect/api/Attachments.scala | 16 -- .../scala/reflect/makro/internal/Utils.scala | 133 ++++++++++++++++ .../scala/reflect/makro/internal/typeTagImpl.scala | 133 ---------------- 14 files changed, 513 insertions(+), 513 deletions(-) create mode 100644 src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala delete mode 100644 src/compiler/scala/reflect/makro/runtime/Errors.scala create mode 100644 src/compiler/scala/reflect/reify/Reifier.scala delete mode 100644 src/compiler/scala/reflect/reify/Reifiers.scala create mode 100644 src/library/scala/concurrent/util/duration/IntMult.scala delete mode 100644 src/library/scala/concurrent/util/duration/NumericMultiplication.scala create mode 100644 src/library/scala/reflect/ArrayTag.scala delete mode 100644 src/library/scala/reflect/ArrayTags.scala create mode 100644 src/library/scala/reflect/ClassTag.scala delete mode 100644 src/library/scala/reflect/ClassTags.scala create mode 100644 src/library/scala/reflect/api/Attachment.scala delete mode 100644 src/library/scala/reflect/api/Attachments.scala create mode 100644 src/library/scala/reflect/makro/internal/Utils.scala delete mode 100644 src/library/scala/reflect/makro/internal/typeTagImpl.scala diff --git a/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala b/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala new file mode 100644 index 0000000000..d78eae9237 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala @@ -0,0 +1,6 @@ +package scala.reflect.makro +package runtime + +import scala.reflect.api.Position + +class AbortMacroException(val pos: Position, val msg: String) extends Throwable(msg) diff --git a/src/compiler/scala/reflect/makro/runtime/Errors.scala b/src/compiler/scala/reflect/makro/runtime/Errors.scala deleted file mode 100644 index d78eae9237..0000000000 --- a/src/compiler/scala/reflect/makro/runtime/Errors.scala +++ /dev/null @@ -1,6 +0,0 @@ -package scala.reflect.makro -package runtime - -import scala.reflect.api.Position - -class AbortMacroException(val pos: Position, val msg: String) extends Throwable(msg) diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala new file mode 100644 index 0000000000..16c26734b2 --- /dev/null +++ b/src/compiler/scala/reflect/reify/Reifier.scala @@ -0,0 +1,154 @@ +package scala.reflect +package reify + +import scala.tools.nsc.Global + +/** Given a tree or a type, generate a tree that when executed at runtime produces the original tree or type. + * See more info in the comments to ``reify'' in scala.reflect.api.Universe. + * + * @author Martin Odersky + * @version 2.10 + */ +abstract class Reifier extends Phases + with Errors { + + val mirror: Global + import mirror._ + import definitions._ + import treeInfo._ + + val typer: mirror.analyzer.Typer + val prefix: Tree + val reifee: Any + val dontSpliceAtTopLevel: Boolean + val requireConcreteTypeTag: Boolean + + /** + * For ``reifee'' and other reification parameters, generate a tree of the form + * + * { + * val $mr = <[ prefix ]> + * $mr.Expr[T](rtree) // if data is a Tree + * $mr.TypeTag[T](rtree) // if data is a Type + * } + * + * where + * + * - `prefix` is the tree that represents the universe + * the result will be bound to + * - `rtree` is code that generates `reifee` at runtime. + * - `T` is the type that corresponds to `data`. + * + * This is not a method, but a value to indicate the fact that Reifier instances are a one-off. + */ + lazy val reified: Tree = { + try { + // [Eugene] conventional way of doing this? + if (prefix exists (_.isErroneous)) CannotReifyErroneousPrefix(prefix) + if (prefix.tpe == null) CannotReifyUntypedPrefix(prefix) + + val rtree = reifee match { + case tree: Tree => + reifyTrace("reifying = ")(if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) + reifyTrace("reifee is located at: ")(tree.pos) + reifyTrace("prefix = ")(prefix) + // [Eugene] conventional way of doing this? + if (tree exists (_.isErroneous)) CannotReifyErroneousReifee(prefix) + if (tree.tpe == null) CannotReifyUntypedReifee(tree) + val pipeline = mkReificationPipeline + val rtree = pipeline(tree) + + // consider the following code snippet + // + // val x = reify { class C; new C } + // + // inferred type for x will be C + // but C ceases to exist after reification so this type is clearly incorrect + // however, reify is "just" a library function, so it cannot affect type inference + // + // hence we crash here even though the reification itself goes well + // fortunately, all that it takes to fix the error is to cast "new C" to Object + // so I'm not very much worried about introducing this restriction + if (tree.tpe exists (sub => sub.typeSymbol.isLocalToReifee)) + CannotReifyReifeeThatHasTypeLocalToReifee(tree) + + val manifestedType = typer.packedType(tree, NoSymbol) + val manifestedRtype = reifyType(manifestedType) + val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule + var typeTagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) + var exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType))) + Apply(Apply(exprCtor, List(rtree)), List(Apply(typeTagCtor, List(manifestedRtype)))) + + case tpe: Type => + reifyTrace("reifying = ")(tpe.toString) + reifyTrace("prefix = ")(prefix) + val rtree = reify(tpe) + + val manifestedType = tpe + var tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule + var ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) + Apply(ctor, List(rtree)) + + case _ => + throw new Error("reifee %s of type %s is not supported".format(reifee, if (reifee == null) "null" else reifee.getClass.toString)) + } + + val mirrorAlias = ValDef(NoMods, nme.MIRROR_SHORT, SingletonTypeTree(prefix), prefix) + val wrapped = Block(mirrorAlias :: symbolTable, rtree) + + // todo. why do we resetAllAttrs? + // + // typically we do some preprocessing before reification and + // the code emitted/moved around during preprocessing is very hard to typecheck, so we leave it as it is + // however this "as it is" sometimes doesn't make any sense + // + // ===example 1=== + // we move a freevar from a nested symbol table to a top-level symbol table, + // and then the reference to mr$ becomes screwed up, because nested symbol tables are already typechecked, + // so we have an mr$ symbol that points to the nested mr$ rather than to the top-level one. + // + // ===example 2=== + // we inline a freevar by replacing a reference to it, e.g. $mr.Apply($mr.Select($mr.Ident($mr.newTermName("$mr")), $mr.newTermName("Ident")), List($mr.Ident($mr.newTermName("free$x")))) + // with its original binding (e.g. $mr.Ident("x")) + // we'd love to typecheck the result, but we cannot do this easily, because $mr is external to this tree + // what's even worse, sometimes $mr can point to the top-level symbol table's $mr, which doesn't have any symbol/type yet - + // it's just a ValDef that will be emitted only after the reification is completed + // + // hence, the simplest solution is to erase all attrs so that invalid (as well as non-existent) bindings get rebound correctly + // this is ugly, but it's the best we can do + // + // 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: + // 1) local freetype inlining in Nested + // 2) external freevar moving in Nested + // 3) local freeterm inlining in Metalevels + // 4) trivial tree splice inlining in Reify (Trees.scala) + // 5) trivial type splice inlining in Reify (Types.scala) + val freevarBindings = symbolTable collect { case freedef @ FreeDef(_, _, binding, _) => binding.symbol } toSet + val untyped = resetAllAttrs(wrapped, leaveAlone = { + case ValDef(_, mr, _, _) if mr == nme.MIRROR_SHORT => true + case tree if freevarBindings contains tree.symbol => true + case _ => false + }) + + if (reifyCopypaste) { + if (reifyDebug) println("=============================") + println(reifiedNodeToString(prefix, untyped)) + if (reifyDebug) println("=============================") + } else { + reifyTrace("reified = ")(untyped) + } + + untyped + } catch { + case ex: ReificationError => + throw ex + case ex: UnexpectedReificationError => + throw ex + case ex: Throwable => + throw new UnexpectedReificationError(defaultErrorPosition, "reification crashed", ex) + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/Reifiers.scala b/src/compiler/scala/reflect/reify/Reifiers.scala deleted file mode 100644 index 16c26734b2..0000000000 --- a/src/compiler/scala/reflect/reify/Reifiers.scala +++ /dev/null @@ -1,154 +0,0 @@ -package scala.reflect -package reify - -import scala.tools.nsc.Global - -/** Given a tree or a type, generate a tree that when executed at runtime produces the original tree or type. - * See more info in the comments to ``reify'' in scala.reflect.api.Universe. - * - * @author Martin Odersky - * @version 2.10 - */ -abstract class Reifier extends Phases - with Errors { - - val mirror: Global - import mirror._ - import definitions._ - import treeInfo._ - - val typer: mirror.analyzer.Typer - val prefix: Tree - val reifee: Any - val dontSpliceAtTopLevel: Boolean - val requireConcreteTypeTag: Boolean - - /** - * For ``reifee'' and other reification parameters, generate a tree of the form - * - * { - * val $mr = <[ prefix ]> - * $mr.Expr[T](rtree) // if data is a Tree - * $mr.TypeTag[T](rtree) // if data is a Type - * } - * - * where - * - * - `prefix` is the tree that represents the universe - * the result will be bound to - * - `rtree` is code that generates `reifee` at runtime. - * - `T` is the type that corresponds to `data`. - * - * This is not a method, but a value to indicate the fact that Reifier instances are a one-off. - */ - lazy val reified: Tree = { - try { - // [Eugene] conventional way of doing this? - if (prefix exists (_.isErroneous)) CannotReifyErroneousPrefix(prefix) - if (prefix.tpe == null) CannotReifyUntypedPrefix(prefix) - - val rtree = reifee match { - case tree: Tree => - reifyTrace("reifying = ")(if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) - reifyTrace("reifee is located at: ")(tree.pos) - reifyTrace("prefix = ")(prefix) - // [Eugene] conventional way of doing this? - if (tree exists (_.isErroneous)) CannotReifyErroneousReifee(prefix) - if (tree.tpe == null) CannotReifyUntypedReifee(tree) - val pipeline = mkReificationPipeline - val rtree = pipeline(tree) - - // consider the following code snippet - // - // val x = reify { class C; new C } - // - // inferred type for x will be C - // but C ceases to exist after reification so this type is clearly incorrect - // however, reify is "just" a library function, so it cannot affect type inference - // - // hence we crash here even though the reification itself goes well - // fortunately, all that it takes to fix the error is to cast "new C" to Object - // so I'm not very much worried about introducing this restriction - if (tree.tpe exists (sub => sub.typeSymbol.isLocalToReifee)) - CannotReifyReifeeThatHasTypeLocalToReifee(tree) - - val manifestedType = typer.packedType(tree, NoSymbol) - val manifestedRtype = reifyType(manifestedType) - val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule - var typeTagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) - var exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType))) - Apply(Apply(exprCtor, List(rtree)), List(Apply(typeTagCtor, List(manifestedRtype)))) - - case tpe: Type => - reifyTrace("reifying = ")(tpe.toString) - reifyTrace("prefix = ")(prefix) - val rtree = reify(tpe) - - val manifestedType = tpe - var tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule - var ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) - Apply(ctor, List(rtree)) - - case _ => - throw new Error("reifee %s of type %s is not supported".format(reifee, if (reifee == null) "null" else reifee.getClass.toString)) - } - - val mirrorAlias = ValDef(NoMods, nme.MIRROR_SHORT, SingletonTypeTree(prefix), prefix) - val wrapped = Block(mirrorAlias :: symbolTable, rtree) - - // todo. why do we resetAllAttrs? - // - // typically we do some preprocessing before reification and - // the code emitted/moved around during preprocessing is very hard to typecheck, so we leave it as it is - // however this "as it is" sometimes doesn't make any sense - // - // ===example 1=== - // we move a freevar from a nested symbol table to a top-level symbol table, - // and then the reference to mr$ becomes screwed up, because nested symbol tables are already typechecked, - // so we have an mr$ symbol that points to the nested mr$ rather than to the top-level one. - // - // ===example 2=== - // we inline a freevar by replacing a reference to it, e.g. $mr.Apply($mr.Select($mr.Ident($mr.newTermName("$mr")), $mr.newTermName("Ident")), List($mr.Ident($mr.newTermName("free$x")))) - // with its original binding (e.g. $mr.Ident("x")) - // we'd love to typecheck the result, but we cannot do this easily, because $mr is external to this tree - // what's even worse, sometimes $mr can point to the top-level symbol table's $mr, which doesn't have any symbol/type yet - - // it's just a ValDef that will be emitted only after the reification is completed - // - // hence, the simplest solution is to erase all attrs so that invalid (as well as non-existent) bindings get rebound correctly - // this is ugly, but it's the best we can do - // - // 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: - // 1) local freetype inlining in Nested - // 2) external freevar moving in Nested - // 3) local freeterm inlining in Metalevels - // 4) trivial tree splice inlining in Reify (Trees.scala) - // 5) trivial type splice inlining in Reify (Types.scala) - val freevarBindings = symbolTable collect { case freedef @ FreeDef(_, _, binding, _) => binding.symbol } toSet - val untyped = resetAllAttrs(wrapped, leaveAlone = { - case ValDef(_, mr, _, _) if mr == nme.MIRROR_SHORT => true - case tree if freevarBindings contains tree.symbol => true - case _ => false - }) - - if (reifyCopypaste) { - if (reifyDebug) println("=============================") - println(reifiedNodeToString(prefix, untyped)) - if (reifyDebug) println("=============================") - } else { - reifyTrace("reified = ")(untyped) - } - - untyped - } catch { - case ex: ReificationError => - throw ex - case ex: UnexpectedReificationError => - throw ex - case ex: Throwable => - throw new UnexpectedReificationError(defaultErrorPosition, "reification crashed", ex) - } - } -} \ No newline at end of file diff --git a/src/library/scala/concurrent/util/duration/IntMult.scala b/src/library/scala/concurrent/util/duration/IntMult.scala new file mode 100644 index 0000000000..94c58fb8c2 --- /dev/null +++ b/src/library/scala/concurrent/util/duration/IntMult.scala @@ -0,0 +1,18 @@ +package scala.concurrent.util.duration + +import scala.concurrent.util.{ Duration } + +/* + * Avoid reflection based invocation by using non-duck type + */ +protected[duration] class IntMult(i: Int) { + def *(d: Duration) = d * i +} + +protected[duration] class LongMult(i: Long) { + def *(d: Duration) = d * i +} + +protected[duration] class DoubleMult(f: Double) { + def *(d: Duration) = d * f +} diff --git a/src/library/scala/concurrent/util/duration/NumericMultiplication.scala b/src/library/scala/concurrent/util/duration/NumericMultiplication.scala deleted file mode 100644 index 94c58fb8c2..0000000000 --- a/src/library/scala/concurrent/util/duration/NumericMultiplication.scala +++ /dev/null @@ -1,18 +0,0 @@ -package scala.concurrent.util.duration - -import scala.concurrent.util.{ Duration } - -/* - * Avoid reflection based invocation by using non-duck type - */ -protected[duration] class IntMult(i: Int) { - def *(d: Duration) = d * i -} - -protected[duration] class LongMult(i: Long) { - def *(d: Duration) = d * i -} - -protected[duration] class DoubleMult(f: Double) { - def *(d: Duration) = d * f -} diff --git a/src/library/scala/reflect/ArrayTag.scala b/src/library/scala/reflect/ArrayTag.scala new file mode 100644 index 0000000000..8df7fe5f4e --- /dev/null +++ b/src/library/scala/reflect/ArrayTag.scala @@ -0,0 +1,19 @@ +package scala.reflect + +/** An `ArrayTag[T]` is a descriptor that is requested by the compiler every time + * when an array is instantiated, but the element type is unknown at compile time. + * + * Scala library provides a standard implementation of this trait, + * `ClassTag[T]` that explicitly carries the `java.lang.Class` erasure of type T. + * + * However other platforms (e.g. a Scala -> JS crosscompiler) may reimplement this trait as they see fit + * and then expose the implementation via an implicit macro. + */ +@annotation.implicitNotFound(msg = "No ArrayTag available for ${T}") +trait ArrayTag[T] { + /** Produces an `ArrayTag` that knows how to build `Array[Array[T]]` */ + def wrap: ArrayTag[Array[T]] + + /** Produces a new array with element type `T` and length `len` */ + def newArray(len: Int): Array[T] +} \ No newline at end of file diff --git a/src/library/scala/reflect/ArrayTags.scala b/src/library/scala/reflect/ArrayTags.scala deleted file mode 100644 index 8df7fe5f4e..0000000000 --- a/src/library/scala/reflect/ArrayTags.scala +++ /dev/null @@ -1,19 +0,0 @@ -package scala.reflect - -/** An `ArrayTag[T]` is a descriptor that is requested by the compiler every time - * when an array is instantiated, but the element type is unknown at compile time. - * - * Scala library provides a standard implementation of this trait, - * `ClassTag[T]` that explicitly carries the `java.lang.Class` erasure of type T. - * - * However other platforms (e.g. a Scala -> JS crosscompiler) may reimplement this trait as they see fit - * and then expose the implementation via an implicit macro. - */ -@annotation.implicitNotFound(msg = "No ArrayTag available for ${T}") -trait ArrayTag[T] { - /** Produces an `ArrayTag` that knows how to build `Array[Array[T]]` */ - def wrap: ArrayTag[Array[T]] - - /** Produces a new array with element type `T` and length `len` */ - def newArray(len: Int): Array[T] -} \ No newline at end of file diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala new file mode 100644 index 0000000000..cde6da5539 --- /dev/null +++ b/src/library/scala/reflect/ClassTag.scala @@ -0,0 +1,167 @@ +package scala.reflect + +import java.lang.{ Class => jClass } +import scala.reflect.{ mirror => rm } + +/** A `ClassTag[T]` wraps a Java class, which can be accessed via the `erasure` method. + * + * This is useful in itself, but also enables very important use case. + * Having this knowledge ClassTag can instantiate `Arrays` + * in those cases where the element type is unknown at compile time. + * Hence, ClassTag[T] conforms to the ArrayTag[T] trait. + * + * If an implicit value of type u.ClassTag[T] is required, the compiler will make one up on demand. + * The implicitly created value contains in its erasure field the Java class that is the result of erasing type T. + * In that value, any occurrences of type parameters or abstract types U which come themselves with a ClassTag + * or a reflect.mirror.ConcreteTypeTag are represented by the type referenced by that tag. + * If the type T contains unresolved references to type parameters or abstract types, a static error results. + * + * A ConcreteTypeTag member of the reflect.mirror object is convertible to a ClassTag via an implicit conversion + * (this is not possible to do in all reflection universes because an operation that converts a type to a Java class might not be available). */ +// please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` +// class tags, and all tags in general, should be as minimalistic as possible +@annotation.implicitNotFound(msg = "No ClassTag available for ${T}") +abstract case class ClassTag[T](erasure: jClass[_]) extends ArrayTag[T] { + // quick and dirty fix to a deadlock in Predef: + // http://groups.google.com/group/scala-internals/browse_thread/thread/977de028a4e75d6f + // todo. fix that in a sane way + // assert(erasure != null) + + /** A Scala reflection type representing T. + * For ClassTags this representation is lossy (in their case tpe is retrospectively constructed from erasure). + * For TypeTags and ConcreteTypeTags the representation is almost precise, because they use reification + * (information is lost only when T refers to non-locatable symbols, which are then reified as free variables). */ + def tpe: rm.Type = rm.classToType(erasure) + + /** A Scala reflection symbol representing T. */ + def symbol: rm.Symbol = rm.classToSymbol(erasure) + + /** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */ + def wrap: ClassTag[Array[T]] = { + val arrayClazz = java.lang.reflect.Array.newInstance(erasure, 0).getClass.asInstanceOf[jClass[Array[T]]] + ClassTag[Array[T]](arrayClazz) + } + + /** Produces a new array with element type `T` and length `len` */ + def newArray(len: Int): Array[T] = + erasure match { + case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] + case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] + case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] + case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] + case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] + case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] + case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] + case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] + case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] + case _ => java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] + } +} + +object ClassTag { + private val ObjectTYPE = classOf[java.lang.Object] + private val StringTYPE = classOf[java.lang.String] + + val Byte : ClassTag[scala.Byte] = new ClassTag[scala.Byte](java.lang.Byte.TYPE) { private def readResolve() = ClassTag.Byte } + val Short : ClassTag[scala.Short] = new ClassTag[scala.Short](java.lang.Short.TYPE) { private def readResolve() = ClassTag.Short } + val Char : ClassTag[scala.Char] = new ClassTag[scala.Char](java.lang.Character.TYPE) { private def readResolve() = ClassTag.Char } + val Int : ClassTag[scala.Int] = new ClassTag[scala.Int](java.lang.Integer.TYPE) { private def readResolve() = ClassTag.Int } + val Long : ClassTag[scala.Long] = new ClassTag[scala.Long](java.lang.Long.TYPE) { private def readResolve() = ClassTag.Long } + val Float : ClassTag[scala.Float] = new ClassTag[scala.Float](java.lang.Float.TYPE) { private def readResolve() = ClassTag.Float } + val Double : ClassTag[scala.Double] = new ClassTag[scala.Double](java.lang.Double.TYPE) { private def readResolve() = ClassTag.Double } + val Boolean : ClassTag[scala.Boolean] = new ClassTag[scala.Boolean](java.lang.Boolean.TYPE) { private def readResolve() = ClassTag.Boolean } + val Unit : ClassTag[scala.Unit] = new ClassTag[scala.Unit](java.lang.Void.TYPE) { private def readResolve() = ClassTag.Unit } + val Any : ClassTag[scala.Any] = new ClassTag[scala.Any](ObjectTYPE) { private def readResolve() = ClassTag.Any } + val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object](ObjectTYPE) { private def readResolve() = ClassTag.Object } + val AnyVal : ClassTag[scala.AnyVal] = new ClassTag[scala.AnyVal](ObjectTYPE) { private def readResolve() = ClassTag.AnyVal } + val AnyRef : ClassTag[scala.AnyRef] = new ClassTag[scala.AnyRef](ObjectTYPE) { private def readResolve() = ClassTag.AnyRef } + val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing](ObjectTYPE) { private def readResolve() = ClassTag.Nothing } + val Null : ClassTag[scala.Null] = new ClassTag[scala.Null](ObjectTYPE) { private def readResolve() = ClassTag.Null } + val String : ClassTag[java.lang.String] = new ClassTag[java.lang.String](StringTYPE) { private def readResolve() = ClassTag.String } + + def apply[T](clazz: jClass[_]): ClassTag[T] = + clazz match { + case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] + case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] + case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] + case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] + case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] + case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] + case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] + case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] + case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] + case ObjectTYPE => ClassTag.Object.asInstanceOf[ClassTag[T]] + case StringTYPE => ClassTag.String.asInstanceOf[ClassTag[T]] + case _ => new ClassTag[T](clazz) {} + } + + def apply[T](tpe: rm.Type): ClassTag[T] = + tpe match { + case rm.ByteTpe => ClassTag.Byte.asInstanceOf[ClassTag[T]] + case rm.ShortTpe => ClassTag.Short.asInstanceOf[ClassTag[T]] + case rm.CharTpe => ClassTag.Char.asInstanceOf[ClassTag[T]] + case rm.IntTpe => ClassTag.Int.asInstanceOf[ClassTag[T]] + case rm.LongTpe => ClassTag.Long.asInstanceOf[ClassTag[T]] + case rm.FloatTpe => ClassTag.Float.asInstanceOf[ClassTag[T]] + case rm.DoubleTpe => ClassTag.Double.asInstanceOf[ClassTag[T]] + case rm.BooleanTpe => ClassTag.Boolean.asInstanceOf[ClassTag[T]] + case rm.UnitTpe => ClassTag.Unit.asInstanceOf[ClassTag[T]] + case rm.AnyTpe => ClassTag.Any.asInstanceOf[ClassTag[T]] + case rm.ObjectTpe => ClassTag.Object.asInstanceOf[ClassTag[T]] + case rm.AnyValTpe => ClassTag.AnyVal.asInstanceOf[ClassTag[T]] + case rm.AnyRefTpe => ClassTag.AnyRef.asInstanceOf[ClassTag[T]] + case rm.NothingTpe => ClassTag.Nothing.asInstanceOf[ClassTag[T]] + case rm.NullTpe => ClassTag.Null.asInstanceOf[ClassTag[T]] + case rm.StringTpe => ClassTag.String.asInstanceOf[ClassTag[T]] + case _ => apply[T](rm.typeToClass(tpe.erasure)) + } + + implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag) +} + +// this class should not be used directly in client code +class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) { + import scala.collection.mutable.{ WrappedArray, ArrayBuilder } + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def <:<(that: ClassManifest[_]): Boolean = ctag.tpe <:< that.tpe + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def >:>(that: ClassManifest[_]): Boolean = that <:< ctag + + @deprecated("Use `wrap` instead", "2.10.0") + def arrayManifest: ClassManifest[Array[T]] = ctag.wrap + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray2(len: Int): Array[Array[T]] = ctag.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray3(len: Int): Array[Array[Array[T]]] = ctag.wrap.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray4(len: Int): Array[Array[Array[Array[T]]]] = ctag.wrap.wrap.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = ctag.wrap.wrap.wrap.wrap.newArray(len) + + @deprecated("Use `@scala.collection.mutable.WrappedArray` object instead", "2.10.0") + def newWrappedArray(len: Int): WrappedArray[T] = + ctag.erasure match { + case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](len)).asInstanceOf[WrappedArray[T]] + case _ => new WrappedArray.ofRef[T with AnyRef](ctag.newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] + } + + @deprecated("Use `@scala.collection.mutable.ArrayBuilder` object instead", "2.10.0") + def newArrayBuilder(): ArrayBuilder[T] = ArrayBuilder.make[T]()(ctag) + + @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.ConcreteTypeTag` to capture and analyze type arguments", "2.10.0") + def typeArguments: List[OptManifest[_]] = List() +} \ No newline at end of file diff --git a/src/library/scala/reflect/ClassTags.scala b/src/library/scala/reflect/ClassTags.scala deleted file mode 100644 index cde6da5539..0000000000 --- a/src/library/scala/reflect/ClassTags.scala +++ /dev/null @@ -1,167 +0,0 @@ -package scala.reflect - -import java.lang.{ Class => jClass } -import scala.reflect.{ mirror => rm } - -/** A `ClassTag[T]` wraps a Java class, which can be accessed via the `erasure` method. - * - * This is useful in itself, but also enables very important use case. - * Having this knowledge ClassTag can instantiate `Arrays` - * in those cases where the element type is unknown at compile time. - * Hence, ClassTag[T] conforms to the ArrayTag[T] trait. - * - * If an implicit value of type u.ClassTag[T] is required, the compiler will make one up on demand. - * The implicitly created value contains in its erasure field the Java class that is the result of erasing type T. - * In that value, any occurrences of type parameters or abstract types U which come themselves with a ClassTag - * or a reflect.mirror.ConcreteTypeTag are represented by the type referenced by that tag. - * If the type T contains unresolved references to type parameters or abstract types, a static error results. - * - * A ConcreteTypeTag member of the reflect.mirror object is convertible to a ClassTag via an implicit conversion - * (this is not possible to do in all reflection universes because an operation that converts a type to a Java class might not be available). */ -// please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` -// class tags, and all tags in general, should be as minimalistic as possible -@annotation.implicitNotFound(msg = "No ClassTag available for ${T}") -abstract case class ClassTag[T](erasure: jClass[_]) extends ArrayTag[T] { - // quick and dirty fix to a deadlock in Predef: - // http://groups.google.com/group/scala-internals/browse_thread/thread/977de028a4e75d6f - // todo. fix that in a sane way - // assert(erasure != null) - - /** A Scala reflection type representing T. - * For ClassTags this representation is lossy (in their case tpe is retrospectively constructed from erasure). - * For TypeTags and ConcreteTypeTags the representation is almost precise, because they use reification - * (information is lost only when T refers to non-locatable symbols, which are then reified as free variables). */ - def tpe: rm.Type = rm.classToType(erasure) - - /** A Scala reflection symbol representing T. */ - def symbol: rm.Symbol = rm.classToSymbol(erasure) - - /** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */ - def wrap: ClassTag[Array[T]] = { - val arrayClazz = java.lang.reflect.Array.newInstance(erasure, 0).getClass.asInstanceOf[jClass[Array[T]]] - ClassTag[Array[T]](arrayClazz) - } - - /** Produces a new array with element type `T` and length `len` */ - def newArray(len: Int): Array[T] = - erasure match { - case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] - case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] - case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] - case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] - case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] - case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] - case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] - case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] - case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] - case _ => java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] - } -} - -object ClassTag { - private val ObjectTYPE = classOf[java.lang.Object] - private val StringTYPE = classOf[java.lang.String] - - val Byte : ClassTag[scala.Byte] = new ClassTag[scala.Byte](java.lang.Byte.TYPE) { private def readResolve() = ClassTag.Byte } - val Short : ClassTag[scala.Short] = new ClassTag[scala.Short](java.lang.Short.TYPE) { private def readResolve() = ClassTag.Short } - val Char : ClassTag[scala.Char] = new ClassTag[scala.Char](java.lang.Character.TYPE) { private def readResolve() = ClassTag.Char } - val Int : ClassTag[scala.Int] = new ClassTag[scala.Int](java.lang.Integer.TYPE) { private def readResolve() = ClassTag.Int } - val Long : ClassTag[scala.Long] = new ClassTag[scala.Long](java.lang.Long.TYPE) { private def readResolve() = ClassTag.Long } - val Float : ClassTag[scala.Float] = new ClassTag[scala.Float](java.lang.Float.TYPE) { private def readResolve() = ClassTag.Float } - val Double : ClassTag[scala.Double] = new ClassTag[scala.Double](java.lang.Double.TYPE) { private def readResolve() = ClassTag.Double } - val Boolean : ClassTag[scala.Boolean] = new ClassTag[scala.Boolean](java.lang.Boolean.TYPE) { private def readResolve() = ClassTag.Boolean } - val Unit : ClassTag[scala.Unit] = new ClassTag[scala.Unit](java.lang.Void.TYPE) { private def readResolve() = ClassTag.Unit } - val Any : ClassTag[scala.Any] = new ClassTag[scala.Any](ObjectTYPE) { private def readResolve() = ClassTag.Any } - val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object](ObjectTYPE) { private def readResolve() = ClassTag.Object } - val AnyVal : ClassTag[scala.AnyVal] = new ClassTag[scala.AnyVal](ObjectTYPE) { private def readResolve() = ClassTag.AnyVal } - val AnyRef : ClassTag[scala.AnyRef] = new ClassTag[scala.AnyRef](ObjectTYPE) { private def readResolve() = ClassTag.AnyRef } - val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing](ObjectTYPE) { private def readResolve() = ClassTag.Nothing } - val Null : ClassTag[scala.Null] = new ClassTag[scala.Null](ObjectTYPE) { private def readResolve() = ClassTag.Null } - val String : ClassTag[java.lang.String] = new ClassTag[java.lang.String](StringTYPE) { private def readResolve() = ClassTag.String } - - def apply[T](clazz: jClass[_]): ClassTag[T] = - clazz match { - case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] - case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] - case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] - case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] - case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] - case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] - case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] - case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] - case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] - case ObjectTYPE => ClassTag.Object.asInstanceOf[ClassTag[T]] - case StringTYPE => ClassTag.String.asInstanceOf[ClassTag[T]] - case _ => new ClassTag[T](clazz) {} - } - - def apply[T](tpe: rm.Type): ClassTag[T] = - tpe match { - case rm.ByteTpe => ClassTag.Byte.asInstanceOf[ClassTag[T]] - case rm.ShortTpe => ClassTag.Short.asInstanceOf[ClassTag[T]] - case rm.CharTpe => ClassTag.Char.asInstanceOf[ClassTag[T]] - case rm.IntTpe => ClassTag.Int.asInstanceOf[ClassTag[T]] - case rm.LongTpe => ClassTag.Long.asInstanceOf[ClassTag[T]] - case rm.FloatTpe => ClassTag.Float.asInstanceOf[ClassTag[T]] - case rm.DoubleTpe => ClassTag.Double.asInstanceOf[ClassTag[T]] - case rm.BooleanTpe => ClassTag.Boolean.asInstanceOf[ClassTag[T]] - case rm.UnitTpe => ClassTag.Unit.asInstanceOf[ClassTag[T]] - case rm.AnyTpe => ClassTag.Any.asInstanceOf[ClassTag[T]] - case rm.ObjectTpe => ClassTag.Object.asInstanceOf[ClassTag[T]] - case rm.AnyValTpe => ClassTag.AnyVal.asInstanceOf[ClassTag[T]] - case rm.AnyRefTpe => ClassTag.AnyRef.asInstanceOf[ClassTag[T]] - case rm.NothingTpe => ClassTag.Nothing.asInstanceOf[ClassTag[T]] - case rm.NullTpe => ClassTag.Null.asInstanceOf[ClassTag[T]] - case rm.StringTpe => ClassTag.String.asInstanceOf[ClassTag[T]] - case _ => apply[T](rm.typeToClass(tpe.erasure)) - } - - implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag) -} - -// this class should not be used directly in client code -class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) { - import scala.collection.mutable.{ WrappedArray, ArrayBuilder } - - @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") - def <:<(that: ClassManifest[_]): Boolean = ctag.tpe <:< that.tpe - - @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") - def >:>(that: ClassManifest[_]): Boolean = that <:< ctag - - @deprecated("Use `wrap` instead", "2.10.0") - def arrayManifest: ClassManifest[Array[T]] = ctag.wrap - - @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") - def newArray2(len: Int): Array[Array[T]] = ctag.wrap.newArray(len) - - @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") - def newArray3(len: Int): Array[Array[Array[T]]] = ctag.wrap.wrap.newArray(len) - - @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") - def newArray4(len: Int): Array[Array[Array[Array[T]]]] = ctag.wrap.wrap.wrap.newArray(len) - - @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") - def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = ctag.wrap.wrap.wrap.wrap.newArray(len) - - @deprecated("Use `@scala.collection.mutable.WrappedArray` object instead", "2.10.0") - def newWrappedArray(len: Int): WrappedArray[T] = - ctag.erasure match { - case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](len)).asInstanceOf[WrappedArray[T]] - case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](len)).asInstanceOf[WrappedArray[T]] - case _ => new WrappedArray.ofRef[T with AnyRef](ctag.newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] - } - - @deprecated("Use `@scala.collection.mutable.ArrayBuilder` object instead", "2.10.0") - def newArrayBuilder(): ArrayBuilder[T] = ArrayBuilder.make[T]()(ctag) - - @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.ConcreteTypeTag` to capture and analyze type arguments", "2.10.0") - def typeArguments: List[OptManifest[_]] = List() -} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala new file mode 100644 index 0000000000..dfd362ebe0 --- /dev/null +++ b/src/library/scala/reflect/api/Attachment.scala @@ -0,0 +1,16 @@ +package scala.reflect +package api + +/** Attachment is a generalisation of Position. + * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads. + * + * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree + * imposing an unnecessary memory tax because of something that will not be used in most cases. + */ +trait Attachment { + /** Gets the underlying position */ + def pos: Position + + /** Creates a copy of this attachment with its position updated */ + def withPos(pos: Position): Attachment +} diff --git a/src/library/scala/reflect/api/Attachments.scala b/src/library/scala/reflect/api/Attachments.scala deleted file mode 100644 index dfd362ebe0..0000000000 --- a/src/library/scala/reflect/api/Attachments.scala +++ /dev/null @@ -1,16 +0,0 @@ -package scala.reflect -package api - -/** Attachment is a generalisation of Position. - * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads. - * - * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree - * imposing an unnecessary memory tax because of something that will not be used in most cases. - */ -trait Attachment { - /** Gets the underlying position */ - def pos: Position - - /** Creates a copy of this attachment with its position updated */ - def withPos(pos: Position): Attachment -} diff --git a/src/library/scala/reflect/makro/internal/Utils.scala b/src/library/scala/reflect/makro/internal/Utils.scala new file mode 100644 index 0000000000..de404ff39f --- /dev/null +++ b/src/library/scala/reflect/makro/internal/Utils.scala @@ -0,0 +1,133 @@ +package scala.reflect.makro + +import scala.reflect.api.Universe + +/** This package is required by the compiler and should not be used in client code. */ +package object internal { + /** This method is required by the compiler and should not be used in client code. */ + def materializeClassTag[T](u: Universe): ClassTag[T] = macro materializeClassTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeClassTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[ClassTag[T]] = + c.Expr[Nothing](c.materializeClassTag(u.tree, implicitly[c.TypeTag[T]].tpe))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + def materializeTypeTag[T](u: Universe): u.TypeTag[T] = macro materializeTypeTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.TypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireConcreteTypeTag = false))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + def materializeConcreteTypeTag[T](u: Universe): u.ConcreteTypeTag[T] = macro materializeConcreteTypeTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeConcreteTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.ConcreteTypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireConcreteTypeTag = true))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + private[scala] implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils +} + +package internal { + private[scala] abstract class Utils { + val c: Context + + import c.mirror._ + import definitions._ + + val coreTags = Map( + ByteClass.asType -> newTermName("Byte"), + ShortClass.asType -> newTermName("Short"), + CharClass.asType -> newTermName("Char"), + IntClass.asType -> newTermName("Int"), + LongClass.asType -> newTermName("Long"), + FloatClass.asType -> newTermName("Float"), + DoubleClass.asType -> newTermName("Double"), + BooleanClass.asType -> newTermName("Boolean"), + UnitClass.asType -> newTermName("Unit"), + AnyClass.asType -> newTermName("Any"), + ObjectClass.asType -> newTermName("Object"), + AnyValClass.asType -> newTermName("AnyVal"), + AnyRefClass.asType -> newTermName("AnyRef"), + NothingClass.asType -> newTermName("Nothing"), + NullClass.asType -> newTermName("Null")) + + def materializeClassTag(prefix: Tree, tpe: Type): Tree = { + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) + typetagInScope match { + case success if !success.isEmpty && !typetagIsSynthetic(success) => + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(Select(typetagInScope, newTermName("tpe")))) + case _ => + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Ident(ClassTagModule), coreTags(coreTpe)) + case _ => + if (tpe.typeSymbol == ArrayClass) { + val componentTpe = tpe.typeArguments(0) + val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe))) + val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe) + Select(componentTag, newTermName("wrap")) + } else { + // [Eugene] what's the intended behavior? there's no spec on ClassManifests + // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? + // if its the latter, what should be the result of tagging Array[T] where T <: Int? + if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type") + val erasure = + if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct? + else tpe.erasure.normalize // necessary to deal with erasures of HK types + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure))))) + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + } + + def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { + val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Select(prefix, tagModule.name), coreTags(coreTpe)) + case _ => + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + val ex1 = ex + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case c.ReificationError(pos, msg) => + c.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case c.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + + private def fail(reason: Any): Nothing = { + val Apply(TypeApply(fun, List(tpeTree)), _) = c.macroApplication + val tpe = tpeTree.tpe + val PolyType(_, MethodType(_, tagTpe)) = fun.tpe + val tagModule = tagTpe.typeSymbol.companionSymbol + if (c.compilerSettings.contains("-Xlog-implicits")) + c.echo(c.enclosingPosition, "cannot materialize " + tagModule.name + "[" + tpe + "] because:\n" + reason) + c.abort(c.enclosingPosition, "No %s available for %s".format(tagModule.name, tpe)) + } + } +} diff --git a/src/library/scala/reflect/makro/internal/typeTagImpl.scala b/src/library/scala/reflect/makro/internal/typeTagImpl.scala deleted file mode 100644 index de404ff39f..0000000000 --- a/src/library/scala/reflect/makro/internal/typeTagImpl.scala +++ /dev/null @@ -1,133 +0,0 @@ -package scala.reflect.makro - -import scala.reflect.api.Universe - -/** This package is required by the compiler and should not be used in client code. */ -package object internal { - /** This method is required by the compiler and should not be used in client code. */ - def materializeClassTag[T](u: Universe): ClassTag[T] = macro materializeClassTag_impl[T] - - /** This method is required by the compiler and should not be used in client code. */ - def materializeClassTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[ClassTag[T]] = - c.Expr[Nothing](c.materializeClassTag(u.tree, implicitly[c.TypeTag[T]].tpe))(c.TypeTag.Nothing) - - /** This method is required by the compiler and should not be used in client code. */ - def materializeTypeTag[T](u: Universe): u.TypeTag[T] = macro materializeTypeTag_impl[T] - - /** This method is required by the compiler and should not be used in client code. */ - def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.TypeTag[T]] = - c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireConcreteTypeTag = false))(c.TypeTag.Nothing) - - /** This method is required by the compiler and should not be used in client code. */ - def materializeConcreteTypeTag[T](u: Universe): u.ConcreteTypeTag[T] = macro materializeConcreteTypeTag_impl[T] - - /** This method is required by the compiler and should not be used in client code. */ - def materializeConcreteTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.ConcreteTypeTag[T]] = - c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireConcreteTypeTag = true))(c.TypeTag.Nothing) - - /** This method is required by the compiler and should not be used in client code. */ - private[scala] implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils -} - -package internal { - private[scala] abstract class Utils { - val c: Context - - import c.mirror._ - import definitions._ - - val coreTags = Map( - ByteClass.asType -> newTermName("Byte"), - ShortClass.asType -> newTermName("Short"), - CharClass.asType -> newTermName("Char"), - IntClass.asType -> newTermName("Int"), - LongClass.asType -> newTermName("Long"), - FloatClass.asType -> newTermName("Float"), - DoubleClass.asType -> newTermName("Double"), - BooleanClass.asType -> newTermName("Boolean"), - UnitClass.asType -> newTermName("Unit"), - AnyClass.asType -> newTermName("Any"), - ObjectClass.asType -> newTermName("Object"), - AnyValClass.asType -> newTermName("AnyVal"), - AnyRefClass.asType -> newTermName("AnyRef"), - NothingClass.asType -> newTermName("Nothing"), - NullClass.asType -> newTermName("Null")) - - def materializeClassTag(prefix: Tree, tpe: Type): Tree = { - val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe))) - def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) - typetagInScope match { - case success if !success.isEmpty && !typetagIsSynthetic(success) => - val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) - Apply(factory, List(Select(typetagInScope, newTermName("tpe")))) - case _ => - val result = - tpe match { - case coreTpe if coreTags contains coreTpe => - Select(Ident(ClassTagModule), coreTags(coreTpe)) - case _ => - if (tpe.typeSymbol == ArrayClass) { - val componentTpe = tpe.typeArguments(0) - val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe))) - val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe) - Select(componentTag, newTermName("wrap")) - } else { - // [Eugene] what's the intended behavior? there's no spec on ClassManifests - // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? - // if its the latter, what should be the result of tagging Array[T] where T <: Int? - if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type") - val erasure = - if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct? - else tpe.erasure.normalize // necessary to deal with erasures of HK types - val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) - Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure))))) - } - } - try c.typeCheck(result) - catch { case terr @ c.TypeError(pos, msg) => fail(terr) } - } - } - - def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { - val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule - val result = - tpe match { - case coreTpe if coreTags contains coreTpe => - Select(Select(prefix, tagModule.name), coreTags(coreTpe)) - case _ => - try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) - catch { - case ex: Throwable => - // [Eugene] cannot pattern match on an abstract type, so had to do this - val ex1 = ex - if (ex.getClass.toString.endsWith("$ReificationError")) { - ex match { - case c.ReificationError(pos, msg) => - c.error(pos, msg) - EmptyTree - } - } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { - ex match { - case c.UnexpectedReificationError(pos, err, cause) => - if (cause != null) throw cause else throw ex - } - } else { - throw ex - } - } - } - try c.typeCheck(result) - catch { case terr @ c.TypeError(pos, msg) => fail(terr) } - } - - private def fail(reason: Any): Nothing = { - val Apply(TypeApply(fun, List(tpeTree)), _) = c.macroApplication - val tpe = tpeTree.tpe - val PolyType(_, MethodType(_, tagTpe)) = fun.tpe - val tagModule = tagTpe.typeSymbol.companionSymbol - if (c.compilerSettings.contains("-Xlog-implicits")) - c.echo(c.enclosingPosition, "cannot materialize " + tagModule.name + "[" + tpe + "] because:\n" + reason) - c.abort(c.enclosingPosition, "No %s available for %s".format(tagModule.name, tpe)) - } - } -} -- cgit v1.2.3 From 72d86cbe8cb4792a2eae190aee3677854bffb89f Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Wed, 11 Apr 2012 17:29:49 -0700 Subject: SI-5663: Tweak warnings on case class equals Re-enable testing the sensibility of comparing instances of two case classes. In particular, warn if we detect that the two objects inherit from different case classes. In addition, avoid emitting misleading warnings when comparing "new C". --- .../scala/tools/nsc/typechecker/RefChecks.scala | 65 +++++++++++------- test/files/neg/t5663-badwarneq.check | 22 +++++++ test/files/neg/t5663-badwarneq.flags | 1 + test/files/neg/t5663-badwarneq.scala | 76 ++++++++++++++++++++++ 4 files changed, 142 insertions(+), 22 deletions(-) create mode 100644 test/files/neg/t5663-badwarneq.check create mode 100644 test/files/neg/t5663-badwarneq.flags create mode 100644 test/files/neg/t5663-badwarneq.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 806ee480f0..c4b08f6ea2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1059,12 +1059,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R // equals. def isUsingWarnableEquals = { val m = receiver.info.member(nme.equals_) - def n = actual.info.member(nme.equals_) - ( (m == Object_equals) - || (m == Any_equals) - || (m.isSynthetic && m.owner.isCase && !n.owner.isCase) - ) + ((m == Object_equals) || (m == Any_equals) || isMethodCaseEquals(m)) } + def isMethodCaseEquals(m: Symbol) = m.isSynthetic && m.owner.isCase + def isCaseEquals = isMethodCaseEquals(receiver.info.member(nme.equals_)) // Whether this == or != is one of those defined in Any/AnyRef or an overload from elsewhere. def isUsingDefaultScalaOp = { val s = fn.symbol @@ -1087,9 +1085,11 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R val msg = alwaysEqual == (name == nme.EQ || name == nme.eq) unit.warning(pos, "comparing "+what+" using `"+name.decode+"' will always yield " + msg) } - def nonSensible(pre: String, alwaysEqual: Boolean) = nonSensibleWarning(pre+"values of types "+typesString, alwaysEqual) + def nonSensiblyEq() = nonSensible("", true) + def nonSensiblyNeq() = nonSensible("", false) + def nonSensiblyNew() = nonSensibleWarning("a fresh object", false) def unrelatedTypes() = { val msg = if (name == nme.EQ || name == nme.eq) @@ -1097,52 +1097,73 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R unit.warning(pos, typesString + " are unrelated: they will most likely " + msg) } - if (nullCount == 2) - nonSensible("", true) // null == null + if (nullCount == 2) // null == null + nonSensiblyEq() else if (nullCount == 1) { if (onSyms(_ exists isPrimitiveValueClass)) // null == 5 - nonSensible("", false) + nonSensiblyNeq() else if (onTrees( _ exists isNew)) // null == new AnyRef - nonSensibleWarning("a fresh object", false) + nonSensiblyNew() } else if (isBoolean(receiver)) { if (!isBoolean(actual) && !isMaybeValue(actual)) // true == 5 - nonSensible("", false) + nonSensiblyNeq() } else if (isUnit(receiver)) { if (isUnit(actual)) // () == () - nonSensible("", true) + nonSensiblyEq() else if (!isUnit(actual) && !isMaybeValue(actual)) // () == "abc" - nonSensible("", false) + nonSensiblyNeq() } else if (isNumeric(receiver)) { if (!isNumeric(actual) && !forMSIL) if (isUnit(actual) || isBoolean(actual) || !isMaybeValue(actual)) // 5 == "abc" - nonSensible("", false) + nonSensiblyNeq() } - else if (isWarnable) { + else if (isWarnable && !isCaseEquals) { if (isNew(qual)) // new X == y - nonSensibleWarning("a fresh object", false) + nonSensiblyNew() else if (isNew(args.head) && (receiver.isEffectivelyFinal || isReferenceOp)) // object X ; X == new Y - nonSensibleWarning("a fresh object", false) + nonSensiblyNew() else if (receiver.isEffectivelyFinal && !(receiver isSubClass actual)) { // object X, Y; X == Y if (isEitherNullable) nonSensible("non-null ", false) else - nonSensible("", false) + nonSensiblyNeq() } } // possibleNumericCount is insufficient or this will warn on e.g. Boolean == j.l.Boolean if (isWarnable && nullCount == 0 && !(isSpecial(receiver) && isSpecial(actual))) { - if (actual isSubClass receiver) () - else if (receiver isSubClass actual) () - // warn only if they have no common supertype below Object - else { + // better to have lubbed and lost + def warnIfLubless(): Unit = { val common = global.lub(List(actual.tpe, receiver.tpe)) if (ObjectClass.tpe <:< common) unrelatedTypes() } + def eitherSubclasses = (actual isSubClass receiver) || (receiver isSubClass actual) + // warn if actual has a case parent that is not same as receiver's; + // if actual is not a case, then warn if no common supertype, as below + if (isCaseEquals) { + def thisCase = receiver.info.member(nme.equals_).owner + actual.info.baseClasses.find(_.isCase) match { + case Some(p) if (p != thisCase) => nonSensible("case class ", false) + case None => + // stronger message on (Some(1) == None) + //if (receiver.isCase && receiver.isEffectivelyFinal && !(receiver isSubClass actual)) nonSensiblyNeq() + //else + // if a class, it must be super to thisCase (and receiver) since not <: thisCase + if (!actual.isTrait && !(receiver isSubClass actual)) nonSensiblyNeq() + else if (!eitherSubclasses) warnIfLubless() + case _ => + } + } + else if (actual isSubClass receiver) () + else if (receiver isSubClass actual) () + // warn only if they have no common supertype below Object + else { + warnIfLubless() + } } case _ => } diff --git a/test/files/neg/t5663-badwarneq.check b/test/files/neg/t5663-badwarneq.check new file mode 100644 index 0000000000..00c2234e9d --- /dev/null +++ b/test/files/neg/t5663-badwarneq.check @@ -0,0 +1,22 @@ +t5663-badwarneq.scala:42: error: comparing case class values of types Some[Int] and None.type using `==' will always yield false + println(new Some(1) == None) // Should complain on type, was: spuriously complains on fresh object + ^ +t5663-badwarneq.scala:43: error: comparing case class values of types Some[Int] and Thing using `==' will always yield false + println(Some(1) == new Thing(1)) // Should complain on type, was: spuriously complains on fresh object + ^ +t5663-badwarneq.scala:51: error: ThingOne and Thingy are unrelated: they will most likely never compare equal + println(t1 == t2) // true, but apparently unrelated, a compromise warning + ^ +t5663-badwarneq.scala:52: error: ThingThree and Thingy are unrelated: they will most likely never compare equal + println(t4 == t2) // true, complains because ThingThree is final and Thingy not a subclass, stronger claim than unrelated + ^ +t5663-badwarneq.scala:55: error: comparing case class values of types ThingTwo and Some[Int] using `==' will always yield false + println(t3 == Some(1)) // false, warn on different cases + ^ +t5663-badwarneq.scala:56: error: comparing values of types ThingOne and Cousin using `==' will always yield false + println(t1 == c) // should warn + ^ +t5663-badwarneq.scala:64: error: comparing case class values of types Simple and SimpleSibling.type using `==' will always yield false + println(new Simple() == SimpleSibling) // like Some(1) == None, but needn't be final case + ^ +7 errors found diff --git a/test/files/neg/t5663-badwarneq.flags b/test/files/neg/t5663-badwarneq.flags new file mode 100644 index 0000000000..85d8eb2ba2 --- /dev/null +++ b/test/files/neg/t5663-badwarneq.flags @@ -0,0 +1 @@ +-Xfatal-warnings diff --git a/test/files/neg/t5663-badwarneq.scala b/test/files/neg/t5663-badwarneq.scala new file mode 100644 index 0000000000..56ec389c03 --- /dev/null +++ b/test/files/neg/t5663-badwarneq.scala @@ -0,0 +1,76 @@ + +// alias +trait Thingy + +class Gramps + +// sibling classes that extend a case class +case class Thing(i: Int) extends Gramps +class ThingOne(x:Int) extends Thing(x) +class ThingTwo(y:Int) extends Thing(y) with Thingy +final class ThingThree(z:Int) extends Thing(z) + +// not case cousin +class Cousin extends Gramps + +class SimpleParent +case class Simple() extends SimpleParent +case object SimpleSibling extends SimpleParent + +/* It's not possible to run partest without -deprecation. + * Since detecting the warnings requires a neg test with + * -Xfatal-warnings, and deprecation terminates the compile, + * we'll just comment out the nasty part. The point was + * just to show there's nothing special about a trait + * that extends a case class, which is only permitted + * (deprecatingly) by omitting the parens. + * +// common ancestor is something else +class AnyThing +case class SomeThing extends AnyThing // deprecation +class OtherThing extends AnyThing + +// how you inherit caseness doesn't matter +trait InThing extends SomeThing +class MyThing extends InThing +*/ + +object Test { + def main(a: Array[String]) { + // nothing to do with Gavin + println(new Some(1) == new Some(1)) // OK, true + println(new Some(1) == None) // Should complain on type, was: spuriously complains on fresh object + println(Some(1) == new Thing(1)) // Should complain on type, was: spuriously complains on fresh object + + val t1 = new ThingOne(11) + val t2: Thingy = new ThingTwo(11) + val t3 = new ThingTwo(11) + val t4 = new ThingThree(11) + val c = new Cousin + + println(t1 == t2) // true, but apparently unrelated, a compromise warning + println(t4 == t2) // true, complains because ThingThree is final and Thingy not a subclass, stronger claim than unrelated + println(t2 == t3) // OK, two Thingy + println(t3 == t2) // ditto with case receiver + println(t3 == Some(1)) // false, warn on different cases + println(t1 == c) // should warn + + // don't warn on fresh cases + println(new ThingOne(11) == t1) // OK, was: two cases not warnable on trunk + println(new ThingTwo(11) == t2) // true, was: spuriously complains on fresh object + println(new ThingOne(11) == t3) // two cases not warnable on trunk + println(new ThingTwo(11) == t3) // ditto + + println(new Simple() == SimpleSibling) // like Some(1) == None, but needn't be final case + + /* + val mine = new MyThing + val some = new SomeThing + val other = new OtherThing + println(mine == some) // OK, two Something + println(some == mine) + println(mine == other) // OK, two Anything? + println(mine == t1) // false + */ + } +} -- cgit v1.2.3 From 7f2624e2ee57d10ff39452164899937dc799e8b1 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 13 Apr 2012 15:46:02 -0700 Subject: Fixed problems with new deprecated idents scheme. --- src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 105db805d8..583da36ead 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -115,17 +115,16 @@ trait Scanners extends ScannersCommon { /** Clear buffer and set name and token */ private def finishNamed(idtoken: Int = IDENTIFIER) { name = newTermName(cbuf.toString) + cbuf.clear() token = idtoken - val idx = name.start - kwOffset - if (idx >= 0 && idx < kwArray.length) { - token = kwArray(idx) - if (token == IDENTIFIER) { - if (idtoken == IDENTIFIER && allowIdent != name) + if (idtoken == IDENTIFIER) { + val idx = name.start - kwOffset + if (idx >= 0 && idx < kwArray.length) { + token = kwArray(idx) + if (token == IDENTIFIER && allowIdent != name) deprecationWarning(name+" is now a reserved word; usage as an identifier is deprecated") - token = idtoken } } - cbuf.clear() } /** Clear buffer and set string */ -- cgit v1.2.3 From 3324a7215c87c61791f3e4afb49bc63cf9c80f12 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 13 Apr 2012 15:46:40 -0700 Subject: Fine-tuning of isRepresentableWithWildcards and wildcard printing. --- src/compiler/scala/reflect/internal/Types.scala | 41 +++++++++++----------- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index c13a33a6fc..b3d425f0c5 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -2517,34 +2517,35 @@ trait Types extends api.Types { self: SymbolTable => override def skolemizeExistential(owner: Symbol, origin: AnyRef) = deriveType(quantified, tparam => (owner orElse tparam.owner).newExistentialSkolem(tparam, origin))(underlying) - private def wildcardArgsString(available: Set[Symbol], args: List[Type]): List[String] = args match { - case TypeRef(_, sym, _) :: args1 if (available contains sym) => - ("_"+sym.infoString(sym.info)) :: wildcardArgsString(available - sym, args1) - case arg :: args1 if !(quantified exists (arg contains _)) => - arg.toString :: wildcardArgsString(available, args1) - case _ => - List() + private def wildcardArgsString(qset: Set[Symbol], args: List[Type]): List[String] = args map { + case TypeRef(_, sym, _) if (qset contains sym) => + "_"+sym.infoString(sym.info) + case arg => + arg.toString } + /** An existential can only be printed with wildcards if: * - the underlying type is a typeref - * - where there is a 1-to-1 correspondence between underlying's typeargs and quantified - * - and none of the existential parameters is referenced from anywhere else in the type - * - and none of the existential parameters are singleton types - * - @param checkBounds if set returns false for situations like - * (S, T) forSome { type S; type T <: S } - * If not set returns true. The reason for this mode is to - * avoid cyclic reference errors when the method is called - * early (e.g. from Typers # checkExistentialsFeature) + * - every quantified variable appears at most once as a type argument and + * nowhere inside a type argument + * - no quantified type argument contains a quantified variable in its bound + * - the typeref's symbol is not itself quantified + * - the prefix is not quanitified */ - def isRepresentableWithWildcards(checkBounds: Boolean) = { + def isRepresentableWithWildcards = { val qset = quantified.toSet underlying match { - case TypeRef(_, sym, args) => - def isQuantified(tpe: Type) = tpe exists (t => quantified contains t.typeSymbol) + case TypeRef(pre, sym, args) => + def isQuantified(tpe: Type): Boolean = { + (tpe exists (t => qset contains t.typeSymbol)) || + tpe.typeSymbol.isRefinementClass && (tpe.parents exists isQuantified) + } val (wildcardArgs, otherArgs) = args partition (arg => qset contains arg.typeSymbol) wildcardArgs.distinct == wildcardArgs && !(otherArgs exists (arg => isQuantified(arg))) && - !(wildcardArgs exists (arg => isQuantified(arg.typeSymbol.info.bounds))) + !(wildcardArgs exists (arg => isQuantified(arg.typeSymbol.info.bounds))) && + !(qset contains sym) && + !isQuantified(pre) case _ => false } } @@ -2555,7 +2556,7 @@ trait Types extends api.Types { self: SymbolTable => if (settings.explaintypes.value) "(" + str + ")" else str } underlying match { - case TypeRef(pre, sym, args) if !settings.debug.value && isRepresentableWithWildcards(checkBounds = true) => + case TypeRef(pre, sym, args) if !settings.debug.value && isRepresentableWithWildcards => "" + TypeRef(pre, sym, Nil) + wildcardArgsString(quantified.toSet, args).mkString("[", ", ", "]") case MethodType(_, _) | NullaryMethodType(_) | PolyType(_, _) => "(" + underlying + ")" + clauses diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1425cd4755..9431c6f5e5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -761,7 +761,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } def checkExistentialsFeature(pos: Position, tpe: Type, prefix: String) = tpe match { - case extp: ExistentialType if !extp.isRepresentableWithWildcards(checkBounds = false) => + case extp: ExistentialType if !extp.isRepresentableWithWildcards => checkFeature(pos, ExistentialsFeature, prefix+" "+tpe) case _ => } -- cgit v1.2.3 From b5757577c520e6339e4278fa91f725e66561f73e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 13 Apr 2012 15:47:39 -0700 Subject: Fixed tests to account for SIP 18 --- test/files/buildmanager/t2650_1/t2650_1.check | 1 + test/files/buildmanager/t2657/t2657.check | 1 + test/files/jvm/interpreter.check | 741 +++++++++++---------- test/files/pos/generic-sigs.scala | 4 +- test/files/pos/t1439.flags | 2 +- test/files/run/constrained-types.check | 7 + test/files/run/existentials-in-compiler.check | 16 +- .../run/macro-reflective-mamd-normal-mi.check | 1 - test/files/run/macro-repl-basic.check | 105 +-- test/files/run/macro-repl-basic.scala | 4 +- test/files/run/macro-repl-dontexpand.scala | 4 +- test/files/run/repl-parens.check | 2 +- test/files/run/repl-parens.scala | 4 +- test/files/run/repl-power.check | 65 +- test/files/run/t4172.check | 2 + test/files/run/t4317/S_1.scala | 2 + test/files/run/t4710.check | 1 + 17 files changed, 492 insertions(+), 470 deletions(-) mode change 100755 => 100644 test/files/jvm/interpreter.check diff --git a/test/files/buildmanager/t2650_1/t2650_1.check b/test/files/buildmanager/t2650_1/t2650_1.check index ecddb33620..f1e4b1b8bc 100644 --- a/test/files/buildmanager/t2650_1/t2650_1.check +++ b/test/files/buildmanager/t2650_1/t2650_1.check @@ -1,5 +1,6 @@ builder > A.scala B.scala compiling Set(A.scala, B.scala) +warning: there were 1 feature warnings; re-run with -feature for details Changes: Map() builder > A.scala compiling Set(A.scala) diff --git a/test/files/buildmanager/t2657/t2657.check b/test/files/buildmanager/t2657/t2657.check index 74ba87a21d..cd0357599c 100644 --- a/test/files/buildmanager/t2657/t2657.check +++ b/test/files/buildmanager/t2657/t2657.check @@ -1,5 +1,6 @@ builder > A.scala B.scala compiling Set(A.scala, B.scala) +warning: there were 1 feature warnings; re-run with -feature for details Changes: Map() builder > A.scala compiling Set(A.scala) diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check old mode 100755 new mode 100644 index d93e314d8e..b9ff6afa2b --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -1,372 +1,375 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> - -scala> // basics - -scala> 3+4 -res0: Int = 7 - -scala> def gcd(x: Int, y: Int): Int = { - if (x == 0) y - else if (y == 0) x - else gcd(y%x, x) -} -gcd: (x: Int, y: Int)Int - -scala> val five = gcd(15,35) -five: Int = 5 - -scala> var x = 1 -x: Int = 1 - -scala> x = 2 -x: Int = 2 - -scala> val three = x+1 -three: Int = 3 - -scala> type anotherint = Int -defined type alias anotherint - -scala> val four: anotherint = 4 -four: anotherint = 4 - -scala> val bogus: anotherint = "hello" -:8: error: type mismatch; - found : String("hello") - required: anotherint - (which expands to) Int - val bogus: anotherint = "hello" - ^ - -scala> trait PointlessTrait -defined trait PointlessTrait - -scala> val (x,y) = (2,3) -x: Int = 2 -y: Int = 3 - -scala> println("hello") -hello - -scala> - -scala> // ticket #1513 - -scala> val t1513 = Array(null) -t1513: Array[Null] = Array(null) - -scala> // ambiguous toString problem from #547 - -scala> val atom = new scala.xml.Atom() -atom: scala.xml.Atom[Unit] = () - -scala> // overriding toString problem from #1404 - -scala> class S(override val toString : String) -defined class S - -scala> val fish = new S("fish") -fish: S = fish - -scala> // Test that arrays pretty print nicely. - -scala> val arr = Array("What's", "up", "doc?") -arr: Array[String] = Array(What's, up, doc?) - -scala> // Test that arrays pretty print nicely, even when we give them type Any - -scala> val arrInt : Any = Array(1,2,3) -arrInt: Any = Array(1, 2, 3) - -scala> // Test that nested arrays are pretty-printed correctly - -scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4)) -arrArrInt: Any = Array(Array(1, 2), Array(3, 4)) - -scala> - -scala> // implicit conversions - -scala> case class Foo(n: Int) -defined class Foo - -scala> case class Bar(n: Int) -defined class Bar - -scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) -foo2bar: (foo: Foo)Bar - -scala> val bar: Bar = Foo(3) -bar: Bar = Bar(3) - -scala> - -scala> // importing from a previous result - -scala> import bar._ -import bar._ - -scala> val m = n -m: Int = 3 - -scala> - -scala> // stressing the imports mechanism - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> - -scala> - -scala> val x1 = 1 -x1: Int = 1 - -scala> val x2 = 1 -x2: Int = 1 - -scala> val x3 = 1 -x3: Int = 1 - -scala> val x4 = 1 -x4: Int = 1 - -scala> val x5 = 1 -x5: Int = 1 - -scala> val x6 = 1 -x6: Int = 1 - -scala> val x7 = 1 -x7: Int = 1 - -scala> val x8 = 1 -x8: Int = 1 - -scala> val x9 = 1 -x9: Int = 1 - -scala> val x10 = 1 -x10: Int = 1 - -scala> val x11 = 1 -x11: Int = 1 - -scala> val x12 = 1 -x12: Int = 1 - -scala> val x13 = 1 -x13: Int = 1 - -scala> val x14 = 1 -x14: Int = 1 - -scala> val x15 = 1 -x15: Int = 1 - -scala> val x16 = 1 -x16: Int = 1 - -scala> val x17 = 1 -x17: Int = 1 - -scala> val x18 = 1 -x18: Int = 1 - -scala> val x19 = 1 -x19: Int = 1 - -scala> val x20 = 1 -x20: Int = 1 - -scala> - -scala> val two = one + x5 -two: Int = 2 - -scala> - -scala> // handling generic wildcard arrays (#2386) - -scala> // It's put here because type feedback is an important part of it. - -scala> val xs: Array[_] = Array(1, 2) -xs: Array[_] = Array(1, 2) - -scala> xs.size -res2: Int = 2 - -scala> xs.head -res3: Any = 1 - -scala> xs filter (_ == 2) -res4: Array[_] = Array(2) - -scala> xs map (_ => "abc") -res5: Array[String] = Array(abc, abc) - -scala> xs map (x => x) -res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(1, 2) - -scala> xs map (x => (x, x)) -res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) - -scala> - -scala> // interior syntax errors should *not* go into multi-line input mode. - -scala> // both of the following should abort immediately: - -scala> def x => y => z -:1: error: '=' expected but '=>' found. - def x => y => z - ^ - -scala> [1,2,3] -:1: error: illegal start of definition - [1,2,3] - ^ - -scala> - -scala> - -scala> // multi-line XML - -scala> - -res8: scala.xml.Elem = - - - -scala> - -scala> - -scala> /* - /* - multi-line comment - */ -*/ - -scala> - -scala> - -scala> // multi-line string - -scala> """ -hello -there -""" -res9: String = -" -hello -there -" - -scala> - -scala> (1 + // give up early by typing two blank lines - - -You typed two blank lines. Starting a new command. - -scala> // defining and using quoted names should work (ticket #323) - -scala> def `match` = 1 -match: Int - -scala> val x = `match` -x: Int = 1 - -scala> - -scala> // multiple classes defined on one line - -scala> sealed class Exp; class Fact extends Exp; class Term extends Exp -defined class Exp -defined class Fact -defined class Term - -scala> def f(e: Exp) = e match { // non-exhaustive warning here - case _:Fact => 3 -} -:18: warning: match is not exhaustive! -missing combination Exp -missing combination Term - - def f(e: Exp) = e match { // non-exhaustive warning here - ^ -f: (e: Exp)Int - -scala> - -scala> +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> // basics + +scala> 3+4 +res0: Int = 7 + +scala> def gcd(x: Int, y: Int): Int = { + if (x == 0) y + else if (y == 0) x + else gcd(y%x, x) +} +gcd: (x: Int, y: Int)Int + +scala> val five = gcd(15,35) +five: Int = 5 + +scala> var x = 1 +x: Int = 1 + +scala> x = 2 +x: Int = 2 + +scala> val three = x+1 +three: Int = 3 + +scala> type anotherint = Int +defined type alias anotherint + +scala> val four: anotherint = 4 +four: anotherint = 4 + +scala> val bogus: anotherint = "hello" +:8: error: type mismatch; + found : String("hello") + required: anotherint + (which expands to) Int + val bogus: anotherint = "hello" + ^ + +scala> trait PointlessTrait +defined trait PointlessTrait + +scala> val (x,y) = (2,3) +x: Int = 2 +y: Int = 3 + +scala> println("hello") +hello + +scala> + +scala> // ticket #1513 + +scala> val t1513 = Array(null) +t1513: Array[Null] = Array(null) + +scala> // ambiguous toString problem from #547 + +scala> val atom = new scala.xml.Atom() +atom: scala.xml.Atom[Unit] = () + +scala> // overriding toString problem from #1404 + +scala> class S(override val toString : String) +defined class S + +scala> val fish = new S("fish") +fish: S = fish + +scala> // Test that arrays pretty print nicely. + +scala> val arr = Array("What's", "up", "doc?") +arr: Array[String] = Array(What's, up, doc?) + +scala> // Test that arrays pretty print nicely, even when we give them type Any + +scala> val arrInt : Any = Array(1,2,3) +arrInt: Any = Array(1, 2, 3) + +scala> // Test that nested arrays are pretty-printed correctly + +scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4)) +arrArrInt: Any = Array(Array(1, 2), Array(3, 4)) + +scala> + +scala> // implicit conversions + +scala> case class Foo(n: Int) +defined class Foo + +scala> case class Bar(n: Int) +defined class Bar + +scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) +warning: there were 1 feature warnings; re-run with -feature for details +foo2bar: (foo: Foo)Bar + +scala> val bar: Bar = Foo(3) +bar: Bar = Bar(3) + +scala> + +scala> // importing from a previous result + +scala> import bar._ +import bar._ + +scala> val m = n +m: Int = 3 + +scala> + +scala> // stressing the imports mechanism + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> + +scala> + +scala> val x1 = 1 +x1: Int = 1 + +scala> val x2 = 1 +x2: Int = 1 + +scala> val x3 = 1 +x3: Int = 1 + +scala> val x4 = 1 +x4: Int = 1 + +scala> val x5 = 1 +x5: Int = 1 + +scala> val x6 = 1 +x6: Int = 1 + +scala> val x7 = 1 +x7: Int = 1 + +scala> val x8 = 1 +x8: Int = 1 + +scala> val x9 = 1 +x9: Int = 1 + +scala> val x10 = 1 +x10: Int = 1 + +scala> val x11 = 1 +x11: Int = 1 + +scala> val x12 = 1 +x12: Int = 1 + +scala> val x13 = 1 +x13: Int = 1 + +scala> val x14 = 1 +x14: Int = 1 + +scala> val x15 = 1 +x15: Int = 1 + +scala> val x16 = 1 +x16: Int = 1 + +scala> val x17 = 1 +x17: Int = 1 + +scala> val x18 = 1 +x18: Int = 1 + +scala> val x19 = 1 +x19: Int = 1 + +scala> val x20 = 1 +x20: Int = 1 + +scala> + +scala> val two = one + x5 +two: Int = 2 + +scala> + +scala> // handling generic wildcard arrays (#2386) + +scala> // It's put here because type feedback is an important part of it. + +scala> val xs: Array[_] = Array(1, 2) +xs: Array[_] = Array(1, 2) + +scala> xs.size +res2: Int = 2 + +scala> xs.head +res3: Any = 1 + +scala> xs filter (_ == 2) +res4: Array[_] = Array(2) + +scala> xs map (_ => "abc") +res5: Array[String] = Array(abc, abc) + +scala> xs map (x => x) +res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(1, 2) + +scala> xs map (x => (x, x)) +warning: there were 1 feature warnings; re-run with -feature for details +warning: there were 1 feature warnings; re-run with -feature for details +res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) + +scala> + +scala> // interior syntax errors should *not* go into multi-line input mode. + +scala> // both of the following should abort immediately: + +scala> def x => y => z +:1: error: '=' expected but '=>' found. + def x => y => z + ^ + +scala> [1,2,3] +:1: error: illegal start of definition + [1,2,3] + ^ + +scala> + +scala> + +scala> // multi-line XML + +scala> + +res8: scala.xml.Elem = + + + +scala> + +scala> + +scala> /* + /* + multi-line comment + */ +*/ + +scala> + +scala> + +scala> // multi-line string + +scala> """ +hello +there +""" +res9: String = +" +hello +there +" + +scala> + +scala> (1 + // give up early by typing two blank lines + + +You typed two blank lines. Starting a new command. + +scala> // defining and using quoted names should work (ticket #323) + +scala> def `match` = 1 +match: Int + +scala> val x = `match` +x: Int = 1 + +scala> + +scala> // multiple classes defined on one line + +scala> sealed class Exp; class Fact extends Exp; class Term extends Exp +defined class Exp +defined class Fact +defined class Term + +scala> def f(e: Exp) = e match { // non-exhaustive warning here + case _:Fact => 3 +} +:18: warning: match is not exhaustive! +missing combination Exp +missing combination Term + + def f(e: Exp) = e match { // non-exhaustive warning here + ^ +f: (e: Exp)Int + +scala> + +scala> plusOne: (x: Int)Int res0: Int = 6 res0: String = after reset diff --git a/test/files/pos/generic-sigs.scala b/test/files/pos/generic-sigs.scala index 40ec044656..b112766056 100644 --- a/test/files/pos/generic-sigs.scala +++ b/test/files/pos/generic-sigs.scala @@ -1,3 +1,5 @@ +import language.existentials + object A { def f1 = List(classOf[Int], classOf[String]) def f2 = List(classOf[String], classOf[Int]) @@ -15,4 +17,4 @@ object A { class Boppy[+T1,-T2] def g1 = new Boppy[t forSome { type t <: Int }, u forSome { type u <: String }] -} \ No newline at end of file +} diff --git a/test/files/pos/t1439.flags b/test/files/pos/t1439.flags index 830f024342..d86a0144e8 100644 --- a/test/files/pos/t1439.flags +++ b/test/files/pos/t1439.flags @@ -1 +1 @@ --unchecked -Xfatal-warnings -language:higher-kinds \ No newline at end of file +-unchecked -Xfatal-warnings -language:higherKinds \ No newline at end of file diff --git a/test/files/run/constrained-types.check b/test/files/run/constrained-types.check index ac8817cb08..37784a20ca 100644 --- a/test/files/run/constrained-types.check +++ b/test/files/run/constrained-types.check @@ -75,9 +75,13 @@ scala> var four = "four" four: String = four scala> val four2 = m(four) // should have an existential bound +warning: there were 1 feature warnings; re-run with -feature for details +warning: there were 1 feature warnings; re-run with -feature for details four2: String @Annot(x) forSome { val x: String } = four scala> val four3 = four2 // should have the same type as four2 +warning: there were 1 feature warnings; re-run with -feature for details +warning: there were 1 feature warnings; re-run with -feature for details four3: String @Annot(x) forSome { val x: String } = four scala> val stuff = m("stuff") // should not crash @@ -100,6 +104,8 @@ scala> def m = { val y : String @Annot(x) = x y } // x should not escape the local scope with a narrow type +warning: there were 1 feature warnings; re-run with -feature for details +warning: there were 1 feature warnings; re-run with -feature for details m: String @Annot(x) forSome { val x: String } scala> @@ -113,6 +119,7 @@ scala> def n(y: String) = { } m("stuff".stripMargin) } // x should be existentially bound +warning: there were 1 feature warnings; re-run with -feature for details n: (y: String)String @Annot(x) forSome { val x: String } scala> diff --git a/test/files/run/existentials-in-compiler.check b/test/files/run/existentials-in-compiler.check index 83e3cdf435..4df4b0ca96 100644 --- a/test/files/run/existentials-in-compiler.check +++ b/test/files/run/existentials-in-compiler.check @@ -100,8 +100,8 @@ abstract trait Cov31[+A, +B, C <: (A, B)] extends Object abstract trait Cov32[+A, B, C <: (A, B)] extends Object extest.Cov32[A,B,C] forSome { +A; B; C <: (A, B) } -abstract trait Cov33[+A, -B, C <: (A, _$10) forSome { type _$10 }] extends Object - extest.Cov33[A,B,C] forSome { +A; -B; C <: (A, _$10) forSome { type _$10 } } +abstract trait Cov33[+A, -B, C <: Tuple2[A, _]] extends Object + extest.Cov33[A,B,C] forSome { +A; -B; C <: Tuple2[A, _] } abstract trait Cov34[A, +B, C <: (A, B)] extends Object extest.Cov34[A,B,C] forSome { A; +B; C <: (A, B) } @@ -109,14 +109,14 @@ abstract trait Cov34[A, +B, C <: (A, B)] extends Object abstract trait Cov35[A, B, C <: (A, B)] extends Object extest.Cov35[A,B,C] forSome { A; B; C <: (A, B) } -abstract trait Cov36[A, -B, C <: (A, _$11) forSome { type _$11 }] extends Object - extest.Cov36[A,B,C] forSome { A; -B; C <: (A, _$11) forSome { type _$11 } } +abstract trait Cov36[A, -B, C <: Tuple2[A, _]] extends Object + extest.Cov36[A,B,C] forSome { A; -B; C <: Tuple2[A, _] } -abstract trait Cov37[-A, +B, C <: (_$12, B) forSome { type _$12 }] extends Object - extest.Cov37[A,B,C] forSome { -A; +B; C <: (_$12, B) forSome { type _$12 } } +abstract trait Cov37[-A, +B, C <: Tuple2[_, B]] extends Object + extest.Cov37[A,B,C] forSome { -A; +B; C <: Tuple2[_, B] } -abstract trait Cov38[-A, B, C <: (_$13, B) forSome { type _$13 }] extends Object - extest.Cov38[A,B,C] forSome { -A; B; C <: (_$13, B) forSome { type _$13 } } +abstract trait Cov38[-A, B, C <: Tuple2[_, B]] extends Object + extest.Cov38[A,B,C] forSome { -A; B; C <: Tuple2[_, B] } abstract trait Cov39[-A, -B, C <: Tuple2[_, _]] extends Object extest.Cov39[_, _, _ <: Tuple2[_, _]] diff --git a/test/files/run/macro-reflective-mamd-normal-mi.check b/test/files/run/macro-reflective-mamd-normal-mi.check index ac4213d6e9..e69de29bb2 100644 --- a/test/files/run/macro-reflective-mamd-normal-mi.check +++ b/test/files/run/macro-reflective-mamd-normal-mi.check @@ -1 +0,0 @@ -43 \ No newline at end of file diff --git a/test/files/run/macro-repl-basic.check b/test/files/run/macro-repl-basic.check index 3bc899f49b..9e0f9aa1a2 100644 --- a/test/files/run/macro-repl-basic.check +++ b/test/files/run/macro-repl-basic.check @@ -1,51 +1,54 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> - -scala> import scala.reflect.makro.{Context => Ctx} -import scala.reflect.makro.{Context=>Ctx} - -scala> - -scala> object Impls { - def foo(c: Ctx)(x: c.Expr[Int]) = { - import c.mirror._ - val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) - Expr[Int](body) - } - - def bar(c: Ctx)(x: c.Expr[Int]) = { - import c.mirror._ - val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) - Expr[Int](body) - } - - def quux(c: Ctx)(x: c.Expr[Int]) = { - import c.mirror._ - val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) - Expr[Int](body) - } -} -defined module Impls - -scala> object Macros { - object Shmacros { - def foo(x: Int): Int = macro Impls.foo - } - def bar(x: Int): Int = macro Impls.bar -}; class Macros { - def quux(x: Int): Int = macro Impls.quux -} -defined module Macros -defined class Macros - -scala> - -scala> import Macros.Shmacros._ -import Macros.Shmacros._ - -scala> println(foo(2) + Macros.bar(2) * new Macros().quux(4)) -31 - -scala> +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import language.experimental.macros +import language.experimental.macros + +scala> import scala.reflect.makro.{Context => Ctx} +import scala.reflect.makro.{Context=>Ctx} + +scala> + +scala> object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } + + def bar(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + Expr[Int](body) + } + + def quux(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} +defined module Impls + +scala> object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo + } + def bar(x: Int): Int = macro Impls.bar +}; class Macros { + def quux(x: Int): Int = macro Impls.quux +} +defined module Macros +defined class Macros + +scala> + +scala> import Macros.Shmacros._ +import Macros.Shmacros._ + +scala> println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +31 + +scala> diff --git a/test/files/run/macro-repl-basic.scala b/test/files/run/macro-repl-basic.scala index a21eb7815f..e8849b4b56 100644 --- a/test/files/run/macro-repl-basic.scala +++ b/test/files/run/macro-repl-basic.scala @@ -1,8 +1,8 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { - override def extraSettings = "-Xmacros" def code = """ + |import language.experimental.macros |import scala.reflect.makro.{Context => Ctx} | |object Impls { @@ -36,4 +36,4 @@ object Test extends ReplTest { |import Macros.Shmacros._ |println(foo(2) + Macros.bar(2) * new Macros().quux(4)) |""".stripMargin -} \ No newline at end of file +} diff --git a/test/files/run/macro-repl-dontexpand.scala b/test/files/run/macro-repl-dontexpand.scala index 9889a8ffdf..cd1b2e1969 100644 --- a/test/files/run/macro-repl-dontexpand.scala +++ b/test/files/run/macro-repl-dontexpand.scala @@ -1,9 +1,9 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { - override def extraSettings = "-Xmacros" + override def extraSettings = "-language:experimental.macros" def code = """ |def bar(c: scala.reflect.makro.Context) = ??? |def foo = macro bar |""".stripMargin -} \ No newline at end of file +} diff --git a/test/files/run/repl-parens.check b/test/files/run/repl-parens.check index 69f0a9ce30..4b7ce6b059 100644 --- a/test/files/run/repl-parens.check +++ b/test/files/run/repl-parens.check @@ -34,7 +34,7 @@ res7: (Int, Int) = (4,4) scala> (((2 + 2)), ((2 + 2)), 2) res8: (Int, Int, Int) = (4,4,2) -scala> ((((2 + 2)), ((2 + 2)), 2).productIterator ++ Iterator(3) mkString) +scala> (((((2 + 2)), ((2 + 2)), 2).productIterator ++ Iterator(3)).mkString) res9: String = 4423 scala> diff --git a/test/files/run/repl-parens.scala b/test/files/run/repl-parens.scala index c1cf9b50e1..e25933b1a2 100644 --- a/test/files/run/repl-parens.scala +++ b/test/files/run/repl-parens.scala @@ -11,7 +11,7 @@ object Test extends ReplTest { 5 ; ( (2 + 2 ) ) ; ((5)) (((2 + 2)), ((2 + 2))) (((2 + 2)), ((2 + 2)), 2) -((((2 + 2)), ((2 + 2)), 2).productIterator ++ Iterator(3) mkString) +(((((2 + 2)), ((2 + 2)), 2).productIterator ++ Iterator(3)).mkString) 55 ; ((2 + 2)) ; (1, 2, 3) 55 ; (x: Int) => x + 1 ; () => ((5)) @@ -26,4 +26,4 @@ foo(5)(10)(15)+foo(5)(10)(15) List(1) ++ List('a') """.trim -} \ No newline at end of file +} diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check index b811a4a8c5..e439a2a7f4 100644 --- a/test/files/run/repl-power.check +++ b/test/files/run/repl-power.check @@ -1,32 +1,33 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> :power -** Power User mode enabled - BEEP WHIR GYVE ** -** :phase has been set to 'typer'. ** -** scala.tools.nsc._ has been imported ** -** global._, definitions._ also imported ** -** Try :help, :vals, power. ** - -scala> // guarding against "error: reference to global is ambiguous" - -scala> global.emptyValDef // "it is imported twice in the same scope by ..." -res0: $r.global.emptyValDef.type = private val _ = _ - -scala> val tp = ArrayClass[scala.util.Random] // magic with manifests -tp: $r.global.Type = Array[scala.util.Random] - -scala> tp.memberType(Array_apply) // evidence -res1: $r.global.Type = (i: Int)scala.util.Random - -scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl -m: $r.treedsl.global.Match = -10 match { - case 5 => false - case _ => true -} - -scala> typed(m).tpe // typed is in scope -res2: $r.treedsl.global.Type = Boolean - -scala> +Type in expressions to have them evaluated. +Type :help for more information. + +scala> :power +** Power User mode enabled - BEEP WHIR GYVE ** +** :phase has been set to 'typer'. ** +** scala.tools.nsc._ has been imported ** +** global._, definitions._ also imported ** +** Try :help, :vals, power. ** + +scala> // guarding against "error: reference to global is ambiguous" + +scala> global.emptyValDef // "it is imported twice in the same scope by ..." +res0: $r.global.emptyValDef.type = private val _ = _ + +scala> val tp = ArrayClass[scala.util.Random] // magic with manifests +warning: there were 2 feature warnings; re-run with -feature for details +tp: $r.global.Type = Array[scala.util.Random] + +scala> tp.memberType(Array_apply) // evidence +res1: $r.global.Type = (i: Int)scala.util.Random + +scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl +m: $r.treedsl.global.Match = +10 match { + case 5 => false + case _ => true +} + +scala> typed(m).tpe // typed is in scope +res2: $r.treedsl.global.Type = Boolean + +scala> diff --git a/test/files/run/t4172.check b/test/files/run/t4172.check index da467e27ea..4598e02d1f 100644 --- a/test/files/run/t4172.check +++ b/test/files/run/t4172.check @@ -4,6 +4,8 @@ Type :help for more information. scala> scala> val c = { class C { override def toString = "C" }; ((new C, new C { def f = 2 })) } +warning: there were 1 feature warnings; re-run with -feature for details +warning: there were 1 feature warnings; re-run with -feature for details c: (C, C{def f: Int}) forSome { type C <: Object } = (C,C) scala> diff --git a/test/files/run/t4317/S_1.scala b/test/files/run/t4317/S_1.scala index 2de408268c..2756c879eb 100644 --- a/test/files/run/t4317/S_1.scala +++ b/test/files/run/t4317/S_1.scala @@ -1,3 +1,5 @@ +import language.existentials + object S_1 { def foo1(x: Class[_ <: AnyRef]) = 0 def foo2(x: Class[_ <: AnyRef], y: Int) = 99 diff --git a/test/files/run/t4710.check b/test/files/run/t4710.check index aa2f08d452..7c2b10b098 100644 --- a/test/files/run/t4710.check +++ b/test/files/run/t4710.check @@ -2,6 +2,7 @@ Type in expressions to have them evaluated. Type :help for more information. scala> def method : String = { implicit def f(s: Symbol) = "" ; 'symbol } +warning: there were 1 feature warnings; re-run with -feature for details method: String scala> -- cgit v1.2.3 From 53a0e803f03fe715c214c01c03f82baa19d7f2c2 Mon Sep 17 00:00:00 2001 From: Christopher Vogt Date: Sat, 14 Apr 2012 00:57:09 +0200 Subject: implemented DynamicProxy as portrayed by the Scala reflection team --- src/library/scala/reflect/DynamicProxy.scala | 67 ++++++++++++++++++++++++++ src/library/scala/reflect/api/Names.scala | 4 +- test/files/run/dynamic-proxy.check | 20 ++++++++ test/files/run/dynamic-proxy.flags | 1 + test/files/run/dynamic-proxy.scala | 72 ++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 src/library/scala/reflect/DynamicProxy.scala create mode 100644 test/files/run/dynamic-proxy.check create mode 100644 test/files/run/dynamic-proxy.flags create mode 100644 test/files/run/dynamic-proxy.scala diff --git a/src/library/scala/reflect/DynamicProxy.scala b/src/library/scala/reflect/DynamicProxy.scala new file mode 100644 index 0000000000..8449cb4063 --- /dev/null +++ b/src/library/scala/reflect/DynamicProxy.scala @@ -0,0 +1,67 @@ +package scala.reflect +/** + * A dynamic proxy which redirect method calls and attribute access to a given + * target object at runtime using reflection. + * A usage example can be found in test/files/run/dynamic-reflect.scala + * Not supported (yet): + * - implicit conversions and parameters + * - multiple arguments lists + * - explicit type arguments + */ +trait DynamicProxy extends Dynamic{ + val dynamicProxyTarget : AnyRef + + import scala.reflect.mirror._ + /** + * boxing to preserve information on primitive types for overloading resolution + */ + case class DynamicReflectBoxed( class_ : Class[_], value: Any ) + object DynamicReflectBoxed{ + implicit def box[@specialized T]( v:T ) = DynamicReflectBoxed( v.getClass, v ) + } + + def selectDynamic( method:String ) = { + val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName ) + invoke( dynamicProxyTarget, symbol )() + } + + def updateDynamic( method:String )( value : Any ) = { + val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method+"_=").encodedName ) + invoke( dynamicProxyTarget, symbol )( value ) + } + + def applyDynamic( method:String )( args:DynamicReflectBoxed* ) : Any + = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* ) + + def applyDynamicNamed( method:String )( args:(String,DynamicReflectBoxed)* ) : Any = { + val class_ = dynamicProxyTarget.getClass + var i = 0 + val toolbox = mkToolBox(mkConsoleReporter(),"") + val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName ) + if(args.size == 0){ + invoke( dynamicProxyTarget, symbol )() + } else { + val call = + Apply( + Select( + TypeApply( + Select( + Select( + Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this, null)) + , newTermName("dynamicProxyTarget") + ), + newTermName("asInstanceOf") ) + , List(TypeTree().setType(classToType(class_))) + ) + ,newTermName(method).encodedName + ) + ,args.map{ case(name,box) => + val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value, null)) + if( name == "" ) value + else AssignOrNamedArg( Ident(name), value ) + }.toList + ) + toolbox.runExpr( call ) + } + } +} diff --git a/src/library/scala/reflect/api/Names.scala b/src/library/scala/reflect/api/Names.scala index c72774dfc7..d92d056751 100755 --- a/src/library/scala/reflect/api/Names.scala +++ b/src/library/scala/reflect/api/Names.scala @@ -34,12 +34,12 @@ trait Names { def toTypeName: TypeName /** Replaces all occurrences of $op_names in this name by corresponding operator symbols. - * Example: `foo_+=` becomes `foo_$plus$eq`. + * Example: `foo_$plus$eq` becomes `foo_+=` */ def decoded: String /** Replaces all occurrences of operator symbols in this name by corresponding $op_names. - * Example: `foo_$plus$eq` becomes `foo_+=` + * Example: `foo_+=` becomes `foo_$plus$eq`. */ def encoded: String diff --git a/test/files/run/dynamic-proxy.check b/test/files/run/dynamic-proxy.check new file mode 100644 index 0000000000..83c386812d --- /dev/null +++ b/test/files/run/dynamic-proxy.check @@ -0,0 +1,20 @@ +noargs +noargs +nullary +value +symbolic +symbolic with args +non-existent method +before mutation +mutation 1 +after mutation 1 +mutation 2 +after mutation 2 +overloaded with object +overloaded with primitive +overloaded with object in var +overloaded with object in var 2 +typeArgs: I am a car +default: 4 +default: 3 +named: 6 diff --git a/test/files/run/dynamic-proxy.flags b/test/files/run/dynamic-proxy.flags new file mode 100644 index 0000000000..68ecfa03f8 --- /dev/null +++ b/test/files/run/dynamic-proxy.flags @@ -0,0 +1 @@ +-Xexperimental diff --git a/test/files/run/dynamic-proxy.scala b/test/files/run/dynamic-proxy.scala new file mode 100644 index 0000000000..194da2d092 --- /dev/null +++ b/test/files/run/dynamic-proxy.scala @@ -0,0 +1,72 @@ +import scala.reflect._ + +class Car{ override def toString = "I am a car" } +object x{ + def nullary = "nullary" + def noargs() = "noargs" + def - = "symbolic" + def $(s:String) = "symbolic with args" + val value = "value" + def overloaded(i:Int) = "overloaded with primitive" + def overloaded(s:String) = s + def default( a:Int, b:Int = 2 ) = "default: "+(a+b) + def named( a:Int, b:Int, c:Int ) = "named: "+(a+b+c) + def typeArgs[T]( v:T ) = "typeArgs: "+v + var mutable = "before mutation" + def multiArgLists( a:String )( b:String ) = "multiArgList " + a + b + def bar( s:String )(implicit car:Car) = s + car.toString +} + +object Test extends App{ + val d = new DynamicProxy{ val dynamicProxyTarget = x } + + println( d.noargs ) + println( d.noargs() ) + println( d.nullary ) + println( d.value ) + println( d.- ) + println( d.$("x") ) + + try{ + println( d.test ) + } catch { + case _ => println("non-existent method") + } + + println( d.mutable ) + + println("mutation 1") + d.mutable_=("after mutation 1") + println( d.mutable ) + + println("mutation 2") + d.mutable = "after mutation 2" + println( d.mutable ) + + println( d.overloaded("overloaded with object") ) + println( d.overloaded(1) ) + + // test some non-constant arguments + def s = "overloaded with object in var" + println( d.overloaded(s) ) + println( d.overloaded(s + " 2") ) + + val car = new Car + println( d.typeArgs(car) ) // inferred + // println( d.typeArgs[Car](car) ) // explicit not working (yet) + + println( d.default( 1,3 ) ) + println( d.default( 1 ) ) + + println( d.named(1,c=3,b=2) ) // applyDynamicNamed seems to be broken + + // println( d.multiArgLists("a")("b") ) // not working yet + + /* + // may never work + // testing implicit parameters (first test works when moving x into TestDynamicReflect) + implicit val car2 = new Car + println( d.bar( "Yeah, ") ); // FAILS: could not find implicit value for parameter car + {println( d.bar( "Yeah, ") )} // FAILS: could not find implicit value for parameter car + */ +} -- cgit v1.2.3 From e9280cba72d322973b14f3bc97cd43e423774144 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 13 Apr 2012 16:57:48 -0700 Subject: Disabled macro neg tests that no longer make sense in this form --- ...cro-deprecate-dont-touch-backquotedidents.check | 10 ++++ ...cro-deprecate-dont-touch-backquotedidents.flags | 1 + ...cro-deprecate-dont-touch-backquotedidents.scala | 56 ++++++++++++++++++++++ test/disabled/neg/macro-invalidshape-d.check | 4 ++ test/disabled/neg/macro-invalidshape-d.flags | 1 + .../neg/macro-invalidshape-d/Impls_1.scala | 5 ++ .../neg/macro-invalidshape-d/Macros_Test_2.scala | 8 ++++ test/disabled/neg/macro-keyword-bind.check | 7 +++ test/disabled/neg/macro-keyword-bind.flags | 1 + test/disabled/neg/macro-keyword-bind.scala | 6 +++ test/disabled/neg/macro-keyword-class1.check | 4 ++ test/disabled/neg/macro-keyword-class1.flags | 1 + test/disabled/neg/macro-keyword-class1.scala | 3 ++ test/disabled/neg/macro-keyword-class2.check | 4 ++ test/disabled/neg/macro-keyword-class2.flags | 1 + test/disabled/neg/macro-keyword-class2.scala | 3 ++ test/disabled/neg/macro-keyword-object1.check | 4 ++ test/disabled/neg/macro-keyword-object1.flags | 1 + test/disabled/neg/macro-keyword-object1.scala | 3 ++ test/disabled/neg/macro-keyword-object2.check | 4 ++ test/disabled/neg/macro-keyword-object2.flags | 1 + test/disabled/neg/macro-keyword-object2.scala | 3 ++ test/disabled/neg/macro-keyword-package1.check | 4 ++ test/disabled/neg/macro-keyword-package1.flags | 1 + test/disabled/neg/macro-keyword-package1.scala | 3 ++ test/disabled/neg/macro-keyword-package2.check | 4 ++ test/disabled/neg/macro-keyword-package2.flags | 1 + test/disabled/neg/macro-keyword-package2.scala | 3 ++ test/disabled/neg/macro-keyword-trait1.check | 4 ++ test/disabled/neg/macro-keyword-trait1.flags | 1 + test/disabled/neg/macro-keyword-trait1.scala | 3 ++ test/disabled/neg/macro-keyword-trait2.check | 4 ++ test/disabled/neg/macro-keyword-trait2.flags | 1 + test/disabled/neg/macro-keyword-trait2.scala | 3 ++ test/disabled/neg/macro-keyword-type.check | 4 ++ test/disabled/neg/macro-keyword-type.flags | 1 + test/disabled/neg/macro-keyword-type.scala | 3 ++ test/disabled/neg/macro-keyword-val.check | 7 +++ test/disabled/neg/macro-keyword-val.flags | 1 + test/disabled/neg/macro-keyword-val.scala | 3 ++ test/disabled/neg/macro-keyword-var.check | 7 +++ test/disabled/neg/macro-keyword-var.flags | 1 + test/disabled/neg/macro-keyword-var.scala | 3 ++ test/disabled/neg/macro-without-xmacros-a.check | 10 ++++ .../neg/macro-without-xmacros-a/Impls_1.scala | 18 +++++++ .../neg/macro-without-xmacros-a/Macros_2.scala | 12 +++++ .../neg/macro-without-xmacros-a/Test_3.scala | 4 ++ test/disabled/neg/macro-without-xmacros-b.check | 10 ++++ .../neg/macro-without-xmacros-b/Impls_1.scala | 18 +++++++ .../neg/macro-without-xmacros-b/Macros_2.scala | 10 ++++ .../neg/macro-without-xmacros-b/Test_3.scala | 4 ++ ...cro-deprecate-dont-touch-backquotedidents.check | 10 ---- ...cro-deprecate-dont-touch-backquotedidents.flags | 1 - ...cro-deprecate-dont-touch-backquotedidents.scala | 56 ---------------------- test/files/neg/macro-invalidshape-d.check | 4 -- test/files/neg/macro-invalidshape-d.flags | 1 - test/files/neg/macro-invalidshape-d/Impls_1.scala | 5 -- .../neg/macro-invalidshape-d/Macros_Test_2.scala | 8 ---- test/files/neg/macro-keyword-bind.check | 7 --- test/files/neg/macro-keyword-bind.flags | 1 - test/files/neg/macro-keyword-bind.scala | 6 --- test/files/neg/macro-keyword-class1.check | 4 -- test/files/neg/macro-keyword-class1.flags | 1 - test/files/neg/macro-keyword-class1.scala | 3 -- test/files/neg/macro-keyword-class2.check | 4 -- test/files/neg/macro-keyword-class2.flags | 1 - test/files/neg/macro-keyword-class2.scala | 3 -- test/files/neg/macro-keyword-object1.check | 4 -- test/files/neg/macro-keyword-object1.flags | 1 - test/files/neg/macro-keyword-object1.scala | 3 -- test/files/neg/macro-keyword-object2.check | 4 -- test/files/neg/macro-keyword-object2.flags | 1 - test/files/neg/macro-keyword-object2.scala | 3 -- test/files/neg/macro-keyword-package1.check | 4 -- test/files/neg/macro-keyword-package1.flags | 1 - test/files/neg/macro-keyword-package1.scala | 3 -- test/files/neg/macro-keyword-package2.check | 4 -- test/files/neg/macro-keyword-package2.flags | 1 - test/files/neg/macro-keyword-package2.scala | 3 -- test/files/neg/macro-keyword-trait1.check | 4 -- test/files/neg/macro-keyword-trait1.flags | 1 - test/files/neg/macro-keyword-trait1.scala | 3 -- test/files/neg/macro-keyword-trait2.check | 4 -- test/files/neg/macro-keyword-trait2.flags | 1 - test/files/neg/macro-keyword-trait2.scala | 3 -- test/files/neg/macro-keyword-type.check | 4 -- test/files/neg/macro-keyword-type.flags | 1 - test/files/neg/macro-keyword-type.scala | 3 -- test/files/neg/macro-keyword-val.check | 7 --- test/files/neg/macro-keyword-val.flags | 1 - test/files/neg/macro-keyword-val.scala | 3 -- test/files/neg/macro-keyword-var.check | 7 --- test/files/neg/macro-keyword-var.flags | 1 - test/files/neg/macro-keyword-var.scala | 3 -- test/files/neg/macro-without-xmacros-a.check | 10 ---- .../neg/macro-without-xmacros-a/Impls_1.scala | 18 ------- .../neg/macro-without-xmacros-a/Macros_2.scala | 12 ----- .../files/neg/macro-without-xmacros-a/Test_3.scala | 4 -- test/files/neg/macro-without-xmacros-b.check | 10 ---- .../neg/macro-without-xmacros-b/Impls_1.scala | 18 ------- .../neg/macro-without-xmacros-b/Macros_2.scala | 10 ---- .../files/neg/macro-without-xmacros-b/Test_3.scala | 4 -- 102 files changed, 279 insertions(+), 279 deletions(-) create mode 100644 test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.check create mode 100644 test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.flags create mode 100644 test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.scala create mode 100644 test/disabled/neg/macro-invalidshape-d.check create mode 100644 test/disabled/neg/macro-invalidshape-d.flags create mode 100644 test/disabled/neg/macro-invalidshape-d/Impls_1.scala create mode 100644 test/disabled/neg/macro-invalidshape-d/Macros_Test_2.scala create mode 100644 test/disabled/neg/macro-keyword-bind.check create mode 100644 test/disabled/neg/macro-keyword-bind.flags create mode 100644 test/disabled/neg/macro-keyword-bind.scala create mode 100644 test/disabled/neg/macro-keyword-class1.check create mode 100644 test/disabled/neg/macro-keyword-class1.flags create mode 100644 test/disabled/neg/macro-keyword-class1.scala create mode 100644 test/disabled/neg/macro-keyword-class2.check create mode 100644 test/disabled/neg/macro-keyword-class2.flags create mode 100644 test/disabled/neg/macro-keyword-class2.scala create mode 100644 test/disabled/neg/macro-keyword-object1.check create mode 100644 test/disabled/neg/macro-keyword-object1.flags create mode 100644 test/disabled/neg/macro-keyword-object1.scala create mode 100644 test/disabled/neg/macro-keyword-object2.check create mode 100644 test/disabled/neg/macro-keyword-object2.flags create mode 100644 test/disabled/neg/macro-keyword-object2.scala create mode 100644 test/disabled/neg/macro-keyword-package1.check create mode 100644 test/disabled/neg/macro-keyword-package1.flags create mode 100644 test/disabled/neg/macro-keyword-package1.scala create mode 100644 test/disabled/neg/macro-keyword-package2.check create mode 100644 test/disabled/neg/macro-keyword-package2.flags create mode 100644 test/disabled/neg/macro-keyword-package2.scala create mode 100644 test/disabled/neg/macro-keyword-trait1.check create mode 100644 test/disabled/neg/macro-keyword-trait1.flags create mode 100644 test/disabled/neg/macro-keyword-trait1.scala create mode 100644 test/disabled/neg/macro-keyword-trait2.check create mode 100644 test/disabled/neg/macro-keyword-trait2.flags create mode 100644 test/disabled/neg/macro-keyword-trait2.scala create mode 100644 test/disabled/neg/macro-keyword-type.check create mode 100644 test/disabled/neg/macro-keyword-type.flags create mode 100644 test/disabled/neg/macro-keyword-type.scala create mode 100644 test/disabled/neg/macro-keyword-val.check create mode 100644 test/disabled/neg/macro-keyword-val.flags create mode 100644 test/disabled/neg/macro-keyword-val.scala create mode 100644 test/disabled/neg/macro-keyword-var.check create mode 100644 test/disabled/neg/macro-keyword-var.flags create mode 100644 test/disabled/neg/macro-keyword-var.scala create mode 100644 test/disabled/neg/macro-without-xmacros-a.check create mode 100644 test/disabled/neg/macro-without-xmacros-a/Impls_1.scala create mode 100644 test/disabled/neg/macro-without-xmacros-a/Macros_2.scala create mode 100644 test/disabled/neg/macro-without-xmacros-a/Test_3.scala create mode 100644 test/disabled/neg/macro-without-xmacros-b.check create mode 100644 test/disabled/neg/macro-without-xmacros-b/Impls_1.scala create mode 100644 test/disabled/neg/macro-without-xmacros-b/Macros_2.scala create mode 100644 test/disabled/neg/macro-without-xmacros-b/Test_3.scala delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents.check delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents.flags delete mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents.scala delete mode 100644 test/files/neg/macro-invalidshape-d.check delete mode 100644 test/files/neg/macro-invalidshape-d.flags delete mode 100644 test/files/neg/macro-invalidshape-d/Impls_1.scala delete mode 100644 test/files/neg/macro-invalidshape-d/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-keyword-bind.check delete mode 100644 test/files/neg/macro-keyword-bind.flags delete mode 100644 test/files/neg/macro-keyword-bind.scala delete mode 100644 test/files/neg/macro-keyword-class1.check delete mode 100644 test/files/neg/macro-keyword-class1.flags delete mode 100644 test/files/neg/macro-keyword-class1.scala delete mode 100644 test/files/neg/macro-keyword-class2.check delete mode 100644 test/files/neg/macro-keyword-class2.flags delete mode 100644 test/files/neg/macro-keyword-class2.scala delete mode 100644 test/files/neg/macro-keyword-object1.check delete mode 100644 test/files/neg/macro-keyword-object1.flags delete mode 100644 test/files/neg/macro-keyword-object1.scala delete mode 100644 test/files/neg/macro-keyword-object2.check delete mode 100644 test/files/neg/macro-keyword-object2.flags delete mode 100644 test/files/neg/macro-keyword-object2.scala delete mode 100644 test/files/neg/macro-keyword-package1.check delete mode 100644 test/files/neg/macro-keyword-package1.flags delete mode 100644 test/files/neg/macro-keyword-package1.scala delete mode 100644 test/files/neg/macro-keyword-package2.check delete mode 100644 test/files/neg/macro-keyword-package2.flags delete mode 100644 test/files/neg/macro-keyword-package2.scala delete mode 100644 test/files/neg/macro-keyword-trait1.check delete mode 100644 test/files/neg/macro-keyword-trait1.flags delete mode 100644 test/files/neg/macro-keyword-trait1.scala delete mode 100644 test/files/neg/macro-keyword-trait2.check delete mode 100644 test/files/neg/macro-keyword-trait2.flags delete mode 100644 test/files/neg/macro-keyword-trait2.scala delete mode 100644 test/files/neg/macro-keyword-type.check delete mode 100644 test/files/neg/macro-keyword-type.flags delete mode 100644 test/files/neg/macro-keyword-type.scala delete mode 100644 test/files/neg/macro-keyword-val.check delete mode 100644 test/files/neg/macro-keyword-val.flags delete mode 100644 test/files/neg/macro-keyword-val.scala delete mode 100644 test/files/neg/macro-keyword-var.check delete mode 100644 test/files/neg/macro-keyword-var.flags delete mode 100644 test/files/neg/macro-keyword-var.scala delete mode 100644 test/files/neg/macro-without-xmacros-a.check delete mode 100644 test/files/neg/macro-without-xmacros-a/Impls_1.scala delete mode 100644 test/files/neg/macro-without-xmacros-a/Macros_2.scala delete mode 100644 test/files/neg/macro-without-xmacros-a/Test_3.scala delete mode 100644 test/files/neg/macro-without-xmacros-b.check delete mode 100644 test/files/neg/macro-without-xmacros-b/Impls_1.scala delete mode 100644 test/files/neg/macro-without-xmacros-b/Macros_2.scala delete mode 100644 test/files/neg/macro-without-xmacros-b/Test_3.scala diff --git a/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.check b/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.check new file mode 100644 index 0000000000..25df9a6a4a --- /dev/null +++ b/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.check @@ -0,0 +1,10 @@ +macro-deprecate-dont-touch-backquotedidents.scala:37: error: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro` { + ^ +macro-deprecate-dont-touch-backquotedidents.scala:38: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + package `macro`.bar { + ^ +macro-deprecate-dont-touch-backquotedidents.scala:43: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + package `macro`.foo { + ^ +three errors found diff --git a/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.flags b/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.scala b/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.scala new file mode 100644 index 0000000000..dee2f1de3b --- /dev/null +++ b/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.scala @@ -0,0 +1,56 @@ +object Test1 { + val `macro` = ??? +} + +object Test2 { + var `macro` = ??? +} + +object Test3 { + type `macro` = Int +} + +package test4 { + class `macro` +} + +object Test5 { + class `macro` +} + +package test6 { + object `macro` +} + +object Test7 { + object `macro` +} + +package test8 { + trait `macro` +} + +object Test9 { + trait `macro` +} + +package `macro` { + package `macro`.bar { + } +} + +package foo { + package `macro`.foo { + } +} + +object Test12 { + val Some(`macro`) = Some(42) + `macro` match { + case `macro` => println(`macro`) + } +} + +object Test13 { + def `macro` = 2 +} \ No newline at end of file diff --git a/test/disabled/neg/macro-invalidshape-d.check b/test/disabled/neg/macro-invalidshape-d.check new file mode 100644 index 0000000000..031aa653ab --- /dev/null +++ b/test/disabled/neg/macro-invalidshape-d.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: illegal start of statement + def foo(x: Any) = {2; macro Impls.foo} + ^ +one error found diff --git a/test/disabled/neg/macro-invalidshape-d.flags b/test/disabled/neg/macro-invalidshape-d.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/disabled/neg/macro-invalidshape-d.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-invalidshape-d/Impls_1.scala b/test/disabled/neg/macro-invalidshape-d/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/disabled/neg/macro-invalidshape-d/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/disabled/neg/macro-invalidshape-d/Macros_Test_2.scala b/test/disabled/neg/macro-invalidshape-d/Macros_Test_2.scala new file mode 100644 index 0000000000..bacd9a6e7c --- /dev/null +++ b/test/disabled/neg/macro-invalidshape-d/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = {2; macro Impls.foo} +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-bind.check b/test/disabled/neg/macro-keyword-bind.check new file mode 100644 index 0000000000..1f74cfe5cd --- /dev/null +++ b/test/disabled/neg/macro-keyword-bind.check @@ -0,0 +1,7 @@ +macro-keyword-bind.scala:2: error: illegal start of simple pattern + val Some(macro) = Some(42) + ^ +macro-keyword-bind.scala:6: error: ')' expected but '}' found. +} +^ +two errors found diff --git a/test/disabled/neg/macro-keyword-bind.flags b/test/disabled/neg/macro-keyword-bind.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-bind.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-bind.scala b/test/disabled/neg/macro-keyword-bind.scala new file mode 100644 index 0000000000..a3b1553348 --- /dev/null +++ b/test/disabled/neg/macro-keyword-bind.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-class1.check b/test/disabled/neg/macro-keyword-class1.check new file mode 100644 index 0000000000..d8983180ef --- /dev/null +++ b/test/disabled/neg/macro-keyword-class1.check @@ -0,0 +1,4 @@ +macro-keyword-class1.scala:3: error: identifier expected but 'macro' found. +class macro + ^ +one error found diff --git a/test/disabled/neg/macro-keyword-class1.flags b/test/disabled/neg/macro-keyword-class1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-class1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-class1.scala b/test/disabled/neg/macro-keyword-class1.scala new file mode 100644 index 0000000000..8635d1f4f6 --- /dev/null +++ b/test/disabled/neg/macro-keyword-class1.scala @@ -0,0 +1,3 @@ +package test4 + +class macro diff --git a/test/disabled/neg/macro-keyword-class2.check b/test/disabled/neg/macro-keyword-class2.check new file mode 100644 index 0000000000..0e4d11bcc4 --- /dev/null +++ b/test/disabled/neg/macro-keyword-class2.check @@ -0,0 +1,4 @@ +macro-keyword-class2.scala:2: error: identifier expected but 'macro' found. + class macro + ^ +one error found diff --git a/test/disabled/neg/macro-keyword-class2.flags b/test/disabled/neg/macro-keyword-class2.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-class2.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-class2.scala b/test/disabled/neg/macro-keyword-class2.scala new file mode 100644 index 0000000000..af24a489d0 --- /dev/null +++ b/test/disabled/neg/macro-keyword-class2.scala @@ -0,0 +1,3 @@ +object Test5 { + class macro +} diff --git a/test/disabled/neg/macro-keyword-object1.check b/test/disabled/neg/macro-keyword-object1.check new file mode 100644 index 0000000000..cfbd06ffd6 --- /dev/null +++ b/test/disabled/neg/macro-keyword-object1.check @@ -0,0 +1,4 @@ +macro-keyword-object1.scala:3: error: identifier expected but 'macro' found. +object macro + ^ +one error found diff --git a/test/disabled/neg/macro-keyword-object1.flags b/test/disabled/neg/macro-keyword-object1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-object1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-object1.scala b/test/disabled/neg/macro-keyword-object1.scala new file mode 100644 index 0000000000..66eb494e6b --- /dev/null +++ b/test/disabled/neg/macro-keyword-object1.scala @@ -0,0 +1,3 @@ +package test6 + +object macro diff --git a/test/disabled/neg/macro-keyword-object2.check b/test/disabled/neg/macro-keyword-object2.check new file mode 100644 index 0000000000..ede31f13e5 --- /dev/null +++ b/test/disabled/neg/macro-keyword-object2.check @@ -0,0 +1,4 @@ +macro-keyword-object2.scala:2: error: identifier expected but 'macro' found. + object macro + ^ +one error found diff --git a/test/disabled/neg/macro-keyword-object2.flags b/test/disabled/neg/macro-keyword-object2.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-object2.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-object2.scala b/test/disabled/neg/macro-keyword-object2.scala new file mode 100644 index 0000000000..6f5b9ceacd --- /dev/null +++ b/test/disabled/neg/macro-keyword-object2.scala @@ -0,0 +1,3 @@ +object Test7 { + object macro +} diff --git a/test/disabled/neg/macro-keyword-package1.check b/test/disabled/neg/macro-keyword-package1.check new file mode 100644 index 0000000000..22c1e11ded --- /dev/null +++ b/test/disabled/neg/macro-keyword-package1.check @@ -0,0 +1,4 @@ +macro-keyword-package1.scala:1: error: identifier expected but 'macro' found. +package macro + ^ +one error found diff --git a/test/disabled/neg/macro-keyword-package1.flags b/test/disabled/neg/macro-keyword-package1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-package1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-package1.scala b/test/disabled/neg/macro-keyword-package1.scala new file mode 100644 index 0000000000..52d3fbabf6 --- /dev/null +++ b/test/disabled/neg/macro-keyword-package1.scala @@ -0,0 +1,3 @@ +package macro + +package macro.bar \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-package2.check b/test/disabled/neg/macro-keyword-package2.check new file mode 100644 index 0000000000..0cb542a85d --- /dev/null +++ b/test/disabled/neg/macro-keyword-package2.check @@ -0,0 +1,4 @@ +macro-keyword-package2.scala:3: error: identifier expected but 'macro' found. +package macro.foo + ^ +one error found diff --git a/test/disabled/neg/macro-keyword-package2.flags b/test/disabled/neg/macro-keyword-package2.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-package2.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-package2.scala b/test/disabled/neg/macro-keyword-package2.scala new file mode 100644 index 0000000000..a68ebd935f --- /dev/null +++ b/test/disabled/neg/macro-keyword-package2.scala @@ -0,0 +1,3 @@ +package foo + +package macro.foo diff --git a/test/disabled/neg/macro-keyword-trait1.check b/test/disabled/neg/macro-keyword-trait1.check new file mode 100644 index 0000000000..9586a62e08 --- /dev/null +++ b/test/disabled/neg/macro-keyword-trait1.check @@ -0,0 +1,4 @@ +macro-keyword-trait1.scala:3: error: identifier expected but 'macro' found. +trait macro + ^ +one error found diff --git a/test/disabled/neg/macro-keyword-trait1.flags b/test/disabled/neg/macro-keyword-trait1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-trait1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-trait1.scala b/test/disabled/neg/macro-keyword-trait1.scala new file mode 100644 index 0000000000..e32d4c1385 --- /dev/null +++ b/test/disabled/neg/macro-keyword-trait1.scala @@ -0,0 +1,3 @@ +package test8 + +trait macro diff --git a/test/disabled/neg/macro-keyword-trait2.check b/test/disabled/neg/macro-keyword-trait2.check new file mode 100644 index 0000000000..40aa764378 --- /dev/null +++ b/test/disabled/neg/macro-keyword-trait2.check @@ -0,0 +1,4 @@ +macro-keyword-trait2.scala:2: error: identifier expected but 'macro' found. + trait macro + ^ +one error found diff --git a/test/disabled/neg/macro-keyword-trait2.flags b/test/disabled/neg/macro-keyword-trait2.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-trait2.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-trait2.scala b/test/disabled/neg/macro-keyword-trait2.scala new file mode 100644 index 0000000000..243a54abe6 --- /dev/null +++ b/test/disabled/neg/macro-keyword-trait2.scala @@ -0,0 +1,3 @@ +object Test9 { + trait macro +} diff --git a/test/disabled/neg/macro-keyword-type.check b/test/disabled/neg/macro-keyword-type.check new file mode 100644 index 0000000000..4a7481114c --- /dev/null +++ b/test/disabled/neg/macro-keyword-type.check @@ -0,0 +1,4 @@ +macro-keyword-type.scala:2: error: identifier expected but 'macro' found. + type macro = Int + ^ +one error found diff --git a/test/disabled/neg/macro-keyword-type.flags b/test/disabled/neg/macro-keyword-type.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-type.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-type.scala b/test/disabled/neg/macro-keyword-type.scala new file mode 100644 index 0000000000..30e523bcaf --- /dev/null +++ b/test/disabled/neg/macro-keyword-type.scala @@ -0,0 +1,3 @@ +object Test3 { + type macro = Int +} \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-val.check b/test/disabled/neg/macro-keyword-val.check new file mode 100644 index 0000000000..0dc4c030a9 --- /dev/null +++ b/test/disabled/neg/macro-keyword-val.check @@ -0,0 +1,7 @@ +macro-keyword-val.scala:2: error: illegal start of simple pattern + val macro = ??? + ^ +macro-keyword-val.scala:3: error: '=' expected but '}' found. +} +^ +two errors found diff --git a/test/disabled/neg/macro-keyword-val.flags b/test/disabled/neg/macro-keyword-val.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/disabled/neg/macro-keyword-val.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-val.scala b/test/disabled/neg/macro-keyword-val.scala new file mode 100644 index 0000000000..96f57acb30 --- /dev/null +++ b/test/disabled/neg/macro-keyword-val.scala @@ -0,0 +1,3 @@ +object Test1 { + val macro = ??? +} \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-var.check b/test/disabled/neg/macro-keyword-var.check new file mode 100644 index 0000000000..96d02e0052 --- /dev/null +++ b/test/disabled/neg/macro-keyword-var.check @@ -0,0 +1,7 @@ +macro-keyword-var.scala:2: error: illegal start of simple pattern + var macro = ??? + ^ +macro-keyword-var.scala:3: error: '=' expected but '}' found. +} +^ +two errors found diff --git a/test/disabled/neg/macro-keyword-var.flags b/test/disabled/neg/macro-keyword-var.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/disabled/neg/macro-keyword-var.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-var.scala b/test/disabled/neg/macro-keyword-var.scala new file mode 100644 index 0000000000..a79dda6dc2 --- /dev/null +++ b/test/disabled/neg/macro-keyword-var.scala @@ -0,0 +1,3 @@ +object Test2 { + var macro = ??? +} \ No newline at end of file diff --git a/test/disabled/neg/macro-without-xmacros-a.check b/test/disabled/neg/macro-without-xmacros-a.check new file mode 100644 index 0000000000..a3ca081f04 --- /dev/null +++ b/test/disabled/neg/macro-without-xmacros-a.check @@ -0,0 +1,10 @@ +Macros_2.scala:5: error: not found: value macro + def foo(x: Int): Int = macro foo_impl + ^ +Macros_2.scala:7: error: not found: value macro + def bar(x: Int): Int = macro bar_impl + ^ +Macros_2.scala:11: error: not found: value macro + def quux(x: Int): Int = macro quux_impl + ^ +three errors found diff --git a/test/disabled/neg/macro-without-xmacros-a/Impls_1.scala b/test/disabled/neg/macro-without-xmacros-a/Impls_1.scala new file mode 100644 index 0000000000..2493c81c95 --- /dev/null +++ b/test/disabled/neg/macro-without-xmacros-a/Impls_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + } +} diff --git a/test/disabled/neg/macro-without-xmacros-a/Macros_2.scala b/test/disabled/neg/macro-without-xmacros-a/Macros_2.scala new file mode 100644 index 0000000000..62f9dcf505 --- /dev/null +++ b/test/disabled/neg/macro-without-xmacros-a/Macros_2.scala @@ -0,0 +1,12 @@ +import Impls._ + +object Macros { + object Shmacros { + def foo(x: Int): Int = macro foo_impl + } + def bar(x: Int): Int = macro bar_impl +} + +class Macros { + def quux(x: Int): Int = macro quux_impl +} \ No newline at end of file diff --git a/test/disabled/neg/macro-without-xmacros-a/Test_3.scala b/test/disabled/neg/macro-without-xmacros-a/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/disabled/neg/macro-without-xmacros-a/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/disabled/neg/macro-without-xmacros-b.check b/test/disabled/neg/macro-without-xmacros-b.check new file mode 100644 index 0000000000..dce4a084c9 --- /dev/null +++ b/test/disabled/neg/macro-without-xmacros-b.check @@ -0,0 +1,10 @@ +Macros_2.scala:3: error: ';' expected but '.' found. + def foo(x: Int): Int = macro Impls.foo_impl + ^ +Macros_2.scala:5: error: ';' expected but '.' found. + def bar(x: Int): Int = macro Impls.bar_impl + ^ +Macros_2.scala:9: error: ';' expected but '.' found. + def quux(x: Int): Int = macro Impls.quux_impl + ^ +three errors found diff --git a/test/disabled/neg/macro-without-xmacros-b/Impls_1.scala b/test/disabled/neg/macro-without-xmacros-b/Impls_1.scala new file mode 100644 index 0000000000..2493c81c95 --- /dev/null +++ b/test/disabled/neg/macro-without-xmacros-b/Impls_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + } +} diff --git a/test/disabled/neg/macro-without-xmacros-b/Macros_2.scala b/test/disabled/neg/macro-without-xmacros-b/Macros_2.scala new file mode 100644 index 0000000000..de7080c7e8 --- /dev/null +++ b/test/disabled/neg/macro-without-xmacros-b/Macros_2.scala @@ -0,0 +1,10 @@ +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo_impl + } + def bar(x: Int): Int = macro Impls.bar_impl +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux_impl +} \ No newline at end of file diff --git a/test/disabled/neg/macro-without-xmacros-b/Test_3.scala b/test/disabled/neg/macro-without-xmacros-b/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/disabled/neg/macro-without-xmacros-b/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check deleted file mode 100644 index 25df9a6a4a..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check +++ /dev/null @@ -1,10 +0,0 @@ -macro-deprecate-dont-touch-backquotedidents.scala:37: error: in future versions of Scala "macro" will be a keyword. consider using a different name. -package `macro` { - ^ -macro-deprecate-dont-touch-backquotedidents.scala:38: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - package `macro`.bar { - ^ -macro-deprecate-dont-touch-backquotedidents.scala:43: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - package `macro`.foo { - ^ -three errors found diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.flags b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.flags deleted file mode 100644 index e8fb65d50c..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.flags +++ /dev/null @@ -1 +0,0 @@ --Xfatal-warnings \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.scala deleted file mode 100644 index dee2f1de3b..0000000000 --- a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.scala +++ /dev/null @@ -1,56 +0,0 @@ -object Test1 { - val `macro` = ??? -} - -object Test2 { - var `macro` = ??? -} - -object Test3 { - type `macro` = Int -} - -package test4 { - class `macro` -} - -object Test5 { - class `macro` -} - -package test6 { - object `macro` -} - -object Test7 { - object `macro` -} - -package test8 { - trait `macro` -} - -object Test9 { - trait `macro` -} - -package `macro` { - package `macro`.bar { - } -} - -package foo { - package `macro`.foo { - } -} - -object Test12 { - val Some(`macro`) = Some(42) - `macro` match { - case `macro` => println(`macro`) - } -} - -object Test13 { - def `macro` = 2 -} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d.check b/test/files/neg/macro-invalidshape-d.check deleted file mode 100644 index 031aa653ab..0000000000 --- a/test/files/neg/macro-invalidshape-d.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:2: error: illegal start of statement - def foo(x: Any) = {2; macro Impls.foo} - ^ -one error found diff --git a/test/files/neg/macro-invalidshape-d.flags b/test/files/neg/macro-invalidshape-d.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-invalidshape-d.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d/Impls_1.scala b/test/files/neg/macro-invalidshape-d/Impls_1.scala deleted file mode 100644 index 7b1620d117..0000000000 --- a/test/files/neg/macro-invalidshape-d/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.makro.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala deleted file mode 100644 index bacd9a6e7c..0000000000 --- a/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = {2; macro Impls.foo} -} - -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/files/neg/macro-keyword-bind.check b/test/files/neg/macro-keyword-bind.check deleted file mode 100644 index 1f74cfe5cd..0000000000 --- a/test/files/neg/macro-keyword-bind.check +++ /dev/null @@ -1,7 +0,0 @@ -macro-keyword-bind.scala:2: error: illegal start of simple pattern - val Some(macro) = Some(42) - ^ -macro-keyword-bind.scala:6: error: ')' expected but '}' found. -} -^ -two errors found diff --git a/test/files/neg/macro-keyword-bind.flags b/test/files/neg/macro-keyword-bind.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-bind.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-bind.scala b/test/files/neg/macro-keyword-bind.scala deleted file mode 100644 index a3b1553348..0000000000 --- a/test/files/neg/macro-keyword-bind.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test12 { - val Some(macro) = Some(42) - macro match { - case macro => println(macro) - } -} \ No newline at end of file diff --git a/test/files/neg/macro-keyword-class1.check b/test/files/neg/macro-keyword-class1.check deleted file mode 100644 index d8983180ef..0000000000 --- a/test/files/neg/macro-keyword-class1.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-class1.scala:3: error: identifier expected but 'macro' found. -class macro - ^ -one error found diff --git a/test/files/neg/macro-keyword-class1.flags b/test/files/neg/macro-keyword-class1.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-class1.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-class1.scala b/test/files/neg/macro-keyword-class1.scala deleted file mode 100644 index 8635d1f4f6..0000000000 --- a/test/files/neg/macro-keyword-class1.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test4 - -class macro diff --git a/test/files/neg/macro-keyword-class2.check b/test/files/neg/macro-keyword-class2.check deleted file mode 100644 index 0e4d11bcc4..0000000000 --- a/test/files/neg/macro-keyword-class2.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-class2.scala:2: error: identifier expected but 'macro' found. - class macro - ^ -one error found diff --git a/test/files/neg/macro-keyword-class2.flags b/test/files/neg/macro-keyword-class2.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-class2.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-class2.scala b/test/files/neg/macro-keyword-class2.scala deleted file mode 100644 index af24a489d0..0000000000 --- a/test/files/neg/macro-keyword-class2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test5 { - class macro -} diff --git a/test/files/neg/macro-keyword-object1.check b/test/files/neg/macro-keyword-object1.check deleted file mode 100644 index cfbd06ffd6..0000000000 --- a/test/files/neg/macro-keyword-object1.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-object1.scala:3: error: identifier expected but 'macro' found. -object macro - ^ -one error found diff --git a/test/files/neg/macro-keyword-object1.flags b/test/files/neg/macro-keyword-object1.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-object1.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-object1.scala b/test/files/neg/macro-keyword-object1.scala deleted file mode 100644 index 66eb494e6b..0000000000 --- a/test/files/neg/macro-keyword-object1.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test6 - -object macro diff --git a/test/files/neg/macro-keyword-object2.check b/test/files/neg/macro-keyword-object2.check deleted file mode 100644 index ede31f13e5..0000000000 --- a/test/files/neg/macro-keyword-object2.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-object2.scala:2: error: identifier expected but 'macro' found. - object macro - ^ -one error found diff --git a/test/files/neg/macro-keyword-object2.flags b/test/files/neg/macro-keyword-object2.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-object2.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-object2.scala b/test/files/neg/macro-keyword-object2.scala deleted file mode 100644 index 6f5b9ceacd..0000000000 --- a/test/files/neg/macro-keyword-object2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test7 { - object macro -} diff --git a/test/files/neg/macro-keyword-package1.check b/test/files/neg/macro-keyword-package1.check deleted file mode 100644 index 22c1e11ded..0000000000 --- a/test/files/neg/macro-keyword-package1.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-package1.scala:1: error: identifier expected but 'macro' found. -package macro - ^ -one error found diff --git a/test/files/neg/macro-keyword-package1.flags b/test/files/neg/macro-keyword-package1.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-package1.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-package1.scala b/test/files/neg/macro-keyword-package1.scala deleted file mode 100644 index 52d3fbabf6..0000000000 --- a/test/files/neg/macro-keyword-package1.scala +++ /dev/null @@ -1,3 +0,0 @@ -package macro - -package macro.bar \ No newline at end of file diff --git a/test/files/neg/macro-keyword-package2.check b/test/files/neg/macro-keyword-package2.check deleted file mode 100644 index 0cb542a85d..0000000000 --- a/test/files/neg/macro-keyword-package2.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-package2.scala:3: error: identifier expected but 'macro' found. -package macro.foo - ^ -one error found diff --git a/test/files/neg/macro-keyword-package2.flags b/test/files/neg/macro-keyword-package2.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-package2.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-package2.scala b/test/files/neg/macro-keyword-package2.scala deleted file mode 100644 index a68ebd935f..0000000000 --- a/test/files/neg/macro-keyword-package2.scala +++ /dev/null @@ -1,3 +0,0 @@ -package foo - -package macro.foo diff --git a/test/files/neg/macro-keyword-trait1.check b/test/files/neg/macro-keyword-trait1.check deleted file mode 100644 index 9586a62e08..0000000000 --- a/test/files/neg/macro-keyword-trait1.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-trait1.scala:3: error: identifier expected but 'macro' found. -trait macro - ^ -one error found diff --git a/test/files/neg/macro-keyword-trait1.flags b/test/files/neg/macro-keyword-trait1.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-trait1.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-trait1.scala b/test/files/neg/macro-keyword-trait1.scala deleted file mode 100644 index e32d4c1385..0000000000 --- a/test/files/neg/macro-keyword-trait1.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test8 - -trait macro diff --git a/test/files/neg/macro-keyword-trait2.check b/test/files/neg/macro-keyword-trait2.check deleted file mode 100644 index 40aa764378..0000000000 --- a/test/files/neg/macro-keyword-trait2.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-trait2.scala:2: error: identifier expected but 'macro' found. - trait macro - ^ -one error found diff --git a/test/files/neg/macro-keyword-trait2.flags b/test/files/neg/macro-keyword-trait2.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-trait2.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-trait2.scala b/test/files/neg/macro-keyword-trait2.scala deleted file mode 100644 index 243a54abe6..0000000000 --- a/test/files/neg/macro-keyword-trait2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test9 { - trait macro -} diff --git a/test/files/neg/macro-keyword-type.check b/test/files/neg/macro-keyword-type.check deleted file mode 100644 index 4a7481114c..0000000000 --- a/test/files/neg/macro-keyword-type.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-type.scala:2: error: identifier expected but 'macro' found. - type macro = Int - ^ -one error found diff --git a/test/files/neg/macro-keyword-type.flags b/test/files/neg/macro-keyword-type.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-type.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-type.scala b/test/files/neg/macro-keyword-type.scala deleted file mode 100644 index 30e523bcaf..0000000000 --- a/test/files/neg/macro-keyword-type.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test3 { - type macro = Int -} \ No newline at end of file diff --git a/test/files/neg/macro-keyword-val.check b/test/files/neg/macro-keyword-val.check deleted file mode 100644 index 0dc4c030a9..0000000000 --- a/test/files/neg/macro-keyword-val.check +++ /dev/null @@ -1,7 +0,0 @@ -macro-keyword-val.scala:2: error: illegal start of simple pattern - val macro = ??? - ^ -macro-keyword-val.scala:3: error: '=' expected but '}' found. -} -^ -two errors found diff --git a/test/files/neg/macro-keyword-val.flags b/test/files/neg/macro-keyword-val.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/neg/macro-keyword-val.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-val.scala b/test/files/neg/macro-keyword-val.scala deleted file mode 100644 index 96f57acb30..0000000000 --- a/test/files/neg/macro-keyword-val.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test1 { - val macro = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-keyword-var.check b/test/files/neg/macro-keyword-var.check deleted file mode 100644 index 96d02e0052..0000000000 --- a/test/files/neg/macro-keyword-var.check +++ /dev/null @@ -1,7 +0,0 @@ -macro-keyword-var.scala:2: error: illegal start of simple pattern - var macro = ??? - ^ -macro-keyword-var.scala:3: error: '=' expected but '}' found. -} -^ -two errors found diff --git a/test/files/neg/macro-keyword-var.flags b/test/files/neg/macro-keyword-var.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/neg/macro-keyword-var.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-keyword-var.scala b/test/files/neg/macro-keyword-var.scala deleted file mode 100644 index a79dda6dc2..0000000000 --- a/test/files/neg/macro-keyword-var.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test2 { - var macro = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-a.check b/test/files/neg/macro-without-xmacros-a.check deleted file mode 100644 index a3ca081f04..0000000000 --- a/test/files/neg/macro-without-xmacros-a.check +++ /dev/null @@ -1,10 +0,0 @@ -Macros_2.scala:5: error: not found: value macro - def foo(x: Int): Int = macro foo_impl - ^ -Macros_2.scala:7: error: not found: value macro - def bar(x: Int): Int = macro bar_impl - ^ -Macros_2.scala:11: error: not found: value macro - def quux(x: Int): Int = macro quux_impl - ^ -three errors found diff --git a/test/files/neg/macro-without-xmacros-a/Impls_1.scala b/test/files/neg/macro-without-xmacros-a/Impls_1.scala deleted file mode 100644 index 2493c81c95..0000000000 --- a/test/files/neg/macro-without-xmacros-a/Impls_1.scala +++ /dev/null @@ -1,18 +0,0 @@ -import scala.reflect.makro.{Context => Ctx} - -object Impls { - def foo_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) - } - - def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) - } - - def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) - } -} diff --git a/test/files/neg/macro-without-xmacros-a/Macros_2.scala b/test/files/neg/macro-without-xmacros-a/Macros_2.scala deleted file mode 100644 index 62f9dcf505..0000000000 --- a/test/files/neg/macro-without-xmacros-a/Macros_2.scala +++ /dev/null @@ -1,12 +0,0 @@ -import Impls._ - -object Macros { - object Shmacros { - def foo(x: Int): Int = macro foo_impl - } - def bar(x: Int): Int = macro bar_impl -} - -class Macros { - def quux(x: Int): Int = macro quux_impl -} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-a/Test_3.scala b/test/files/neg/macro-without-xmacros-a/Test_3.scala deleted file mode 100644 index e9a10e20c9..0000000000 --- a/test/files/neg/macro-without-xmacros-a/Test_3.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros.Shmacros._ - println(foo(2) + Macros.bar(2) * new Macros().quux(4)) -} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-b.check b/test/files/neg/macro-without-xmacros-b.check deleted file mode 100644 index dce4a084c9..0000000000 --- a/test/files/neg/macro-without-xmacros-b.check +++ /dev/null @@ -1,10 +0,0 @@ -Macros_2.scala:3: error: ';' expected but '.' found. - def foo(x: Int): Int = macro Impls.foo_impl - ^ -Macros_2.scala:5: error: ';' expected but '.' found. - def bar(x: Int): Int = macro Impls.bar_impl - ^ -Macros_2.scala:9: error: ';' expected but '.' found. - def quux(x: Int): Int = macro Impls.quux_impl - ^ -three errors found diff --git a/test/files/neg/macro-without-xmacros-b/Impls_1.scala b/test/files/neg/macro-without-xmacros-b/Impls_1.scala deleted file mode 100644 index 2493c81c95..0000000000 --- a/test/files/neg/macro-without-xmacros-b/Impls_1.scala +++ /dev/null @@ -1,18 +0,0 @@ -import scala.reflect.makro.{Context => Ctx} - -object Impls { - def foo_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) - } - - def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) - } - - def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) - } -} diff --git a/test/files/neg/macro-without-xmacros-b/Macros_2.scala b/test/files/neg/macro-without-xmacros-b/Macros_2.scala deleted file mode 100644 index de7080c7e8..0000000000 --- a/test/files/neg/macro-without-xmacros-b/Macros_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Macros { - object Shmacros { - def foo(x: Int): Int = macro Impls.foo_impl - } - def bar(x: Int): Int = macro Impls.bar_impl -} - -class Macros { - def quux(x: Int): Int = macro Impls.quux_impl -} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-b/Test_3.scala b/test/files/neg/macro-without-xmacros-b/Test_3.scala deleted file mode 100644 index e9a10e20c9..0000000000 --- a/test/files/neg/macro-without-xmacros-b/Test_3.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros.Shmacros._ - println(foo(2) + Macros.bar(2) * new Macros().quux(4)) -} \ No newline at end of file -- cgit v1.2.3 From f67a00a3cef270835369b8ab1bb57cbe8b2bd2a3 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Fri, 13 Apr 2012 20:18:41 -0400 Subject: change com.typesafe.config dep to version 0.4.0 --- build.xml | 2 +- src/build/maven/scala-library-pom.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.xml b/build.xml index 1a0e85a6f0..d2438e3112 100644 --- a/build.xml +++ b/build.xml @@ -249,7 +249,7 @@ INITIALISATION - + diff --git a/src/build/maven/scala-library-pom.xml b/src/build/maven/scala-library-pom.xml index c3f8a4531c..e8db512125 100644 --- a/src/build/maven/scala-library-pom.xml +++ b/src/build/maven/scala-library-pom.xml @@ -32,9 +32,9 @@ - org.skife.com.typesafe.config - typesafe-config - 0.3.0 + com.typesafe + config + 0.4.0 -- cgit v1.2.3 From c26f2ae86bb8ecdfc07787c1ad66350c6cb8b36b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 13 Apr 2012 17:36:49 -0700 Subject: disabled failing macro test; needs to be adapted to new scheme. --- test/disabled/run/macro-reflective-mamd-normal-mi.check | 0 test/disabled/run/macro-reflective-mamd-normal-mi.flags | 0 .../run/macro-reflective-mamd-normal-mi/Impls_1.scala | 9 +++++++++ .../macro-reflective-mamd-normal-mi/Macros_Test_2.scala | 16 ++++++++++++++++ test/files/run/macro-reflective-mamd-normal-mi.check | 0 test/files/run/macro-reflective-mamd-normal-mi.flags | 0 .../run/macro-reflective-mamd-normal-mi/Impls_1.scala | 9 --------- .../macro-reflective-mamd-normal-mi/Macros_Test_2.scala | 16 ---------------- 8 files changed, 25 insertions(+), 25 deletions(-) create mode 100644 test/disabled/run/macro-reflective-mamd-normal-mi.check create mode 100644 test/disabled/run/macro-reflective-mamd-normal-mi.flags create mode 100644 test/disabled/run/macro-reflective-mamd-normal-mi/Impls_1.scala create mode 100644 test/disabled/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala delete mode 100644 test/files/run/macro-reflective-mamd-normal-mi.check delete mode 100644 test/files/run/macro-reflective-mamd-normal-mi.flags delete mode 100644 test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala delete mode 100644 test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala diff --git a/test/disabled/run/macro-reflective-mamd-normal-mi.check b/test/disabled/run/macro-reflective-mamd-normal-mi.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/disabled/run/macro-reflective-mamd-normal-mi.flags b/test/disabled/run/macro-reflective-mamd-normal-mi.flags new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/disabled/run/macro-reflective-mamd-normal-mi/Impls_1.scala b/test/disabled/run/macro-reflective-mamd-normal-mi/Impls_1.scala new file mode 100644 index 0000000000..dc7d42d23e --- /dev/null +++ b/test/disabled/run/macro-reflective-mamd-normal-mi/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } +} diff --git a/test/disabled/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala b/test/disabled/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala new file mode 100644 index 0000000000..7cbe425fc8 --- /dev/null +++ b/test/disabled/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala @@ -0,0 +1,16 @@ +//object Macros { +// def foo(x: Int) = macro Impls.foo +//} + +object Test extends App { + import scala.reflect.mirror._ + + val macrobody = Select(Ident(newTermName("Impls")), newTermName("foo")) + val macroparam = ValDef(NoMods, newTermName("x"), TypeTree(definitions.IntClass.asType), EmptyTree) + val macrodef = DefDef(Modifiers(Set(scala.reflect.api.Modifier.`macro`)), newTermName("foo"), Nil, List(List(macroparam)), TypeTree(), macrobody) + val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(Apply(Select(Super(This(EmptyTypeName), EmptyTypeName), nme.CONSTRUCTOR), List()))) + val module = ModuleDef(NoMods, newTermName("Macros"), Template(Nil, emptyValDef, List(modulector, macrodef))) + val macroapp = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + val tree = Block(macrodef, module, macroapp) + println(tree.eval) +} diff --git a/test/files/run/macro-reflective-mamd-normal-mi.check b/test/files/run/macro-reflective-mamd-normal-mi.check deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/files/run/macro-reflective-mamd-normal-mi.flags b/test/files/run/macro-reflective-mamd-normal-mi.flags deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala b/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala deleted file mode 100644 index dc7d42d23e..0000000000 --- a/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.makro.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Int]) = { - import c.mirror._ - val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) - Expr[Int](body) - } -} diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala deleted file mode 100644 index 7cbe425fc8..0000000000 --- a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala +++ /dev/null @@ -1,16 +0,0 @@ -//object Macros { -// def foo(x: Int) = macro Impls.foo -//} - -object Test extends App { - import scala.reflect.mirror._ - - val macrobody = Select(Ident(newTermName("Impls")), newTermName("foo")) - val macroparam = ValDef(NoMods, newTermName("x"), TypeTree(definitions.IntClass.asType), EmptyTree) - val macrodef = DefDef(Modifiers(Set(scala.reflect.api.Modifier.`macro`)), newTermName("foo"), Nil, List(List(macroparam)), TypeTree(), macrobody) - val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(Apply(Select(Super(This(EmptyTypeName), EmptyTypeName), nme.CONSTRUCTOR), List()))) - val module = ModuleDef(NoMods, newTermName("Macros"), Template(Nil, emptyValDef, List(modulector, macrodef))) - val macroapp = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) - val tree = Block(macrodef, module, macroapp) - println(tree.eval) -} -- cgit v1.2.3 From 66f75183c0614681c61eaa4f3af005be040ddd11 Mon Sep 17 00:00:00 2001 From: Christopher Vogt Date: Sat, 14 Apr 2012 02:43:10 +0200 Subject: DynamicProxy: improved docs, fixed EOL style --- src/library/scala/reflect/DynamicProxy.scala | 141 +++++++++++++------------- test/files/run/dynamic-proxy.check | 40 ++++---- test/files/run/dynamic-proxy.flags | 2 +- test/files/run/dynamic-proxy.scala | 144 +++++++++++++-------------- 4 files changed, 167 insertions(+), 160 deletions(-) diff --git a/src/library/scala/reflect/DynamicProxy.scala b/src/library/scala/reflect/DynamicProxy.scala index 8449cb4063..ffd1e7a39f 100644 --- a/src/library/scala/reflect/DynamicProxy.scala +++ b/src/library/scala/reflect/DynamicProxy.scala @@ -1,67 +1,74 @@ -package scala.reflect -/** - * A dynamic proxy which redirect method calls and attribute access to a given - * target object at runtime using reflection. - * A usage example can be found in test/files/run/dynamic-reflect.scala - * Not supported (yet): - * - implicit conversions and parameters - * - multiple arguments lists - * - explicit type arguments - */ -trait DynamicProxy extends Dynamic{ - val dynamicProxyTarget : AnyRef - - import scala.reflect.mirror._ - /** - * boxing to preserve information on primitive types for overloading resolution - */ - case class DynamicReflectBoxed( class_ : Class[_], value: Any ) - object DynamicReflectBoxed{ - implicit def box[@specialized T]( v:T ) = DynamicReflectBoxed( v.getClass, v ) - } - - def selectDynamic( method:String ) = { - val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName ) - invoke( dynamicProxyTarget, symbol )() - } - - def updateDynamic( method:String )( value : Any ) = { - val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method+"_=").encodedName ) - invoke( dynamicProxyTarget, symbol )( value ) - } - - def applyDynamic( method:String )( args:DynamicReflectBoxed* ) : Any - = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* ) - - def applyDynamicNamed( method:String )( args:(String,DynamicReflectBoxed)* ) : Any = { - val class_ = dynamicProxyTarget.getClass - var i = 0 - val toolbox = mkToolBox(mkConsoleReporter(),"") - val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName ) - if(args.size == 0){ - invoke( dynamicProxyTarget, symbol )() - } else { - val call = - Apply( - Select( - TypeApply( - Select( - Select( - Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this, null)) - , newTermName("dynamicProxyTarget") - ), - newTermName("asInstanceOf") ) - , List(TypeTree().setType(classToType(class_))) - ) - ,newTermName(method).encodedName - ) - ,args.map{ case(name,box) => - val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value, null)) - if( name == "" ) value - else AssignOrNamedArg( Ident(name), value ) - }.toList - ) - toolbox.runExpr( call ) - } - } -} +package scala.reflect +/** + * A dynamic proxy which redirects method calls and attribute access to a given + * target object at runtime using reflection. + * + * Usage example: + * + * object x{ def hello = "hello world" } + * val d = new DynamicProxy{ val dynamicProxyTarget = x } + * assert( d.hello == "hello world" ) + * + * Not supported (yet): + * - implicit conversions and parameters + * - multiple arguments lists + * - explicit type arguments + */ +trait DynamicProxy extends Dynamic{ + /** Method calls on DynamicProxy are redirected to this object. Needs to be defined in a subclass. */ + val dynamicProxyTarget : AnyRef + + import scala.reflect.mirror._ + /** + * boxing to preserve information on primitive types for overloading resolution + */ + case class DynamicReflectBoxed( class_ : Class[_], value: Any ) + object DynamicReflectBoxed{ + implicit def box[@specialized T]( v:T ) = DynamicReflectBoxed( v.getClass, v ) + } + + def selectDynamic( method:String ) = { + val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName ) + invoke( dynamicProxyTarget, symbol )() + } + + def updateDynamic( method:String )( value : Any ) = { + val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method+"_=").encodedName ) + invoke( dynamicProxyTarget, symbol )( value ) + } + + def applyDynamic( method:String )( args:DynamicReflectBoxed* ) : Any + = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* ) + + def applyDynamicNamed( method:String )( args:(String,DynamicReflectBoxed)* ) : Any = { + val class_ = dynamicProxyTarget.getClass + var i = 0 + val toolbox = mkToolBox(mkConsoleReporter(),"") + val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName ) + if(args.size == 0){ + invoke( dynamicProxyTarget, symbol )() + } else { + val call = + Apply( + Select( + TypeApply( + Select( + Select( + Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this, null)) + , newTermName("dynamicProxyTarget") + ), + newTermName("asInstanceOf") ) + , List(TypeTree().setType(classToType(class_))) + ) + ,newTermName(method).encodedName + ) + ,args.map{ case(name,box) => + val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value, null)) + if( name == "" ) value + else AssignOrNamedArg( Ident(name), value ) + }.toList + ) + toolbox.runExpr( call ) + } + } +} diff --git a/test/files/run/dynamic-proxy.check b/test/files/run/dynamic-proxy.check index 83c386812d..d1b85daff4 100644 --- a/test/files/run/dynamic-proxy.check +++ b/test/files/run/dynamic-proxy.check @@ -1,20 +1,20 @@ -noargs -noargs -nullary -value -symbolic -symbolic with args -non-existent method -before mutation -mutation 1 -after mutation 1 -mutation 2 -after mutation 2 -overloaded with object -overloaded with primitive -overloaded with object in var -overloaded with object in var 2 -typeArgs: I am a car -default: 4 -default: 3 -named: 6 +noargs +noargs +nullary +value +symbolic +symbolic with args +non-existent method +before mutation +mutation 1 +after mutation 1 +mutation 2 +after mutation 2 +overloaded with object +overloaded with primitive +overloaded with object in var +overloaded with object in var 2 +typeArgs: I am a car +default: 4 +default: 3 +named: 6 diff --git a/test/files/run/dynamic-proxy.flags b/test/files/run/dynamic-proxy.flags index 68ecfa03f8..48fd867160 100644 --- a/test/files/run/dynamic-proxy.flags +++ b/test/files/run/dynamic-proxy.flags @@ -1 +1 @@ --Xexperimental +-Xexperimental diff --git a/test/files/run/dynamic-proxy.scala b/test/files/run/dynamic-proxy.scala index 194da2d092..ab5a8b1d66 100644 --- a/test/files/run/dynamic-proxy.scala +++ b/test/files/run/dynamic-proxy.scala @@ -1,72 +1,72 @@ -import scala.reflect._ - -class Car{ override def toString = "I am a car" } -object x{ - def nullary = "nullary" - def noargs() = "noargs" - def - = "symbolic" - def $(s:String) = "symbolic with args" - val value = "value" - def overloaded(i:Int) = "overloaded with primitive" - def overloaded(s:String) = s - def default( a:Int, b:Int = 2 ) = "default: "+(a+b) - def named( a:Int, b:Int, c:Int ) = "named: "+(a+b+c) - def typeArgs[T]( v:T ) = "typeArgs: "+v - var mutable = "before mutation" - def multiArgLists( a:String )( b:String ) = "multiArgList " + a + b - def bar( s:String )(implicit car:Car) = s + car.toString -} - -object Test extends App{ - val d = new DynamicProxy{ val dynamicProxyTarget = x } - - println( d.noargs ) - println( d.noargs() ) - println( d.nullary ) - println( d.value ) - println( d.- ) - println( d.$("x") ) - - try{ - println( d.test ) - } catch { - case _ => println("non-existent method") - } - - println( d.mutable ) - - println("mutation 1") - d.mutable_=("after mutation 1") - println( d.mutable ) - - println("mutation 2") - d.mutable = "after mutation 2" - println( d.mutable ) - - println( d.overloaded("overloaded with object") ) - println( d.overloaded(1) ) - - // test some non-constant arguments - def s = "overloaded with object in var" - println( d.overloaded(s) ) - println( d.overloaded(s + " 2") ) - - val car = new Car - println( d.typeArgs(car) ) // inferred - // println( d.typeArgs[Car](car) ) // explicit not working (yet) - - println( d.default( 1,3 ) ) - println( d.default( 1 ) ) - - println( d.named(1,c=3,b=2) ) // applyDynamicNamed seems to be broken - - // println( d.multiArgLists("a")("b") ) // not working yet - - /* - // may never work - // testing implicit parameters (first test works when moving x into TestDynamicReflect) - implicit val car2 = new Car - println( d.bar( "Yeah, ") ); // FAILS: could not find implicit value for parameter car - {println( d.bar( "Yeah, ") )} // FAILS: could not find implicit value for parameter car - */ -} +import scala.reflect._ + +class Car{ override def toString = "I am a car" } +object x{ + def nullary = "nullary" + def noargs() = "noargs" + def - = "symbolic" + def $(s:String) = "symbolic with args" + val value = "value" + def overloaded(i:Int) = "overloaded with primitive" + def overloaded(s:String) = s + def default( a:Int, b:Int = 2 ) = "default: "+(a+b) + def named( a:Int, b:Int, c:Int ) = "named: "+(a+b+c) + def typeArgs[T]( v:T ) = "typeArgs: "+v + var mutable = "before mutation" + def multiArgLists( a:String )( b:String ) = "multiArgList " + a + b + def bar( s:String )(implicit car:Car) = s + car.toString +} + +object Test extends App{ + val d = new DynamicProxy{ val dynamicProxyTarget = x } + + println( d.noargs ) + println( d.noargs() ) + println( d.nullary ) + println( d.value ) + println( d.- ) + println( d.$("x") ) + + try{ + println( d.test ) + } catch { + case _ => println("non-existent method") + } + + println( d.mutable ) + + println("mutation 1") + d.mutable_=("after mutation 1") + println( d.mutable ) + + println("mutation 2") + d.mutable = "after mutation 2" + println( d.mutable ) + + println( d.overloaded("overloaded with object") ) + println( d.overloaded(1) ) + + // test some non-constant arguments + def s = "overloaded with object in var" + println( d.overloaded(s) ) + println( d.overloaded(s + " 2") ) + + val car = new Car + println( d.typeArgs(car) ) // inferred + // println( d.typeArgs[Car](car) ) // explicit not working (yet) + + println( d.default( 1,3 ) ) + println( d.default( 1 ) ) + + println( d.named(1,c=3,b=2) ) // applyDynamicNamed seems to be broken + + // println( d.multiArgLists("a")("b") ) // not working yet + + /* + // may never work + // testing implicit parameters (first test works when moving x into TestDynamicReflect) + implicit val car2 = new Car + println( d.bar( "Yeah, ") ); // FAILS: could not find implicit value for parameter car + {println( d.bar( "Yeah, ") )} // FAILS: could not find implicit value for parameter car + */ +} -- cgit v1.2.3 From b2991c6676fdf024eb53bbaeeedf86f315523798 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 13 Apr 2012 19:15:13 -0700 Subject: one more macro test sdisabled that lipped through the net before. --- test/disabled/neg/macro-deprecate-idents.check | 46 +++++++++++++++++++++ test/disabled/neg/macro-deprecate-idents.flags | 1 + test/disabled/neg/macro-deprecate-idents.scala | 56 ++++++++++++++++++++++++++ test/files/neg/macro-deprecate-idents.check | 46 --------------------- test/files/neg/macro-deprecate-idents.flags | 1 - test/files/neg/macro-deprecate-idents.scala | 56 -------------------------- 6 files changed, 103 insertions(+), 103 deletions(-) create mode 100644 test/disabled/neg/macro-deprecate-idents.check create mode 100644 test/disabled/neg/macro-deprecate-idents.flags create mode 100644 test/disabled/neg/macro-deprecate-idents.scala delete mode 100644 test/files/neg/macro-deprecate-idents.check delete mode 100644 test/files/neg/macro-deprecate-idents.flags delete mode 100644 test/files/neg/macro-deprecate-idents.scala diff --git a/test/disabled/neg/macro-deprecate-idents.check b/test/disabled/neg/macro-deprecate-idents.check new file mode 100644 index 0000000000..bd685fc7b9 --- /dev/null +++ b/test/disabled/neg/macro-deprecate-idents.check @@ -0,0 +1,46 @@ +macro-deprecate-idents.scala:2: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + val macro = ??? + ^ +macro-deprecate-idents.scala:6: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + var macro = ??? + ^ +macro-deprecate-idents.scala:10: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + type macro = Int + ^ +macro-deprecate-idents.scala:14: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + class macro + ^ +macro-deprecate-idents.scala:18: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + class macro + ^ +macro-deprecate-idents.scala:22: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + object macro + ^ +macro-deprecate-idents.scala:26: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + object macro + ^ +macro-deprecate-idents.scala:30: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + trait macro + ^ +macro-deprecate-idents.scala:34: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + trait macro + ^ +macro-deprecate-idents.scala:37: error: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro { + ^ +macro-deprecate-idents.scala:38: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + package macro.bar { + ^ +macro-deprecate-idents.scala:43: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + package macro.foo { + ^ +macro-deprecate-idents.scala:48: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + val Some(macro) = Some(42) + ^ +macro-deprecate-idents.scala:50: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + case macro => println(macro) + ^ +macro-deprecate-idents.scala:55: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + def macro = 2 + ^ +15 errors found diff --git a/test/disabled/neg/macro-deprecate-idents.flags b/test/disabled/neg/macro-deprecate-idents.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/disabled/neg/macro-deprecate-idents.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/disabled/neg/macro-deprecate-idents.scala b/test/disabled/neg/macro-deprecate-idents.scala new file mode 100644 index 0000000000..23c398e341 --- /dev/null +++ b/test/disabled/neg/macro-deprecate-idents.scala @@ -0,0 +1,56 @@ +object Test1 { + val macro = ??? +} + +object Test2 { + var macro = ??? +} + +object Test3 { + type macro = Int +} + +package test4 { + class macro +} + +object Test5 { + class macro +} + +package test6 { + object macro +} + +object Test7 { + object macro +} + +package test8 { + trait macro +} + +object Test9 { + trait macro +} + +package macro { + package macro.bar { + } +} + +package foo { + package macro.foo { + } +} + +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} + +object Test13 { + def macro = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents.check b/test/files/neg/macro-deprecate-idents.check deleted file mode 100644 index bd685fc7b9..0000000000 --- a/test/files/neg/macro-deprecate-idents.check +++ /dev/null @@ -1,46 +0,0 @@ -macro-deprecate-idents.scala:2: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - val macro = ??? - ^ -macro-deprecate-idents.scala:6: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - var macro = ??? - ^ -macro-deprecate-idents.scala:10: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - type macro = Int - ^ -macro-deprecate-idents.scala:14: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - class macro - ^ -macro-deprecate-idents.scala:18: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - class macro - ^ -macro-deprecate-idents.scala:22: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - object macro - ^ -macro-deprecate-idents.scala:26: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - object macro - ^ -macro-deprecate-idents.scala:30: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - trait macro - ^ -macro-deprecate-idents.scala:34: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - trait macro - ^ -macro-deprecate-idents.scala:37: error: in future versions of Scala "macro" will be a keyword. consider using a different name. -package macro { - ^ -macro-deprecate-idents.scala:38: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - package macro.bar { - ^ -macro-deprecate-idents.scala:43: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - package macro.foo { - ^ -macro-deprecate-idents.scala:48: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - val Some(macro) = Some(42) - ^ -macro-deprecate-idents.scala:50: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - case macro => println(macro) - ^ -macro-deprecate-idents.scala:55: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - def macro = 2 - ^ -15 errors found diff --git a/test/files/neg/macro-deprecate-idents.flags b/test/files/neg/macro-deprecate-idents.flags deleted file mode 100644 index e8fb65d50c..0000000000 --- a/test/files/neg/macro-deprecate-idents.flags +++ /dev/null @@ -1 +0,0 @@ --Xfatal-warnings \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents.scala b/test/files/neg/macro-deprecate-idents.scala deleted file mode 100644 index 23c398e341..0000000000 --- a/test/files/neg/macro-deprecate-idents.scala +++ /dev/null @@ -1,56 +0,0 @@ -object Test1 { - val macro = ??? -} - -object Test2 { - var macro = ??? -} - -object Test3 { - type macro = Int -} - -package test4 { - class macro -} - -object Test5 { - class macro -} - -package test6 { - object macro -} - -object Test7 { - object macro -} - -package test8 { - trait macro -} - -object Test9 { - trait macro -} - -package macro { - package macro.bar { - } -} - -package foo { - package macro.foo { - } -} - -object Test12 { - val Some(macro) = Some(42) - macro match { - case macro => println(macro) - } -} - -object Test13 { - def macro = 2 -} \ No newline at end of file -- cgit v1.2.3 From e638405d4c89c22f9fd72bc63806c7ff57c30e41 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 13 Apr 2012 20:52:29 -0700 Subject: disabling scaladoc tests. Don't know how to fix them to make them work under SIP 18. --- test/disabled/run/implicits-base.check | 1 + test/disabled/run/implicits-base.scala | 180 ++++++++++++++++++++++++++ test/disabled/run/implicits-chaining.check | 1 + test/disabled/run/implicits-chaining.scala | 65 ++++++++++ test/disabled/run/implicits-elimination.check | 1 + test/disabled/run/implicits-elimination.scala | 23 ++++ test/disabled/run/implicits-scopes.check | 1 + test/disabled/run/implicits-scopes.scala | 77 +++++++++++ test/scaladoc/run/implicits-base.check | 1 - test/scaladoc/run/implicits-base.scala | 179 ------------------------- test/scaladoc/run/implicits-chaining.check | 1 - test/scaladoc/run/implicits-chaining.scala | 64 --------- test/scaladoc/run/implicits-elimination.check | 1 - test/scaladoc/run/implicits-elimination.scala | 22 ---- test/scaladoc/run/implicits-scopes.check | 1 - test/scaladoc/run/implicits-scopes.scala | 76 ----------- 16 files changed, 349 insertions(+), 345 deletions(-) create mode 100644 test/disabled/run/implicits-base.check create mode 100644 test/disabled/run/implicits-base.scala create mode 100644 test/disabled/run/implicits-chaining.check create mode 100644 test/disabled/run/implicits-chaining.scala create mode 100644 test/disabled/run/implicits-elimination.check create mode 100644 test/disabled/run/implicits-elimination.scala create mode 100644 test/disabled/run/implicits-scopes.check create mode 100644 test/disabled/run/implicits-scopes.scala delete mode 100644 test/scaladoc/run/implicits-base.check delete mode 100644 test/scaladoc/run/implicits-base.scala delete mode 100644 test/scaladoc/run/implicits-chaining.check delete mode 100644 test/scaladoc/run/implicits-chaining.scala delete mode 100644 test/scaladoc/run/implicits-elimination.check delete mode 100644 test/scaladoc/run/implicits-elimination.scala delete mode 100644 test/scaladoc/run/implicits-scopes.check delete mode 100644 test/scaladoc/run/implicits-scopes.scala diff --git a/test/disabled/run/implicits-base.check b/test/disabled/run/implicits-base.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/disabled/run/implicits-base.check @@ -0,0 +1 @@ +Done. diff --git a/test/disabled/run/implicits-base.scala b/test/disabled/run/implicits-base.scala new file mode 100644 index 0000000000..06d017ed70 --- /dev/null +++ b/test/disabled/run/implicits-base.scala @@ -0,0 +1,180 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest +import language._ + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-base-res.scala" + + // start implicits + def scaladocSettings = "-implicits -implicits-show-all" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // SEE THE test/resources/implicits-base-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("base") + var conv: ImplicitConversion = null + +//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val A = base._class("A") + + // the method pimped on by pimpA0 should be shadowed by the method in class A + assert(A._conversions(A.qualifiedName + ".pimpA0").isEmpty) + + // def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope + conv = A._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToNumericA").resultType.name == "T") + + // def convToIntA: Int // pimpA2: with a constraint that T = Int + conv = A._conversion(A.qualifiedName + ".pimpA2") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToIntA").resultType.name == "Int") + + // def convToGtColonDoubleA: Double // pimpA3: with a constraint that T <: Double + conv = A._conversion(A.qualifiedName + ".pimpA3") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") + + // def convToPimpedA: S // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar + conv = A._conversion(A.qualifiedName + ".pimpA4") + assert(conv.members.length == 1) + assert(conv.constraints.length == 3) + assert(conv._member("convToPimpedA").resultType.name == "S") + + // def convToPimpedA: Bar[Foo[T]] // pimpA5: no constraints + conv = A._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[T]]") + + // def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope + conv = A._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "T") + + // def convToManifestA: T // pimpA7: with 2 constraints: T: Manifest and T <: Double + // def convToTraversableOps: T // pimpA7: with 2 constraints: T: Manifest and T <: Double + // should not be abstract! + conv = A._conversion(A.qualifiedName + ".pimpA7") + assert(conv.members.length == 2) + assert(conv.constraints.length == 2) + assert(conv._member("convToManifestA").resultType.name == "T") + assert(conv._member("convToTraversableOps").resultType.name == "T") + assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1) + +//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val B = base._class("B") + + // these conversions should not affect B + assert(B._conversions(A.qualifiedName + ".pimpA0").isEmpty) + assert(B._conversions(A.qualifiedName + ".pimpA2").isEmpty) + assert(B._conversions(A.qualifiedName + ".pimpA4").isEmpty) + + // def convToNumericA: Double // pimpA1: no constraintsd + conv = B._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToNumericA").resultType.name == "Double") + + // def convToGtColonDoubleA: Double // pimpA3: no constraints + conv = B._conversion(A.qualifiedName + ".pimpA3") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") + + // def convToPimpedA: Bar[Foo[Double]] // pimpA5: no constraints + conv = B._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Double]]") + + // def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope + conv = B._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "Double") + + // def convToManifestA: Double // pimpA7: no constraints + // def convToTraversableOps: Double // pimpA7: no constraints + // // should not be abstract! + conv = B._conversion(A.qualifiedName + ".pimpA7") + assert(conv.members.length == 2) + assert(conv.constraints.length == 0) + assert(conv._member("convToManifestA").resultType.name == "Double") + assert(conv._member("convToTraversableOps").resultType.name == "Double") + assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1) + +//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val C = base._class("C") + + // these conversions should not affect C + assert(C._conversions(A.qualifiedName + ".pimpA0").isEmpty) + assert(C._conversions(A.qualifiedName + ".pimpA3").isEmpty) + assert(C._conversions(A.qualifiedName + ".pimpA4").isEmpty) + assert(C._conversions(A.qualifiedName + ".pimpA7").isEmpty) + + // def convToNumericA: Int // pimpA1: no constraints + conv = C._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToNumericA").resultType.name == "Int") + + // def convToIntA: Int // pimpA2: no constraints + conv = C._conversion(A.qualifiedName + ".pimpA2") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToIntA").resultType.name == "Int") + + // def convToPimpedA: Bar[Foo[Int]] // pimpA5: no constraints + conv = C._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Int]]") + + // def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope + conv = C._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "Int") + +//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val D = base._class("D") + + // these conversions should not affect D + assert(D._conversions(A.qualifiedName + ".pimpA0").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA2").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA3").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA4").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA7").isEmpty) + + // def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope + conv = D._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToNumericA").resultType.name == "String") + + // def convToPimpedA: Bar[Foo[String]] // pimpA5: no constraints + conv = D._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[String]]") + + // def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope + conv = D._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "String") + } +} diff --git a/test/disabled/run/implicits-chaining.check b/test/disabled/run/implicits-chaining.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/disabled/run/implicits-chaining.check @@ -0,0 +1 @@ +Done. diff --git a/test/disabled/run/implicits-chaining.scala b/test/disabled/run/implicits-chaining.scala new file mode 100644 index 0000000000..858ca9ce61 --- /dev/null +++ b/test/disabled/run/implicits-chaining.scala @@ -0,0 +1,65 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest +import language._ + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-chaining-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("chaining") + var conv: ImplicitConversion = null + +//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val A = base._class("A") + + conv = A._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + +//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val B = base._class("B") + + conv = B._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + +//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val C = base._class("C") + + assert(C._conversions(base.qualifiedName + ".convertToZ").isEmpty) + +//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val D = base._class("D") + + conv = D._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + +//// class E /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val E = base._class("E") + + conv = E._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + +//// class F /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val F = base._class("F") + + assert(F._conversions(base.qualifiedName + ".convertToZ").isEmpty) + } +} diff --git a/test/disabled/run/implicits-elimination.check b/test/disabled/run/implicits-elimination.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/disabled/run/implicits-elimination.check @@ -0,0 +1 @@ +Done. diff --git a/test/disabled/run/implicits-elimination.scala b/test/disabled/run/implicits-elimination.scala new file mode 100644 index 0000000000..ed37b9cd90 --- /dev/null +++ b/test/disabled/run/implicits-elimination.scala @@ -0,0 +1,23 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest +import language._ + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-elimination-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // SEE THE test/resources/implicits-elimination-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("elimination") + val A = base._class("A") + + assert(A._conversions(A.qualifiedName + ".toB").isEmpty) + } +} diff --git a/test/disabled/run/implicits-scopes.check b/test/disabled/run/implicits-scopes.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/disabled/run/implicits-scopes.check @@ -0,0 +1 @@ +Done. diff --git a/test/disabled/run/implicits-scopes.scala b/test/disabled/run/implicits-scopes.scala new file mode 100644 index 0000000000..7b9e80e148 --- /dev/null +++ b/test/disabled/run/implicits-scopes.scala @@ -0,0 +1,77 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest +import language._ + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-scopes-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + var conv: ImplicitConversion = null + + // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("scopes") + +//// test1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest1 = { + val test1 = base._package("test1") + val A = test1._class("A") + + conv = A._conversion(test1.qualifiedName + ".package.toB") // the .package means it's the package object + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + +//// test2 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest2 = { + val test2 = base._package("test2") + val classes = test2._package("classes") + val A = classes._class("A") + + assert(A._conversions(test2.qualifiedName + ".toB").isEmpty) + } + +//// test3 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest3 = { + val test3 = base._package("test3") + val A = test3._class("A") + + conv = A._conversion(A.qualifiedName + ".toB") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + +//// test4 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest4 = { + val test4 = base._package("test4") + val A = test4._class("A") + val S = test4._object("S") + + conv = A._conversion(S.qualifiedName + ".toB") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + +//// test5 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest5 = { + val test5 = base._package("test5") + val scope = test5._object("scope") + val A = scope._class("A") + + conv = A._conversion(scope.qualifiedName + ".toB") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + } +} diff --git a/test/scaladoc/run/implicits-base.check b/test/scaladoc/run/implicits-base.check deleted file mode 100644 index 619c56180b..0000000000 --- a/test/scaladoc/run/implicits-base.check +++ /dev/null @@ -1 +0,0 @@ -Done. diff --git a/test/scaladoc/run/implicits-base.scala b/test/scaladoc/run/implicits-base.scala deleted file mode 100644 index a0dd2071d7..0000000000 --- a/test/scaladoc/run/implicits-base.scala +++ /dev/null @@ -1,179 +0,0 @@ -import scala.tools.nsc.doc.model._ -import scala.tools.partest.ScaladocModelTest - -object Test extends ScaladocModelTest { - - // test a file instead of a piece of code - override def resourceFile = "implicits-base-res.scala" - - // start implicits - def scaladocSettings = "-implicits -implicits-show-all" - - def testModel(root: Package) = { - // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) - import access._ - - // SEE THE test/resources/implicits-base-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: - val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("base") - var conv: ImplicitConversion = null - -//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val A = base._class("A") - - // the method pimped on by pimpA0 should be shadowed by the method in class A - assert(A._conversions(A.qualifiedName + ".pimpA0").isEmpty) - - // def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope - conv = A._conversion(A.qualifiedName + ".pimpA1") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToNumericA").resultType.name == "T") - - // def convToIntA: Int // pimpA2: with a constraint that T = Int - conv = A._conversion(A.qualifiedName + ".pimpA2") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToIntA").resultType.name == "Int") - - // def convToGtColonDoubleA: Double // pimpA3: with a constraint that T <: Double - conv = A._conversion(A.qualifiedName + ".pimpA3") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") - - // def convToPimpedA: S // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar - conv = A._conversion(A.qualifiedName + ".pimpA4") - assert(conv.members.length == 1) - assert(conv.constraints.length == 3) - assert(conv._member("convToPimpedA").resultType.name == "S") - - // def convToPimpedA: Bar[Foo[T]] // pimpA5: no constraints - conv = A._conversion(A.qualifiedName + ".pimpA5") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[T]]") - - // def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope - conv = A._conversion(A.qualifiedName + ".pimpA6") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToMyNumericA").resultType.name == "T") - - // def convToManifestA: T // pimpA7: with 2 constraints: T: Manifest and T <: Double - // def convToTraversableOps: T // pimpA7: with 2 constraints: T: Manifest and T <: Double - // should not be abstract! - conv = A._conversion(A.qualifiedName + ".pimpA7") - assert(conv.members.length == 2) - assert(conv.constraints.length == 2) - assert(conv._member("convToManifestA").resultType.name == "T") - assert(conv._member("convToTraversableOps").resultType.name == "T") - assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1) - -//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val B = base._class("B") - - // these conversions should not affect B - assert(B._conversions(A.qualifiedName + ".pimpA0").isEmpty) - assert(B._conversions(A.qualifiedName + ".pimpA2").isEmpty) - assert(B._conversions(A.qualifiedName + ".pimpA4").isEmpty) - - // def convToNumericA: Double // pimpA1: no constraintsd - conv = B._conversion(A.qualifiedName + ".pimpA1") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToNumericA").resultType.name == "Double") - - // def convToGtColonDoubleA: Double // pimpA3: no constraints - conv = B._conversion(A.qualifiedName + ".pimpA3") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") - - // def convToPimpedA: Bar[Foo[Double]] // pimpA5: no constraints - conv = B._conversion(A.qualifiedName + ".pimpA5") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Double]]") - - // def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope - conv = B._conversion(A.qualifiedName + ".pimpA6") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToMyNumericA").resultType.name == "Double") - - // def convToManifestA: Double // pimpA7: no constraints - // def convToTraversableOps: Double // pimpA7: no constraints - // // should not be abstract! - conv = B._conversion(A.qualifiedName + ".pimpA7") - assert(conv.members.length == 2) - assert(conv.constraints.length == 0) - assert(conv._member("convToManifestA").resultType.name == "Double") - assert(conv._member("convToTraversableOps").resultType.name == "Double") - assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1) - -//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val C = base._class("C") - - // these conversions should not affect C - assert(C._conversions(A.qualifiedName + ".pimpA0").isEmpty) - assert(C._conversions(A.qualifiedName + ".pimpA3").isEmpty) - assert(C._conversions(A.qualifiedName + ".pimpA4").isEmpty) - assert(C._conversions(A.qualifiedName + ".pimpA7").isEmpty) - - // def convToNumericA: Int // pimpA1: no constraints - conv = C._conversion(A.qualifiedName + ".pimpA1") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToNumericA").resultType.name == "Int") - - // def convToIntA: Int // pimpA2: no constraints - conv = C._conversion(A.qualifiedName + ".pimpA2") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToIntA").resultType.name == "Int") - - // def convToPimpedA: Bar[Foo[Int]] // pimpA5: no constraints - conv = C._conversion(A.qualifiedName + ".pimpA5") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Int]]") - - // def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope - conv = C._conversion(A.qualifiedName + ".pimpA6") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToMyNumericA").resultType.name == "Int") - -//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val D = base._class("D") - - // these conversions should not affect D - assert(D._conversions(A.qualifiedName + ".pimpA0").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA2").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA3").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA4").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA7").isEmpty) - - // def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope - conv = D._conversion(A.qualifiedName + ".pimpA1") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToNumericA").resultType.name == "String") - - // def convToPimpedA: Bar[Foo[String]] // pimpA5: no constraints - conv = D._conversion(A.qualifiedName + ".pimpA5") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[String]]") - - // def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope - conv = D._conversion(A.qualifiedName + ".pimpA6") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToMyNumericA").resultType.name == "String") - } -} \ No newline at end of file diff --git a/test/scaladoc/run/implicits-chaining.check b/test/scaladoc/run/implicits-chaining.check deleted file mode 100644 index 619c56180b..0000000000 --- a/test/scaladoc/run/implicits-chaining.check +++ /dev/null @@ -1 +0,0 @@ -Done. diff --git a/test/scaladoc/run/implicits-chaining.scala b/test/scaladoc/run/implicits-chaining.scala deleted file mode 100644 index 96e288b204..0000000000 --- a/test/scaladoc/run/implicits-chaining.scala +++ /dev/null @@ -1,64 +0,0 @@ -import scala.tools.nsc.doc.model._ -import scala.tools.partest.ScaladocModelTest - -object Test extends ScaladocModelTest { - - // test a file instead of a piece of code - override def resourceFile = "implicits-chaining-res.scala" - - // start implicits - def scaladocSettings = "-implicits" - - def testModel(root: Package) = { - // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) - import access._ - - // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: - val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("chaining") - var conv: ImplicitConversion = null - -//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val A = base._class("A") - - conv = A._conversion(base.qualifiedName + ".convertToZ") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - -//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val B = base._class("B") - - conv = B._conversion(base.qualifiedName + ".convertToZ") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - -//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val C = base._class("C") - - assert(C._conversions(base.qualifiedName + ".convertToZ").isEmpty) - -//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val D = base._class("D") - - conv = D._conversion(base.qualifiedName + ".convertToZ") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - -//// class E /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val E = base._class("E") - - conv = E._conversion(base.qualifiedName + ".convertToZ") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - -//// class F /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val F = base._class("F") - - assert(F._conversions(base.qualifiedName + ".convertToZ").isEmpty) - } -} \ No newline at end of file diff --git a/test/scaladoc/run/implicits-elimination.check b/test/scaladoc/run/implicits-elimination.check deleted file mode 100644 index 619c56180b..0000000000 --- a/test/scaladoc/run/implicits-elimination.check +++ /dev/null @@ -1 +0,0 @@ -Done. diff --git a/test/scaladoc/run/implicits-elimination.scala b/test/scaladoc/run/implicits-elimination.scala deleted file mode 100644 index 71319f9f47..0000000000 --- a/test/scaladoc/run/implicits-elimination.scala +++ /dev/null @@ -1,22 +0,0 @@ -import scala.tools.nsc.doc.model._ -import scala.tools.partest.ScaladocModelTest - -object Test extends ScaladocModelTest { - - // test a file instead of a piece of code - override def resourceFile = "implicits-elimination-res.scala" - - // start implicits - def scaladocSettings = "-implicits" - - def testModel(root: Package) = { - // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) - import access._ - - // SEE THE test/resources/implicits-elimination-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: - val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("elimination") - val A = base._class("A") - - assert(A._conversions(A.qualifiedName + ".toB").isEmpty) - } -} \ No newline at end of file diff --git a/test/scaladoc/run/implicits-scopes.check b/test/scaladoc/run/implicits-scopes.check deleted file mode 100644 index 619c56180b..0000000000 --- a/test/scaladoc/run/implicits-scopes.check +++ /dev/null @@ -1 +0,0 @@ -Done. diff --git a/test/scaladoc/run/implicits-scopes.scala b/test/scaladoc/run/implicits-scopes.scala deleted file mode 100644 index 7fb41e1ae8..0000000000 --- a/test/scaladoc/run/implicits-scopes.scala +++ /dev/null @@ -1,76 +0,0 @@ -import scala.tools.nsc.doc.model._ -import scala.tools.partest.ScaladocModelTest - -object Test extends ScaladocModelTest { - - // test a file instead of a piece of code - override def resourceFile = "implicits-scopes-res.scala" - - // start implicits - def scaladocSettings = "-implicits" - - def testModel(root: Package) = { - // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) - import access._ - var conv: ImplicitConversion = null - - // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: - val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("scopes") - -//// test1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val doTest1 = { - val test1 = base._package("test1") - val A = test1._class("A") - - conv = A._conversion(test1.qualifiedName + ".package.toB") // the .package means it's the package object - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - } - -//// test2 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val doTest2 = { - val test2 = base._package("test2") - val classes = test2._package("classes") - val A = classes._class("A") - - assert(A._conversions(test2.qualifiedName + ".toB").isEmpty) - } - -//// test3 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val doTest3 = { - val test3 = base._package("test3") - val A = test3._class("A") - - conv = A._conversion(A.qualifiedName + ".toB") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - } - -//// test4 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val doTest4 = { - val test4 = base._package("test4") - val A = test4._class("A") - val S = test4._object("S") - - conv = A._conversion(S.qualifiedName + ".toB") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - } - -//// test5 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val doTest5 = { - val test5 = base._package("test5") - val scope = test5._object("scope") - val A = scope._class("A") - - conv = A._conversion(scope.qualifiedName + ".toB") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - } - } -} \ No newline at end of file -- cgit v1.2.3 From 7bd3b62ea5fc425fcf24685b6b8d8c5d1da0b8f5 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 14 Apr 2012 05:01:20 +0100 Subject: One more macro test to disable for SIP 18. --- test/disabled/neg/macro-deprecate-idents.check | 46 +++++++++++++++++++++ test/disabled/neg/macro-deprecate-idents.flags | 1 + test/disabled/neg/macro-deprecate-idents.scala | 56 ++++++++++++++++++++++++++ test/files/neg/macro-deprecate-idents.check | 46 --------------------- test/files/neg/macro-deprecate-idents.flags | 1 - test/files/neg/macro-deprecate-idents.scala | 56 -------------------------- 6 files changed, 103 insertions(+), 103 deletions(-) create mode 100644 test/disabled/neg/macro-deprecate-idents.check create mode 100644 test/disabled/neg/macro-deprecate-idents.flags create mode 100644 test/disabled/neg/macro-deprecate-idents.scala delete mode 100644 test/files/neg/macro-deprecate-idents.check delete mode 100644 test/files/neg/macro-deprecate-idents.flags delete mode 100644 test/files/neg/macro-deprecate-idents.scala diff --git a/test/disabled/neg/macro-deprecate-idents.check b/test/disabled/neg/macro-deprecate-idents.check new file mode 100644 index 0000000000..bd685fc7b9 --- /dev/null +++ b/test/disabled/neg/macro-deprecate-idents.check @@ -0,0 +1,46 @@ +macro-deprecate-idents.scala:2: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + val macro = ??? + ^ +macro-deprecate-idents.scala:6: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + var macro = ??? + ^ +macro-deprecate-idents.scala:10: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + type macro = Int + ^ +macro-deprecate-idents.scala:14: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + class macro + ^ +macro-deprecate-idents.scala:18: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + class macro + ^ +macro-deprecate-idents.scala:22: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + object macro + ^ +macro-deprecate-idents.scala:26: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + object macro + ^ +macro-deprecate-idents.scala:30: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + trait macro + ^ +macro-deprecate-idents.scala:34: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + trait macro + ^ +macro-deprecate-idents.scala:37: error: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro { + ^ +macro-deprecate-idents.scala:38: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + package macro.bar { + ^ +macro-deprecate-idents.scala:43: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + package macro.foo { + ^ +macro-deprecate-idents.scala:48: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + val Some(macro) = Some(42) + ^ +macro-deprecate-idents.scala:50: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + case macro => println(macro) + ^ +macro-deprecate-idents.scala:55: error: in future versions of Scala "macro" will be a keyword. consider using a different name. + def macro = 2 + ^ +15 errors found diff --git a/test/disabled/neg/macro-deprecate-idents.flags b/test/disabled/neg/macro-deprecate-idents.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/disabled/neg/macro-deprecate-idents.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/disabled/neg/macro-deprecate-idents.scala b/test/disabled/neg/macro-deprecate-idents.scala new file mode 100644 index 0000000000..23c398e341 --- /dev/null +++ b/test/disabled/neg/macro-deprecate-idents.scala @@ -0,0 +1,56 @@ +object Test1 { + val macro = ??? +} + +object Test2 { + var macro = ??? +} + +object Test3 { + type macro = Int +} + +package test4 { + class macro +} + +object Test5 { + class macro +} + +package test6 { + object macro +} + +object Test7 { + object macro +} + +package test8 { + trait macro +} + +object Test9 { + trait macro +} + +package macro { + package macro.bar { + } +} + +package foo { + package macro.foo { + } +} + +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} + +object Test13 { + def macro = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents.check b/test/files/neg/macro-deprecate-idents.check deleted file mode 100644 index bd685fc7b9..0000000000 --- a/test/files/neg/macro-deprecate-idents.check +++ /dev/null @@ -1,46 +0,0 @@ -macro-deprecate-idents.scala:2: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - val macro = ??? - ^ -macro-deprecate-idents.scala:6: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - var macro = ??? - ^ -macro-deprecate-idents.scala:10: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - type macro = Int - ^ -macro-deprecate-idents.scala:14: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - class macro - ^ -macro-deprecate-idents.scala:18: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - class macro - ^ -macro-deprecate-idents.scala:22: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - object macro - ^ -macro-deprecate-idents.scala:26: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - object macro - ^ -macro-deprecate-idents.scala:30: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - trait macro - ^ -macro-deprecate-idents.scala:34: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - trait macro - ^ -macro-deprecate-idents.scala:37: error: in future versions of Scala "macro" will be a keyword. consider using a different name. -package macro { - ^ -macro-deprecate-idents.scala:38: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - package macro.bar { - ^ -macro-deprecate-idents.scala:43: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - package macro.foo { - ^ -macro-deprecate-idents.scala:48: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - val Some(macro) = Some(42) - ^ -macro-deprecate-idents.scala:50: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - case macro => println(macro) - ^ -macro-deprecate-idents.scala:55: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - def macro = 2 - ^ -15 errors found diff --git a/test/files/neg/macro-deprecate-idents.flags b/test/files/neg/macro-deprecate-idents.flags deleted file mode 100644 index e8fb65d50c..0000000000 --- a/test/files/neg/macro-deprecate-idents.flags +++ /dev/null @@ -1 +0,0 @@ --Xfatal-warnings \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents.scala b/test/files/neg/macro-deprecate-idents.scala deleted file mode 100644 index 23c398e341..0000000000 --- a/test/files/neg/macro-deprecate-idents.scala +++ /dev/null @@ -1,56 +0,0 @@ -object Test1 { - val macro = ??? -} - -object Test2 { - var macro = ??? -} - -object Test3 { - type macro = Int -} - -package test4 { - class macro -} - -object Test5 { - class macro -} - -package test6 { - object macro -} - -object Test7 { - object macro -} - -package test8 { - trait macro -} - -object Test9 { - trait macro -} - -package macro { - package macro.bar { - } -} - -package foo { - package macro.foo { - } -} - -object Test12 { - val Some(macro) = Some(42) - macro match { - case macro => println(macro) - } -} - -object Test13 { - def macro = 2 -} \ No newline at end of file -- cgit v1.2.3 From 0ba3d542cc236ab2dbed3dc551920ede94787a0c Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 14 Apr 2012 10:33:10 +0200 Subject: restores some disabled macro tests, makes checkFeature synchronous when used for macros --- .../scala/tools/nsc/typechecker/Implicits.scala | 2 +- .../scala/tools/nsc/typechecker/Macros.scala | 13 +++++ ...cro-deprecate-dont-touch-backquotedidents.check | 10 ---- ...cro-deprecate-dont-touch-backquotedidents.flags | 1 - ...cro-deprecate-dont-touch-backquotedidents.scala | 56 ---------------------- test/disabled/neg/macro-deprecate-idents.check | 46 ------------------ test/disabled/neg/macro-deprecate-idents.flags | 1 - test/disabled/neg/macro-deprecate-idents.scala | 56 ---------------------- test/disabled/neg/macro-invalidshape-d.check | 4 -- test/disabled/neg/macro-invalidshape-d.flags | 1 - .../neg/macro-invalidshape-d/Impls_1.scala | 5 -- .../neg/macro-invalidshape-d/Macros_Test_2.scala | 8 ---- test/disabled/neg/macro-keyword-bind.flags | 2 +- test/disabled/neg/macro-keyword-class1.flags | 2 +- test/disabled/neg/macro-keyword-class2.flags | 2 +- test/disabled/neg/macro-keyword-object1.flags | 2 +- test/disabled/neg/macro-keyword-object2.flags | 2 +- test/disabled/neg/macro-keyword-package1.flags | 2 +- test/disabled/neg/macro-keyword-package2.flags | 2 +- test/disabled/neg/macro-keyword-trait1.flags | 2 +- test/disabled/neg/macro-keyword-trait2.flags | 2 +- test/disabled/neg/macro-keyword-type.flags | 2 +- test/disabled/neg/macro-keyword-val.flags | 2 +- test/disabled/neg/macro-without-xmacros-a.check | 10 ---- .../neg/macro-without-xmacros-a/Impls_1.scala | 18 ------- .../neg/macro-without-xmacros-a/Macros_2.scala | 12 ----- .../neg/macro-without-xmacros-a/Test_3.scala | 4 -- test/disabled/neg/macro-without-xmacros-b.check | 10 ---- .../neg/macro-without-xmacros-b/Impls_1.scala | 18 ------- .../neg/macro-without-xmacros-b/Macros_2.scala | 10 ---- .../neg/macro-without-xmacros-b/Test_3.scala | 4 -- .../run/macro-reflective-mamd-normal-mi.check | 0 .../run/macro-reflective-mamd-normal-mi.flags | 0 .../macro-reflective-mamd-normal-mi/Impls_1.scala | 9 ---- .../Macros_Test_2.scala | 16 ------- test/files/neg/macro-deprecate-idents.check | 52 ++++++++++++++++++++ test/files/neg/macro-deprecate-idents.flags | 1 + test/files/neg/macro-deprecate-idents.scala | 56 ++++++++++++++++++++++ test/files/neg/macro-invalidshape-d.check | 8 ++++ test/files/neg/macro-invalidshape-d.flags | 1 + test/files/neg/macro-invalidshape-d/Impls_1.scala | 5 ++ .../neg/macro-invalidshape-d/Macros_Test_2.scala | 8 ++++ test/files/neg/macro-without-xmacros-a.check | 17 +++++++ .../neg/macro-without-xmacros-a/Impls_1.scala | 18 +++++++ .../neg/macro-without-xmacros-a/Macros_2.scala | 12 +++++ .../files/neg/macro-without-xmacros-a/Test_3.scala | 4 ++ test/files/neg/macro-without-xmacros-b.check | 17 +++++++ .../neg/macro-without-xmacros-b/Impls_1.scala | 18 +++++++ .../neg/macro-without-xmacros-b/Macros_2.scala | 10 ++++ .../files/neg/macro-without-xmacros-b/Test_3.scala | 4 ++ ...cro-deprecate-dont-touch-backquotedidents.flags | 1 + ...cro-deprecate-dont-touch-backquotedidents.scala | 56 ++++++++++++++++++++++ .../run/macro-reflective-mamd-normal-mi.check | 1 + .../macro-reflective-mamd-normal-mi/Impls_1.scala | 9 ++++ .../Macros_Test_2.scala | 17 +++++++ test/files/run/t2886.check | 10 ++-- test/files/run/t2886.scala | 9 ++++ 57 files changed, 354 insertions(+), 316 deletions(-) delete mode 100644 test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.check delete mode 100644 test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.flags delete mode 100644 test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.scala delete mode 100644 test/disabled/neg/macro-deprecate-idents.check delete mode 100644 test/disabled/neg/macro-deprecate-idents.flags delete mode 100644 test/disabled/neg/macro-deprecate-idents.scala delete mode 100644 test/disabled/neg/macro-invalidshape-d.check delete mode 100644 test/disabled/neg/macro-invalidshape-d.flags delete mode 100644 test/disabled/neg/macro-invalidshape-d/Impls_1.scala delete mode 100644 test/disabled/neg/macro-invalidshape-d/Macros_Test_2.scala delete mode 100644 test/disabled/neg/macro-without-xmacros-a.check delete mode 100644 test/disabled/neg/macro-without-xmacros-a/Impls_1.scala delete mode 100644 test/disabled/neg/macro-without-xmacros-a/Macros_2.scala delete mode 100644 test/disabled/neg/macro-without-xmacros-a/Test_3.scala delete mode 100644 test/disabled/neg/macro-without-xmacros-b.check delete mode 100644 test/disabled/neg/macro-without-xmacros-b/Impls_1.scala delete mode 100644 test/disabled/neg/macro-without-xmacros-b/Macros_2.scala delete mode 100644 test/disabled/neg/macro-without-xmacros-b/Test_3.scala delete mode 100644 test/disabled/run/macro-reflective-mamd-normal-mi.check delete mode 100644 test/disabled/run/macro-reflective-mamd-normal-mi.flags delete mode 100644 test/disabled/run/macro-reflective-mamd-normal-mi/Impls_1.scala delete mode 100644 test/disabled/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala create mode 100644 test/files/neg/macro-deprecate-idents.check create mode 100644 test/files/neg/macro-deprecate-idents.flags create mode 100644 test/files/neg/macro-deprecate-idents.scala create mode 100644 test/files/neg/macro-invalidshape-d.check create mode 100644 test/files/neg/macro-invalidshape-d.flags create mode 100644 test/files/neg/macro-invalidshape-d/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-d/Macros_Test_2.scala create mode 100644 test/files/neg/macro-without-xmacros-a.check create mode 100644 test/files/neg/macro-without-xmacros-a/Impls_1.scala create mode 100644 test/files/neg/macro-without-xmacros-a/Macros_2.scala create mode 100644 test/files/neg/macro-without-xmacros-a/Test_3.scala create mode 100644 test/files/neg/macro-without-xmacros-b.check create mode 100644 test/files/neg/macro-without-xmacros-b/Impls_1.scala create mode 100644 test/files/neg/macro-without-xmacros-b/Macros_2.scala create mode 100644 test/files/neg/macro-without-xmacros-b/Test_3.scala create mode 100644 test/files/pos/macro-deprecate-dont-touch-backquotedidents.flags create mode 100644 test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala create mode 100644 test/files/run/macro-reflective-mamd-normal-mi.check create mode 100644 test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala create mode 100644 test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala create mode 100644 test/files/run/t2886.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index b4e0ad6edf..4fb9362ccc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -166,7 +166,7 @@ trait Implicits { } def isCyclicOrErroneous = - try containsError(tpe) + try sym.hasFlag(LOCKED) || containsError(tpe) catch { case _: CyclicReference => true } var useCountArg: Int = 0 diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 988b821d1a..b7e0eaef2b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -184,8 +184,21 @@ trait Macros { self: Analyzer => def typedMacroBody(typer: Typer, ddef: DefDef): Tree = { import typer.context if (macroDebug) println("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos)) + typer.checkFeature(ddef.pos, MacrosFeature) + // [Eugene to Martin] todo. copy/pasted this from checkFeature, because don't know a better way + // this is necessary to prevent macros from typechecking/expanding when they are not enabled + // `checkFeature` call alone is not enough, because it merely posts validation callback to unit.toCheck + def hasImport = inferImplicit(EmptyTree: Tree, MacrosFeature.tpe, true, false, typer.context) != SearchFailure + val nestedOwners = MacrosFeature.owner.ownerChain.takeWhile(_ != languageFeatureModule.moduleClass).reverse + val featureName = (nestedOwners map (_.name + ".")).mkString + MacrosFeature.name + def hasOption = settings.language.value contains featureName + if (!hasImport && !hasOption) { + ddef.symbol setFlag IS_ERROR + return EmptyTree + } + implicit class AugmentedString(s: String) { def abbreviateCoreAliases: String = { // hack! var result = s diff --git a/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.check b/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.check deleted file mode 100644 index 25df9a6a4a..0000000000 --- a/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.check +++ /dev/null @@ -1,10 +0,0 @@ -macro-deprecate-dont-touch-backquotedidents.scala:37: error: in future versions of Scala "macro" will be a keyword. consider using a different name. -package `macro` { - ^ -macro-deprecate-dont-touch-backquotedidents.scala:38: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - package `macro`.bar { - ^ -macro-deprecate-dont-touch-backquotedidents.scala:43: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - package `macro`.foo { - ^ -three errors found diff --git a/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.flags b/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.flags deleted file mode 100644 index e8fb65d50c..0000000000 --- a/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.flags +++ /dev/null @@ -1 +0,0 @@ --Xfatal-warnings \ No newline at end of file diff --git a/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.scala b/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.scala deleted file mode 100644 index dee2f1de3b..0000000000 --- a/test/disabled/neg/macro-deprecate-dont-touch-backquotedidents.scala +++ /dev/null @@ -1,56 +0,0 @@ -object Test1 { - val `macro` = ??? -} - -object Test2 { - var `macro` = ??? -} - -object Test3 { - type `macro` = Int -} - -package test4 { - class `macro` -} - -object Test5 { - class `macro` -} - -package test6 { - object `macro` -} - -object Test7 { - object `macro` -} - -package test8 { - trait `macro` -} - -object Test9 { - trait `macro` -} - -package `macro` { - package `macro`.bar { - } -} - -package foo { - package `macro`.foo { - } -} - -object Test12 { - val Some(`macro`) = Some(42) - `macro` match { - case `macro` => println(`macro`) - } -} - -object Test13 { - def `macro` = 2 -} \ No newline at end of file diff --git a/test/disabled/neg/macro-deprecate-idents.check b/test/disabled/neg/macro-deprecate-idents.check deleted file mode 100644 index bd685fc7b9..0000000000 --- a/test/disabled/neg/macro-deprecate-idents.check +++ /dev/null @@ -1,46 +0,0 @@ -macro-deprecate-idents.scala:2: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - val macro = ??? - ^ -macro-deprecate-idents.scala:6: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - var macro = ??? - ^ -macro-deprecate-idents.scala:10: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - type macro = Int - ^ -macro-deprecate-idents.scala:14: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - class macro - ^ -macro-deprecate-idents.scala:18: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - class macro - ^ -macro-deprecate-idents.scala:22: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - object macro - ^ -macro-deprecate-idents.scala:26: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - object macro - ^ -macro-deprecate-idents.scala:30: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - trait macro - ^ -macro-deprecate-idents.scala:34: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - trait macro - ^ -macro-deprecate-idents.scala:37: error: in future versions of Scala "macro" will be a keyword. consider using a different name. -package macro { - ^ -macro-deprecate-idents.scala:38: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - package macro.bar { - ^ -macro-deprecate-idents.scala:43: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - package macro.foo { - ^ -macro-deprecate-idents.scala:48: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - val Some(macro) = Some(42) - ^ -macro-deprecate-idents.scala:50: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - case macro => println(macro) - ^ -macro-deprecate-idents.scala:55: error: in future versions of Scala "macro" will be a keyword. consider using a different name. - def macro = 2 - ^ -15 errors found diff --git a/test/disabled/neg/macro-deprecate-idents.flags b/test/disabled/neg/macro-deprecate-idents.flags deleted file mode 100644 index e8fb65d50c..0000000000 --- a/test/disabled/neg/macro-deprecate-idents.flags +++ /dev/null @@ -1 +0,0 @@ --Xfatal-warnings \ No newline at end of file diff --git a/test/disabled/neg/macro-deprecate-idents.scala b/test/disabled/neg/macro-deprecate-idents.scala deleted file mode 100644 index 23c398e341..0000000000 --- a/test/disabled/neg/macro-deprecate-idents.scala +++ /dev/null @@ -1,56 +0,0 @@ -object Test1 { - val macro = ??? -} - -object Test2 { - var macro = ??? -} - -object Test3 { - type macro = Int -} - -package test4 { - class macro -} - -object Test5 { - class macro -} - -package test6 { - object macro -} - -object Test7 { - object macro -} - -package test8 { - trait macro -} - -object Test9 { - trait macro -} - -package macro { - package macro.bar { - } -} - -package foo { - package macro.foo { - } -} - -object Test12 { - val Some(macro) = Some(42) - macro match { - case macro => println(macro) - } -} - -object Test13 { - def macro = 2 -} \ No newline at end of file diff --git a/test/disabled/neg/macro-invalidshape-d.check b/test/disabled/neg/macro-invalidshape-d.check deleted file mode 100644 index 031aa653ab..0000000000 --- a/test/disabled/neg/macro-invalidshape-d.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:2: error: illegal start of statement - def foo(x: Any) = {2; macro Impls.foo} - ^ -one error found diff --git a/test/disabled/neg/macro-invalidshape-d.flags b/test/disabled/neg/macro-invalidshape-d.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-invalidshape-d.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-invalidshape-d/Impls_1.scala b/test/disabled/neg/macro-invalidshape-d/Impls_1.scala deleted file mode 100644 index 7b1620d117..0000000000 --- a/test/disabled/neg/macro-invalidshape-d/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.makro.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/disabled/neg/macro-invalidshape-d/Macros_Test_2.scala b/test/disabled/neg/macro-invalidshape-d/Macros_Test_2.scala deleted file mode 100644 index bacd9a6e7c..0000000000 --- a/test/disabled/neg/macro-invalidshape-d/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = {2; macro Impls.foo} -} - -object Test extends App { - import Macros._ - foo(42) -} \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-bind.flags b/test/disabled/neg/macro-keyword-bind.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-bind.flags +++ b/test/disabled/neg/macro-keyword-bind.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-class1.flags b/test/disabled/neg/macro-keyword-class1.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-class1.flags +++ b/test/disabled/neg/macro-keyword-class1.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-class2.flags b/test/disabled/neg/macro-keyword-class2.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-class2.flags +++ b/test/disabled/neg/macro-keyword-class2.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-object1.flags b/test/disabled/neg/macro-keyword-object1.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-object1.flags +++ b/test/disabled/neg/macro-keyword-object1.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-object2.flags b/test/disabled/neg/macro-keyword-object2.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-object2.flags +++ b/test/disabled/neg/macro-keyword-object2.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-package1.flags b/test/disabled/neg/macro-keyword-package1.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-package1.flags +++ b/test/disabled/neg/macro-keyword-package1.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-package2.flags b/test/disabled/neg/macro-keyword-package2.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-package2.flags +++ b/test/disabled/neg/macro-keyword-package2.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-trait1.flags b/test/disabled/neg/macro-keyword-trait1.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-trait1.flags +++ b/test/disabled/neg/macro-keyword-trait1.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-trait2.flags b/test/disabled/neg/macro-keyword-trait2.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-trait2.flags +++ b/test/disabled/neg/macro-keyword-trait2.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-type.flags b/test/disabled/neg/macro-keyword-type.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-type.flags +++ b/test/disabled/neg/macro-keyword-type.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-val.flags b/test/disabled/neg/macro-keyword-val.flags index 7fea2ff901..cd66464f2f 100644 --- a/test/disabled/neg/macro-keyword-val.flags +++ b/test/disabled/neg/macro-keyword-val.flags @@ -1 +1 @@ --Xmacros \ No newline at end of file +-language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-without-xmacros-a.check b/test/disabled/neg/macro-without-xmacros-a.check deleted file mode 100644 index a3ca081f04..0000000000 --- a/test/disabled/neg/macro-without-xmacros-a.check +++ /dev/null @@ -1,10 +0,0 @@ -Macros_2.scala:5: error: not found: value macro - def foo(x: Int): Int = macro foo_impl - ^ -Macros_2.scala:7: error: not found: value macro - def bar(x: Int): Int = macro bar_impl - ^ -Macros_2.scala:11: error: not found: value macro - def quux(x: Int): Int = macro quux_impl - ^ -three errors found diff --git a/test/disabled/neg/macro-without-xmacros-a/Impls_1.scala b/test/disabled/neg/macro-without-xmacros-a/Impls_1.scala deleted file mode 100644 index 2493c81c95..0000000000 --- a/test/disabled/neg/macro-without-xmacros-a/Impls_1.scala +++ /dev/null @@ -1,18 +0,0 @@ -import scala.reflect.makro.{Context => Ctx} - -object Impls { - def foo_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) - } - - def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) - } - - def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) - } -} diff --git a/test/disabled/neg/macro-without-xmacros-a/Macros_2.scala b/test/disabled/neg/macro-without-xmacros-a/Macros_2.scala deleted file mode 100644 index 62f9dcf505..0000000000 --- a/test/disabled/neg/macro-without-xmacros-a/Macros_2.scala +++ /dev/null @@ -1,12 +0,0 @@ -import Impls._ - -object Macros { - object Shmacros { - def foo(x: Int): Int = macro foo_impl - } - def bar(x: Int): Int = macro bar_impl -} - -class Macros { - def quux(x: Int): Int = macro quux_impl -} \ No newline at end of file diff --git a/test/disabled/neg/macro-without-xmacros-a/Test_3.scala b/test/disabled/neg/macro-without-xmacros-a/Test_3.scala deleted file mode 100644 index e9a10e20c9..0000000000 --- a/test/disabled/neg/macro-without-xmacros-a/Test_3.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros.Shmacros._ - println(foo(2) + Macros.bar(2) * new Macros().quux(4)) -} \ No newline at end of file diff --git a/test/disabled/neg/macro-without-xmacros-b.check b/test/disabled/neg/macro-without-xmacros-b.check deleted file mode 100644 index dce4a084c9..0000000000 --- a/test/disabled/neg/macro-without-xmacros-b.check +++ /dev/null @@ -1,10 +0,0 @@ -Macros_2.scala:3: error: ';' expected but '.' found. - def foo(x: Int): Int = macro Impls.foo_impl - ^ -Macros_2.scala:5: error: ';' expected but '.' found. - def bar(x: Int): Int = macro Impls.bar_impl - ^ -Macros_2.scala:9: error: ';' expected but '.' found. - def quux(x: Int): Int = macro Impls.quux_impl - ^ -three errors found diff --git a/test/disabled/neg/macro-without-xmacros-b/Impls_1.scala b/test/disabled/neg/macro-without-xmacros-b/Impls_1.scala deleted file mode 100644 index 2493c81c95..0000000000 --- a/test/disabled/neg/macro-without-xmacros-b/Impls_1.scala +++ /dev/null @@ -1,18 +0,0 @@ -import scala.reflect.makro.{Context => Ctx} - -object Impls { - def foo_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) - } - - def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) - } - - def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { - import c.mirror._ - Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) - } -} diff --git a/test/disabled/neg/macro-without-xmacros-b/Macros_2.scala b/test/disabled/neg/macro-without-xmacros-b/Macros_2.scala deleted file mode 100644 index de7080c7e8..0000000000 --- a/test/disabled/neg/macro-without-xmacros-b/Macros_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Macros { - object Shmacros { - def foo(x: Int): Int = macro Impls.foo_impl - } - def bar(x: Int): Int = macro Impls.bar_impl -} - -class Macros { - def quux(x: Int): Int = macro Impls.quux_impl -} \ No newline at end of file diff --git a/test/disabled/neg/macro-without-xmacros-b/Test_3.scala b/test/disabled/neg/macro-without-xmacros-b/Test_3.scala deleted file mode 100644 index e9a10e20c9..0000000000 --- a/test/disabled/neg/macro-without-xmacros-b/Test_3.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros.Shmacros._ - println(foo(2) + Macros.bar(2) * new Macros().quux(4)) -} \ No newline at end of file diff --git a/test/disabled/run/macro-reflective-mamd-normal-mi.check b/test/disabled/run/macro-reflective-mamd-normal-mi.check deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/disabled/run/macro-reflective-mamd-normal-mi.flags b/test/disabled/run/macro-reflective-mamd-normal-mi.flags deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/disabled/run/macro-reflective-mamd-normal-mi/Impls_1.scala b/test/disabled/run/macro-reflective-mamd-normal-mi/Impls_1.scala deleted file mode 100644 index dc7d42d23e..0000000000 --- a/test/disabled/run/macro-reflective-mamd-normal-mi/Impls_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.makro.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Int]) = { - import c.mirror._ - val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) - Expr[Int](body) - } -} diff --git a/test/disabled/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala b/test/disabled/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala deleted file mode 100644 index 7cbe425fc8..0000000000 --- a/test/disabled/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala +++ /dev/null @@ -1,16 +0,0 @@ -//object Macros { -// def foo(x: Int) = macro Impls.foo -//} - -object Test extends App { - import scala.reflect.mirror._ - - val macrobody = Select(Ident(newTermName("Impls")), newTermName("foo")) - val macroparam = ValDef(NoMods, newTermName("x"), TypeTree(definitions.IntClass.asType), EmptyTree) - val macrodef = DefDef(Modifiers(Set(scala.reflect.api.Modifier.`macro`)), newTermName("foo"), Nil, List(List(macroparam)), TypeTree(), macrobody) - val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(Apply(Select(Super(This(EmptyTypeName), EmptyTypeName), nme.CONSTRUCTOR), List()))) - val module = ModuleDef(NoMods, newTermName("Macros"), Template(Nil, emptyValDef, List(modulector, macrodef))) - val macroapp = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) - val tree = Block(macrodef, module, macroapp) - println(tree.eval) -} diff --git a/test/files/neg/macro-deprecate-idents.check b/test/files/neg/macro-deprecate-idents.check new file mode 100644 index 0000000000..f8a7e519df --- /dev/null +++ b/test/files/neg/macro-deprecate-idents.check @@ -0,0 +1,52 @@ +macro-deprecate-idents.scala:2: error: macro is now a reserved word; usage as an identifier is deprecated + val macro = ??? + ^ +macro-deprecate-idents.scala:6: error: macro is now a reserved word; usage as an identifier is deprecated + var macro = ??? + ^ +macro-deprecate-idents.scala:10: error: macro is now a reserved word; usage as an identifier is deprecated + type macro = Int + ^ +macro-deprecate-idents.scala:14: error: macro is now a reserved word; usage as an identifier is deprecated + class macro + ^ +macro-deprecate-idents.scala:18: error: macro is now a reserved word; usage as an identifier is deprecated + class macro + ^ +macro-deprecate-idents.scala:22: error: macro is now a reserved word; usage as an identifier is deprecated + object macro + ^ +macro-deprecate-idents.scala:26: error: macro is now a reserved word; usage as an identifier is deprecated + object macro + ^ +macro-deprecate-idents.scala:30: error: macro is now a reserved word; usage as an identifier is deprecated + trait macro + ^ +macro-deprecate-idents.scala:34: error: macro is now a reserved word; usage as an identifier is deprecated + trait macro + ^ +macro-deprecate-idents.scala:37: error: macro is now a reserved word; usage as an identifier is deprecated +package macro { + ^ +macro-deprecate-idents.scala:38: error: macro is now a reserved word; usage as an identifier is deprecated + package macro.bar { + ^ +macro-deprecate-idents.scala:43: error: macro is now a reserved word; usage as an identifier is deprecated + package macro.foo { + ^ +macro-deprecate-idents.scala:48: error: macro is now a reserved word; usage as an identifier is deprecated + val Some(macro) = Some(42) + ^ +macro-deprecate-idents.scala:49: error: macro is now a reserved word; usage as an identifier is deprecated + macro match { + ^ +macro-deprecate-idents.scala:50: error: macro is now a reserved word; usage as an identifier is deprecated + case macro => println(macro) + ^ +macro-deprecate-idents.scala:50: error: macro is now a reserved word; usage as an identifier is deprecated + case macro => println(macro) + ^ +macro-deprecate-idents.scala:55: error: macro is now a reserved word; usage as an identifier is deprecated + def macro = 2 + ^ +17 errors found diff --git a/test/files/neg/macro-deprecate-idents.flags b/test/files/neg/macro-deprecate-idents.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/neg/macro-deprecate-idents.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents.scala b/test/files/neg/macro-deprecate-idents.scala new file mode 100644 index 0000000000..23c398e341 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents.scala @@ -0,0 +1,56 @@ +object Test1 { + val macro = ??? +} + +object Test2 { + var macro = ??? +} + +object Test3 { + type macro = Int +} + +package test4 { + class macro +} + +object Test5 { + class macro +} + +package test6 { + object macro +} + +object Test7 { + object macro +} + +package test8 { + trait macro +} + +object Test9 { + trait macro +} + +package macro { + package macro.bar { + } +} + +package foo { + package macro.foo { + } +} + +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} + +object Test13 { + def macro = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d.check b/test/files/neg/macro-invalidshape-d.check new file mode 100644 index 0000000000..f0d77e2f2d --- /dev/null +++ b/test/files/neg/macro-invalidshape-d.check @@ -0,0 +1,8 @@ +Macros_Test_2.scala:2: warning: macro is now a reserved word; usage as an identifier is deprecated + def foo(x: Any) = {2; macro Impls.foo} + ^ +Macros_Test_2.scala:2: error: ';' expected but '.' found. + def foo(x: Any) = {2; macro Impls.foo} + ^ +one warning found +one error found diff --git a/test/files/neg/macro-invalidshape-d.flags b/test/files/neg/macro-invalidshape-d.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/neg/macro-invalidshape-d.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d/Impls_1.scala b/test/files/neg/macro-invalidshape-d/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidshape-d/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala new file mode 100644 index 0000000000..bacd9a6e7c --- /dev/null +++ b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = {2; macro Impls.foo} +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-a.check b/test/files/neg/macro-without-xmacros-a.check new file mode 100644 index 0000000000..fd2667dbb8 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a.check @@ -0,0 +1,17 @@ +Macros_2.scala:5: error: macro definition needs to be enabled +by making the implicit value language.experimental.macros visible. +This can be achieved by adding the import clause 'import language.experimental.macros' +or by setting the compiler option -language:experimental.macros. +See the Scala docs for value scala.language.experimental.macros for a discussion +why the feature needs to be explicitly enabled. + def foo(x: Int): Int = macro foo_impl + ^ +Macros_2.scala:7: error: macro definition needs to be enabled +by making the implicit value language.experimental.macros visible. + def bar(x: Int): Int = macro bar_impl + ^ +Macros_2.scala:11: error: macro definition needs to be enabled +by making the implicit value language.experimental.macros visible. + def quux(x: Int): Int = macro quux_impl + ^ +three errors found diff --git a/test/files/neg/macro-without-xmacros-a/Impls_1.scala b/test/files/neg/macro-without-xmacros-a/Impls_1.scala new file mode 100644 index 0000000000..01daf12b1a --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a/Impls_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + } +} diff --git a/test/files/neg/macro-without-xmacros-a/Macros_2.scala b/test/files/neg/macro-without-xmacros-a/Macros_2.scala new file mode 100644 index 0000000000..62f9dcf505 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a/Macros_2.scala @@ -0,0 +1,12 @@ +import Impls._ + +object Macros { + object Shmacros { + def foo(x: Int): Int = macro foo_impl + } + def bar(x: Int): Int = macro bar_impl +} + +class Macros { + def quux(x: Int): Int = macro quux_impl +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-a/Test_3.scala b/test/files/neg/macro-without-xmacros-a/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-b.check b/test/files/neg/macro-without-xmacros-b.check new file mode 100644 index 0000000000..2d675b8319 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b.check @@ -0,0 +1,17 @@ +Macros_2.scala:3: error: macro definition needs to be enabled +by making the implicit value language.experimental.macros visible. +This can be achieved by adding the import clause 'import language.experimental.macros' +or by setting the compiler option -language:experimental.macros. +See the Scala docs for value scala.language.experimental.macros for a discussion +why the feature needs to be explicitly enabled. + def foo(x: Int): Int = macro Impls.foo_impl + ^ +Macros_2.scala:5: error: macro definition needs to be enabled +by making the implicit value language.experimental.macros visible. + def bar(x: Int): Int = macro Impls.bar_impl + ^ +Macros_2.scala:9: error: macro definition needs to be enabled +by making the implicit value language.experimental.macros visible. + def quux(x: Int): Int = macro Impls.quux_impl + ^ +three errors found diff --git a/test/files/neg/macro-without-xmacros-b/Impls_1.scala b/test/files/neg/macro-without-xmacros-b/Impls_1.scala new file mode 100644 index 0000000000..01daf12b1a --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b/Impls_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + } +} diff --git a/test/files/neg/macro-without-xmacros-b/Macros_2.scala b/test/files/neg/macro-without-xmacros-b/Macros_2.scala new file mode 100644 index 0000000000..de7080c7e8 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b/Macros_2.scala @@ -0,0 +1,10 @@ +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo_impl + } + def bar(x: Int): Int = macro Impls.bar_impl +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux_impl +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-b/Test_3.scala b/test/files/neg/macro-without-xmacros-b/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/pos/macro-deprecate-dont-touch-backquotedidents.flags b/test/files/pos/macro-deprecate-dont-touch-backquotedidents.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/macro-deprecate-dont-touch-backquotedidents.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala b/test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala new file mode 100644 index 0000000000..69a7333011 --- /dev/null +++ b/test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala @@ -0,0 +1,56 @@ +object Test1 { + val `macro` = ??? +} + +object Test2 { + var `macro` = ??? +} + +object Test3 { + type `macro` = Int +} + +package test4 { + class `macro` +} + +object Test5 { + class `macro` +} + +package test6 { + object `macro` +} + +object Test7 { + object `macro` +} + +package test8 { + trait `macro` +} + +object Test9 { + trait `macro` +} + +package `macro` { + package `macro`.bar { + } +} + +package foo { + package `macro`.foo { + } +} + +//object Test12 { +// val Some(`macro`) = Some(42) +// `macro` match { +// case `macro` => println(`macro`) +// } +//} + +object Test13 { + def `macro` = 2 +} \ No newline at end of file diff --git a/test/files/run/macro-reflective-mamd-normal-mi.check b/test/files/run/macro-reflective-mamd-normal-mi.check new file mode 100644 index 0000000000..ac4213d6e9 --- /dev/null +++ b/test/files/run/macro-reflective-mamd-normal-mi.check @@ -0,0 +1 @@ +43 \ No newline at end of file diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala b/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala new file mode 100644 index 0000000000..dc7d42d23e --- /dev/null +++ b/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } +} diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala new file mode 100644 index 0000000000..cf34f1685d --- /dev/null +++ b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala @@ -0,0 +1,17 @@ +//object Macros { +// def foo(x: Int) = macro Impls.foo +//} + +object Test extends App { + import scala.reflect.mirror._ + + val macrobody = Select(Ident(newTermName("Impls")), newTermName("foo")) + val macroparam = ValDef(NoMods, newTermName("x"), TypeTree(definitions.IntClass.asType), EmptyTree) + val macrodef = DefDef(Modifiers(Set(scala.reflect.api.Modifier.`macro`)), newTermName("foo"), Nil, List(List(macroparam)), TypeTree(), macrobody) + val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(Apply(Select(Super(This(EmptyTypeName), EmptyTypeName), nme.CONSTRUCTOR), List()))) + val module = ModuleDef(NoMods, newTermName("Macros"), Template(Nil, emptyValDef, List(modulector, macrodef))) + val macroapp = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + val tree = Block(macrodef, module, macroapp) + val toolbox = mkToolBox(options = "-language:experimental.macros") + println(toolbox.runExpr(tree)) +} diff --git a/test/files/run/t2886.check b/test/files/run/t2886.check index 5fe1e73a45..8d97a82799 100644 --- a/test/files/run/t2886.check +++ b/test/files/run/t2886.check @@ -1,5 +1,5 @@ -((x: scala.Predef.String) => { - val x$1 = x; - val x$2 = x; - Test.test(x$2, x$1) -}) +((x: String) => { + val x$1 = x; + val x$2 = x; + Test.this.test(x$2, x$1) +}) diff --git a/test/files/run/t2886.scala b/test/files/run/t2886.scala new file mode 100644 index 0000000000..e0835a0a44 --- /dev/null +++ b/test/files/run/t2886.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test { + def test(name: String, address: String) = null + def main(args: Array[String]) = { + val tree = reify((x:String) => test(address=x,name=x)).tree + println(tree) + } +} -- cgit v1.2.3 From f5857462ccb770f3433637efa3c342ec98622137 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 29 Mar 2012 16:50:29 +0200 Subject: print labeldef's parameter types --- src/compiler/scala/reflect/internal/TreePrinters.scala | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala index 9b4c18ce86..486a3d3567 100644 --- a/src/compiler/scala/reflect/internal/TreePrinters.scala +++ b/src/compiler/scala/reflect/internal/TreePrinters.scala @@ -103,6 +103,16 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => } } + def printLabelParams(ps: List[Ident]) { + print("(") + printSeq(ps){printLabelParam}{print(", ")} + print(")") + } + + def printLabelParam(p: Ident) { + print(symName(p, p.name)); printOpt(": ", TypeTree() setType p.tpe) + } + def printValueParams(ts: List[ValDef]) { print("(") if (!ts.isEmpty) printFlags(ts.head.mods.flags & IMPLICIT, "") @@ -219,7 +229,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => } case LabelDef(name, params, rhs) => - print(symName(tree, name)); printRow(params, "(", ",", ")"); printBlock(rhs) + print(symName(tree, name)); printLabelParams(params); printBlock(rhs) case Import(expr, selectors) => // Is this selector remapping a name (i.e, {name1 => name2}) -- cgit v1.2.3 From 98a85ccae54195ee17f4b4aa12c22d018fd43bee Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 13 Apr 2012 13:58:48 +0200 Subject: cleanup in refchecks --- src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index af75c75156..2d656e02b4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1655,9 +1655,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R inPattern = false treeCopy.CaseDef(tree, pat1, transform(guard), transform(body)) case LabelDef(_, _, _) if gen.hasSynthCaseSymbol(result) => + val old = inPattern inPattern = true val res = deriveLabelDef(result)(transform) - inPattern = false + inPattern = old res case _ => super.transform(result) -- cgit v1.2.3 From d383f458aa5c53629727c5b6abb5134218471543 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Wed, 11 Apr 2012 15:05:27 +0200 Subject: synth PartialFunction in uncurry due to interaction with the CPS plugin, can't synth PartialFun during typer (the types don't work out: in PartialFun[T, U @cps[V]], U @cps[V] does not conform to Any, and we can't move the annot from the type arg directly to applyOrElse's result, since then it won't override anything) thus, we face the pain of mangling labeldefs again resetLocalAttrsKeepLabels can't use leaveAlone don't cast matcherror throw, uncurry gets confused uncurry: cast selector valdef's rhs to avoid skolem mismatch NOTE: I'm not happy about this code, but I don't know how to make the clean way (typedMatchAnonFun) compatible with the CPS plugin one avenue to explor would be to introduce PartialFunCPS, which is transformed into a regular PartialFun when T @cps[U] is turned into ControlContext[T, U] --- src/compiler/scala/tools/nsc/ast/TreeGen.scala | 55 ++------ src/compiler/scala/tools/nsc/ast/Trees.scala | 9 +- .../scala/tools/nsc/transform/UnCurry.scala | 146 +++++++++++++++++++-- .../tools/nsc/typechecker/PatMatVirtualiser.scala | 6 +- .../scala/tools/nsc/typechecker/Typers.scala | 71 +++++----- test/files/pos/virtpatmat_exist_uncurry.scala | 6 + 6 files changed, 194 insertions(+), 99 deletions(-) create mode 100644 test/files/pos/virtpatmat_exist_uncurry.scala diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index e566384713..d3e64811d3 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -72,14 +72,6 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { Annotated(Ident(nme.synthSwitch), expr) } - // must be kept in synch with the codegen in PatMatVirtualiser - object VirtualCaseDef { - def unapply(b: Block): Option[(Assign, Tree, Tree)] = b match { - case Block(List(assign@Assign(keepGoingLhs, falseLit), matchRes), zero) => Some((assign, matchRes, zero)) // TODO: check tree annotation - case _ => None - } - } - def hasSynthCaseSymbol(t: Tree) = (t.symbol ne null) && (t.symbol hasFlag (CASE | SYNTHETIC)) // TODO: would be so much nicer if we would know during match-translation (i.e., type checking) @@ -87,9 +79,11 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { class MatchMatcher { def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = unknownTree(orig) def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = unknownTree(orig) - def caseVirtualizedMatchOpt(orig: Tree, zero: ValDef, x: ValDef, matchRes: ValDef, keepGoing: ValDef, stats: List[Tree], epilogue: Tree, wrap: Tree => Tree): Tree = unknownTree(orig) + def caseVirtualizedMatchOpt(orig: Tree, prologue: List[Tree], cases: List[Tree], matchEndDef: Tree, wrap: Tree => Tree): Tree = unknownTree(orig) - def apply(matchExpr: Tree): Tree = (matchExpr: @unchecked) match { + def genVirtualizedMatch(prologue: List[Tree], cases: List[Tree], matchEndDef: Tree): Tree = Block(prologue ++ cases, matchEndDef) + + def apply(matchExpr: Tree): Tree = matchExpr match { // old-style match or virtpatmat switch case Match(selector, cases) => // println("simple match: "+ (selector, cases) + "for:\n"+ matchExpr ) caseMatch(matchExpr, selector, cases, identity) @@ -100,11 +94,15 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { case Apply(Apply(TypeApply(Select(tgt, nme.runOrElse), targs), List(scrut)), List(matcher)) if opt.virtPatmat => // println("virt match: "+ (tgt, targs, scrut, matcher) + "for:\n"+ matchExpr ) caseVirtualizedMatch(matchExpr, tgt, targs, scrut, matcher) // optimized version of virtpatmat - case Block((zero: ValDef) :: (x: ValDef) :: (matchRes: ValDef) :: (keepGoing: ValDef) :: stats, epilogue) if opt.virtPatmat => // TODO: check tree annotation // println("virtopt match: "+ (zero, x, matchRes, keepGoing, stats) + "for:\n"+ matchExpr ) - caseVirtualizedMatchOpt(matchExpr, zero, x, matchRes, keepGoing, stats, epilogue, identity) + case Block(stats, matchEndDef) if opt.virtPatmat && (stats forall hasSynthCaseSymbol) => + // the assumption is once we encounter a case, the remainder of the block will consist of cases + // the prologue may be empty, usually it is the valdef that stores the scrut + val (prologue, cases) = stats span (s => !s.isInstanceOf[LabelDef]) + caseVirtualizedMatchOpt(matchExpr, prologue, cases, matchEndDef, identity) // optimized version of virtpatmat - case Block(outerStats, orig@Block((zero: ValDef) :: (x: ValDef) :: (matchRes: ValDef) :: (keepGoing: ValDef) :: stats, epilogue)) if opt.virtPatmat => // TODO: check tree annotation // println("virt opt block match: "+ (zero, x, matchRes, keepGoing, stats, outerStats) + "for:\n"+ matchExpr ) - caseVirtualizedMatchOpt(matchExpr, zero, x, matchRes, keepGoing, stats, epilogue, m => copyBlock(matchExpr, outerStats, m)) + case Block(outerStats, orig@Block(stats, matchEndDef)) if opt.virtPatmat && (stats forall hasSynthCaseSymbol) => + val (prologue, cases) = stats span (s => !s.isInstanceOf[LabelDef]) + caseVirtualizedMatchOpt(matchExpr, prologue, cases, matchEndDef, m => copyBlock(matchExpr, outerStats, m)) case other => unknownTree(other) } @@ -120,35 +118,6 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { } } - def withDefaultCase(matchExpr: Tree, defaultAction: Tree/*scrutinee*/ => Tree): Tree = { - object withDefaultTransformer extends MatchMatcher { - override def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = { - val casesNoSynthCatchAll = dropSyntheticCatchAll(cases) - if (casesNoSynthCatchAll exists treeInfo.isDefaultCase) orig - else { - val defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, defaultAction(selector.duplicate)) - wrap(Match(selector, casesNoSynthCatchAll :+ defaultCase)) - } - } - override def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = { import CODE._ - ((matcher APPLY (scrut)) DOT nme.getOrElse) APPLY (defaultAction(scrut.duplicate)) // TODO: pass targs - } - override def caseVirtualizedMatchOpt(orig: Tree, zero: ValDef, x: ValDef, matchRes: ValDef, keepGoing: ValDef, stats: List[Tree], epilogue: Tree, wrap: Tree => Tree): Tree = { import CODE._ - wrap(Block( - zero :: - x :: - matchRes :: - keepGoing :: - stats, - // replace `if (keepGoing) throw new MatchError(...) else matchRes` by `if (keepGoing) ${defaultAction(`x`)} else matchRes` - (IF (REF(keepGoing.symbol)) THEN defaultAction(x.rhs.duplicate) ELSE REF(matchRes.symbol)) - )) - } - } - withDefaultTransformer(matchExpr) - } - - def mkCached(cvar: Symbol, expr: Tree): Tree = { val cvarRef = mkUnattributedRef(cvar) Block( diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 59e36e86f6..04452c68e5 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -255,6 +255,7 @@ trait Trees extends reflect.internal.Trees { self: Global => def resetAllAttrs[A <: Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(false, leaveAlone).transform(x) def resetLocalAttrs[A <: Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(true, leaveAlone).transform(x) + def resetLocalAttrsKeepLabels[A<:Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(true, leaveAlone, true).transform(x) /** A transformer which resets symbol and tpe fields of all nodes in a given tree, * with special treatment of: @@ -265,7 +266,7 @@ trait Trees extends reflect.internal.Trees { self: Global => * * (bq:) This transformer has mutable state and should be discarded after use */ - private class ResetAttrs(localOnly: Boolean, leaveAlone: Tree => Boolean = null) { + private class ResetAttrs(localOnly: Boolean, leaveAlone: Tree => Boolean = null, keepLabels: Boolean = false) { val debug = settings.debug.value val trace = scala.tools.nsc.util.trace when debug @@ -328,18 +329,18 @@ trait Trees extends reflect.internal.Trees { self: Global => case EmptyTree => tree case _ => - if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol))) + if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol)) && !(keepLabels && tree.symbol.isLabel)) tree.symbol = NoSymbol tree.tpe = null tree } } - } + } } def transform[T <: Tree](x: T): T = { if (localOnly) - new MarkLocals().traverse(x) + new MarkLocals().traverse(x) if (localOnly && debug) { assert(locals.size == orderedLocals.size) diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 1d2206bc3d..57cd51ad35 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -241,7 +241,6 @@ abstract class UnCurry extends InfoTransform def owner = fun.symbol.owner def targs = fun.tpe.typeArgs def isPartial = fun.tpe.typeSymbol == PartialFunctionClass - assert(!(opt.virtPatmat && isPartial)) // empty-selector matches have already been translated into instantiations of anonymous (partial) functions def parents = if (isFunctionType(fun.tpe)) List(abstractFunctionForFunctionType(fun.tpe), SerializableClass.tpe) @@ -282,7 +281,44 @@ abstract class UnCurry extends InfoTransform val substParam = new TreeSymSubstituter(fun.vparams map (_.symbol), List(x)) val body = localTyper.typedPos(fun.pos) { import CODE._ - gen.mkUncheckedMatch(gen.withDefaultCase(substParam(fun.body), scrut => REF(default) APPLY (REF(x)))) + def defaultAction(scrut: Tree) = REF(default) APPLY (REF(x)) + + object withDefaultTransformer extends gen.MatchMatcher { + override def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = { + val casesNoSynthCatchAll = dropSyntheticCatchAll(cases) + if (casesNoSynthCatchAll exists treeInfo.isDefaultCase) orig + else { + val defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, defaultAction(selector.duplicate)) + wrap(Match(/*gen.mkUnchecked*/(selector), casesNoSynthCatchAll :+ defaultCase)) + } + } + override def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = { import CODE._ + ((matcher APPLY (scrut)) DOT nme.getOrElse) APPLY (defaultAction(scrut.duplicate)) // TODO: pass targs + } + override def caseVirtualizedMatchOpt(orig: Tree, prologue: List[Tree], cases: List[Tree], matchEndDef: Tree, wrap: Tree => Tree): Tree = { import CODE._ + val scrutRef = REF(prologue.head.symbol) // scrut valdef is always emitted (except for nested matchers that handle alternatives) + + val casesNewSynthCatchAll = cases.init :+ (deriveLabelDef(cases.last){ + case Apply(matchEnd, List(Throw(Apply(Select(New(exTpt), nme.CONSTRUCTOR), _)))) if exTpt.tpe.typeSymbol eq MatchErrorClass => + assert(matchEnd.symbol == matchEndDef.symbol, "matchEnd discrepancy "+(matchEnd, matchEndDef)) + matchEnd APPLY (defaultAction(scrutRef)) + case x => x + } setSymbol cases.last.symbol setType null) + + val LabelDef(_, List(matchRes), rhs) = matchEndDef + val matchEnd = matchEndDef.symbol + matchRes setType B1.tpe + rhs setType B1.tpe + matchEndDef setType B1.tpe + matchRes.symbol setInfo B1.tpe + matchEnd setInfo MethodType(List(matchRes.symbol), B1.tpe) + cases foreach (c => c.symbol setInfo MethodType(List(), B1.tpe)) + + wrap(Block(prologue ++ casesNewSynthCatchAll, matchEndDef)) + } + } + + withDefaultTransformer(substParam(fun.body)) } body.changeOwner(fun.symbol -> methSym) @@ -294,30 +330,115 @@ abstract class UnCurry extends InfoTransform methDef } - // duplicate before applyOrElseMethodDef is run so we start with the same symbols as applyOrElseMethodDef + // duplicate before applyOrElseMethodDef is run so that it does not mess up our trees and label symbols (we have a fresh set) // otherwise `TreeSymSubstituter(fun.vparams map (_.symbol), params)` won't work as the subst has been run already - val bodyForIDA = fun.body.duplicate + val bodyForIDA = { + val duped = fun.body.duplicate + val oldParams = new mutable.ListBuffer[Symbol]() + val newParams = new mutable.ListBuffer[Symbol]() + + val oldSyms0 = + duped filter { + case l@LabelDef(_, params, _) => + params foreach {p => + val oldSym = p.symbol + p.symbol = oldSym.cloneSymbol + oldParams += oldSym + newParams += p.symbol + } + true + case _ => false + } map (_.symbol) + val oldSyms = oldParams.toList ++ oldSyms0 + val newSyms = newParams.toList ++ (oldSyms0 map (_.cloneSymbol)) + // println("duping "+ oldSyms +" --> "+ (newSyms map (_.ownerChain))) + + val substLabels = new TreeSymSubstituter(oldSyms, newSyms) + + substLabels(duped) + } + def isDefinedAtMethodDef = { val methSym = anonClass.newMethod(nme.isDefinedAt, fun.pos, FINAL) val params = methSym newSyntheticValueParams formals methSym setInfoAndEnter MethodType(params, BooleanClass.tpe) val substParam = new TreeSymSubstituter(fun.vparams map (_.symbol), params) - def doSubst(x: Tree) = substParam(resetLocalAttrs(x)) // see pos/t1761 for why `resetLocalAttrs` + def doSubst(x: Tree) = substParam(resetLocalAttrsKeepLabels(x)) // see pos/t1761 for why `resetLocalAttrs`, but must keep label symbols around + object isDefinedAtTransformer extends gen.MatchMatcher { // TODO: optimize duplication, but make sure ValDef's introduced by wrap are treated correctly override def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = { import CODE._ - gen.mkUncheckedMatch( - if (cases exists treeInfo.isDefaultCase) TRUE_typed + val casesNoSynthCatchAll = dropSyntheticCatchAll(cases) + if (casesNoSynthCatchAll exists treeInfo.isDefaultCase) TRUE_typed else doSubst(wrap( - Match(selector, - (cases map (c => deriveCaseDef(c)(x => TRUE_typed))) :+ ( + Match(/*gen.mkUnchecked*/(selector), + (casesNoSynthCatchAll map (c => deriveCaseDef(c)(x => TRUE_typed))) :+ ( DEFAULT ==> FALSE_typed) ))) - ) + } + override def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = { + object noOne extends Transformer { + override val treeCopy = newStrictTreeCopier // must duplicate everything + val one = _match.tpe member newTermName("one") + override def transform(tree: Tree): Tree = tree match { + case Apply(fun, List(a)) if fun.symbol == one => + // blow one's argument away since all we want to know is whether the match succeeds or not + // (the alternative, making `one` CBN, would entail moving away from Option) + Apply(fun.duplicate, List(gen.mkZeroContravariantAfterTyper(a.tpe))) + case _ => + super.transform(tree) + } + } + doSubst(Apply(Apply(TypeApply(Select(_match.duplicate, _match.tpe.member(newTermName("isSuccess"))), targs map (_.duplicate)), List(scrut.duplicate)), List(noOne.transform(matcher)))) + } + + override def caseVirtualizedMatchOpt(orig: Tree, prologue: List[Tree], cases: List[Tree], matchEndDef: Tree, wrap: Tree => Tree) = { + val matchEnd = matchEndDef.symbol + val LabelDef(_, List(matchRes), rhs) = matchEndDef + matchRes setType BooleanClass.tpe + rhs setType BooleanClass.tpe + matchEndDef setType BooleanClass.tpe + matchRes.symbol setInfo BooleanClass.tpe + matchEnd setInfo MethodType(List(matchRes.symbol), BooleanClass.tpe) + cases foreach (c => c.symbol setInfo MethodType(List(), BooleanClass.tpe)) + // println("matchEnd: "+ matchEnd) + + // when the type of the selector contains a skolem owned by the applyOrElseMethod, should reskolemize everything, + // for now, just cast the RHS (since we're just trying to keep the typer happy, the cast is meaningless) + // ARGH -- this is why I would prefer the typedMatchAnonFun approach (but alas, CPS blocks that) + val newPrologue = prologue match { + case List(vd@ValDef(mods, name, tpt, rhs)) => List(treeCopy.ValDef(vd, mods, name, tpt, gen.mkAsInstanceOf(rhs, tpt.tpe, true, false))) + case _ => prologue + } + object casesReturnTrue extends Transformer { + // override val treeCopy = newStrictTreeCopier // will duplicate below + override def transform(tree: Tree): Tree = tree match { + // don't compute the result of the match, return true instead + case Apply(fun, List(res)) if fun.symbol eq matchEnd => + // println("matchend call "+ fun.symbol) + Apply(fun, List(TRUE_typed)) setType BooleanClass.tpe + case _ => super.transform(tree) + } + } + val newCatchAll = cases.last match { + case LabelDef(n, ps, Apply(matchEnd1, List(Throw(Apply(Select(New(exTpt), nme.CONSTRUCTOR), _))))) if exTpt.tpe.typeSymbol eq MatchErrorClass => + assert(matchEnd1.symbol == matchEnd, "matchEnd discrepancy "+(matchEnd, matchEndDef)) + List(treeCopy.LabelDef(cases.last, n, ps, matchEnd APPLY (FALSE_typed)) setSymbol cases.last.symbol) + case x => Nil + } + val casesWithoutCatchAll = if(newCatchAll.isEmpty) cases else cases.init + doSubst(wrap(Block(newPrologue ++ casesReturnTrue.transformTrees(casesWithoutCatchAll) ++ newCatchAll, matchEndDef))) + + // val duped = idaBlock //.duplicate // TODO: duplication of labeldefs is BROKEN + // duped foreach { + // case l@LabelDef(name, params, rhs) if gen.hasSynthCaseSymbol(l) => println("newInfo"+ l.symbol.info) + // case _ => + // } } } + val body = isDefinedAtTransformer(bodyForIDA) body.changeOwner(fun.symbol -> methSym) @@ -328,11 +449,14 @@ abstract class UnCurry extends InfoTransform if (isPartial) List(applyOrElseMethodDef, isDefinedAtMethodDef) else List(applyMethodDef) - localTyper.typedPos(fun.pos) { + // println("MEMBERS "+ members) + val res = localTyper.typedPos(fun.pos) { Block( List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, fun.pos)), Typed(New(anonClass.tpe), TypeTree(fun.tpe))) } + // println("MEMBERS TYPED "+ members) + res } def transformArgs(pos: Position, fun: Symbol, args: List[Tree], formals: List[Type]) = { diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index e8e65071af..313818a9d4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -1650,7 +1650,11 @@ class Foo(x: Other) { x._1 } // no error in this order def catchAll = matchFailGen map { matchFailGen => val scrutRef = if(scrutSym ne NoSymbol) REF(scrutSym) else EmptyTree // for alternatives - LabelDef(nextCase, Nil, matchEnd APPLY (_asInstanceOf(matchFailGen(scrutRef), restpe))) // need to jump to matchEnd with result generated by matchFailGen (could be `FALSE` for isDefinedAt) + // must jump to matchEnd, use result generated by matchFailGen (could be `FALSE` for isDefinedAt) + LabelDef(nextCase, Nil, matchEnd APPLY (matchFailGen(scrutRef))) + // don't cast the arg to matchEnd when using PartialFun synth in uncurry, since it won't detect the throw (see gen.withDefaultCase) + // the cast is necessary when using typedMatchAnonFun-style PartialFun synth: + // (_asInstanceOf(matchFailGen(scrutRef), restpe)) } toList // catchAll.isEmpty iff no synthetic default case needed (the (last) user-defined case is a default) // if the last user-defined case is a default, it will never jump to the next case; it will go immediately to matchEnd diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index a6893ff4b2..c4eb43c427 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2193,7 +2193,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def adaptCase(cdef: CaseDef, mode: Int, tpe: Type): CaseDef = deriveCaseDef(cdef)(adapt(_, mode, tpe)) - def prepareTranslateMatch(selector0: Tree, cases: List[CaseDef], mode: Int, resTp: Type) = { + def typedMatch(selector0: Tree, cases: List[CaseDef], mode: Int, resTp: Type) = { val (selector, doTranslation) = selector0 match { case Annotated(Ident(nme.synthSwitch), selector) => (selector, false) case s => (s, true) @@ -2210,7 +2210,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { (selector1, selectorTp, casesAdapted, ownType, doTranslation) } - def translateMatch(selector1: Tree, selectorTp: Type, casesAdapted: List[CaseDef], ownType: Type, doTranslation: Boolean, matchFailGen: Option[Tree => Tree] = None) = { + def translatedMatch(selector1: Tree, selectorTp: Type, casesAdapted: List[CaseDef], ownType: Type, doTranslation: Boolean, matchFailGen: Option[Tree => Tree] = None) = { def repeatedToSeq(tp: Type): Type = (tp baseType RepeatedParamClass) match { case TypeRef(_, RepeatedParamClass, arg :: Nil) => seqType(arg) case _ => tp @@ -2220,7 +2220,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { Match(selector1, casesAdapted) setType ownType // setType of the Match to avoid recursing endlessly } else { val scrutType = repeatedToSeq(elimAnonymousClass(selectorTp)) - // we've packed the type for each case in prepareTranslateMatch so that if all cases have the same existential case, we get a clean lub + // we've packed the type for each case in typedMatch so that if all cases have the same existential case, we get a clean lub // here, we should open up the existential again // relevant test cases: pos/existentials-harmful.scala, pos/gadt-gilles.scala, pos/t2683.scala, pos/virtpatmat_exist4.scala MatchTranslator(this).translateMatch(selector1, casesAdapted, repeatedToSeq(ownType.skolemizeExistential(context.owner, context.tree)), scrutType, matchFailGen) @@ -2283,7 +2283,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it) paramSyms foreach (methodBodyTyper.context.scope enter _) - val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.prepareTranslateMatch(selector, cases, mode, ptRes) + val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.typedMatch(selector, cases, mode, ptRes) val methFormals = paramSyms map (_.tpe) val parents = List(abstractFunctionType(methFormals, resTp), SerializableClass.tpe) @@ -2291,7 +2291,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { anonClass setInfo ClassInfoType(parents, newScope, anonClass) methodSym setInfoAndEnter MethodType(paramSyms, resTp) - DefDef(methodSym, methodBodyTyper.translateMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation)) + DefDef(methodSym, methodBodyTyper.translatedMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation)) } } @@ -2321,7 +2321,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it) paramSyms foreach (methodBodyTyper.context.scope enter _) - val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.prepareTranslateMatch(selector, cases, mode, ptRes) + val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.typedMatch(selector, cases, mode, ptRes) anonClass setInfo ClassInfoType(parents(List(argTp, resTp)), newScope, anonClass) B1 setInfo TypeBounds.lower(resTp) @@ -2330,7 +2330,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // use applyOrElse's first parameter since the scrut's type has been widened def doDefault(scrut_ignored: Tree) = REF(default) APPLY (REF(x)) - val body = methodBodyTyper.translateMatch(selector1, selectorTp, casesAdapted, B1.tpe, doTranslation, Some(doDefault)) + val body = methodBodyTyper.translatedMatch(selector1, selectorTp, casesAdapted, B1.tpe, doTranslation, Some(doDefault)) DefDef(methodSym, body) } @@ -2345,8 +2345,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { paramSyms foreach (methodBodyTyper.context.scope enter _) methodSym setInfoAndEnter MethodType(paramSyms, BooleanClass.tpe) - val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.prepareTranslateMatch(selector, casesTrue, mode, BooleanClass.tpe) - val body = methodBodyTyper.translateMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation, Some(scrutinee => FALSE_typed)) + val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.typedMatch(selector, casesTrue, mode, BooleanClass.tpe) + val body = methodBodyTyper.translatedMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation, Some(scrutinee => FALSE_typed)) DefDef(methodSym, body) } @@ -2407,29 +2407,21 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } } - fun.body match { - case Match(sel, cases) if opt.virtPatmat => - // go to outer context -- must discard the context that was created for the Function since we're discarding the function - // thus, its symbol, which serves as the current context.owner, is not the right owner - // you won't know you're using the wrong owner until lambda lift crashes (unless you know better than to use the wrong owner) - newTyper(context.outer).typedMatchAnonFun(fun, cases, mode, pt, Some((fun.vparams, sel))) - case _ => - val vparamSyms = fun.vparams map { vparam => - enterSym(context, vparam) - if (context.retyping) context.scope enter vparam.symbol - vparam.symbol - } - val vparams = fun.vparams mapConserve (typedValDef) - // for (vparam <- vparams) { - // checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); () - // } - val formals = vparamSyms map (_.tpe) - val body1 = typed(fun.body, respt) - val restpe = packedType(body1, fun.symbol).deconst.resultType - val funtpe = typeRef(clazz.tpe.prefix, clazz, formals :+ restpe) - // body = checkNoEscaping.locals(context.scope, restpe, body) - treeCopy.Function(fun, vparams, body1).setType(funtpe) + val vparamSyms = fun.vparams map { vparam => + enterSym(context, vparam) + if (context.retyping) context.scope enter vparam.symbol + vparam.symbol } + val vparams = fun.vparams mapConserve (typedValDef) +// for (vparam <- vparams) { +// checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); () +// } + val formals = vparamSyms map (_.tpe) + val body1 = typed(fun.body, respt) + val restpe = packedType(body1, fun.symbol).deconst.resultType + val funtpe = typeRef(clazz.tpe.prefix, clazz, formals :+ restpe) +// body = checkNoEscaping.locals(context.scope, restpe, body) + treeCopy.Function(fun, vparams, body1).setType(funtpe) } } @@ -3797,13 +3789,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } } - def typedMatch(tree: Tree, selector: Tree, cases: List[CaseDef]): Tree = { - if (opt.virtPatmat && !isPastTyper) { - if (selector ne EmptyTree) { - val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = prepareTranslateMatch(selector, cases, mode, pt) - typed(translateMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt) - } else typedMatchAnonFun(tree, cases, mode, pt) - } else if (selector == EmptyTree) { + // translation only happens when (selector != EmptyTree) && !isPastTyper && opt.virtPatmat + def typedTranslatedMatch(tree: Tree, selector: Tree, cases: List[CaseDef]): Tree = { + if (selector == EmptyTree) { val arity = if (isFunctionType(pt)) pt.normalize.typeArgs.length - 1 else 1 val params = for (i <- List.range(0, arity)) yield atPos(tree.pos.focusStart) { @@ -3814,7 +3802,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val selector1 = atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) } val body = treeCopy.Match(tree, selector1, cases) typed1(atPos(tree.pos) { Function(params, body) }, mode, pt) - } else { + } else if (!opt.virtPatmat || isPastTyper) { val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType)) var cases1 = typedCases(cases, packCaptured(selector1.tpe.widen), pt) val (owntype, needAdapt) = ptOrLub(cases1 map (_.tpe)) @@ -3822,6 +3810,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { cases1 = cases1 map (adaptCase(_, mode, owntype)) } treeCopy.Match(tree, selector1, cases1) setType owntype + } else { + val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = typedMatch(selector, cases, mode, pt) + typed(translatedMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt) } } @@ -4681,7 +4672,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { typedIf(cond, thenp, elsep) case tree @ Match(selector, cases) => - typedMatch(tree, selector, cases) + typedTranslatedMatch(tree, selector, cases) case Return(expr) => typedReturn(expr) diff --git a/test/files/pos/virtpatmat_exist_uncurry.scala b/test/files/pos/virtpatmat_exist_uncurry.scala new file mode 100644 index 0000000000..e017da6343 --- /dev/null +++ b/test/files/pos/virtpatmat_exist_uncurry.scala @@ -0,0 +1,6 @@ +object Test { + trait Leaf[T] { + def collect[U](f: PartialFunction[Leaf[_], U]): List[U] + def leaves: List[Leaf[T]] = collect { case l: Leaf[T] => l } + } +} \ No newline at end of file -- cgit v1.2.3 From 3515ac4449c72992be411e1e0579d76189dc7bf1 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 13 Apr 2012 18:52:12 +0200 Subject: more prudent bridging to unapply[Seq] since we can't statically know whether the unapply we'll be bridging to is synthetic, drop this condition, and do pessimistic bridging for all unapply[Seq] (i.e., if we can't statically guarantee the type that would be assumed to be safe to cast to by a synthetic extractor, do the type test and return None if it fails) --- .../scala/tools/nsc/transform/Erasure.scala | 9 ++-- test/files/run/patmat_unapp_abstype.check | 2 + test/files/run/patmat_unapp_abstype.scala | 49 +++++++++++++++++++--- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index bdf2f2883f..5e61359a25 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -480,11 +480,10 @@ abstract class Erasure extends AddInterfaces // TODO: should we do this for user-defined unapplies as well? // does the first argument list have exactly one argument -- for user-defined unapplies we can't be sure def maybeWrap(bridgingCall: Tree): Tree = { - val canReturnNone = afterErasure( - member.isSynthetic - && (member.name == nme.unapply || member.name == nme.unapplySeq) - && !(member.tpe <:< other.tpe) // no static guarantees (TODO: is the subtype test ever true?) - ) + val canReturnNone = ( // can't statically know which member is going to be selected, so don't let this depend on member.isSynthetic + (member.name == nme.unapply || member.name == nme.unapplySeq) + && !afterErasure((member.tpe <:< other.tpe))) // no static guarantees (TODO: is the subtype test ever true?) + if (canReturnNone) { import CODE._ val typeTest = gen.mkIsInstanceOf(REF(bridge.firstParam), member.tpe.params.head.tpe) diff --git a/test/files/run/patmat_unapp_abstype.check b/test/files/run/patmat_unapp_abstype.check index ac28ccdb95..72239d16cd 100644 --- a/test/files/run/patmat_unapp_abstype.check +++ b/test/files/run/patmat_unapp_abstype.check @@ -1,2 +1,4 @@ TypeRef none of the above +Bar +Foo diff --git a/test/files/run/patmat_unapp_abstype.scala b/test/files/run/patmat_unapp_abstype.scala index e5adec5c16..fb0b491d39 100644 --- a/test/files/run/patmat_unapp_abstype.scala +++ b/test/files/run/patmat_unapp_abstype.scala @@ -32,8 +32,47 @@ trait TypesImpl extends TypesAPI { //lazy val typeRefMani = manifest[TypeRef] } -object Test extends TypesImpl with TypesUser with App { - shouldNotCrash(TypeRef(10)) // should and does print "TypeRef" - // once #1697/#2337 are fixed, this should generate the correct output - shouldNotCrash(MethodType(10)) // should print "MethodType" but prints "none of the above" -- good one, pattern matcher! -} \ No newline at end of file +trait Foos { + trait Bar + type Foo <: Bar + trait FooExtractor { + def unapply(foo: Foo): Option[Int] + } + val Foo: FooExtractor +} + +trait RealFoos extends Foos { + class Foo(val x: Int) extends Bar + object Foo extends FooExtractor { + def unapply(foo: Foo): Option[Int] = Some(foo.x) + } +} + +trait Intermed extends Foos { + def crash(bar: Bar): Unit = + bar match { + case Foo(x) => println("Foo") + case _ => println("Bar") + } +} + +object TestUnappStaticallyKnownSynthetic extends TypesImpl with TypesUser { + def test() = { + shouldNotCrash(TypeRef(10)) // should and does print "TypeRef" + // once #1697/#2337 are fixed, this should generate the correct output + shouldNotCrash(MethodType(10)) // should print "MethodType" but prints "none of the above" -- good one, pattern matcher! + } +} + +object TestUnappDynamicSynth extends RealFoos with Intermed { + case class FooToo(n: Int) extends Bar + def test() = { + crash(FooToo(10)) + crash(new Foo(5)) + } +} + +object Test extends App { + TestUnappStaticallyKnownSynthetic.test() + TestUnappDynamicSynth.test() +} -- cgit v1.2.3 From e1c8e2da26831c9a2d123bed5cb0f53230a3f939 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 13 Apr 2012 17:32:38 +0200 Subject: wip: put skeleton for typetag-based typetests in place --- .../scala/tools/nsc/typechecker/Infer.scala | 44 ++++++++++++++++++++++ .../tools/nsc/typechecker/PatMatVirtualiser.scala | 36 ++++++++++++++---- test/files/run/patmat_unapp_abstype.scala | 5 +++ 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index d78fd35d25..fb0616c890 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1189,6 +1189,50 @@ trait Infer { } } + /** Does `tp` contain any types that cannot be checked at run-time (i.e., after erasure, will isInstanceOf[erased(tp)] imply conceptualIsInstanceOf[tp]?) + * we should find a way to ask erasure: hey, is `tp` going to make it through you with all of its isInstanceOf resolving powers intact? + * TODO: at the very least, reduce duplication wrt checkCheckable + */ + def containsUnchecked(tp: Type): Boolean = { + def check(tp: Type, bound: List[Symbol]): Boolean = { + def isSurroundingTypeParam(sym: Symbol) = { + val e = context.scope.lookupEntry(sym.name) + ( (e ne null) + && (e.sym == sym ) + && !e.sym.isTypeParameterOrSkolem + && (e.owner == context.scope) + ) + } + def isLocalBinding(sym: Symbol) = ( + sym.isAbstractType && ( + (bound contains sym) + || (sym.name == tpnme.WILDCARD) + || isSurroundingTypeParam(sym) + ) + ) + tp.normalize match { + case SingleType(pre, _) => + check(pre, bound) + case TypeRef(_, ArrayClass, arg :: _) => + check(arg, bound) + case tp @ TypeRef(pre, sym, args) => + ( (sym.isAbstractType && !isLocalBinding(sym)) + || (args exists (x => !isLocalBinding(x.typeSymbol))) + || check(pre, bound) + ) + // case RefinedType(_, decls) if decls.nonEmpty => + // patternWarning(tp, "refinement ") + case RefinedType(parents, _) => + parents exists (p => check(p, bound)) + case ExistentialType(quantified, tp1) => + check(tp1, bound ::: quantified) + case _ => + false + } + } + check(tp, Nil) + } + def checkCheckable(tree: Tree, tp: Type, kind: String) { def patternWarning(tp0: Type, prefix: String) = { context.unit.uncheckedWarning(tree.pos, prefix+tp0+" in type "+kind+tp+" is unchecked since it is eliminated by erasure") diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 313818a9d4..9b50853c51 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -22,7 +22,7 @@ import language.postfixOps * - Array patterns * - implement spec more closely (see TODO's) * - DCE - * - use manifests for type testing + * - use TypeTags for type testing * * (longer-term) TODO: * - user-defined unapplyProd @@ -119,6 +119,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer => trait MatchTranslation extends MatchMonadInterface { self: TreeMakers with CodegenCore => import typer.{typed, context, silent, reallyExists} + // import typer.infer.containsUnchecked /** Implement a pattern match by turning its cases (including the implicit failure case) * into the corresponding (monadic) extractors, and combining them with the `orElse` combinator. @@ -820,13 +821,34 @@ class Foo(x: Other) { x._1 } // no error in this order cond } - // TODO: also need to test when erasing pt loses crucial information (and if we can recover it using a manifest) - def needsTypeTest(tp: Type, pt: Type) = !(tp <:< pt) - private def typeTest(binder: Symbol, pt: Type) = maybeWithOuterCheck(binder, pt)(codegen._isInstanceOf(binder, pt)) + // containsUnchecked: also need to test when erasing pt loses crucial information (maybe we can recover it using a TypeTag) + def needsTypeTest(tp: Type, pt: Type): Boolean = !(tp <:< pt) // || containsUnchecked(pt) + // TODO: try to find the TypeTag for the binder's type and the expected type, and if they exists, + // check that the TypeTag of the binder's type conforms to the TypeTag of the expected type + private def typeTest(binderToTest: Symbol, expectedTp: Type, disableOuterCheck: Boolean = false, dynamic: Boolean = false): Tree = { import CODE._ + // def coreTest = + if (disableOuterCheck) codegen._isInstanceOf(binderToTest, expectedTp) else maybeWithOuterCheck(binderToTest, expectedTp)(codegen._isInstanceOf(binderToTest, expectedTp)) + // if (opt.experimental && containsUnchecked(expectedTp)) { + // if (dynamic) { + // val expectedTpTagTree = findManifest(expectedTp, true) + // if (!expectedTpTagTree.isEmpty) + // ((expectedTpTagTree DOT "erasure".toTermName) DOT "isAssignableFrom".toTermName)(REF(binderToTest) DOT nme.getClass_) + // else + // coreTest + // } else { + // val expectedTpTagTree = findManifest(expectedTp, true) + // val binderTpTagTree = findManifest(binderToTest.info, true) + // if(!(expectedTpTagTree.isEmpty || binderTpTagTree.isEmpty)) + // coreTest AND (binderTpTagTree DOT nme.CONFORMS)(expectedTpTagTree) + // else + // coreTest + // } + // } else coreTest + } // need to substitute since binder may be used outside of the next extractor call (say, in the body of the case) case class TypeTestTreeMaker(prevBinder: Symbol, nextBinderTp: Type, pos: Position) extends CondTreeMaker { - val cond = typeTest(prevBinder, nextBinderTp) + val cond = typeTest(prevBinder, nextBinderTp, dynamic = true) val res = codegen._asInstanceOf(prevBinder, nextBinderTp) override def toString = "TT"+(prevBinder, nextBinderTp) } @@ -866,7 +888,7 @@ class Foo(x: Other) { x._1 } // no error in this order // TODO: `null match { x : T }` will yield a check that (indirectly) tests whether `null ne null` // don't bother (so that we don't end up with the warning "comparing values of types Null and Null using `ne' will always yield false") def genEqualsAndInstanceOf(sym: Symbol): Tree - = codegen._equals(REF(sym), patBinder) AND codegen._isInstanceOf(patBinder, pt.widen) + = codegen._equals(REF(sym), patBinder) AND typeTest(patBinder, pt.widen, disableOuterCheck = true) def isRefTp(tp: Type) = tp <:< AnyRefClass.tpe @@ -874,7 +896,7 @@ class Foo(x: Other) { x._1 } // no error in this order def isMatchUnlessNull = isRefTp(pt) && !needsTypeTest(patBinderTp, pt) // TODO: [SPEC] type test for Array - // TODO: use manifests to improve tests (for erased types we can do better when we have a manifest) + // TODO: use TypeTags to improve tests (for erased types we can do better when we have a TypeTag) pt match { case SingleType(_, sym) /*this implies sym.isStable*/ => genEqualsAndInstanceOf(sym) // TODO: [SPEC] the spec requires `eq` instead of `==` here case ThisType(sym) if sym.isModule => genEqualsAndInstanceOf(sym) // must use == to support e.g. List() == Nil diff --git a/test/files/run/patmat_unapp_abstype.scala b/test/files/run/patmat_unapp_abstype.scala index fb0b491d39..45496f08a2 100644 --- a/test/files/run/patmat_unapp_abstype.scala +++ b/test/files/run/patmat_unapp_abstype.scala @@ -19,6 +19,11 @@ trait TypesUser extends TypesAPI { def shouldNotCrash(tp: Type): Unit = { tp match { case TypeRef(x) => println("TypeRef") + // the above checks tp.isInstanceOf[TypeRef], which is erased to tp.isInstanceOf[Type] + // before calling TypeRef.unapply(tp), which will then crash unless tp.isInstanceOf[TypesImpl#TypeRef] (which is not implied by tp.isInstanceOf[Type]) + // tp.isInstanceOf[TypesImpl#TypeRef] is equivalent to classOf[TypesImpl#TypeRef].isAssignableFrom(tp.getClass) + // this is equivalent to manifest + // it is NOT equivalent to manifest[Type] <:< typeRefMani case MethodType(x) => println("MethodType") case _ => println("none of the above") } -- cgit v1.2.3 From 391f92f4005700799ac2e775980f5c5a77fea203 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 13 Apr 2012 19:15:35 +0200 Subject: virtpatmat: initial CPS support typers&patmatvirtualizer have ad-hoc support for dropping annotations in a way that makes the CPS plugins happy... this is not ideal, but unless virtpatmat runs after the plugin phases, I don't see how to solve it running virtpatmat after the CPS plugin would mean the pattern matching evaluation cannot be captured by CPS, so it's not even desirable to move it to a later phase - typedIf must lub annotated types - drop selector.tpe's annotations - drop annots in matchEnd's argument type - deal with annots in casts synth by in virtpatmat (drop them from type arg to asInstanceof, recover them using type ascription) - workaround skolemize existential dropping annots CPS is the main reason why typedMatchAnonFun is not used anymore, and PartialFunction synthesis is moved back to uncurry (which is quite painful due to labeldefs being so broken) we can't synth partialfunction during typer since T @cps[U] does not conform to Any, so we can't pass it as a type arg to PartialFunction, so we can't type a cps-transformed PF after the CPS plugin, T @cps[U] becomes ControlContext[...], which is a type we can pass to PartialFunction virtpatmat is now also run until right before uncurry (so, can't use isPastTyper, although it means more or less the same thing -- we don't run after uncurry) the main functional improvements are in the selective ANF transform its treatment of labeldefs was broken: for example, LabelDef L1; LabelDef L2 --> DefDef L1; L1(); DefDef L2; L2() but this does not take into account L1 may jump over L2 to another label since methods always return (or fail), and the ANF transform generates ValDefs to store the result of those method calls, both L1 and L2 would always be executed (so you would run a match with N cases N times, with each partial run starting at a later case) also fixed a couple of weird bugs in selective anf that caused matches to be duplicated (with the duplicate being nested in the original) since label defs are turned into method defs, and later defs will be nested in the flatMap calls on the controlcontext yielded by earlier statements, we reverse the list of method definitions, so that earlier (in the control flow sense) methods are visible in later ones selective CPS now generates a catch that's directly digestible by backend --- .../tools/nsc/typechecker/PatMatVirtualiser.scala | 28 ++-- .../scala/tools/nsc/typechecker/Typers.scala | 16 +- .../tools/selectivecps/SelectiveANFTransform.scala | 168 +++++++++++++-------- .../tools/selectivecps/SelectiveCPSTransform.scala | 16 +- test/files/continuations-run/match2.scala | 2 +- 5 files changed, 137 insertions(+), 93 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 9b50853c51..1fd9f6fc13 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -132,10 +132,10 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer => * this could probably optimized... (but note that the matchStrategy must be solved for each nested patternmatch) */ def translateMatch(scrut: Tree, cases: List[CaseDef], pt: Type, scrutType: Type, matchFailGenOverride: Option[Tree => Tree] = None): Tree = { - // we don't transform after typers - // (that would require much more sophistication when generating trees, + // we don't transform after uncurry + // (that would require more sophistication when generating trees, // and the only place that emits Matches after typers is for exception handling anyway) - assert(phase.id <= currentRun.typerPhase.id, phase) + assert(phase.id < currentRun.uncurryPhase.id, phase) val scrutSym = freshSym(scrut.pos, pureType(scrutType)) setFlag SYNTH_CASE // pt = Any* occurs when compiling test/files/pos/annotDepMethType.scala with -Xexperimental @@ -1105,22 +1105,14 @@ class Foo(x: Other) { x._1 } // no error in this order def _equals(checker: Tree, binder: Symbol): Tree = checker MEMBER_== REF(binder) // NOTE: checker must be the target of the ==, that's the patmat semantics for ya def and(a: Tree, b: Tree): Tree = a AND b + // drop annotations generated by CPS plugin etc, since its annotationchecker rejects T @cps[U] <: Any + // let's assume for now annotations don't affect casts, drop them there, and bring them back using the outer Typed tree + private def mkCast(t: Tree, tp: Type) = Typed(gen.mkAsInstanceOf(t, tp.withoutAnnotations, true, false), TypeTree() setType tp) // the force is needed mainly to deal with the GADT typing hack (we can't detect it otherwise as tp nor pt need contain an abstract type, we're just casting wildly) - def _asInstanceOf(t: Tree, tp: Type, force: Boolean = false): Tree = { val tpX = /*repackExistential*/(tp) - if (!force && (t.tpe ne NoType) && t.isTyped && typesConform(t.tpe, tpX)) t //{ println("warning: emitted redundant asInstanceOf: "+(t, t.tpe, tp)); t } //.setType(tpX) - else gen.mkAsInstanceOf(t, tpX, true, false) - } - - def _isInstanceOf(b: Symbol, tp: Type): Tree = gen.mkIsInstanceOf(REF(b), /*repackExistential*/(tp), true, false) - // { val tpX = /*repackExistential*/(tp) + def _asInstanceOf(t: Tree, tp: Type, force: Boolean = false): Tree = if (!force && (t.tpe ne NoType) && t.isTyped && typesConform(t.tpe, tp)) t else mkCast(t, tp) + def _asInstanceOf(b: Symbol, tp: Type): Tree = if (typesConform(b.info, tp)) REF(b) else mkCast(REF(b), tp) + def _isInstanceOf(b: Symbol, tp: Type): Tree = gen.mkIsInstanceOf(REF(b), tp.withoutAnnotations, true, false) // if (typesConform(b.info, tpX)) { println("warning: emitted spurious isInstanceOf: "+(b, tp)); TRUE } - // else gen.mkIsInstanceOf(REF(b), tpX, true, false) - // } - - def _asInstanceOf(b: Symbol, tp: Type): Tree = { val tpX = /*repackExistential*/(tp) - if (typesConform(b.info, tpX)) REF(b) //{ println("warning: emitted redundant asInstanceOf: "+(b, b.info, tp)); REF(b) } //.setType(tpX) - else gen.mkAsInstanceOf(REF(b), tpX, true, false) - } // duplicated out of frustration with cast generation def mkZero(tp: Type): Tree = { @@ -1658,7 +1650,7 @@ class Foo(x: Other) { x._1 } // no error in this order */ def matcher(scrut: Tree, scrutSym: Symbol, restpe: Type)(cases: List[Casegen => Tree], matchFailGen: Option[Tree => Tree]): Tree = { val matchEnd = NoSymbol.newLabel(freshName("matchEnd"), NoPosition) setFlag SYNTH_CASE - val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, SYNTHETIC) setInfo restpe + val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, SYNTHETIC) setInfo restpe.withoutAnnotations // matchEnd setInfo MethodType(List(matchRes), restpe) def newCaseSym = NoSymbol.newLabel(freshName("case"), NoPosition) setInfo MethodType(Nil, restpe) setFlag SYNTH_CASE diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index c4eb43c427..dd8631ba21 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2199,7 +2199,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case s => (s, true) } val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType)) - val selectorTp = packCaptured(selector1.tpe.widen) + val selectorTp = packCaptured(selector1.tpe.widen.withoutAnnotations) val casesTyped = typedCases(cases, selectorTp, resTp) val caseTypes = casesTyped map (c => packedType(c, context.owner).deconst) @@ -2223,7 +2223,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // we've packed the type for each case in typedMatch so that if all cases have the same existential case, we get a clean lub // here, we should open up the existential again // relevant test cases: pos/existentials-harmful.scala, pos/gadt-gilles.scala, pos/t2683.scala, pos/virtpatmat_exist4.scala - MatchTranslator(this).translateMatch(selector1, casesAdapted, repeatedToSeq(ownType.skolemizeExistential(context.owner, context.tree)), scrutType, matchFailGen) + // TODO: fix skolemizeExistential (it should preserve annotations, right?) + val ownTypeSkolemized = ownType.skolemizeExistential(context.owner, context.tree) withAnnotations ownType.annotations + MatchTranslator(this).translateMatch(selector1, casesAdapted, repeatedToSeq(ownTypeSkolemized), scrutType, matchFailGen) } } @@ -3772,12 +3774,16 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { lazy val thenTp = packedType(thenp1, context.owner) lazy val elseTp = packedType(elsep1, context.owner) + // println("typedIf: "+(thenp1.tpe, elsep1.tpe, ptOrLub(List(thenp1.tpe, elsep1.tpe)),"\n", thenTp, elseTp, thenTp =:= elseTp)) val (owntype, needAdapt) = // in principle we should pack the types of each branch before lubbing, but lub doesn't really work for existentials anyway // in the special (though common) case where the types are equal, it pays to pack before comparing // especially virtpatmat needs more aggressive unification of skolemized types // this breaks src/library/scala/collection/immutable/TrieIterator.scala - if (opt.virtPatmat && !isPastTyper && thenTp =:= elseTp) (thenp1.tpe, false) // use unpacked type + if ( opt.virtPatmat && !isPastTyper + && thenp1.tpe.annotations.isEmpty && elsep1.tpe.annotations.isEmpty // annotated types need to be lubbed regardless (at least, continations break if you by pass them like this) + && thenTp =:= elseTp + ) (thenp1.tpe, false) // use unpacked type // TODO: skolemize (lub of packed types) when that no longer crashes on files/pos/t4070b.scala else ptOrLub(List(thenp1.tpe, elsep1.tpe)) @@ -3802,7 +3808,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val selector1 = atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) } val body = treeCopy.Match(tree, selector1, cases) typed1(atPos(tree.pos) { Function(params, body) }, mode, pt) - } else if (!opt.virtPatmat || isPastTyper) { + } else if (!((phase.id < currentRun.uncurryPhase.id) && opt.virtPatmat)) { val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType)) var cases1 = typedCases(cases, packCaptured(selector1.tpe.widen), pt) val (owntype, needAdapt) = ptOrLub(cases1 map (_.tpe)) @@ -4688,7 +4694,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { catches1 = catches1 map (adaptCase(_, mode, owntype)) } - if(!isPastTyper && opt.virtPatmat) { + if((phase.id < currentRun.uncurryPhase.id) && opt.virtPatmat) { catches1 = (MatchTranslator(this)).translateTry(catches1, owntype, tree.pos) } diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala index a6737573ea..0975f16c6e 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala @@ -71,24 +71,46 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with // { x => x match { case A => ... }} to // { x => shiftUnit(x match { case A => ... })} // which Uncurry cannot handle (see function6.scala) + // thus, we push down the shiftUnit to each of the case bodies val ext = getExternalAnswerTypeAnn(body.tpe) + val pureBody = getAnswerTypeAnn(body.tpe).isEmpty + + def transformPureMatch(tree: Tree, selector: Tree, cases: List[CaseDef]) = { + val caseVals = cases map { case cd @ CaseDef(pat, guard, body) => + // if (!hasPlusMarker(body.tpe)) body.tpe = body.tpe withAnnotation newPlusMarker() // TODO: to avoid warning + val bodyVal = transExpr(body, None, ext) // ??? triggers "cps-transformed unexpectedly" warning in transTailValue + treeCopy.CaseDef(cd, transform(pat), transform(guard), bodyVal) + } + treeCopy.Match(tree, transform(selector), caseVals) + } + + def transformPureVirtMatch(body: Block, selDef: ValDef, cases: List[Tree], matchEnd: Tree) = { + val stats = transform(selDef) :: (cases map (transExpr(_, None, ext))) + treeCopy.Block(body, stats, transExpr(matchEnd, None, ext)) + } val body1 = body match { - case Match(selector, cases) if (ext.isDefined && getAnswerTypeAnn(body.tpe).isEmpty) => - val cases1 = for { - cd @ CaseDef(pat, guard, caseBody) <- cases - caseBody1 = transExpr(body, None, ext) - } yield { - treeCopy.CaseDef(cd, transform(pat), transform(guard), caseBody1) - } - treeCopy.Match(tree, transform(selector), cases1) + case Match(selector, cases) if ext.isDefined && pureBody => + transformPureMatch(body, selector, cases) + + // virtpatmat switch + case Block(List(selDef: ValDef), mat@Match(selector, cases)) if ext.isDefined && pureBody => + treeCopy.Block(body, List(transform(selDef)), transformPureMatch(mat, selector, cases)) + + // virtpatmat + case b@Block(matchStats@((selDef: ValDef) :: cases), matchEnd) if ext.isDefined && pureBody && (matchStats forall gen.hasSynthCaseSymbol) => + transformPureVirtMatch(b, selDef, cases, matchEnd) + + // virtpatmat that stores the scrut separately -- TODO: can we eliminate this case?? + case Block(List(selDef0: ValDef), mat@Block(matchStats@((selDef: ValDef) :: cases), matchEnd)) if ext.isDefined && pureBody && (matchStats forall gen.hasSynthCaseSymbol)=> + treeCopy.Block(body, List(transform(selDef0)), transformPureVirtMatch(mat, selDef, cases, matchEnd)) case _ => transExpr(body, None, ext) } - debuglog("result "+body1) + debuglog("anf result "+body1) debuglog("result is of type "+body1.tpe) treeCopy.Function(ff, transformValDefs(vparams), body1) @@ -170,63 +192,72 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with tree match { case Block(stms, expr) => val (cpsA2, cpsR2) = (cpsA, linearize(cpsA, getAnswerTypeAnn(tree.tpe))) // tbd -// val (cpsA2, cpsR2) = (None, getAnswerTypeAnn(tree.tpe)) - val (a, b) = transBlock(stms, expr, cpsA2, cpsR2) + // val (cpsA2, cpsR2) = (None, getAnswerTypeAnn(tree.tpe)) - val tree1 = (treeCopy.Block(tree, a, b)) // no updateSynthFlag here!!! + val (a, b) = transBlock(stms, expr, cpsA2, cpsR2) + val tree1 = (treeCopy.Block(tree, a, b)) // no updateSynthFlag here!!! (Nil, tree1, cpsA) - case If(cond, thenp, elsep) => - /* possible situations: - cps before (cpsA) - cps in condition (spc) <-- synth flag set if *only* here! - cps in (one or both) branches */ - val (condStats, condVal, spc) = transInlineValue(cond, cpsA) - val (cpsA2, cpsR2) = if (hasSynthMarker(tree.tpe)) - (spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) else - (None, getAnswerTypeAnn(tree.tpe)) // if no cps in condition, branches must conform to tree.tpe directly - val thenVal = transExpr(thenp, cpsA2, cpsR2) - val elseVal = transExpr(elsep, cpsA2, cpsR2) - - // check that then and else parts agree (not necessary any more, but left as sanity check) - if (cpsR.isDefined) { - if (elsep == EmptyTree) - unit.error(tree.pos, "always need else part in cps code") - } - if (hasAnswerTypeAnn(thenVal.tpe) != hasAnswerTypeAnn(elseVal.tpe)) { - unit.error(tree.pos, "then and else parts must both be cps code or neither of them") - } - - (condStats, updateSynthFlag(treeCopy.If(tree, condVal, thenVal, elseVal)), spc) + case If(cond, thenp, elsep) => + /* possible situations: + cps before (cpsA) + cps in condition (spc) <-- synth flag set if *only* here! + cps in (one or both) branches */ + val (condStats, condVal, spc) = transInlineValue(cond, cpsA) + val (cpsA2, cpsR2) = if (hasSynthMarker(tree.tpe)) + (spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) else + (None, getAnswerTypeAnn(tree.tpe)) // if no cps in condition, branches must conform to tree.tpe directly + val thenVal = transExpr(thenp, cpsA2, cpsR2) + val elseVal = transExpr(elsep, cpsA2, cpsR2) + + // check that then and else parts agree (not necessary any more, but left as sanity check) + if (cpsR.isDefined) { + if (elsep == EmptyTree) + unit.error(tree.pos, "always need else part in cps code") + } + if (hasAnswerTypeAnn(thenVal.tpe) != hasAnswerTypeAnn(elseVal.tpe)) { + unit.error(tree.pos, "then and else parts must both be cps code or neither of them") + } - case Match(selector, cases) => + (condStats, updateSynthFlag(treeCopy.If(tree, condVal, thenVal, elseVal)), spc) - val (selStats, selVal, spc) = transInlineValue(selector, cpsA) - val (cpsA2, cpsR2) = if (hasSynthMarker(tree.tpe)) - (spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) else - (None, getAnswerTypeAnn(tree.tpe)) + case Match(selector, cases) => + val (selStats, selVal, spc) = transInlineValue(selector, cpsA) + val (cpsA2, cpsR2) = + if (hasSynthMarker(tree.tpe)) (spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) + else (None, getAnswerTypeAnn(tree.tpe)) - val caseVals = for { - cd @ CaseDef(pat, guard, body) <- cases - bodyVal = transExpr(body, cpsA2, cpsR2) - } yield { - treeCopy.CaseDef(cd, transform(pat), transform(guard), bodyVal) - } + val caseVals = cases map { case cd @ CaseDef(pat, guard, body) => + val bodyVal = transExpr(body, cpsA2, cpsR2) + treeCopy.CaseDef(cd, transform(pat), transform(guard), bodyVal) + } - (selStats, updateSynthFlag(treeCopy.Match(tree, selVal, caseVals)), spc) + (selStats, updateSynthFlag(treeCopy.Match(tree, selVal, caseVals)), spc) + // this is utterly broken: LabelDefs need to be considered together when transforming them to DefDefs: + // suppose a Block {L1; ... ; LN} + // this should become {D1def ; ... ; DNdef ; D1()} + // where D$idef = def L$i(..) = {L$i.body; L${i+1}(..)} case ldef @ LabelDef(name, params, rhs) => if (hasAnswerTypeAnn(tree.tpe)) { - val sym = currentOwner.newMethod(name, tree.pos, Flags.SYNTHETIC) setInfo ldef.symbol.info - val rhs1 = new TreeSymSubstituter(List(ldef.symbol), List(sym)).transform(rhs) + // currentOwner.newMethod(name, tree.pos, Flags.SYNTHETIC) setInfo ldef.symbol.info + val sym = ldef.symbol resetFlag Flags.LABEL + val rhs1 = rhs //new TreeSymSubstituter(List(ldef.symbol), List(sym)).transform(rhs) val rhsVal = transExpr(rhs1, None, getAnswerTypeAnn(tree.tpe)) changeOwner (currentOwner -> sym) val stm1 = localTyper.typed(DefDef(sym, rhsVal)) - val expr = localTyper.typed(Apply(Ident(sym), List())) - - (List(stm1), expr, cpsA) + // since virtpatmat does not rely on fall-through, don't call the labels it emits + // transBlock will take care of calling the first label + // calling each labeldef is wrong, since some labels may be jumped over + // we can get away with this for now since the only other labels we emit are for tailcalls/while loops, + // which do not have consecutive labeldefs (and thus fall-through is irrelevant) + if (gen.hasSynthCaseSymbol(ldef)) (List(stm1), localTyper.typed{Literal(Constant(()))}, cpsA) + else { + assert(params.isEmpty, "problem in ANF transforming label with non-empty params "+ ldef) + (List(stm1), localTyper.typed{Apply(Ident(sym), List())}, cpsA) + } } else { val rhsVal = transExpr(rhs, None, None) (Nil, updateSynthFlag(treeCopy.LabelDef(tree, name, params, rhsVal)), cpsA) @@ -412,18 +443,29 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with } def transBlock(stms: List[Tree], expr: Tree, cpsA: CPSInfo, cpsR: CPSInfo): (List[Tree], Tree) = { - stms match { - case Nil => - transTailValue(expr, cpsA, cpsR) - - case stm::rest => - var (rest2, expr2) = (rest, expr) - val (headStms, headSpc) = transInlineStm(stm, cpsA) - val (restStms, restExpr) = transBlock(rest2, expr2, headSpc, cpsR) - (headStms:::restStms, restExpr) - } + def rec(currStats: List[Tree], currAns: CPSInfo, accum: List[Tree]): (List[Tree], Tree) = + currStats match { + case Nil => + val (anfStats, anfExpr) = transTailValue(expr, currAns, cpsR) + (accum ++ anfStats, anfExpr) + + case stat :: rest => + val (stats, nextAns) = transInlineStm(stat, currAns) + rec(rest, nextAns, accum ++ stats) + } + + val (anfStats, anfExpr) = rec(stms, cpsA, List()) + // println("\nanf-block:\n"+ ((stms :+ expr) mkString ("{", "\n", "}")) +"\nBECAME\n"+ ((anfStats :+ anfExpr) mkString ("{", "\n", "}"))) + + if (anfStats.nonEmpty && (anfStats forall gen.hasSynthCaseSymbol)) { + val (prologue, rest) = (anfStats :+ anfExpr) span (s => !s.isInstanceOf[DefDef]) // find first case + // val (defs, calls) = rest partition (_.isInstanceOf[DefDef]) + if (rest nonEmpty){ + val stats = prologue ++ rest.reverse // ++ calls + // println("REVERSED "+ (stats mkString ("{", "\n", "}"))) + (stats, localTyper.typed{Apply(Ident(rest.head.symbol), List())}) // call first label to kick-start the match + } else (anfStats, anfExpr) + } else (anfStats, anfExpr) } - - } } diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala index 6453671eac..2db4054ef5 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala @@ -15,7 +15,7 @@ import scala.tools.nsc.ast._ * In methods marked @cps, CPS-transform assignments introduced by ANF-transform phase. */ abstract class SelectiveCPSTransform extends PluginComponent with - InfoTransform with TypingTransformers with CPSUtils { + InfoTransform with TypingTransformers with CPSUtils with TreeDSL { // inherits abstract value `global` and class `Phase` from Transform import global._ // the global environment @@ -203,12 +203,16 @@ abstract class SelectiveCPSTransform extends PluginComponent with rhs.changeOwner(currentOwner -> fun.symbol) val exSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe) - val catch2 = { localTyper.typedCases(List( - CaseDef(Bind(exSym, Typed(Ident("_"), TypeTree(ThrowableClass.tpe))), - Apply(Select(Ident(funSym), nme.isDefinedAt), List(Ident(exSym))), - Apply(Ident(funSym), List(Ident(exSym)))) - ), ThrowableClass.tpe, targettp) } + import CODE._ + // generate a case that is supported directly by the back-end + val catchIfDefined = CaseDef( + Bind(exSym, Ident(nme.WILDCARD)), + EmptyTree, + IF ((REF(funSym) DOT nme.isDefinedAt)(REF(exSym))) THEN (REF(funSym) APPLY (REF(exSym))) ELSE Throw(REF(exSym)) + ) + + val catch2 = localTyper.typedCases(List(catchIfDefined), ThrowableClass.tpe, targettp) //typedCases(tree, catches, ThrowableClass.tpe, pt) localTyper.typed(Block(List(funDef), treeCopy.Try(tree, treeCopy.Block(block1, stms, expr2), catch2, finalizer1))) diff --git a/test/files/continuations-run/match2.scala b/test/files/continuations-run/match2.scala index 8b0fb946df..5092ce3abe 100644 --- a/test/files/continuations-run/match2.scala +++ b/test/files/continuations-run/match2.scala @@ -18,7 +18,7 @@ object Test { } - def main(args: Array[String]): Any = { + def main(args: Array[String]): Unit = { println(reset(test1())) println(reset(test2())) } -- cgit v1.2.3 From 4804efef205adbe359dd353d51ab16e1e0337dc5 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 13 Apr 2012 20:15:10 +0200 Subject: virtpatmat on by default; chicken out: -Xoldpatmat some tests (unreachability, exhaustivity, @switch annotation checking) are still run under -Xoldpatmat, but that will change before we go into RC mode (then the test/ partest of this commit will be reverted) removed irrelevant dependency on patmat --- src/compiler/scala/reflect/internal/Types.scala | 2 +- .../internal/settings/MutableSettings.scala | 2 +- src/compiler/scala/reflect/runtime/Settings.scala | 2 +- src/compiler/scala/tools/nsc/Global.scala | 2 +- .../nsc/interactive/tests/core/CoreTestDefs.scala | 2 +- .../tools/nsc/settings/AestheticSettings.scala | 2 +- .../scala/tools/nsc/settings/ScalaSettings.scala | 3 +- test/files/buildmanager/t2559/D.scala | 6 +- test/files/buildmanager/t2559/t2559.check | 5 - test/files/jvm/interpreter.scala | 2 +- test/files/neg/array-not-seq.check | 12 +- test/files/neg/exhausting.flags | 2 +- test/files/neg/gadts1.check | 5 +- test/files/neg/pat_unreachable.flags | 1 + test/files/neg/patmat-type-check.check | 14 +- test/files/neg/patmatexhaust.flags | 2 +- test/files/neg/sealed-java-enums.flags | 2 +- test/files/neg/switch.flags | 1 + test/files/neg/t0418.check | 5 +- test/files/neg/t112706A.check | 5 +- test/files/neg/t1878.check | 5 +- test/files/neg/t3098.flags | 2 +- test/files/neg/t3392.check | 5 +- test/files/neg/t3683a.flags | 2 +- test/files/neg/t3692.flags | 1 + test/files/neg/t418.check | 5 +- test/files/neg/t4425.check | 2 +- test/files/neg/t5589neg.check | 5 +- test/files/neg/tailrec.check | 6 +- test/files/neg/unreachablechar.flags | 1 + test/files/pos/t1439.flags | 2 +- test/files/pos/virtpatmat_alts_subst.flags | 2 +- test/files/pos/virtpatmat_anonfun_for.flags | 1 - test/files/pos/virtpatmat_binding_opt.flags | 2 +- test/files/pos/virtpatmat_castbinder.flags | 2 +- test/files/pos/virtpatmat_exist1.flags | 2 +- test/files/pos/virtpatmat_exist2.flags | 2 +- test/files/pos/virtpatmat_exist3.flags | 2 +- test/files/pos/virtpatmat_gadt_array.flags | 2 +- test/files/pos/virtpatmat_infer_single_1.flags | 2 +- test/files/pos/virtpatmat_instof_valuetype.flags | 2 +- test/files/pos/virtpatmat_obj_in_case.flags | 2 +- .../presentation/callcc-interpreter/Runner.scala | 4 +- test/files/presentation/random.check | 3 +- test/files/run/inline-ex-handlers.check | 261 +++++++++++---------- test/files/run/patmat_unapp_abstype.flags | 1 + test/files/run/reify_fors.flags | 1 + test/files/run/reify_maps.flags | 1 + test/files/run/repl-suppressed-warnings.scala | 1 + test/files/run/t5273_1.flags | 1 + test/files/run/t5273_2a.flags | 1 + test/files/run/t5273_2b.flags | 1 + test/files/run/virtpatmat_alts.flags | 2 +- test/files/run/virtpatmat_apply.flags | 2 +- test/files/run/virtpatmat_casting.flags | 2 +- test/files/run/virtpatmat_extends_product.flags | 2 +- test/files/run/virtpatmat_literal.flags | 2 +- test/files/run/virtpatmat_nested_lists.flags | 2 +- test/files/run/virtpatmat_npe.flags | 2 +- test/files/run/virtpatmat_opt_sharing.flags | 2 +- test/files/run/virtpatmat_partial.flags | 2 +- test/files/run/virtpatmat_staging.flags | 2 +- test/files/run/virtpatmat_switch.flags | 2 +- .../run/virtpatmat_tailcalls_verifyerror.flags | 2 +- test/files/run/virtpatmat_try.flags | 2 +- test/files/run/virtpatmat_typed.flags | 2 +- test/files/run/virtpatmat_unapply.flags | 2 +- test/files/run/virtpatmat_unapplyprod.flags | 2 +- test/files/run/virtpatmat_unapplyseq.flags | 2 +- test/files/specialized/spec-patmatch.check | 2 +- 70 files changed, 248 insertions(+), 197 deletions(-) create mode 100644 test/files/neg/pat_unreachable.flags create mode 100644 test/files/neg/switch.flags create mode 100644 test/files/neg/t3692.flags create mode 100644 test/files/neg/unreachablechar.flags create mode 100644 test/files/run/patmat_unapp_abstype.flags create mode 100644 test/files/run/reify_fors.flags create mode 100644 test/files/run/reify_maps.flags create mode 100644 test/files/run/t5273_1.flags create mode 100644 test/files/run/t5273_2a.flags create mode 100644 test/files/run/t5273_2b.flags diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 3efbe4b4df..17c9b955ca 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -97,7 +97,7 @@ trait Types extends api.Types { self: SymbolTable => */ private final val propagateParameterBoundsToTypeVars = sys.props contains "scalac.debug.prop-constraints" - protected val enableTypeVarExperimentals = settings.Xexperimental.value || settings.YvirtPatmat.value + protected val enableTypeVarExperimentals = settings.Xexperimental.value || !settings.XoldPatmat.value /** Empty immutable maps to avoid allocations. */ private val emptySymMap = immutable.Map[Symbol, Symbol]() diff --git a/src/compiler/scala/reflect/internal/settings/MutableSettings.scala b/src/compiler/scala/reflect/internal/settings/MutableSettings.scala index b556c33aba..45ba4ed3e6 100644 --- a/src/compiler/scala/reflect/internal/settings/MutableSettings.scala +++ b/src/compiler/scala/reflect/internal/settings/MutableSettings.scala @@ -43,5 +43,5 @@ abstract class MutableSettings extends AbsSettings { def Yrecursion: IntSetting def maxClassfileName: IntSetting def Xexperimental: BooleanSetting - def YvirtPatmat: BooleanSetting + def XoldPatmat: BooleanSetting } \ No newline at end of file diff --git a/src/compiler/scala/reflect/runtime/Settings.scala b/src/compiler/scala/reflect/runtime/Settings.scala index 27e90c94bd..bbe4d60e9c 100644 --- a/src/compiler/scala/reflect/runtime/Settings.scala +++ b/src/compiler/scala/reflect/runtime/Settings.scala @@ -34,5 +34,5 @@ class Settings extends internal.settings.MutableSettings { val maxClassfileName = new IntSetting(255) val Xexperimental = new BooleanSetting(false) val deepCloning = new BooleanSetting (false) - val YvirtPatmat = new BooleanSetting(false) + val XoldPatmat = new BooleanSetting(false) } diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 0f9f7df548..403b5717b0 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -347,7 +347,7 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S override protected val etaExpandKeepsStar = settings.etaExpandKeepsStar.value // Here comes another one... override protected val enableTypeVarExperimentals = ( - settings.Xexperimental.value || settings.YvirtPatmat.value + settings.Xexperimental.value || !settings.XoldPatmat.value ) // True if -Xscript has been set, indicating a script run. diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala index 40bbd3fa8e..99541ff4b4 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala @@ -81,7 +81,7 @@ private[tests] trait CoreTestDefs else { reporter.println("\naskHyperlinkPos for `" + tree.symbol.name + "` at " + format(pos) + " " + pos.source.file.name) val r = new Response[Position] - // `tree.symbol.sourceFile` was discovered to be null when testing -Yvirtpatmat on the akka presentation test, where a position had shifted to point to `Int` + // `tree.symbol.sourceFile` was discovered to be null when testing using virtpatmat on the akka presentation test, where a position had shifted to point to `Int` // askHyperlinkPos for `Int` at (73,19) pi.scala --> class Int in package scala has null sourceFile! val treePath = if (tree.symbol.sourceFile ne null) tree.symbol.sourceFile.path else null val treeName = if (tree.symbol.sourceFile ne null) tree.symbol.sourceFile.name else null diff --git a/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala b/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala index 2fdc3004d6..63775ff1c5 100644 --- a/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala @@ -31,7 +31,7 @@ trait AestheticSettings { def target = settings.target.value def unchecked = settings.unchecked.value def verbose = settings.verbose.value - def virtPatmat = settings.YvirtPatmat.value + def virtPatmat = !settings.XoldPatmat.value /** Derived values */ def jvm = target startsWith "jvm" diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index f7878cae71..d4c2ffa832 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -108,6 +108,8 @@ trait ScalaSettings extends AbsScalaSettings val showPhases = BooleanSetting ("-Xshow-phases", "Print a synopsis of compiler phases.") val sourceReader = StringSetting ("-Xsource-reader", "classname", "Specify a custom method for reading source files.", "") + val XoldPatmat = BooleanSetting ("-Xoldpatmat", "Use the pre-2.10 pattern matcher. Otherwise, the 'virtualizing' pattern matcher is used in 2.10.") + /** Compatibility stubs for options whose value name did * not previously match the option name. */ @@ -175,7 +177,6 @@ trait ScalaSettings extends AbsScalaSettings val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.") val etaExpandKeepsStar = BooleanSetting ("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.") val noSelfCheck = BooleanSetting ("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.") - val YvirtPatmat = BooleanSetting ("-Yvirtpatmat", "Translate pattern matches into flatMap/orElse calls. See scala.MatchingStrategy.") val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes") val exposeEmptyPackage = BooleanSetting("-Yexpose-empty-package", "Internal only: expose the empty package.").internalOnly() diff --git a/test/files/buildmanager/t2559/D.scala b/test/files/buildmanager/t2559/D.scala index 906b69a3e7..62dc5427f9 100644 --- a/test/files/buildmanager/t2559/D.scala +++ b/test/files/buildmanager/t2559/D.scala @@ -1,8 +1,4 @@ object D { - def x(a: A) = - a match { - case _: B => () - case _: C => () - } + def x(a: A) = if (a.isInstanceOf[B] || a.isInstanceOf[C]) () } diff --git a/test/files/buildmanager/t2559/t2559.check b/test/files/buildmanager/t2559/t2559.check index 752278fbe8..4d43838cf5 100644 --- a/test/files/buildmanager/t2559/t2559.check +++ b/test/files/buildmanager/t2559/t2559.check @@ -6,9 +6,4 @@ compiling Set(A.scala) Changes: Map(class B -> List(), class C -> List(), class E -> List(Changed(Class(A))[class E extends a sealed trait A]), trait A -> List()) invalidate D.scala because it references changed class [Changed(Class(A))[class E extends a sealed trait A]] compiling Set(D.scala) -D.scala:3: warning: match is not exhaustive! -missing combination E - - a match { - ^ Changes: Map(object D -> List()) diff --git a/test/files/jvm/interpreter.scala b/test/files/jvm/interpreter.scala index 1f289d9335..755b2ac9ae 100644 --- a/test/files/jvm/interpreter.scala +++ b/test/files/jvm/interpreter.scala @@ -2,7 +2,7 @@ import scala.tools.nsc._ import scala.tools.partest.ReplTest object Test extends ReplTest { - override def extraSettings = "-deprecation" + override def extraSettings = "-deprecation -Xoldpatmat" def code = // basics 3+4 diff --git a/test/files/neg/array-not-seq.check b/test/files/neg/array-not-seq.check index c16ecdad72..a3a639e772 100644 --- a/test/files/neg/array-not-seq.check +++ b/test/files/neg/array-not-seq.check @@ -1,7 +1,13 @@ array-not-seq.scala:2: error: An Array will no longer match as Seq[_]. def f1(x: Any) = x.isInstanceOf[Seq[_]] ^ -error: An Array will no longer match as Seq[_]. -error: An Array will no longer match as Seq[_]. -error: An Array will no longer match as Seq[_]. +array-not-seq.scala:4: error: An Array will no longer match as Seq[_]. + case _: Seq[_] => true + ^ +array-not-seq.scala:16: error: An Array will no longer match as Seq[_]. + case (Some(_: Seq[_]), Nil, _) => 1 + ^ +array-not-seq.scala:17: error: An Array will no longer match as Seq[_]. + case (None, List(_: List[_], _), _) => 2 + ^ four errors found diff --git a/test/files/neg/exhausting.flags b/test/files/neg/exhausting.flags index e8fb65d50c..b7eb21d5f5 100644 --- a/test/files/neg/exhausting.flags +++ b/test/files/neg/exhausting.flags @@ -1 +1 @@ --Xfatal-warnings \ No newline at end of file +-Xfatal-warnings -Xoldpatmat diff --git a/test/files/neg/gadts1.check b/test/files/neg/gadts1.check index 44d2b114d6..0441f604c9 100644 --- a/test/files/neg/gadts1.check +++ b/test/files/neg/gadts1.check @@ -11,4 +11,7 @@ gadts1.scala:20: error: type mismatch; required: a case Cell[a](x: Int) => c.x = 5 ^ -three errors found +gadts1.scala:20: error: Could not typecheck extractor call: case class with arguments List((x @ (_: Int))) + case Cell[a](x: Int) => c.x = 5 + ^ +four errors found diff --git a/test/files/neg/pat_unreachable.flags b/test/files/neg/pat_unreachable.flags new file mode 100644 index 0000000000..ba80cad69b --- /dev/null +++ b/test/files/neg/pat_unreachable.flags @@ -0,0 +1 @@ +-Xoldpatmat diff --git a/test/files/neg/patmat-type-check.check b/test/files/neg/patmat-type-check.check index e045841ce1..ab4451f089 100644 --- a/test/files/neg/patmat-type-check.check +++ b/test/files/neg/patmat-type-check.check @@ -3,19 +3,31 @@ patmat-type-check.scala:22: error: scrutinee is incompatible with pattern type; required: String def f1 = "bob".reverse match { case Seq('b', 'o', 'b') => true } // fail ^ +patmat-type-check.scala:22: error: value _1 is not a member of object Seq + def f1 = "bob".reverse match { case Seq('b', 'o', 'b') => true } // fail + ^ patmat-type-check.scala:23: error: scrutinee is incompatible with pattern type; found : Seq[A] required: Array[Char] def f2 = "bob".toArray match { case Seq('b', 'o', 'b') => true } // fail ^ +patmat-type-check.scala:23: error: value _1 is not a member of object Seq + def f2 = "bob".toArray match { case Seq('b', 'o', 'b') => true } // fail + ^ patmat-type-check.scala:27: error: scrutinee is incompatible with pattern type; found : Seq[A] required: Test.Bop2 def f3(x: Bop2) = x match { case Seq('b', 'o', 'b') => true } // fail ^ +patmat-type-check.scala:27: error: value _1 is not a member of object Seq + def f3(x: Bop2) = x match { case Seq('b', 'o', 'b') => true } // fail + ^ patmat-type-check.scala:30: error: scrutinee is incompatible with pattern type; found : Seq[A] required: Test.Bop3[Char] def f4[T](x: Bop3[Char]) = x match { case Seq('b', 'o', 'b') => true } // fail ^ -four errors found +patmat-type-check.scala:30: error: value _1 is not a member of object Seq + def f4[T](x: Bop3[Char]) = x match { case Seq('b', 'o', 'b') => true } // fail + ^ +8 errors found diff --git a/test/files/neg/patmatexhaust.flags b/test/files/neg/patmatexhaust.flags index e8fb65d50c..b7eb21d5f5 100644 --- a/test/files/neg/patmatexhaust.flags +++ b/test/files/neg/patmatexhaust.flags @@ -1 +1 @@ --Xfatal-warnings \ No newline at end of file +-Xfatal-warnings -Xoldpatmat diff --git a/test/files/neg/sealed-java-enums.flags b/test/files/neg/sealed-java-enums.flags index e709c65918..312f3a87ec 100644 --- a/test/files/neg/sealed-java-enums.flags +++ b/test/files/neg/sealed-java-enums.flags @@ -1 +1 @@ --Xexperimental -Xfatal-warnings +-Xexperimental -Xfatal-warnings -Xoldpatmat diff --git a/test/files/neg/switch.flags b/test/files/neg/switch.flags new file mode 100644 index 0000000000..809e9ff2f2 --- /dev/null +++ b/test/files/neg/switch.flags @@ -0,0 +1 @@ + -Xoldpatmat diff --git a/test/files/neg/t0418.check b/test/files/neg/t0418.check index 4e9ad2f9ae..50931a1bca 100644 --- a/test/files/neg/t0418.check +++ b/test/files/neg/t0418.check @@ -4,4 +4,7 @@ t0418.scala:2: error: not found: value Foo12340771 t0418.scala:2: error: not found: value x null match { case Foo12340771.Bar(x) => x } ^ -two errors found +t0418.scala:2: error: Could not typecheck extractor call: case class with arguments List((x @ _)) + null match { case Foo12340771.Bar(x) => x } + ^ +three errors found diff --git a/test/files/neg/t112706A.check b/test/files/neg/t112706A.check index 30d0c3ec91..fb18b31be1 100644 --- a/test/files/neg/t112706A.check +++ b/test/files/neg/t112706A.check @@ -3,4 +3,7 @@ t112706A.scala:5: error: constructor cannot be instantiated to expected type; required: String case Tuple2(node,_) => ^ -one error found +t112706A.scala:5: error: Could not typecheck extractor call: case class Tuple2 with arguments List((node @ _), _) + case Tuple2(node,_) => + ^ +two errors found diff --git a/test/files/neg/t1878.check b/test/files/neg/t1878.check index 128741a022..b47367e12c 100644 --- a/test/files/neg/t1878.check +++ b/test/files/neg/t1878.check @@ -9,10 +9,13 @@ t1878.scala:3: error: scrutinee is incompatible with pattern type; t1878.scala:3: error: not found: value f val err1 = "" match { case Seq(f @ _*, ',') => f } ^ +t1878.scala:3: error: value _2 is not a member of object Seq + val err1 = "" match { case Seq(f @ _*, ',') => f } + ^ t1878.scala:9: error: _* may only come last val List(List(_*, arg2), _) = List(List(1,2,3), List(4,5,6)) ^ t1878.scala:13: error: _* may only come last case

    { _* }

    => ^ -5 errors found +6 errors found diff --git a/test/files/neg/t3098.flags b/test/files/neg/t3098.flags index e8fb65d50c..b7eb21d5f5 100644 --- a/test/files/neg/t3098.flags +++ b/test/files/neg/t3098.flags @@ -1 +1 @@ --Xfatal-warnings \ No newline at end of file +-Xfatal-warnings -Xoldpatmat diff --git a/test/files/neg/t3392.check b/test/files/neg/t3392.check index 842d63eec9..3a39098c4e 100644 --- a/test/files/neg/t3392.check +++ b/test/files/neg/t3392.check @@ -1,4 +1,7 @@ t3392.scala:9: error: not found: value x case x@A(x/*<-- refers to the pattern that includes this comment*/.Ex(42)) => ^ -one error found +t3392.scala:9: error: Could not typecheck extractor call: case class with arguments List(42) + case x@A(x/*<-- refers to the pattern that includes this comment*/.Ex(42)) => + ^ +two errors found diff --git a/test/files/neg/t3683a.flags b/test/files/neg/t3683a.flags index 85d8eb2ba2..b7eb21d5f5 100644 --- a/test/files/neg/t3683a.flags +++ b/test/files/neg/t3683a.flags @@ -1 +1 @@ --Xfatal-warnings +-Xfatal-warnings -Xoldpatmat diff --git a/test/files/neg/t3692.flags b/test/files/neg/t3692.flags new file mode 100644 index 0000000000..82becdfbfd --- /dev/null +++ b/test/files/neg/t3692.flags @@ -0,0 +1 @@ + -Xoldpatmat \ No newline at end of file diff --git a/test/files/neg/t418.check b/test/files/neg/t418.check index 1489547823..c06088ba9d 100644 --- a/test/files/neg/t418.check +++ b/test/files/neg/t418.check @@ -4,4 +4,7 @@ t418.scala:2: error: not found: value Foo12340771 t418.scala:2: error: not found: value x null match { case Foo12340771.Bar(x) => x } ^ -two errors found +t418.scala:2: error: Could not typecheck extractor call: case class with arguments List((x @ _)) + null match { case Foo12340771.Bar(x) => x } + ^ +three errors found diff --git a/test/files/neg/t4425.check b/test/files/neg/t4425.check index 4ff4b1eec0..0f2fe6f2d1 100644 --- a/test/files/neg/t4425.check +++ b/test/files/neg/t4425.check @@ -1,4 +1,4 @@ -t4425.scala:3: error: erroneous or inaccessible type +t4425.scala:3: error: isInstanceOf cannot test if value types are references. 42 match { case _ X _ => () } ^ one error found diff --git a/test/files/neg/t5589neg.check b/test/files/neg/t5589neg.check index b3ff16d7e4..fb6858a397 100644 --- a/test/files/neg/t5589neg.check +++ b/test/files/neg/t5589neg.check @@ -22,6 +22,9 @@ t5589neg.scala:4: error: constructor cannot be instantiated to expected type; t5589neg.scala:4: error: not found: value y2 def f7(x: Either[Int, (String, Int)]) = for (y1 @ Tuple1(y2) <- x.right) yield ((y1, y2)) ^ +t5589neg.scala:4: error: Could not typecheck extractor call: case class Tuple1 with arguments List((y2 @ _)) + def f7(x: Either[Int, (String, Int)]) = for (y1 @ Tuple1(y2) <- x.right) yield ((y1, y2)) + ^ t5589neg.scala:5: error: constructor cannot be instantiated to expected type; found : (T1, T2, T3) required: (String, Int) @@ -34,4 +37,4 @@ t5589neg.scala:5: error: not found: value y2 def f8(x: Either[Int, (String, Int)]) = for ((y1, y2, y3) <- x.right) yield ((y1, y2)) ^ two warnings found -7 errors found +8 errors found diff --git a/test/files/neg/tailrec.check b/test/files/neg/tailrec.check index ad92731b2c..946d3421e6 100644 --- a/test/files/neg/tailrec.check +++ b/test/files/neg/tailrec.check @@ -4,9 +4,9 @@ tailrec.scala:45: error: could not optimize @tailrec annotated method facfail: i tailrec.scala:50: error: could not optimize @tailrec annotated method fail1: it is neither private nor final so can be overridden @tailrec def fail1(x: Int): Int = fail1(x) ^ -tailrec.scala:55: error: could not optimize @tailrec annotated method fail2: it contains a recursive call not in tail position - case x :: xs => x :: fail2[T](xs) - ^ +tailrec.scala:53: error: could not optimize @tailrec annotated method fail2: it contains a recursive call not in tail position + @tailrec final def fail2[T](xs: List[T]): List[T] = xs match { + ^ tailrec.scala:59: error: could not optimize @tailrec annotated method fail3: it is called recursively with different type arguments @tailrec final def fail3[T](x: Int): Int = fail3(x - 1) ^ diff --git a/test/files/neg/unreachablechar.flags b/test/files/neg/unreachablechar.flags new file mode 100644 index 0000000000..809e9ff2f2 --- /dev/null +++ b/test/files/neg/unreachablechar.flags @@ -0,0 +1 @@ + -Xoldpatmat diff --git a/test/files/pos/t1439.flags b/test/files/pos/t1439.flags index d86a0144e8..1e70f5c5c7 100644 --- a/test/files/pos/t1439.flags +++ b/test/files/pos/t1439.flags @@ -1 +1 @@ --unchecked -Xfatal-warnings -language:higherKinds \ No newline at end of file +-unchecked -Xfatal-warnings -Xoldpatmat -language:higherKinds diff --git a/test/files/pos/virtpatmat_alts_subst.flags b/test/files/pos/virtpatmat_alts_subst.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/pos/virtpatmat_alts_subst.flags +++ b/test/files/pos/virtpatmat_alts_subst.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/pos/virtpatmat_anonfun_for.flags b/test/files/pos/virtpatmat_anonfun_for.flags index 23e3dc7d26..e69de29bb2 100644 --- a/test/files/pos/virtpatmat_anonfun_for.flags +++ b/test/files/pos/virtpatmat_anonfun_for.flags @@ -1 +0,0 @@ --Yvirtpatmat \ No newline at end of file diff --git a/test/files/pos/virtpatmat_binding_opt.flags b/test/files/pos/virtpatmat_binding_opt.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/pos/virtpatmat_binding_opt.flags +++ b/test/files/pos/virtpatmat_binding_opt.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/pos/virtpatmat_castbinder.flags b/test/files/pos/virtpatmat_castbinder.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/pos/virtpatmat_castbinder.flags +++ b/test/files/pos/virtpatmat_castbinder.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/pos/virtpatmat_exist1.flags b/test/files/pos/virtpatmat_exist1.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/pos/virtpatmat_exist1.flags +++ b/test/files/pos/virtpatmat_exist1.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/pos/virtpatmat_exist2.flags b/test/files/pos/virtpatmat_exist2.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/pos/virtpatmat_exist2.flags +++ b/test/files/pos/virtpatmat_exist2.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/pos/virtpatmat_exist3.flags b/test/files/pos/virtpatmat_exist3.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/pos/virtpatmat_exist3.flags +++ b/test/files/pos/virtpatmat_exist3.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/pos/virtpatmat_gadt_array.flags b/test/files/pos/virtpatmat_gadt_array.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/pos/virtpatmat_gadt_array.flags +++ b/test/files/pos/virtpatmat_gadt_array.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/pos/virtpatmat_infer_single_1.flags b/test/files/pos/virtpatmat_infer_single_1.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/pos/virtpatmat_infer_single_1.flags +++ b/test/files/pos/virtpatmat_infer_single_1.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/pos/virtpatmat_instof_valuetype.flags b/test/files/pos/virtpatmat_instof_valuetype.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/pos/virtpatmat_instof_valuetype.flags +++ b/test/files/pos/virtpatmat_instof_valuetype.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/pos/virtpatmat_obj_in_case.flags b/test/files/pos/virtpatmat_obj_in_case.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/pos/virtpatmat_obj_in_case.flags +++ b/test/files/pos/virtpatmat_obj_in_case.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/presentation/callcc-interpreter/Runner.scala b/test/files/presentation/callcc-interpreter/Runner.scala index 1ef3cf9025..61b6efd50d 100644 --- a/test/files/presentation/callcc-interpreter/Runner.scala +++ b/test/files/presentation/callcc-interpreter/Runner.scala @@ -1,3 +1,5 @@ import scala.tools.nsc.interactive.tests._ -object Test extends InteractiveTest \ No newline at end of file +object Test extends InteractiveTest { + settings.XoldPatmat.value = true // TODO: could this be running into some kind of race condition? sometimes the match has been translated, sometimes it hasn't +} \ No newline at end of file diff --git a/test/files/presentation/random.check b/test/files/presentation/random.check index fce4b69fb3..1b73720312 100644 --- a/test/files/presentation/random.check +++ b/test/files/presentation/random.check @@ -4,7 +4,8 @@ askType at Random.scala(18,14) ================================================================================ [response] askTypeAt at (18,14) val filter: Int => Boolean = try { - java.this.lang.Integer.parseInt(args.apply(0)) match { + case val x1: Int = java.this.lang.Integer.parseInt(args.apply(0)); + x1 match { case 1 => ((x: Int) => x.%(2).!=(0)) case 2 => ((x: Int) => x.%(2).==(0)) case _ => ((x: Int) => x.!=(0)) diff --git a/test/files/run/inline-ex-handlers.check b/test/files/run/inline-ex-handlers.check index 7a8a744bfa..708fcc6985 100644 --- a/test/files/run/inline-ex-handlers.check +++ b/test/files/run/inline-ex-handlers.check @@ -1,40 +1,44 @@ 172c172 -< locals: value x$1, value temp1 +< locals: value x$1, value x1 --- -> locals: value x$1, value temp1, variable boxed1 +> locals: value x$1, value x1, variable boxed1 174c174 < blocks: [1,2,3,4] --- -> blocks: [1,2,3] -187,189d186 -< 92 JUMP 4 -< -< 4: -195a193,194 +> blocks: [1,3,4] +186a187,188 > 92 STORE_LOCAL(variable boxed1) > 92 LOAD_LOCAL(variable boxed1) -386c385 -< blocks: [1,2,3,4,5,7,8,10] +195,197d196 +< 92 JUMP 2 +< +< 2: +385c384 +< blocks: [1,2,3,4,5,8,11,13,14,16] --- -> blocks: [1,2,3,4,5,7,8,10,11] -410c409,418 +> blocks: [1,2,3,5,8,11,13,14,16,17] +409c408,417 < 103 THROW(MyException) --- -> ? STORE_LOCAL(value ex$1) -> ? JUMP 11 +> ? STORE_LOCAL(value ex5) +> ? JUMP 17 > -> 11: -> 101 LOAD_LOCAL(value ex$1) -> 101 STORE_LOCAL(value temp2) -> 101 SCOPE_ENTER value temp2 -> 101 LOAD_LOCAL(value temp2) -> 101 IS_INSTANCE REF(class MyException) -> 101 CZJUMP (BOOL)NE ? 4 : 5 -501c509 +> 17: +> 101 LOAD_LOCAL(value ex5) +> 101 STORE_LOCAL(value x3) +> 101 SCOPE_ENTER value x3 +> 106 LOAD_LOCAL(value x3) +> 106 IS_INSTANCE REF(class MyException) +> 106 CZJUMP (BOOL)NE ? 5 : 11 +422,424d429 +< 101 JUMP 4 +< +< 4: +512c517 < blocks: [1,2,3,4,6,7,8,9,10] --- > blocks: [1,2,3,4,6,7,8,9,10,11,12,13] -530c538,543 +541c546,551 < 306 THROW(MyException) --- > ? JUMP 11 @@ -43,7 +47,7 @@ > ? LOAD_LOCAL(variable monitor4) > 305 MONITOR_EXIT > ? JUMP 12 -536c549,555 +547c557,563 < ? THROW(Throwable) --- > ? JUMP 12 @@ -53,7 +57,7 @@ > 304 MONITOR_EXIT > ? STORE_LOCAL(value t) > ? JUMP 13 -542c561,574 +553c569,582 < ? THROW(Throwable) --- > ? STORE_LOCAL(value t) @@ -70,19 +74,19 @@ > 310 CALL_PRIMITIVE(EndConcat) > 310 CALL_METHOD scala.Predef.println (dynamic) > 310 JUMP 2 -566c598 +577c606 < catch (Throwable) in ArrayBuffer(7, 8, 9, 10) starting at: 6 --- > catch (Throwable) in ArrayBuffer(7, 8, 9, 10, 11) starting at: 6 -569c601 +580c609 < catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10) starting at: 3 --- > catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10, 11, 12) starting at: 3 -601c633 +612c641 < blocks: [1,2,3,4,5,6,7,9,10] --- > blocks: [1,2,3,4,5,6,7,9,10,11,12] -625c657,663 +636c665,671 < 78 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) @@ -92,7 +96,7 @@ > 81 LOAD_LOCAL(value e) > ? STORE_LOCAL(variable exc1) > ? JUMP 12 -654c692,706 +665c700,714 < 81 THROW(Exception) --- > ? STORE_LOCAL(variable exc1) @@ -110,57 +114,53 @@ > 84 STORE_LOCAL(variable result) > 84 LOAD_LOCAL(variable exc1) > 84 THROW(Throwable) -676c728 +687c736 < catch () in ArrayBuffer(4, 6, 7, 9) starting at: 3 --- > catch () in ArrayBuffer(4, 6, 7, 9, 11) starting at: 3 -702c754 -< blocks: [1,2,3,4,5,6,7,8,11,12,13,14,15,16,18,19] +713c762 +< blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31] --- -> blocks: [1,2,3,4,5,6,7,8,11,12,13,14,15,16,18,19,20,21,22] -726c778,787 +> blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31,32,33,34] +737c786,793 < 172 THROW(MyException) --- -> ? STORE_LOCAL(value ex$4) -> ? JUMP 20 +> ? STORE_LOCAL(value ex5) +> ? JUMP 32 > -> 20: -> 170 LOAD_LOCAL(value ex$4) -> 170 STORE_LOCAL(value temp11) -> 170 SCOPE_ENTER value temp11 -> 170 LOAD_LOCAL(value temp11) -> 170 IS_INSTANCE REF(class MyException) -> 170 CZJUMP (BOOL)NE ? 12 : 13 -780c841,842 +> 32: +> 170 LOAD_LOCAL(value ex5) +> 170 STORE_LOCAL(value x3) +> 170 SCOPE_ENTER value x3 +> 170 JUMP 18 +793c849,850 < 177 THROW(MyException) --- -> ? STORE_LOCAL(value ex$5) -> ? JUMP 21 -784c846,855 +> ? STORE_LOCAL(value ex5) +> ? JUMP 33 +797c854,861 < 170 THROW(Throwable) --- -> ? STORE_LOCAL(value ex$5) -> ? JUMP 21 +> ? STORE_LOCAL(value ex5) +> ? JUMP 33 > -> 21: -> 169 LOAD_LOCAL(value ex$5) -> 169 STORE_LOCAL(value temp14) -> 169 SCOPE_ENTER value temp14 -> 169 LOAD_LOCAL(value temp14) -> 169 IS_INSTANCE REF(class MyException) -> 169 CZJUMP (BOOL)NE ? 5 : 6 -815c886,887 +> 33: +> 169 LOAD_LOCAL(value ex5) +> 169 STORE_LOCAL(value x3) +> 169 SCOPE_ENTER value x3 +> 169 JUMP 5 +830c894,895 < 182 THROW(MyException) --- > ? STORE_LOCAL(variable exc2) -> ? JUMP 22 -819c891,905 +> ? JUMP 34 +834c899,900 < 169 THROW(Throwable) --- > ? STORE_LOCAL(variable exc2) -> ? JUMP 22 -> -> 22: +> ? JUMP 34 +835a902,914 +> 34: > 184 LOAD_MODULE object Predef > 184 CONSTANT("finally") > 184 CALL_METHOD scala.Predef.println (dynamic) @@ -172,57 +172,60 @@ > 185 STORE_LOCAL(variable result) > 185 LOAD_LOCAL(variable exc2) > 185 THROW(Throwable) -841c927 -< catch (Throwable) in ArrayBuffer(11, 12, 13, 14, 15, 16, 18) starting at: 4 +> +856c935 +< catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30) starting at: 4 --- -> catch (Throwable) in ArrayBuffer(11, 12, 13, 14, 15, 16, 18, 20) starting at: 4 -844c930 -< catch () in ArrayBuffer(4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 18) starting at: 3 +> catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30, 32) starting at: 4 +859c938 +< catch () in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30) starting at: 3 --- -> catch () in ArrayBuffer(4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 18, 20, 21) starting at: 3 -870c956 -< blocks: [1,2,3,6,7,8,10,11,13] +> catch () in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30, 32, 33) starting at: 3 +885c964 +< blocks: [1,2,3,6,7,8,11,14,16,17,19] --- -> blocks: [1,2,3,6,7,8,10,11,13,14] -894c980,989 +> blocks: [1,2,3,6,7,8,11,14,16,17,19,20] +909c988,995 < 124 THROW(MyException) --- -> ? STORE_LOCAL(value ex$2) -> ? JUMP 14 +> ? STORE_LOCAL(value ex5) +> ? JUMP 20 > -> 14: -> 122 LOAD_LOCAL(value ex$2) -> 122 STORE_LOCAL(value temp5) -> 122 SCOPE_ENTER value temp5 -> 122 LOAD_LOCAL(value temp5) -> 122 IS_INSTANCE REF(class MyException) -> 122 CZJUMP (BOOL)NE ? 7 : 8 -942c1037 -< catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 10, 11, 13) starting at: 3 ---- -> catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 10, 11, 13, 14) starting at: 3 -968c1063 -< blocks: [1,2,3,4,5,9,10,11,13] ---- -> blocks: [1,2,3,4,5,9,10,11,13,14] -992c1087,1096 +> 20: +> 122 LOAD_LOCAL(value ex5) +> 122 STORE_LOCAL(value x3) +> 122 SCOPE_ENTER value x3 +> 122 JUMP 7 +969c1055 +< catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19) starting at: 3 +--- +> catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19, 20) starting at: 3 +995c1081 +< blocks: [1,2,3,4,5,8,11,15,16,17,19] +--- +> blocks: [1,2,3,5,8,11,15,16,17,19,20] +1019c1105,1114 < 148 THROW(MyException) --- -> ? STORE_LOCAL(value ex$3) -> ? JUMP 14 +> ? STORE_LOCAL(value ex5) +> ? JUMP 20 > -> 14: -> 145 LOAD_LOCAL(value ex$3) -> 145 STORE_LOCAL(value temp8) -> 145 SCOPE_ENTER value temp8 -> 145 LOAD_LOCAL(value temp8) -> 145 IS_INSTANCE REF(class MyException) -> 145 CZJUMP (BOOL)NE ? 4 : 5 -1236c1340 +> 20: +> 145 LOAD_LOCAL(value ex5) +> 145 STORE_LOCAL(value x3) +> 145 SCOPE_ENTER value x3 +> 154 LOAD_LOCAL(value x3) +> 154 IS_INSTANCE REF(class MyException) +> 154 CZJUMP (BOOL)NE ? 5 : 11 +1040,1042d1134 +< 145 JUMP 4 +< +< 4: +1275c1367 < blocks: [1,2,3,4,5,7] --- > blocks: [1,2,3,4,5,7,8] -1260c1364,1371 +1299c1391,1398 < 38 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) @@ -233,33 +236,37 @@ > 42 CONSTANT("IllegalArgumentException") > 42 CALL_METHOD scala.Predef.println (dynamic) > 42 JUMP 2 -1309c1420 -< blocks: [1,2,3,4,5,7,8,10,11,13] +1348c1447 +< blocks: [1,2,3,4,5,8,11,13,14,16,17,19] --- -> blocks: [1,2,3,4,5,7,8,10,11,13,14] -1333c1444,1445 +> blocks: [1,2,3,5,8,11,13,14,16,17,19,20] +1372c1471,1472 < 203 THROW(MyException) --- -> ? STORE_LOCAL(value ex$6) -> ? JUMP 14 -1353c1465,1474 +> ? STORE_LOCAL(value ex5) +> ? JUMP 20 +1392c1492,1501 < 209 THROW(MyException) --- -> ? STORE_LOCAL(value ex$6) -> ? JUMP 14 +> ? STORE_LOCAL(value ex5) +> ? JUMP 20 > -> 14: -> 200 LOAD_LOCAL(value ex$6) -> 200 STORE_LOCAL(value temp17) -> 200 SCOPE_ENTER value temp17 -> 200 LOAD_LOCAL(value temp17) -> 200 IS_INSTANCE REF(class MyException) -> 200 CZJUMP (BOOL)NE ? 4 : 5 -1416c1537 +> 20: +> 200 LOAD_LOCAL(value ex5) +> 200 STORE_LOCAL(value x3) +> 200 SCOPE_ENTER value x3 +> 212 LOAD_LOCAL(value x3) +> 212 IS_INSTANCE REF(class MyException) +> 212 CZJUMP (BOOL)NE ? 5 : 11 +1405,1407d1513 +< 200 JUMP 4 +< +< 4: +1467c1573 < blocks: [1,2,3,4,5,7] --- > blocks: [1,2,3,4,5,7,8] -1440c1561,1568 +1491c1597,1604 < 58 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) @@ -270,11 +277,11 @@ > 62 CONSTANT("RuntimeException") > 62 CALL_METHOD scala.Predef.println (dynamic) > 62 JUMP 2 -1489c1617 +1540c1653 < blocks: [1,2,3,4] --- > blocks: [1,2,3,4,5] -1509c1637,1642 +1560c1673,1678 < 229 THROW(MyException) --- > ? JUMP 5 @@ -283,19 +290,19 @@ > ? LOAD_LOCAL(variable monitor1) > 228 MONITOR_EXIT > 228 THROW(Throwable) -1515c1648 +1566c1684 < ? THROW(Throwable) --- > 228 THROW(Throwable) -1543c1676 +1594c1712 < locals: value args, variable result, variable monitor2, variable monitorResult1 --- > locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1 -1545c1678 +1596c1714 < blocks: [1,2,3,4] --- > blocks: [1,2,3,4,5] -1568c1701,1709 +1619c1737,1745 < 245 THROW(MyException) --- > ? STORE_LOCAL(value exception$1) @@ -307,7 +314,7 @@ > ? LOAD_LOCAL(variable monitor2) > 244 MONITOR_EXIT > 244 THROW(Throwable) -1574c1715 +1625c1751 < ? THROW(Throwable) --- > 244 THROW(Throwable) diff --git a/test/files/run/patmat_unapp_abstype.flags b/test/files/run/patmat_unapp_abstype.flags new file mode 100644 index 0000000000..ba80cad69b --- /dev/null +++ b/test/files/run/patmat_unapp_abstype.flags @@ -0,0 +1 @@ +-Xoldpatmat diff --git a/test/files/run/reify_fors.flags b/test/files/run/reify_fors.flags new file mode 100644 index 0000000000..ba80cad69b --- /dev/null +++ b/test/files/run/reify_fors.flags @@ -0,0 +1 @@ +-Xoldpatmat diff --git a/test/files/run/reify_maps.flags b/test/files/run/reify_maps.flags new file mode 100644 index 0000000000..ba80cad69b --- /dev/null +++ b/test/files/run/reify_maps.flags @@ -0,0 +1 @@ +-Xoldpatmat diff --git a/test/files/run/repl-suppressed-warnings.scala b/test/files/run/repl-suppressed-warnings.scala index a78b00f36e..9afbbaf1a5 100644 --- a/test/files/run/repl-suppressed-warnings.scala +++ b/test/files/run/repl-suppressed-warnings.scala @@ -1,6 +1,7 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { + override def extraSettings = "-Xoldpatmat" def code = """ // "Is this thing on?" Not working on first couple diff --git a/test/files/run/t5273_1.flags b/test/files/run/t5273_1.flags new file mode 100644 index 0000000000..ba80cad69b --- /dev/null +++ b/test/files/run/t5273_1.flags @@ -0,0 +1 @@ +-Xoldpatmat diff --git a/test/files/run/t5273_2a.flags b/test/files/run/t5273_2a.flags new file mode 100644 index 0000000000..ba80cad69b --- /dev/null +++ b/test/files/run/t5273_2a.flags @@ -0,0 +1 @@ +-Xoldpatmat diff --git a/test/files/run/t5273_2b.flags b/test/files/run/t5273_2b.flags new file mode 100644 index 0000000000..ba80cad69b --- /dev/null +++ b/test/files/run/t5273_2b.flags @@ -0,0 +1 @@ +-Xoldpatmat diff --git a/test/files/run/virtpatmat_alts.flags b/test/files/run/virtpatmat_alts.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_alts.flags +++ b/test/files/run/virtpatmat_alts.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_apply.flags b/test/files/run/virtpatmat_apply.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_apply.flags +++ b/test/files/run/virtpatmat_apply.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_casting.flags b/test/files/run/virtpatmat_casting.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_casting.flags +++ b/test/files/run/virtpatmat_casting.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_extends_product.flags b/test/files/run/virtpatmat_extends_product.flags index ac6b805bd0..8b13789179 100644 --- a/test/files/run/virtpatmat_extends_product.flags +++ b/test/files/run/virtpatmat_extends_product.flags @@ -1 +1 @@ --Yvirtpatmat + diff --git a/test/files/run/virtpatmat_literal.flags b/test/files/run/virtpatmat_literal.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_literal.flags +++ b/test/files/run/virtpatmat_literal.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_nested_lists.flags b/test/files/run/virtpatmat_nested_lists.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_nested_lists.flags +++ b/test/files/run/virtpatmat_nested_lists.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_npe.flags b/test/files/run/virtpatmat_npe.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_npe.flags +++ b/test/files/run/virtpatmat_npe.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_opt_sharing.flags b/test/files/run/virtpatmat_opt_sharing.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_opt_sharing.flags +++ b/test/files/run/virtpatmat_opt_sharing.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_partial.flags b/test/files/run/virtpatmat_partial.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_partial.flags +++ b/test/files/run/virtpatmat_partial.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_staging.flags b/test/files/run/virtpatmat_staging.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_staging.flags +++ b/test/files/run/virtpatmat_staging.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_switch.flags b/test/files/run/virtpatmat_switch.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_switch.flags +++ b/test/files/run/virtpatmat_switch.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_tailcalls_verifyerror.flags b/test/files/run/virtpatmat_tailcalls_verifyerror.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_tailcalls_verifyerror.flags +++ b/test/files/run/virtpatmat_tailcalls_verifyerror.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_try.flags b/test/files/run/virtpatmat_try.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_try.flags +++ b/test/files/run/virtpatmat_try.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_typed.flags b/test/files/run/virtpatmat_typed.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_typed.flags +++ b/test/files/run/virtpatmat_typed.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_unapply.flags b/test/files/run/virtpatmat_unapply.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_unapply.flags +++ b/test/files/run/virtpatmat_unapply.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_unapplyprod.flags b/test/files/run/virtpatmat_unapplyprod.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_unapplyprod.flags +++ b/test/files/run/virtpatmat_unapplyprod.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/run/virtpatmat_unapplyseq.flags b/test/files/run/virtpatmat_unapplyseq.flags index 9769db9257..3f5a3100e4 100644 --- a/test/files/run/virtpatmat_unapplyseq.flags +++ b/test/files/run/virtpatmat_unapplyseq.flags @@ -1 +1 @@ - -Yvirtpatmat -Xexperimental + -Xexperimental diff --git a/test/files/specialized/spec-patmatch.check b/test/files/specialized/spec-patmatch.check index 33306ab5d9..a2746c0f48 100644 --- a/test/files/specialized/spec-patmatch.check +++ b/test/files/specialized/spec-patmatch.check @@ -17,4 +17,4 @@ long double float default -2 \ No newline at end of file +10 -- cgit v1.2.3 From 625397b02ead976f7144d30868f1b058eb6823b6 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 14 Apr 2012 10:36:48 +0100 Subject: Added NameTree Tree interface. --- src/compiler/scala/reflect/internal/Trees.scala | 6 ++---- .../scala/tools/nsc/typechecker/TreeCheckers.scala | 24 +++++++++------------- src/library/scala/reflect/api/Trees.scala | 10 +++++++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index 0413fd9896..5f1a8f3fbe 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -144,11 +144,9 @@ trait Trees extends api.Trees { self: SymbolTable => * less than the whole tree. */ def summaryString: String = tree match { - case Select(qual, name) => qual.summaryString + "." + name.decode - case Ident(name) => name.longString case Literal(const) => "Literal(" + const + ")" - case t: DefTree => t.shortClass + " `" + t.name.decode + "`" - case t: RefTree => t.shortClass + " `" + t.name.longString + "`" + case Select(qual, name) => qual.summaryString + "." + name.decode + case t: NameTree => t.name.longString case t => t.shortClass + ( if (t.symbol != null && t.symbol != NoSymbol) " " + t.symbol diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index 45d916c633..4319dd10c7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -14,8 +14,9 @@ import util.returning abstract class TreeCheckers extends Analyzer { import global._ - private val everything = ListBuffer[(Phase, Map[Tree, (Symbol, Type)])]() + private val everything = ListBuffer[(Phase, Map[Tree, (Symbol, Type)])]() private val currentTrees = mutable.Map[Tree, (Symbol, Type)]() + private val tpeOfTree = mutable.HashMap[Tree, Type]() if (settings.debug.value) { sys addShutdownHook { @@ -49,12 +50,13 @@ abstract class TreeCheckers extends Analyzer { object SymbolTracker extends Traverser { type PhaseMap = mutable.HashMap[Symbol, List[Tree]] + val defSyms = mutable.HashMap[Symbol, List[DefTree]]() withDefaultValue Nil + val newSyms = mutable.HashSet[Symbol]() val maps = ListBuffer[(Phase, PhaseMap)]() + val movedMsgs = ListBuffer[String]() + def prev = maps.init.last._2 def latest = maps.last._2 - val defSyms = mutable.HashMap[Symbol, List[DefTree]]() - val newSyms = mutable.HashSet[Symbol]() - val movedMsgs = new ListBuffer[String] def sortedNewSyms = newSyms.toList.distinct sortBy (_.name.toString) def inPrev(sym: Symbol) = { @@ -119,10 +121,8 @@ abstract class TreeCheckers extends Analyzer { if (sym != null && sym != NoSymbol) { record(sym, tree) tree match { - case x: DefTree => - if (defSyms contains sym) defSyms(sym) = defSyms(sym) :+ x - else defSyms(sym) = List(x) - case _ => () + case x: DefTree => defSyms(sym) :+= x + case _ => () } } @@ -130,8 +130,6 @@ abstract class TreeCheckers extends Analyzer { } } - lazy val tpeOfTree = mutable.HashMap[Tree, Type]() - def posstr(p: Position) = try p.source.path + ":" + p.line catch { case _: UnsupportedOperationException => p.toString } @@ -147,9 +145,7 @@ abstract class TreeCheckers extends Analyzer { if (!cond) errorFn(msg) def checkTrees() { - if (settings.verbose.value) - Console.println("[consistency check at the beginning of phase " + phase + "]") - + informFn("[consistency check at the beginning of phase " + phase + "]") currentRun.units foreach check } @@ -172,7 +168,7 @@ abstract class TreeCheckers extends Analyzer { informProgress("checking "+unit) val context = rootContext(unit) context.checking = true - tpeOfTree.clear + tpeOfTree.clear() SymbolTracker.check(phase, unit) val checker = new TreeChecker(context) runWithUnit(unit) { diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 6ddb2ea673..d659a9e9eb 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -294,18 +294,24 @@ trait Trees { self: Universe => override var symbol: Symbol = NoSymbol } + /** A tree with a name - effectively, a DefTree or RefTree. + */ + trait NameTree extends Tree { + def name: Name + } + /** A tree which references a symbol-carrying entity. * References one, as opposed to defining one; definitions * are in DefTrees. */ - trait RefTree extends SymTree { + trait RefTree extends SymTree with NameTree { def qualifier: Tree // empty for Idents def name: Name } /** A tree which defines a symbol-carrying entity. */ - abstract class DefTree extends SymTree { + abstract class DefTree extends SymTree with NameTree { def name: Name override def isDef = true } -- cgit v1.2.3 From 883a97992e7aab36b2cdf3da6951b200b110cf92 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Sat, 14 Apr 2012 12:00:53 +0200 Subject: no longer need -Yvirtpatmat --- test/files/run/virtpatmat_stringinterp.flags | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/files/run/virtpatmat_stringinterp.flags b/test/files/run/virtpatmat_stringinterp.flags index 0612c4f8ff..e1b37447c9 100644 --- a/test/files/run/virtpatmat_stringinterp.flags +++ b/test/files/run/virtpatmat_stringinterp.flags @@ -1 +1 @@ --Xexperimental -Yvirtpatmat \ No newline at end of file +-Xexperimental \ No newline at end of file -- cgit v1.2.3 From 651f2219b325c1a4cf586da4cae58e60caec0860 Mon Sep 17 00:00:00 2001 From: Vlad Ureche Date: Sat, 14 Apr 2012 12:07:02 +0200 Subject: Fixing the docs.scalap breakage --- src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 9fcd43ac02..124a7509e8 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -398,11 +398,13 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { else if (bSym.isPackage) makeTemplate(bSym.owner) match { case inPkg: PackageImpl => makePackage(bSym, inPkg) getOrElse (new NoDocTemplateImpl(bSym, inPkg)) + case inNoDocTpl: NoDocTemplateImpl => new NoDocTemplateImpl(bSym, inNoDocTpl) case _ => throw new Error("'" + bSym + "' must be in a package") } else if (templateShouldDocument(bSym)) makeTemplate(bSym.owner) match { case inDTpl: DocTemplateImpl => makeDocTemplate(bSym, inDTpl) + case inNoDocTpl: NoDocTemplateImpl => new NoDocTemplateImpl(bSym, inNoDocTpl) case _ => throw new Error("'" + bSym + "' must be in documentable template") } else -- cgit v1.2.3 From 95ad0bbddb09f1177cf8cd6f0e8ef2f7135bf4ae Mon Sep 17 00:00:00 2001 From: Vlad Ureche Date: Sat, 14 Apr 2012 12:27:55 +0200 Subject: Adapted implicits testsuite for SIP18 --- test/disabled/run/implicits-base.check | 1 - test/disabled/run/implicits-base.scala | 180 --------------------- test/disabled/run/implicits-chaining.check | 1 - test/disabled/run/implicits-chaining.scala | 65 -------- test/disabled/run/implicits-elimination.check | 1 - test/disabled/run/implicits-elimination.scala | 23 --- test/disabled/run/implicits-scopes.check | 1 - test/disabled/run/implicits-scopes.scala | 77 --------- test/scaladoc/resources/implicits-base-res.scala | 2 + .../resources/implicits-chaining-res.scala | 2 + .../resources/implicits-elimination-res.scala | 7 +- test/scaladoc/resources/implicits-scopes-res.scala | 1 + test/scaladoc/run/implicits-base.check | 1 + test/scaladoc/run/implicits-base.scala | 180 +++++++++++++++++++++ test/scaladoc/run/implicits-chaining.check | 1 + test/scaladoc/run/implicits-chaining.scala | 65 ++++++++ test/scaladoc/run/implicits-elimination.check | 1 + test/scaladoc/run/implicits-elimination.scala | 23 +++ test/scaladoc/run/implicits-scopes.check | 1 + test/scaladoc/run/implicits-scopes.scala | 77 +++++++++ 20 files changed, 360 insertions(+), 350 deletions(-) delete mode 100644 test/disabled/run/implicits-base.check delete mode 100644 test/disabled/run/implicits-base.scala delete mode 100644 test/disabled/run/implicits-chaining.check delete mode 100644 test/disabled/run/implicits-chaining.scala delete mode 100644 test/disabled/run/implicits-elimination.check delete mode 100644 test/disabled/run/implicits-elimination.scala delete mode 100644 test/disabled/run/implicits-scopes.check delete mode 100644 test/disabled/run/implicits-scopes.scala create mode 100644 test/scaladoc/run/implicits-base.check create mode 100644 test/scaladoc/run/implicits-base.scala create mode 100644 test/scaladoc/run/implicits-chaining.check create mode 100644 test/scaladoc/run/implicits-chaining.scala create mode 100644 test/scaladoc/run/implicits-elimination.check create mode 100644 test/scaladoc/run/implicits-elimination.scala create mode 100644 test/scaladoc/run/implicits-scopes.check create mode 100644 test/scaladoc/run/implicits-scopes.scala diff --git a/test/disabled/run/implicits-base.check b/test/disabled/run/implicits-base.check deleted file mode 100644 index 619c56180b..0000000000 --- a/test/disabled/run/implicits-base.check +++ /dev/null @@ -1 +0,0 @@ -Done. diff --git a/test/disabled/run/implicits-base.scala b/test/disabled/run/implicits-base.scala deleted file mode 100644 index 06d017ed70..0000000000 --- a/test/disabled/run/implicits-base.scala +++ /dev/null @@ -1,180 +0,0 @@ -import scala.tools.nsc.doc.model._ -import scala.tools.partest.ScaladocModelTest -import language._ - -object Test extends ScaladocModelTest { - - // test a file instead of a piece of code - override def resourceFile = "implicits-base-res.scala" - - // start implicits - def scaladocSettings = "-implicits -implicits-show-all" - - def testModel(root: Package) = { - // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) - import access._ - - // SEE THE test/resources/implicits-base-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: - val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("base") - var conv: ImplicitConversion = null - -//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val A = base._class("A") - - // the method pimped on by pimpA0 should be shadowed by the method in class A - assert(A._conversions(A.qualifiedName + ".pimpA0").isEmpty) - - // def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope - conv = A._conversion(A.qualifiedName + ".pimpA1") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToNumericA").resultType.name == "T") - - // def convToIntA: Int // pimpA2: with a constraint that T = Int - conv = A._conversion(A.qualifiedName + ".pimpA2") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToIntA").resultType.name == "Int") - - // def convToGtColonDoubleA: Double // pimpA3: with a constraint that T <: Double - conv = A._conversion(A.qualifiedName + ".pimpA3") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") - - // def convToPimpedA: S // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar - conv = A._conversion(A.qualifiedName + ".pimpA4") - assert(conv.members.length == 1) - assert(conv.constraints.length == 3) - assert(conv._member("convToPimpedA").resultType.name == "S") - - // def convToPimpedA: Bar[Foo[T]] // pimpA5: no constraints - conv = A._conversion(A.qualifiedName + ".pimpA5") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[T]]") - - // def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope - conv = A._conversion(A.qualifiedName + ".pimpA6") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToMyNumericA").resultType.name == "T") - - // def convToManifestA: T // pimpA7: with 2 constraints: T: Manifest and T <: Double - // def convToTraversableOps: T // pimpA7: with 2 constraints: T: Manifest and T <: Double - // should not be abstract! - conv = A._conversion(A.qualifiedName + ".pimpA7") - assert(conv.members.length == 2) - assert(conv.constraints.length == 2) - assert(conv._member("convToManifestA").resultType.name == "T") - assert(conv._member("convToTraversableOps").resultType.name == "T") - assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1) - -//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val B = base._class("B") - - // these conversions should not affect B - assert(B._conversions(A.qualifiedName + ".pimpA0").isEmpty) - assert(B._conversions(A.qualifiedName + ".pimpA2").isEmpty) - assert(B._conversions(A.qualifiedName + ".pimpA4").isEmpty) - - // def convToNumericA: Double // pimpA1: no constraintsd - conv = B._conversion(A.qualifiedName + ".pimpA1") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToNumericA").resultType.name == "Double") - - // def convToGtColonDoubleA: Double // pimpA3: no constraints - conv = B._conversion(A.qualifiedName + ".pimpA3") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") - - // def convToPimpedA: Bar[Foo[Double]] // pimpA5: no constraints - conv = B._conversion(A.qualifiedName + ".pimpA5") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Double]]") - - // def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope - conv = B._conversion(A.qualifiedName + ".pimpA6") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToMyNumericA").resultType.name == "Double") - - // def convToManifestA: Double // pimpA7: no constraints - // def convToTraversableOps: Double // pimpA7: no constraints - // // should not be abstract! - conv = B._conversion(A.qualifiedName + ".pimpA7") - assert(conv.members.length == 2) - assert(conv.constraints.length == 0) - assert(conv._member("convToManifestA").resultType.name == "Double") - assert(conv._member("convToTraversableOps").resultType.name == "Double") - assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1) - -//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val C = base._class("C") - - // these conversions should not affect C - assert(C._conversions(A.qualifiedName + ".pimpA0").isEmpty) - assert(C._conversions(A.qualifiedName + ".pimpA3").isEmpty) - assert(C._conversions(A.qualifiedName + ".pimpA4").isEmpty) - assert(C._conversions(A.qualifiedName + ".pimpA7").isEmpty) - - // def convToNumericA: Int // pimpA1: no constraints - conv = C._conversion(A.qualifiedName + ".pimpA1") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToNumericA").resultType.name == "Int") - - // def convToIntA: Int // pimpA2: no constraints - conv = C._conversion(A.qualifiedName + ".pimpA2") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToIntA").resultType.name == "Int") - - // def convToPimpedA: Bar[Foo[Int]] // pimpA5: no constraints - conv = C._conversion(A.qualifiedName + ".pimpA5") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Int]]") - - // def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope - conv = C._conversion(A.qualifiedName + ".pimpA6") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToMyNumericA").resultType.name == "Int") - -//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val D = base._class("D") - - // these conversions should not affect D - assert(D._conversions(A.qualifiedName + ".pimpA0").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA2").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA3").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA4").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA7").isEmpty) - - // def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope - conv = D._conversion(A.qualifiedName + ".pimpA1") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToNumericA").resultType.name == "String") - - // def convToPimpedA: Bar[Foo[String]] // pimpA5: no constraints - conv = D._conversion(A.qualifiedName + ".pimpA5") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[String]]") - - // def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope - conv = D._conversion(A.qualifiedName + ".pimpA6") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - assert(conv._member("convToMyNumericA").resultType.name == "String") - } -} diff --git a/test/disabled/run/implicits-chaining.check b/test/disabled/run/implicits-chaining.check deleted file mode 100644 index 619c56180b..0000000000 --- a/test/disabled/run/implicits-chaining.check +++ /dev/null @@ -1 +0,0 @@ -Done. diff --git a/test/disabled/run/implicits-chaining.scala b/test/disabled/run/implicits-chaining.scala deleted file mode 100644 index 858ca9ce61..0000000000 --- a/test/disabled/run/implicits-chaining.scala +++ /dev/null @@ -1,65 +0,0 @@ -import scala.tools.nsc.doc.model._ -import scala.tools.partest.ScaladocModelTest -import language._ - -object Test extends ScaladocModelTest { - - // test a file instead of a piece of code - override def resourceFile = "implicits-chaining-res.scala" - - // start implicits - def scaladocSettings = "-implicits" - - def testModel(root: Package) = { - // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) - import access._ - - // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: - val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("chaining") - var conv: ImplicitConversion = null - -//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val A = base._class("A") - - conv = A._conversion(base.qualifiedName + ".convertToZ") - assert(conv.members.length == 1) - assert(conv.constraints.length == 1) - -//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val B = base._class("B") - - conv = B._conversion(base.qualifiedName + ".convertToZ") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - -//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val C = base._class("C") - - assert(C._conversions(base.qualifiedName + ".convertToZ").isEmpty) - -//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val D = base._class("D") - - conv = D._conversion(base.qualifiedName + ".convertToZ") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - -//// class E /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val E = base._class("E") - - conv = E._conversion(base.qualifiedName + ".convertToZ") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - -//// class F /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val F = base._class("F") - - assert(F._conversions(base.qualifiedName + ".convertToZ").isEmpty) - } -} diff --git a/test/disabled/run/implicits-elimination.check b/test/disabled/run/implicits-elimination.check deleted file mode 100644 index 619c56180b..0000000000 --- a/test/disabled/run/implicits-elimination.check +++ /dev/null @@ -1 +0,0 @@ -Done. diff --git a/test/disabled/run/implicits-elimination.scala b/test/disabled/run/implicits-elimination.scala deleted file mode 100644 index ed37b9cd90..0000000000 --- a/test/disabled/run/implicits-elimination.scala +++ /dev/null @@ -1,23 +0,0 @@ -import scala.tools.nsc.doc.model._ -import scala.tools.partest.ScaladocModelTest -import language._ - -object Test extends ScaladocModelTest { - - // test a file instead of a piece of code - override def resourceFile = "implicits-elimination-res.scala" - - // start implicits - def scaladocSettings = "-implicits" - - def testModel(root: Package) = { - // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) - import access._ - - // SEE THE test/resources/implicits-elimination-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: - val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("elimination") - val A = base._class("A") - - assert(A._conversions(A.qualifiedName + ".toB").isEmpty) - } -} diff --git a/test/disabled/run/implicits-scopes.check b/test/disabled/run/implicits-scopes.check deleted file mode 100644 index 619c56180b..0000000000 --- a/test/disabled/run/implicits-scopes.check +++ /dev/null @@ -1 +0,0 @@ -Done. diff --git a/test/disabled/run/implicits-scopes.scala b/test/disabled/run/implicits-scopes.scala deleted file mode 100644 index 7b9e80e148..0000000000 --- a/test/disabled/run/implicits-scopes.scala +++ /dev/null @@ -1,77 +0,0 @@ -import scala.tools.nsc.doc.model._ -import scala.tools.partest.ScaladocModelTest -import language._ - -object Test extends ScaladocModelTest { - - // test a file instead of a piece of code - override def resourceFile = "implicits-scopes-res.scala" - - // start implicits - def scaladocSettings = "-implicits" - - def testModel(root: Package) = { - // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) - import access._ - var conv: ImplicitConversion = null - - // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: - val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("scopes") - -//// test1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val doTest1 = { - val test1 = base._package("test1") - val A = test1._class("A") - - conv = A._conversion(test1.qualifiedName + ".package.toB") // the .package means it's the package object - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - } - -//// test2 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val doTest2 = { - val test2 = base._package("test2") - val classes = test2._package("classes") - val A = classes._class("A") - - assert(A._conversions(test2.qualifiedName + ".toB").isEmpty) - } - -//// test3 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val doTest3 = { - val test3 = base._package("test3") - val A = test3._class("A") - - conv = A._conversion(A.qualifiedName + ".toB") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - } - -//// test4 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val doTest4 = { - val test4 = base._package("test4") - val A = test4._class("A") - val S = test4._object("S") - - conv = A._conversion(S.qualifiedName + ".toB") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - } - -//// test5 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - val doTest5 = { - val test5 = base._package("test5") - val scope = test5._object("scope") - val A = scope._class("A") - - conv = A._conversion(scope.qualifiedName + ".toB") - assert(conv.members.length == 1) - assert(conv.constraints.length == 0) - } - } -} diff --git a/test/scaladoc/resources/implicits-base-res.scala b/test/scaladoc/resources/implicits-base-res.scala index db7ca4fa51..ce86ba8918 100644 --- a/test/scaladoc/resources/implicits-base-res.scala +++ b/test/scaladoc/resources/implicits-base-res.scala @@ -28,6 +28,8 @@ class A[T] { } /** Companion object with implicit transformations */ object A { + import language.implicitConversions // according to SIP18 + implicit def pimpA0[V](a: A[V]) = new PimpedA(a) implicit def pimpA1[ZBUR: Numeric](a: A[ZBUR]) = new NumericA[ZBUR](a) implicit def pimpA2(a: A[Int]) = new IntA(a) diff --git a/test/scaladoc/resources/implicits-chaining-res.scala b/test/scaladoc/resources/implicits-chaining-res.scala index b20c8f846c..c005d5fe09 100644 --- a/test/scaladoc/resources/implicits-chaining-res.scala +++ b/test/scaladoc/resources/implicits-chaining-res.scala @@ -3,6 +3,8 @@ */ package scala.test.scaladoc.implicits { + import language.implicitConversions // according to SIP18 + // the classes involved case class Z[U](a: U) case class Intermediate[T, U](t: T, u: U) diff --git a/test/scaladoc/resources/implicits-elimination-res.scala b/test/scaladoc/resources/implicits-elimination-res.scala index 68743aee06..b23667440c 100644 --- a/test/scaladoc/resources/implicits-elimination-res.scala +++ b/test/scaladoc/resources/implicits-elimination-res.scala @@ -2,8 +2,13 @@ * Testing scaladoc implicits elimination */ package scala.test.scaladoc.implicits.elimination { + + import language.implicitConversions // according to SIP18 + /** No conversion, as B doesn't bring any member */ class A class B { class C; trait V; type T; } - object A { implicit def toB(a: A): B = null } + object A { + implicit def toB(a: A): B = null + } } diff --git a/test/scaladoc/resources/implicits-scopes-res.scala b/test/scaladoc/resources/implicits-scopes-res.scala index 4e55c3e388..aaeb43f95b 100644 --- a/test/scaladoc/resources/implicits-scopes-res.scala +++ b/test/scaladoc/resources/implicits-scopes-res.scala @@ -2,6 +2,7 @@ * Testing scaladoc implicit scopes - looking for implicits in the right places */ package scala.test.scaladoc.implicits.scopes +import language.implicitConversions // according to SIP18 // TEST1 - In package object package object test1 { diff --git a/test/scaladoc/run/implicits-base.check b/test/scaladoc/run/implicits-base.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-base.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-base.scala b/test/scaladoc/run/implicits-base.scala new file mode 100644 index 0000000000..06d017ed70 --- /dev/null +++ b/test/scaladoc/run/implicits-base.scala @@ -0,0 +1,180 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest +import language._ + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-base-res.scala" + + // start implicits + def scaladocSettings = "-implicits -implicits-show-all" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // SEE THE test/resources/implicits-base-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("base") + var conv: ImplicitConversion = null + +//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val A = base._class("A") + + // the method pimped on by pimpA0 should be shadowed by the method in class A + assert(A._conversions(A.qualifiedName + ".pimpA0").isEmpty) + + // def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope + conv = A._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToNumericA").resultType.name == "T") + + // def convToIntA: Int // pimpA2: with a constraint that T = Int + conv = A._conversion(A.qualifiedName + ".pimpA2") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToIntA").resultType.name == "Int") + + // def convToGtColonDoubleA: Double // pimpA3: with a constraint that T <: Double + conv = A._conversion(A.qualifiedName + ".pimpA3") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") + + // def convToPimpedA: S // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar + conv = A._conversion(A.qualifiedName + ".pimpA4") + assert(conv.members.length == 1) + assert(conv.constraints.length == 3) + assert(conv._member("convToPimpedA").resultType.name == "S") + + // def convToPimpedA: Bar[Foo[T]] // pimpA5: no constraints + conv = A._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[T]]") + + // def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope + conv = A._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "T") + + // def convToManifestA: T // pimpA7: with 2 constraints: T: Manifest and T <: Double + // def convToTraversableOps: T // pimpA7: with 2 constraints: T: Manifest and T <: Double + // should not be abstract! + conv = A._conversion(A.qualifiedName + ".pimpA7") + assert(conv.members.length == 2) + assert(conv.constraints.length == 2) + assert(conv._member("convToManifestA").resultType.name == "T") + assert(conv._member("convToTraversableOps").resultType.name == "T") + assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1) + +//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val B = base._class("B") + + // these conversions should not affect B + assert(B._conversions(A.qualifiedName + ".pimpA0").isEmpty) + assert(B._conversions(A.qualifiedName + ".pimpA2").isEmpty) + assert(B._conversions(A.qualifiedName + ".pimpA4").isEmpty) + + // def convToNumericA: Double // pimpA1: no constraintsd + conv = B._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToNumericA").resultType.name == "Double") + + // def convToGtColonDoubleA: Double // pimpA3: no constraints + conv = B._conversion(A.qualifiedName + ".pimpA3") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") + + // def convToPimpedA: Bar[Foo[Double]] // pimpA5: no constraints + conv = B._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Double]]") + + // def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope + conv = B._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "Double") + + // def convToManifestA: Double // pimpA7: no constraints + // def convToTraversableOps: Double // pimpA7: no constraints + // // should not be abstract! + conv = B._conversion(A.qualifiedName + ".pimpA7") + assert(conv.members.length == 2) + assert(conv.constraints.length == 0) + assert(conv._member("convToManifestA").resultType.name == "Double") + assert(conv._member("convToTraversableOps").resultType.name == "Double") + assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1) + +//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val C = base._class("C") + + // these conversions should not affect C + assert(C._conversions(A.qualifiedName + ".pimpA0").isEmpty) + assert(C._conversions(A.qualifiedName + ".pimpA3").isEmpty) + assert(C._conversions(A.qualifiedName + ".pimpA4").isEmpty) + assert(C._conversions(A.qualifiedName + ".pimpA7").isEmpty) + + // def convToNumericA: Int // pimpA1: no constraints + conv = C._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToNumericA").resultType.name == "Int") + + // def convToIntA: Int // pimpA2: no constraints + conv = C._conversion(A.qualifiedName + ".pimpA2") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToIntA").resultType.name == "Int") + + // def convToPimpedA: Bar[Foo[Int]] // pimpA5: no constraints + conv = C._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Int]]") + + // def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope + conv = C._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "Int") + +//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val D = base._class("D") + + // these conversions should not affect D + assert(D._conversions(A.qualifiedName + ".pimpA0").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA2").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA3").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA4").isEmpty) + assert(D._conversions(A.qualifiedName + ".pimpA7").isEmpty) + + // def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope + conv = D._conversion(A.qualifiedName + ".pimpA1") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToNumericA").resultType.name == "String") + + // def convToPimpedA: Bar[Foo[String]] // pimpA5: no constraints + conv = D._conversion(A.qualifiedName + ".pimpA5") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[String]]") + + // def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope + conv = D._conversion(A.qualifiedName + ".pimpA6") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + assert(conv._member("convToMyNumericA").resultType.name == "String") + } +} diff --git a/test/scaladoc/run/implicits-chaining.check b/test/scaladoc/run/implicits-chaining.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-chaining.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-chaining.scala b/test/scaladoc/run/implicits-chaining.scala new file mode 100644 index 0000000000..858ca9ce61 --- /dev/null +++ b/test/scaladoc/run/implicits-chaining.scala @@ -0,0 +1,65 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest +import language._ + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-chaining-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("chaining") + var conv: ImplicitConversion = null + +//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val A = base._class("A") + + conv = A._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 1) + +//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val B = base._class("B") + + conv = B._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + +//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val C = base._class("C") + + assert(C._conversions(base.qualifiedName + ".convertToZ").isEmpty) + +//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val D = base._class("D") + + conv = D._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + +//// class E /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val E = base._class("E") + + conv = E._conversion(base.qualifiedName + ".convertToZ") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + +//// class F /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val F = base._class("F") + + assert(F._conversions(base.qualifiedName + ".convertToZ").isEmpty) + } +} diff --git a/test/scaladoc/run/implicits-elimination.check b/test/scaladoc/run/implicits-elimination.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-elimination.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-elimination.scala b/test/scaladoc/run/implicits-elimination.scala new file mode 100644 index 0000000000..ed37b9cd90 --- /dev/null +++ b/test/scaladoc/run/implicits-elimination.scala @@ -0,0 +1,23 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest +import language._ + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-elimination-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // SEE THE test/resources/implicits-elimination-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("elimination") + val A = base._class("A") + + assert(A._conversions(A.qualifiedName + ".toB").isEmpty) + } +} diff --git a/test/scaladoc/run/implicits-scopes.check b/test/scaladoc/run/implicits-scopes.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-scopes.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-scopes.scala b/test/scaladoc/run/implicits-scopes.scala new file mode 100644 index 0000000000..7b9e80e148 --- /dev/null +++ b/test/scaladoc/run/implicits-scopes.scala @@ -0,0 +1,77 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest +import language._ + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-scopes-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + var conv: ImplicitConversion = null + + // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("scopes") + +//// test1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest1 = { + val test1 = base._package("test1") + val A = test1._class("A") + + conv = A._conversion(test1.qualifiedName + ".package.toB") // the .package means it's the package object + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + +//// test2 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest2 = { + val test2 = base._package("test2") + val classes = test2._package("classes") + val A = classes._class("A") + + assert(A._conversions(test2.qualifiedName + ".toB").isEmpty) + } + +//// test3 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest3 = { + val test3 = base._package("test3") + val A = test3._class("A") + + conv = A._conversion(A.qualifiedName + ".toB") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + +//// test4 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest4 = { + val test4 = base._package("test4") + val A = test4._class("A") + val S = test4._object("S") + + conv = A._conversion(S.qualifiedName + ".toB") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + +//// test5 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val doTest5 = { + val test5 = base._package("test5") + val scope = test5._object("scope") + val A = scope._class("A") + + conv = A._conversion(scope.qualifiedName + ".toB") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + } + } +} -- cgit v1.2.3 From cb2468a8a0971207ceb33c7bb9d2596bdbac8072 Mon Sep 17 00:00:00 2001 From: Vlad Ureche Date: Sat, 14 Apr 2012 12:40:03 +0200 Subject: Reimplemented shadowing between class members and implicit pimped on members. Thanks to Lukas for pointing it out! --- .../doc/model/ModelFactoryImplicitSupport.scala | 22 ++++++- test/scaladoc/resources/implicits-base-res.scala | 66 ++++++++++---------- .../resources/implicits-shadowing-res.scala | 64 ++++++++++++++++++++ test/scaladoc/run/implicits-shadowing.check | 1 + test/scaladoc/run/implicits-shadowing.scala | 70 ++++++++++++++++++++++ 5 files changed, 189 insertions(+), 34 deletions(-) create mode 100644 test/scaladoc/resources/implicits-shadowing-res.scala create mode 100644 test/scaladoc/run/implicits-shadowing.check create mode 100644 test/scaladoc/run/implicits-shadowing.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 23bef02bed..0e44933ac6 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -137,8 +137,8 @@ trait ModelFactoryImplicitSupport { // Members inherited by implicit conversions cannot override actual members memberSyms = memberSyms.filterNot((sym1: Symbol) => - existingMembers.exists(sym2 => sym1.name == sym2.name && - isSameType(toType.memberInfo(sym1), sym.info.memberInfo(sym2)))) + existingMembers.exists(sym2 => sym1.name == sym2.name && + !isDistinguishableFrom(toType.memberInfo(sym1), sym.info.memberInfo(sym2)))) debug(" -> full type: " + toType) if (constraints.length != 0) { @@ -498,4 +498,22 @@ trait ModelFactoryImplicitSupport { (aSym.isMethod || aSym.isGetter || aSym.isSetter) && (aSym.nameString != "getClass") } + + /* To put it very bluntly: checks if you can call implicitly added method with t1 when t2 is already there in the + * class. We suppose the name of the two members coincides + * + * The trick here is that the resultType does not matter - the condition for removal it that paramss have the same + * structure (A => B => C may not override (A, B) => C) and that all the types involved are + * of the implcit conversion's member are subtypes of the parent members' parameters */ + def isDistinguishableFrom(t1: Type, t2: Type): Boolean = + if (t1.paramss.map(_.length) == t2.paramss.map(_.length)) { + for ((t1p, t2p) <- t1.paramss.flatten zip t2.paramss.flatten) + if (!isSubType(t1 memberInfo t1p, t2 memberInfo t2p)) + return true // if on the corresponding parameter you give a type that is in t1 but not in t2 + // example: + // def foo(a: Either[Int, Double]): Int = 3 + // def foo(b: Left[T1]): Int = 6 + // a.foo(Right(4.5d)) prints out 3 :) + false + } else true // the member structure is different foo(3, 5) vs foo(3)(5) } \ No newline at end of file diff --git a/test/scaladoc/resources/implicits-base-res.scala b/test/scaladoc/resources/implicits-base-res.scala index ce86ba8918..3e3d0f01a6 100644 --- a/test/scaladoc/resources/implicits-base-res.scala +++ b/test/scaladoc/resources/implicits-base-res.scala @@ -11,20 +11,22 @@ trait MyNumeric[R] * - tests the complete type inference * - the following inherited methods should appear: * {{{ - * def convToGtColonDoubleA: Double // pimpA3: with a constraint that T <: Double - * def convToIntA: Int // pimpA2: with a constraint that T = Int - * def convToManifestA: T // pimpA7: with 2 constraints: T: Manifest and T <: Double - * def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope - * def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope - * def convToPimpedA: Bar[Foo[T]] // pimpA5: no constraints - * def convToPimpedA: S // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar - * def convToTraversableOps: T // pimpA7: with 2 constraints: T: Manifest and T <: Double - * // should not be abstract! + * def convToGtColonDoubleA(x: Double) // pimpA3: with a constraint that T <: Double + * def convToIntA(x: Int) // pimpA2: with a constraint that T = Int + * def convToManifestA(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double + * def convToMyNumericA(x: T) // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope + * def convToNumericA(x: T) // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope + * def convToPimpedA(x: Bar[Foo[T]]) // pimpA5: no constraints + * def convToPimpedA(x: S) // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar + * def convToTraversableOps(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double + * // should not be abstract! * }}} */ class A[T] { /** This should prevent the implicitly inherited `def convToPimpedA: T` from `pimpA0` from showing up */ - def convToPimpedA: T = sys.error("Let's check it out!") + def convToPimpedA(x: T): T = sys.error("Let's check it out!") + /** This should check implicit member elimination in the case of subtyping */ + def foo(a: T, b: AnyRef): T } /** Companion object with implicit transformations */ object A { @@ -38,7 +40,7 @@ object A { implicit def pimpA5[Z](a: A[Z]): PimpedA[Bar[Foo[Z]]] = sys.error("not implemented") implicit def pimpA6[Z: MyNumeric](a: A[Z]) = new MyNumericA[Z](a) // TODO: Add H <: Double and see why it crashes for C and D -- context bounds, need to check! - implicit def pimpA7[H <: Double : Manifest](a: A[H]) = new ManifestA[H](a) with MyTraversableOps[H] { def convToTraversableOps: H = sys.error("no") } + implicit def pimpA7[H <: Double : Manifest](a: A[H]) = new ManifestA[H](a) with MyTraversableOps[H] { def convToTraversableOps(x: H): H = sys.error("no") } } @@ -46,13 +48,13 @@ object A { * - tests the existential type solving * - the following inherited methods should appear: * {{{ - * def convToGtColonDoubleA: Double // pimpA3: no constraints - * def convToManifestA: Double // pimpA7: no constraints - * def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope - * def convToNumericA: Double // pimpA1: no constraintsd - * def convToPimpedA: Bar[Foo[Double]] // pimpA5: no constraints - * def convToTraversableOps: Double // pimpA7: no constraints - * // should not be abstract! + * def convToGtColonDoubleA(x: Double) // pimpA3: no constraints + * def convToManifestA(x: Double) // pimpA7: no constraints + * def convToMyNumericA(x: Double) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope + * def convToNumericA(x: Double) // pimpA1: no constraintsd + * def convToPimpedA(x: Bar[Foo[Double]]) // pimpA5: no constraints + * def convToTraversableOps(x: Double) // pimpA7: no constraints + * // should not be abstract! * }}} */ class B extends A[Double] @@ -63,10 +65,10 @@ object B extends A * - tests asSeenFrom * - the following inherited methods should appear: * {{{ - * def convToIntA: Int // pimpA2: no constraints - * def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope - * def convToNumericA: Int // pimpA1: no constraints - * def convToPimpedA: Bar[Foo[Int]] // pimpA5: no constraints + * def convToIntA(x: Int) // pimpA2: no constraints + * def convToMyNumericA(x: Int) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope + * def convToNumericA(x: Int) // pimpA1: no constraints + * def convToPimpedA(x: Bar[Foo[Int]]) // pimpA5: no constraints * }}} */ class C extends A[Int] @@ -77,9 +79,9 @@ object C extends A * - tests implicit elimination * - the following inherited methods should appear: * {{{ - * def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope - * def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope - * def convToPimpedA: Bar[Foo[String]] // pimpA5: no constraints + * def convToMyNumericA(x: String) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope + * def convToNumericA(x: String) // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope + * def convToPimpedA(x: Bar[Foo[String]]) // pimpA5: no constraints * }}} */ class D extends A[String] @@ -92,7 +94,7 @@ object D extends A * - A, B and C should be implicitly converted to this */ class PimpedA[V](a: A[V]) { /** The convToPimpedA: V documentation... */ - def convToPimpedA: V = sys.error("Not implemented") + def convToPimpedA(x: V): V = sys.error("Not implemented") } /** NumericA class
    @@ -100,7 +102,7 @@ class PimpedA[V](a: A[V]) { * - A, B and C should be implicitly converted to this */ class NumericA[U: Numeric](a: A[U]) { /** The convToNumericA: U documentation... */ - def convToNumericA: U = implicitly[Numeric[U]].zero + def convToNumericA(x: U): U = implicitly[Numeric[U]].zero } /** IntA class
    @@ -108,7 +110,7 @@ class NumericA[U: Numeric](a: A[U]) { * - A and C should be implicitly converted to this */ class IntA(a: A[Int]) { /** The convToIntA: Int documentation... */ - def convToIntA: Int = 0 + def convToIntA(x: Int): Int = 0 } /** GtColonDoubleA class
    @@ -116,7 +118,7 @@ class IntA(a: A[Int]) { * - A and B should be implicitly converted to this */ class GtColonDoubleA(a: A[T] forSome { type T <: Double }) { /** The convToGtColonDoubleA: Double documentation... */ - def convToGtColonDoubleA: Double = 0 + def convToGtColonDoubleA(x: Double): Double = 0 } /** MyNumericA class
    @@ -124,7 +126,7 @@ class GtColonDoubleA(a: A[T] forSome { type T <: Double }) { * - A should be implicitly converted to this */ class MyNumericA[U: MyNumeric](a: A[U]) { /** The convToMyNumericA: U documentation... */ - def convToMyNumericA: U = sys.error("dunno") + def convToMyNumericA(x: U): U = sys.error("dunno") } /** ManifestA class
    @@ -132,7 +134,7 @@ class MyNumericA[U: MyNumeric](a: A[U]) { * - A, B, C, D should be implicitly converted to this */ class ManifestA[W: Manifest](a: A[W]) { /** The convToManifestA: W documentation... */ - def convToManifestA: W = sys.error("dunno") + def convToManifestA(x: W): W = sys.error("dunno") } /** MyTraversableOps class
    @@ -140,6 +142,6 @@ class ManifestA[W: Manifest](a: A[W]) { */ trait MyTraversableOps[S] { /** The convToTraversableOps: S documentation... */ - def convToTraversableOps: S + def convToTraversableOps(x: S): S } diff --git a/test/scaladoc/resources/implicits-shadowing-res.scala b/test/scaladoc/resources/implicits-shadowing-res.scala new file mode 100644 index 0000000000..c5e9493bf3 --- /dev/null +++ b/test/scaladoc/resources/implicits-shadowing-res.scala @@ -0,0 +1,64 @@ +/** + * Test scaladoc implicits distinguishing -- supress all members by implicit conversion that are shadowed by the + * class' own members + * + * {{{ + * scala> class A { def foo(t: String) = 4 } + * defined class A + * + * scala> class B { def foo(t: Any) = 5 } + * defined class B + * + * scala> implicit def AtoB(a:A) = new B + * AtoB: (a: A)B + * + * scala> val a = new A + * a: A = A@28f553e3 + * + * scala> a.foo("T") + * res1: Int = 4 + * + * scala> a.foo(4) + * res2: Int = 5 + * }}} + */ +package scala.test.scaladoc.implicits.shadowing +import language.implicitConversions // according to SIP18 + +/** conv5, conv8, conv9, conv10, conv11 should be visible */ +class A[T] { + def conv1: AnyRef = ??? + def conv2: T = ??? + def conv3(l: Int): AnyRef = ??? + def conv4(l: AnyRef): AnyRef = ??? + def conv5(l: String): AnyRef = ??? + def conv6(l: AnyRef): AnyRef = ??? + def conv7(l: AnyRef): String = ??? + def conv8(l: String)(m: String): AnyRef = ??? + def conv9(l: AnyRef)(m: AnyRef): AnyRef = ??? + def conv10(l: T): T = ??? + def conv11(l: T): T = ??? +} +/** conv5, conv8, conv9, conv11 should be visible */ +class B extends A[Int] +/** conv5, conv8, conv9, conv10, conv11 should be visible */ +class C extends A[Double] +/** conv5, conv8, conv9, conv10 should be visible */ +class D extends A[AnyRef] + +class Z[T] { + def conv1: AnyRef = ??? + def conv2: T = ??? + def conv3(p: Int): AnyRef = ??? + def conv4(p: String): AnyRef = ??? + def conv5(p: AnyRef): AnyRef = ??? + def conv6(p: AnyRef): String = ??? + def conv7(p: AnyRef): AnyRef = ??? + def conv8(p: String, q: String): AnyRef = ??? + def conv9(p: AnyRef, q: AnyRef): AnyRef = ??? + def conv10(p: Int): T = ??? + def conv11(p: String): T = ??? +} +object A { + implicit def AtoZ[T](a: A[T]) = new Z[T] +} diff --git a/test/scaladoc/run/implicits-shadowing.check b/test/scaladoc/run/implicits-shadowing.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-shadowing.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-shadowing.scala b/test/scaladoc/run/implicits-shadowing.scala new file mode 100644 index 0000000000..7835223d21 --- /dev/null +++ b/test/scaladoc/run/implicits-shadowing.scala @@ -0,0 +1,70 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-shadowing-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("shadowing") + var conv: ImplicitConversion = null + +//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val A = base._class("A") + + conv = A._conversion(base._object("A").qualifiedName + ".AtoZ") + assert(conv.members.length == 5) + conv._member("conv5") + conv._member("conv8") + conv._member("conv9") + conv._member("conv10") + conv._member("conv11") + assert(conv.constraints.length == 0) + +//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val B = base._class("B") + + conv = B._conversion(base._object("A").qualifiedName + ".AtoZ") + assert(conv.members.length == 4) + conv._member("conv5") + conv._member("conv8") + conv._member("conv9") + conv._member("conv11") + assert(conv.constraints.length == 0) + +//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val C = base._class("C") + + conv = C._conversion(base._object("A").qualifiedName + ".AtoZ") + assert(conv.members.length == 5) + conv._member("conv5") + conv._member("conv8") + conv._member("conv9") + conv._member("conv10") + conv._member("conv11") + assert(conv.constraints.length == 0) + +//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val D = base._class("D") + + conv = D._conversion(base._object("A").qualifiedName + ".AtoZ") + assert(conv.members.length == 4) + conv._member("conv5") + conv._member("conv8") + conv._member("conv9") + conv._member("conv10") + assert(conv.constraints.length == 0) + } +} \ No newline at end of file -- cgit v1.2.3 From 0b3b12fb29b8a4a624c4a0bb4520114f10599036 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 14 Apr 2012 11:40:00 +0100 Subject: Move primitive widening implicits to companions. Take a 15-implicit load off Predef and put it where it belongs: on those brave souls who like their longs to get floaty by way of T. --- src/compiler/scala/tools/cmd/gen/AnyVals.scala | 16 ++++++++- src/library/scala/Byte.scala | 5 +++ src/library/scala/Char.scala | 4 +++ src/library/scala/Float.scala | 1 + src/library/scala/Int.scala | 3 ++ src/library/scala/Long.scala | 2 ++ src/library/scala/Predef.scala | 48 +++++++++++++------------- src/library/scala/Short.scala | 4 +++ 8 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/compiler/scala/tools/cmd/gen/AnyVals.scala b/src/compiler/scala/tools/cmd/gen/AnyVals.scala index 0869350dd3..b9f1ee2317 100644 --- a/src/compiler/scala/tools/cmd/gen/AnyVals.scala +++ b/src/compiler/scala/tools/cmd/gen/AnyVals.scala @@ -14,6 +14,20 @@ trait AnyValReps { sealed abstract class AnyValNum(name: String, repr: Option[String], javaEquiv: String) extends AnyValRep(name,repr,javaEquiv) { case class Op(val op : String, val doc : String) + + private def companionCoercions(tos: String*) = { + tos.toList map (to => + """implicit def %s2%s(x: %s): %s = x.to%s""".format(javaEquiv, to, name, to.capitalize, to.capitalize) + ) + } + def implicitCoercions: List[String] = javaEquiv match { + case "byte" => companionCoercions("short", "int", "long", "float", "double") + case "short" | "char" => companionCoercions("int", "long", "float", "double") + case "int" => companionCoercions("long", "float", "double") + case "long" => companionCoercions("float", "double") + case "float" => companionCoercions("double") + case _ => Nil + } def isCardinal: Boolean = isIntegerType(this) def unaryOps = { @@ -160,7 +174,7 @@ trait AnyValReps { } def objectLines = { val comp = if (isCardinal) cardinalCompanion else floatingCompanion - (comp + allCompanions).trim.lines map interpolate toList + ((comp + allCompanions).trim.lines map interpolate).toList ++ implicitCoercions } /** Makes a set of binary operations based on the given set of ops, args, and resultFn. diff --git a/src/library/scala/Byte.scala b/src/library/scala/Byte.scala index f9c5f6003e..4e64b68bbc 100644 --- a/src/library/scala/Byte.scala +++ b/src/library/scala/Byte.scala @@ -622,5 +622,10 @@ object Byte extends AnyValCompanion { /** The String representation of the scala.Byte companion object. */ override def toString = "object scala.Byte" + implicit def byte2short(x: Byte): Short = x.toShort + implicit def byte2int(x: Byte): Int = x.toInt + implicit def byte2long(x: Byte): Long = x.toLong + implicit def byte2float(x: Byte): Float = x.toFloat + implicit def byte2double(x: Byte): Double = x.toDouble } diff --git a/src/library/scala/Char.scala b/src/library/scala/Char.scala index 3d459782cd..8f770316c1 100644 --- a/src/library/scala/Char.scala +++ b/src/library/scala/Char.scala @@ -622,5 +622,9 @@ object Char extends AnyValCompanion { /** The String representation of the scala.Char companion object. */ override def toString = "object scala.Char" + implicit def char2int(x: Char): Int = x.toInt + implicit def char2long(x: Char): Long = x.toLong + implicit def char2float(x: Char): Float = x.toFloat + implicit def char2double(x: Char): Double = x.toDouble } diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala index ff5b3cb112..ddbbd48bf4 100644 --- a/src/library/scala/Float.scala +++ b/src/library/scala/Float.scala @@ -401,5 +401,6 @@ object Float extends AnyValCompanion { /** The String representation of the scala.Float companion object. */ override def toString = "object scala.Float" + implicit def float2double(x: Float): Double = x.toDouble } diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala index 316bbced2d..ef82b1f979 100644 --- a/src/library/scala/Int.scala +++ b/src/library/scala/Int.scala @@ -622,5 +622,8 @@ object Int extends AnyValCompanion { /** The String representation of the scala.Int companion object. */ override def toString = "object scala.Int" + implicit def int2long(x: Int): Long = x.toLong + implicit def int2float(x: Int): Float = x.toFloat + implicit def int2double(x: Int): Double = x.toDouble } diff --git a/src/library/scala/Long.scala b/src/library/scala/Long.scala index ce8618c22a..d57fe8b379 100644 --- a/src/library/scala/Long.scala +++ b/src/library/scala/Long.scala @@ -622,5 +622,7 @@ object Long extends AnyValCompanion { /** The String representation of the scala.Long companion object. */ override def toString = "object scala.Long" + implicit def long2float(x: Long): Float = x.toFloat + implicit def long2double(x: Long): Double = x.toDouble } diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 0954454e41..15e007528b 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -349,30 +349,30 @@ object Predef extends LowPriorityImplicits { // Primitive Widenings -------------------------------------------------------------- - implicit def byte2short(x: Byte): Short = x.toShort - implicit def byte2int(x: Byte): Int = x.toInt - implicit def byte2long(x: Byte): Long = x.toLong - implicit def byte2float(x: Byte): Float = x.toFloat - implicit def byte2double(x: Byte): Double = x.toDouble - - implicit def short2int(x: Short): Int = x.toInt - implicit def short2long(x: Short): Long = x.toLong - implicit def short2float(x: Short): Float = x.toFloat - implicit def short2double(x: Short): Double = x.toDouble - - implicit def char2int(x: Char): Int = x.toInt - implicit def char2long(x: Char): Long = x.toLong - implicit def char2float(x: Char): Float = x.toFloat - implicit def char2double(x: Char): Double = x.toDouble - - implicit def int2long(x: Int): Long = x.toLong - implicit def int2float(x: Int): Float = x.toFloat - implicit def int2double(x: Int): Double = x.toDouble - - implicit def long2float(x: Long): Float = x.toFloat - implicit def long2double(x: Long): Double = x.toDouble - - implicit def float2double(x: Float): Double = x.toDouble + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2short(x: Byte): Short = x.toShort + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2int(x: Byte): Int = x.toInt + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2long(x: Byte): Long = x.toLong + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2float(x: Byte): Float = x.toFloat + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2double(x: Byte): Double = x.toDouble + + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2int(x: Short): Int = x.toInt + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2long(x: Short): Long = x.toLong + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2float(x: Short): Float = x.toFloat + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2double(x: Short): Double = x.toDouble + + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2int(x: Char): Int = x.toInt + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2long(x: Char): Long = x.toLong + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2float(x: Char): Float = x.toFloat + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2double(x: Char): Double = x.toDouble + + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2long(x: Int): Long = x.toLong + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2float(x: Int): Float = x.toFloat + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2double(x: Int): Double = x.toDouble + + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def long2float(x: Long): Float = x.toFloat + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def long2double(x: Long): Double = x.toDouble + + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def float2double(x: Float): Double = x.toDouble // "Autoboxing" and "Autounboxing" --------------------------------------------------- diff --git a/src/library/scala/Short.scala b/src/library/scala/Short.scala index 5664c3b44c..707f9bc4eb 100644 --- a/src/library/scala/Short.scala +++ b/src/library/scala/Short.scala @@ -622,5 +622,9 @@ object Short extends AnyValCompanion { /** The String representation of the scala.Short companion object. */ override def toString = "object scala.Short" + implicit def short2int(x: Short): Int = x.toInt + implicit def short2long(x: Short): Long = x.toLong + implicit def short2float(x: Short): Float = x.toFloat + implicit def short2double(x: Short): Double = x.toDouble } -- cgit v1.2.3 From fb0024ce18e57bd24d87ca9bab6b81af4d52a5ce Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 14 Apr 2012 09:27:15 -0700 Subject: Made checkFeature conditionally run immediately. Adapted Macros to make use of it. --- .../scala/tools/nsc/typechecker/Macros.scala | 11 +-------- .../scala/tools/nsc/typechecker/Typers.scala | 27 ++++++++++++++++++---- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index b7e0eaef2b..62a0e08aad 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -185,16 +185,7 @@ trait Macros { self: Analyzer => import typer.context if (macroDebug) println("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos)) - typer.checkFeature(ddef.pos, MacrosFeature) - - // [Eugene to Martin] todo. copy/pasted this from checkFeature, because don't know a better way - // this is necessary to prevent macros from typechecking/expanding when they are not enabled - // `checkFeature` call alone is not enough, because it merely posts validation callback to unit.toCheck - def hasImport = inferImplicit(EmptyTree: Tree, MacrosFeature.tpe, true, false, typer.context) != SearchFailure - val nestedOwners = MacrosFeature.owner.ownerChain.takeWhile(_ != languageFeatureModule.moduleClass).reverse - val featureName = (nestedOwners map (_.name + ".")).mkString + MacrosFeature.name - def hasOption = settings.language.value contains featureName - if (!hasImport && !hasOption) { + if (!typer.checkFeature(ddef.pos, MacrosFeature, immediate = true)) { ddef.symbol setFlag IS_ERROR return EmptyTree } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 0541f85f31..043e826d32 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -733,15 +733,27 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } } - def checkFeature(pos: Position, featureTrait: Symbol, construct: => String = "") = - if (!isPastTyper) { + /** Check whether feature given by `featureTrait` is enabled. + * If it is not, issue an error or a warning depending on whether the feature is required. + * @param construct A string expression that is substituted for "#" in the feature description string + * @param immediate When set, feature check is run immediately, otherwise it is run + * at the end of the typechecking run for the enclosing unit. This + * is done to avoid potential cyclic reference errors by implicits + * that are forced too early. + * @return if feature check is run immediately: true if feature is enabled, false otherwise + * if feature check is delayed or suppressed because we are past typer: true + */ + def checkFeature(pos: Position, featureTrait: Symbol, construct: => String = "", immediate: Boolean = false): Boolean = + if (isPastTyper) true + else { val nestedOwners = featureTrait.owner.ownerChain.takeWhile(_ != languageFeatureModule.moduleClass).reverse val featureName = (nestedOwners map (_.name + ".")).mkString + featureTrait.name - unit.toCheck += { () => + def action(): Boolean = { def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, true, false, context) != SearchFailure def hasOption = settings.language.value contains featureName - if (!hasImport && !hasOption) { + val OK = hasImport || hasOption + if (!OK) { val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) = featureTrait getAnnotation LanguageFeatureAnnot val req = if (required) "needs to" else "should" @@ -757,6 +769,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (required) unit.error(pos, msg) else currentRun.featureWarnings.warn(pos, msg) } + OK + } + if (immediate) { + action() + } else { + unit.toCheck += action + true } } -- cgit v1.2.3 From 9998a85b4c20f5f40b1739b379a11f005e2d8a80 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Sat, 14 Apr 2012 18:03:32 +0200 Subject: work around optimizer bug SI-5672 the optimizer generates wrong bytecode for switches in arguments virtpatmat happily emits a switch for a one-case switch, whereas -Xoldpatmat did not this is not the focus of this test, hence the temporary workaround --- test/files/run/t3835.scala | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/files/run/t3835.scala b/test/files/run/t3835.scala index 49e591195f..c120a61f6e 100644 --- a/test/files/run/t3835.scala +++ b/test/files/run/t3835.scala @@ -1,4 +1,9 @@ object Test extends App { - println((1, 2, 3) match { case (r, \u03b8, \u03c6) => r + \u03b8 + \u03c6 }) - println(1 match { case \u00e9 => \u00e9 }) + // work around optimizer bug SI-5672 -- generates wrong bytecode for switches in arguments + // virtpatmat happily emits a switch for a one-case switch, whereas -Xoldpatmat did not + // this is not the focus of this test, hence the temporary workaround + def a = (1, 2, 3) match { case (r, \u03b8, \u03c6) => r + \u03b8 + \u03c6 } + println(a) + def b = (1 match { case \u00e9 => \u00e9 }) + println(b) } -- cgit v1.2.3 From f8653625f67f9f1b5d123e43f5b3b36d8067563e Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Sun, 15 Apr 2012 02:51:00 +0900 Subject: change Application to App in scaladoc sample code --- src/library/scala/xml/factory/LoggedNodeFactory.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/scala/xml/factory/LoggedNodeFactory.scala b/src/library/scala/xml/factory/LoggedNodeFactory.scala index abf8f97f03..45ba9530e1 100644 --- a/src/library/scala/xml/factory/LoggedNodeFactory.scala +++ b/src/library/scala/xml/factory/LoggedNodeFactory.scala @@ -12,7 +12,7 @@ package factory /** This class logs what the nodefactory is actually doing. * If you want to see what happens during loading, use it like this: {{{ -object testLogged extends Application { +object testLogged extends App { val x = new scala.xml.parsing.NoBindingFactoryAdapter with scala.xml.factory.LoggedNodeFactory[scala.xml.Elem] with scala.util.logging.ConsoleLogger -- cgit v1.2.3 From 76903fe0b51ece5a994bab7ba19ecf57b93dc2bd Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 14 Apr 2012 11:13:13 -0700 Subject: Added preliminary doc comments to language object. --- src/library/scala/language.scala | 99 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/src/library/scala/language.scala b/src/library/scala/language.scala index 907adb5f72..2837187d48 100644 --- a/src/library/scala/language.scala +++ b/src/library/scala/language.scala @@ -4,22 +4,121 @@ object language { import languageFeature._ + /** Where enabled, direct or indirect subclasses of trait scala.Dynamic can + * be defined. Unless dynamics is enabled, a definition of a class, trait, + * or object that has Dynamic as a base trait is rejected. Dynamic member + * selection of existing subclasses of trait Dynamic are unaffected; + * they can be used anywhere. + * + * _Why introduce the feature?_ To enable flexible DSLs and convenient interfacing + * with dynamic languages. + * + * _Why control it?_ Dynamic member selection can undermine static checkability + * of programs. Furthermore, dynamic member selection often relies on reflection, + * which is not available on all platforms. + */ implicit val dynamics: dynamics = ??? + /** Only where enabled, postfix operator notation `(expr op)` will be allowed. + * + * _Why keep the feature?_ Several DSLs written in Scala need the notation. + * + * _Why control it?_ Postfix operators interact poorly with semicolon inference. + * Most programmers avoid them for this reason. + */ implicit val postfixOps: postfixOps = ??? + /** Only where enabled, accesses to members of structural types that need + * reflection are supported. Reminder: A structural type is a type of the form + * `Parents { Decls }` where `Decls` contains declarations of new members that do + * not override any member in `Parents`. To access one of these members, a + * reflective call is needed. + * + * _Why keep the feature?_ Structural types provide great flexibility because + * they avoid the need to define inheritance hierarchies a priori. Besides, + * their definition falls out quite naturally from Scala’s concept of type refinement. + * + * _Why control it?+ Reflection is not available on all platforms. Popular tools + * such as ProGuard have problems dealing with it. Even where reflection is available, + * reflective dispatch can lead to surprising performance degradations. + */ implicit val reflectiveCalls: reflectiveCalls = ??? + /** Only where enabled, definitions of implicit conversions are allowed. An + * implicit conversion is an implicit value of unary function type `A => B`, + * or an implicit method that has in its first parameter section a single, + * non-implicit parameter. Examples: + * + * implicit def stringToInt(s: String): Int = s.length + * implicit val conv = (s: String) => s.length + * implicit def listToX(xs: List[T])(implicit f: T => X): X = … + * + * Implicit values of other types are not affected, and neither are implicit + * classes. + * + * _Why keep the feature?_ Implicit conversions are central to many aspects + * of Scala’s core libraries. + * + * _Why control it?_ Implicit conversions are known to cause many pitfalls + * if over-used. And there is a tendency to over-use them because they look + * very powerful and their effects seem to be easy to understand. Also, in + * most situations using implicit parameters leads to a better design than + * implicit conversions. + */ implicit val implicitConversions: implicitConversions = ??? + /** Only where this flag is enabled, higher-kinded types can be written. + * + * _Why keep the feature?_ Higher-kinded types enable the definition of very general + * abstractions such as functor, monad, or arrow. A significant set of advanced + * libraries relies on them. Higher-kinded types are also at the core of the + * scala-virtualized effort to produce high-performance parallel DSLs through staging. + * + * _Why control it?_ Higher kinded types in Scala lead to a Turing-complete + * type system, where compiler termination is no longer guaranteed. They tend + * to be useful mostly for type-level computation and for highly generic design + * patterns. The level of abstraction implied by these design patterns is often + * a barrier to understanding for newcomers to a Scala codebase. Some syntactic + * aspects of higher-kinded types are hard to understand for the uninitiated and + * type inference is less effective for them than for normal types. Because we are + * not completely happy with them yet, it is possible that some aspects of + * higher-kinded types will change in future versions of Scala. So an explicit + * enabling also serves as a warning that code involving higher-kinded types + * might have to be slightly revised in the future. + */ implicit val higherKinds: higherKinds = ??? + /** Only where enabled, existential types that cannot be expressed as wildcard + * types can be written and are allowed in inferred types of values or return + * types of methods. Existential types with wildcard type syntax such as `List[_]`, + * or `Map[String, _]` are not affected. + * + * _Why keep the feature?_ Existential types are needed to make sense of Java’s wildcard + * types and raw types and the erased types of run-time values. + * + * Why control it? Having complex existential types in a code base usually makes + * application code very brittle, with a tendency to produce type errors with + * obscure error messages. Therefore, going overboard with existential types + * is generally perceived not to be a good idea. Also, complicated existential types + * might be no longer supported in a future simplification of the language. + */ implicit val existentials: existentials = ??? object experimental { import languageFeature.experimental._ + /** Where enabled, macro definitions are allowed. Macro implementations and + * macro applications are unaffected; they can be used anywhere. + * + * _Why introduce the feature?_ Macros promise to make the language more regular, + * replacing ad-hoc language constructs with a general powerful abstraction + * capability that can express them. Macros are also a more disciplined and + * powerful replacement for compiler plugins. + * + * _Why control it?_ For their very power, macros can lead to code that is hard + * to debug and understand. + */ implicit val macros: macros = ??? } } -- cgit v1.2.3 From 5e4c47f33b8e25feb59ab4599231b1b8d3150de8 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 14 Apr 2012 21:11:37 +0200 Subject: implements reification of tough types --- src/compiler/scala/reflect/internal/StdNames.scala | 1 + src/compiler/scala/reflect/internal/Symbols.scala | 4 +- src/compiler/scala/reflect/internal/TreeInfo.scala | 16 +-- src/compiler/scala/reflect/internal/Types.scala | 33 ++++- .../reflect/reify/codegen/AnnotationInfos.scala | 56 ++++++++ .../scala/reflect/reify/codegen/Symbols.scala | 114 +++++++++++++---- .../scala/reflect/reify/codegen/Trees.scala | 20 ++- .../scala/reflect/reify/codegen/Types.scala | 141 ++++++--------------- .../scala/reflect/reify/phases/Metalevels.scala | 2 + .../scala/reflect/reify/phases/Reify.scala | 4 + src/compiler/scala/tools/nsc/util/Position.scala | 10 +- src/library/scala/reflect/api/Attachment.scala | 10 +- src/library/scala/reflect/api/StandardNames.scala | 1 + src/library/scala/reflect/api/Symbols.scala | 5 + src/library/scala/reflect/api/Trees.scala | 18 ++- src/library/scala/reflect/api/TypeTags.scala | 7 +- src/library/scala/reflect/api/Types.scala | 4 + test/files/jvm/manifests.check | 56 ++++++++ .../files/jvm/manifests.check.temporarily.disabled | 55 -------- test/files/jvm/manifests.scala | 112 ++++++++++++++++ .../files/jvm/manifests.scala.temporarily.disabled | 109 ---------------- test/files/neg/t3507.check | 4 - test/files/neg/t3507.scala | 15 --- test/files/pos/implicits.scala | 89 +++++++++++++ .../files/pos/implicits.scala.temporarily.disabled | 89 ------------- test/files/pos/manifest1.scala | 21 +++ .../files/pos/manifest1.scala.temporarily.disabled | 21 --- test/files/run/existentials3.check | 24 ++++ .../run/existentials3.check.temporarily.disabled | 22 ---- test/files/run/existentials3.scala | 79 ++++++++++++ .../run/existentials3.scala.temporarily.disabled | 73 ----------- test/files/run/t1195.check | 6 + test/files/run/t1195.check.temporarily.disabled | 6 - test/files/run/t1195.scala | 26 ++++ test/files/run/t1195.scala.temporarily.disabled | 26 ---- test/files/run/t3507.check | 1 + test/files/run/t3507.scala | 15 +++ test/files/run/t4110.check | 2 + test/files/run/t4110.check.temporarily.disabled | 2 - test/files/run/t4110.scala | 11 ++ test/files/run/t4110.scala.temporarily.disabled | 11 -- test/files/run/treePrint.check | 5 + .../files/run/treePrint.check.temporarily.disabled | 5 - test/files/run/treePrint.scala | 43 +++++++ .../files/run/treePrint.scala.temporarily.disabled | 42 ------ 45 files changed, 786 insertions(+), 630 deletions(-) create mode 100644 src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala create mode 100644 test/files/jvm/manifests.check delete mode 100644 test/files/jvm/manifests.check.temporarily.disabled create mode 100644 test/files/jvm/manifests.scala delete mode 100644 test/files/jvm/manifests.scala.temporarily.disabled delete mode 100644 test/files/neg/t3507.check delete mode 100644 test/files/neg/t3507.scala create mode 100644 test/files/pos/implicits.scala delete mode 100644 test/files/pos/implicits.scala.temporarily.disabled create mode 100644 test/files/pos/manifest1.scala delete mode 100644 test/files/pos/manifest1.scala.temporarily.disabled create mode 100644 test/files/run/existentials3.check delete mode 100644 test/files/run/existentials3.check.temporarily.disabled create mode 100644 test/files/run/existentials3.scala delete mode 100644 test/files/run/existentials3.scala.temporarily.disabled create mode 100644 test/files/run/t1195.check delete mode 100644 test/files/run/t1195.check.temporarily.disabled create mode 100644 test/files/run/t1195.scala delete mode 100644 test/files/run/t1195.scala.temporarily.disabled create mode 100644 test/files/run/t3507.check create mode 100644 test/files/run/t3507.scala create mode 100644 test/files/run/t4110.check delete mode 100644 test/files/run/t4110.check.temporarily.disabled create mode 100644 test/files/run/t4110.scala delete mode 100644 test/files/run/t4110.scala.temporarily.disabled create mode 100644 test/files/run/treePrint.check delete mode 100644 test/files/run/treePrint.check.temporarily.disabled create mode 100644 test/files/run/treePrint.scala delete mode 100644 test/files/run/treePrint.scala.temporarily.disabled diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index ac2cf178bf..bf468affe6 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -206,6 +206,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val MIRROR_FREE_PREFIX: NameType = "free$" val MIRROR_FREE_THIS_SUFFIX: NameType = "$this" val MIRROR_FREE_VALUE_SUFFIX: NameType = "$value" + val MIRROR_SYMDEF_PREFIX: NameType = "symdef$" val MIXIN_CONSTRUCTOR: NameType = "$init$" val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$" val OUTER: NameType = "$outer" diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 3bb57cea04..c9947c3c09 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -64,6 +64,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => this: Symbol => def kind: String = kindString + def isExistential: Boolean = this.isExistentiallyBound def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { case n: TermName => newTermSymbol(n, pos, newFlags) @@ -897,8 +898,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => if (!owner.isLocatable) return false if (owner.isTerm) return false + if (isLocalDummy) return false if (isType && isNonClassType) return false + if (isRefinementClass) return false return true } @@ -2965,7 +2968,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isFreeTerm = true } - // [Eugene] the NoSymbol origin works for type parameters. what about existential free types? class FreeType(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) { def value = value0 override def isFreeType = true diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index a8cca1625f..039c8e557a 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -590,7 +590,7 @@ abstract class TreeInfo { } object Reified { - def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match { + def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match { case ReifiedTree(reifee, symbolTable, reified, _) => Some(reifee, symbolTable, reified) case ReifiedType(reifee, symbolTable, reified) => @@ -601,16 +601,16 @@ abstract class TreeInfo { } object ReifiedTree { - def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree)] = tree match { + def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree)] = tree match { case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(Apply(_, List(tree)), List(Apply(_, List(tpe))))) if mrDef.name == nme.MIRROR_SHORT => - Some(reifee, symbolTable map (_.asInstanceOf[ValDef]), tree, tpe) + Some(reifee, symbolTable, tree, tpe) case _ => None } } object InlineableTreeSplice { - def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree, Symbol)] = tree match { + def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree, Symbol)] = tree match { case select @ Select(ReifiedTree(splicee, symbolTable, tree, tpe), _) if select.symbol == ExprEval || select.symbol == ExprValue => Some(splicee, symbolTable, tree, tpe, select.symbol) case _ => @@ -619,7 +619,7 @@ abstract class TreeInfo { } object InlinedTreeSplice { - def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree)] = tree match { + def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree)] = tree match { case Select(ReifiedTree(splicee, symbolTable, tree, tpe), name) if name == ExprTree.name => Some(splicee, symbolTable, tree, tpe) case _ => @@ -628,16 +628,16 @@ abstract class TreeInfo { } object ReifiedType { - def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match { + def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match { case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(_, List(tpe))) if mrDef.name == nme.MIRROR_SHORT => - Some(reifee, symbolTable map (_.asInstanceOf[ValDef]), tpe) + Some(reifee, symbolTable, tpe) case _ => None } } object InlinedTypeSplice { - def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match { + def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match { case Select(ReifiedType(splicee, symbolTable, tpe), name) if name == TypeTagTpe.name => Some(splicee, symbolTable, tpe) case _ => diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 3efbe4b4df..d7c90d597c 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -266,6 +266,35 @@ trait Types extends api.Types { self: SymbolTable => def typeArguments = typeArgs def erasure = transformedType(this) 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 + + def notConcreteTpe(tpe: Type): Boolean = tpe match { + case ThisType(_) => false + case SuperType(_, _) => false + case SingleType(pre, sym) => notConcreteSym(sym) + case ConstantType(_) => false + case TypeRef(_, sym, _) => notConcreteSym(sym) + case RefinedType(_, _) => false + case ExistentialType(_, _) => false + case AnnotatedType(_, tp, _) => notConcreteTpe(tp) + case _ => true + } + + !notConcreteTpe(this) + } + + // [Eugene] is this comprehensive? + // the only thingies that we want to splice are: 1) type parameters, 2) 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 + } } /** The base class for all types */ @@ -2147,7 +2176,7 @@ trait Types extends api.Types { self: SymbolTable => sym.isPackageClass || pre.isGround && args.forall(_.isGround) ) - + def etaExpand: Type = { // must initialise symbol, see test/files/pos/ticket0137.scala val tpars = initializedTypeParams @@ -2763,7 +2792,7 @@ trait Types extends api.Types { self: SymbolTable => zippedArgs map { case (p, a) => p.name + "=" + a } mkString (origin + "[", ", ", "]") ) } - + trait UntouchableTypeVar extends TypeVar { override def untouchable = true override def isGround = true diff --git a/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala b/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala new file mode 100644 index 0000000000..1d218317dc --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala @@ -0,0 +1,56 @@ +package scala.reflect.reify +package codegen + +trait AnnotationInfos { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + // usually annotations are reified as their originals from Modifiers + // however, when reifying free and tough types, we're forced to reify annotation infos as is + // why is that bad? take a look inside + def reifyAnnotationInfo(ann: AnnotationInfo): Tree = { + val reifiedArgs = ann.args map { arg => + val saved1 = reifyTreeSymbols + val saved2 = reifyTreeTypes + + try { + // one more quirk of reifying annotations + // + // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs + // that's because a lot of logic expects post-typer trees to have non-null tpes + // + // Q: reified trees are pre-typer, so there's shouldn't be a problem. + // reflective typechecker will fill in missing symbols and types, right? + // A: actually, no. annotation ASTs live inside AnnotatedTypes, + // and insides of the types is the place where typechecker doesn't look. + reifyTreeSymbols = true + reifyTreeTypes = true + + // todo. every AnnotationInfo is an island, entire of itself + // no regular Traverser or Transformer can reach it + // hence we need to run its contents through the entire reification pipeline + // e.g. to apply reshaping or to check metalevels + reify(arg) + } finally { + reifyTreeSymbols = saved1 + reifyTreeTypes = saved2 + } + } + + def reifyClassfileAnnotArg(arg: ClassfileAnnotArg): Tree = arg match { + case LiteralAnnotArg(const) => + mirrorFactoryCall(nme.LiteralAnnotArg, reifyProduct(const)) + case ArrayAnnotArg(args) => + mirrorFactoryCall(nme.ArrayAnnotArg, scalaFactoryCall(nme.Array, args map reifyClassfileAnnotArg: _*)) + case NestedAnnotArg(ann) => + mirrorFactoryCall(nme.NestedAnnotArg, reifyAnnotationInfo(ann)) + } + + // if you reify originals of anns, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important + val reifiedAssocs = ann.assocs map (assoc => scalaFactoryCall(nme.Tuple2, reify(assoc._1), reifyClassfileAnnotArg(assoc._2))) + mirrorFactoryCall(nme.AnnotationInfo, reify(ann.atp), mkList(reifiedArgs), mkList(reifiedAssocs)) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala index 3328f5e402..2fc0002838 100644 --- a/src/compiler/scala/reflect/reify/codegen/Symbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala @@ -46,13 +46,8 @@ trait Symbols { } } else { // todo. make sure that free methods and free local defs work correctly - if (sym.isTerm) { - if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym) - reifyFreeTerm(sym, Ident(sym)) - } else { - if (reifyDebug) println("Free type: " + sym) - reifyFreeType(sym, Ident(sym)) - } + if (sym.isTerm) reifyFreeTerm(sym, Ident(sym)) + else reifyFreeType(sym, Ident(sym)) } } @@ -61,13 +56,16 @@ trait Symbols { case Some(reified) => reified case None => + if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym + "(" + sym.accurateKindString + ")") + var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name) + if (sym.isType) name = name.append(nme.MIRROR_FREE_THIS_SUFFIX) if (sym.isCapturedVariable) { assert(value.isInstanceOf[Ident], showRaw(value)) val capturedTpe = capturedVariableType(sym) val capturedValue = referenceCapturedVariable(sym) - locallyReify(sym, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, reify(origin(sym)))) + locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, reify(origin(sym)))) } else { - locallyReify(sym, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, reify(origin(sym)))) + locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, reify(origin(sym)))) } } @@ -76,36 +74,104 @@ trait Symbols { case Some(reified) => reified case None => + if (reifyDebug) println("Free type: %s (%s)".format(sym, sym.accurateKindString)) + var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name) val phantomTypeTag = Apply(TypeApply(Select(Ident(nme.MIRROR_SHORT), nme.TypeTag), List(value)), List(Literal(Constant(null)))) // todo. implement info reification for free types: type bounds, HK-arity, whatever else that can be useful - locallyReify(sym, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(origin(sym)))) + locallyReify(sym, name, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(origin(sym)))) + } + + def reifySymDef(sym: Symbol): Tree = + locallyReified get sym match { + case Some(reified) => + reified + case None => + if (reifyDebug) println("Sym def: %s (%s)".format(sym, sym.accurateKindString)) + assert(!sym.isLocatable, sym) // if this assertion fires, then tough type reification needs to be rethought + sym.owner.ownersIterator find (!_.isLocatable) foreach reifySymDef + var name = newTermName(nme.MIRROR_SYMDEF_PREFIX + sym.name) + locallyReify(sym, name, Apply(Select(reify(sym.owner), nme.newNestedSymbol), List(reify(sym.name), reify(sym.pos), reify(sym.flags), reify(sym.isClass)))) } + // todo. very brittle abstraction, needs encapsulation import scala.collection.mutable._ - private val localReifications = ArrayBuffer[ValDef]() + private val localReifications = ArrayBuffer[Tree]() private val locallyReified = Map[Symbol, Tree]() - def symbolTable: List[ValDef] = localReifications.toList - def symbolTable_=(newSymbolTable: List[ValDef]): Unit = { + private var filledIn = false + def symbolTable: List[Tree] = { fillInSymbolTable(); localReifications.toList } + def symbolTable_=(newSymbolTable: List[Tree]): Unit = { localReifications.clear() locallyReified.clear() + filledIn = false newSymbolTable foreach { - case freedef @ FreeDef(_, name, binding, _) => - if (!(locallyReified contains binding.symbol)) { - localReifications += freedef - locallyReified(binding.symbol) = Ident(name) + case entry => + val att = entry.attachment + att match { + case sym: Symbol => + // don't duplicate reified symbols when merging inlined reifee + if (!(locallyReified contains sym)) { + val ValDef(_, name, _, _) = entry + localReifications += entry + locallyReified(sym) = Ident(name) + } + case other => + // do nothing => symbol table fill-ins will be repopulated later } } } - private def locallyReify(sym: Symbol, reificode: => Tree): Tree = { + private def localName(name0: TermName): TermName = { + var name = name0.toString + name = name.replace(".type", "$type") + name = name.replace(" ", "$") + val fresh = typer.context.unit.fresh + newTermName(fresh.newName(name)) + } + + private def locallyReify(sym: Symbol, name0: TermName, reificode: => Tree): Tree = { val reified = reificode - val Apply(Select(_, flavor), _) = reified - // [Eugene] name clashes are impossible, right? - var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name) - if (flavor == nme.newFreeTerm && sym.isType) name = name.append(nme.MIRROR_FREE_THIS_SUFFIX); - // todo. also reify annotations for free vars - localReifications += ValDef(NoMods, name, TypeTree(), reified) + val name = localName(name0) + // todo. tried to declare a private class here to carry an attachment, but it's path-dependent + // so got troubles with exchanging free variables between nested and enclosing quasiquotes + // attaching just Symbol isn't good either, so we need to think of a principled solution + val local = ValDef(NoMods, name, TypeTree(), reified) setAttachment sym + localReifications += local + filledIn = false locallyReified(sym) = Ident(name) locallyReified(sym) } + + /** Sets type signatures and annotations for locally reified symbols */ + private def fillInSymbolTable() = { + if (!filledIn) { + val fillIns = new ArrayBuffer[Tree] + var i = 0 + while (i < localReifications.length) { + // fillInSymbol might create new locallyReified symbols, that's why this is done iteratively + val reified = localReifications(i) + reified.attachment match { + case sym: Symbol => fillIns += fillInSymbol(sym) + case other => // do nothing + } + i += 1 + } + + filledIn = true + localReifications ++= fillIns.toList + } + } + + /** Generate code to add type and annotation info to a reified symbol */ + private def fillInSymbol(sym: Symbol): Tree = { + if (reifyDebug) println("Filling in: %s (%s)".format(sym, sym.accurateKindString)) + val isFree = locallyReified(sym) match { case Ident(name) => name startsWith nme.MIRROR_FREE_PREFIX } + if (isFree) { + if (sym.annotations.isEmpty) EmptyTree + else Apply(Select(locallyReified(sym), nme.setAnnotations), List(reify(sym.annotations))) + } else { + val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reifyType(sym.info))) + if (sym.annotations.isEmpty) rset + else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations))) + } + } } \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Trees.scala b/src/compiler/scala/reflect/reify/codegen/Trees.scala index 22f42aea49..5ad53c0009 100644 --- a/src/compiler/scala/reflect/reify/codegen/Trees.scala +++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala @@ -8,6 +8,11 @@ trait Trees { import definitions._ import treeInfo._ + // unfortunately, these are necessary to reify AnnotatedTypes + // I'd gladly got rid of them, but I don't fancy making a metaprogramming API that doesn't work with annotated types + var reifyTreeSymbols = false + var reifyTreeTypes = false + /** * Reify a tree. * For internal use only, use ``reified'' instead. @@ -59,6 +64,17 @@ trait Trees { reifyProduct(tree) } + // usually we don't reify symbols/types, because they can be re-inferred during subsequent reflective compilation + // however, reification of AnnotatedTypes is special. see ``reifyType'' to find out why. + if (reifyTreeSymbols && tree.hasSymbol) { + if (reifyDebug) println("reifying symbol %s for tree %s".format(tree.symbol, tree)) + rtree = Apply(Select(rtree, nme.setSymbol), List(reifySymRef(tree.symbol))) + } + if (reifyTreeTypes && tree.tpe != null) { + if (reifyDebug) println("reifying type %s for tree %s".format(tree.tpe, tree)) + rtree = Apply(Select(rtree, nme.setType), List(reifyType(tree.tpe))) + } + rtree } @@ -82,7 +98,7 @@ trait Trees { case InlinedTreeSplice(_, inlinedSymbolTable, tree, _) => if (reifyDebug) println("inlining the splicee") // all free vars local to the enclosing reifee should've already been inlined by ``Metalevels'' - inlinedSymbolTable foreach { case freedef @ FreeDef(_, _, binding, _) => assert(!binding.symbol.isLocalToReifee, freedef) } + inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _) if binding.symbol.isLocalToReifee => assert(false, freedef) } symbolTable ++= inlinedSymbolTable tree case tree => @@ -152,7 +168,7 @@ trait Trees { val tpe = tpe0.dealias if (reifyDebug) println("reifying bound type %s (underlying type is %s, dealiased is %s)".format(sym0, tpe0, tpe)) - if (eligibleForSplicing(tpe)) { + if (tpe.isSpliceable) { val spliced = spliceType(tpe) if (spliced == EmptyTree) { if (reifyDebug) println("splicing failed: reify as is") diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala index 9bc113e8a4..948728088e 100644 --- a/src/compiler/scala/reflect/reify/codegen/Types.scala +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -55,11 +55,9 @@ trait Types { case tpe @ NullaryMethodType(restpe) => reifyProduct(tpe) case tpe @ AnnotatedType(anns, underlying, selfsym) => -// reifyAnnotatedType(tpe) - CannotReifyType(tpe) + reifyAnnotatedType(tpe) case _ => -// reifyToughType(tpe) - CannotReifyType(tpe) + reifyToughType(tpe) } } @@ -70,13 +68,6 @@ trait Types { var maybeConcrete = true var definitelyConcrete = true - def eligibleForSplicing(tpe: Type): Boolean = { - // [Eugene] is this comprehensive? - // the only thingies that we want to splice are: 1) type parameters, 2) type members - // this check seems to cover them all, right? - tpe.isInstanceOf[TypeRef] && tpe.typeSymbol.isAbstractType - } - private type SpliceCacheKey = (Symbol, Symbol) private lazy val spliceCache: collection.mutable.Map[SpliceCacheKey, Tree] = { val cache = analyzer.perRunMacroCache.getOrElseUpdate(MacroContextReify, collection.mutable.Map[Any, Any]()) @@ -84,7 +75,7 @@ trait Types { } def spliceType(tpe: Type): Tree = { - if (eligibleForSplicing(tpe)) { + if (tpe.isSpliceable) { if (reifyDebug) println("splicing " + tpe) if (spliceTypesEnabled) { @@ -113,7 +104,7 @@ trait Types { splice match { case InlinedTypeSplice(_, inlinedSymbolTable, tpe) => // all free vars local to the enclosing reifee should've already been inlined by ``Metalevels'' - inlinedSymbolTable foreach { case freedef @ FreeDef(_, _, binding, _) => assert(!binding.symbol.isLocalToReifee, freedef) } + inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _) if binding.symbol.isLocalToReifee => assert(false, freedef) } symbolTable ++= inlinedSymbolTable reifyTrace("inlined the splicee: ")(tpe) case tpe => @@ -134,93 +125,39 @@ trait Types { EmptyTree } - // yet another thingie disabled for simplicity - // in principle, we could retain and reify AnnotatedTypes - // but that'd require reifying every type and symbol inside ann.args - // however, since we've given up on tough types for the moment, the former would be problematic -// private def reifyAnnotatedType(tpe: AnnotatedType): Tree = { -// // ``Reshaper'' transforms annotation infos from symbols back into Modifier.annotations, which are trees -// // so the only place on Earth that can lead to reification of AnnotationInfos is the Ay Tee Land -// // therefore this function is as local as possible, don't move it out of this scope -// def reifyAnnotationInfo(ann: AnnotationInfo): Tree = { -// val reifiedArgs = ann.args map { arg => -// val saved1 = reifyTreeSymbols -// val saved2 = reifyTreeTypes -// -// try { -// // one more quirk of reifying annotations -// // -// // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs -// // that's because a lot of logic expects post-typer trees to have non-null tpes -// // -// // Q: reified trees are pre-typer, so there's shouldn't be a problem. -// // reflective typechecker will fill in missing symbols and types, right? -// // A: actually, no. annotation ASTs live inside AnnotatedTypes, -// // and insides of the types is the place where typechecker doesn't look. -// reifyTreeSymbols = true -// reifyTreeTypes = true -// -// // todo. every AnnotationInfo is an island, entire of itself -// // no regular Traverser or Transformer can reach it -// // hence we need to run its contents through the entire reification pipeline -// // e.g. to apply reshaping or to check metalevels -// reify(arg) -// } finally { -// reifyTreeSymbols = saved1 -// reifyTreeTypes = saved2 -// } -// } -// -// def reifyClassfileAnnotArg(arg: ClassfileAnnotArg): Tree = arg match { -// case LiteralAnnotArg(const) => -// mirrorFactoryCall(nme.LiteralAnnotArg, reifyProduct(const)) -// case ArrayAnnotArg(args) => -// mirrorFactoryCall(nme.ArrayAnnotArg, scalaFactoryCall(nme.Array, args map reifyClassfileAnnotArg: _*)) -// case NestedAnnotArg(ann) => -// mirrorFactoryCall(nme.NestedAnnotArg, reifyAnnotationInfo(ann)) -// } -// -// // if you reify originals of anns, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important -// val reifiedAssocs = ann.assocs map (assoc => scalaFactoryCall(nme.Tuple2, reify(assoc._1), reifyClassfileAnnotArg(assoc._2))) -// mirrorFactoryCall(nme.AnnotationInfo, reify(ann.atp), mkList(reifiedArgs), mkList(reifiedAssocs)) -// } -// -// val AnnotatedType(anns, underlying, selfsym) = tpe -// mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying), reify(selfsym)) -// } - - // previous solution to reifying tough types involved creating dummy symbols (see ``registerReifiableSymbol'' calls below) - // however such symbols lost all the connections with their origins and became almost useless, except for typechecking - // hence this approach was replaced by less powerful, but more principled one based on ``reifyFreeType'' - // it's possible that later on we will revise and revive ``reifyToughType'', but for now it's disabled under an implementation restriction -// /** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */ -// // This is the uncharted territory in the reifier -// private def reifyToughType(tpe: Type): Tree = { -// if (reifyDebug) println("tough type: %s (%s)".format(tpe, tpe.kind)) -// -// def reifyScope(scope: Scope): Tree = { -// scope foreach registerReifiableSymbol -// mirrorCall(nme.newScopeWith, scope.toList map reify: _*) -// } -// -// tpe match { -// case tpe @ RefinedType(parents, decls) => -// registerReifiableSymbol(tpe.typeSymbol) -// mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) -// case tpe @ ExistentialType(tparams, underlying) => -// tparams foreach registerReifiableSymbol -// mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) -// case tpe @ ClassInfoType(parents, decls, clazz) => -// registerReifiableSymbol(clazz) -// mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) -// case tpe @ MethodType(params, restpe) => -// params foreach registerReifiableSymbol -// mirrorFactoryCall(tpe, reify(params), reify(restpe)) -// case tpe @ PolyType(tparams, underlying) => -// tparams foreach registerReifiableSymbol -// mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) -// case _ => -// throw new Error("internal error: %s (%s) is not supported".format(tpe, tpe.kind)) -// } -// } + /** Reify an annotated type, i.e. the one that makes us deal with AnnotationInfos */ + private def reifyAnnotatedType(tpe: AnnotatedType): Tree = { + val AnnotatedType(anns, underlying, selfsym) = tpe + mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying), reify(selfsym)) + } + + /** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */ + private def reifyToughType(tpe: Type): Tree = { + if (reifyDebug) println("tough type: %s (%s)".format(tpe, tpe.kind)) + + def reifyScope(scope: Scope): Tree = { + scope foreach reifySymDef + mirrorCall(nme.newScopeWith, scope.toList map reify: _*) + } + + tpe match { + case tpe @ RefinedType(parents, decls) => + reifySymDef(tpe.typeSymbol) + mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) + case tpe @ ExistentialType(tparams, underlying) => + tparams foreach reifySymDef + mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) + case tpe @ ClassInfoType(parents, decls, clazz) => + reifySymDef(clazz) + mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) + case tpe @ MethodType(params, restpe) => + params foreach reifySymDef + mirrorFactoryCall(tpe, reify(params), reify(restpe)) + case tpe @ PolyType(tparams, underlying) => + tparams foreach reifySymDef + mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) + case _ => + throw new Error("internal error: %s (%s) is not supported".format(tpe, tpe.kind)) + } + } } \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/phases/Metalevels.scala b/src/compiler/scala/reflect/reify/phases/Metalevels.scala index a329a1043d..bb0b8ac138 100644 --- a/src/compiler/scala/reflect/reify/phases/Metalevels.scala +++ b/src/compiler/scala/reflect/reify/phases/Metalevels.scala @@ -134,6 +134,8 @@ trait Metalevels { // FreeRef(_, _) check won't work, because metalevels of symbol table and body are different, hence, freerefs in symbol table look different from freerefs in body // todo. also perform garbage collection on local symbols // so that local symbols used only in type signatures of free vars get removed + // todo. same goes for auxiliary symbol defs reified to support tough types + // some of them need to be rebuilt, some of them need to be removed, because they're no longer necessary case FreeRef(mr, name) if freedefsToInline contains name => if (reifyDebug) println("inlineable free ref: %s in %s".format(name, showRaw(tree))) val freedef @ FreeDef(_, _, binding, _) = freedefsToInline(name) diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala index f6d6423605..02a96987ed 100644 --- a/src/compiler/scala/reflect/reify/phases/Reify.scala +++ b/src/compiler/scala/reflect/reify/phases/Reify.scala @@ -9,6 +9,7 @@ trait Reify extends Symbols with Types with Names with Trees + with AnnotationInfos with Positions with Util { @@ -30,6 +31,9 @@ trait Reify extends Symbols case tpe: Type => reifyType(tpe) case name: Name => reifyName(name) case tree: Tree => reifyTree(tree) + // disabled because this is a very special case that I plan to remove later + // why do I dislike annotations? see comments to `reifyAnnotationInfo` +// case ann: AnnotationInfo => reifyAnnotationInfo(ann) case pos: Position => reifyPosition(pos) case mods: mirror.Modifiers => reifyModifiers(mods) case xs: List[_] => reifyList(xs) diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala index 573f7bc7b2..208cd5703a 100644 --- a/src/compiler/scala/tools/nsc/util/Position.scala +++ b/src/compiler/scala/tools/nsc/util/Position.scala @@ -40,7 +40,15 @@ trait Position extends scala.reflect.api.Position with scala.reflect.api.Attachm /** A bit weird method that is necessary to safely update positions without destroying custom attachments */ // necessary for conformance with Attachment - def withPos(pos: scala.reflect.api.Position) = pos + def withPos(newPos: scala.reflect.api.Position): scala.reflect.api.Attachment = newPos + + /** Exposes itself as payload of Attachment */ + // necessary for conformance with Attachment + def payload: Position = this + + /** A bit weird method that is necessary to safely update positions without destroying custom attachments */ + // necessary for conformance with Attachment + def withPayload(newPos: Any): scala.reflect.api.Attachment = newPos.asInstanceOf[Position] /** Java file corresponding to the source file of this position. */ diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala index dfd362ebe0..9fa5ceb0fb 100644 --- a/src/library/scala/reflect/api/Attachment.scala +++ b/src/library/scala/reflect/api/Attachment.scala @@ -7,10 +7,18 @@ package api * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree * imposing an unnecessary memory tax because of something that will not be used in most cases. */ +// [Eugene] with the introduction of `attach` and `payload[T]` users don't need to create custom attachments anymore +// however, we cannot move attachments to scala.reflect.internal, because they are used in Trees, which are implemented completely in scala.reflect.api trait Attachment { /** Gets the underlying position */ def pos: Position /** Creates a copy of this attachment with its position updated */ - def withPos(pos: Position): Attachment + def withPos(newPos: Position): Attachment + + /** Gets the underlying payload */ + def payload: Any + + /** Creates a copy of this attachment with its payload updated */ + def withPayload(newPayload: Any): Attachment } diff --git a/src/library/scala/reflect/api/StandardNames.scala b/src/library/scala/reflect/api/StandardNames.scala index d2110ede75..d39d44dd86 100644 --- a/src/library/scala/reflect/api/StandardNames.scala +++ b/src/library/scala/reflect/api/StandardNames.scala @@ -44,6 +44,7 @@ trait StandardNames { self: Universe => val MIRROR_FREE_PREFIX: TermName val MIRROR_FREE_THIS_SUFFIX: TermName val MIRROR_FREE_VALUE_SUFFIX: TermName + val MIRROR_SYMDEF_PREFIX: TermName val MIXIN_CONSTRUCTOR: TermName val MODULE_INSTANCE_FIELD: TermName val OUTER: TermName diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index a154e5f7a0..e47bc7216e 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -173,6 +173,11 @@ trait Symbols { self: Universe => */ def isSkolem : Boolean + /** Does this symbol represent an existentially bound type? + * If yes, `isType` is also guaranteed to be true. + */ + def isExistential : Boolean + /** Does this symbol represent a free type captured by reification? */ // needed for ones who wish to inspect reified trees diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 6ddb2ea673..5ef73cba0c 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -85,10 +85,18 @@ trait Trees { self: Universe => def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) // the "withPos" part is crucial to robustness def setPos(newpos: Position): this.type = { pos = newpos; this } - private[this] var rawatt: Attachment = NoPosition - def attachment: Attachment = rawatt - def attachment_=(att: Attachment): Unit = rawatt = att - def setAttachment(att: Attachment): this.type = { rawatt = att; this } + private var rawatt: Attachment = NoPosition + private case class NontrivialAttachment(pos: api.Position, payload: Any) extends Attachment { + def withPos(newPos: api.Position) = copy(pos = newPos, payload = payload) + def withPayload(newPayload: Any) = copy(pos = pos, payload = newPayload) + } + // todo. annotate T with ClassTag and make pattern matcher use it + // todo. support multiple attachments, and remove the assignment. only leave attach/detach +// def attachment[T]: T = rawatt.payload.asInstanceOf[T] +// def attachmentOpt[T]: Option[T] = try { Some(rawatt.payload.asInstanceOf[T]) } catch { case _: Throwable => None } + def attachment: Any = rawatt.payload + def attachment_=(att: Any): Unit = rawatt = NontrivialAttachment(pos, att) + def setAttachment(att: Any): this.type = { attachment = att; this } private[this] var rawtpe: Type = _ @@ -238,7 +246,7 @@ trait Trees { self: Universe => duplicateTree(this).asInstanceOf[this.type] private[scala] def copyAttrs(tree: Tree): this.type = { - attachment = tree.attachment + rawatt = tree.rawatt tpe = tree.tpe if (hasSymbol) symbol = tree.symbol this diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index 4ffabe1c36..59a7c87f44 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -61,9 +61,8 @@ trait TypeTags { self: Universe => // assert(tpe != null) def sym = tpe.typeSymbol - - def isConcrete = !isNotConcrete - def isNotConcrete = tpe exists (_.typeSymbol.isAbstractType) + def isConcrete = tpe.isConcrete + def notConcrete = !isConcrete def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe) override def toString = { @@ -124,7 +123,7 @@ trait TypeTags { self: Universe => // it's unsafe to use assert here, because we might run into deadlocks with Predef // also see comments in ClassTags.scala //assert(isConcrete, tpe) - if (isNotConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind)) + if (notConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind)) override def productPrefix = "ConcreteTypeTag" } diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala index 12aad453b1..5e1c1af2fe 100755 --- a/src/library/scala/reflect/api/Types.scala +++ b/src/library/scala/reflect/api/Types.scala @@ -57,6 +57,10 @@ trait Types { self: Universe => */ def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no? + /** Does this type refer to abstract types or is an abstract type? + */ + def isConcrete: Boolean + /** * Expands type aliases and converts higher-kinded TypeRefs to PolyTypes. * Functions on types are also implemented as PolyTypes. diff --git a/test/files/jvm/manifests.check b/test/files/jvm/manifests.check new file mode 100644 index 0000000000..be8ec2bb5b --- /dev/null +++ b/test/files/jvm/manifests.check @@ -0,0 +1,56 @@ +x=(), m=ConcreteTypeTag[Unit], k=TypeRef, s=class Unit +x=true, m=ConcreteTypeTag[Boolean], k=TypeRef, s=class Boolean +x=a, m=ConcreteTypeTag[Char], k=TypeRef, s=class Char +x=1, m=ConcreteTypeTag[Int], k=TypeRef, s=class Int +x=abc, m=ConcreteTypeTag[String], k=TypeRef, s=class String +x='abc, m=ConcreteTypeTag[Symbol], k=TypeRef, s=class Symbol + +x=List(()), m=ConcreteTypeTag[List[Unit]], k=TypeRef, s=class List +x=List(true), m=ConcreteTypeTag[List[Boolean]], k=TypeRef, s=class List +x=List(1), m=ConcreteTypeTag[List[Int]], k=TypeRef, s=class List +x=List(abc), m=ConcreteTypeTag[List[String]], k=TypeRef, s=class List +x=List('abc), m=ConcreteTypeTag[List[Symbol]], k=TypeRef, s=class List + +x=[Z, m=ConcreteTypeTag[Array[Boolean]], k=TypeRef, s=class Array +x=[C, m=ConcreteTypeTag[Array[Char]], k=TypeRef, s=class Array +x=[I, m=ConcreteTypeTag[Array[Int]], k=TypeRef, s=class Array +x=[Ljava.lang.String;, m=ConcreteTypeTag[Array[String]], k=TypeRef, s=class Array +x=[Lscala.Symbol;, m=ConcreteTypeTag[Array[Symbol]], k=TypeRef, s=class Array + +x=((),()), m=ConcreteTypeTag[(Unit, Unit)], k=TypeRef, s=class Tuple2 +x=(true,false), m=ConcreteTypeTag[(Boolean, Boolean)], k=TypeRef, s=class Tuple2 +x=(1,2), m=ConcreteTypeTag[(Int, Int)], k=TypeRef, s=class Tuple2 +x=(abc,xyz), m=ConcreteTypeTag[(String, String)], k=TypeRef, s=class Tuple2 +x=('abc,'xyz), m=ConcreteTypeTag[(Symbol, Symbol)], k=TypeRef, s=class Tuple2 + + +x=Foo, m=ConcreteTypeTag[Foo[Int]], k=TypeRef, s=class Foo +x=Foo, m=ConcreteTypeTag[Foo[List[Int]]], k=TypeRef, s=class Foo +x=Foo, m=ConcreteTypeTag[Foo[Foo[Int]]], k=TypeRef, s=class Foo +x=Foo, m=ConcreteTypeTag[Foo[List[Foo[Int]]]], k=TypeRef, s=class Foo + +x=Test1$$anon$1, m=ConcreteTypeTag[Bar[String]], k=RefinedType, s= +x=Test1$$anon$2, m=ConcreteTypeTag[Bar[String]], k=RefinedType, s= + +()=() +true=true +a=a +1=1 +'abc='abc + +List(())=List(()) +List(true)=List(true) +List('abc)=List('abc) + +Array()=Array() +Array(true)=Array(true) +Array(a)=Array(a) +Array(1)=Array(1) + +((),())=((),()) +(true,false)=(true,false) + +List(List(1), List(2))=List(List(1), List(2)) + +Array(Array(1), Array(2))=Array(Array(1), Array(2)) + diff --git a/test/files/jvm/manifests.check.temporarily.disabled b/test/files/jvm/manifests.check.temporarily.disabled deleted file mode 100644 index 54f504b929..0000000000 --- a/test/files/jvm/manifests.check.temporarily.disabled +++ /dev/null @@ -1,55 +0,0 @@ -x=(), m=Unit -x=true, m=Boolean -x=a, m=Char -x=1, m=Int -x=abc, m=java.lang.String -x='abc, m=scala.Symbol - -x=List(()), m=scala.collection.immutable.List[Unit] -x=List(true), m=scala.collection.immutable.List[Boolean] -x=List(1), m=scala.collection.immutable.List[Int] -x=List(abc), m=scala.collection.immutable.List[java.lang.String] -x=List('abc), m=scala.collection.immutable.List[scala.Symbol] - -x=[Z, m=Array[Boolean] -x=[C, m=Array[Char] -x=[I, m=Array[Int] -x=[Ljava.lang.String;, m=Array[java.lang.String] -x=[Lscala.Symbol;, m=Array[scala.Symbol] - -x=((),()), m=scala.Tuple2[Unit, Unit] -x=(true,false), m=scala.Tuple2[Boolean, Boolean] -x=(1,2), m=scala.Tuple2[Int, Int] -x=(abc,xyz), m=scala.Tuple2[java.lang.String, java.lang.String] -x=('abc,'xyz), m=scala.Tuple2[scala.Symbol, scala.Symbol] - - -x=Foo, m=Foo[Int] -x=Foo, m=Foo[scala.collection.immutable.List[Int]] -x=Foo, m=Foo[Foo[Int]] -x=Foo, m=Foo[scala.collection.immutable.List[Foo[Int]]] - -x=Test1$$anon$1, m=Object with Bar[java.lang.String] - -()=() -true=true -a=a -1=1 -'abc='abc - -List(())=List(()) -List(true)=List(true) -List('abc)=List('abc) - -Array()=Array() -Array(true)=Array(true) -Array(a)=Array(a) -Array(1)=Array(1) - -((),())=((),()) -(true,false)=(true,false) - -List(List(1), List(2))=List(List(1), List(2)) - -Array(Array(1), Array(2))=Array(Array(1), Array(2)) - diff --git a/test/files/jvm/manifests.scala b/test/files/jvm/manifests.scala new file mode 100644 index 0000000000..935427f5d4 --- /dev/null +++ b/test/files/jvm/manifests.scala @@ -0,0 +1,112 @@ +object Test extends App { + Test1 + Test2 +} + +class Foo[T](x: T) +trait Bar[T] { def f: T } + +object Test1 extends TestUtil { + print(()) + print(true) + print('a') + print(1) + print("abc") + print('abc) + println() + + print(List(())) + print(List(true)) + print(List(1)) + print(List("abc")) + print(List('abc)) + println() + + //print(Array(())) //Illegal class name "[V" in class file Test$ + print(Array(true)) + print(Array('a')) + print(Array(1)) + print(Array("abc")) + print(Array('abc)) + println() + + print(((), ())) + print((true, false)) + print((1, 2)) + print(("abc", "xyz")) + print(('abc, 'xyz)) + println() + + // Disabled: should these work? changing the inference for objects from + // "object Test" to "Test.type" drags in a singleton manifest which for + // some reason leads to serialization failure. + // print(Test) + // print(List) + println() + + print(new Foo(2)) + print(new Foo(List(2))) + print(new Foo(new Foo(2))) + print(new Foo(List(new Foo(2)))) + println() + + print(new Bar[String] { def f = "abc" }); + {print(new Bar[String] { def f = "abc" })} + println() +} + +object Test2 { + import scala.util.Marshal._ + println("()="+load[Unit](dump(()))) + println("true="+load[Boolean](dump(true))) + println("a="+load[Char](dump('a'))) + println("1="+load[Int](dump(1))) + println("'abc="+load[Symbol](dump('abc))) + println() + + println("List(())="+load[List[Unit]](dump(List(())))) + println("List(true)="+load[List[Boolean]](dump(List(true)))) + println("List('abc)="+load[List[Symbol]](dump(List('abc)))) + println() + + def loadArray[T](x: Array[Byte])(implicit m: reflect.Manifest[Array[T]]) = + load[Array[T]](x)(m).deep.toString + println("Array()="+loadArray[Int](dump(Array(): Array[Int]))) + println("Array(true)="+loadArray[Boolean](dump(Array(true)))) + println("Array(a)="+loadArray[Char](dump(Array('a')))) + println("Array(1)="+loadArray[Int](dump(Array(1)))) + println() + + println("((),())="+load[(Unit, Unit)](dump(((), ())))) + println("(true,false)="+load[(Boolean, Boolean)](dump((true, false)))) + println() + + println("List(List(1), List(2))="+load[List[List[Int]]](dump(List(List(1), List(2))))) + println() + + println("Array(Array(1), Array(2))="+loadArray[Array[Int]](dump(Array(Array(1), Array(2))))) + println() +} + +trait TestUtil { + import java.io._ + def write[A](o: A): Array[Byte] = { + val ba = new ByteArrayOutputStream(512) + val out = new ObjectOutputStream(ba) + out.writeObject(o) + out.close() + ba.toByteArray() + } + def read[A](buffer: Array[Byte]): A = { + val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) + in.readObject().asInstanceOf[A] + } + import scala.reflect._ + def print[T](x: T)(implicit m: Manifest[T]) { + // manifests are no longer serializable +// val m1: Manifest[T] = read(write(m)) + val m1: Manifest[T] = m + val x1 = x.toString.replaceAll("@[0-9a-z]+$", "") + println("x="+x1+", m="+m1+", k="+m1.tpe.kind+", s="+m1.sym.toString) + } +} diff --git a/test/files/jvm/manifests.scala.temporarily.disabled b/test/files/jvm/manifests.scala.temporarily.disabled deleted file mode 100644 index 241966fd9d..0000000000 --- a/test/files/jvm/manifests.scala.temporarily.disabled +++ /dev/null @@ -1,109 +0,0 @@ -object Test extends App { - Test1 - Test2 -} - -class Foo[T](x: T) -trait Bar[T] { def f: T } - -object Test1 extends TestUtil { - print(()) - print(true) - print('a') - print(1) - print("abc") - print('abc) - println() - - print(List(())) - print(List(true)) - print(List(1)) - print(List("abc")) - print(List('abc)) - println() - - //print(Array(())) //Illegal class name "[V" in class file Test$ - print(Array(true)) - print(Array('a')) - print(Array(1)) - print(Array("abc")) - print(Array('abc)) - println() - - print(((), ())) - print((true, false)) - print((1, 2)) - print(("abc", "xyz")) - print(('abc, 'xyz)) - println() - - // Disabled: should these work? changing the inference for objects from - // "object Test" to "Test.type" drags in a singleton manifest which for - // some reason leads to serialization failure. - // print(Test) - // print(List) - println() - - print(new Foo(2)) - print(new Foo(List(2))) - print(new Foo(new Foo(2))) - print(new Foo(List(new Foo(2)))) - println() - - print(new Bar[String] { def f = "abc" }) - println() -} - -object Test2 { - import scala.util.Marshal._ - println("()="+load[Unit](dump(()))) - println("true="+load[Boolean](dump(true))) - println("a="+load[Char](dump('a'))) - println("1="+load[Int](dump(1))) - println("'abc="+load[Symbol](dump('abc))) - println() - - println("List(())="+load[List[Unit]](dump(List(())))) - println("List(true)="+load[List[Boolean]](dump(List(true)))) - println("List('abc)="+load[List[Symbol]](dump(List('abc)))) - println() - - def loadArray[T](x: Array[Byte])(implicit m: reflect.Manifest[Array[T]]) = - load[Array[T]](x)(m).deep.toString - println("Array()="+loadArray[Int](dump(Array(): Array[Int]))) - println("Array(true)="+loadArray[Boolean](dump(Array(true)))) - println("Array(a)="+loadArray[Char](dump(Array('a')))) - println("Array(1)="+loadArray[Int](dump(Array(1)))) - println() - - println("((),())="+load[(Unit, Unit)](dump(((), ())))) - println("(true,false)="+load[(Boolean, Boolean)](dump((true, false)))) - println() - - println("List(List(1), List(2))="+load[List[List[Int]]](dump(List(List(1), List(2))))) - println() - - println("Array(Array(1), Array(2))="+loadArray[Array[Int]](dump(Array(Array(1), Array(2))))) - println() -} - -trait TestUtil { - import java.io._ - def write[A](o: A): Array[Byte] = { - val ba = new ByteArrayOutputStream(512) - val out = new ObjectOutputStream(ba) - out.writeObject(o) - out.close() - ba.toByteArray() - } - def read[A](buffer: Array[Byte]): A = { - val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) - in.readObject().asInstanceOf[A] - } - import scala.reflect._ - def print[T](x: T)(implicit m: Manifest[T]) { - val m1: Manifest[T] = read(write(m)) - val x1 = x.toString.replaceAll("@[0-9a-z]+$", "") - println("x="+x1+", m="+m1) - } -} diff --git a/test/files/neg/t3507.check b/test/files/neg/t3507.check deleted file mode 100644 index 71bf295039..0000000000 --- a/test/files/neg/t3507.check +++ /dev/null @@ -1,4 +0,0 @@ -t3507.scala:13: error: No ConcreteTypeTag available for _1.b.c.type - mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier - ^ -one error found diff --git a/test/files/neg/t3507.scala b/test/files/neg/t3507.scala deleted file mode 100644 index 32688d3934..0000000000 --- a/test/files/neg/t3507.scala +++ /dev/null @@ -1,15 +0,0 @@ -class A { - object b { - object c - } - def m = b.c -} - -object Test { - var a: A = new A // mutable - val c /*: object _1.b.c forSome { val _1: A } */ = a.m // widening using existential - - def mani[T: Manifest](x: T) = () - mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier - // --> _1 is not in scope here -} \ No newline at end of file diff --git a/test/files/pos/implicits.scala b/test/files/pos/implicits.scala new file mode 100644 index 0000000000..2c01dd0ba8 --- /dev/null +++ b/test/files/pos/implicits.scala @@ -0,0 +1,89 @@ +// #1435 +object t1435 { + implicit def a(s:String):String = error("") + implicit def a(i:Int):String = error("") + implicit def b(i:Int):String = error("") +} + +class C1435 { + val v:String = { + import t1435.a + 2 + } +} + +// #1492 +class C1492 { + + class X + + def foo(x: X => X) {} + + foo ( implicit x => implicitly[X] ) + foo { implicit x => implicitly[X] } +} + +// #1579 +object Test1579 { + class Column + class Query[E](val value: E) + class Invoker(q: Any) { val foo = null } + + implicit def unwrap[C](q: Query[C]) = q.value + implicit def invoker(q: Query[Column]) = new Invoker(q) + + val q = new Query(new Column) + q.foo +} +// #1625 +object Test1625 { + + class Wrapped(x:Any) { + def unwrap() = x + } + + implicit def byName[A](x: =>A) = new Wrapped(x) + + implicit def byVal[A](x: A) = x + + def main(args: Array[String]) = { + +// val res:Wrapped = 7 // works + + val res = 7.unwrap() // doesn't work + + println("=> result: " + res) + } +} + +object Test2188 { + implicit def toJavaList[A: ClassManifest](t:collection.Seq[A]):java.util.List[A] = java.util.Arrays.asList(t.toArray:_*) + + val x: java.util.List[String] = List("foo") +} + +object TestNumericWidening { + val y = 1 + val x: java.lang.Long = y +} + +// #2709 +package foo2709 { + class A + class B + + package object bar { + implicit def a2b(a: A): B = new B + } + + package bar { + object test { + new A: B + } + } +} + +// Problem with specs +object specsProblem { + println(implicitly[Manifest[Class[_]]]) +} diff --git a/test/files/pos/implicits.scala.temporarily.disabled b/test/files/pos/implicits.scala.temporarily.disabled deleted file mode 100644 index 2c01dd0ba8..0000000000 --- a/test/files/pos/implicits.scala.temporarily.disabled +++ /dev/null @@ -1,89 +0,0 @@ -// #1435 -object t1435 { - implicit def a(s:String):String = error("") - implicit def a(i:Int):String = error("") - implicit def b(i:Int):String = error("") -} - -class C1435 { - val v:String = { - import t1435.a - 2 - } -} - -// #1492 -class C1492 { - - class X - - def foo(x: X => X) {} - - foo ( implicit x => implicitly[X] ) - foo { implicit x => implicitly[X] } -} - -// #1579 -object Test1579 { - class Column - class Query[E](val value: E) - class Invoker(q: Any) { val foo = null } - - implicit def unwrap[C](q: Query[C]) = q.value - implicit def invoker(q: Query[Column]) = new Invoker(q) - - val q = new Query(new Column) - q.foo -} -// #1625 -object Test1625 { - - class Wrapped(x:Any) { - def unwrap() = x - } - - implicit def byName[A](x: =>A) = new Wrapped(x) - - implicit def byVal[A](x: A) = x - - def main(args: Array[String]) = { - -// val res:Wrapped = 7 // works - - val res = 7.unwrap() // doesn't work - - println("=> result: " + res) - } -} - -object Test2188 { - implicit def toJavaList[A: ClassManifest](t:collection.Seq[A]):java.util.List[A] = java.util.Arrays.asList(t.toArray:_*) - - val x: java.util.List[String] = List("foo") -} - -object TestNumericWidening { - val y = 1 - val x: java.lang.Long = y -} - -// #2709 -package foo2709 { - class A - class B - - package object bar { - implicit def a2b(a: A): B = new B - } - - package bar { - object test { - new A: B - } - } -} - -// Problem with specs -object specsProblem { - println(implicitly[Manifest[Class[_]]]) -} diff --git a/test/files/pos/manifest1.scala b/test/files/pos/manifest1.scala new file mode 100644 index 0000000000..8901aa7437 --- /dev/null +++ b/test/files/pos/manifest1.scala @@ -0,0 +1,21 @@ +import scala.reflect.Manifest + +object Test { + def foo[T](x: T)(implicit m: Manifest[T]) { + foo(List(x)) + } + foo(1) + foo("abc") + foo(List(1, 2, 3)) + val x: List[Int] with Ordered[List[Int]] = null + foo(x) + foo[x.type](x) + abstract class C { type T = String; val x: T } + val c = new C { val x = "abc" } + foo(c.x) + abstract class D { type T; implicit val m: Manifest[T]; val x: T } + val stringm = implicitly[Manifest[String]] + val d: D = new D { type T = String; val m = stringm; val x = "x" } + import d.m + foo(d.x) +} diff --git a/test/files/pos/manifest1.scala.temporarily.disabled b/test/files/pos/manifest1.scala.temporarily.disabled deleted file mode 100644 index 8901aa7437..0000000000 --- a/test/files/pos/manifest1.scala.temporarily.disabled +++ /dev/null @@ -1,21 +0,0 @@ -import scala.reflect.Manifest - -object Test { - def foo[T](x: T)(implicit m: Manifest[T]) { - foo(List(x)) - } - foo(1) - foo("abc") - foo(List(1, 2, 3)) - val x: List[Int] with Ordered[List[Int]] = null - foo(x) - foo[x.type](x) - abstract class C { type T = String; val x: T } - val c = new C { val x = "abc" } - foo(c.x) - abstract class D { type T; implicit val m: Manifest[T]; val x: T } - val stringm = implicitly[Manifest[String]] - val d: D = new D { type T = String; val m = stringm; val x = "x" } - import d.m - foo(d.x) -} diff --git a/test/files/run/existentials3.check b/test/files/run/existentials3.check new file mode 100644 index 0000000000..8227d77909 --- /dev/null +++ b/test/files/run/existentials3.check @@ -0,0 +1,24 @@ +ConcreteTypeTag[Bar.type], t=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton +ConcreteTypeTag[Bar], t=TypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar} +ConcreteTypeTag[Test.ToS], t=RefinedType, s=f3 +ConcreteTypeTag[Test.ToS], t=RefinedType, s=f4 +ConcreteTypeTag[Test.ToS], t=RefinedType, s=f5 +ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 +ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 +ConcreteTypeTag[$anon], t=TypeRef, s= <: B with Test.ToS +ConcreteTypeTag[$anon], t=TypeRef, s= <: B with A with Test.ToS +ConcreteTypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List +ConcreteTypeTag[List[Seq[Int]]], t=TypeRef, s=class List +ConcreteTypeTag[List[Seq[U forSome { type U <: Int }]]], t=TypeRef, s=class List +ConcreteTypeTag[Bar.type], t=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton +ConcreteTypeTag[Bar], t=TypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar} +ConcreteTypeTag[Test.ToS], t=RefinedType, s=g3 +ConcreteTypeTag[Test.ToS], t=RefinedType, s=g4 +ConcreteTypeTag[Test.ToS], t=RefinedType, s=g5 +ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 +ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0 +ConcreteTypeTag[$anon], t=TypeRef, s= <: B with Test.ToS +ConcreteTypeTag[$anon], t=TypeRef, s= <: B with A with Test.ToS +ConcreteTypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List +ConcreteTypeTag[List[Seq[Int]]], t=TypeRef, s=class List +ConcreteTypeTag[List[Seq[U forSome { type U <: Int }]]], t=TypeRef, s=class List diff --git a/test/files/run/existentials3.check.temporarily.disabled b/test/files/run/existentials3.check.temporarily.disabled deleted file mode 100644 index 36a458dacc..0000000000 --- a/test/files/run/existentials3.check.temporarily.disabled +++ /dev/null @@ -1,22 +0,0 @@ -_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with Test$ToS with scala.Product with scala.Serializable -Object with Test$ToS -Object with Test$ToS -Object with Test$ToS -scala.Function0[Object with Test$ToS] -scala.Function0[Object with Test$ToS] -_ <: Object with _ <: Object with Object with Test$ToS -_ <: Object with _ <: Object with _ <: Object with Test$ToS -scala.collection.immutable.List[Object with scala.collection.Seq[Int]] -scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] -_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with Test$ToS with scala.Product with scala.Serializable -Object with Test$ToS -Object with Test$ToS -Object with Test$ToS -scala.Function0[Object with Test$ToS] -scala.Function0[Object with Test$ToS] -_ <: Object with _ <: Object with Object with Test$ToS -_ <: Object with _ <: Object with _ <: Object with Test$ToS -scala.collection.immutable.List[Object with scala.collection.Seq[Int]] -scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] diff --git a/test/files/run/existentials3.scala b/test/files/run/existentials3.scala new file mode 100644 index 0000000000..d6d5612687 --- /dev/null +++ b/test/files/run/existentials3.scala @@ -0,0 +1,79 @@ +object Test { + trait ToS { final override def toString = getClass.getName } + + def f1 = { case class Bar() extends ToS; Bar } + def f2 = { case class Bar() extends ToS; Bar() } + def f3 = { class Bar() extends ToS; object Bar extends ToS; Bar } + def f4 = { class Bar() extends ToS; new Bar() } + def f5 = { object Bar extends ToS; Bar } + def f6 = { () => { object Bar extends ToS ; Bar } } + def f7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } + + def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } + def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } + + def f10 = { class A { type T1 } ; List[A#T1]() } + def f11 = { abstract class A extends Seq[Int] ; List[A]() } + def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } + + val g1 = { case class Bar() extends ToS; Bar } + val g2 = { case class Bar() extends ToS; Bar() } + val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar } + val g4 = { class Bar() extends ToS; new Bar() } + val g5 = { object Bar extends ToS; Bar } + val g6 = { () => { object Bar extends ToS ; Bar } } + val g7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } + + val g8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } + val g9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } + + val g10 = { class A { type T1 } ; List[A#T1]() } + val g11 = { abstract class A extends Seq[Int] ; List[A]() } + val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } + + def printTag(t: TypeTag[_]) = { + val s = if (t.sym.isFreeType) t.sym.typeSignature.toString else t.sym.toString + println("%s, t=%s, s=%s".format(t, t.tpe.kind, s)) + } + def m[T: ConcreteTypeTag](x: T) = printTag(concreteTypeTag[T]) + def m2[T: TypeTag](x: T) = printTag(typeTag[T]) + + // manifests don't work for f10/g10 + // oh, they do now :) + def main(args: Array[String]): Unit = { + m(f1) + m(f2) + m(f3) + m(f4) + m(f5) + m(f6) + m(f7) + m(f8) + m(f9) + m2(f10) + m(f11) + m(f12) + m(g1) + m(g2) + m(g3) + m(g4) + m(g5) + m(g6) + m(g7) + m(g8) + m(g9) + m2(g10) + m(g11) + m(g12) + } +} + +object Misc { + trait Bippy { def bippy = "I'm Bippy!" } + object o1 { + def f1 = { trait A extends Seq[U forSome { type U <: Bippy }] ; abstract class B extends A ; trait C extends B ; (null: C) } + def f2 = f1.head.bippy + } + def g1 = o1.f1 _ + def g2 = o1.f2 _ +} diff --git a/test/files/run/existentials3.scala.temporarily.disabled b/test/files/run/existentials3.scala.temporarily.disabled deleted file mode 100644 index bb80d366cc..0000000000 --- a/test/files/run/existentials3.scala.temporarily.disabled +++ /dev/null @@ -1,73 +0,0 @@ -object Test { - trait ToS { final override def toString = getClass.getName } - - def f1 = { case class Bar() extends ToS; Bar } - def f2 = { case class Bar() extends ToS; Bar() } - def f3 = { class Bar() extends ToS; object Bar extends ToS; Bar } - def f4 = { class Bar() extends ToS; new Bar() } - def f5 = { object Bar extends ToS; Bar } - def f6 = { () => { object Bar extends ToS ; Bar } } - def f7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } - - def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } - def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } - - def f10 = { class A { type T1 } ; List[A#T1]() } - def f11 = { abstract class A extends Seq[Int] ; List[A]() } - def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } - - val g1 = { case class Bar() extends ToS; Bar } - val g2 = { case class Bar() extends ToS; Bar() } - val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar } - val g4 = { class Bar() extends ToS; new Bar() } - val g5 = { object Bar extends ToS; Bar } - val g6 = { () => { object Bar extends ToS ; Bar } } - val g7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } - - val g8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } - val g9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } - - val g10 = { class A { type T1 } ; List[A#T1]() } - val g11 = { abstract class A extends Seq[Int] ; List[A]() } - val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } - - def m[T: Manifest](x: T) = println(manifest[T]) - - // manifests don't work for f10/g10 - def main(args: Array[String]): Unit = { - m(f1) - m(f2) - m(f3) - m(f4) - m(f5) - m(f6) - m(f7) - m(f8) - m(f9) - // m(f10) - m(f11) - m(f12) - m(g1) - m(g2) - m(g3) - m(g4) - m(g5) - m(g6) - m(g7) - m(g8) - m(g9) - // m(g10) - m(g11) - m(g12) - } -} - -object Misc { - trait Bippy { def bippy = "I'm Bippy!" } - object o1 { - def f1 = { trait A extends Seq[U forSome { type U <: Bippy }] ; abstract class B extends A ; trait C extends B ; (null: C) } - def f2 = f1.head.bippy - } - def g1 = o1.f1 _ - def g2 = o1.f2 _ -} diff --git a/test/files/run/t1195.check b/test/files/run/t1195.check new file mode 100644 index 0000000000..554e3fd03d --- /dev/null +++ b/test/files/run/t1195.check @@ -0,0 +1,6 @@ +ConcreteTypeTag[Bar.type], underlying = <: scala.runtime.AbstractFunction1[Int,Bar] with Serializable{case def unapply(x$0: Bar): Option[Int]} with Singleton +ConcreteTypeTag[Bar], underlying = <: Product with Serializable{val x: Int; def copy(x: Int): Bar; def copy$default$1: Int; def _1: Int} +ConcreteTypeTag[Product with Serializable], underlying = Product with Serializable +ConcreteTypeTag[Bar.type], underlying = <: scala.runtime.AbstractFunction1[Int,Bar] with Serializable{case def unapply(x$0: Bar): Option[Int]} with Singleton +ConcreteTypeTag[Bar], underlying = <: Product with Serializable{val x: Int; def copy(x: Int): Bar; def copy$default$1: Int; def _1: Int} +ConcreteTypeTag[Product with Serializable], underlying = Product with Serializable diff --git a/test/files/run/t1195.check.temporarily.disabled b/test/files/run/t1195.check.temporarily.disabled deleted file mode 100644 index d023bc91f7..0000000000 --- a/test/files/run/t1195.check.temporarily.disabled +++ /dev/null @@ -1,6 +0,0 @@ -_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with scala.Product with scala.Serializable -Object with scala.Product with scala.Serializable -_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with scala.Product with scala.Serializable -Object with scala.Product with scala.Serializable diff --git a/test/files/run/t1195.scala b/test/files/run/t1195.scala new file mode 100644 index 0000000000..93b1dcbd07 --- /dev/null +++ b/test/files/run/t1195.scala @@ -0,0 +1,26 @@ +object Test { + def f() = { case class Bar(x: Int); Bar } + def g() = { case class Bar(x: Int); Bar(5) } + def h() = { case object Bar ; Bar } + + val f1 = f() + val g1 = g() + val h1 = h() + + def m[T: Manifest](x: T) = println(manifest[T] + ", underlying = " + manifest[T].sym.typeSignature) + + def main(args: Array[String]): Unit = { + m(f) + m(g) + m(h) + m(f1) + m(g1) + m(h1) + } +} + +class A1[T] { + class B1[U] { + def f = { case class D(x: Int) extends A1[String] ; new D(5) } + } +} diff --git a/test/files/run/t1195.scala.temporarily.disabled b/test/files/run/t1195.scala.temporarily.disabled deleted file mode 100644 index 81ef5bdb0e..0000000000 --- a/test/files/run/t1195.scala.temporarily.disabled +++ /dev/null @@ -1,26 +0,0 @@ -object Test { - def f() = { case class Bar(x: Int); Bar } - def g() = { case class Bar(x: Int); Bar(5) } - def h() = { case object Bar ; Bar } - - val f1 = f() - val g1 = g() - val h1 = h() - - def m[T: Manifest](x: T) = println(manifest[T]) - - def main(args: Array[String]): Unit = { - m(f) - m(g) - m(h) - m(f1) - m(g1) - m(h1) - } -} - -class A1[T] { - class B1[U] { - def f = { case class D(x: Int) extends A1[String] ; new D(5) } - } -} diff --git a/test/files/run/t3507.check b/test/files/run/t3507.check new file mode 100644 index 0000000000..50ab029592 --- /dev/null +++ b/test/files/run/t3507.check @@ -0,0 +1 @@ +ConcreteTypeTag[_1.type#b.c.type] diff --git a/test/files/run/t3507.scala b/test/files/run/t3507.scala new file mode 100644 index 0000000000..3cdd40a881 --- /dev/null +++ b/test/files/run/t3507.scala @@ -0,0 +1,15 @@ +class A { + object b { + object c + } + def m = b.c +} + +object Test extends App { + var a: A = new A // mutable + val c /*: object _1.b.c forSome { val _1: A } */ = a.m // widening using existential + + def mani[T: Manifest](x: T) = println(manifest[T]) + mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier + // --> _1 is not in scope here +} \ No newline at end of file diff --git a/test/files/run/t4110.check b/test/files/run/t4110.check new file mode 100644 index 0000000000..28f220e1fe --- /dev/null +++ b/test/files/run/t4110.check @@ -0,0 +1,2 @@ +ConcreteTypeTag[Test.A with Test.B] +ConcreteTypeTag[Test.A with Test.B] diff --git a/test/files/run/t4110.check.temporarily.disabled b/test/files/run/t4110.check.temporarily.disabled deleted file mode 100644 index 8b005989de..0000000000 --- a/test/files/run/t4110.check.temporarily.disabled +++ /dev/null @@ -1,2 +0,0 @@ -Object with Test$A with Test$B -Object with Test$A with Test$B diff --git a/test/files/run/t4110.scala b/test/files/run/t4110.scala new file mode 100644 index 0000000000..4bd377b73e --- /dev/null +++ b/test/files/run/t4110.scala @@ -0,0 +1,11 @@ +object Test extends App { + def inferredType[T : Manifest](v : T) = println(manifest[T]) + + trait A + trait B + + inferredType(new A with B) + + val name = new A with B + inferredType(name) +} \ No newline at end of file diff --git a/test/files/run/t4110.scala.temporarily.disabled b/test/files/run/t4110.scala.temporarily.disabled deleted file mode 100644 index 4bd377b73e..0000000000 --- a/test/files/run/t4110.scala.temporarily.disabled +++ /dev/null @@ -1,11 +0,0 @@ -object Test extends App { - def inferredType[T : Manifest](v : T) = println(manifest[T]) - - trait A - trait B - - inferredType(new A with B) - - val name = new A with B - inferredType(name) -} \ No newline at end of file diff --git a/test/files/run/treePrint.check b/test/files/run/treePrint.check new file mode 100644 index 0000000000..3360815ac1 --- /dev/null +++ b/test/files/run/treePrint.check @@ -0,0 +1,5 @@ +def foo = { + var q: Boolean = false; + val x = 5; + ((x == 5) || (!q)) || (true) +} diff --git a/test/files/run/treePrint.check.temporarily.disabled b/test/files/run/treePrint.check.temporarily.disabled deleted file mode 100644 index 3360815ac1..0000000000 --- a/test/files/run/treePrint.check.temporarily.disabled +++ /dev/null @@ -1,5 +0,0 @@ -def foo = { - var q: Boolean = false; - val x = 5; - ((x == 5) || (!q)) || (true) -} diff --git a/test/files/run/treePrint.scala b/test/files/run/treePrint.scala new file mode 100644 index 0000000000..4a80e2824d --- /dev/null +++ b/test/files/run/treePrint.scala @@ -0,0 +1,43 @@ +/** Testing compact tree printers. + */ +object Test { + import scala.tools.nsc._ + import interpreter._ + import java.io.{ OutputStream, BufferedReader, StringReader, PrintWriter, Writer, OutputStreamWriter} + + val code = """ + def foo = { + var q: Boolean = false + val x = if (true) { + if (true) { + if (true) { + 5 + } + else if (true) { + 5 + } else { + 10 + } + } + else 20 + } + else 30 + + (x == 5) || !q || true + } + """ + + class NullOutputStream extends OutputStream { def write(b: Int) { } } + + def main(args: Array[String]) { + val settings = new Settings + settings.classpath.value = System.getProperty("java.class.path") + settings.Ycompacttrees.value = true + + val intp = new IMain(settings, new PrintWriter(new NullOutputStream)) + val vals = new ReplVals { } + val power = new Power(intp, vals) + intp.interpret("""def initialize = "Have to interpret something or we get errors." """) + power trees code foreach println + } +} diff --git a/test/files/run/treePrint.scala.temporarily.disabled b/test/files/run/treePrint.scala.temporarily.disabled deleted file mode 100644 index e0332a705f..0000000000 --- a/test/files/run/treePrint.scala.temporarily.disabled +++ /dev/null @@ -1,42 +0,0 @@ -/** Testing compact tree printers. - */ -object Test { - import scala.tools.nsc._ - import interpreter._ - import java.io.{ OutputStream, BufferedReader, StringReader, PrintWriter, Writer, OutputStreamWriter} - - val code = """ - def foo = { - var q: Boolean = false - val x = if (true) { - if (true) { - if (true) { - 5 - } - else if (true) { - 5 - } else { - 10 - } - } - else 20 - } - else 30 - - (x == 5) || !q || true - } - """ - - class NullOutputStream extends OutputStream { def write(b: Int) { } } - - def main(args: Array[String]) { - val settings = new Settings - settings.classpath.value = System.getProperty("java.class.path") - settings.Ycompacttrees.value = true - - val intp = new IMain(settings, new PrintWriter(new NullOutputStream)) - val power = new Power(intp, new ReplVals { }) - intp.interpret("""def initialize = "Have to interpret something or we get errors." """) - power trees code foreach println - } -} -- cgit v1.2.3 From 904578fa10188756ea0e88073ebba057fb4ac4a5 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 14 Apr 2012 21:48:15 +0200 Subject: removes obsolete macro tests --- test/disabled/neg/macro-keyword-bind.check | 7 ------- test/disabled/neg/macro-keyword-bind.flags | 1 - test/disabled/neg/macro-keyword-bind.scala | 6 ------ test/disabled/neg/macro-keyword-class1.check | 4 ---- test/disabled/neg/macro-keyword-class1.flags | 1 - test/disabled/neg/macro-keyword-class1.scala | 3 --- test/disabled/neg/macro-keyword-class2.check | 4 ---- test/disabled/neg/macro-keyword-class2.flags | 1 - test/disabled/neg/macro-keyword-class2.scala | 3 --- test/disabled/neg/macro-keyword-object1.check | 4 ---- test/disabled/neg/macro-keyword-object1.flags | 1 - test/disabled/neg/macro-keyword-object1.scala | 3 --- test/disabled/neg/macro-keyword-object2.check | 4 ---- test/disabled/neg/macro-keyword-object2.flags | 1 - test/disabled/neg/macro-keyword-object2.scala | 3 --- test/disabled/neg/macro-keyword-package1.check | 4 ---- test/disabled/neg/macro-keyword-package1.flags | 1 - test/disabled/neg/macro-keyword-package1.scala | 3 --- test/disabled/neg/macro-keyword-package2.check | 4 ---- test/disabled/neg/macro-keyword-package2.flags | 1 - test/disabled/neg/macro-keyword-package2.scala | 3 --- test/disabled/neg/macro-keyword-trait1.check | 4 ---- test/disabled/neg/macro-keyword-trait1.flags | 1 - test/disabled/neg/macro-keyword-trait1.scala | 3 --- test/disabled/neg/macro-keyword-trait2.check | 4 ---- test/disabled/neg/macro-keyword-trait2.flags | 1 - test/disabled/neg/macro-keyword-trait2.scala | 3 --- test/disabled/neg/macro-keyword-type.check | 4 ---- test/disabled/neg/macro-keyword-type.flags | 1 - test/disabled/neg/macro-keyword-type.scala | 3 --- test/disabled/neg/macro-keyword-val.check | 7 ------- test/disabled/neg/macro-keyword-val.flags | 1 - test/disabled/neg/macro-keyword-val.scala | 3 --- test/disabled/neg/macro-keyword-var.check | 7 ------- test/disabled/neg/macro-keyword-var.flags | 1 - test/disabled/neg/macro-keyword-var.scala | 3 --- 36 files changed, 108 deletions(-) delete mode 100644 test/disabled/neg/macro-keyword-bind.check delete mode 100644 test/disabled/neg/macro-keyword-bind.flags delete mode 100644 test/disabled/neg/macro-keyword-bind.scala delete mode 100644 test/disabled/neg/macro-keyword-class1.check delete mode 100644 test/disabled/neg/macro-keyword-class1.flags delete mode 100644 test/disabled/neg/macro-keyword-class1.scala delete mode 100644 test/disabled/neg/macro-keyword-class2.check delete mode 100644 test/disabled/neg/macro-keyword-class2.flags delete mode 100644 test/disabled/neg/macro-keyword-class2.scala delete mode 100644 test/disabled/neg/macro-keyword-object1.check delete mode 100644 test/disabled/neg/macro-keyword-object1.flags delete mode 100644 test/disabled/neg/macro-keyword-object1.scala delete mode 100644 test/disabled/neg/macro-keyword-object2.check delete mode 100644 test/disabled/neg/macro-keyword-object2.flags delete mode 100644 test/disabled/neg/macro-keyword-object2.scala delete mode 100644 test/disabled/neg/macro-keyword-package1.check delete mode 100644 test/disabled/neg/macro-keyword-package1.flags delete mode 100644 test/disabled/neg/macro-keyword-package1.scala delete mode 100644 test/disabled/neg/macro-keyword-package2.check delete mode 100644 test/disabled/neg/macro-keyword-package2.flags delete mode 100644 test/disabled/neg/macro-keyword-package2.scala delete mode 100644 test/disabled/neg/macro-keyword-trait1.check delete mode 100644 test/disabled/neg/macro-keyword-trait1.flags delete mode 100644 test/disabled/neg/macro-keyword-trait1.scala delete mode 100644 test/disabled/neg/macro-keyword-trait2.check delete mode 100644 test/disabled/neg/macro-keyword-trait2.flags delete mode 100644 test/disabled/neg/macro-keyword-trait2.scala delete mode 100644 test/disabled/neg/macro-keyword-type.check delete mode 100644 test/disabled/neg/macro-keyword-type.flags delete mode 100644 test/disabled/neg/macro-keyword-type.scala delete mode 100644 test/disabled/neg/macro-keyword-val.check delete mode 100644 test/disabled/neg/macro-keyword-val.flags delete mode 100644 test/disabled/neg/macro-keyword-val.scala delete mode 100644 test/disabled/neg/macro-keyword-var.check delete mode 100644 test/disabled/neg/macro-keyword-var.flags delete mode 100644 test/disabled/neg/macro-keyword-var.scala diff --git a/test/disabled/neg/macro-keyword-bind.check b/test/disabled/neg/macro-keyword-bind.check deleted file mode 100644 index 1f74cfe5cd..0000000000 --- a/test/disabled/neg/macro-keyword-bind.check +++ /dev/null @@ -1,7 +0,0 @@ -macro-keyword-bind.scala:2: error: illegal start of simple pattern - val Some(macro) = Some(42) - ^ -macro-keyword-bind.scala:6: error: ')' expected but '}' found. -} -^ -two errors found diff --git a/test/disabled/neg/macro-keyword-bind.flags b/test/disabled/neg/macro-keyword-bind.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-bind.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-bind.scala b/test/disabled/neg/macro-keyword-bind.scala deleted file mode 100644 index a3b1553348..0000000000 --- a/test/disabled/neg/macro-keyword-bind.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test12 { - val Some(macro) = Some(42) - macro match { - case macro => println(macro) - } -} \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-class1.check b/test/disabled/neg/macro-keyword-class1.check deleted file mode 100644 index d8983180ef..0000000000 --- a/test/disabled/neg/macro-keyword-class1.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-class1.scala:3: error: identifier expected but 'macro' found. -class macro - ^ -one error found diff --git a/test/disabled/neg/macro-keyword-class1.flags b/test/disabled/neg/macro-keyword-class1.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-class1.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-class1.scala b/test/disabled/neg/macro-keyword-class1.scala deleted file mode 100644 index 8635d1f4f6..0000000000 --- a/test/disabled/neg/macro-keyword-class1.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test4 - -class macro diff --git a/test/disabled/neg/macro-keyword-class2.check b/test/disabled/neg/macro-keyword-class2.check deleted file mode 100644 index 0e4d11bcc4..0000000000 --- a/test/disabled/neg/macro-keyword-class2.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-class2.scala:2: error: identifier expected but 'macro' found. - class macro - ^ -one error found diff --git a/test/disabled/neg/macro-keyword-class2.flags b/test/disabled/neg/macro-keyword-class2.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-class2.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-class2.scala b/test/disabled/neg/macro-keyword-class2.scala deleted file mode 100644 index af24a489d0..0000000000 --- a/test/disabled/neg/macro-keyword-class2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test5 { - class macro -} diff --git a/test/disabled/neg/macro-keyword-object1.check b/test/disabled/neg/macro-keyword-object1.check deleted file mode 100644 index cfbd06ffd6..0000000000 --- a/test/disabled/neg/macro-keyword-object1.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-object1.scala:3: error: identifier expected but 'macro' found. -object macro - ^ -one error found diff --git a/test/disabled/neg/macro-keyword-object1.flags b/test/disabled/neg/macro-keyword-object1.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-object1.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-object1.scala b/test/disabled/neg/macro-keyword-object1.scala deleted file mode 100644 index 66eb494e6b..0000000000 --- a/test/disabled/neg/macro-keyword-object1.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test6 - -object macro diff --git a/test/disabled/neg/macro-keyword-object2.check b/test/disabled/neg/macro-keyword-object2.check deleted file mode 100644 index ede31f13e5..0000000000 --- a/test/disabled/neg/macro-keyword-object2.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-object2.scala:2: error: identifier expected but 'macro' found. - object macro - ^ -one error found diff --git a/test/disabled/neg/macro-keyword-object2.flags b/test/disabled/neg/macro-keyword-object2.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-object2.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-object2.scala b/test/disabled/neg/macro-keyword-object2.scala deleted file mode 100644 index 6f5b9ceacd..0000000000 --- a/test/disabled/neg/macro-keyword-object2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test7 { - object macro -} diff --git a/test/disabled/neg/macro-keyword-package1.check b/test/disabled/neg/macro-keyword-package1.check deleted file mode 100644 index 22c1e11ded..0000000000 --- a/test/disabled/neg/macro-keyword-package1.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-package1.scala:1: error: identifier expected but 'macro' found. -package macro - ^ -one error found diff --git a/test/disabled/neg/macro-keyword-package1.flags b/test/disabled/neg/macro-keyword-package1.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-package1.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-package1.scala b/test/disabled/neg/macro-keyword-package1.scala deleted file mode 100644 index 52d3fbabf6..0000000000 --- a/test/disabled/neg/macro-keyword-package1.scala +++ /dev/null @@ -1,3 +0,0 @@ -package macro - -package macro.bar \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-package2.check b/test/disabled/neg/macro-keyword-package2.check deleted file mode 100644 index 0cb542a85d..0000000000 --- a/test/disabled/neg/macro-keyword-package2.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-package2.scala:3: error: identifier expected but 'macro' found. -package macro.foo - ^ -one error found diff --git a/test/disabled/neg/macro-keyword-package2.flags b/test/disabled/neg/macro-keyword-package2.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-package2.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-package2.scala b/test/disabled/neg/macro-keyword-package2.scala deleted file mode 100644 index a68ebd935f..0000000000 --- a/test/disabled/neg/macro-keyword-package2.scala +++ /dev/null @@ -1,3 +0,0 @@ -package foo - -package macro.foo diff --git a/test/disabled/neg/macro-keyword-trait1.check b/test/disabled/neg/macro-keyword-trait1.check deleted file mode 100644 index 9586a62e08..0000000000 --- a/test/disabled/neg/macro-keyword-trait1.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-trait1.scala:3: error: identifier expected but 'macro' found. -trait macro - ^ -one error found diff --git a/test/disabled/neg/macro-keyword-trait1.flags b/test/disabled/neg/macro-keyword-trait1.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-trait1.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-trait1.scala b/test/disabled/neg/macro-keyword-trait1.scala deleted file mode 100644 index e32d4c1385..0000000000 --- a/test/disabled/neg/macro-keyword-trait1.scala +++ /dev/null @@ -1,3 +0,0 @@ -package test8 - -trait macro diff --git a/test/disabled/neg/macro-keyword-trait2.check b/test/disabled/neg/macro-keyword-trait2.check deleted file mode 100644 index 40aa764378..0000000000 --- a/test/disabled/neg/macro-keyword-trait2.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-trait2.scala:2: error: identifier expected but 'macro' found. - trait macro - ^ -one error found diff --git a/test/disabled/neg/macro-keyword-trait2.flags b/test/disabled/neg/macro-keyword-trait2.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-trait2.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-trait2.scala b/test/disabled/neg/macro-keyword-trait2.scala deleted file mode 100644 index 243a54abe6..0000000000 --- a/test/disabled/neg/macro-keyword-trait2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test9 { - trait macro -} diff --git a/test/disabled/neg/macro-keyword-type.check b/test/disabled/neg/macro-keyword-type.check deleted file mode 100644 index 4a7481114c..0000000000 --- a/test/disabled/neg/macro-keyword-type.check +++ /dev/null @@ -1,4 +0,0 @@ -macro-keyword-type.scala:2: error: identifier expected but 'macro' found. - type macro = Int - ^ -one error found diff --git a/test/disabled/neg/macro-keyword-type.flags b/test/disabled/neg/macro-keyword-type.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-type.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-type.scala b/test/disabled/neg/macro-keyword-type.scala deleted file mode 100644 index 30e523bcaf..0000000000 --- a/test/disabled/neg/macro-keyword-type.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test3 { - type macro = Int -} \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-val.check b/test/disabled/neg/macro-keyword-val.check deleted file mode 100644 index 0dc4c030a9..0000000000 --- a/test/disabled/neg/macro-keyword-val.check +++ /dev/null @@ -1,7 +0,0 @@ -macro-keyword-val.scala:2: error: illegal start of simple pattern - val macro = ??? - ^ -macro-keyword-val.scala:3: error: '=' expected but '}' found. -} -^ -two errors found diff --git a/test/disabled/neg/macro-keyword-val.flags b/test/disabled/neg/macro-keyword-val.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-val.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-val.scala b/test/disabled/neg/macro-keyword-val.scala deleted file mode 100644 index 96f57acb30..0000000000 --- a/test/disabled/neg/macro-keyword-val.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test1 { - val macro = ??? -} \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-var.check b/test/disabled/neg/macro-keyword-var.check deleted file mode 100644 index 96d02e0052..0000000000 --- a/test/disabled/neg/macro-keyword-var.check +++ /dev/null @@ -1,7 +0,0 @@ -macro-keyword-var.scala:2: error: illegal start of simple pattern - var macro = ??? - ^ -macro-keyword-var.scala:3: error: '=' expected but '}' found. -} -^ -two errors found diff --git a/test/disabled/neg/macro-keyword-var.flags b/test/disabled/neg/macro-keyword-var.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/disabled/neg/macro-keyword-var.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros \ No newline at end of file diff --git a/test/disabled/neg/macro-keyword-var.scala b/test/disabled/neg/macro-keyword-var.scala deleted file mode 100644 index a79dda6dc2..0000000000 --- a/test/disabled/neg/macro-keyword-var.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test2 { - var macro = ??? -} \ No newline at end of file -- cgit v1.2.3 From 59bcf821eec1bbf61fd646ea3fe909083df02fba Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 14 Apr 2012 21:08:31 +0100 Subject: Revert "change com.typesafe.config dep to version 0.4.0" This reverts commit f67a00a3cef270835369b8ab1bb57cbe8b2bd2a3. --- build.xml | 2 +- src/build/maven/scala-library-pom.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.xml b/build.xml index d2438e3112..1a0e85a6f0 100644 --- a/build.xml +++ b/build.xml @@ -249,7 +249,7 @@ INITIALISATION - + diff --git a/src/build/maven/scala-library-pom.xml b/src/build/maven/scala-library-pom.xml index e8db512125..c3f8a4531c 100644 --- a/src/build/maven/scala-library-pom.xml +++ b/src/build/maven/scala-library-pom.xml @@ -32,9 +32,9 @@ - com.typesafe - config - 0.4.0 + org.skife.com.typesafe.config + typesafe-config + 0.3.0 -- cgit v1.2.3 From 364dd41c3e0e33afe6c3ec6e0c04f1d345c4b6ca Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 15 Apr 2012 10:41:47 +0100 Subject: Fix for test checkfile. --- test/files/neg/t5666.check | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/test/files/neg/t5666.check b/test/files/neg/t5666.check index 1be51d0138..cc31390dc7 100644 --- a/test/files/neg/t5666.check +++ b/test/files/neg/t5666.check @@ -1,37 +1,10 @@ t5666.scala:2: error: class Any is abstract; cannot be instantiated new Any ^ -t5666.scala:3: error: trait AnyVal is abstract; cannot be instantiated +t5666.scala:3: error: class AnyVal is abstract; cannot be instantiated new AnyVal ^ -t5666.scala:4: error: Double does not have a constructor - new Double - ^ -t5666.scala:5: error: Float does not have a constructor - new Float - ^ -t5666.scala:6: error: Long does not have a constructor - new Long - ^ -t5666.scala:7: error: Int does not have a constructor - new Int - ^ -t5666.scala:8: error: Char does not have a constructor - new Char - ^ -t5666.scala:9: error: Short does not have a constructor - new Short - ^ -t5666.scala:10: error: Byte does not have a constructor - new Byte - ^ -t5666.scala:11: error: Boolean does not have a constructor - new Boolean - ^ -t5666.scala:12: error: Unit does not have a constructor - new Unit - ^ t5666.scala:13: error: trait Nothing is abstract; cannot be instantiated new Nothing ^ -12 errors found +three errors found -- cgit v1.2.3