diff options
75 files changed, 473 insertions, 100 deletions
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index 4f5b28d370..6c843e6f15 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -327,8 +327,19 @@ trait Importers { self: SymbolTable => null } if (mytree != null) { - if (mytree hasSymbol) mytree.symbol = importSymbol(tree.symbol) - mytree.tpe = importType(tree.tpe) + val mysym = if (tree hasSymbol) importSymbol(tree.symbol) else NoSymbol + val mytpe = importType(tree.tpe) + + mytree match { + case mytt: TypeTree => + val tt = tree.asInstanceOf[from.TypeTree] + if (mytree hasSymbol) mytt.symbol = mysym + if (tt.wasEmpty) mytt.defineType(mytpe) else mytt.setType(mytpe) + if (tt.original != null) mytt.setOriginal(importTree(tt.original)) + case _ => + if (mytree hasSymbol) mytree.symbol = importSymbol(tree.symbol) + mytree.tpe = importType(tree.tpe) + } } mytree } diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index b3069adfb4..b1a24c0be2 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -271,6 +271,7 @@ trait StdNames extends NameManglers { self: SymbolTable => // Compiler utilized names // val productElementName: NameType = "productElementName" val Ident: NameType = "Ident" + val This: NameType = "This" val StringContext: NameType = "StringContext" val TYPE_ : NameType = "TYPE" val TypeTree: NameType = "TypeTree" diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index 5bb0c98bfb..ca7801ac9d 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -251,8 +251,6 @@ trait Trees extends api.Trees { self: SymbolTable => def Super(sym: Symbol, mix: TypeName): Tree = Super(This(sym), mix) - def This(sym: Symbol): Tree = This(sym.name.toTypeName) setSymbol sym - /** Block factory that flattens directly nested blocks. */ def Block(stats: Tree*): Block = { diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala index 46d890c5d1..6e671ae06e 100644 --- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala +++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala @@ -44,17 +44,19 @@ trait ToolBoxes extends { self: Universe => // !!! 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)) val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName("<expression-owner>"), List(ObjectClass.tpe), newScope) val owner = ownerClass.newLocalDummy(tree.pos) - - typer.atOwner(tree, owner).typed(tree, analyzer.EXPRmode, pt) + val ttree = typer.atOwner(tree, owner).typed(tree, analyzer.EXPRmode, pt) + trace("typed: ")(showAttributed(ttree)) + 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, ScalaObjectClass.tpe), newScope, obj.moduleClass) @@ -66,9 +68,7 @@ trait ToolBoxes extends { self: Universe => minfo.decls enter meth trace("wrapping ")(defOwner(expr) -> meth) val methdef = DefDef(meth, expr changeOwner (defOwner(expr) -> meth)) - trace("wrapped: ")(showAttributed(methdef)) - resetAllAttrs( - ModuleDef( + val moduledef = ModuleDef( obj, Template( List(TypeTree(ObjectClass.tpe)), @@ -77,7 +77,11 @@ trait ToolBoxes extends { self: Universe => List(), List(List()), List(methdef), - NoPosition))) + NoPosition)) + trace("wrapped: ")(showAttributed(moduledef)) + val cleanedUp = resetLocalAttrs(moduledef) + trace("cleaned up: ")(showAttributed(cleanedUp)) + cleanedUp } def wrapInPackage(clazz: Tree): PackageDef = @@ -91,7 +95,7 @@ trait ToolBoxes extends { self: Universe => def compileExpr(expr: Tree, fvs: List[Symbol]): String = { val mdef = wrapInObject(expr, fvs) - val pdef = trace("wrapped: ")(wrapInPackage(mdef)) + val pdef = wrapInPackage(mdef) val unit = wrapInCompilationUnit(pdef) val run = new Run run.compileUnits(List(unit), run.namerPhase) @@ -104,24 +108,27 @@ trait ToolBoxes extends { self: Universe => def runExpr(expr: Tree): Any = { val etpe = expr.tpe val fvs = (expr filter isFree map (_.symbol)).distinct - + reporter.reset() val className = compileExpr(expr, fvs) if (reporter.hasErrors) { throw new Error("reflective compilation has failed") } - + if (settings.debug.value) println("generated: "+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) - val result = jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*) - if (etpe.typeSymbol != FunctionClass(0)) result - else { - val applyMeth = result.getClass.getMethod("apply") - applyMeth.invoke(result) - } + // @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]): _*) +// 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]): _*) } def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = { @@ -131,7 +138,7 @@ trait ToolBoxes extends { self: Universe => try { settings.printtypes.value = printTypes settings.uniqid.value = printIds - settings.uniqid.value = printKinds + settings.Yshowsymkinds.value = printKinds tree.toString } finally { settings.printtypes.value = saved1 @@ -167,7 +174,7 @@ trait ToolBoxes extends { self: Universe => lazy val exporter = importer.reverse lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, defaultReflectiveClassLoader) - + private def importAndTypeCheck(tree: rm.Tree, expectedType: rm.Type): compiler.Tree = { // 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 @@ -189,8 +196,8 @@ trait ToolBoxes extends { self: Universe => def typeCheck(tree: rm.Tree): rm.Tree = typeCheck(tree, WildcardType.asInstanceOf[rm.Type]) - def showAttributed(tree: rm.Tree): String = - compiler.showAttributed(importer.importTree(tree.asInstanceOf[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) def runExpr(tree: rm.Tree, expectedType: rm.Type): Any = { val ttree = importAndTypeCheck(tree, expectedType) diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index c80b07c44d..83b6252b26 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -42,8 +42,8 @@ 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. + + /** 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. @@ -208,7 +208,7 @@ trait Trees extends reflect.internal.Trees { self: Global => case _ => this.treeCopy.SelectFromArray(tree, qualifier, selector, erasure) } def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match { - case t @ ReferenceToBoxed(idt0) + case t @ ReferenceToBoxed(idt0) if (idt0 == idt) => t case _ => this.treeCopy.ReferenceToBoxed(tree, idt) } @@ -251,62 +251,79 @@ trait Trees extends reflect.internal.Trees { self: Global => } } - /** resets symbol and tpe fields in a tree, @see ResetAttrsTraverse + /** resets symbol and tpe fields in a tree, @see ResetAttrs */ // 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 ResetAttrsTransformer(false).transformPoly(x) - def resetLocalAttrs[A<:Tree](x:A): A = new ResetAttrsTransformer(true).transformPoly(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) /** A transformer which resets symbol and tpe fields of all nodes in a given tree, * with special treatment of: * TypeTree nodes: are replaced by their original if it exists, otherwise tpe field is reset * to empty if it started out empty or refers to local symbols (which are erased). * TypeApply nodes: are deleted if type arguments end up reverted to empty - * This(pkg) notes where pkg is a pckage: these are kept. + * This(pkg) nodes where pkg is a package: these are kept. * - * (bq:) This traverser has mutable state and should be discarded after use + * (bq:) This transformer has mutable state and should be discarded after use */ - private class ResetAttrsTransformer(localOnly: Boolean) extends Transformer { - private val erasedSyms = util.HashSet[Symbol](8) - private def resetDef(tree: Tree) { - if (tree.symbol != null && tree.symbol != NoSymbol) - erasedSyms addEntry tree.symbol - tree.symbol = NoSymbol + private class ResetAttrs(localOnly: Boolean) { + val locals = util.HashSet[Symbol](8) + + class MarkLocals extends self.Traverser { + def markLocal(tree: Tree) = + if (tree.symbol != null && tree.symbol != NoSymbol) + locals addEntry tree.symbol + + override def traverse(tree: Tree) = { + tree match { + case _: DefTree | Function(_, _) | Template(_, _, _) => + markLocal(tree) + case _ if tree.symbol.isInstanceOf[FreeVar] => + markLocal(tree) + case _ => + ; + } + + super.traverse(tree) + } } - override def transform(tree: Tree): Tree = super.transform { - tree match { - case Template(_, _, body) => - body foreach resetDef - resetDef(tree) - tree.tpe = null - tree - case _: DefTree | Function(_, _) | Template(_, _, _) => - resetDef(tree) - tree.tpe = null - tree - case tpt: TypeTree => - if (tpt.original != null) - tpt.original - else if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => erasedSyms contains tp.typeSymbol)))) - tpt.tpe = null - tree - case TypeApply(fn, args) if args map transform exists (_.isEmpty) => - fn - case This(_) if tree.symbol != null && tree.symbol.isPackageClass => - tree - case EmptyTree => - tree - case _ => - if (tree.hasSymbol && (!localOnly || (erasedSyms contains tree.symbol))) - tree.symbol = NoSymbol - tree.tpe = null - tree + + 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 + } + 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 transformPoly[T <: Tree](x: T): T = { - val x1 = transform(x) + + def transform[T <: Tree](x: T): T = { + new MarkLocals().traverse(x) + + val trace = scala.tools.nsc.util.trace when settings.debug.value + val eoln = System.getProperty("line.separator") + trace("locals (%d total): %n".format(locals.size))(locals.toList map {" " + _} mkString eoln) + + val x1 = new Transformer().transform(x) assert(x.getClass isInstance x1) x1.asInstanceOf[T] } diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 107ffc35c6..d1ce460eb9 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -166,7 +166,9 @@ trait ScalaSettings extends AbsScalaSettings val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.") val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") - val Yreifydebug = BooleanSetting ("-Yreify-debug", "Trace reification actions.") + val Yreifydebug = BooleanSetting ("-Yreify-debug", "Trace reification.") + val Yreifytyperdebug + = BooleanSetting ("-Yreifytyper-debug", "Trace typings of reified trees.") val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") val Yrepldebug = BooleanSetting ("-Yrepl-debug", "Trace all repl activity.") . withPostSetHook(_ => interpreter.replProps.debug setValue true) diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index f1182fc2a9..d0ed92f8ba 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -55,10 +55,16 @@ abstract class LiftCode extends Transform with TypingTransformers { class Codifier(unit: CompilationUnit) extends TypingTransformer(unit) { val reifyDebug = settings.Yreifydebug.value + val reifyTyperDebug = settings.Yreifytyperdebug.value val debugTrace = util.trace when reifyDebug val reifyCopypaste = settings.Yreifycopypaste.value def printCopypaste(tree: Tree) { + if (reifyDebug) println("=======================") + printCopypaste1(tree) + if (reifyDebug) println("=======================") + } + def printCopypaste1(tree: Tree) { import scala.reflect.api.Modifier import scala.reflect.api.Modifier._ @@ -123,11 +129,14 @@ abstract class LiftCode extends Transform with TypingTransformers { case Apply(_, List(tree)) if sym == Code_lift => // reify Code.lift[T](expr) instances val saved = printTypings try { - printTypings = reifyDebug + debugTrace("transforming = ")(if (settings.Xshowtrees.value) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) debugTrace("transformed = ") { - val result = localTyper.typedPos(tree.pos)(codify(super.transform(tree))) - if (reifyCopypaste) printCopypaste(result) - result + val untyped = codify(super.transform(tree)) + if (reifyCopypaste) printCopypaste(untyped) + + printTypings = reifyTyperDebug + val typed = localTyper.typedPos(tree.pos)(untyped) + typed } } catch { case ex: ReifierError => @@ -145,7 +154,8 @@ abstract class LiftCode extends Transform with TypingTransformers { val targetType = definitions.CodeClass.primaryConstructor.info.paramTypes.head val reifier = new Reifier() val arg = gen.mkAsInstanceOf(reifier.reifyTopLevel(tree), targetType, wrapInApply = false) - val treetpe = + val treetpe = // this really should use packedType(tree.tpe, context.owner) + // where packedType is defined in Typers. But we can do that only if liftCode is moved to Typers. if (tree.tpe.typeSymbol.isAnonymousClass) tree.tpe.typeSymbol.classBound else tree.tpe New(TypeTree(appliedType(definitions.CodeClass.typeConstructor, List(treetpe.widen))), @@ -274,6 +284,14 @@ abstract class LiftCode extends Transform with TypingTransformers { 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 == EmptyPackageClass) + mirrorSelect("definitions.EmptyPackageClass") else if (sym.isModuleClass) Select(reifySymRef(sym.sourceModule), "moduleClass") else if (sym.isStatic && sym.isClass) @@ -300,7 +318,7 @@ abstract class LiftCode extends Transform with TypingTransformers { if (sym.isTerm) { if (reifyDebug) println("Free: " + sym) val symtpe = lambdaLift.boxIfCaptured(sym, sym.tpe, erasedTypes = false) - def markIfCaptured(arg: Ident): Tree = + def markIfCaptured(arg: Ident): Tree = if (sym.isCapturedVariable) referenceCapturedVariable(arg) else arg mirrorCall("freeVar", reify(sym.name.toString), reify(symtpe), markIfCaptured(Ident(sym))) } else { @@ -381,6 +399,14 @@ abstract class LiftCode extends Transform with TypingTransformers { } } + private def definedInLiftedCode(tpe: Type) = + tpe exists (tp => boundSyms contains tp.typeSymbol) + + private def isErased(tree: Tree) = tree match { + case tt: TypeTree => definedInLiftedCode(tt.tpe) && tt.original == null + case _ => false + } + /** Reify a tree */ private def reifyTree(tree: Tree): Tree = tree match { case EmptyTree => @@ -393,13 +419,21 @@ abstract class LiftCode extends Transform with TypingTransformers { mirrorCall("Select", reifyFree(tree), reifyName(nme.elem)) } else reifyFree(tree) case tt: TypeTree if (tt.tpe != null) => - if (!(boundSyms exists (tt.tpe contains _))) mirrorCall("TypeTree", reifyType(tt.tpe)) - else if (tt.original != null) reify(tt.original) - else mirrorCall(nme.TypeTree) + if (definedInLiftedCode(tt.tpe)) { + // erase non-essential (i.e. inferred) types + // reify symless counterparts of essential types + if (tt.original != null) reify(tt.original) else mirrorCall("TypeTree") + } else { + var rtt = mirrorCall(nme.TypeTree, reifyType(tt.tpe)) + if (tt.original != null) { + val setOriginal = Select(rtt, newTermName("setOriginal")) + val reifiedOriginal = reify(tt.original) + rtt = Apply(setOriginal, List(reifiedOriginal)) + } + rtt + } case ta @ TypeApply(hk, ts) => - val thereAreOnlyTTs = ts collect { case t if !t.isInstanceOf[TypeTree] => t } isEmpty; - val ttsAreNotEssential = ts collect { case tt: TypeTree => tt } find { tt => tt.original != null } isEmpty; - if (thereAreOnlyTTs && ttsAreNotEssential) reifyTree(hk) else reifyProduct(ta) + if (ts exists isErased) reifyTree(hk) else reifyProduct(ta) case global.emptyValDef => mirrorSelect(nme.emptyValDef) case Literal(constant @ Constant(tpe: Type)) if boundSyms exists (tpe contains _) => @@ -407,8 +441,10 @@ abstract class LiftCode extends Transform with TypingTransformers { case Literal(constant @ Constant(sym: Symbol)) if boundSyms contains sym => CannotReifyClassOfBoundEnum(tree, constant.tpe) case _ => - if (tree.isDef) + if (tree.isDef) { + if (reifyDebug) println("boundSym: " + tree.symbol) boundSyms += tree.symbol + } reifyProduct(tree) /* @@ -424,8 +460,19 @@ abstract class LiftCode extends Transform with TypingTransformers { * 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 = - mirrorCall(nme.Ident, reifySymRef(tree.symbol)) + 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("freeVar", 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 = diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index eaf1b1ffbc..036e7fc750 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -625,7 +625,7 @@ trait Implicits { if (context.hasErrors) fail("typing TypeApply reported errors for the implicit tree") else { - val result = new SearchResult(checked, subst) + val result = new SearchResult(itree2, subst) incCounter(foundImplicits) printInference("[success] found %s for pt %s".format(result, ptInstantiated)) result diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d3ff331f98..2749f99e18 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -100,6 +100,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case MethodType(params, _) => val argResultsBuff = new ListBuffer[SearchResult]() val argBuff = new ListBuffer[Tree]() + var paramFailed = false def mkPositionalArg(argTree: Tree, paramName: Name) = argTree def mkNamedArg(argTree: Tree, paramName: Name) = atPos(argTree.pos)(new AssignOrNamedArg(Ident(paramName), (argTree))) @@ -114,14 +115,14 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { for(ar <- argResultsBuff) paramTp = paramTp.subst(ar.subst.from, ar.subst.to) - val res = inferImplicit(fun, paramTp, true, false, context) + val res = if (paramFailed) SearchFailure else inferImplicit(fun, paramTp, context.reportErrors, false, context) argResultsBuff += res if (res != SearchFailure) { argBuff += mkArg(res.tree, param.name) } else { mkArg = mkNamedArg // don't pass the default argument (if any) here, but start emitting named arguments for the following args - if (!param.hasDefault) { + if (!param.hasDefault && !paramFailed) { context.errBuffer.find(_.kind == ErrorKinds.Divergent) match { case Some(divergentImplicit) => // DivergentImplicit error has higher priority than "no implicit found" @@ -133,6 +134,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case None => NoImplicitFoundError(fun, param) } + paramFailed = true } /* else { TODO: alternative (to expose implicit search failure more) --> @@ -767,7 +769,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { withCondConstrTyper(treeInfo.isSelfOrSuperConstrCall(tree)){ typer1 => if (original != EmptyTree && pt != WildcardType) - typer1.silent(tpr => tpr.typed(tpr.applyImplicitArgs(tree), mode, pt)) match { + typer1.silent(tpr => { + val withImplicitArgs = tpr.applyImplicitArgs(tree) + if (tpr.context.hasErrors) tree // silent will wrap it in SilentTypeError anyway + else tpr.typed(withImplicitArgs, mode, pt) + }) match { case SilentResultValue(result) => result case _ => @@ -2915,7 +2921,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { existentialAbstraction(captured.toList, tpe) } - /** convert skolems to existentials */ + /** convert local symbols and skolems to existentials */ def packedType(tree: Tree, owner: Symbol): Type = { def defines(tree: Tree, sym: Symbol) = sym.isExistentialSkolem && sym.unpackLocation == tree || diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala index 08071660a2..3526cf259d 100755 --- a/src/library/scala/reflect/api/StandardDefinitions.scala +++ b/src/library/scala/reflect/api/StandardDefinitions.scala @@ -12,7 +12,7 @@ trait StandardDefinitions { self: Universe => abstract class AbsDefinitions { // outer packages and their classes - def RootPackage: Symbol + def RootPackage: Symbol // under consideration def RootClass: Symbol def EmptyPackage: Symbol def EmptyPackageClass: Symbol @@ -46,6 +46,11 @@ trait StandardDefinitions { self: Universe => def StringClass : Symbol def ClassClass : Symbol + // product, tuple, function + def TupleClass : Array[Symbol] + def ProductClass : Array[Symbol] + def FunctionClass : Array[Symbol] + // fundamental modules def PredefModule: Symbol diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 03b043c188..0a38fb45bf 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -537,6 +537,9 @@ trait Trees { self: Universe => // 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 + /** Designator <qualifier> . <name> */ case class Select(qualifier: Tree, name: Name) extends RefTree diff --git a/src/partest/scala/tools/partest/utils/CodeTest.scala b/src/partest/scala/tools/partest/utils/CodeTest.scala index c90168a313..c236d89bbd 100644 --- a/src/partest/scala/tools/partest/utils/CodeTest.scala +++ b/src/partest/scala/tools/partest/utils/CodeTest.scala @@ -24,11 +24,17 @@ object CodeTest { def apply[T](code: Code[T], args: Array[String] = Array()) = { println("testing: "+code.tree) + println("type is: "+code.manifest.tpe) + val isNullary = code.manifest.tpe.typeSymbol == scala.reflect.mirror.definitions.FunctionClass(0) val reporter = new ConsoleReporter(new Settings) val toolbox = new ToolBox(reporter, args mkString " ") val ttree = toolbox.typeCheck(code.tree, code.manifest.tpe) - println("result = " + toolbox.showAttributed(ttree)) - val evaluated = toolbox.runExpr(ttree) + println("result = " + toolbox.showAttributed(ttree, printTypes = true, printIds = false)) + var evaluated = toolbox.runExpr(ttree) + if (evaluated != null && isNullary) { + val applyMeth = evaluated.getClass.getMethod("apply") + evaluated = applyMeth.invoke(evaluated) + } println("evaluated = "+evaluated) evaluated } diff --git a/test/files/run/code.check b/test/files/run/code.check index b946554fda..9b0351bbf9 100644 --- a/test/files/run/code.check +++ b/test/files/run/code.check @@ -1,29 +1,36 @@ testing: ((x: Int) => x.$plus(ys.length)) +type is: Int => Int result = ((x: Int) => x.+{(x: <?>)Int}(ys.length{Int}){Int}){Int => Int} evaluated = <function1> testing: (() => { val e: Element = new Element("someName"); e }) +type is: () => Element result = (() => { val e: Element = new Element{Element}{(name: <?>)Element}("someName"{String("someName")}){Element}; e{Element} }{Element}){() => Element} evaluated = Element(someName) testing: (() => truc.elem = 6) +type is: () => Unit result = (() => truc.elem{Int} = 6{Int(6)}{Unit}){() => Unit} evaluated = null testing: (() => truc.elem = truc.elem.$plus(6)) +type is: () => Unit result = (() => truc.elem{Int} = truc.elem.+{(x: <?>)Int}(6{Int(6)}){Int}{Unit}){() => Unit} evaluated = null testing: (() => new baz.BazElement("someName")) +type is: () => baz.BazElement result = (() => new baz.BazElement{baz.BazElement}{(name: <?>)baz.BazElement}("someName"{String("someName")}){baz.BazElement}){() => baz.BazElement} evaluated = BazElement(someName) testing: ((x: Int) => x.$plus(ys.length)) +type is: Int => Int result = ((x: Int) => x.+{(x: <?>)Int}(ys.length{Int}){Int}){Int => Int} evaluated = <function1> static: 2 testing: (() => x.$plus(1)) +type is: () => Int result = (() => x.+{(x: <?>)Int}(1{Int(1)}){Int}){() => Int} evaluated = 2 1+1 = 2 diff --git a/test/pending/run/reify_closure1.check b/test/files/run/reify_closure1.check index b2f7f08c17..b2f7f08c17 100644 --- a/test/pending/run/reify_closure1.check +++ b/test/files/run/reify_closure1.check diff --git a/test/pending/run/reify_closure1.scala b/test/files/run/reify_closure1.scala index 825a38dc1d..825a38dc1d 100644 --- a/test/pending/run/reify_closure1.scala +++ b/test/files/run/reify_closure1.scala diff --git a/test/pending/run/reify_closure2a.check b/test/files/run/reify_closure2a.check index c1f3abd7e6..c1f3abd7e6 100644 --- a/test/pending/run/reify_closure2a.check +++ b/test/files/run/reify_closure2a.check diff --git a/test/pending/run/reify_closure2a.scala b/test/files/run/reify_closure2a.scala index b88bec005d..b88bec005d 100644 --- a/test/pending/run/reify_closure2a.scala +++ b/test/files/run/reify_closure2a.scala diff --git a/test/pending/run/reify_closure3a.check b/test/files/run/reify_closure3a.check index c1f3abd7e6..c1f3abd7e6 100644 --- a/test/pending/run/reify_closure3a.check +++ b/test/files/run/reify_closure3a.check diff --git a/test/pending/run/reify_closure3a.scala b/test/files/run/reify_closure3a.scala index 6414fa58a3..6414fa58a3 100644 --- a/test/pending/run/reify_closure3a.scala +++ b/test/files/run/reify_closure3a.scala diff --git a/test/pending/run/reify_closure4a.check b/test/files/run/reify_closure4a.check index c1f3abd7e6..c1f3abd7e6 100644 --- a/test/pending/run/reify_closure4a.check +++ b/test/files/run/reify_closure4a.check diff --git a/test/pending/run/reify_closure4a.scala b/test/files/run/reify_closure4a.scala index 99e9d82706..99e9d82706 100644 --- a/test/pending/run/reify_closure4a.scala +++ b/test/files/run/reify_closure4a.scala diff --git a/test/pending/run/reify_closure5a.check b/test/files/run/reify_closure5a.check index df9e19c591..df9e19c591 100644 --- a/test/pending/run/reify_closure5a.check +++ b/test/files/run/reify_closure5a.check diff --git a/test/pending/run/reify_closure5a.scala b/test/files/run/reify_closure5a.scala index 0ac53d5479..0ac53d5479 100644 --- a/test/pending/run/reify_closure5a.scala +++ b/test/files/run/reify_closure5a.scala diff --git a/test/files/run/reify_closure6.check b/test/files/run/reify_closure6.check new file mode 100644 index 0000000000..b9de4c6baf --- /dev/null +++ b/test/files/run/reify_closure6.check @@ -0,0 +1,7 @@ +q = 1 +y = 1 +first invocation = 15 +q = 2 +y = 1 +second invocation = 17 +q after second invocation = 2
\ No newline at end of file diff --git a/test/pending/run/reify_closure6.scala b/test/files/run/reify_closure6.scala index 909071aa44..54f1791bf2 100644 --- a/test/pending/run/reify_closure6.scala +++ b/test/files/run/reify_closure6.scala @@ -10,6 +10,8 @@ object Test extends App { val fun: reflect.Code[Int => Int] = x => { y += 1 q += 1 + println("q = " + q) + println("y = " + y) x + ys.length * z + q + y } @@ -23,4 +25,4 @@ object Test extends App { println("first invocation = " + foo(List(1, 2, 3))(10)) println("second invocation = " + foo(List(1, 2, 3, 4))(10)) println("q after second invocation = " + q) -} +}
\ No newline at end of file diff --git a/test/files/run/reify_closure7.check b/test/files/run/reify_closure7.check new file mode 100644 index 0000000000..bf58b52bce --- /dev/null +++ b/test/files/run/reify_closure7.check @@ -0,0 +1,6 @@ +q = 1 +y = 1 +first invocation = 15 +q = 2 +y = 2 +second invocation = 17 diff --git a/test/files/run/reify_closure7.scala b/test/files/run/reify_closure7.scala new file mode 100644 index 0000000000..8933df23fa --- /dev/null +++ b/test/files/run/reify_closure7.scala @@ -0,0 +1,32 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + var q = 0 + var clo: Int => Int = null + def foo[T](ys: List[T]): Int => Int = { + val z = 1 + var y = 0 + val fun: reflect.Code[Int => Int] = x => { + y += 1 + q += 1 + println("q = " + q) + println("y = " + y) + x + ys.length * z + q + y + } + + if (clo == null) { + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + clo = dyn.asInstanceOf[Int => Int] + } + + clo + } + + println("first invocation = " + foo(List(1, 2, 3))(10)) + println("second invocation = " + foo(List(1, 2, 3, 4))(10)) +} diff --git a/test/files/run/reify_closure8a.check b/test/files/run/reify_closure8a.check new file mode 100644 index 0000000000..9a037142aa --- /dev/null +++ b/test/files/run/reify_closure8a.check @@ -0,0 +1 @@ +10
\ No newline at end of file diff --git a/test/files/run/reify_closure8a.scala b/test/files/run/reify_closure8a.scala new file mode 100644 index 0000000000..5e54bfc8c7 --- /dev/null +++ b/test/files/run/reify_closure8a.scala @@ -0,0 +1,17 @@ +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(val y: Int) { + def fun = lift{y} + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(10).fun.tree) + val dyn = toolbox.runExpr(ttree) + val foo = dyn.asInstanceOf[Int] + println(foo) +} diff --git a/test/files/run/reify_closures10.check b/test/files/run/reify_closures10.check new file mode 100644 index 0000000000..fd3c81a4d7 --- /dev/null +++ b/test/files/run/reify_closures10.check @@ -0,0 +1,2 @@ +5 +5 diff --git a/test/files/run/reify_closures10.scala b/test/files/run/reify_closures10.scala new file mode 100644 index 0000000000..d0f895ae4d --- /dev/null +++ b/test/files/run/reify_closures10.scala @@ -0,0 +1,15 @@ +import scala.reflect.Code._ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val x = 2 + val y = 3 + val code = lift{println(x + y); x + y} + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + println(toolbox.runExpr(ttree)) +} diff --git a/test/pending/run/reify_complex.check b/test/files/run/reify_complex.check index 7df35e33a0..7df35e33a0 100644 --- a/test/pending/run/reify_complex.check +++ b/test/files/run/reify_complex.check diff --git a/test/pending/run/reify_complex.scala b/test/files/run/reify_complex.scala index aae4d558cf..aae4d558cf 100644 --- a/test/pending/run/reify_complex.scala +++ b/test/files/run/reify_complex.scala diff --git a/test/pending/run/reify_extendbuiltins.check b/test/files/run/reify_extendbuiltins.check index a48033a30d..a48033a30d 100644 --- a/test/pending/run/reify_extendbuiltins.check +++ b/test/files/run/reify_extendbuiltins.check diff --git a/test/pending/run/reify_extendbuiltins.scala b/test/files/run/reify_extendbuiltins.scala index 57acd699ff..57acd699ff 100644 --- a/test/pending/run/reify_extendbuiltins.scala +++ b/test/files/run/reify_extendbuiltins.scala diff --git a/test/files/run/reify_generic2.check b/test/files/run/reify_generic2.check new file mode 100644 index 0000000000..b8626c4cff --- /dev/null +++ b/test/files/run/reify_generic2.check @@ -0,0 +1 @@ +4 diff --git a/test/files/run/reify_generic2.scala b/test/files/run/reify_generic2.scala new file mode 100644 index 0000000000..d03fe7602b --- /dev/null +++ b/test/files/run/reify_generic2.scala @@ -0,0 +1,16 @@ +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{ + 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) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/test/files/run/reify_getter.check b/test/files/run/reify_getter.check new file mode 100644 index 0000000000..5ef4ff4d04 --- /dev/null +++ b/test/files/run/reify_getter.check @@ -0,0 +1 @@ +evaluated = 2 diff --git a/test/files/run/reify_getter.scala b/test/files/run/reify_getter.scala new file mode 100644 index 0000000000..83eaded506 --- /dev/null +++ b/test/files/run/reify_getter.scala @@ -0,0 +1,19 @@ +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{ + class C { + val x = 2 + } + + new C().x + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + val evaluated = toolbox.runExpr(ttree) + println("evaluated = " + evaluated) +} diff --git a/test/pending/run/reify_implicits.check b/test/files/run/reify_implicits.check index e3aeb20f6b..e3aeb20f6b 100644 --- a/test/pending/run/reify_implicits.check +++ b/test/files/run/reify_implicits.check diff --git a/test/pending/run/reify_implicits.scala b/test/files/run/reify_implicits.scala index a15cef9c97..a15cef9c97 100644 --- a/test/pending/run/reify_implicits.scala +++ b/test/files/run/reify_implicits.scala diff --git a/test/pending/run/reify_sort.check b/test/files/run/reify_sort.check index 375536cc29..375536cc29 100644 --- a/test/pending/run/reify_sort.check +++ b/test/files/run/reify_sort.check diff --git a/test/pending/run/reify_sort.scala b/test/files/run/reify_sort.scala index 42991fe5d2..42991fe5d2 100644 --- a/test/pending/run/reify_sort.scala +++ b/test/files/run/reify_sort.scala diff --git a/test/pending/run/reify_sort1.check b/test/files/run/reify_sort1.check index 0d30805141..0d30805141 100644 --- a/test/pending/run/reify_sort1.check +++ b/test/files/run/reify_sort1.check diff --git a/test/pending/run/reify_sort1.scala b/test/files/run/reify_sort1.scala index 42f4c824a5..42f4c824a5 100644 --- a/test/pending/run/reify_sort1.scala +++ b/test/files/run/reify_sort1.scala diff --git a/test/files/run/reify_this.check b/test/files/run/reify_this.check new file mode 100644 index 0000000000..af3d0652a9 --- /dev/null +++ b/test/files/run/reify_this.check @@ -0,0 +1,5 @@ +foo +false +2 +bar +2
\ No newline at end of file diff --git a/test/files/run/reify_this.scala b/test/files/run/reify_this.scala new file mode 100644 index 0000000000..38ef72b6eb --- /dev/null +++ b/test/files/run/reify_this.scala @@ -0,0 +1,31 @@ +import scala.reflect._ +import scala.reflect.Code._ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +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) + val ttree = toolbox.typeCheck(tree) + toolbox.runExpr(ttree) + } +} + +object Test extends App with Eval { + // select a value from package + eval(lift{println("foo")}) + eval(lift{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)}) + + // select a value from module + val x = 2 + eval(lift{println(x)}) +} diff --git a/test/pending/run/t5269.check b/test/files/run/t5269.check index 0cfbf08886..0cfbf08886 100644 --- a/test/pending/run/t5269.check +++ b/test/files/run/t5269.check diff --git a/test/pending/run/t5269.scala b/test/files/run/t5269.scala index a30509f3fe..a30509f3fe 100644 --- a/test/pending/run/t5269.scala +++ b/test/files/run/t5269.scala diff --git a/test/pending/run/t5274_1.check b/test/files/run/t5274_1.check index fca8bc3d3e..fca8bc3d3e 100644 --- a/test/pending/run/t5274_1.check +++ b/test/files/run/t5274_1.check diff --git a/test/pending/run/t5274_1.scala b/test/files/run/t5274_1.scala index c501172518..c501172518 100644 --- a/test/pending/run/t5274_1.scala +++ b/test/files/run/t5274_1.scala diff --git a/test/pending/run/t5274_2.check b/test/files/run/t5274_2.check index 375536cc29..375536cc29 100644 --- a/test/pending/run/t5274_2.check +++ b/test/files/run/t5274_2.check diff --git a/test/pending/run/t5274_2.scala b/test/files/run/t5274_2.scala index 42991fe5d2..42991fe5d2 100644 --- a/test/pending/run/t5274_2.scala +++ b/test/files/run/t5274_2.scala diff --git a/test/pending/run/t5275.check b/test/files/run/t5275.check index 0cfbf08886..0cfbf08886 100644 --- a/test/pending/run/t5275.check +++ b/test/files/run/t5275.check diff --git a/test/pending/run/t5275.scala b/test/files/run/t5275.scala index d419834ded..d419834ded 100644 --- a/test/pending/run/t5275.scala +++ b/test/files/run/t5275.scala diff --git a/test/pending/run/t5277_1.check b/test/files/run/t5277_1.check index a48033a30d..a48033a30d 100644 --- a/test/pending/run/t5277_1.check +++ b/test/files/run/t5277_1.check diff --git a/test/pending/run/t5277_1.scala b/test/files/run/t5277_1.scala index 57acd699ff..57acd699ff 100644 --- a/test/pending/run/t5277_1.scala +++ b/test/files/run/t5277_1.scala diff --git a/test/files/run/t5277_2.check b/test/files/run/t5277_2.check new file mode 100644 index 0000000000..ca017e2a40 --- /dev/null +++ b/test/files/run/t5277_2.check @@ -0,0 +1,2 @@ +2() +1() diff --git a/test/pending/run/t5277_2.scala b/test/files/run/t5277_2.scala index 67b6b000bc..67b6b000bc 100644 --- a/test/pending/run/t5277_2.scala +++ b/test/files/run/t5277_2.scala diff --git a/test/pending/run/t5279.check b/test/files/run/t5279.check index f599e28b8a..f599e28b8a 100644 --- a/test/pending/run/t5279.check +++ b/test/files/run/t5279.check diff --git a/test/pending/run/t5279.scala b/test/files/run/t5279.scala index 39e7dd2c66..39e7dd2c66 100644 --- a/test/pending/run/t5279.scala +++ b/test/files/run/t5279.scala diff --git a/test/pending/run/t5277_2.check b/test/files/run/t5335.check index 5f1d0ecea5..0cfbf08886 100644 --- a/test/pending/run/t5277_2.check +++ b/test/files/run/t5335.check @@ -1,2 +1 @@ 2 -1 diff --git a/test/files/run/t5335.scala b/test/files/run/t5335.scala new file mode 100644 index 0000000000..9a8b91f04d --- /dev/null +++ b/test/files/run/t5335.scala @@ -0,0 +1,14 @@ +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(new {def x = 2}.x) + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/test/files/run/t5415.check b/test/files/run/t5415.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/run/t5415.check diff --git a/test/files/run/t5415.scala b/test/files/run/t5415.scala new file mode 100644 index 0000000000..3db356da86 --- /dev/null +++ b/test/files/run/t5415.scala @@ -0,0 +1,14 @@ +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)} + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) +} diff --git a/test/pending/run/reify_closure6.check b/test/pending/run/reify_closure6.check deleted file mode 100644 index 3526d04b0e..0000000000 --- a/test/pending/run/reify_closure6.check +++ /dev/null @@ -1,3 +0,0 @@ -first invocation = 15 -second invocation = 18 -q after second invocation = 2 diff --git a/test/pending/run/reify_closure8b.check b/test/pending/run/reify_closure8b.check new file mode 100644 index 0000000000..9a037142aa --- /dev/null +++ b/test/pending/run/reify_closure8b.check @@ -0,0 +1 @@ +10
\ No newline at end of file diff --git a/test/pending/run/reify_closure8b.scala b/test/pending/run/reify_closure8b.scala new file mode 100644 index 0000000000..9e37e4e09a --- /dev/null +++ b/test/pending/run/reify_closure8b.scala @@ -0,0 +1,17 @@ +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 ttree = toolbox.typeCheck(new Foo(10).fun.tree) + val dyn = toolbox.runExpr(ttree) + val foo = dyn.asInstanceOf[Int] + println(foo) +} diff --git a/test/pending/run/reify_closure9a.check b/test/pending/run/reify_closure9a.check new file mode 100644 index 0000000000..9a037142aa --- /dev/null +++ b/test/pending/run/reify_closure9a.check @@ -0,0 +1 @@ +10
\ No newline at end of file diff --git a/test/pending/run/reify_closure9a.scala b/test/pending/run/reify_closure9a.scala new file mode 100644 index 0000000000..f3ee153d3c --- /dev/null +++ b/test/pending/run/reify_closure9a.scala @@ -0,0 +1,20 @@ +import scala.reflect.Code._ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int) = { + class Foo(val y: Int) { + def fun = lift{y} + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(y).fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int] + } + + println(foo(10)) +} diff --git a/test/pending/run/reify_closure9b.check b/test/pending/run/reify_closure9b.check new file mode 100644 index 0000000000..9a037142aa --- /dev/null +++ b/test/pending/run/reify_closure9b.check @@ -0,0 +1 @@ +10
\ No newline at end of file diff --git a/test/pending/run/reify_closure9b.scala b/test/pending/run/reify_closure9b.scala new file mode 100644 index 0000000000..8d349e8701 --- /dev/null +++ b/test/pending/run/reify_closure9b.scala @@ -0,0 +1,20 @@ +import scala.reflect.Code._ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int) = { + class Foo(y: Int) { + def fun = lift{y} + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(y).fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int] + } + + println(foo(10)) +} diff --git a/test/pending/run/reify_closures11.check b/test/pending/run/reify_closures11.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/pending/run/reify_closures11.check @@ -0,0 +1 @@ +2
\ No newline at end of file diff --git a/test/pending/run/reify_closures11.scala b/test/pending/run/reify_closures11.scala new file mode 100644 index 0000000000..42053bd029 --- /dev/null +++ b/test/pending/run/reify_closures11.scala @@ -0,0 +1,18 @@ +import scala.reflect.Code._ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def fun() = { + def z() = 2 + lift{z} + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun().tree) + val dyn = toolbox.runExpr(ttree) + val foo = dyn.asInstanceOf[Int] + println(foo) +} diff --git a/tools/get-scala-revision b/tools/get-scala-revision index 8d48c8cb78..eac512a010 100755 --- a/tools/get-scala-revision +++ b/tools/get-scala-revision @@ -16,9 +16,12 @@ tag=$(git describe --abbrev=0) # the full string - padding correctness depends on abbrev=10. described=$(git describe --abbrev=10 --always --tags) +suffix="${described##${tag}-}" +counter=$(echo $suffix | cut -d - -f 1) +hash=$(echo $suffix | cut -d - -f 2) # 016 is rocket-surgically-calibrated to pad the distance from the # tag to the current commit into a 4-digit number - since maven # will be treating this as a string, the ide depends on # 10 being greater than 9 (thus 0010 and 00009.) -printf "%s-%016s-%s\n" "$tag" "${described##${tag}-}" $(date "+%Y-%m-%d") +printf "%s-%04d-%10s-%s\n" "$tag" "$counter" "$hash" $(date "+%Y-%m-%d") |