From 28483739c365b1a3b748ebab50b03bd66a4db61d Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Sat, 14 Apr 2012 19:50:21 +0200 Subject: restore typedMatchAnonFun in all its glory detect partialfunction in cpsannotationchecker emit apply/isDefinedAt if PF has @cps targs (applyOrElse can't be typed) further hacky improvements to selective anf better try/catch support in selective cps using freshly minted anonfun match make virtpatmat resilient to scaladoc (after uncurry, don't translate matches TODO: factor out translation all together so presentation compiler/scaladoc can skip it) --- .../scala/reflect/internal/Definitions.scala | 7 +++ .../scala/tools/nsc/transform/UnCurry.scala | 6 +- .../tools/nsc/typechecker/PatMatVirtualiser.scala | 6 +- .../scala/tools/nsc/typechecker/Typers.scala | 73 ++++++++++++++-------- .../tools/selectivecps/CPSAnnotationChecker.scala | 3 +- .../tools/selectivecps/SelectiveANFTransform.scala | 6 +- .../tools/selectivecps/SelectiveCPSTransform.scala | 49 +++++++-------- 7 files changed, 89 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 72fca5da12..4d1dc69afc 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -400,6 +400,8 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN_NAME, 0L)(_ => AnyClass.tpe) lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.tpe)) lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => seqType(tparam.tpe)) + + lazy val MarkerCPSTypes = getClassIfDefined("scala.util.continuations.cpsParam") def isByNameParamType(tp: Type) = tp.typeSymbol == ByNameParamClass def isScalaRepeatedParamType(tp: Type) = tp.typeSymbol == RepeatedParamClass @@ -655,6 +657,11 @@ trait Definitions extends reflect.api.StandardDefinitions { false } + def isPartialFunctionType(tp: Type): Boolean = { + val sym = tp.typeSymbol + (sym eq PartialFunctionClass) || (sym eq AbstractPartialFunctionClass) + } + def isSeqType(tp: Type) = elementType(SeqClass, tp.normalize) != NoType def elementType(container: Symbol, tp: Type): Type = tp match { diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 57cd51ad35..6b894a724f 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -446,8 +446,10 @@ abstract class UnCurry extends InfoTransform } val members = - if (isPartial) List(applyOrElseMethodDef, isDefinedAtMethodDef) - else List(applyMethodDef) + if (isPartial) { + assert(!opt.virtPatmat, "PartialFunction should have been synthesized during typer "+ fun); + List(applyOrElseMethodDef, isDefinedAtMethodDef) + } else List(applyMethodDef) // println("MEMBERS "+ members) val res = localTyper.typedPos(fun.pos) { diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 1fd9f6fc13..82e2442ba8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -135,7 +135,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer => // 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.uncurryPhase.id, phase) + if(phase.id >= currentRun.uncurryPhase.id) debugwarn("running translateMatch at "+ phase +" on "+ scrut +" match "+ cases) val scrutSym = freshSym(scrut.pos, pureType(scrutType)) setFlag SYNTH_CASE // pt = Any* occurs when compiling test/files/pos/annotDepMethType.scala with -Xexperimental @@ -1107,7 +1107,9 @@ class Foo(x: Other) { x._1 } // no error in this order // 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) + 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 = 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) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 0541f85f31..ff54c11af8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2193,6 +2193,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def adaptCase(cdef: CaseDef, mode: Int, tpe: Type): CaseDef = deriveCaseDef(cdef)(adapt(_, mode, tpe)) + // takes untyped sub-trees of a match and type checks them def typedMatch(selector0: Tree, cases: List[CaseDef], mode: Int, resTp: Type) = { val (selector, doTranslation) = selector0 match { case Annotated(Ident(nme.synthSwitch), selector) => (selector, false) @@ -2210,6 +2211,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { (selector1, selectorTp, casesAdapted, ownType, doTranslation) } + // match has been typed, now translate it 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) @@ -2271,11 +2273,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // need to duplicate the cases before typing them to generate the apply method, or the symbols will be all messed up val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => TRUE_typed).duplicate) else Nil + def parentsPartial(targs: List[Type]) = List(appliedType(AbstractPartialFunctionClass.typeConstructor, targs), SerializableClass.tpe) def applyMethod = { // 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 methodSym = anonClass.newMethod(nme.apply, tree.pos, if(isPartial) (FINAL | OVERRIDE) else FINAL) val (paramSyms, selector) = mkParams(methodSym) if (selector eq EmptyTree) EmptyTree @@ -2288,7 +2291,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { 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) + val parents = + if (isPartial) parentsPartial(List(methFormals.head, resTp)) + else List(abstractFunctionType(methFormals, resTp), SerializableClass.tpe) anonClass setInfo ClassInfoType(parents, newScope, anonClass) methodSym setInfoAndEnter MethodType(paramSyms, resTp) @@ -2301,9 +2306,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def applyOrElseMethodDef = { // rig the show so we can get started typing the method body -- later we'll correct the infos... // targs were type arguments for PartialFunction, so we know they will work for AbstractPartialFunction as well - def parents(targs: List[Type]) = List(appliedType(AbstractPartialFunctionClass.typeConstructor, targs), SerializableClass.tpe) - - anonClass setInfo ClassInfoType(parents(targs), newScope, anonClass) + anonClass setInfo ClassInfoType(parentsPartial(targs), newScope, anonClass) val methodSym = anonClass.newMethod(nme.applyOrElse, tree.pos, FINAL | OVERRIDE) // create the parameter that corresponds to the function's parameter @@ -2325,7 +2328,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.typedMatch(selector, cases, mode, ptRes) - anonClass setInfo ClassInfoType(parents(List(argTp, resTp)), newScope, anonClass) + anonClass setInfo ClassInfoType(parentsPartial(List(argTp, resTp)), newScope, anonClass) B1 setInfo TypeBounds.lower(resTp) anonClass.info.decls enter methodSym // methodSym's info need not change (B1's bound has been updated instead) @@ -2354,7 +2357,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } } - val members = if (!isPartial) List(applyMethod) else List(applyOrElseMethodDef, isDefinedAtMethod) + val members = if (isPartial) { + if ((MarkerCPSTypes ne NoSymbol) && (targs exists (_ hasAnnotation MarkerCPSTypes))) List(applyMethod, isDefinedAtMethod) + else List(applyOrElseMethodDef, isDefinedAtMethod) + } else List(applyMethod) + if (members.head eq EmptyTree) setError(tree) else typed(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos)), New(anonClass.tpe)), mode, pt) } @@ -2409,21 +2416,31 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } } - val vparamSyms = fun.vparams map { vparam => - enterSym(context, vparam) - if (context.retyping) context.scope enter vparam.symbol - vparam.symbol + fun.body match { + // later phase indicates scaladoc is calling (where shit is messed up, I tell you) + // -- so fall back to old patmat, which is more forgiving + case Match(sel, cases) if opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id) => + // 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 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) } } @@ -3795,9 +3812,14 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } } - // translation only happens when (selector != EmptyTree) && !isPastTyper && opt.virtPatmat def typedTranslatedMatch(tree: Tree, selector: Tree, cases: List[CaseDef]): Tree = { - if (selector == EmptyTree) { + if (opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id)) { + if (selector ne EmptyTree) { + val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = typedMatch(selector, cases, mode, pt) + typed(translatedMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt) + } else typedMatchAnonFun(tree, cases, mode, pt) + } else if (selector == EmptyTree) { + if (opt.virtPatmat) debugwarn("virtpatmat should not encounter empty-selector matches "+ tree) 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) { @@ -3808,7 +3830,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 (!((phase.id < currentRun.uncurryPhase.id) && opt.virtPatmat)) { + } else { val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType)) var cases1 = typedCases(cases, packCaptured(selector1.tpe.widen), pt) val (owntype, needAdapt) = ptOrLub(cases1 map (_.tpe)) @@ -3816,9 +3838,6 @@ 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) } } diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala index af0d768607..bed8e93d1b 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala @@ -94,8 +94,7 @@ abstract class CPSAnnotationChecker extends CPSUtils { if (!cpsEnabled) return bounds val anyAtCPS = newCpsParamsMarker(NothingClass.tpe, AnyClass.tpe) - - if (isFunctionType(tparams.head.owner.tpe) || tparams.head.owner == PartialFunctionClass) { + if (isFunctionType(tparams.head.owner.tpe) || isPartialFunctionType(tparams.head.owner.tpe)) { vprintln("function bound: " + tparams.head.owner.tpe + "/"+bounds+"/"+targs) if (hasCpsParamTypes(targs.last)) bounds.reverse match { diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala index 0975f16c6e..e1d699debc 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala @@ -457,11 +457,13 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with 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)) { + // SUPER UGLY HACK: handle virtpatmat-style matches, whose labels have already been turned into DefDefs + if (anfStats.nonEmpty && (anfStats forall (t => !t.isDef || gen.hasSynthCaseSymbol(t)))) { 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 + // the filter drops the ()'s emitted when transValue encountered a LabelDef + val stats = prologue ++ (rest filter (_.isInstanceOf[DefDef])).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) diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala index 2db4054ef5..a78de8e6c8 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala @@ -190,32 +190,29 @@ abstract class SelectiveCPSTransform extends PluginComponent with val targettp = transformCPSType(tree.tpe) -// val expr2 = if (catches.nonEmpty) { - val pos = catches.head.pos - val argSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe) - val rhs = Match(Ident(argSym), catches1) - val fun = Function(List(ValDef(argSym)), rhs) - val funSym = currentOwner.newValueParameter(cpsNames.catches, pos).setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp))) - val funDef = localTyper.typed(atPos(pos) { ValDef(funSym, fun) }) - val expr2 = localTyper.typed(atPos(pos) { Apply(Select(expr1, expr1.tpe.member(cpsNames.flatMapCatch)), List(Ident(funSym))) }) - - argSym.owner = fun.symbol - rhs.changeOwner(currentOwner -> fun.symbol) - - val exSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe) - - 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))) + val pos = catches.head.pos + val funSym = currentOwner.newValueParameter(cpsNames.catches, pos).setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp))) + val funDef = localTyper.typed(atPos(pos) { + ValDef(funSym, Match(EmptyTree, catches1)) + }) + val expr2 = localTyper.typed(atPos(pos) { + Apply(Select(expr1, expr1.tpe.member(cpsNames.flatMapCatch)), List(Ident(funSym))) + }) + + val exSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe) + + 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))) /* -- cgit v1.2.3 From c2cd6acf993d66eac6f6917ee3b7300eeaceb8a3 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Sat, 14 Apr 2012 15:43:33 +0200 Subject: don't emit tiny switches: optimizer chokes on them workaround for inliner bug in run/t3835 see SI-5672 for the optimizer bug tiny switches (2 cases or less) don't make sense anyway, so this is not a big deal the annotDepMethType.flags contained -Xexperimental, which causes Any* to be considered as a valid return type, before we weren't exposed to this, because the product methods used (tiny) switches; with this change, they went back to pattern matches in any case, the -Xexperimental was intended to turn on dependent method types, not Any* as valid type (I can only assume), and they are now on by default the other tests were affected by our refusal to emit tiny switches --- .../tools/nsc/typechecker/PatMatVirtualiser.scala | 2 +- test/files/pos/annotDepMethType.flags | 1 - test/files/run/inline-ex-handlers.check | 109 +++++++++++---------- test/files/run/t5272_1.flags | 1 + test/files/run/t5272_2.flags | 1 + 5 files changed, 60 insertions(+), 54 deletions(-) delete mode 100644 test/files/pos/annotDepMethType.flags create mode 100644 test/files/run/t5272_1.flags create mode 100644 test/files/run/t5272_2.flags (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 82e2442ba8..88cea2231f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -1570,7 +1570,7 @@ class Foo(x: Other) { x._1 } // no error in this order // TODO: if patterns allow switch but the type of the scrutinee doesn't, cast (type-test) the scrutinee to the corresponding switchable type and switch on the result if (regularSwitchMaker.switchableTpe(scrutSym.tpe)) { val caseDefsWithDefault = regularSwitchMaker(cases map {c => (scrutSym, c)}, pt) - if (caseDefsWithDefault isEmpty) None + if (caseDefsWithDefault.length <= 2) None // not worth emitting a switch... also, the optimizer has trouble digesting tiny switches, apparently, so let's be nice and not generate them else { // match on scrutSym -- converted to an int if necessary -- not on scrut directly (to avoid duplicating scrut) val scrutToInt: Tree = diff --git a/test/files/pos/annotDepMethType.flags b/test/files/pos/annotDepMethType.flags deleted file mode 100644 index e1b37447c9..0000000000 --- a/test/files/pos/annotDepMethType.flags +++ /dev/null @@ -1 +0,0 @@ --Xexperimental \ No newline at end of file diff --git a/test/files/run/inline-ex-handlers.check b/test/files/run/inline-ex-handlers.check index 708fcc6985..a5d7e93334 100644 --- a/test/files/run/inline-ex-handlers.check +++ b/test/files/run/inline-ex-handlers.check @@ -1,23 +1,27 @@ 172c172 -< locals: value x$1, value x1 +< locals: value x$1, value x1, value x2, value x --- -> locals: value x$1, value x1, variable boxed1 +> locals: value x$1, value x1, value x2, value x, variable boxed1 174c174 -< blocks: [1,2,3,4] +< blocks: [1,2,3,5,6,7] --- -> blocks: [1,3,4] -186a187,188 -> 92 STORE_LOCAL(variable boxed1) -> 92 LOAD_LOCAL(variable boxed1) -195,197d196 +> blocks: [1,3,5,6] +180,182d179 < 92 JUMP 2 < < 2: -385c384 +194,196d190 +< 92 JUMP 7 +< +< 7: +204a199,200 +> 92 STORE_LOCAL(variable boxed1) +> 92 LOAD_LOCAL(variable boxed1) +395c391 < blocks: [1,2,3,4,5,8,11,13,14,16] --- > blocks: [1,2,3,5,8,11,13,14,16,17] -409c408,417 +419c415,424 < 103 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -30,15 +34,15 @@ > 106 LOAD_LOCAL(value x3) > 106 IS_INSTANCE REF(class MyException) > 106 CZJUMP (BOOL)NE ? 5 : 11 -422,424d429 +432,434d436 < 101 JUMP 4 < < 4: -512c517 +522c524 < blocks: [1,2,3,4,6,7,8,9,10] --- > blocks: [1,2,3,4,6,7,8,9,10,11,12,13] -541c546,551 +551c553,558 < 306 THROW(MyException) --- > ? JUMP 11 @@ -47,7 +51,7 @@ > ? LOAD_LOCAL(variable monitor4) > 305 MONITOR_EXIT > ? JUMP 12 -547c557,563 +557c564,570 < ? THROW(Throwable) --- > ? JUMP 12 @@ -57,7 +61,7 @@ > 304 MONITOR_EXIT > ? STORE_LOCAL(value t) > ? JUMP 13 -553c569,582 +563c576,589 < ? THROW(Throwable) --- > ? STORE_LOCAL(value t) @@ -74,29 +78,30 @@ > 310 CALL_PRIMITIVE(EndConcat) > 310 CALL_METHOD scala.Predef.println (dynamic) > 310 JUMP 2 -577c606 +587c613 < catch (Throwable) in ArrayBuffer(7, 8, 9, 10) starting at: 6 --- > catch (Throwable) in ArrayBuffer(7, 8, 9, 10, 11) starting at: 6 -580c609 +590c616 < 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 -612c641 +622c648 < blocks: [1,2,3,4,5,6,7,9,10] --- > blocks: [1,2,3,4,5,6,7,9,10,11,12] -636c665,671 +646c672,673 < 78 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) > ? JUMP 11 -> +647a675,679 > 11: > 81 LOAD_LOCAL(value e) > ? STORE_LOCAL(variable exc1) > ? JUMP 12 -665c700,714 +> +675c707,721 < 81 THROW(Exception) --- > ? STORE_LOCAL(variable exc1) @@ -114,15 +119,15 @@ > 84 STORE_LOCAL(variable result) > 84 LOAD_LOCAL(variable exc1) > 84 THROW(Throwable) -687c736 +697c743 < catch () in ArrayBuffer(4, 6, 7, 9) starting at: 3 --- > catch () in ArrayBuffer(4, 6, 7, 9, 11) starting at: 3 -713c762 +723c769 < 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,9,12,14,17,18,19,22,25,27,28,30,31,32,33,34] -737c786,793 +747c793,800 < 172 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -133,12 +138,12 @@ > 170 STORE_LOCAL(value x3) > 170 SCOPE_ENTER value x3 > 170 JUMP 18 -793c849,850 +803c856,857 < 177 THROW(MyException) --- > ? STORE_LOCAL(value ex5) > ? JUMP 33 -797c854,861 +807c861,868 < 170 THROW(Throwable) --- > ? STORE_LOCAL(value ex5) @@ -149,17 +154,17 @@ > 169 STORE_LOCAL(value x3) > 169 SCOPE_ENTER value x3 > 169 JUMP 5 -830c894,895 +840c901,902 < 182 THROW(MyException) --- > ? STORE_LOCAL(variable exc2) > ? JUMP 34 -834c899,900 +844c906,907 < 169 THROW(Throwable) --- > ? STORE_LOCAL(variable exc2) > ? JUMP 34 -835a902,914 +845a909,921 > 34: > 184 LOAD_MODULE object Predef > 184 CONSTANT("finally") @@ -173,19 +178,19 @@ > 185 LOAD_LOCAL(variable exc2) > 185 THROW(Throwable) > -856c935 +866c942 < catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30) starting at: 4 --- > catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30, 32) starting at: 4 -859c938 +869c945 < 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, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30, 32, 33) starting at: 3 -885c964 +895c971 < blocks: [1,2,3,6,7,8,11,14,16,17,19] --- > blocks: [1,2,3,6,7,8,11,14,16,17,19,20] -909c988,995 +919c995,1002 < 124 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -196,15 +201,15 @@ > 122 STORE_LOCAL(value x3) > 122 SCOPE_ENTER value x3 > 122 JUMP 7 -969c1055 +979c1062 < 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 +1005c1088 < 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 +1029c1112,1121 < 148 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -217,15 +222,15 @@ > 154 LOAD_LOCAL(value x3) > 154 IS_INSTANCE REF(class MyException) > 154 CZJUMP (BOOL)NE ? 5 : 11 -1040,1042d1134 +1050,1052d1141 < 145 JUMP 4 < < 4: -1275c1367 +1285c1374 < blocks: [1,2,3,4,5,7] --- > blocks: [1,2,3,4,5,7,8] -1299c1391,1398 +1309c1398,1405 < 38 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) @@ -236,16 +241,16 @@ > 42 CONSTANT("IllegalArgumentException") > 42 CALL_METHOD scala.Predef.println (dynamic) > 42 JUMP 2 -1348c1447 +1358c1454 < blocks: [1,2,3,4,5,8,11,13,14,16,17,19] --- > blocks: [1,2,3,5,8,11,13,14,16,17,19,20] -1372c1471,1472 +1382c1478,1479 < 203 THROW(MyException) --- > ? STORE_LOCAL(value ex5) > ? JUMP 20 -1392c1492,1501 +1402c1499,1508 < 209 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -258,15 +263,15 @@ > 212 LOAD_LOCAL(value x3) > 212 IS_INSTANCE REF(class MyException) > 212 CZJUMP (BOOL)NE ? 5 : 11 -1405,1407d1513 +1415,1417d1520 < 200 JUMP 4 < < 4: -1467c1573 +1477c1580 < blocks: [1,2,3,4,5,7] --- > blocks: [1,2,3,4,5,7,8] -1491c1597,1604 +1501c1604,1611 < 58 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) @@ -277,11 +282,11 @@ > 62 CONSTANT("RuntimeException") > 62 CALL_METHOD scala.Predef.println (dynamic) > 62 JUMP 2 -1540c1653 +1550c1660 < blocks: [1,2,3,4] --- > blocks: [1,2,3,4,5] -1560c1673,1678 +1570c1680,1685 < 229 THROW(MyException) --- > ? JUMP 5 @@ -290,19 +295,19 @@ > ? LOAD_LOCAL(variable monitor1) > 228 MONITOR_EXIT > 228 THROW(Throwable) -1566c1684 +1576c1691 < ? THROW(Throwable) --- > 228 THROW(Throwable) -1594c1712 +1604c1719 < locals: value args, variable result, variable monitor2, variable monitorResult1 --- > locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1 -1596c1714 +1606c1721 < blocks: [1,2,3,4] --- > blocks: [1,2,3,4,5] -1619c1737,1745 +1629c1744,1752 < 245 THROW(MyException) --- > ? STORE_LOCAL(value exception$1) @@ -314,7 +319,7 @@ > ? LOAD_LOCAL(variable monitor2) > 244 MONITOR_EXIT > 244 THROW(Throwable) -1625c1751 +1635c1758 < ? THROW(Throwable) --- > 244 THROW(Throwable) diff --git a/test/files/run/t5272_1.flags b/test/files/run/t5272_1.flags new file mode 100644 index 0000000000..cb8324a345 --- /dev/null +++ b/test/files/run/t5272_1.flags @@ -0,0 +1 @@ +-Xoldpatmat \ No newline at end of file diff --git a/test/files/run/t5272_2.flags b/test/files/run/t5272_2.flags new file mode 100644 index 0000000000..cb8324a345 --- /dev/null +++ b/test/files/run/t5272_2.flags @@ -0,0 +1 @@ +-Xoldpatmat \ No newline at end of file -- cgit v1.2.3 From 967ceb28ab2737ee16112b4c9be46419f43b9a99 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sun, 15 Apr 2012 11:36:43 +0200 Subject: big fat error message for default mirror failures --- src/library/scala/reflect/ReflectionUtils.scala | 22 ++++++++ src/library/scala/reflect/package.scala | 67 ++++++++++++++++++++++--- 2 files changed, 83 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/library/scala/reflect/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala index 1be46eac55..79a42f6ec4 100644 --- a/src/library/scala/reflect/ReflectionUtils.scala +++ b/src/library/scala/reflect/ReflectionUtils.scala @@ -27,6 +27,28 @@ object ReflectionUtils { case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex)) } + private def systemProperties: Iterator[(String, String)] = { + import scala.collection.JavaConverters._ + System.getProperties.asScala.iterator + } + + private def searchForBootClasspath = ( + systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse "" + ) + + def show(cl: ClassLoader) = { + def inferClasspath(cl: ClassLoader) = cl match { + case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]" + case _ => "" + } + cl match { + case cl if cl != null => + "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl)) + case null => + "primordial classloader with boot classpath [%s]".format(searchForBootClasspath) + } + } + def defaultReflectionClassLoader() = { // say no to non-determinism of mirror classloaders // default classloader will be instantiated using current system classloader diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 1738642932..6f40a3ac3e 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -3,6 +3,7 @@ package scala package object reflect { import ReflectionUtils._ + import scala.compat.Platform.EOL // !!! 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 @@ -12,15 +13,69 @@ package object reflect { // 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) + private def mirrorDiagnostics(cl: ClassLoader): String = """ + | + | This error has happened because `scala.reflect.runtime.package` located in + | scala-compiler.jar cannot be loaded. Classloader you are using is: + | %s. + | + | In Scala 2.10.0 M3, scala-compiler.jar is required to be on the classpath + | for manifests and type tags to function. This will change in the final release, + | but for now you need to adjust your scripts or build system to proceed. + | Here are the instructions for some of the situations that might be relevant. + | + | If you compile your application directly from the command line + | or a hand-rolled script, this is a bug. Please, report it. + | + | If you compile your application with Maven using the maven-scala plugin, + | set its "fork" configuration entry to "false: + | + | + | org.scala-tools + | maven-scala-plugin + | 2.15.0 + | + | + | + | ... + | + | + | false + | ... + | + | + | + | + | + | If you compile your application with SBT, + | + | + | If you compile your application in Scala IDE, + | . + | + | If you launch your application directly from the command line + | or a hand-rolled script, add `scala-compiler.jar` to the classpath: + | + | scalac HelloWorld.scala + | scala HelloWorld -cp path/to/scala-compiler.jar + | + | If you launch your application with Maven using the maven-scala plugin, + | set its "fork" configuration entry to "false as shown above. + | + | If you launch your application with SBT, make sure that you use + | + | + | If you launch your application in Scala IDE, make sure that both scala-library.jar and scala-compiler.jar + | are in bootstrap entries on the classpath of your launch configuration. + """.stripMargin('|').format(show(cl)) + 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 - // 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) + val coreClassLoader = getClass.getClassLoader + val instance = invokeFactoryOpt(coreClassLoader, "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") + case Some(_) => throw new UnsupportedOperationException("Available scala reflection implementation is incompatible with this interface." + mirrorDiagnostics(coreClassLoader)) + case None => throw new UnsupportedOperationException("Scala reflection not available on this platform." + mirrorDiagnostics(coreClassLoader)) } } -- cgit v1.2.3 From 23ae258c37bd5de050ae9d8b4287dc8c309af8de Mon Sep 17 00:00:00 2001 From: Vlad Ureche Date: Mon, 16 Apr 2012 02:32:20 +0200 Subject: Inliner won't touch private/protected fields anymore And we'll need a separate mechanism for making internal fields public. --- src/compiler/scala/tools/nsc/CompilationUnits.scala | 3 +++ src/compiler/scala/tools/nsc/Global.scala | 3 ++- .../scala/tools/nsc/backend/opt/Inliners.scala | 18 +++++++++++------- .../scala/tools/nsc/settings/ScalaSettings.scala | 1 + 4 files changed, 17 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index 92a0efff1e..369c59cd43 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -93,6 +93,9 @@ trait CompilationUnits { self: Global => def uncheckedWarning(pos: Position, msg: String) = currentRun.uncheckedWarnings.warn(pos, msg) + def inlinerWarning(pos: Position, msg: String) = + currentRun.inlinerWarnings.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 403b5717b0..7cfccf3baf 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -964,7 +964,8 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S 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) + val inlinerWarnings = new ConditionalWarning("inliner", settings.YinlinerWarnings) + val allConditionalWarnings = List(deprecationWarnings, uncheckedWarnings, featureWarnings, inlinerWarnings) var reportedFeature = Set[Symbol]() diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index cf51a5b926..05d8c632c0 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -135,7 +135,7 @@ abstract class Inliners extends SubComponent { /** The current iclass */ private var currentIClazz: IClass = _ - private def warn(pos: Position, msg: String) = currentIClazz.cunit.warning(pos, msg) + private def warn(pos: Position, msg: String) = currentIClazz.cunit.inlinerWarning(pos, msg) val recentTFAs = mutable.Map.empty[Symbol, Tuple2[Boolean, analysis.MethodTFA]] private def getRecentTFA(incm: IMethod): (Boolean, analysis.MethodTFA) = { @@ -759,12 +759,16 @@ abstract class Inliners extends SubComponent { private def helperIsSafeToInline(stackLength: Int): Boolean = { def makePublic(f: Symbol): Boolean = - (inc.m.sourceFile ne NoSourceFile) && (f.isSynthetic || f.isParamAccessor) && { - debuglog("Making not-private symbol out of synthetic: " + f) - - f setNotFlag Flags.PRIVATE - true - } + /* + * Completely disabling member publifying. This shouldn't have been done in the first place. :| + */ + false + // (inc.m.sourceFile ne NoSourceFile) && (f.isSynthetic || f.isParamAccessor) && { + // debuglog("Making not-private symbol out of synthetic: " + f) + + // f setNotFlag Flags.PRIVATE + // true + // } if (!inc.m.hasCode || inc.isRecursive) { return false } if (inc.m.symbol.hasFlag(Flags.SYNCHRONIZED)) { return false } diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index d4c2ffa832..6a5c4c92bc 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -138,6 +138,7 @@ trait ScalaSettings extends AbsScalaSettings 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 YinlinerWarnings= BooleanSetting ("-Yinline-warnings", "Emit inlining warnings. (Normally surpressed due to high volume)") 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.") -- cgit v1.2.3 From 4a6f54b5f16b3179b23a44f2f1d83f080e218f72 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 14 Apr 2012 06:16:32 +0100 Subject: New facility: TypeDestructurers. Would prefer to bake a little longer, but, scala days. More elaboration to come. --- .../scala/reflect/internal/Definitions.scala | 6 +- .../scala/reflect/internal/SymbolCreations.scala | 1 - .../scala/reflect/internal/SymbolFlags.scala | 1 - src/compiler/scala/reflect/internal/Symbols.scala | 10 +- src/compiler/scala/reflect/internal/Types.scala | 5 +- .../scala/tools/nsc/CompilationUnits.scala | 2 +- src/compiler/scala/tools/nsc/Global.scala | 7 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 9 +- .../scala/tools/nsc/interpreter/CodeHandlers.scala | 12 +- .../scala/tools/nsc/interpreter/ExprTyper.scala | 117 +++++------- .../scala/tools/nsc/interpreter/ILoop.scala | 178 +++++++++++------- .../scala/tools/nsc/interpreter/IMain.scala | 81 +++++--- .../tools/nsc/interpreter/JLineCompletion.scala | 9 +- .../tools/nsc/interpreter/MemberHandlers.scala | 3 + .../scala/tools/nsc/interpreter/Power.scala | 4 +- .../scala/tools/nsc/interpreter/ReplGlobal.scala | 57 ++++++ .../scala/tools/nsc/interpreter/ReplReporter.scala | 4 + .../scala/tools/nsc/interpreter/ReplVals.scala | 7 +- .../scala/tools/nsc/interpreter/RichClass.scala | 5 +- .../scala/tools/nsc/interpreter/TypeStrings.scala | 136 ++++++++++++++ .../tools/nsc/typechecker/ContextErrors.scala | 4 +- .../tools/nsc/typechecker/DestructureTypes.scala | 206 +++++++++++++++++++++ src/library/scala/collection/SeqExtractors.scala | 3 + test/files/jvm/interpreter.check | 5 +- test/files/run/repl-colon-type.check | 173 ++++++++++++++++- test/files/run/repl-colon-type.scala | 8 + test/files/run/repl-power.check | 1 - test/files/run/repl-type-verbose.check | 186 +++++++++++++++++++ test/files/run/repl-type-verbose.scala | 20 ++ 29 files changed, 1067 insertions(+), 193 deletions(-) create mode 100644 src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala create mode 100644 src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala create mode 100644 test/files/run/repl-type-verbose.check create mode 100644 test/files/run/repl-type-verbose.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 72fca5da12..66b505c0d1 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -292,7 +292,7 @@ trait Definitions extends reflect.api.StandardDefinitions { sealed abstract class BottomClassSymbol(name: TypeName, parent: Symbol) extends ClassSymbol(ScalaPackageClass, NoPosition, name) { locally { - this initFlags ABSTRACT | TRAIT | FINAL + this initFlags ABSTRACT | FINAL this setInfoAndEnter ClassInfoType(List(parent.tpe), newScope, this) } final override def isBottomClass = true @@ -1014,10 +1014,10 @@ trait Definitions extends reflect.api.StandardDefinitions { val flatname = nme.flattenedName(owner.name, name) getMember(pkg, flatname) } else { - throw new FatalError(owner + " does not have a member " + name) - } + throw new FatalError(owner + " does not have a member " + name) } } + } def getMemberIfDefined(owner: Symbol, name: Name): Symbol = owner.info.nonPrivateMember(name) diff --git a/src/compiler/scala/reflect/internal/SymbolCreations.scala b/src/compiler/scala/reflect/internal/SymbolCreations.scala index a1163b0f57..ac82ffe62a 100644 --- a/src/compiler/scala/reflect/internal/SymbolCreations.scala +++ b/src/compiler/scala/reflect/internal/SymbolCreations.scala @@ -11,7 +11,6 @@ import scala.collection.mutable.ListBuffer import util.Statistics._ import Flags._ import api.Modifier -import scala.tools.util.StringOps.{ ojoin } trait SymbolCreations { self: SymbolTable => diff --git a/src/compiler/scala/reflect/internal/SymbolFlags.scala b/src/compiler/scala/reflect/internal/SymbolFlags.scala index febcec8c7c..7741d700b9 100644 --- a/src/compiler/scala/reflect/internal/SymbolFlags.scala +++ b/src/compiler/scala/reflect/internal/SymbolFlags.scala @@ -11,7 +11,6 @@ import scala.collection.mutable.ListBuffer import util.Statistics._ import Flags._ import api.Modifier -import scala.tools.util.StringOps.{ ojoin } trait SymbolFlags { self: SymbolTable => diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index c9947c3c09..6eaae7f1ee 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -707,7 +707,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => || isAnonOrRefinementClass // has uninteresting or prefix || nme.isReplWrapperName(name) // has ugly $iw. prefix (doesn't call isInterpreterWrapper due to nesting) ) - def isFBounded = info.baseTypeSeq exists (_ contains this) + def isFBounded = info match { + case TypeBounds(_, _) => info.baseTypeSeq exists (_ contains this) + case _ => false + } /** Is symbol a monomorphic type? * assumption: if a type starts out as monomorphic, it will not acquire @@ -1205,8 +1208,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Set new info valid from start of this phase. */ def updateInfo(info: Type): Symbol = { - assert(phaseId(infos.validFrom) <= phase.id) - if (phaseId(infos.validFrom) == phase.id) infos = infos.prev + val pid = phaseId(infos.validFrom) + assert(pid <= phase.id, (pid, phase.id)) + if (pid == phase.id) infos = infos.prev infos = TypeHistory(currentPeriod, info, infos) _validTo = if (info.isComplete) currentPeriod else NoPeriod this diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index afb1d8061e..fc57a130d1 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -2082,7 +2082,7 @@ trait Types extends api.Types { self: SymbolTable => // TODO: is there another way a typeref's symbol can refer to a symbol defined in its pre? case _ => sym } - + override def kind = "AliasTypeRef" } trait AbstractTypeRef extends NonClassTypeRef { @@ -2135,6 +2135,7 @@ trait Types extends api.Types { self: SymbolTable => override def bounds = thisInfo.bounds // def transformInfo(tp: Type): Type = appliedType(tp.asSeenFrom(pre, sym.owner), typeArgsOrDummies) override protected[Types] def baseTypeSeqImpl: BaseTypeSeq = transform(bounds.hi).baseTypeSeq prepend this + override def kind = "AbstractTypeRef" } /** A class for named types of the form @@ -2579,7 +2580,7 @@ trait Types extends api.Types { self: SymbolTable => !(qset contains sym) && !isQuantified(pre) case _ => false - } + } } override def safeToString: String = { diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index 92a0efff1e..ce6a7ed6af 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -5,7 +5,7 @@ package scala.tools.nsc -import util.{ FreshNameCreator, Position, NoPosition, SourceFile, NoSourceFile } +import util.{ FreshNameCreator, Position, NoPosition, BatchSourceFile, SourceFile, NoSourceFile } import scala.collection.mutable import scala.collection.mutable.{ LinkedHashSet, ListBuffer } diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 403b5717b0..9169f80e1c 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -950,6 +950,11 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S reporter.warning(NoPosition, "there were %d %s warnings; re-run with %s for details".format(warnings.size, what, option.name)) } + def newUnitParser(code: String) = new syntaxAnalyzer.UnitParser(newCompilationUnit(code)) + def newUnitScanner(code: String) = new syntaxAnalyzer.UnitScanner(newCompilationUnit(code)) + def newCompilationUnit(code: String) = new CompilationUnit(newSourceFile(code)) + def newSourceFile(code: String) = new BatchSourceFile("", code) + /** A Run is a single execution of the compiler on a sets of units */ class Run { @@ -1275,7 +1280,7 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S // nothing to compile, but we should still report use of deprecated options if (sources.isEmpty) { - checkDeprecatedSettings(new CompilationUnit(new BatchSourceFile("", ""))) + checkDeprecatedSettings(newCompilationUnit("")) reportCompileErrors() return } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index eb4deeeee2..bca1cc4596 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -317,7 +317,7 @@ self => * by compilationUnit(). */ def scriptBody(): Tree = { - val stmts = templateStatSeq(false)._2 + val stmts = templateStats() accept(EOF) def mainModuleName = newTermName(settings.script.value) @@ -2869,6 +2869,13 @@ self => stats.toList } + /** Informal - for the repl and other direct parser accessors. + */ + def templateStats(): List[Tree] = templateStatSeq(false)._2 match { + case Nil => List(EmptyTree) + case stats => stats + } + /** {{{ * TemplateStatSeq ::= [id [`:' Type] `=>'] TemplateStat {semi TemplateStat} * TemplateStat ::= Import diff --git a/src/compiler/scala/tools/nsc/interpreter/CodeHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/CodeHandlers.scala index 42a47896a2..453b106808 100644 --- a/src/compiler/scala/tools/nsc/interpreter/CodeHandlers.scala +++ b/src/compiler/scala/tools/nsc/interpreter/CodeHandlers.scala @@ -17,9 +17,7 @@ import scala.util.control.ControlThrowable trait CodeHandlers[T] { self => - // Expressions are composed of operators and operands. - def expr(code: String): T - +/* // A declaration introduces names and assigns them types. // It can form part of a class definition (§5.1) or of a refinement in a compound type (§3.2.7). // (Ed: aka abstract members.) @@ -34,6 +32,10 @@ trait CodeHandlers[T] { // ‘val’ PatDef | ‘var’ VarDef | ‘def’ FunDef | ‘type’ {nl} TypeDef | // [‘case’] ‘class’ ClassDef | [‘case’] ‘object’ ObjectDef | ‘trait’ TraitDef def defn(code: String): T +*/ + + // Expressions are composed of operators and operands. + def expr(code: String): T // An import clause has the form import p.I where p is a stable identifier (§3.1) and I is an import expression. def impt(code: String): T @@ -52,9 +54,9 @@ trait CodeHandlers[T] { case _: NoSuccess => Nil } + // def decl(code: String) = try Some(self.decl(code)) catch handler + // def defn(code: String) = try Some(self.defn(code)) catch handler def expr(code: String) = try Some(self.expr(code)) catch handler - def decl(code: String) = try Some(self.decl(code)) catch handler - def defn(code: String) = try Some(self.defn(code)) catch handler def impt(code: String) = try Some(self.impt(code)) catch handler def stmt(code: String) = try Some(self.stmt(code)) catch handler def stmts(code: String) = try (self.stmts(code) map (x => Some(x))) catch handlerSeq diff --git a/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala b/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala index a2ce8439de..0cd918b6a5 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala @@ -22,8 +22,7 @@ trait ExprTyper { object codeParser extends { val global: repl.global.type = repl.global } with CodeHandlers[Tree] { def applyRule[T](code: String, rule: UnitParser => T): T = { reporter.reset() - val unit = new CompilationUnit(new BatchSourceFile("", code)) - val scanner = new UnitParser(unit) + val scanner = newUnitParser(code) val result = rule(scanner) if (!reporter.hasErrors) @@ -33,23 +32,17 @@ trait ExprTyper { } def tokens(code: String) = { reporter.reset() - val unit = new CompilationUnit(new BatchSourceFile("", code)) - val in = new UnitScanner(unit) + val in = newUnitScanner(code) in.init() - new Tokenizer(in) tokenIterator } - def decl(code: String) = CodeHandlers.fail("todo") - def defn(code: String) = CodeHandlers.fail("todo") + def defns(code: String) = stmts(code) collect { case x: DefTree => x } def expr(code: String) = applyRule(code, _.expr()) def impt(code: String) = applyRule(code, _.importExpr()) def impts(code: String) = applyRule(code, _.importClause()) - def stmts(code: String) = applyRule(code, _.templateStatSeq(false)._2) - def stmt(code: String) = stmts(code) match { - case List(t) => t - case xs => CodeHandlers.fail("Not a single statement: " + xs.mkString(", ")) - } + def stmts(code: String) = applyRule(code, _.templateStats()) + def stmt(code: String) = stmts(code).last // guaranteed nonempty } /** Parse a line into a sequence of trees. Returns None if the input is incomplete. */ @@ -62,77 +55,69 @@ trait ExprTyper { else Some(trees) } } - def tokens(line: String) = beQuietDuring(codeParser.tokens(line)) + // def parsesAsExpr(line: String) = { + // import codeParser._ + // (opt expr line).isDefined + // } - // TODO: integrate these into a CodeHandler[Type]. + def symbolOfLine(code: String): Symbol = { + def asExpr(): Symbol = { + val name = freshInternalVarName() + // Typing it with a lazy val would give us the right type, but runs + // into compiler bugs with things like existentials, so we compile it + // behind a def and strip the NullaryMethodType which wraps the expr. + val line = "def " + name + " = {\n" + code + "\n}" + + interpretSynthetic(line) match { + case IR.Success => + val sym0 = symbolOfTerm(name) + // drop NullaryMethodType + val sym = sym0.cloneSymbol setInfo afterTyper(sym0.info.finalResultType) + if (sym.info.typeSymbol eq UnitClass) NoSymbol + else sym + case _ => NoSymbol + } + } + def asDefn(): Symbol = { + val old = repl.definedSymbolList.toSet + + interpretSynthetic(code) match { + case IR.Success => + repl.definedSymbolList filterNot old match { + case Nil => NoSymbol + case sym :: Nil => sym + case syms => NoSymbol.newOverloaded(NoPrefix, syms) + } + case _ => NoSymbol + } + } + beQuietDuring(asExpr()) orElse beQuietDuring(asDefn()) + } - // XXX literals. - // 1) Identifiers defined in the repl. - // 2) A path loadable via getModule. - // 3) Try interpreting it as an expression. private var typeOfExpressionDepth = 0 def typeOfExpression(expr: String, silent: Boolean = true): Type = { - repltrace("typeOfExpression(" + expr + ")") if (typeOfExpressionDepth > 2) { repldbg("Terminating typeOfExpression recursion for expression: " + expr) return NoType } - - def asQualifiedImport: Type = { - val name = expr.takeWhile(_ != '.') - typeOfExpression(importedTermNamed(name).fullName + expr.drop(name.length), true) - } - def asModule: Type = getModuleIfDefined(expr).tpe - def asExpr: Type = { - val lhs = freshInternalVarName() - val line = "lazy val " + lhs + " =\n" + expr - - interpret(line, true) match { - case IR.Success => typeOfExpression(lhs, true) - case _ => NoType - } - } - - def evaluate(): Type = { - typeOfExpressionDepth += 1 - try typeOfTerm(expr) orElse asModule orElse asExpr orElse asQualifiedImport - finally typeOfExpressionDepth -= 1 - } - + typeOfExpressionDepth += 1 // Don't presently have a good way to suppress undesirable success output // while letting errors through, so it is first trying it silently: if there // is an error, and errors are desired, then it re-evaluates non-silently // to induce the error message. - beSilentDuring(evaluate()) orElse beSilentDuring(typeOfDeclaration(expr)) orElse { - if (!silent) - evaluate() - - NoType + try beSilentDuring(symbolOfLine(expr).tpe) match { + case NoType if !silent => symbolOfLine(expr).tpe // generate error + case tpe => tpe } + finally typeOfExpressionDepth -= 1 } - // Since people will be giving us ":t def foo = 5" even though that is not an - // expression, we have a means of typing declarations too. - private def typeOfDeclaration(code: String): Type = { - repltrace("typeOfDeclaration(" + code + ")") - val obname = freshInternalVarName() - interpret("object " + obname + " {\n" + code + "\n}\n", true) match { - case IR.Success => - val sym = symbolOfTerm(obname) - if (sym == NoSymbol) NoType else { - // TODO: bitmap$n is not marked synthetic. - val decls = sym.tpe.decls.toList filterNot (x => x.isConstructor || x.isPrivate || (x.name.toString contains "$")) - repltrace("decls: " + decls) - if (decls.isEmpty) NoType - else cleanMemberDecl(sym, decls.last.name) - } - case _ => - NoType - } - } + def tokens(line: String) = beQuietDuring(codeParser.tokens(line)) + + // In the todo column + // // def compileAndTypeExpr(expr: String): Option[Typer] = { // class TyperRun extends Run { // override def stopPhase(name: String) = name == "superaccessors" // } - // } } diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index bf386d8a12..9279d37464 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -49,12 +49,60 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) var settings: Settings = _ var intp: IMain = _ - override def echoCommandMessage(msg: String): Unit = - intp.reporter.printMessage(msg) + /** Having inherited the difficult "var-ness" of the repl instance, + * I'm trying to work around it by moving operations into a class from + * which it will appear a stable prefix. + */ + private def onIntp[T](f: IMain => T): T = f(intp) + + class IMainOps[T <: IMain](val intp: T) { + import intp._ + import global._ + + def printAfterTyper(msg: => String) = + intp.reporter printUntruncatedMessage afterTyper(msg) + + /** Strip NullaryMethodType artifacts. */ + private def replInfo(sym: Symbol) = { + sym.info match { + case NullaryMethodType(restpe) if sym.isAccessor => restpe + case info => info + } + } + def echoTypeStructure(sym: Symbol) = + printAfterTyper("" + deconstruct.show(replInfo(sym))) + + def echoTypeSignature(sym: Symbol, verbose: Boolean) = { + if (verbose) ILoop.this.echo("// Type signature") + printAfterTyper("" + replInfo(sym)) + + if (verbose) { + ILoop.this.echo("\n// Internal Type structure") + echoTypeStructure(sym) + } + } + } + implicit def stabilizeIMain(intp: IMain) = new IMainOps[intp.type](intp) + + /** TODO - + * -n normalize + * -l label with case class parameter names + * -c complete - leave nothing out + */ + private def typeCommandInternal(expr: String, verbose: Boolean): Result = { + onIntp { intp => + val sym = intp.symbolOfLine(expr) + if (sym.exists) intp.echoTypeSignature(sym, verbose) + else "" + } + } + + override def echoCommandMessage(msg: String) { + intp.reporter printUntruncatedMessage msg + } def isAsync = !settings.Yreplsync.value lazy val power = new Power(intp, new StdReplVals(this)) - lazy val NoType = intp.global.NoType // TODO // object opt extends AestheticSettings @@ -249,7 +297,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) // nullary("reset", "reset the interpreter, forgetting session values but retaining session types", replay), shCommand, nullary("silent", "disable/enable automatic printing of results", verbosity), - cmd("type", "", "display the type of an expression without evaluating it", typeCommand), + cmd("type", "[-v] ", "display the type of an expression without evaluating it", typeCommand), nullary("warnings", "show the suppressed warnings from the most recent line which had any", warningsCommand) ) @@ -322,10 +370,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) } } - private def implicitsCommand(line: String): Result = { - val intp = ILoop.this.intp + private def implicitsCommand(line: String): Result = onIntp { intp => import intp._ - import global.{ Symbol, afterTyper } + import global._ def p(x: Any) = intp.reporter.printMessage("" + x) @@ -436,14 +483,14 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) private lazy val javap = substituteAndLog[Javap]("javap", NoJavap)(newJavap()) // Still todo: modules. - private def typeCommand(line: String): Result = { - if (line.trim == "") ":type " - else { - val tp = intp.typeOfExpression(line, false) - if (tp == NoType) "" // the error message was already printed - else intp.global.afterTyper(tp.toString) + private def typeCommand(line0: String): Result = { + line0.trim match { + case "" => ":type [-v] " + case s if s startsWith "-v " => typeCommandInternal(s stripPrefix "-v " trim, true) + case s => typeCommandInternal(s, false) } } + private def warningsCommand(): Result = { intp.lastWarnings foreach { case (pos, msg) => intp.reporter.warning(pos, msg) } } @@ -471,33 +518,34 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) } private def wrapCommand(line: String): Result = { def failMsg = "Argument to :wrap must be the name of a method with signature [T](=> T): T" - val intp = ILoop.this.intp - val g: intp.global.type = intp.global - import g._ - - words(line) match { - case Nil => - intp.executionWrapper match { - case "" => "No execution wrapper is set." - case s => "Current execution wrapper: " + s - } - case "clear" :: Nil => - intp.executionWrapper match { - case "" => "No execution wrapper is set." - case s => intp.clearExecutionWrapper() ; "Cleared execution wrapper." - } - case wrapper :: Nil => - intp.typeOfExpression(wrapper) match { - case PolyType(List(targ), MethodType(List(arg), restpe)) => - intp setExecutionWrapper intp.pathToTerm(wrapper) - "Set wrapper to '" + wrapper + "'" - case tp => - failMsg + ( - if (tp == g.NoType) "\nFound: " - else "\nFound: " - ) - } - case _ => failMsg + onIntp { intp => + import intp._ + import global._ + + words(line) match { + case Nil => + intp.executionWrapper match { + case "" => "No execution wrapper is set." + case s => "Current execution wrapper: " + s + } + case "clear" :: Nil => + intp.executionWrapper match { + case "" => "No execution wrapper is set." + case s => intp.clearExecutionWrapper() ; "Cleared execution wrapper." + } + case wrapper :: Nil => + intp.typeOfExpression(wrapper) match { + case PolyType(List(targ), MethodType(List(arg), restpe)) => + intp setExecutionWrapper intp.pathToTerm(wrapper) + "Set wrapper to '" + wrapper + "'" + case tp => + failMsg + ( + if (tp == NoType) "\nFound: " + else "\nFound: " + ) + } + case _ => failMsg + } } } @@ -798,6 +846,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) }) } + def runCompletion = + try in.completion execute code map (intp bindSyntheticValue _) + catch { case ex: Exception => None } + /** Here we place ourselves between the user and the interpreter and examine * the input they are ostensibly submitting. We intervene in several cases: * @@ -815,30 +867,28 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) else if (Completion.looksLikeInvocation(code) && intp.mostRecentVar != "") { interpretStartingWith(intp.mostRecentVar + code) } - else { - def runCompletion = - try in.completion execute code map (intp bindValue _) - catch { case ex: Exception => None } - - /** Due to my accidentally letting file completion execution sneak ahead - * of actual parsing this now operates in such a way that the scala - * interpretation always wins. However to avoid losing useful file - * completion I let it fail and then check the others. So if you - * type /tmp it will echo a failure and then give you a Directory object. - * It's not pretty: maybe I'll implement the silence bits I need to avoid - * echoing the failure. - */ - if (intp isParseable code) { - val (code, result) = reallyInterpret - if (power != null && code == IR.Error) - runCompletion - - result - } - else runCompletion match { - case Some(_) => None // completion hit: avoid the latent error - case _ => reallyInterpret._2 // trigger the latent error - } + else if (code.trim startsWith "//") { + // line comment, do nothing + None + } + /** Due to my accidentally letting file completion execution sneak ahead + * of actual parsing this now operates in such a way that the scala + * interpretation always wins. However to avoid losing useful file + * completion I let it fail and then check the others. So if you + * type /tmp it will echo a failure and then give you a Directory object. + * It's not pretty: maybe I'll implement the silence bits I need to avoid + * echoing the failure. + */ + else if (intp isParseable code) { + val (code, result) = reallyInterpret + if (power != null && code == IR.Error) + runCompletion + + result + } + else runCompletion match { + case Some(_) => None // completion hit: avoid the latent error + case _ => reallyInterpret._2 // trigger the latent error } } diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 43e01bebfd..13124e6afc 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 typechecker.Analyzer import language.implicitConversions /** directory to save .class files to */ @@ -140,7 +141,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends lazy val formatting: Formatting = new Formatting { val prompt = Properties.shellPromptString } - lazy val reporter: ConsoleReporter = new ReplReporter(this) + lazy val reporter: ReplReporter = new ReplReporter(this) import formatting._ import reporter.{ printMessage, withoutTruncating } @@ -156,6 +157,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends } catch AbstractOrMissingHandler() } + private def tquoted(s: String) = "\"\"\"" + s + "\"\"\"" + // argument is a thunk to execute after init is done def initialize(postInitSignal: => Unit) { synchronized { @@ -226,6 +229,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends } import naming._ + object deconstruct extends { + val global: imain.global.type = imain.global + } with StructuredTypeStrings + // object dossiers extends { // val intp: imain.type = imain // } with Dossiers { } @@ -275,11 +282,10 @@ 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: NscReporter) = { + protected def newCompiler(settings: Settings, reporter: NscReporter): ReplGlobal = { settings.outputDirs setSingleOutput virtualDirectory settings.exposeEmptyPackage.value = true - - Global(settings, reporter) + new Global(settings, reporter) with ReplGlobal } /** Parent classloader. Overridable. */ @@ -521,7 +527,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends trees.last match { case _:Assign => // we don't want to include assignments case _:TermTree | _:Ident | _:Select => // ... but do want other unnamed terms. - val varName = if (synthetic) freshInternalVarName() else ("" + freshUserTermName()) + val varName = if (synthetic) freshInternalVarName() else freshUserVarName() val rewrittenLine = ( // In theory this would come out the same without the 1-specific test, but // it's a cushion against any more sneaky parse-tree position vs. code mismatches: @@ -587,6 +593,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends * e.g. that there were no parse errors. */ def interpret(line: String): IR.Result = interpret(line, false) + def interpretSynthetic(line: String): IR.Result = interpret(line, true) def interpret(line: String, synthetic: Boolean): IR.Result = { def loadAndRunReq(req: Request) = { val (result, succeeded) = req.loadAndRun @@ -679,7 +686,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def quietBind(p: NamedParam): IR.Result = beQuietDuring(bind(p)) def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value) def bind[T: Manifest](name: String, value: T): IR.Result = bind((name, value)) - def bindValue(x: Any): IR.Result = bindValue("" + freshUserTermName(), x) + def bindSyntheticValue(x: Any): IR.Result = bindValue(freshInternalVarName(), x) + def bindValue(x: Any): IR.Result = bindValue(freshUserVarName(), x) def bindValue(name: String, x: Any): IR.Result = bind(name, TypeStrings.fromValue(x), x) /** Reset this interpreter, forgetting all user-specified requests. */ @@ -852,6 +860,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** handlers for each tree in this request */ val handlers: List[MemberHandler] = trees map (memberHandlers chooseHandler _) + def defHandlers = handlers collect { case x: MemberDefHandler => x } /** all (public) names defined by these statements */ val definedNames = handlers flatMap (_.definedNames) @@ -863,6 +872,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def termNames = handlers flatMap (_.definesTerm) def typeNames = handlers flatMap (_.definesType) def definedOrImported = handlers flatMap (_.definedOrImported) + def definedSymbolList = defHandlers flatMap (_.definedSymbols) + + def definedTypeSymbol(name: String) = definedSymbols(newTypeName(name)) + def definedTermSymbol(name: String) = definedSymbols(newTermName(name)) /** Code to import bound names from previous lines - accessPath is code to * append to objectName to access anything bound by request. @@ -915,8 +928,6 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends val generate = (m: MemberHandler) => m extraCodeToEvaluate Request.this } - def tquoted(s: String) = "\"\"\"" + s + "\"\"\"" - private object ResultObjectSourceCode extends CodeAssembler[MemberHandler] { /** We only want to generate this code when the result * is a value which can be referred to as-is. @@ -970,6 +981,16 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends typeOf typesOfDefinedTerms + // Assign symbols to the original trees + // TODO - just use the new trees. + defHandlers foreach { dh => + val name = dh.member.name + definedSymbols get name foreach { sym => + dh.member setSymbol sym + repldbg("Set symbol of " + name + " to " + sym.defString) + } + } + // compile the result-extraction object beQuietDuring { savingSettings(_.nowarn.value = true) { @@ -991,17 +1012,17 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends } /** Types of variables defined by this request. */ - lazy val compilerTypeOf = typeMap[Type](x => x) + lazy val compilerTypeOf = typeMap[Type](x => x) withDefaultValue NoType /** String representations of same. */ lazy val typeOf = typeMap[String](tp => afterTyper(tp.toString)) // lazy val definedTypes: Map[Name, Type] = { // typeNames map (x => x -> afterTyper(resultSymbol.info.nonPrivateDecl(x).tpe)) toMap // } - lazy val definedSymbols: Map[Name, Symbol] = ( + lazy val definedSymbols = ( termNames.map(x => x -> applyToResultMember(x, x => x)) ++ - typeNames.map(x => x -> compilerTypeOf.get(x).map(_.typeSymbol).getOrElse(NoSymbol)) - ).toMap + typeNames.map(x => x -> compilerTypeOf(x).typeSymbol) + ).toMap[Name, Symbol] withDefaultValue NoSymbol lazy val typesOfDefinedTerms: Map[Name, Type] = termNames map (x => x -> applyToResultMember(x, _.tpe)) toMap @@ -1075,18 +1096,21 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends } def valueOfTerm(id: String): Option[AnyRef] = - requestForIdent(id) flatMap (_.getEval) + requestForName(newTermName(id)) flatMap (_.getEval) def classOfTerm(id: String): Option[JClass] = valueOfTerm(id) map (_.getClass) def typeOfTerm(id: String): Type = newTermName(id) match { case nme.ROOTPKG => definitions.RootClass.tpe - case name => requestForName(name) flatMap (_.compilerTypeOf get name) getOrElse NoType + case name => requestForName(name).fold(NoType: Type)(_ compilerTypeOf name) } + def symbolOfType(id: String): Symbol = + requestForName(newTypeName(id)).fold(NoSymbol: Symbol)(_ definedTypeSymbol id) + def symbolOfTerm(id: String): Symbol = - requestForIdent(id) flatMap (_.definedSymbols get newTermName(id)) getOrElse NoSymbol + requestForIdent(newTermName(id)).fold(NoSymbol: Symbol)(_ definedTermSymbol id) def runtimeClassAndTypeOfTerm(id: String): Option[(JClass, Type)] = { classOfTerm(id) flatMap { clazz => @@ -1120,11 +1144,15 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends val global: imain.global.type = imain.global } with ReplTokens { } - private object exprTyper extends { + object exprTyper extends { val repl: IMain.this.type = imain } with ExprTyper { } def parse(line: String): Option[List[Tree]] = exprTyper.parse(line) + + def symbolOfLine(code: String): Symbol = + exprTyper.symbolOfLine(code) + def typeOfExpression(expr: String, silent: Boolean = true): Type = exprTyper.typeOfExpression(expr, silent) @@ -1134,14 +1162,15 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends protected def onlyTerms(xs: List[Name]) = xs collect { case x: TermName => x } protected def onlyTypes(xs: List[Name]) = xs collect { case x: TypeName => x } - def definedTerms = onlyTerms(allDefinedNames) filterNot isInternalTermName - def definedTypes = onlyTypes(allDefinedNames) - def definedSymbols = prevRequests.toSet flatMap ((x: Request) => x.definedSymbols.values) + def definedTerms = onlyTerms(allDefinedNames) filterNot isInternalTermName + def definedTypes = onlyTypes(allDefinedNames) + def definedSymbols = prevRequestList.flatMap(_.definedSymbols.values).toSet[Symbol] + def definedSymbolList = prevRequestList flatMap (_.definedSymbolList) filterNot (s => isInternalTermName(s.name)) // Terms with user-given names (i.e. not res0 and not synthetic) def namedDefinedTerms = definedTerms filterNot (x => isUserVarName("" + x) || directlyBoundNames(x)) - private def findName(name: Name) = definedSymbols find (_.name == name) + private def findName(name: Name) = definedSymbols find (_.name == name) getOrElse NoSymbol /** Translate a repl-defined identifier into a Symbol. */ @@ -1150,16 +1179,19 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def types(name: String): Symbol = { val tpname = newTypeName(name) - findName(tpname) getOrElse getClassIfDefined(tpname) + findName(tpname) orElse getClassIfDefined(tpname) } def terms(name: String): Symbol = { val termname = newTypeName(name) - findName(termname) getOrElse getModuleIfDefined(termname) + findName(termname) orElse getModuleIfDefined(termname) } def types[T: ClassManifest] : Symbol = types(classManifest[T].erasure.getName) def terms[T: ClassManifest] : Symbol = terms(classManifest[T].erasure.getName) def apply[T: ClassManifest] : Symbol = apply(classManifest[T].erasure.getName) + def classSymbols = allDefSymbols collect { case x: ClassSymbol => x } + def methodSymbols = allDefSymbols collect { case x: MethodSymbol => x } + /** the previous requests this interpreter has processed */ private var executingRequest: Request = _ private val prevRequests = mutable.ListBuffer[Request]() @@ -1167,7 +1199,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends private val definedNameMap = mutable.Map[Name, Request]() private val directlyBoundNames = mutable.Set[Name]() - private def allHandlers = prevRequestList flatMap (_.handlers) + def allHandlers = prevRequestList flatMap (_.handlers) + def allDefHandlers = allHandlers collect { case x: MemberDefHandler => x } + def allDefSymbols = allDefHandlers map (_.symbol) filter (_ ne NoSymbol) + def lastRequest = if (prevRequests.isEmpty) null else prevRequests.last def prevRequestList = prevRequests.toList def allSeenTypes = prevRequestList flatMap (_.typeOf.values.toList) distinct diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala index a86462ad5f..795b2e3678 100644 --- a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala +++ b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala @@ -194,14 +194,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput // literal Ints, Strings, etc. object literals extends CompletionAware { - def simpleParse(code: String): Tree = { - val unit = new CompilationUnit(new util.BatchSourceFile("", code)) - val scanner = new syntaxAnalyzer.UnitParser(unit) - val tss = scanner.templateStatSeq(false)._2 - - if (tss.size == 1) tss.head else EmptyTree - } - + def simpleParse(code: String): Tree = newUnitParser(code).templateStats().last def completions(verbosity: Int) = Nil override def follow(id: String) = simpleParse(id) match { diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala index 40993eb916..fcede04aaf 100644 --- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala +++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala @@ -64,6 +64,7 @@ trait MemberHandlers { } sealed abstract class MemberDefHandler(override val member: MemberDef) extends MemberHandler(member) { + def symbol = if (member.symbol eq null) NoSymbol else member.symbol def name: Name = member.name def mods: Modifiers = member.mods def keyword = member.keyword @@ -72,6 +73,7 @@ trait MemberHandlers { override def definesImplicit = member.mods.isImplicit override def definesTerm: Option[TermName] = Some(name.toTermName) filter (_ => name.isTermName) override def definesType: Option[TypeName] = Some(name.toTypeName) filter (_ => name.isTypeName) + override def definedSymbols = if (symbol eq NoSymbol) Nil else List(symbol) } /** Class to handle one member among all the members included @@ -89,6 +91,7 @@ trait MemberHandlers { def importedNames = List[Name]() def definedNames = definesTerm.toList ++ definesType.toList def definedOrImported = definedNames ++ importedNames + def definedSymbols = List[Symbol]() def extraCodeToEvaluate(req: Request): String = "" def resultExtractionCode(req: Request): String = "" diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index ecf9dd219b..2cb034f7ab 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Power.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala @@ -410,8 +410,8 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl lazy val phased: Phased = new { val global: intp.global.type = intp.global } with Phased { } def context(code: String) = analyzer.rootContext(unit(code)) - def source(code: String) = new BatchSourceFile("", code) - def unit(code: String) = new CompilationUnit(source(code)) + def source(code: String) = newSourceFile(code) + def unit(code: String) = newCompilationUnit(code) def trees(code: String) = parse(code) getOrElse Nil def typeOf(id: String) = intp.typeOfExpression(id) diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala b/src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala new file mode 100644 index 0000000000..05321dd7e6 --- /dev/null +++ b/src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala @@ -0,0 +1,57 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package interpreter + +import reporters._ +import typechecker.Analyzer + +/** A layer on top of Global so I can guarantee some extra + * functionality for the repl. It doesn't do much yet. + */ +trait ReplGlobal extends Global { + // This exists mostly because using the reporter too early leads to deadlock. + private def echo(msg: String) { Console println msg } + + override def abort(msg: String): Nothing = { + echo("ReplGlobal.abort: " + msg) + super.abort(msg) + } + + override lazy val analyzer = new { + val global: ReplGlobal.this.type = ReplGlobal.this + } with Analyzer { + override def newTyper(context: Context): Typer = new Typer(context) { + override def typed(tree: Tree, mode: Int, pt: Type): Tree = { + val res = super.typed(tree, mode, pt) + tree match { + case Ident(name) if !tree.symbol.hasPackageFlag && !name.toString.startsWith("$") => + repldbg("typed %s: %s".format(name, res.tpe)) + case _ => + } + res + } + } + } + + object replPhase extends SubComponent { + val global: ReplGlobal.this.type = ReplGlobal.this + val phaseName = "repl" + val runsAfter = List[String]("typer") + val runsRightAfter = None + def newPhase(_prev: Phase): StdPhase = new StdPhase(_prev) { + def apply(unit: CompilationUnit) { + repldbg("Running replPhase on " + unit.body) + // newNamer(rootContext(unit)).enterSym(unit.body) + } + } + } + + override protected def computePhaseDescriptors: List[SubComponent] = { + addToPhasesSet(replPhase, "repl") + super.computePhaseDescriptors + } +} diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplReporter.scala b/src/compiler/scala/tools/nsc/interpreter/ReplReporter.scala index 130af990ad..fb61dfb672 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplReporter.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplReporter.scala @@ -9,7 +9,11 @@ package interpreter import reporters._ import IMain._ +/** Like ReplGlobal, a layer for ensuring extra functionality. + */ class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.in, new ReplStrippingWriter(intp)) { + def printUntruncatedMessage(msg: String) = withoutTruncating(printMessage(msg)) + override def printMessage(msg: String) { // Avoiding deadlock if the compiler starts logging before // the lazy val is complete. diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala index 8b891e0010..4efab7e260 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala @@ -27,7 +27,8 @@ class StdReplVals(final val r: ILoop) extends ReplVals { final lazy val phased = power.phased final lazy val analyzer = global.analyzer - final lazy val treedsl = new { val global: intp.global.type = intp.global } with ast.TreeDSL { } + object treedsl extends { val global: intp.global.type = intp.global } with ast.TreeDSL { } + final lazy val typer = analyzer.newTyper( analyzer.rootContext( power.unit("").asInstanceOf[analyzer.global.CompilationUnit] @@ -35,13 +36,15 @@ class StdReplVals(final val r: ILoop) extends ReplVals { ) def lastRequest = intp.lastRequest - final lazy val replImplicits = new power.Implicits2 { + class ReplImplicits extends power.Implicits2 { import intp.global._ private val manifestFn = ReplVals.mkManifestToType[intp.global.type](global) implicit def mkManifestToType(sym: Symbol) = manifestFn(sym) } + final lazy val replImplicits = new ReplImplicits + def typed[T <: analyzer.global.Tree](tree: T): T = typer.typed(tree).asInstanceOf[T] } diff --git a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala index 59a7b9b5d2..b1bee6ce93 100644 --- a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala +++ b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala @@ -13,7 +13,10 @@ class RichClass[T](val clazz: Class[T]) { // Sadly isAnonymousClass does not return true for scala anonymous // classes because our naming scheme is not doing well against the // jvm's many assumptions. - def isScalaAnonymous = clazz.isAnonymousClass || (clazz.getName contains "$anon$") + def isScalaAnonymous = ( + try clazz.isAnonymousClass || (clazz.getName contains "$anon$") + catch { case _: java.lang.InternalError => false } // good ol' "Malformed class name" + ) /** It's not easy... to be... me... */ def supermans: List[Manifest[_]] = supers map (_.toManifest) diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala index 872ac00bfd..9ba75d9166 100644 --- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala +++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala @@ -11,6 +11,142 @@ import r.TypeVariable import scala.reflect.NameTransformer import NameTransformer._ import scala.reflect.{mirror => rm} +import typechecker.DestructureTypes +import scala.tools.util.StringOps.ojoin + +/** A more principled system for turning types into strings. + */ +trait StructuredTypeStrings extends DestructureTypes { + val global: Global + import global._ + import definitions._ + + case class LabelAndType(label: String, typeName: String) { } + object LabelAndType { + val empty = LabelAndType("", "") + } + case class Grouping(ldelim: String, mdelim: String, rdelim: String, labels: Boolean) { + def join(elems: String*): String = ( + if (elems.isEmpty) "" + else elems.mkString(ldelim, mdelim, rdelim) + ) + } + val NoGrouping = Grouping("", "", "", false) + val ListGrouping = Grouping("(", ", ", ")", false) + val ProductGrouping = Grouping("(", ", ", ")", true) + val ParamGrouping = Grouping("(", ", ", ")", true) + val BlockGrouping = Grouping(" { ", "; ", "}", false) + + private implicit def lowerName(n: Name): String = "" + n + private def str(level: Int)(body: => String): String = " " * level + body + private def block(level: Int, grouping: Grouping)(name: String, nodes: List[TypeNode]): String = { + val l1 = str(level)(name + grouping.ldelim) + val l2 = nodes.map(_ show level + 1) + val l3 = str(level)(grouping.rdelim) + + l1 +: l2 :+ l3 mkString "\n" + } + private def maybeBlock(level: Int, grouping: Grouping)(name: String, nodes: List[TypeNode]): String = { + import grouping._ + val threshold = 70 + + val try1 = str(level)(name + grouping.join(nodes map (_.show(0, grouping.labels)): _*)) + if (try1.length < threshold) try1 + else block(level, grouping)(name, nodes) + } + private def shortClass(x: Any) = { + if (opt.debug) { + val name = (x.getClass.getName split '.').last + val isAnon = name.reverse takeWhile (_ != '$') forall (_.isDigit) + val str = if (isAnon) name else (name split '$').last + + " // " + str + } + else "" + } + + sealed abstract class TypeNode { + def grouping: Grouping + def nodes: List[TypeNode] + + def show(indent: Int, showLabel: Boolean): String = maybeBlock(indent, grouping)(mkPrefix(showLabel), nodes) + def show(indent: Int): String = show(indent, true) + def show(): String = show(0) + + def withLabel(l: String): this.type = modifyNameInfo(_.copy(label = l)) + def withType(t: String): this.type = modifyNameInfo(_.copy(typeName = t)) + + def label = nameInfo.label + def typeName = nameInfo.typeName + + protected def mkPrefix(showLabel: Boolean) = { + val pre = if (showLabel && label != "") label + " = " else "" + pre + typeName + } + override def toString = show() // + "(toString)" + private var nameInfo: LabelAndType = LabelAndType.empty + private def modifyNameInfo(f: LabelAndType => LabelAndType): this.type = { + nameInfo = f(nameInfo) + this + } + } + case class TypeAtom[T](atom: T) extends TypeNode { + def grouping = NoGrouping + def nodes = Nil + override protected def mkPrefix(showLabel: Boolean) = + super.mkPrefix(showLabel) + atom + shortClass(atom) + } + case class TypeProduct(nodes: List[TypeNode]) extends TypeNode { + def grouping: Grouping = ProductGrouping + def emptyTypeName = "" + override def typeName = if (nodes.isEmpty) emptyTypeName else super.typeName + } + + /** For a NullaryMethod, in = TypeEmpty; for MethodType(Nil, _) in = TypeNil */ + class NullaryFunction(out: TypeNode) extends TypeProduct(List(out)) { + override def typeName = "NullaryMethodType" + } + class MonoFunction(in: TypeNode, out: TypeNode) extends TypeProduct(List(in, out)) { + override def typeName = "MethodType" + } + class PolyFunction(in: TypeNode, out: TypeNode) extends TypeProduct(List(in, out)) { + override def typeName = "PolyType" + } + + class TypeList(nodes: List[TypeNode]) extends TypeProduct(nodes) { + override def grouping = ListGrouping + override def emptyTypeName = "Nil" + override def typeName = "List" + } + class TypeScope(nodes: List[TypeNode]) extends TypeProduct(nodes) { + override def grouping = BlockGrouping + override def typeName = "Scope" + override def emptyTypeName = "EmptyScope" + } + + object TypeEmpty extends TypeNode { + override def grouping = NoGrouping + override def nodes = Nil + override def label = "" + override def typeName = "" + override def show(indent: Int, showLabel: Boolean) = "" + } + + object intoNodes extends DestructureType[TypeNode] { + def withLabel(node: TypeNode, label: String): TypeNode = node withLabel label + def withType(node: TypeNode, typeName: String): TypeNode = node withType typeName + + def wrapEmpty = TypeEmpty + def wrapSequence(nodes: List[TypeNode]) = new TypeList(nodes) + def wrapProduct(nodes: List[TypeNode]) = new TypeProduct(nodes) + def wrapPoly(in: TypeNode, out: TypeNode) = new PolyFunction(in, out) + def wrapMono(in: TypeNode, out: TypeNode) = if (in == wrapEmpty) new NullaryFunction(out) else new MonoFunction(in, out) + def wrapAtom[U](value: U) = new TypeAtom(value) + } + + def show(tp: Type): String = intoNodes(tp).show +} + /** 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 diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index e9c3bef737..8d26f66370 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -129,11 +129,11 @@ trait ContextErrors { val retyped = typed (tree.duplicate setType null) val foundDecls = retyped.tpe.decls filter (sym => !sym.isConstructor && !sym.isSynthetic) - if (foundDecls.isEmpty) found + if (foundDecls.isEmpty || (found.typeSymbol eq NoSymbol)) found else { // The members arrive marked private, presumably because there was no // expected type and so they're considered members of an anon class. - foundDecls foreach (_ resetFlag (PRIVATE | PROTECTED)) + foundDecls foreach (_.makePublic) // TODO: if any of the found parents match up with required parents after normalization, // print the error so that they match. The major beneficiary there would be // java.lang.Object vs. AnyRef. diff --git a/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala b/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala new file mode 100644 index 0000000000..0b414801d6 --- /dev/null +++ b/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala @@ -0,0 +1,206 @@ +/* NSC -- new Scala compiler +* Copyright 2005-2012 LAMP/EPFL +* @author Paul Phillips +*/ + +package scala.tools.nsc +package typechecker + +/** A generic means of breaking down types into their subcomponents. + * Types are decomposed top down, and recognizable substructure is + * dispatched via self-apparently named methods. Those methods can + * be overridden for custom behavior, but only the abstract methods + * require implementations, each of which must create some unknown + * "Node" type from its inputs. + * + * - wrapProduct create Node from a product of Nodes + * - wrapSequence create Node from a sequence of Nodes + * - wrapAtom create Node from an arbitrary value + * + * This is a work in progress. + */ +trait DestructureTypes { + val global: Global + import global._ + import definitions.{ NothingClass, AnyClass } + + trait DestructureType[Node] extends (Type => Node) { + def withLabel(node: Node, label: String): Node + def withType(node: Node, typeName: String): Node + + def wrapEmpty: Node + def wrapPoly(in: Node, out: Node): Node + def wrapMono(in: Node, out: Node): Node + def wrapProduct(nodes: List[Node]): Node + def wrapSequence(nodes: List[Node]): Node + def wrapAtom[U](value: U): Node + + private implicit def liftToTerm(name: String): TermName = newTermName(name) + + private val openSymbols = collection.mutable.Set[Symbol]() + + private def nodeList[T](elems: List[T], mkNode: T => Node): Node = + if (elems.isEmpty) wrapEmpty else list(elems map mkNode) + + private def scopeMemberList(elems: List[Symbol]): Node = nodeList(elems, wrapAtom) + private def typeList(elems: List[Type]): Node = nodeList(elems, this) + private def symbolList(elems: List[Symbol]): Node = nodeList(elems, wrapSymbolInfo) + private def treeList(elems: List[Tree]): Node = nodeList(elems, wrapTree) + private def annotationList(annots: List[AnnotationInfo]): Node = nodeList(annots, annotation) + + private def assocsNode(ann: AnnotationInfo): Node = { + val (names, args) = ann.assocs.toIndexedSeq.unzip + if (names.isEmpty) wrapEmpty + else node("assocs", nodeList(names.indices.toList, (i: Int) => atom(names(i).toString, args(i)))) + } + private def typeTypeName(tp: Type) = tp match { + case mt @ MethodType(_, _) if mt.isImplicit => "ImplicitMethodType" + case TypeRef(_, sym, _) => typeRefType(sym) + case _ => tp.kind + } + + def wrapTree(tree: Tree): Node = withType( + tree match { + case x: NameTree => atom(x.name.toString, x) + case _ => wrapAtom(tree) + }, + tree.printingPrefix + ) + def wrapSymbol(label: String, sym: Symbol): Node = { + if (sym eq NoSymbol) wrapEmpty + else atom(label, sym) + } + def wrapInfo(sym: Symbol) = sym.info match { + case TypeBounds(lo, hi) => typeBounds(lo, hi) + case PolyType(tparams, restpe) => polyFunction(tparams, restpe) + case _ => wrapEmpty + } + def wrapSymbolInfo(sym: Symbol): Node = { + if ((sym eq NoSymbol) || openSymbols(sym)) wrapEmpty + else { + openSymbols += sym + try product(symbolType(sym), wrapAtom(sym.defString)) + finally openSymbols -= sym + } + } + + def list(nodes: List[Node]): Node = wrapSequence(nodes) + def product(tp: Type, nodes: Node*): Node = product(typeTypeName(tp), nodes: _*) + def product(typeName: String, nodes: Node*): Node = ( + nodes.toList filterNot (_ == wrapEmpty) match { + case Nil => wrapEmpty + case xs => withType(wrapProduct(xs), typeName) + } + ) + + def atom[U](label: String, value: U): Node = node(label, wrapAtom(value)) + def constant(label: String, const: Constant): Node = atom(label, const) + + def scope(decls: Scope): Node = node("decls", scopeMemberList(decls.toList)) + def const[T](named: (String, T)): Node = constant(named._1, Constant(named._2)) + + def resultType(restpe: Type): Node = this("resultType", restpe) + def typeParams(tps: List[Symbol]): Node = node("typeParams", symbolList(tps)) + def valueParams(params: List[Symbol]): Node = node("params", symbolList(params)) + def typeArgs(tps: List[Type]): Node = node("args", typeList(tps)) + def parentList(tps: List[Type]): Node = node("parents", typeList(tps)) + + def polyFunction(tparams: List[Symbol], restpe: Type): Node = wrapPoly(typeParams(tparams), resultType(restpe)) + def monoFunction(params: List[Symbol], restpe: Type): Node = wrapMono(valueParams(params), resultType(restpe)) + def nullaryFunction(restpe: Type): Node = wrapMono(wrapEmpty, this(restpe)) + + def prefix(pre: Type): Node = pre match { + case NoPrefix => wrapEmpty + case _ => this("pre", pre) + } + def typeBounds(lo0: Type, hi0: Type): Node = { + val lo = if ((lo0 eq WildcardType) || (lo0.typeSymbol eq NothingClass)) wrapEmpty else this("lo", lo0) + val hi = if ((hi0 eq WildcardType) || (hi0.typeSymbol eq AnyClass)) wrapEmpty else this("hi", hi0) + + product("TypeBounds", lo, hi) + } + + def annotation(ann: AnnotationInfo): Node = product( + "AnnotationInfo", + this("atp", ann.atp), + node("args", treeList(ann.args)), + assocsNode(ann) + ) + def typeConstraint(constr: TypeConstraint): Node = product( + "TypeConstraint", + node("lo", typeList(constr.loBounds)), + node("hi", typeList(constr.hiBounds)), + this("inst", constr.inst) + ) + def annotatedType(annotations: List[AnnotationInfo], underlying: Type) = product( + "AnnotatedType", + node("annotations", annotationList(annotations)), + this("underlying", underlying) + ) + + /** This imposes additional structure beyond that which is visible in + * the case class hierarchy. In particular, (too) many different constructs + * are encoded in TypeRefs; here they are partitioned somewhat before + * being dispatched. + * + * For example, a typical type parameter is encoded as TypeRef(NoPrefix, sym, Nil) + * with its upper and lower bounds stored in the info of the symbol. Viewing the + * TypeRef naively we are treated to both too much information (useless prefix, usually + * empty args) and too little (bounds hidden behind indirection.) So drop the prefix + * and promote the bounds. + */ + def typeRef(tp: TypeRef) = { + val TypeRef(pre, sym, args) = tp + // Filtered down to elements with "interesting" content + product( + tp, + if (sym.isDefinedInPackage) wrapEmpty else prefix(pre), + wrapSymbolInfo(sym), + typeArgs(args), + if (tp ne tp.normalize) this("normalize", tp.normalize) else wrapEmpty + ) + } + + def symbolType(sym: Symbol) = ( + if (sym.isRefinementClass) "Refinement" + else if (sym.isAliasType) "Alias" + else if (sym.isTypeSkolem) "TypeSkolem" + else if (sym.isTypeParameter) "TypeParam" + else if (sym.isAbstractType) "AbstractType" + else if (sym.isType) "TypeSymbol" + else "TermSymbol" + ) + def typeRefType(sym: Symbol) = ( + if (sym.isRefinementClass) "RefinementTypeRef" + else if (sym.isAliasType) "AliasTypeRef" + else if (sym.isTypeSkolem) "SkolemTypeRef" + else if (sym.isTypeParameter) "TypeParamTypeRef" + else if (sym.isAbstractType) "AbstractTypeRef" + else "TypeRef" + ) + ( if (sym.isFBounded) "(F-Bounded)" else "" ) + + def node(label: String, node: Node): Node = withLabel(node, label) + def apply(label: String, tp: Type): Node = withLabel(this(tp), label) + + def apply(tp: Type): Node = tp match { + case AntiPolyType(pre, targs) => product(tp, prefix(pre), typeArgs(targs)) + case ClassInfoType(parents, decls, clazz) => product(tp, parentList(parents), scope(decls), wrapAtom(clazz)) + case ConstantType(const) => product(tp, constant("value", const)) + case DeBruijnIndex(level, index, args) => product(tp, const("level" -> level), const("index" -> index), typeArgs(args)) + case OverloadedType(pre, alts) => product(tp, prefix(pre), node("alts", typeList(alts map pre.memberType))) + case RefinedType(parents, decls) => product(tp, parentList(parents), scope(decls)) + case SingleType(pre, sym) => product(tp, prefix(pre), wrapAtom(sym)) + case SuperType(thistp, supertp) => product(tp, this("this", thistp), this("super", supertp)) + case ThisType(clazz) => product(tp, wrapAtom(clazz)) + case TypeVar(inst, constr) => product(tp, this("inst", inst), typeConstraint(constr)) + case AnnotatedType(annotations, underlying, _) => annotatedType(annotations, underlying) + case ExistentialType(tparams, underlying) => polyFunction(tparams, underlying) + case PolyType(tparams, restpe) => polyFunction(tparams, restpe) + case MethodType(params, restpe) => monoFunction(params, restpe) + case NullaryMethodType(restpe) => nullaryFunction(restpe) + case TypeBounds(lo, hi) => typeBounds(lo, hi) + case tr @ TypeRef(pre, sym, args) => typeRef(tr) + case _ => wrapAtom(tp) // XXX see what this is + } + } +} diff --git a/src/library/scala/collection/SeqExtractors.scala b/src/library/scala/collection/SeqExtractors.scala index cb3cb27f18..cbb09a0a90 100644 --- a/src/library/scala/collection/SeqExtractors.scala +++ b/src/library/scala/collection/SeqExtractors.scala @@ -19,3 +19,6 @@ object :+ { if(t.isEmpty) None else Some(t.init -> t.last) } + +// Dummy to fool ant +private abstract class SeqExtractors \ No newline at end of file diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index b9ff6afa2b..292d2fc4cb 100644 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -316,9 +316,8 @@ scala> /* */ */ -scala> -scala> +You typed two blank lines. Starting a new command. scala> // multi-line string @@ -326,7 +325,7 @@ scala> """ hello there """ -res9: String = +res12: String = " hello there diff --git a/test/files/run/repl-colon-type.check b/test/files/run/repl-colon-type.check index 66c2fcc77f..cb0b9a6c8b 100644 --- a/test/files/run/repl-colon-type.check +++ b/test/files/run/repl-colon-type.check @@ -7,6 +7,12 @@ scala> :type List[1, 2, 3] :2: error: identifier expected but integer literal found. List[1, 2, 3] ^ +:3: error: ']' expected but '}' found. + } + ^ +:1: error: identifier expected but integer literal found. + List[1, 2, 3] + ^ scala> :type List(1, 2, 3) @@ -25,7 +31,7 @@ scala> :type def f[T >: Null, U <: String](x: T, y: U) = Set(x, y) [T >: Null, U <: String](x: T, y: U)scala.collection.immutable.Set[Any] scala> :type def x = 1 ; def bar[T >: Null <: AnyRef](xyz: T) = 5 -[T >: Null <: AnyRef](xyz: T)Int +=> Int [T >: Null <: AnyRef](xyz: T)Int scala> @@ -39,10 +45,19 @@ scala> :type lazy val f = 5 Int scala> :type protected lazy val f = 5 -Int +:2: error: illegal start of statement (no modifiers allowed here) + protected lazy val f = 5 + ^ +:5: error: lazy value f cannot be accessed in object $iw + Access to protected value f not permitted because + enclosing object $eval in package $line19 is not a subclass of + object $iw where target is defined + lazy val $result = `f` + ^ + scala> :type def f = 5 -Int +=> Int scala> :type def f() = 5 ()Int @@ -54,4 +69,156 @@ scala> :type def g[T](xs: Set[_ <: T]) = Some(xs.head) scala> +scala> // verbose! + +scala> :type -v List(1,2,3) filter _ +// Type signature +(Int => Boolean) => List[Int] + +// Internal Type structure +TypeRef( + TypeSymbol(abstract trait Function1[-T1, +R] extends Object) + args = List( + TypeRef( + TypeSymbol(abstract trait Function1[-T1, +R] extends Object) + args = List( + TypeRef(TypeSymbol(final class Int extends AnyVal)) + TypeRef(TypeSymbol(final class Boolean extends AnyVal)) + ) + ) + TypeRef( + TypeSymbol( + sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] + + ) + args = List( + TypeRef(TypeSymbol(final class Int extends AnyVal)) + ) + ) + ) +) + +scala> :type -v def f[T >: Null, U <: String](x: T, y: U) = Set(x, y) +// Type signature +[T >: Null, U <: String](x: T, y: U)scala.collection.immutable.Set[Any] + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T >: Null), TypeParam(U <: String)) + resultType = MethodType( + params = List(TermSymbol(x: T), TermSymbol(y: U)) + resultType = TypeRef( + TypeSymbol( + abstract trait Set[A] extends Iterable[A] with Set[A] with GenericSetTemplate[A,scala.collection.immutable.Set] with SetLike[A,scala.collection.immutable.Set[A]] with Parallelizable[A,scala.collection.parallel.immutable.ParSet[A]] + + ) + args = List(TypeRef(TypeSymbol(abstract class Any extends ))) + ) + ) +) + +scala> :type -v def x = 1 ; def bar[T >: Null <: AnyRef](xyz: T) = 5 +// Type signature +=> Int [T >: Null <: AnyRef](xyz: T)Int + +// Internal Type structure +OverloadedType( + alts = List( + NullaryMethodType( + TypeRef(TypeSymbol(final class Int extends AnyVal)) + ) + PolyType( + typeParams = List(TypeParam(T >: Null <: AnyRef)) + resultType = MethodType( + params = List(TermSymbol(xyz: T)) + resultType = TypeRef( + TypeSymbol(final class Int extends AnyVal) + ) + ) + ) + ) +) + +scala> :type -v Nil.combinations _ +// Type signature +Int => Iterator[List[Nothing]] + +// Internal Type structure +TypeRef( + TypeSymbol(abstract trait Function1[-T1, +R] extends Object) + args = List( + TypeRef(TypeSymbol(final class Int extends AnyVal)) + TypeRef( + TypeSymbol( + abstract trait Iterator[+A] extends TraversableOnce[A] + ) + args = List( + TypeRef( + TypeSymbol( + sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] + + ) + args = List( + TypeRef( + TypeSymbol(final abstract class Nothing extends Any) + ) + ) + ) + ) + ) + ) +) + +scala> :type -v def f[T <: AnyVal] = List[T]().combinations _ +// Type signature +[T <: AnyVal]=> Int => Iterator[List[T]] + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T <: AnyVal)) + resultType = NullaryMethodType( + TypeRef( + TypeSymbol(abstract trait Function1[-T1, +R] extends Object) + args = List( + TypeRef(TypeSymbol(final class Int extends AnyVal)) + TypeRef( + TypeSymbol( + abstract trait Iterator[+A] extends TraversableOnce[A] + ) + args = List( + TypeRef( + TypeSymbol( + sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] + + ) + args = List(TypeParamTypeRef(TypeParam(T <: AnyVal))) + ) + ) + ) + ) + ) + ) +) + +scala> :type -v def f[T, U >: T](x: T, y: List[U]) = x :: y +// Type signature +[T, U >: T](x: T, y: List[U])List[U] + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T), TypeParam(U >: T)) + resultType = MethodType( + params = List(TermSymbol(x: T), TermSymbol(y: List[U])) + resultType = TypeRef( + TypeSymbol( + sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]] + + ) + args = List(TypeParamTypeRef(TypeParam(U >: T))) + ) + ) +) + +scala> + scala> diff --git a/test/files/run/repl-colon-type.scala b/test/files/run/repl-colon-type.scala index 39ab580d2a..c055b215c2 100644 --- a/test/files/run/repl-colon-type.scala +++ b/test/files/run/repl-colon-type.scala @@ -18,6 +18,14 @@ object Test extends ReplTest { |:type def f() = 5 | |:type def g[T](xs: Set[_ <: T]) = Some(xs.head) + | + |// verbose! + |:type -v List(1,2,3) filter _ + |:type -v def f[T >: Null, U <: String](x: T, y: U) = Set(x, y) + |:type -v def x = 1 ; def bar[T >: Null <: AnyRef](xyz: T) = 5 + |:type -v Nil.combinations _ + |:type -v def f[T <: AnyVal] = List[T]().combinations _ + |:type -v def f[T, U >: T](x: T, y: List[U]) = x :: y """.stripMargin } diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check index e439a2a7f4..1e7b6f0cd8 100644 --- a/test/files/run/repl-power.check +++ b/test/files/run/repl-power.check @@ -14,7 +14,6 @@ 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 diff --git a/test/files/run/repl-type-verbose.check b/test/files/run/repl-type-verbose.check new file mode 100644 index 0000000000..103ac3e64d --- /dev/null +++ b/test/files/run/repl-type-verbose.check @@ -0,0 +1,186 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> // verbose! + +scala> :type -v def f = 5 +// Type signature +=> Int + +// Internal Type structure +NullaryMethodType( + TypeRef(TypeSymbol(final class Int extends AnyVal)) +) + +scala> :type -v def f() = 5 +// Type signature +()Int + +// Internal Type structure +NullaryMethodType( + resultType = TypeRef(TypeSymbol(final class Int extends AnyVal)) +) + +scala> :type -v def f[T] = 5 +// Type signature +[T]=> Int + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T)) + resultType = NullaryMethodType( + TypeRef(TypeSymbol(final class Int extends AnyVal)) + ) +) + +scala> :type -v def f[T >: Null] = 5 +// Type signature +[T >: Null]=> Int + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T >: Null)) + resultType = NullaryMethodType( + TypeRef(TypeSymbol(final class Int extends AnyVal)) + ) +) + +scala> :type -v def f[T <: String] = 5 +// Type signature +[T <: String]=> Int + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T <: String)) + resultType = NullaryMethodType( + TypeRef(TypeSymbol(final class Int extends AnyVal)) + ) +) + +scala> :type -v def f[T]() = 5 +// Type signature +[T]()Int + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T)) + resultType = NullaryMethodType( + resultType = TypeRef(TypeSymbol(final class Int extends AnyVal)) + ) +) + +scala> :type -v def f[T, U]() = 5 +// Type signature +[T, U]()Int + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T), TypeParam(U)) + resultType = NullaryMethodType( + resultType = TypeRef(TypeSymbol(final class Int extends AnyVal)) + ) +) + +scala> :type -v def f[T, U]()() = 5 +// Type signature +[T, U]()()Int + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T), TypeParam(U)) + resultType = NullaryMethodType( + resultType = NullaryMethodType( + resultType = TypeRef( + TypeSymbol(final class Int extends AnyVal) + ) + ) + ) +) + +scala> :type -v def f[T, U <: T] = 5 +// Type signature +[T, U <: T]=> Int + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T), TypeParam(U <: T)) + resultType = NullaryMethodType( + TypeRef(TypeSymbol(final class Int extends AnyVal)) + ) +) + +scala> :type -v def f[T, U <: T](x: T)(y: U) = 5 +// Type signature +[T, U <: T](x: T)(y: U)Int + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T), TypeParam(U <: T)) + resultType = MethodType( + params = List(TermSymbol(x: T)) + resultType = MethodType( + params = List(TermSymbol(y: U)) + resultType = TypeRef( + TypeSymbol(final class Int extends AnyVal) + ) + ) + ) +) + +scala> :type -v def f[T: Ordering] = 5 +// Type signature +[T](implicit evidence$1: Ordering[T])Int + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T)) + resultType = MethodType( + params = List(TermSymbol(implicit evidence$1: Ordering[T])) + resultType = TypeRef(TypeSymbol(final class Int extends AnyVal)) + ) +) + +scala> :type -v def f[T: Ordering] = implicitly[Ordering[T]] +// Type signature +[T](implicit evidence$1: Ordering[T])Ordering[T] + +// Internal Type structure +PolyType( + typeParams = List(TypeParam(T)) + resultType = MethodType( + params = List(TermSymbol(implicit evidence$1: Ordering[T])) + resultType = AliasTypeRef( + Alias(type Ordering[T] = scala.math.Ordering[T]) + args = List(TypeParamTypeRef(TypeParam(T))) + normalize = TypeRef( + TypeSymbol( + abstract trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializable + + ) + args = List(TypeParamTypeRef(TypeParam(T))) + ) + ) + ) +) + +scala> :type -v def f[T <: { type Bippy = List[Int] ; def g(): Bippy }] = 5 +// Type signature +[T <: AnyRef{type Bippy = List[Int]; def g(): this.Bippy}]=> Int + +// Internal Type structure +PolyType( + typeParams = List( + TypeParam( + T <: AnyRef{type Bippy = List[Int]; def g(): this.Bippy} + ) + ) + resultType = NullaryMethodType( + TypeRef(TypeSymbol(final class Int extends AnyVal)) + ) +) + +scala> + +scala> diff --git a/test/files/run/repl-type-verbose.scala b/test/files/run/repl-type-verbose.scala new file mode 100644 index 0000000000..10c390550a --- /dev/null +++ b/test/files/run/repl-type-verbose.scala @@ -0,0 +1,20 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = """ + |// verbose! + |:type -v def f = 5 + |:type -v def f() = 5 + |:type -v def f[T] = 5 + |:type -v def f[T >: Null] = 5 + |:type -v def f[T <: String] = 5 + |:type -v def f[T]() = 5 + |:type -v def f[T, U]() = 5 + |:type -v def f[T, U]()() = 5 + |:type -v def f[T, U <: T] = 5 + |:type -v def f[T, U <: T](x: T)(y: U) = 5 + |:type -v def f[T: Ordering] = 5 + |:type -v def f[T: Ordering] = implicitly[Ordering[T]] + |:type -v def f[T <: { type Bippy = List[Int] ; def g(): Bippy }] = 5 + """.stripMargin +} -- cgit v1.2.3 From add30e2f48f0120728a931377cc8a00748f5c9b9 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 17 Apr 2012 17:13:53 +0100 Subject: Try to fix sbt. It depended on the signature of uncheckedWarnings. --- src/compiler/scala/tools/nsc/CompilationUnits.scala | 2 +- src/compiler/scala/tools/nsc/Global.scala | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index 767df0791e..f89f278338 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -91,7 +91,7 @@ trait CompilationUnits { self: Global => currentRun.deprecationWarnings.warn(pos, msg) def uncheckedWarning(pos: Position, msg: String) = - currentRun.uncheckedWarnings.warn(pos, msg) + currentRun.uncheckedWarnings0.warn(pos, msg) def inlinerWarning(pos: Position, msg: String) = currentRun.inlinerWarnings.warn(pos, msg) diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index bbeee3220b..73c68f44d4 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -967,10 +967,15 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S var currentUnit: CompilationUnit = NoCompilationUnit val deprecationWarnings = new ConditionalWarning("deprecation", settings.deprecation) - val uncheckedWarnings = new ConditionalWarning("unchecked", settings.unchecked) + // This change broke sbt; I gave it the thrilling name of uncheckedWarnings0 so + // as to recover uncheckedWarnings for its ever-fragile compiler interface. + val uncheckedWarnings0 = new ConditionalWarning("unchecked", settings.unchecked) val featureWarnings = new ConditionalWarning("feature", settings.feature) val inlinerWarnings = new ConditionalWarning("inliner", settings.YinlinerWarnings) - val allConditionalWarnings = List(deprecationWarnings, uncheckedWarnings, featureWarnings, inlinerWarnings) + val allConditionalWarnings = List(deprecationWarnings, uncheckedWarnings0, featureWarnings, inlinerWarnings) + + // for sbt's benefit + def uncheckedWarnings: List[(Position, String)] = uncheckedWarnings0.warnings.toList var reportedFeature = Set[Symbol]() -- cgit v1.2.3 From 80aaed000d877010bed54be76155e9034d9531b5 Mon Sep 17 00:00:00 2001 From: Étienne Vallette d'Osia Date: Tue, 17 Apr 2012 19:32:12 +0300 Subject: Fix an potentially-disturbing error (typo?) in Either doc. --- src/library/scala/Either.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/library/scala/Either.scala b/src/library/scala/Either.scala index a5e1dc7fe7..20451600a9 100644 --- a/src/library/scala/Either.scala +++ b/src/library/scala/Either.scala @@ -261,7 +261,7 @@ object Either { * case ex => Left(ex) * } * - * // this will only be executed if interactWithDB returns a Some + * // this will only be executed if interactWithDB returns a Right * val report = * for (r <- interactWithDB(someQuery).right) yield generateReport(r) * if (report.isRight) -- cgit v1.2.3 From 17fa0b13480c7dd9796885e32ec562e162253350 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 16 Apr 2012 12:55:26 +0200 Subject: big fat error message, reloaded --- src/library/scala/reflect/package.scala | 48 +++------------------------------ 1 file changed, 3 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 6f40a3ac3e..6d50a96dfd 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -21,52 +21,10 @@ package object reflect { | | In Scala 2.10.0 M3, scala-compiler.jar is required to be on the classpath | for manifests and type tags to function. This will change in the final release, - | but for now you need to adjust your scripts or build system to proceed. - | Here are the instructions for some of the situations that might be relevant. + | but for now you need to adjust your scripts or the build system to proceed. | - | If you compile your application directly from the command line - | or a hand-rolled script, this is a bug. Please, report it. - | - | If you compile your application with Maven using the maven-scala plugin, - | set its "fork" configuration entry to "false: - | - | - | org.scala-tools - | maven-scala-plugin - | 2.15.0 - | - | - | - | ... - | - | - | false - | ... - | - | - | - | - | - | If you compile your application with SBT, - | - | - | If you compile your application in Scala IDE, - | . - | - | If you launch your application directly from the command line - | or a hand-rolled script, add `scala-compiler.jar` to the classpath: - | - | scalac HelloWorld.scala - | scala HelloWorld -cp path/to/scala-compiler.jar - | - | If you launch your application with Maven using the maven-scala plugin, - | set its "fork" configuration entry to "false as shown above. - | - | If you launch your application with SBT, make sure that you use - | - | - | If you launch your application in Scala IDE, make sure that both scala-library.jar and scala-compiler.jar - | are in bootstrap entries on the classpath of your launch configuration. + | For the instructions for some of the situations that might be relevant + | visit our knowledge base at https://gist.github.com/2391081. """.stripMargin('|').format(show(cl)) def mkMirror(classLoader: ClassLoader): api.Mirror = { -- cgit v1.2.3 From e408aa9ccaba736d0f85b7afecd288c3873d05bb Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 16 Apr 2012 11:52:25 +0200 Subject: adds erasures to concrete type tags --- .../scala/reflect/internal/Importers.scala | 4 +- src/compiler/scala/reflect/internal/StdNames.scala | 8 +- src/compiler/scala/reflect/internal/Symbols.scala | 8 +- .../scala/reflect/internal/TreeBuildUtil.scala | 8 +- src/compiler/scala/reflect/internal/TreeInfo.scala | 31 +- src/compiler/scala/reflect/internal/Types.scala | 2 +- .../scala/reflect/makro/runtime/Reifiers.scala | 41 +- .../scala/reflect/makro/runtime/Typers.scala | 8 +- src/compiler/scala/reflect/reify/Reifier.scala | 26 +- .../scala/reflect/reify/codegen/Symbols.scala | 10 +- .../scala/reflect/reify/codegen/Trees.scala | 35 +- .../scala/reflect/reify/codegen/Types.scala | 27 +- .../scala/reflect/reify/codegen/Util.scala | 2 + .../scala/reflect/reify/phases/Metalevels.scala | 4 +- .../scala/reflect/reify/phases/Reify.scala | 47 +- .../scala/reflect/reify/phases/Reshape.scala | 6 - .../reflect/runtime/SynchronizedSymbols.scala | 8 +- src/compiler/scala/tools/nsc/ast/FreeVars.scala | 4 +- .../scala/tools/nsc/typechecker/Implicits.scala | 3 +- src/library/scala/reflect/ClassTag.scala | 4 + src/library/scala/reflect/DynamicProxy.scala | 20 +- src/library/scala/reflect/TagMaterialization.scala | 49 +- src/library/scala/reflect/api/Symbols.scala | 10 + src/library/scala/reflect/api/TreeBuildUtil.scala | 20 +- src/library/scala/reflect/api/TypeTags.scala | 43 +- src/library/scala/reflect/api/Types.scala | 14 +- src/library/scala/reflect/makro/Reifiers.scala | 4 + .../scala/reflect/makro/internal/Utils.scala | 45 +- src/library/scala/reflect/package.scala | 2 +- test/files/jvm/interpreter.check | 743 +++++++++++---------- test/files/run/existentials3.check | 4 +- .../macro-reify-typetag-typeparams-notags.check | 4 +- .../run/macro-reify-typetag-typeparams-tags.check | 2 +- .../run/macro-reify-typetag-usegroundtypetag.check | 2 +- .../files/run/macro-typecheck-macrosdisabled.check | 2 +- .../Impls_Macros_1.scala | 4 +- test/files/run/reify_newimpl_26.check | 2 +- test/files/run/t3507.check | 2 +- .../run/toolbox_typecheck_macrosdisabled.check | 2 +- .../run/toolbox_typecheck_macrosdisabled.scala | 2 +- 40 files changed, 669 insertions(+), 593 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index ab5e19fca9..596d400628 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -71,9 +71,9 @@ trait Importers { self: SymbolTable => case x: from.ModuleSymbol => linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol) case x: from.FreeTerm => - newFreeTerm(importName(x.name).toTermName, importType(x.info), x.value, x.origin, myflags) + newFreeTermSymbol(importName(x.name).toTermName, importType(x.info), x.value, x.flags, x.origin) case x: from.FreeType => - newFreeType(importName(x.name).toTypeName, importType(x.info), x.value, x.origin, myflags) + newFreeTypeSymbol(importName(x.name).toTypeName, importType(x.info), x.value, x.flags, x.origin) case x: from.TermSymbol => linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol) case x: from.TypeSkolem => diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index bf468affe6..c5fe1ecb45 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -291,11 +291,14 @@ trait StdNames extends NameManglers { self: SymbolTable => val AnnotationInfo: NameType = "AnnotationInfo" val Any: NameType = "Any" val AnyVal: NameType = "AnyVal" + val AppliedTypeTree: NameType = "AppliedTypeTree" val Apply: NameType = "Apply" val ArrayAnnotArg: NameType = "ArrayAnnotArg" + val Constant: NameType = "Constant" val ConstantType: NameType = "ConstantType" val EmptyPackage: NameType = "EmptyPackage" val EmptyPackageClass: NameType = "EmptyPackageClass" + val ExistentialTypeTree: NameType = "ExistentialTypeTree" val Expr: NameType = "Expr" val Ident: NameType = "Ident" val Import: NameType = "Import" @@ -404,13 +407,15 @@ trait StdNames extends NameManglers { self: SymbolTable => val name: NameType = "name" val ne: NameType = "ne" val newArray: NameType = "newArray" + val newFreeExistential: NameType = "newFreeExistential" val newFreeTerm: NameType = "newFreeTerm" val newFreeType: NameType = "newFreeType" val newNestedSymbol: NameType = "newNestedSymbol" val newScopeWith: NameType = "newScopeWith" + val next: NameType = "next" val nmeNewTermName: NameType = "newTermName" val nmeNewTypeName: NameType = "newTypeName" - val next: NameType = "next" + val normalize: NameType = "normalize" val notifyAll_ : NameType = "notifyAll" val notify_ : NameType = "notify" val null_ : NameType = "null" @@ -465,6 +470,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val view_ : NameType = "view" val wait_ : NameType = "wait" val withFilter: NameType = "withFilter" + val wrap: NameType = "wrap" val zip: NameType = "zip" val synthSwitch: NameType = "$synthSwitch" diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 6eaae7f1ee..74e924add4 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -47,13 +47,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Create a new free term. Its owner is NoSymbol. */ - def newFreeTerm(name: TermName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeTerm = - new FreeTerm(name, value, origin) initFlags newFlags setInfo info + def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTerm = + new FreeTerm(name, value, origin) initFlags flags 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 + def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeType = + new FreeType(name, value, origin) initFlags flags setInfo info /** The original owner of a class. Used by the backend to generate * EnclosingMethod attributes. diff --git a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala index fbcd5043bc..d4d4652e91 100644 --- a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala +++ b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala @@ -1,6 +1,8 @@ package scala.reflect package internal +import Flags._ + trait TreeBuildUtil extends api.TreeBuildUtil { self: SymbolTable => // ``staticClass'' and ``staticModule'' rely on ClassLoaders @@ -51,9 +53,11 @@ trait TreeBuildUtil extends api.TreeBuildUtil { self: SymbolTable => 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 newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTermSymbol(newTermName(name), info, value, flags, origin) + + def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) PARAM else flags) | DEFERRED, origin) - def newFreeType(name: String, info: Type, value: => Any, origin: String) = newFreeType(newTypeName(name), info, value, origin) + def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) EXISTENTIAL else flags) | DEFERRED, origin) def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers = Modifiers(flags, privateWithin, annotations) diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index 039c8e557a..937b3ea5d6 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -629,7 +629,7 @@ abstract class TreeInfo { object ReifiedType { 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 => + case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(_, tpe :: _)) if mrDef.name == nme.MIRROR_SHORT => Some(reifee, symbolTable, tpe) case _ => None @@ -646,11 +646,11 @@ abstract class TreeInfo { } 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) + def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match { + case FreeTermDef(mrRef, name, binding, flags, origin) => + Some(mrRef, name, binding, flags, origin) + case FreeTypeDef(mrRef, name, binding, flags, origin) => + Some(mrRef, name, binding, flags, origin) case _ => None } @@ -659,28 +659,29 @@ abstract class TreeInfo { 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))))) + def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match { + case ValDef(_, name, _, Apply(Select(mrRef @ Ident(_), newFreeTerm), List(_, _, binding, Literal(Constant(flags: Long)), Literal(Constant(origin: String))))) if mrRef.name == nme.MIRROR_SHORT && newFreeTerm == newFreeTermMethod.name => - Some(mrRef, name, binding, origin) + Some(mrRef, name, binding, flags, origin) case _ => None } } object FreeTypeDef { - lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType) + lazy val newFreeExistentialMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType) + lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeExistential) - 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 => + def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match { + case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(flags: Long)), Literal(Constant(origin: String))))) + if mrRef1.name == nme.MIRROR_SHORT && (newFreeType == newFreeTypeMethod.name || newFreeType == newFreeExistentialMethod.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) + Some(mrRef1, name, binding, flags, 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) + Some(mrRef1, name, binding, flags, origin) case _ => throw new Error("unsupported free type def: " + showRaw(tree)) } diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index fc57a130d1..7115cafc33 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -277,7 +277,7 @@ trait Types extends api.Types { self: SymbolTable => case SuperType(_, _) => false case SingleType(pre, sym) => notConcreteSym(sym) case ConstantType(_) => false - case TypeRef(_, sym, _) => notConcreteSym(sym) + case TypeRef(_, sym, args) => notConcreteSym(sym) || (args exists (arg => notConcreteTpe(arg))) case RefinedType(_, _) => false case ExistentialType(_, _) => false case AnnotatedType(_, tp, _) => notConcreteTpe(tp) diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala index 2488b06d6c..3586adc590 100644 --- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -10,6 +10,7 @@ trait Reifiers { self: Context => import mirror._ + import definitions._ lazy val reflectMirrorPrefix: Tree = { // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure? @@ -24,6 +25,44 @@ trait Reifiers { def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree = reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, requireConcreteTypeTag) + def reifyErasure(tpe: Type): Tree = { + val positionBearer = enclosingMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] + val typetagInScope = callsiteTyper.context.withMacrosDisabled(callsiteTyper.resolveTypeTag(positionBearer, gen.mkAttributedRef(Reflect_mirror).tpe, tpe, full = true)) + 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), nme.apply), List(TypeTree(tpe))) + Apply(factory, List(typetagInScope)) + case _ => + if (tpe.typeSymbol == ArrayClass) { + val componentTpe = tpe.typeArguments(0) + val componentTag = callsiteTyper.resolveClassTag(positionBearer, componentTpe) + Select(componentTag, nme.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.isSpliceable) throw new ReificationError(enclosingPosition, "tpe %s is an unresolved spliceable type".format(tpe)) + // [Eugene] imho this logic should be moved into `erasure` + var erasure = tpe match { + case tpe if tpe.typeSymbol.isDerivedValueClass => tpe // [Eugene to Martin] is this correct? + case ConstantType(value) => tpe.widen.erasure + case _ => { + // [Eugene] magikz. needs review + var result = tpe.erasure.normalize // necessary to deal with erasures of HK types, typeConstructor won't work + result = result match { + case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) // we don't want undets in the result + case _ => result + } + result + } + } + val factory = TypeApply(Select(Ident(ClassTagModule), nme.apply), List(TypeTree(tpe))) + Apply(factory, List(TypeApply(Select(Ident(PredefModule), nme.classOf), List(TypeTree(erasure))))) + } + } + } + def unreifyTree(tree: Tree): Tree = Select(tree, definitions.ExprEval) @@ -34,7 +73,7 @@ trait Reifiers { try { val result = reifier.reified - logFreeVars(expandee.pos, result) + logFreeVars(enclosingPosition, result) result } catch { case ex: reifier.ReificationError => diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala index 38e819746d..b32d4fb7b1 100644 --- a/src/compiler/scala/reflect/makro/runtime/Typers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala @@ -34,9 +34,9 @@ trait Typers { 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) + val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) + def wrapper (inference: => SearchResult) = wrapper1(inference) 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") @@ -51,11 +51,11 @@ trait Typers { 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] _) + val context = callsiteTyper.context.makeImplicit(reportAmbiguous) + val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (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") diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala index 16c26734b2..c89ebf0d39 100644 --- a/src/compiler/scala/reflect/reify/Reifier.scala +++ b/src/compiler/scala/reflect/reify/Reifier.scala @@ -47,6 +47,15 @@ abstract class Reifier extends Phases if (prefix exists (_.isErroneous)) CannotReifyErroneousPrefix(prefix) if (prefix.tpe == null) CannotReifyUntypedPrefix(prefix) + def reifyErasure(tpe: Type): Tree = { + val result = typer.resolveClassTag(positionBearer, tpe) + if (result == EmptyTree) throw new Error("cannot reify erasure for %s: ".format(tpe)) + result match { + case Apply(TypeApply(Select(_, _), _), List(clazz)) => clazz + case _ => Select(result, nme.erasure) + } + } + val rtree = reifee match { case tree: Tree => reifyTrace("reifying = ")(if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) @@ -73,11 +82,11 @@ abstract class Reifier extends Phases 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)))) + val tagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) + val exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType))) + val tagArgs = if (definitelyConcrete) List(reify(manifestedType), reifyErasure(manifestedType)) else List(reify(manifestedType)) + Apply(Apply(exprCtor, List(rtree)), List(Apply(tagCtor, tagArgs))) case tpe: Type => reifyTrace("reifying = ")(tpe.toString) @@ -85,9 +94,10 @@ abstract class Reifier extends Phases 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)) + val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule + val ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) + val args = if (definitelyConcrete) List(rtree, reifyErasure(manifestedType)) else List(rtree) + Apply(ctor, args) case _ => throw new Error("reifee %s of type %s is not supported".format(reifee, if (reifee == null) "null" else reifee.getClass.toString)) @@ -126,7 +136,7 @@ abstract class Reifier extends Phases // 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 freevarBindings = symbolTable collect { case entry @ 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 diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala index 2fc0002838..0513f99366 100644 --- a/src/compiler/scala/reflect/reify/codegen/Symbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala @@ -63,9 +63,9 @@ trait Symbols { assert(value.isInstanceOf[Ident], showRaw(value)) val capturedTpe = capturedVariableType(sym) val capturedValue = referenceCapturedVariable(sym) - locallyReify(sym, name, 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(sym.flags), reify(origin(sym)))) } else { - locallyReify(sym, name, 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(sym.flags), reify(origin(sym)))) } } @@ -77,8 +77,8 @@ trait Symbols { 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, name, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(origin(sym)))) + val flavor = if (sym.isExistential) nme.newFreeExistential else nme.newFreeType + locallyReify(sym, name, mirrorCall(flavor, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(sym.flags), reify(origin(sym)))) } def reifySymDef(sym: Symbol): Tree = @@ -169,7 +169,7 @@ trait Symbols { 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))) + val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reify(sym.info))) if (sym.annotations.isEmpty) rset else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations))) } diff --git a/src/compiler/scala/reflect/reify/codegen/Trees.scala b/src/compiler/scala/reflect/reify/codegen/Trees.scala index 5ad53c0009..c9f5fc5b8d 100644 --- a/src/compiler/scala/reflect/reify/codegen/Trees.scala +++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala @@ -7,6 +7,7 @@ trait Trees { import mirror._ import definitions._ import treeInfo._ + import scala.reflect.api.Modifier // 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 @@ -46,7 +47,7 @@ trait Trees { reifyMirrorObject(EmptyTree) case mirror.emptyValDef => mirrorSelect(nme.emptyValDef) - case FreeDef(_, _, _, _) => + case FreeDef(_, _, _, _, _) => reifyNestedFreeDef(tree) case FreeRef(_, _) => reifyNestedFreeRef(tree) @@ -57,6 +58,28 @@ trait Trees { case NestedExpr(_, _, _) => reifyNestedExpr(tree) case Literal(const @ Constant(_)) => + // [Eugene] was necessary when we reified erasures as normalized tycons + // now, when we do existentialAbstraction on normalizations, everything works great + // todo. find an explanation +// if (const.tag == ClazzTag) { +//// def preprocess(tpe: Type): Type = tpe.typeSymbol match { +//// case ArrayClass => appliedType(ArrayClass, preprocess(tpe.typeArgs.head)) +//// case _ => tpe.typeConstructor +//// } +//// val tpe = preprocess(const.typeValue) +// val tpe = const.typeValue +// var reified = reify(tpe) +// reified = mirrorCall(nme.Literal, mirrorCall(nme.Constant, reified)) +//// val skolems = ClassClass.typeParams map (_ => newTypeName(typer.context.unit.fresh.newName("_$"))) +//// var existential = mirrorCall(nme.AppliedTypeTree, mirrorCall(nme.TypeTree, reify(ClassClass.typeConstructor)), mkList(skolems map (skolem => mirrorCall(nme.Ident, reify(skolem))))) +//// existential = mirrorCall(nme.ExistentialTypeTree, existential, reify(skolems map (skolem => TypeDef(Modifiers(Set(Modifier.deferred: Modifier)), skolem, Nil, TypeBoundsTree(Ident(NothingClass) setType NothingClass.tpe, Ident(AnyClass) setType AnyClass.tpe))))) +//// reified = mirrorCall(nme.TypeApply, mirrorCall(nme.Select, reified, reify(nme.asInstanceOf_)), mkList(List(existential))) +// // why is this required?? +//// reified = mirrorCall(nme.TypeApply, mirrorCall(nme.Select, reified, reify(nme.asInstanceOf_)), mkList(List(mirrorCall(nme.TypeTree, reify(appliedType(ClassClass.tpe, List(AnyClass.tpe))))))) +// reified +// } else { +// mirrorCall(nme.Literal, reifyProduct(const)) +// } mirrorCall(nme.Literal, reifyProduct(const)) case Import(expr, selectors) => mirrorCall(nme.Import, reify(expr), mkList(selectors map reifyProduct)) @@ -68,11 +91,11 @@ trait Trees { // 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))) + rtree = Apply(Select(rtree, nme.setSymbol), List(reify(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 = Apply(Select(rtree, nme.setType), List(reify(tree.tpe))) } rtree @@ -98,7 +121,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 collect { case freedef @ FreeDef(_, _, binding, _) if binding.symbol.isLocalToReifee => assert(false, freedef) } + inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => assert(false, freedef) } symbolTable ++= inlinedSymbolTable tree case tree => @@ -172,7 +195,7 @@ trait Trees { val spliced = spliceType(tpe) if (spliced == EmptyTree) { if (reifyDebug) println("splicing failed: reify as is") - mirrorCall(nme.TypeTree, reifyType(tpe)) + mirrorCall(nme.TypeTree, reify(tpe)) } else { spliced match { case TypeRefToFreeType(freeType) => @@ -189,7 +212,7 @@ trait Trees { 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)) + mirrorCall(nme.TypeTree, reify(tpe)) } } } diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala index 948728088e..e2a2a69828 100644 --- a/src/compiler/scala/reflect/reify/codegen/Types.scala +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -65,8 +65,16 @@ trait Types { private var spliceTypesEnabled = !dontSpliceAtTopLevel /** Keeps track of whether this reification contains abstract type parameters */ - var maybeConcrete = true - var definitelyConcrete = true + private var _definitelyConcrete = true + def definitelyConcrete = _definitelyConcrete + def definitelyConcrete_=(value: Boolean) { + _definitelyConcrete = value + if (!value && requireConcreteTypeTag) { + assert(current.isInstanceOf[Type], current) + val offender = current.asInstanceOf[Type] + CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(offender) + } + } private type SpliceCacheKey = (Symbol, Symbol) private lazy val spliceCache: collection.mutable.Map[SpliceCacheKey, Tree] = { @@ -75,7 +83,9 @@ trait Types { } def spliceType(tpe: Type): Tree = { - if (tpe.isSpliceable) { + // [Eugene] it seems that depending on the context the very same symbol can be either a spliceable tparam or a quantified existential. very weird! + val quantified = currents collect { case ExistentialType(quantified, _) => quantified } flatMap identity + if (tpe.isSpliceable && !(quantified contains tpe.typeSymbol)) { if (reifyDebug) println("splicing " + tpe) if (spliceTypesEnabled) { @@ -89,22 +99,18 @@ trait Types { // 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, requireConcreteTypeTag) match { case failure if failure.isEmpty => if (reifyDebug) println("implicit search was fruitless") - definitelyConcrete &= false - maybeConcrete &= false EmptyTree case success => if (reifyDebug) println("implicit search has produced a result: " + success) - definitelyConcrete |= requireConcreteTypeTag - maybeConcrete |= true + definitelyConcrete &= requireConcreteTypeTag 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 collect { case freedef @ FreeDef(_, _, binding, _) if binding.symbol.isLocalToReifee => assert(false, freedef) } + inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => assert(false, freedef) } symbolTable ++= inlinedSymbolTable reifyTrace("inlined the splicee: ")(tpe) case tpe => @@ -117,8 +123,7 @@ trait Types { if (reifyDebug) println("splicing has been cancelled: spliceTypesEnabled = false") } - if (requireConcreteTypeTag) - CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(tpe) + definitelyConcrete = false } spliceTypesEnabled = true diff --git a/src/compiler/scala/reflect/reify/codegen/Util.scala b/src/compiler/scala/reflect/reify/codegen/Util.scala index bb369a1adb..8d7cf39ff7 100644 --- a/src/compiler/scala/reflect/reify/codegen/Util.scala +++ b/src/compiler/scala/reflect/reify/codegen/Util.scala @@ -14,6 +14,8 @@ trait Util { object reifiedNodePrinters extends { val global: mirror.type = mirror } with tools.nsc.ast.NodePrinters with NodePrinters val reifiedNodeToString = reifiedNodePrinters.reifiedNodeToString + val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] + def reifyList(xs: List[Any]): Tree = mkList(xs map reify) diff --git a/src/compiler/scala/reflect/reify/phases/Metalevels.scala b/src/compiler/scala/reflect/reify/phases/Metalevels.scala index bb0b8ac138..206f3b1118 100644 --- a/src/compiler/scala/reflect/reify/phases/Metalevels.scala +++ b/src/compiler/scala/reflect/reify/phases/Metalevels.scala @@ -115,7 +115,7 @@ trait Metalevels { 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] } + 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) @@ -138,7 +138,7 @@ trait Metalevels { // 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) + 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))) diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala index 02a96987ed..a1ff486ed7 100644 --- a/src/compiler/scala/reflect/reify/phases/Reify.scala +++ b/src/compiler/scala/reflect/reify/phases/Reify.scala @@ -23,24 +23,33 @@ trait Reify extends Symbols * 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) - // 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) - 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)) + var currents: List[Any] = reifee :: Nil + def current = currents.head + def reify(reifee: Any): Tree = { + currents = reifee :: currents + try { + 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) + // 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) + 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)) + } + } finally { + currents = currents.tail + } } } \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index e700604612..4ab306a13f 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -78,12 +78,6 @@ trait Reshape { 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 } diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala index 6fc5f7ed8a..4048e94d0f 100644 --- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala @@ -14,11 +14,11 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol = synchronized { super.connectModuleToClass(m, moduleClass) } - 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 newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTerm = + new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags flags 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 def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeType = + new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags flags setInfo info override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol diff --git a/src/compiler/scala/tools/nsc/ast/FreeVars.scala b/src/compiler/scala/tools/nsc/ast/FreeVars.scala index 1bf36e8bf2..a1983d1834 100644 --- a/src/compiler/scala/tools/nsc/ast/FreeVars.scala +++ b/src/compiler/scala/tools/nsc/ast/FreeVars.scala @@ -13,9 +13,9 @@ trait FreeVars extends reflect.internal.FreeVars { self: Global => 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 => + 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 => + 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 diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 4fb9362ccc..30a79917c9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1161,7 +1161,8 @@ trait Implicits { // 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) + if (context.macrosEnabled) success(materializer) + else failure(materializer, "macros are disabled") } /** The manifest corresponding to type `pt`, provided `pt` is an instance of Manifest. diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index 7138837f0d..fe8a16a484 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -117,6 +117,10 @@ object ClassTag { case _ => apply[T](rm.typeToClass(tpe.erasure)) } + def apply[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = + if (ttag.erasure != null) ClassTag[T](ttag.erasure) + else ClassTag[T](ttag.tpe) + implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag) } diff --git a/src/library/scala/reflect/DynamicProxy.scala b/src/library/scala/reflect/DynamicProxy.scala index ffd1e7a39f..02872977f5 100644 --- a/src/library/scala/reflect/DynamicProxy.scala +++ b/src/library/scala/reflect/DynamicProxy.scala @@ -2,13 +2,13 @@ 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 @@ -26,7 +26,7 @@ trait DynamicProxy extends Dynamic{ 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 )() @@ -38,7 +38,7 @@ trait DynamicProxy extends Dynamic{ } def applyDynamic( method:String )( args:DynamicReflectBoxed* ) : Any - = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* ) + = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* ) def applyDynamicNamed( method:String )( args:(String,DynamicReflectBoxed)* ) : Any = { val class_ = dynamicProxyTarget.getClass @@ -48,27 +48,27 @@ trait DynamicProxy extends Dynamic{ if(args.size == 0){ invoke( dynamicProxyTarget, symbol )() } else { - val call = + val call = Apply( Select( TypeApply( Select( Select( - Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this, null)) + Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this)) , 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)) + val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value)) if( name == "" ) value else AssignOrNamedArg( Ident(name), value ) }.toList ) toolbox.runExpr( call ) - } + } } } diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala index aede00020f..a7237223f1 100644 --- a/src/library/scala/reflect/TagMaterialization.scala +++ b/src/library/scala/reflect/TagMaterialization.scala @@ -65,59 +65,22 @@ object TagMaterialization { 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) - materializeClassTag(prefix, tpe) - } - - 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 materializeClassTag(tpe: Type): Tree = + materializeTag(c.reflectMirrorPrefix, tpe, ClassTagModule, c.reifyErasure(tpe)) def materializeTypeTag(tpe: Type, requireConcreteTypeTag: Boolean): Tree = { def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix - materializeTypeTag(prefix, tpe, requireConcreteTypeTag) + val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule + materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)) } - def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { - val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule + private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = { 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) + try materializer 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/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index e47bc7216e..d9293888d9 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -120,6 +120,11 @@ trait Symbols { self: Universe => */ def isTerm : Boolean + /** Does this symbol represent a package? + * If yes, `isTerm` is also guaranteed to be true. + */ + def isPackage : Boolean + /** Does this symbol represent the definition of method? * If yes, `isTerm` is also guaranteed to be true. */ @@ -146,6 +151,11 @@ trait Symbols { self: Universe => */ def isClass : Boolean + /** Does this symbol represent a package class? + * If yes, `isClass` is also guaranteed to be true. + */ + def isPackageClass : 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]]? diff --git a/src/library/scala/reflect/api/TreeBuildUtil.scala b/src/library/scala/reflect/api/TreeBuildUtil.scala index 32d7eefa5b..4f510337c2 100644 --- a/src/library/scala/reflect/api/TreeBuildUtil.scala +++ b/src/library/scala/reflect/api/TreeBuildUtil.scala @@ -62,20 +62,34 @@ trait TreeBuildUtil { self: Universe => * @param name the name of the free variable * @param info the type signature of the free variable * @param value the value of the free variable at runtime + * @param flags (optional) flags of the free variable * @param origin debug information that tells where this symbol comes from */ - def newFreeTerm(name: String, info: Type, value: => Any, origin: String): Symbol + def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol - /** Create a fresh free type symbol. + /** Create a fresh free non-existential 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 flags (optional) flags of the free variable * @param origin debug information that tells where this symbol comes from */ - def newFreeType(name: String, info: Type, value: => Any, origin: String): Symbol + def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol + + /** Create a fresh free existential 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 flags (optional) flags of the free variable + * @param origin (optional) debug information that tells where this symbol comes from + */ + def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol /** Create a Modiiers structure given internal flags, qualifier, annotations */ def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index 59a7c87f44..85755cd2f2 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 java.lang.{ Class => jClass } import language.implicitConversions /** @@ -119,7 +120,7 @@ trait TypeTags { self: Universe => * @see [[scala.reflect.api.TypeTags]] */ @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}") - class ConcreteTypeTag[T](tpe: Type) extends TypeTag[T](tpe) { + abstract class ConcreteTypeTag[T](tpe: Type, val erasure: jClass[_]) 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) @@ -128,24 +129,24 @@ trait TypeTags { self: Universe => } 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] = + val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe, ClassTag.Byte.erasure) { private def readResolve() = ConcreteTypeTag.Byte } + val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe, ClassTag.Short.erasure) { private def readResolve() = ConcreteTypeTag.Short } + val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe, ClassTag.Char.erasure) { private def readResolve() = ConcreteTypeTag.Char } + val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe, ClassTag.Int.erasure) { private def readResolve() = ConcreteTypeTag.Int } + val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe, ClassTag.Long.erasure) { private def readResolve() = ConcreteTypeTag.Long } + val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe, ClassTag.Float.erasure) { private def readResolve() = ConcreteTypeTag.Float } + val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe, ClassTag.Double.erasure) { private def readResolve() = ConcreteTypeTag.Double } + val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe, ClassTag.Boolean.erasure) { private def readResolve() = ConcreteTypeTag.Boolean } + val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe, ClassTag.Unit.erasure) { private def readResolve() = ConcreteTypeTag.Unit } + val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe, ClassTag.Any.erasure) { private def readResolve() = ConcreteTypeTag.Any } + val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe, ClassTag.Object.erasure) { private def readResolve() = ConcreteTypeTag.Object } + val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe, ClassTag.AnyVal.erasure) { private def readResolve() = ConcreteTypeTag.AnyVal } + val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe, ClassTag.AnyRef.erasure) { private def readResolve() = ConcreteTypeTag.AnyRef } + val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe, ClassTag.Nothing.erasure) { private def readResolve() = ConcreteTypeTag.Nothing } + val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe, ClassTag.Null.erasure) { private def readResolve() = ConcreteTypeTag.Null } + val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe, ClassTag.String.erasure) { private def readResolve() = ConcreteTypeTag.String } + + def apply[T](tpe: Type, erasure: jClass[_] = null): ConcreteTypeTag[T] = tpe match { case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]] case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]] @@ -163,12 +164,12 @@ trait TypeTags { self: Universe => 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) {} + case _ => new ConcreteTypeTag[T](tpe, erasure) {} } def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None - implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure)) + implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](ttag) implicit def toDeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala index 5e1c1af2fe..4cb5609166 100755 --- a/src/library/scala/reflect/api/Types.scala +++ b/src/library/scala/reflect/api/Types.scala @@ -53,14 +53,26 @@ trait Types { self: Universe => */ def typeArguments: List[Type] + /** For a (potentially wrapped) poly type, its type parameters, + * the empty list for all other types */ + def typeParams: List[Symbol] + /** Is this type a type constructor that is missing its type arguments? */ def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no? - /** Does this type refer to abstract types or is an abstract type? + /** Returns the corresponding type constructor (e.g. List for List[T] or List[String]) + */ + def typeConstructor: Type + + /** Does this type refer to spliceable types or is a spliceable type? */ def isConcrete: Boolean + /** Is this type an abstract type that needs to be resolved? + */ + def isSpliceable: Boolean + /** * Expands type aliases and converts higher-kinded TypeRefs to PolyTypes. * Functions on types are also implemented as PolyTypes. diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala index d690df6aee..b9e82e0387 100644 --- a/src/library/scala/reflect/makro/Reifiers.scala +++ b/src/library/scala/reflect/makro/Reifiers.scala @@ -48,6 +48,10 @@ trait Reifiers { */ def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree + /** Given a type, generate a tree that when compiled and executed produces the erasure of the original type. + */ + def reifyErasure(tpe: Type): Tree + /** Undoes reification of a tree. * * This reversion doesn't simply restore the original tree (that would lose the context of reification), diff --git a/src/library/scala/reflect/makro/internal/Utils.scala b/src/library/scala/reflect/makro/internal/Utils.scala index db658fd637..604bba10b6 100644 --- a/src/library/scala/reflect/makro/internal/Utils.scala +++ b/src/library/scala/reflect/makro/internal/Utils.scala @@ -55,49 +55,22 @@ package internal { 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 materializeClassTag(prefix: Tree, tpe: Type): Tree = + materializeTag(prefix, tpe, ClassTagModule, c.reifyErasure(tpe)) def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule + materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)) + } + + private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = { val result = tpe match { case coreTpe if coreTags contains coreTpe => - Select(Select(prefix, tagModule.name), coreTags(coreTpe)) + val ref = if (tagModule.owner.isPackageClass) Ident(tagModule) else Select(prefix, tagModule.name) + Select(ref, coreTags(coreTpe)) case _ => - try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) + try materializer 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 6d50a96dfd..93fd0bb711 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -64,7 +64,7 @@ package object reflect { @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 + object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.TypeTag.Nothing.tpe) // ClassTag class is defined separately from the mirror type TypeTag[T] = scala.reflect.mirror.TypeTag[T] diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index 292d2fc4cb..85ec46c5f5 100644 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -1,374 +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) -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 - */ -*/ - - -You typed two blank lines. Starting a new command. - -scala> // multi-line string - -scala> """ -hello -there -""" -res12: 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: Array[_] = Array(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/run/existentials3.check b/test/files/run/existentials3.check index 8227d77909..85bc430a21 100644 --- a/test/files/run/existentials3.check +++ b/test/files/run/existentials3.check @@ -7,7 +7,7 @@ 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 +TypeTag[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 @@ -19,6 +19,6 @@ 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 +TypeTag[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/macro-reify-typetag-typeparams-notags.check b/test/files/run/macro-reify-typetag-typeparams-notags.check index af4877e205..11d78ece41 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 @@ -ConcreteTypeTag[T] -ConcreteTypeTag[List[T]] +TypeTag[T] +TypeTag[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 d75b3c72b2..458593c449 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 @@ ConcreteTypeTag[Int] -ConcreteTypeTag[List[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 d75b3c72b2..458593c449 100644 --- a/test/files/run/macro-reify-typetag-usegroundtypetag.check +++ b/test/files/run/macro-reify-typetag-usegroundtypetag.check @@ -1,2 +1,2 @@ ConcreteTypeTag[Int] -ConcreteTypeTag[List[Int]] +*ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-typecheck-macrosdisabled.check b/test/files/run/macro-typecheck-macrosdisabled.check index b432a539fc..3e1057520b 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.ConcreteTypeTag.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)), classOf[scala.Int])) } mr.reify[Int](2) diff --git a/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala index c253f0b1fb..a1f124f790 100644 --- a/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala +++ b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala @@ -8,7 +8,7 @@ object Macros { //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 mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror) //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")) @@ -25,7 +25,7 @@ object Macros { 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 mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror) val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) val ttree2 = c.typeCheck(tree2, withMacrosDisabled = true) diff --git a/test/files/run/reify_newimpl_26.check b/test/files/run/reify_newimpl_26.check index bfbf1d653d..d92b3bd817 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] -ConcreteTypeTag[List[T]] +TypeTag[List[T]] scala> diff --git a/test/files/run/t3507.check b/test/files/run/t3507.check index 50ab029592..6e4fa4170e 100644 --- a/test/files/run/t3507.check +++ b/test/files/run/t3507.check @@ -1 +1 @@ -ConcreteTypeTag[_1.type#b.c.type] +ConcreteTypeTag[_1.b.c.type] diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.check b/test/files/run/toolbox_typecheck_macrosdisabled.check index cf2420bc17..c4af175812 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.ConcreteTypeTag.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)), classOf[scala.Int])) } mr.reify[Int](2) diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.scala b/test/files/run/toolbox_typecheck_macrosdisabled.scala index 7d2707d5e1..afbbce1736 100644 --- a/test/files/run/toolbox_typecheck_macrosdisabled.scala +++ b/test/files/run/toolbox_typecheck_macrosdisabled.scala @@ -5,7 +5,7 @@ object Test extends App { 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 mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror) val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) val ttree1 = toolbox.typeCheck(tree1, withMacrosDisabled = false) -- cgit v1.2.3 From b37350b4126a1030d1060fd982d2ade6e2e5bd8e Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 17 Apr 2012 02:50:33 +0200 Subject: adds a dummy mirror --- src/library/scala/reflect/DummyMirror.scala | 740 +++++++++++++++++++++++++++ src/library/scala/reflect/api/TypeTags.scala | 20 +- src/library/scala/reflect/package.scala | 13 +- 3 files changed, 760 insertions(+), 13 deletions(-) create mode 100644 src/library/scala/reflect/DummyMirror.scala (limited to 'src') diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala new file mode 100644 index 0000000000..1fbf36be9d --- /dev/null +++ b/src/library/scala/reflect/DummyMirror.scala @@ -0,0 +1,740 @@ +package scala.reflect + +import scala.reflect.api.AbsTreeGen +import scala.reflect.api.Attachment +import scala.reflect.api.Modifier +import scala.reflect.api.Universe + +class DummyMirror(cl: ClassLoader) extends api.Mirror { + // Members declared in scala.reflect.api.AnnotationInfos + implicit def classfileAnnotArgManifest: scala.reflect.ClassManifest[ClassfileAnnotArg] = notSupported() + type AnnotationInfo = DummyAnnotationInfo.type + object DummyAnnotationInfo + val AnnotationInfo: AnnotationInfoExtractor = DummyAnnotationInfoExtractor + object DummyAnnotationInfoExtractor extends AnnotationInfoExtractor { + def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo = DummyAnnotationInfo + def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] = notSupported() + } + type ClassfileAnnotArg = AnyRef + type LiteralAnnotArg = DummyLiteralAnnotArg.type + object DummyLiteralAnnotArg + val LiteralAnnotArg: LiteralAnnotArgExtractor = DummyLiteralAnnotArgExtractor + type ArrayAnnotArg = DummyArrayAnnotArg.type + object DummyArrayAnnotArg + val ArrayAnnotArg: ArrayAnnotArgExtractor = DummyArrayAnnotArgExtractor + type NestedAnnotArg = DummyNestedAnnotArg.type + object DummyNestedAnnotArg + val NestedAnnotArg: NestedAnnotArgExtractor = DummyNestedAnnotArgExtractor + object DummyLiteralAnnotArgExtractor extends LiteralAnnotArgExtractor { + def apply(const: Constant): LiteralAnnotArg = DummyLiteralAnnotArg + def unapply(arg: LiteralAnnotArg): Option[Constant] = notSupported() + } + object DummyArrayAnnotArgExtractor extends ArrayAnnotArgExtractor { + def apply(const: Array[ClassfileAnnotArg]): ArrayAnnotArg = DummyArrayAnnotArg + def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]] = notSupported() + } + object DummyNestedAnnotArgExtractor extends NestedAnnotArgExtractor { + def apply(anninfo: AnnotationInfo): NestedAnnotArg = DummyNestedAnnotArg + def unapply(arg: NestedAnnotArg): Option[AnnotationInfo] = notSupported() + } + + // Members declared in scala.reflect.api.Constants + type Constant = DummyConstant.type + object DummyConstant extends AbsConstant { + val value: Any = notSupported() + def tpe: Type = notSupported() + def isNaN: Boolean = notSupported() + def booleanValue: Boolean = notSupported() + def byteValue: Byte = notSupported() + def shortValue: Short = notSupported() + def charValue: Char = notSupported() + def intValue: Int = notSupported() + def longValue: Long = notSupported() + def floatValue: Float = notSupported() + def doubleValue: Double = notSupported() + def stringValue: String = notSupported() + def typeValue: Type = notSupported() + def symbolValue: Symbol = notSupported() + def convertTo(pt: Type): Constant = notSupported() + } + val Constant: ConstantExtractor = DummyConstantExtractor + object DummyConstantExtractor extends ConstantExtractor { + def apply(const: Any): Constant = DummyConstant + def unapply(arg: Constant): Option[Any] = notSupported() + } + + // Members declared in scala.reflect.api.FreeVars + type FreeTerm = DummyFreeTerm.type + val DummyFreeTerm = DummySymbol + val FreeTerm: FreeTermExtractor = DummyFreeTermExtractor + object DummyFreeTermExtractor extends FreeTermExtractor { + def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] = notSupported() + } + type FreeType = DummyFreeType.type + val DummyFreeType = DummySymbol + val FreeType: FreeTypeExtractor = DummyFreeTypeExtractor + object DummyFreeTypeExtractor extends FreeTypeExtractor { + def unapply(freeType: FreeType): Option[(TypeName, Type, String)] = notSupported() + } + def freeTerms(tree: Tree): List[FreeTerm] = notSupported() + def freeTypes(tree: Tree): List[FreeType] = notSupported() + def substituteFreeTypes(tpe: Type,subs: Map[FreeType,Type]): Type = notSupported() + def substituteFreeTypes(tree: Tree,subs: Map[FreeType,Type]): Tree = notSupported() + + // Members declared in scala.reflect.api.Importers + def mkImporter(from0: scala.reflect.api.Universe): Importer{val from: from0.type} = notSupported() + + // Members declared in scala.reflect.api.Mirror + def classLoader: ClassLoader = cl + def classLoader_=(x$1: ClassLoader): Unit = notSupported() + def classToSymbol(clazz: Class[_]): Symbol = notSupported() + def classToType(clazz: Class[_]): Type = notSupported() + def companionInstance(clazz: Symbol): AnyRef = notSupported() + def getValueOfField(receiver: AnyRef,field: Symbol): Any = notSupported() + def invoke(receiver: AnyRef,meth: Symbol)(args: Any*): Any = notSupported() + def setValueOfField(receiver: AnyRef,field: Symbol,value: Any): Unit = notSupported() + def symbolForName(name: String): Symbol = notSupported() + def symbolOfInstance(instance: Any): Symbol = notSupported() + def symbolToClass(sym: Symbol): Class[_] = notSupported() + def typeOfInstance(instance: Any): Type = notSupported() + def typeToClass(tpe: Type): Class[_] = notSupported() + + // Members declared in scala.reflect.api.Names + type Name = DummyName.type + type TypeName = DummyName.type + type TermName = DummyName.type + object DummyName extends AbsName { + def isTermName: Boolean = notSupported() + def isTypeName: Boolean = notSupported() + def toTermName: TermName = notSupported() + def toTypeName: TypeName = notSupported() + def decoded: String = notSupported() + def encoded: String = notSupported() + def decodedName: Name = notSupported() + def encodedName: Name = notSupported() + } + def newTermName(s: String): TermName = notSupported() + def newTypeName(s: String): TypeName = notSupported() + + // Members declared in scala.reflect.api.Positions + type Position = DummyPosition.type + object DummyPosition extends api.Position { + def pos: Position = notSupported() + def withPos(newPos: scala.reflect.api.Position): Attachment = notSupported() + def payload: Any = notSupported() + def withPayload(newPayload: Any): Attachment = notSupported() + def fileInfo: java.io.File = notSupported() + def fileContent: Array[Char] = notSupported() + def isDefined: Boolean = notSupported() + def isTransparent: Boolean = notSupported() + def isRange: Boolean = notSupported() + def isOpaqueRange: Boolean = notSupported() + def makeTransparent: Position = notSupported() + def start: Int = notSupported() + def startOrPoint: Int = notSupported() + def point: Int = notSupported() + def pointOrElse(default: Int): Int = notSupported() + def end: Int = notSupported() + def endOrPoint: Int = notSupported() + def withStart(off: Int): Position = notSupported() + def withEnd(off: Int): Position = notSupported() + def withPoint(off: Int): Position = notSupported() + def union(pos: scala.reflect.api.Position): Position = notSupported() + def focusStart: Position = notSupported() + def focus: Position = notSupported() + def focusEnd: Position = notSupported() + def includes(pos: scala.reflect.api.Position): Boolean = notSupported() + def properlyIncludes(pos: scala.reflect.api.Position): Boolean = notSupported() + def precedes(pos: scala.reflect.api.Position): Boolean = notSupported() + def properlyPrecedes(pos: scala.reflect.api.Position): Boolean = notSupported() + def overlaps(pos: scala.reflect.api.Position): Boolean = notSupported() + def sameRange(pos: scala.reflect.api.Position): Boolean = notSupported() + def line: Int = notSupported() + def column: Int = notSupported() + def toSingleLine: Position = notSupported() + def lineContent: String = notSupported() + def show: String = notSupported() + } + val NoPosition: Position = DummyPosition + def atPos[T <: Tree](pos: Position)(tree: T): T = tree + def ensureNonOverlapping(tree: Tree,others: List[Tree]): Unit = notSupported() + def wrappingPos(trees: List[Tree]): Position = notSupported() + def wrappingPos(default: Position,trees: List[Tree]): Position = notSupported() + + // Members declared in scala.reflect.api.Reporters + def mkConsoleReporter(minSeverity: Int): Reporter = notSupported() + + // Members declared in scala.reflect.api.Scopes + type Scope = DummyScope.type + object DummyScope extends Iterable[Symbol] { + def iterator: Iterator[Symbol] = notSupported() + } + def newScope: Scope = DummyScope + def newScopeWith(elems: Symbol*): Scope = DummyScope + def newNestedScope(outer: Scope): Scope = DummyScope + + // Members declared in scala.reflect.api.StandardDefinitions + val AnyRefTpe: Type = DummyType + val AnyTpe: Type = DummyType + val AnyValTpe: Type = DummyType + val BooleanTpe: Type = DummyType + val ByteTpe: Type = DummyType + val CharTpe: Type = DummyType + val DoubleTpe: Type = DummyType + val FloatTpe: Type = DummyType + val IntTpe: Type = DummyType + val LongTpe: Type = DummyType + val NothingTpe: Type = DummyType + val NullTpe: Type = DummyType + val ObjectTpe: Type = DummyType + val ShortTpe: Type = DummyType + val StringTpe: Type = DummyType + val UnitTpe: Type = DummyType + val definitions: AbsDefinitions = DummyDefinitions + object DummyDefinitions extends AbsDefinitions { + def AnyClass: Symbol = DummySymbol + def AnyRefClass: Symbol = DummySymbol + def AnyValClass: Symbol = DummySymbol + def ArrayClass: Symbol = DummySymbol + def ArrayModule: Symbol = DummySymbol + def ArrayModule_overloadedApply: Symbol = DummySymbol + def Array_apply: Symbol = DummySymbol + def Array_clone: Symbol = DummySymbol + def Array_length: Symbol = DummySymbol + def Array_update: Symbol = DummySymbol + def BooleanClass: Symbol = DummySymbol + def ByNameParamClass: Symbol = DummySymbol + def ByteClass: Symbol = DummySymbol + def CharClass: Symbol = DummySymbol + def ClassClass: Symbol = DummySymbol + def ClassTagClass: Symbol = DummySymbol + def ClassTagModule: Symbol = DummySymbol + def ConcreteTypeTagClass: Symbol = DummySymbol + def ConcreteTypeTagModule: Symbol = DummySymbol + def ConsClass: Symbol = DummySymbol + def DoubleClass: Symbol = DummySymbol + def EmptyPackage: Symbol = DummySymbol + def EmptyPackageClass: Symbol = DummySymbol + def FloatClass: Symbol = DummySymbol + def FunctionClass: Array[Symbol] = Array() + def IntClass: Symbol = DummySymbol + def IterableClass: Symbol = DummySymbol + def IteratorClass: Symbol = DummySymbol + def IteratorModule: Symbol = DummySymbol + def Iterator_apply: Symbol = DummySymbol + def JavaLangPackage: Symbol = DummySymbol + def JavaLangPackageClass: Symbol = DummySymbol + def JavaRepeatedParamClass: Symbol = DummySymbol + def ListClass: Symbol = DummySymbol + def ListModule: Symbol = DummySymbol + def List_apply: Symbol = DummySymbol + def LongClass: Symbol = DummySymbol + def NilModule: Symbol = DummySymbol + def NoneModule: Symbol = DummySymbol + def NothingClass: Symbol = DummySymbol + def NullClass: Symbol = DummySymbol + def ObjectClass: Symbol = DummySymbol + def OptionClass: Symbol = DummySymbol + def PredefModule: Symbol = DummySymbol + def ProductClass: Array[Symbol] = Array() + def RepeatedParamClass: Symbol = DummySymbol + def RootClass: Symbol = DummySymbol + def RootPackage: Symbol = DummySymbol + def ScalaPackage: Symbol = DummySymbol + def ScalaPackageClass: Symbol = DummySymbol + def ScalaPrimitiveValueClasses: List[Symbol] = List() + def SeqClass: Symbol = DummySymbol + def SeqModule: Symbol = DummySymbol + def ShortClass: Symbol = DummySymbol + def SomeClass: Symbol = DummySymbol + def SomeModule: Symbol = DummySymbol + def StringBuilderClass: Symbol = DummySymbol + def StringClass: Symbol = DummySymbol + def SymbolClass: Symbol = DummySymbol + def TraversableClass: Symbol = DummySymbol + def TupleClass: Array[Symbol] = Array() + def TypeTagClass: Symbol = DummySymbol + def TypeTagModule: Symbol = DummySymbol + def UnitClass: Symbol = DummySymbol + def isNumericValueClass(sym: Symbol): Boolean = notSupported() + def isPrimitiveValueClass(sym: Symbol): Boolean = notSupported() + def vmClassType(arg: Type): Type = DummyType + def vmSignature(sym: Symbol,info: Type): String = notSupported() + } + + // Members declared in scala.reflect.api.StandardNames + val nme: AbsTermNames = DummyAbsTermNames + val tpnme: AbsTypeNames = DummyAbsTypeNames + object DummyAbsTermNames extends AbsTermNames { + type NameType = TermName + val EMPTY: NameType = DummyName + val ANON_FUN_NAME: NameType = DummyName + val ANON_CLASS_NAME: NameType = DummyName + val EMPTY_PACKAGE_NAME: NameType = DummyName + val IMPORT: NameType = DummyName + val MODULE_VAR_SUFFIX: NameType = DummyName + val ROOT: NameType = DummyName + val PACKAGE: NameType = DummyName + val SPECIALIZED_SUFFIX: NameType = DummyName + val ERROR: NameType = DummyName + val NO_NAME: NameType = DummyName + val WILDCARD: NameType = DummyName + def flattenedName(segments: Name*): NameType = notSupported() + val EXPAND_SEPARATOR_STRING: String = "" + val ANYNAME: TermName = DummyName + val CONSTRUCTOR: TermName = DummyName + val FAKE_LOCAL_THIS: TermName = DummyName + val INITIALIZER: TermName = DummyName + val LAZY_LOCAL: TermName = DummyName + val LOCAL_SUFFIX_STRING: String = "" + val MIRROR_PREFIX: TermName = DummyName + val MIRROR_SHORT: TermName = DummyName + val MIRROR_FREE_PREFIX: TermName = DummyName + val MIRROR_FREE_THIS_SUFFIX: TermName = DummyName + val MIRROR_FREE_VALUE_SUFFIX: TermName = DummyName + val MIRROR_SYMDEF_PREFIX: TermName = DummyName + val MIXIN_CONSTRUCTOR: TermName = DummyName + val MODULE_INSTANCE_FIELD: TermName = DummyName + val OUTER: TermName = DummyName + val OUTER_LOCAL: TermName = DummyName + val OUTER_SYNTH: TermName = DummyName + val SELECTOR_DUMMY: TermName = DummyName + val SELF: TermName = DummyName + val SPECIALIZED_INSTANCE: TermName = DummyName + val STAR: TermName = DummyName + val THIS: TermName = DummyName + val BITMAP_NORMAL: TermName = DummyName + val BITMAP_TRANSIENT: TermName = DummyName + val BITMAP_PRIVATE: TermName = DummyName + val BITMAP_CHECKINIT: TermName = DummyName + val BITMAP_CHECKINIT_TRANSIENT: TermName = DummyName + val INTERPRETER_IMPORT_WRAPPER: String = "" + val INTERPRETER_LINE_PREFIX: String = "" + val INTERPRETER_VAR_PREFIX: String = "" + val INTERPRETER_WRAPPER_SUFFIX: String = "" + val ROOTPKG: TermName = DummyName + val ADD: TermName = DummyName + val AND: TermName = DummyName + val ASR: TermName = DummyName + val DIV: TermName = DummyName + val EQ: TermName = DummyName + val EQL: TermName = DummyName + val GE: TermName = DummyName + val GT: TermName = DummyName + val HASHHASH: TermName = DummyName + val LE: TermName = DummyName + val LSL: TermName = DummyName + val LSR: TermName = DummyName + val LT: TermName = DummyName + val MINUS: TermName = DummyName + val MOD: TermName = DummyName + val MUL: TermName = DummyName + val NE: TermName = DummyName + val OR: TermName = DummyName + val PLUS : TermName = DummyName + val SUB: TermName = DummyName + val XOR: TermName = DummyName + val ZAND: TermName = DummyName + val ZOR: TermName = DummyName + val UNARY_~ : TermName = DummyName + val UNARY_+ : TermName = DummyName + val UNARY_- : TermName = DummyName + val UNARY_! : TermName = DummyName + val ??? : TermName = DummyName + val MODULE_SUFFIX_NAME: TermName = DummyName + val NAME_JOIN_NAME: TermName = DummyName + 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 = DummyName + def isConstructorName(name: Name): Boolean = notSupported() + def isExceptionResultName(name: Name): Boolean = notSupported() + def isImplClassName(name: Name): Boolean = notSupported() + def isLocalDummyName(name: Name): Boolean = notSupported() + def isLocalName(name: Name): Boolean = notSupported() + def isLoopHeaderLabel(name: Name): Boolean = notSupported() + def isProtectedAccessorName(name: Name): Boolean = notSupported() + def isSuperAccessorName(name: Name): Boolean = notSupported() + def isReplWrapperName(name: Name): Boolean = notSupported() + def isSetterName(name: Name): Boolean = notSupported() + def isTraitSetterName(name: Name): Boolean = notSupported() + def isSingletonName(name: Name): Boolean = notSupported() + def isModuleName(name: Name): Boolean = notSupported() + def isOpAssignmentName(name: Name): Boolean = notSupported() + def segments(name: String, assumeTerm: Boolean): List[Name] = notSupported() + def originalName(name: Name): Name = notSupported() + def stripModuleSuffix(name: Name): Name = notSupported() + def unspecializedName(name: Name): Name = notSupported() + def splitSpecializedName(name: Name): (Name, String, String) = notSupported() + def dropLocalSuffix(name: Name): Name = notSupported() + def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName = notSupported() + def expandedSetterName(name: TermName, base: Symbol): TermName = notSupported() + def protName(name: Name): TermName = notSupported() + def protSetterName(name: Name): TermName = notSupported() + def getterName(name: TermName): TermName = notSupported() + def getterToLocal(name: TermName): TermName = notSupported() + def getterToSetter(name: TermName): TermName = notSupported() + def localToGetter(name: TermName): TermName = notSupported() + def setterToGetter(name: TermName): TermName = notSupported() + def defaultGetterName(name: Name, pos: Int): TermName = notSupported() + def defaultGetterToMethod(name: Name): TermName = notSupported() + def dropSingletonName(name: Name): TypeName = notSupported() + def singletonName(name: Name): TypeName = notSupported() + def implClassName(name: Name): TypeName = notSupported() + def interfaceName(implname: Name): TypeName = notSupported() + def localDummyName(clazz: Symbol): TermName = notSupported() + def superName(name: Name): TermName = notSupported() + } + object DummyAbsTypeNames extends AbsTypeNames { + type NameType = TypeName + val EMPTY: NameType = DummyName + val ANON_FUN_NAME: NameType = DummyName + val ANON_CLASS_NAME: NameType = DummyName + val EMPTY_PACKAGE_NAME: NameType = DummyName + val IMPORT: NameType = DummyName + val MODULE_VAR_SUFFIX: NameType = DummyName + val ROOT: NameType = DummyName + val PACKAGE: NameType = DummyName + val SPECIALIZED_SUFFIX: NameType = DummyName + val ERROR: NameType = DummyName + val NO_NAME: NameType = DummyName + val WILDCARD: NameType = DummyName + def flattenedName(segments: Name*): NameType = notSupported() + val REFINE_CLASS_NAME: TypeName = DummyName + val BYNAME_PARAM_CLASS_NAME: TypeName = DummyName + val EQUALS_PATTERN_NAME: TypeName = DummyName + val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName = DummyName + val LOCAL_CHILD: TypeName = DummyName + val REPEATED_PARAM_CLASS_NAME: TypeName = DummyName + val WILDCARD_STAR: TypeName = DummyName + } + + // Members declared in scala.reflect.api.Symbols + type Symbol = DummySymbol.type + val NoSymbol: Symbol = DummySymbol + object DummySymbol extends AbsSymbol { + this: Symbol => + + def pos: Position = notSupported() + def modifiers: Set[Modifier] = notSupported() + def hasModifier(mod: Modifier): Boolean = notSupported() + def annotations: List[AnnotationInfo] = notSupported() + def hasAnnotation(sym: Symbol): Boolean = notSupported() + def owner: Symbol = notSupported() + def name: Name = notSupported() + def fullName: String = notSupported() + def id: Int = notSupported() + def orElse[T](alt: => Symbol): Symbol = notSupported() + def privateWithin: Symbol = notSupported() + def companionSymbol: Symbol = notSupported() + def moduleClass: Symbol = notSupported() + def enclosingTopLevelClass: Symbol = notSupported() + def enclosingClass: Symbol = notSupported() + def enclosingMethod: Symbol = notSupported() + def enclosingPackageClass: Symbol = notSupported() + def isTerm : Boolean = notSupported() + def isPackage : Boolean = notSupported() + def isMethod : Boolean = notSupported() + def isOverloaded : Boolean = notSupported() + def isFreeTerm : Boolean = notSupported() + def isType : Boolean = notSupported() + def isClass : Boolean = notSupported() + def isPackageClass : Boolean = notSupported() + def isPrimitiveValueClass: Boolean = notSupported() + def isDerivedValueClass: Boolean = notSupported() + def isAliasType : Boolean = notSupported() + def isAbstractType : Boolean = notSupported() + def isSkolem : Boolean = notSupported() + def isExistential : Boolean = notSupported() + def isFreeType : Boolean = notSupported() + def isContravariant : Boolean = notSupported() + def isCovariant : Boolean = notSupported() + def isErroneous : Boolean = notSupported() + def typeSignature: Type = notSupported() + def typeSignatureIn(site: Type): Type = notSupported() + def asType: Type = notSupported() + def asTypeIn(site: Type): Type = notSupported() + def asTypeConstructor: Type = notSupported() + def thisPrefix: Type = notSupported() + def selfType: Type = notSupported() + def alternatives: List[Symbol] = notSupported() + def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol = notSupported() + def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol = notSupported() + def setInternalFlags(flags: Long): this.type = notSupported() + def setTypeSignature(tpe: Type): this.type = notSupported() + def setAnnotations(annots: AnnotationInfo*): this.type = notSupported() + def kind: String = notSupported() + } + + // Members declared in scala.reflect.api.ToolBoxes + def mkToolBox(reporter: Reporter,options: String): AbsToolBox = notSupported() + + // Members declared in scala.reflect.api.TreeBuildUtil + // type TreeGen = DummyTreeGen.type // [Eugene] cannot compile if uncomment this + val gen: TreeGen{val global: DummyMirror.this.type} = DummyTreeGen.asInstanceOf[TreeGen{val global: DummyMirror.this.type}] + def modifiersFromInternalFlags(flags: Long,privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers + def newFreeExistential(name: String,info: Type,value: => Any,flags: Long,origin: String): Symbol = DummySymbol + def newFreeTerm(name: String,info: Type,value: => Any,flags: Long,origin: String): Symbol = DummySymbol + def newFreeType(name: String,info: Type,value: => Any,flags: Long,origin: String): Symbol = DummySymbol + def selectOverloadedMethod(owner: Symbol,name: String,index: Int): Symbol = DummySymbol + def selectOverloadedMethodIfDefined(owner: Symbol,name: String,index: Int): Symbol = DummySymbol + def selectTerm(owner: Symbol,name: String): Symbol = DummySymbol + def selectTermIfDefined(owner: Symbol,name: String): Symbol = DummySymbol + def selectType(owner: Symbol,name: String): Symbol = DummySymbol + def selectTypeIfDefined(owner: Symbol,name: String): Symbol = DummySymbol + def staticClass(fullName: String): Symbol = DummySymbol + def staticClassIfDefined(fullName: String): Symbol = DummySymbol + def staticModule(fullName: String): Symbol = DummySymbol + def staticModuleIfDefined(fullName: String): Symbol = DummySymbol + def thisModuleType(fullName: String): Type = DummyType + object DummyTreeGen extends AbsTreeGen { + val global: Universe = DummyMirror.this + type TreeGenTree = global.Tree + type TreeGenType = global.Type + type TreeGenSymbol = global.Symbol + def mkAttributedQualifier(tpe: TreeGenType): TreeGenTree = notSupported() + def mkAttributedQualifier(tpe: TreeGenType, termSym: TreeGenSymbol): TreeGenTree = notSupported() + def mkAttributedRef(pre: TreeGenType, sym: TreeGenSymbol): TreeGenTree = notSupported() + def mkAttributedRef(sym: TreeGenSymbol): TreeGenTree = notSupported() + def mkAttributedThis(sym: TreeGenSymbol): TreeGenTree = notSupported() + def mkAttributedIdent(sym: TreeGenSymbol): TreeGenTree = notSupported() + def mkAttributedSelect(qual: TreeGenTree, sym: TreeGenSymbol): TreeGenTree = notSupported() + } + + // Members declared in scala.reflect.api.TreePrinters + def newTreePrinter(out: java.io.PrintWriter): TreePrinter = notSupported() + + // Members declared in scala.reflect.api.Trees + def Apply(sym: Symbol,args: Tree*): Tree = Apply(EmptyTree, Nil) + def Bind(sym: Symbol,body: Tree): Bind = Bind(DummyName, EmptyTree) + def Block(stats: Tree*): Block = Block() + def CaseDef(pat: Tree,body: Tree): CaseDef = CaseDef(EmptyTree, EmptyTree, EmptyTree) + def ClassDef(sym: Symbol,impl: Template): ClassDef = ClassDef(DummyModifiers, DummyName, Nil, Template(Nil, emptyValDef, Nil)) + def DefDef(sym: Symbol,rhs: List[List[Symbol]] => Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) + def DefDef(sym: Symbol,rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) + def DefDef(sym: Symbol,mods: Modifiers,rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) + def DefDef(sym: Symbol,vparamss: List[List[ValDef]],rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) + def DefDef(sym: Symbol,mods: Modifiers,vparamss: List[List[ValDef]],rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) + def Ident(sym: Symbol): Ident = Ident(DummyName) + def Ident(name: String): Ident = Ident(DummyName) + def LabelDef(sym: Symbol,params: List[Symbol],rhs: Tree): LabelDef = LabelDef(DummyName, Nil, EmptyTree) + type Modifiers = DummyModifiers.type + val NoMods: Modifiers = DummyModifiers + object DummyModifiers extends AbsModifiers { + def modifiers: Set[Modifier] = notSupported() + def hasModifier(mod: Modifier): Boolean = notSupported() + def privateWithin: Name = notSupported() + def annotations: List[Tree] = notSupported() + def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = notSupported() + } + def Modifiers(mods: Set[scala.reflect.api.Modifier],privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers + def ModuleDef(sym: Symbol,impl: Template): ModuleDef = ModuleDef(DummyModifiers, DummyName, Template(Nil, emptyValDef, Nil)) + def New(sym: Symbol,args: Tree*): Tree = New(EmptyTree) + def New(tpe: Type,args: Tree*): Tree = New(EmptyTree) + def New(tpt: Tree,argss: List[List[Tree]]): Tree = New(EmptyTree) + def Select(qualifier: Tree,sym: Symbol): Select = Select(EmptyTree, DummyName) + def Select(qualifier: Tree,name: String): Select = Select(EmptyTree, DummyName) + def Super(sym: Symbol,mix: TypeName): Tree = Super(EmptyTree, DummyName) + def This(sym: Symbol): Tree = This(DummyName) + def Throw(tpe: Type,args: Tree*): Throw = Throw(EmptyTree) + def Try(body: Tree,cases: (Tree, Tree)*): Try = Try(EmptyTree) + def TypeDef(sym: Symbol): TypeDef = TypeDef(DummyModifiers, DummyName, Nil, EmptyTree) + def TypeDef(sym: Symbol,rhs: Tree): TypeDef = TypeDef(DummyModifiers, DummyName, Nil, EmptyTree) + def ValDef(sym: Symbol): ValDef = ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) + def ValDef(sym: Symbol,rhs: Tree): ValDef = ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) + protected def duplicateTree(tree: Tree): Tree = notSupported() + object emptyValDef extends ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) { override def isEmpty = true } + type TreeCopier = DummyTreeCopier.type + def newStrictTreeCopier: TreeCopier = DummyTreeCopier + def newLazyTreeCopier: TreeCopier = DummyTreeCopier + object DummyTreeCopier extends TreeCopierOps { + def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef = notSupported() + def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]): PackageDef = notSupported() + def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef = notSupported() + def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree): ValDef = notSupported() + def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef = notSupported() + def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree): TypeDef = notSupported() + def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef = notSupported() + def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]): Import = notSupported() + def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]): Template = notSupported() + def Block(tree: Tree, stats: List[Tree], expr: Tree): Block = notSupported() + def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree): CaseDef = notSupported() + def Alternative(tree: Tree, trees: List[Tree]): Alternative = notSupported() + def Star(tree: Tree, elem: Tree): Star = notSupported() + def Bind(tree: Tree, name: Name, body: Tree): Bind = notSupported() + def UnApply(tree: Tree, fun: Tree, args: List[Tree]): UnApply = notSupported() + def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue = notSupported() + def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function = notSupported() + def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign = notSupported() + def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree): AssignOrNamedArg = notSupported() + def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If = notSupported() + def Match(tree: Tree, selector: Tree, cases: List[CaseDef]): Match = notSupported() + def Return(tree: Tree, expr: Tree): Return = notSupported() + def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree): Try = notSupported() + def Throw(tree: Tree, expr: Tree): Throw = notSupported() + def New(tree: Tree, tpt: Tree): New = notSupported() + def Typed(tree: Tree, expr: Tree, tpt: Tree): Typed = notSupported() + def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply = notSupported() + def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply = notSupported() + def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic = notSupported() + def Super(tree: Tree, qual: Tree, mix: TypeName): Super = notSupported() + def This(tree: Tree, qual: Name): This = notSupported() + def Select(tree: Tree, qualifier: Tree, selector: Name): Select = notSupported() + def Ident(tree: Tree, name: Name): Ident = notSupported() + def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed = notSupported() + def Literal(tree: Tree, value: Constant): Literal = notSupported() + def TypeTree(tree: Tree): TypeTree = notSupported() + def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated = notSupported() + def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree = notSupported() + def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree = notSupported() + def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree = notSupported() + def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree = notSupported() + def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree): TypeBoundsTree = notSupported() + def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree = notSupported() + } + + // Members declared in scala.reflect.api.Types + type Type = DummyType.type + type SingletonType = DummyType.type + type CompoundType = DummyType.type + type AnnotatedType = DummyType.type + val AnnotatedType: AnnotatedTypeExtractor = DummyAnnotatedTypeExtractor + type BoundedWildcardType = DummyType.type + val BoundedWildcardType: BoundedWildcardTypeExtractor = DummyBoundedWildcardTypeExtractor + type ClassInfoType = DummyType.type + val ClassInfoType: ClassInfoTypeExtractor = DummyClassInfoTypeExtractor + type ConstantType = DummyType.type + val ConstantType: ConstantTypeExtractor = DummyConstantTypeExtractor + type ExistentialType = DummyType.type + val ExistentialType: ExistentialTypeExtractor = DummyExistentialTypeExtractor + type MethodType = DummyType.type + val MethodType: MethodTypeExtractor = DummyMethodTypeExtractor + val NoPrefix: Type = DummyType + val NoType: Type = DummyType + type NullaryMethodType = DummyType.type + val NullaryMethodType: NullaryMethodTypeExtractor = DummyNullaryMethodTypeExtractor + type PolyType = DummyType.type + val PolyType: PolyTypeExtractor = DummyPolyTypeExtractor + type RefinedType = DummyType.type + val RefinedType: RefinedTypeExtractor = DummyRefinedTypeExtractor + type SingleType = DummyType.type + val SingleType: SingleTypeExtractor = DummySingleTypeExtractor + type SuperType = DummyType.type + val SuperType: SuperTypeExtractor = DummySuperTypeExtractor + type ThisType = DummyType.type + val ThisType: ThisTypeExtractor = DummyThisTypeExtractor + type TypeBounds = DummyType.type + val TypeBounds: TypeBoundsExtractor = DummyTypeBoundsExtractor + type TypeRef = DummyType.type + val TypeRef: TypeRefExtractor = DummyTypeRefExtractor + val WildcardType: Type = DummyType + def appliedType(tycon: Type,args: List[Type]): Type = DummyType + def existentialAbstraction(tparams: List[Symbol],tpe0: Type): Type = DummyType + def glb(ts: List[Type]): Type = DummyType + def intersectionType(tps: List[Type],owner: Symbol): Type = DummyType + def intersectionType(tps: List[Type]): Type = DummyType + def lub(xs: List[Type]): Type = DummyType + def polyType(tparams: List[Symbol],tpe: Type): Type = DummyType + def refinedType(parents: List[Type],owner: Symbol): Type = DummyType + def refinedType(parents: List[Type],owner: Symbol,decls: Scope,pos: Position): Type = DummyType + def singleType(pre: Type,sym: Symbol): Type = DummyType + def typeRef(pre: Type,sym: Symbol,args: List[Type]): Type = DummyType + object DummyType extends AbsType { + def =:=(that: Type): Boolean = notSupported() + def <:<(that: Type): Boolean = notSupported() + def asSeenFrom(pre: Type,clazz: Symbol): Type = notSupported() + def baseClasses: List[Symbol] = notSupported() + def baseType(clazz: Symbol): Type = notSupported() + def contains(sym: Symbol): Boolean = notSupported() + def declaration(name: Name): Symbol = notSupported() + def declarations: Iterable[Symbol] = notSupported() + def erasure: Type = notSupported() + def exists(p: Type => Boolean): Boolean = notSupported() + def find(p: Type => Boolean): Option[Type] = notSupported() + def foreach(f: Type => Unit): Unit = notSupported() + def isConcrete: Boolean = notSupported() + def isHigherKinded: Boolean = notSupported() + def isSpliceable: Boolean = notSupported() + def kind: String = notSupported() + def map(f: Type => Type): Type = notSupported() + def member(name: Name): Symbol = notSupported() + def members: Iterable[Symbol] = notSupported() + def nonPrivateMember(name: Name): Symbol = notSupported() + def nonPrivateMembers: Iterable[Symbol] = notSupported() + def normalize: Type = notSupported() + def parents: List[Type] = notSupported() + def substituteTypes(from: List[Symbol],to: List[Type]): Type = notSupported() + def typeArguments: List[Type] = notSupported() + def typeConstructor: Type = notSupported() + def typeParams: List[Symbol] = notSupported() + def typeSymbol: Symbol = notSupported() + def underlying: Type = notSupported() + def widen: Type = notSupported() + } + object DummyAnnotatedTypeExtractor extends AnnotatedTypeExtractor { + def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType = DummyType + def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)] = notSupported() + } + object DummyBoundedWildcardTypeExtractor extends BoundedWildcardTypeExtractor { + def apply(bounds: TypeBounds): BoundedWildcardType = DummyType + def unapply(tpe: BoundedWildcardType): Option[TypeBounds] = notSupported() + } + object DummyClassInfoTypeExtractor extends ClassInfoTypeExtractor { + def apply(parents: List[Type], decls: Scope, clazz: Symbol): ClassInfoType = DummyType + def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)] = notSupported() + } + object DummyConstantTypeExtractor extends ConstantTypeExtractor { + def apply(value: Constant): ConstantType = DummyType + def unapply(tpe: ConstantType): Option[Constant] = notSupported() + } + object DummyExistentialTypeExtractor extends ExistentialTypeExtractor { + def apply(quantified: List[Symbol], underlying: Type): ExistentialType = DummyType + def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)] = notSupported() + } + object DummyMethodTypeExtractor extends MethodTypeExtractor { + def apply(params: List[Symbol], resultType: Type): MethodType = DummyType + def unapply(tpe: MethodType): Option[(List[Symbol], Type)] = notSupported() + } + object DummyNullaryMethodTypeExtractor extends NullaryMethodTypeExtractor { + def apply(resultType: Type): NullaryMethodType = DummyType + def unapply(tpe: NullaryMethodType): Option[(Type)] = notSupported() + } + object DummyPolyTypeExtractor extends PolyTypeExtractor { + def apply(typeParams: List[Symbol], resultType: Type): PolyType = DummyType + def unapply(tpe: PolyType): Option[(List[Symbol], Type)] = notSupported() + } + object DummyRefinedTypeExtractor extends RefinedTypeExtractor { + def apply(parents: List[Type], decls: Scope): RefinedType = DummyType + def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType = DummyType + def unapply(tpe: RefinedType): Option[(List[Type], Scope)] = notSupported() + } + object DummySingleTypeExtractor extends SingleTypeExtractor { + def apply(pre: Type, sym: Symbol): Type = DummyType + def unapply(tpe: SingleType): Option[(Type, Symbol)] = notSupported() + } + object DummySuperTypeExtractor extends SuperTypeExtractor { + def apply(thistpe: Type, supertpe: Type): Type = DummyType + def unapply(tpe: SuperType): Option[(Type, Type)] = notSupported() + } + object DummyThisTypeExtractor extends ThisTypeExtractor { + def apply(sym: Symbol): Type = DummyType + def unapply(tpe: ThisType): Option[Symbol] = notSupported() + } + object DummyTypeBoundsExtractor extends TypeBoundsExtractor { + def apply(lo: Type, hi: Type): TypeBounds = DummyType + def unapply(tpe: TypeBounds): Option[(Type, Type)] = notSupported() + } + object DummyTypeRefExtractor extends TypeRefExtractor { + def apply(pre: Type, sym: Symbol, args: List[Type]): Type = DummyType + def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])] = notSupported() + } + + // Utils + def notSupported() = { + throw new UnsupportedOperationException("Scala reflection not available on this platform." + mirrorDiagnostics(cl)) + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index 85755cd2f2..f7c4c63e94 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -67,9 +67,13 @@ trait TypeTags { self: Universe => def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe) override def toString = { - var prefix = if (isConcrete) "ConcreteTypeTag" else "TypeTag" - if (prefix != this.productPrefix) prefix = "*" + prefix - prefix + "[" + tpe + "]" + if (!self.isInstanceOf[DummyMirror]) { + var prefix = if (isConcrete) "ConcreteTypeTag" else "TypeTag" + if (prefix != this.productPrefix) prefix = "*" + prefix + prefix + "[" + tpe + "]" + } else { + this.productPrefix + "[?]" + } } } @@ -121,10 +125,12 @@ trait TypeTags { self: Universe => */ @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}") abstract class ConcreteTypeTag[T](tpe: Type, val erasure: jClass[_]) 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 (notConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind)) + if (!self.isInstanceOf[DummyMirror]) { +// 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 (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/package.scala b/src/library/scala/reflect/package.scala index 93fd0bb711..0958f2ce9a 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -11,18 +11,19 @@ package object reflect { // initialization, but in response to a doomed attempt to utilize it. // 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) + lazy val mirror: api.Mirror = + try mkMirror(defaultReflectionClassLoader) + catch { + case ex: UnsupportedOperationException => + new DummyMirror(defaultReflectionClassLoader) + } - private def mirrorDiagnostics(cl: ClassLoader): String = """ + private[scala] def mirrorDiagnostics(cl: ClassLoader): String = """ | | This error has happened because `scala.reflect.runtime.package` located in | scala-compiler.jar cannot be loaded. Classloader you are using is: | %s. | - | In Scala 2.10.0 M3, scala-compiler.jar is required to be on the classpath - | for manifests and type tags to function. This will change in the final release, - | but for now you need to adjust your scripts or the build system to proceed. - | | For the instructions for some of the situations that might be relevant | visit our knowledge base at https://gist.github.com/2391081. """.stripMargin('|').format(show(cl)) -- cgit v1.2.3 From 40c1fe388be22c0ea9c68afcb08b41b69148026e Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sun, 15 Apr 2012 22:27:42 +0200 Subject: assorted stability fixes --- .../scala/reflect/internal/StdAttachments.scala | 12 + .../scala/reflect/internal/SymbolTable.scala | 1 + .../scala/reflect/makro/runtime/Enclosures.scala | 2 +- .../scala/reflect/makro/runtime/Typers.scala | 10 +- .../scala/reflect/reify/codegen/Symbols.scala | 23 +- src/compiler/scala/tools/nsc/Global.scala | 14 +- .../doc/model/ModelFactoryImplicitSupport.scala | 1 + .../scala/tools/nsc/typechecker/Implicits.scala | 5 +- .../scala/tools/nsc/typechecker/Macros.scala | 730 +++++++++++---------- .../scala/tools/nsc/typechecker/Typers.scala | 8 +- src/library/scala/reflect/api/Attachment.scala | 9 +- src/library/scala/reflect/api/Trees.scala | 43 +- ...and-implicit-macro-defeats-type-inference.check | 6 + ...and-implicit-macro-defeats-type-inference.flags | 1 + .../Impls_1.scala | 10 + .../Macros_Test_2.scala | 6 + 16 files changed, 510 insertions(+), 371 deletions(-) create mode 100644 src/compiler/scala/reflect/internal/StdAttachments.scala create mode 100644 test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check create mode 100644 test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags create mode 100644 test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala create mode 100644 test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/StdAttachments.scala b/src/compiler/scala/reflect/internal/StdAttachments.scala new file mode 100644 index 0000000000..488195b7dd --- /dev/null +++ b/src/compiler/scala/reflect/internal/StdAttachments.scala @@ -0,0 +1,12 @@ +package scala.reflect +package internal + +import scala.reflect.makro.runtime.{Context => MacroContext} + +trait StdAttachments { + self: SymbolTable => + + case class ReifyAttachment(original: Symbol) + + case class MacroAttachment(delayed: Boolean, context: Option[MacroContext]) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 0268339ed0..0688d13ae5 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -38,6 +38,7 @@ abstract class SymbolTable extends api.Universe with TreeBuildUtil with Reporters with CapturedVariables + with StdAttachments { def rootLoader: LazyType def log(msg: => AnyRef): Unit diff --git a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala index f9a6987e48..72e9e568c0 100644 --- a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala +++ b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala @@ -11,7 +11,7 @@ trait Enclosures { val macroApplication: Tree = expandee - val enclosingMacros: List[Context] = this :: mirror.analyzer.openMacros + val enclosingMacros: List[Context] = this :: mirror.analyzer.openMacros // include self val enclosingImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala index b32d4fb7b1..98dbd65b72 100644 --- a/src/compiler/scala/reflect/makro/runtime/Typers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala @@ -4,9 +4,9 @@ package runtime trait Typers { self: Context => - val openMacros: List[Context] = this :: mirror.analyzer.openMacros + def openMacros: List[Context] = this :: mirror.analyzer.openMacros - val openImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits + def 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) @@ -34,7 +34,7 @@ trait Typers { 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 context = callsiteTyper.context.makeImplicit(true) + val context = callsiteTyper.context val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) def wrapper (inference: => SearchResult) = wrapper1(inference) wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, pt, true, false, context, !silent, pos)) match { @@ -51,12 +51,12 @@ trait Typers { 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 context = callsiteTyper.context.makeImplicit(reportAmbiguous) + val context = callsiteTyper.context val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (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)) - wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match { + wrapper(mirror.analyzer.inferImplicit(tree, 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) diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala index 0513f99366..7f8b9c53b6 100644 --- a/src/compiler/scala/reflect/reify/codegen/Symbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala @@ -105,9 +105,9 @@ trait Symbols { filledIn = false newSymbolTable foreach { case entry => - val att = entry.attachment + val att = entry.attachmentOpt[ReifyAttachment] att match { - case sym: Symbol => + case Some(ReifyAttachment(sym)) => // don't duplicate reified symbols when merging inlined reifee if (!(locallyReified contains sym)) { val ValDef(_, name, _, _) = entry @@ -134,7 +134,7 @@ trait Symbols { // 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 + val local = ValDef(NoMods, name, TypeTree(), reified) withAttachment ReifyAttachment(sym) localReifications += local filledIn = false locallyReified(sym) = Ident(name) @@ -149,8 +149,9 @@ trait Symbols { 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) + val att = reified.attachmentOpt[ReifyAttachment] + att match { + case Some(ReifyAttachment(sym)) => fillIns += fillInSymbol(sym) case other => // do nothing } i += 1 @@ -169,9 +170,15 @@ trait Symbols { 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(reify(sym.info))) - if (sym.annotations.isEmpty) rset - else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations))) + import scala.reflect.internal.Flags._ + if (sym hasFlag LOCKED) { + // [Eugene] better to have a symbol without a type signature, than to crash with a CyclicReference + EmptyTree + } else { + val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reify(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/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 73c68f44d4..c9394b37b5 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -8,7 +8,6 @@ package scala.tools.nsc import java.io.{ File, FileOutputStream, PrintWriter, IOException, FileNotFoundException } import java.nio.charset.{ Charset, CharsetDecoder, IllegalCharsetNameException, UnsupportedCharsetException } import compat.Platform.currentTime - import scala.tools.util.{ Profiling, PathResolver } import scala.collection.{ mutable, immutable } import io.{ SourceReader, AbstractFile, Path } @@ -16,7 +15,6 @@ 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 } - import symtab.{ Flags, SymbolTable, SymbolLoaders, SymbolTrackers } import symtab.classfile.Pickler import dependencies.DependencyAnalysis @@ -25,13 +23,13 @@ import ast._ import ast.parser._ import typechecker._ import transform._ - import backend.icode.{ ICodes, GenICode, ICodeCheckers } import backend.{ ScalaPrimitives, Platform, MSILPlatform, JavaPlatform } import backend.jvm.GenJVM import backend.opt.{ Inliners, InlineExceptionHandlers, ClosureElimination, DeadCodeElimination } import backend.icode.analysis._ import language.postfixOps +import reflect.internal.StdAttachments class Global(var currentSettings: Settings, var reporter: NscReporter) extends SymbolTable with ClassLoaders @@ -135,6 +133,16 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S infolevel = InfoLevel.Verbose } + def withInfoLevel[T](infolevel: nodePrinters.InfoLevel.Value)(op: => T) = { + val saved = nodePrinters.infolevel + try { + nodePrinters.infolevel = infolevel + op + } finally { + nodePrinters.infolevel = saved + } + } + /** Representing ASTs as graphs */ object treeBrowsers extends { val global: Global.this.type = Global.this diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 0e44933ac6..4e03dc8788 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -246,6 +246,7 @@ trait ModelFactoryImplicitSupport { val appliedTree = new ApplyImplicitView(viewTree, List(Ident("") setType viewTree.tpe.paramTypes.head)) val appliedTreeTyped: Tree = { val newContext = context.makeImplicit(context.ambiguousErrors) + newContext.macrosEnabled = false // [Eugene] I assume you want macro signature, not macro expansion val newTyper = global.analyzer.newTyper(newContext) newTyper.silent(_.typed(appliedTree, global.analyzer.EXPRmode, WildcardType), false) match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 30a79917c9..651120db4f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -32,10 +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, NoPosition) + inferImplicit(tree, pt, reportAmbiguous, isView, context, true, tree.pos) def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean): SearchResult = - inferImplicit(tree, pt, reportAmbiguous, isView, context, saveAmbiguousDivergent, NoPosition) + inferImplicit(tree, pt, reportAmbiguous, isView, context, saveAmbiguousDivergent, tree.pos) /** Search for an implicit value. See the comment on `result` at the end of class `ImplicitSearch` * for more info how the search is conducted. @@ -633,6 +633,7 @@ trait Implicits { else { val subst = new TreeTypeSubstituter(okParams, okArgs) subst traverse itree2 + notifyUndetparamsInferred(okParams, okArgs) subst } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 62a0e08aad..539ddfb19c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -294,6 +294,8 @@ trait Macros { self: Analyzer => } finally { openMacros = openMacros.tail } + case Delay(result) => + result case Fallback(fallback) => typer.typed1(fallback, EXPRmode, WildcardType) case Other(result) => @@ -641,139 +643,147 @@ trait Macros { self: Analyzer => * @return Some(runtime) if macro implementation can be loaded successfully from either of the mirrors, * None otherwise. */ - 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 _ => "" + private type MacroRuntime = List[Any] => Any + private val macroRuntimesCache = perRunCaches.newWeakMap[Symbol, Option[MacroRuntime]] + private def macroRuntime(macroDef: Symbol): Option[MacroRuntime] = + macroRuntimesCache.getOrElseUpdate(macroDef, { + val runtime = { + 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 } - macroTrace("classpath is: ")(inferClasspath(macroMirror.classLoader)) - - // [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 => - val suffix = if (sym.isModuleClass) "$" else "" - sym.fullName + suffix - case sym => - val separator = if (sym.owner.isModuleClass) "" else "$" - recur(sym.owner) + separator + sym.javaSimpleName.toString - } - if (sym.isClass || sym.isModule) recur(sym) - else recur(sym.enclClass) + 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 } - // [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 (macroDebug) { - println("implClassSymbol is: " + implClassSymbol.fullNameString) - - 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))) - } + 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 } - val implObjSymbol = implClassSymbol.companionModule - macroTrace("implObjSymbol is: ")(implObjSymbol.fullNameString) + 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 _ => "" + } + macroTrace("classpath is: ")(inferClasspath(macroMirror.classLoader)) + + // [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 => + val suffix = if (sym.isModuleClass) "$" else "" + sym.fullName + suffix + case sym => + val separator = if (sym.owner.isModuleClass) "" else "$" + recur(sym.owner) + separator + sym.javaSimpleName.toString + } - if (implObjSymbol == macroMirror.NoSymbol) None - else { - // 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 (sym.isClass || sym.isModule) recur(sym) + else recur(sym.enclClass) + } + + // [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 (implObj == null) None - else { - val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString)) if (macroDebug) { - println("implMethSymbol is: " + implMethSymbol.fullNameString) - println("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol)) + println("implClassSymbol is: " + implClassSymbol.fullNameString) + + 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))) + } } - if (implMethSymbol == macroMirror.NoSymbol) None + val implObjSymbol = implClassSymbol.companionModule + macroTrace("implObjSymbol is: ")(implObjSymbol.fullNameString) + + if (implObjSymbol == macroMirror.NoSymbol) None else { - if (macroDebug) println("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol)) - Some((implObj, implMethSymbol)) + // 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 (implObj == null) None + else { + 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 => - macroTrace("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 => + 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 - } - } else { - None + } } - } - } + } + + if (runtime == None) macroDef setFlag IS_ERROR + runtime + }) /** 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 } = @@ -784,7 +794,7 @@ trait Macros { self: Analyzer => 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 */) + override def toString = "MacroContext(%s@%s +%d)".format(expandee.symbol.name, expandee.pos, enclosingMacros.length - 1 /* exclude myself */) } /** Calculate the arguments to pass to a macro implementation when expanding the provided tree. @@ -795,6 +805,10 @@ trait Macros { self: Analyzer => * @return list of runtime objects to pass to the implementation obtained by ``macroRuntime'' */ private def macroArgs(typer: Typer, expandee: Tree): Option[List[Any]] = { + val macroDef = expandee.symbol + val runtime = macroRuntime(macroDef) + if (runtime == None) return None + var prefixTree: Tree = EmptyTree var typeArgs = List[Tree]() val exprArgs = new ListBuffer[List[Expr[_]]] @@ -811,11 +825,10 @@ trait Macros { self: Analyzer => case _ => } collectMacroArgs(expandee) - val context = macroContext(typer, prefixTree, expandee) + val context = expandee.attachmentOpt[MacroAttachment].flatMap(_.context).getOrElse(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 @@ -923,62 +936,92 @@ trait Macros { self: Analyzer => * 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 { - 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 - } - 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 _ => ; - } + def macroExpand(typer: Typer, expandee: Tree, mode: Int = EXPRmode, pt: Type = WildcardType): Tree = { + val start = startTimer(macroExpandNanos) + incCounter(macroExpandCount) + try { + macroExpand1(typer, expandee) match { + case Success(expanded) => + try { + var expectedTpe = expandee.tpe + + // [Eugene] weird situation. what's the conventional way to deal with it? + val isNullaryInvocation = expandee match { + case TypeApply(Select(_, _), _) => true + case TypeApply(Ident(_), _) => true + case Select(_, _) => true + case Ident(_) => true + case _ => false + } + if (isNullaryInvocation) expectedTpe match { + case NullaryMethodType(restpe) => + macroTrace("nullary invocation of a nullary method. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) + expectedTpe = restpe + 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)) - } + def fail(what: String): Tree = { + val err = typer.context.errBuffer.head + this.fail(typer, expanded, "failed to perform %s: %s at %s".format(what, err.errMsg, err.errPos)) + return expandee + } - typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt)) - if (macroDebug) { - println("typechecked2:") - println(typechecked) - println(showRaw(typechecked)) - } + if (macroDebug) println("typechecking1 against %s: %s".format(expectedTpe, expanded)) + var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe)) + if (typer.context.hasErrors) fail("typecheck1") + if (macroDebug) { + println("typechecked1:") + println(typechecked) + println(showRaw(typechecked)) + } - typechecked - } finally { - openMacros = openMacros.tail - } - case Fallback(fallback) => - typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt)) - case Other(result) => - result + if (macroDebug) println("typechecking2 against %s: %s".format(pt, expanded)) + typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt)) + if (typer.context.hasErrors) fail("typecheck2") + if (macroDebug) { + println("typechecked2:") + println(typechecked) + println(showRaw(typechecked)) + } + + typechecked + } finally { + openMacros = openMacros.tail + } + case Delay(expandee) => + // need to save the context to preserve enclosures + val args = macroArgs(typer, expandee) + assert(args.isDefined, expandee) + val context = args.get.head.asInstanceOf[MacroContext] + var result = expandee withAttachment MacroAttachment(delayed = true, context = Some(context)) + // adapting here would be premature, we must wait until undetparams are inferred +// result = typer.adapt(result, mode, pt) + result + case Fallback(fallback) => + typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt)) + case Other(result) => + result + } + } finally { + stopTimer(macroExpandNanos, start) } + } 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 Delay(expandee: 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)) + if (macroDebug) 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) @@ -989,191 +1032,200 @@ trait Macros { self: Analyzer => /** 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)) - } + private def macroExpand1(typer: Typer, expandee: Tree): MacroExpansionResult = + // 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 + withInfoLevel(nodePrinters.InfoLevel.Quiet) { + // 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)) + macroRuntime(expandee.symbol) match { + case Some(runtime) => + macroExpandWithRuntime(typer, expandee, runtime) + case None => + macroExpandWithoutRuntime(typer, expandee) + } + } + /** Expands a macro when a runtime (i.e. the macro implementation) can be successfully loaded + * Meant for internal use within the macro infrastructure, don't use it elsewhere. + */ + private def macroExpandWithRuntime(typer: Typer, expandee: Tree, runtime: MacroRuntime): MacroExpansionResult = + try { + val wasDelayed = isDelayed(expandee) val undetparams = calculateUndetparams(expandee) - if (undetparams.size != 0) { - macroTrace("macro expansion is delayed: ")(expandee) - delayed += expandee -> (typer.context, undetparams) - Delay(expandee) - } else { - 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 nowDelayed = !typer.context.macrosEnabled || undetparams.size != 0 + + if (!wasDelayed) { + if (macroDebug || macroCopypaste) println("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) + if (nowDelayed) { + if (macroDebug || macroCopypaste) println("macro expansion is delayed: %s".format(expandee)) + delayed += expandee -> (typer.context, undetparams) + Delay(expandee) + } else { + 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 + expandee.detach(null) + 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) // errors have been reported by the macro itself + fail(typer, expandee) } 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) - } + // 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) } - } 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 + 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 => - // [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 ex: Throwable => + openMacros = openMacros.tail + throw ex } + if (!expanded.isInstanceOf[Success]) openMacros = openMacros.tail + expanded 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) - } + fail(typer, expandee) // error has been reported by macroArgs } - } finally { - stopTimer(macroExpandNanos, start) } + } else { + if (nowDelayed) + Delay(expandee) + else + Skip(macroExpandAll(typer, expandee)) } - } else { - val undetparams = calculateUndetparams(expandee) - if (undetparams.size != 0) - Delay(expandee) - else - Skip(macroExpandAll(typer, expandee)) + } catch { + case ex => handleMacroExpansionException(typer, expandee, ex) + } finally { + expandee.detach(classOf[MacroAttachment]) + } + + private def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroExpansionResult = { + val macroDef = expandee.symbol + 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) + } + } + + private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = { + // [Eugene] any ideas about how to improve this one? + val realex = ReflectionUtils.unwrapThrowable(ex) + realex match { + case realex: reflect.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 err: TypeError => + if (macroDebug || macroCopypaste) println("macro expansion has failed: %s at %s".format(err.msg, err.pos)) + throw err // error should be propagated, don't report + case _ => + val message = { + try { + // [Eugene] is there a better way? + val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == "macroExpand1") + 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) } } @@ -1194,18 +1246,23 @@ trait Macros { self: Analyzer => 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]() + val calculated = collection.mutable.Set[Symbol]() expandee foreach (sub => { - def traverse(sym: Symbol) = if (sym != null && (undetparams contains sym.id)) calculated += sym.id + def traverse(sym: Symbol) = if (sym != null && (undetparams contains sym.id)) calculated += sym if (sub.symbol != null) traverse(sub.symbol) if (sub.tpe != null) sub.tpe foreach (sub => traverse(sub.typeSymbol)) }) - calculated + if (macroDebug) println("calculateUndetparams: %s".format(calculated)) + calculated map (_.id) } private val undetparams = perRunCaches.newSet[Int] - def notifyUndetparamsAdded(newUndets: List[Symbol]): Unit = undetparams ++= newUndets map (_.id) + def notifyUndetparamsAdded(newUndets: List[Symbol]): Unit = { + undetparams ++= newUndets map (_.id) + if (macroDebug) newUndets foreach (sym => println("undetParam added: %s".format(sym))) + } def notifyUndetparamsInferred(undetNoMore: List[Symbol], inferreds: List[Type]): Unit = { undetparams --= undetNoMore map (_.id) + if (macroDebug) (undetNoMore zip inferreds) foreach {case (sym, tpe) => println("undetParam inferred: %s as %s".format(sym, tpe))} if (!delayed.isEmpty) delayed.toList foreach { case (expandee, (_, undetparams)) if !undetparams.isEmpty => @@ -1230,7 +1287,10 @@ trait Macros { self: Analyzer => case wannabe if (delayed contains wannabe) && calculateUndetparams(wannabe).isEmpty => val (context, _) = delayed(wannabe) delayed -= wannabe - macroExpand(newTyper(context), wannabe, WildcardType) + context.implicitsEnabled = typer.context.implicitsEnabled + context.enrichmentEnabled = typer.context.enrichmentEnabled + context.macrosEnabled = typer.context.macrosEnabled + macroExpand(newTyper(context), wannabe, EXPRmode, WildcardType) case _ => tree }) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 8f5b3fb519..9a59d8f28a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1082,10 +1082,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } if (tree.isType) adaptType() - 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 ( + inExprModeButNot(mode, FUNmode) && !tree.isDef && // typechecking application + tree.symbol != null && tree.symbol.isTermMacro) // of a macro + macroExpand(this, tree, mode, pt) else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode)) adaptConstrPattern() else if (inAllModes(mode, EXPRmode | FUNmode) && diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala index 9fa5ceb0fb..50f55b4aa5 100644 --- a/src/library/scala/reflect/api/Attachment.scala +++ b/src/library/scala/reflect/api/Attachment.scala @@ -7,8 +7,6 @@ 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 @@ -22,3 +20,10 @@ trait Attachment { /** Creates a copy of this attachment with its payload updated */ def withPayload(newPayload: Any): Attachment } + +// [Eugene] with the introduction of `attach` and `attachment[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 +private[scala] case class NontrivialAttachment(pos: api.Position, payload: collection.mutable.ListBuffer[Any]) extends Attachment { + def withPos(newPos: api.Position) = copy(pos = newPos, payload = payload) + def withPayload(newPayload: Any) = copy(pos = pos, payload = newPayload.asInstanceOf[collection.mutable.ListBuffer[Any]]) +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 7548a6bdc0..6e2e8261e7 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -85,18 +85,39 @@ 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 } + // [Eugene] can we make this more type-safe 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 } + def attach(att: Any): Unit = + rawatt match { + case NontrivialAttachment(pos, payload) => + val index = payload.indexWhere(p => p.getClass == att.getClass) + if (index == -1) payload += att + else payload(index) = att + case _ => + rawatt = NontrivialAttachment(pos, collection.mutable.ListBuffer[Any](att)) + } + def withAttachment(att: Any): this.type = { attach(att); this } + def detach(att: Any): Unit = + detach(att.getClass) + def detach(clazz: java.lang.Class[_]): Unit = + rawatt match { + case NontrivialAttachment(pos, payload) => + val index = payload.indexWhere(p => p.getClass == clazz) + if (index != -1) payload.remove(index) + case _ => + // do nothing + } + def withoutAttachment(att: Any): this.type = { detach(att); this } + def attachment[T: ClassTag]: T = attachmentOpt[T] getOrElse { throw new Error("no attachment of type %s".format(classTag[T].erasure)) } + def attachmentOpt[T: ClassTag]: Option[T] = + rawatt match { + case NontrivialAttachment(pos, payload) => + val index = payload.indexWhere(p => p.getClass == classTag[T].erasure) + if (index != -1) Some(payload(index).asInstanceOf[T]) + else None + case _ => + None + } private[this] var rawtpe: Type = _ diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check new file mode 100644 index 0000000000..08f7cb9e3e --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check @@ -0,0 +1,6 @@ +openImplicits are: List() +enclosingImplicits are: List((List[Int],scala.this.Predef.implicitly[List[Int]])) +typetag is: ConcreteTypeTag[Nothing] +openImplicits are: List() +enclosingImplicits are: List((List[String],Test.this.bar[String])) +typetag is: ConcreteTypeTag[Nothing] diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala new file mode 100644 index 0000000000..c096a83c5e --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.Context + +object Impls { + def foo[T: c.TypeTag](c: Context): c.Expr[List[T]] = c.reify { + println("openImplicits are: " + c.literal(c.openImplicits.toString).eval) + println("enclosingImplicits are: " + c.literal(c.enclosingImplicits.toString).eval) + println("typetag is: " + c.literal(c.tag[T].toString).eval) + null + } +} \ No newline at end of file diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala new file mode 100644 index 0000000000..27d0662799 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + implicit def foo[T]: List[T] = macro Impls.foo[T] + def bar[T](implicit foo: List[T]) {} + implicitly[List[Int]] + bar[String] +} \ No newline at end of file -- cgit v1.2.3 From 2093bccc56cbfb77dbcb6e8e3224d2416feb39fb Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 17 Apr 2012 12:26:18 +0200 Subject: reintroduces prematurely removed manifest factories --- src/library/scala/reflect/ClassTag.scala | 135 ++++++++++++++++++--------- src/library/scala/reflect/api/TypeTags.scala | 45 ++++++++- 2 files changed, 134 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index fe8a16a484..06960a5478 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -122,51 +122,96 @@ object ClassTag { else ClassTag[T](ttag.tpe) 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) + /** Manifest for the singleton type `value.type'. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = ??? + + /** 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) + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T <: AnyRef](clazz: jClass[_]): ClassManifest[T] = ClassTag[T](clazz) + + /** ClassManifest for the class type `clazz[args]', where `clazz' is + * a top-level or static class and `args` are its type arguments */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T <: AnyRef](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](clazz) + + /** ClassManifest for the class type `clazz[args]', where `clazz' is + * a class with non-package prefix type `prefix` and type arguments `args`. + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T <: AnyRef](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](clazz) + + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match { + case x: ConcreteTypeTag[_] => ClassManifest[Array[T]](x.erasure) + case _ => Object.asInstanceOf[ClassManifest[Array[T]]] // was there in 2.9.x + } - @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() + /** 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. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def abstractType[T](prefix: OptManifest[_], name: String, clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](clazz) + + /** 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 + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def abstractType[T](prefix: OptManifest[_], name: String, upperbound: ClassManifest[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](upperbound.erasure) + + 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() + } } + diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index f7c4c63e94..b90475b15a 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -180,7 +180,7 @@ trait TypeTags { self: Universe => 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.ConcreteTypeTag[T]) extends DeprecatedClassManifestApis[T](toClassTag(ttag)) { + class DeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]) extends ClassTag.DeprecatedClassManifestApis[T](toClassTag(ttag)) { @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") def <:<(that: Manifest[_]): Boolean = ttag.tpe <:< that.tpe @@ -190,6 +190,49 @@ trait TypeTags { self: Universe => @deprecated("Use `tpe` to analyze the type arguments", "2.10.0") override def typeArguments: List[Manifest[_]] = ttag.tpe.typeArguments map (targ => rm.ConcreteTypeTag(targ)) } + + /** Manifest for the singleton type `value.type'. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = Manifest[T](???, value.getClass) + + /** 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) + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T](clazz: Predef.Class[_]): Manifest[T] = Manifest[T](???, clazz) + + /** Manifest for the class type `clazz', where `clazz' is + * a top-level or static class and args are its type arguments. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = Manifest[T](???, clazz) + + /** Manifest for the class type `clazz[args]', where `clazz' is + * a class with non-package prefix type `prefix` and type arguments `args`. + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = Manifest[T](???, clazz) + + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = Manifest[Array[T]](???, arg.asInstanceOf[Manifest[T]].arrayManifest.erasure) + + /** 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. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def abstractType[T](prefix: Manifest[_], name: String, clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = Manifest[T](???, clazz) + + /** Manifest for the unknown type `_ >: L <: U' in an existential. + */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = Manifest[T](???, upperBound.erasure) + + /** Manifest for the intersection type `parents_0 with ... with parents_n'. */ + @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") + def intersectionType[T](parents: Manifest[_]*): Manifest[T] = Manifest[T](???, parents.head.erasure) } // incantations for summoning -- cgit v1.2.3 From 745fe4e36631f86665eb1bef9cb22e6623894a56 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 17 Apr 2012 22:49:07 +0200 Subject: fixes tests --- src/compiler/scala/reflect/makro/runtime/Reifiers.scala | 2 +- test/files/jvm/interpreter.check | 5 ++--- test/files/run/existentials3.check | 16 ++++++++-------- 3 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala index 3586adc590..7c96b568bd 100644 --- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -27,7 +27,7 @@ trait Reifiers { def reifyErasure(tpe: Type): Tree = { val positionBearer = enclosingMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] - val typetagInScope = callsiteTyper.context.withMacrosDisabled(callsiteTyper.resolveTypeTag(positionBearer, gen.mkAttributedRef(Reflect_mirror).tpe, tpe, full = true)) + val typetagInScope = callsiteTyper.context.withMacrosDisabled(callsiteTyper.resolveTypeTag(positionBearer, singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror), tpe, full = true)) 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) => diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index 85ec46c5f5..dc835bf8b6 100644 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -316,9 +316,8 @@ scala> /* */ */ -scala> -scala> +You typed two blank lines. Starting a new command. scala> // multi-line string @@ -326,7 +325,7 @@ scala> """ hello there """ -res9: String = +res12: String = " hello there diff --git a/test/files/run/existentials3.check b/test/files/run/existentials3.check index 85bc430a21..e2c9382ab4 100644 --- a/test/files/run/existentials3.check +++ b/test/files/run/existentials3.check @@ -1,24 +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[Bar.type], t=AbstractTypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton +ConcreteTypeTag[Bar], t=AbstractTypeRef, 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[$anon], t=AbstractTypeRef, s= <: B with Test.ToS +ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with A with Test.ToS TypeTag[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[Bar.type], t=AbstractTypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton +ConcreteTypeTag[Bar], t=AbstractTypeRef, 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[$anon], t=AbstractTypeRef, s= <: B with Test.ToS +ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with A with Test.ToS TypeTag[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 -- cgit v1.2.3 From 8a285258fdb37af9f4ba8ced0a5c8fb6fefbf62c Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 18 Apr 2012 11:29:42 +0100 Subject: Sigh, sbt needs this one too. --- src/compiler/scala/tools/nsc/CompilationUnits.scala | 2 +- src/compiler/scala/tools/nsc/Global.scala | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index f89f278338..2f1e15168a 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -88,7 +88,7 @@ trait CompilationUnits { self: Global => reporter.warning(pos, msg) def deprecationWarning(pos: Position, msg: String) = - currentRun.deprecationWarnings.warn(pos, msg) + currentRun.deprecationWarnings0.warn(pos, msg) def uncheckedWarning(pos: Position, msg: String) = currentRun.uncheckedWarnings0.warn(pos, msg) diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index c9394b37b5..6c038162b3 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -974,16 +974,17 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S /** The currently compiled unit; set from GlobalPhase */ var currentUnit: CompilationUnit = NoCompilationUnit - val deprecationWarnings = new ConditionalWarning("deprecation", settings.deprecation) // This change broke sbt; I gave it the thrilling name of uncheckedWarnings0 so // as to recover uncheckedWarnings for its ever-fragile compiler interface. + val deprecationWarnings0 = new ConditionalWarning("deprecation", settings.deprecation) val uncheckedWarnings0 = new ConditionalWarning("unchecked", settings.unchecked) val featureWarnings = new ConditionalWarning("feature", settings.feature) val inlinerWarnings = new ConditionalWarning("inliner", settings.YinlinerWarnings) - val allConditionalWarnings = List(deprecationWarnings, uncheckedWarnings0, featureWarnings, inlinerWarnings) + val allConditionalWarnings = List(deprecationWarnings0, uncheckedWarnings0, featureWarnings, inlinerWarnings) // for sbt's benefit def uncheckedWarnings: List[(Position, String)] = uncheckedWarnings0.warnings.toList + def deprecationWarnings: List[(Position, String)] = deprecationWarnings0.warnings.toList var reportedFeature = Set[Symbol]() -- cgit v1.2.3 From 016bc3db52d6f1ffa3ef2285d5801f82f5f49167 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 18 Apr 2012 12:22:59 +0100 Subject: Minor optimizations with nested list operations. I also tried transforming a comment into an assertion and to my shock and happy surprise everything still worked. Let's express those preconditions in code when we can, mmm? --- .../scala/reflect/internal/Definitions.scala | 2 +- .../scala/reflect/internal/Importers.scala | 2 +- src/compiler/scala/reflect/internal/Symbols.scala | 17 ++++++++++------- .../scala/reflect/internal/util/Collections.scala | 15 +++++++++++---- src/compiler/scala/tools/nsc/ast/Trees.scala | 22 ++++++++++++++-------- .../tools/nsc/interpreter/MemberHandlers.scala | 2 +- .../scala/tools/nsc/typechecker/Duplicators.scala | 2 +- .../scala/tools/nsc/typechecker/Macros.scala | 6 +++--- 8 files changed, 42 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 3150b674af..7353e69ab6 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -120,7 +120,7 @@ trait Definitions extends reflect.api.StandardDefinitions { numericWeight contains sym def isGetClass(sym: Symbol) = - (sym.name == nme.getClass_) && (sym.paramss.isEmpty || sym.paramss.head.isEmpty) + (sym.name == nme.getClass_) && flattensToEmpty(sym.paramss) lazy val UnitClass = valueCache(tpnme.Unit) lazy val ByteClass = valueCache(tpnme.Byte) diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index 596d400628..8404386e10 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -326,7 +326,7 @@ trait Importers { self: SymbolTable => case from.ValDef(mods, name, tpt, rhs) => new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs)) case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) => - new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, vparamss map (_ map importValDef), importTree(tpt), importTree(rhs)) + new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs)) case from.TypeDef(mods, name, tparams, rhs) => new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs)) case from.LabelDef(name, params, rhs) => diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 74e924add4..c9ac929edf 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -718,13 +718,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ final def isMonomorphicType = isType && { - var is = infos - (is eq null) || { - while (is.prev ne null) { is = is.prev } - is.info.isComplete && !is.info.isHigherKinded // was: is.info.typeParams.isEmpty. - // YourKit listed the call to PolyType.typeParams as a hot spot but it is likely an artefact. - // The change to isHigherKinded did not reduce the total running time. - } + val info = originalInfo + info.isComplete && !info.isHigherKinded } def isStrictFP = hasAnnotation(ScalaStrictFPAttr) || (enclClass hasAnnotation ScalaStrictFPAttr) @@ -1126,6 +1121,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => // ------ info and type ------------------------------------------------------------------- private[Symbols] var infos: TypeHistory = null + def originalInfo = { + if (infos eq null) null + else { + var is = infos + while (is.prev ne null) { is = is.prev } + is.info + } + } /** Get type. The type of a symbol is: * for a type symbol, the type corresponding to the symbol itself, diff --git a/src/compiler/scala/reflect/internal/util/Collections.scala b/src/compiler/scala/reflect/internal/util/Collections.scala index 9dbf1adeef..9e4ae1ca00 100644 --- a/src/compiler/scala/reflect/internal/util/Collections.scala +++ b/src/compiler/scala/reflect/internal/util/Collections.scala @@ -24,18 +24,21 @@ trait Collections { ) /** All these mm methods are "deep map" style methods for - * mapping etc. on a list of lists. + * mapping etc. on a list of lists while avoiding unnecessary + * intermediate structures like those created via flatten. */ final def mexists[A](xss: List[List[A]])(p: A => Boolean) = xss exists (_ exists p) + final def mforall[A](xss: List[List[A]])(p: A => Boolean) = + xss forall (_ forall p) final def mmap[A, B](xss: List[List[A]])(f: A => B) = xss map (_ map f) final def mforeach[A](xss: List[List[A]])(f: A => Unit) = xss foreach (_ foreach f) final def mfind[A](xss: List[List[A]])(p: A => Boolean): Option[A] = { - for (xs <- xss; x <- xs) - if (p(x)) return Some(x) - None + var res: Option[A] = null + mforeach(xss)(x => if ((res eq null) && p(x)) res = Some(x)) + if (res eq null) None else res } final def mfilter[A](xss: List[List[A]])(p: A => Boolean) = for (xs <- xss; x <- xs; if p(x)) yield x @@ -66,6 +69,10 @@ trait Collections { } lb.toList } + + @tailrec final def flattensToEmpty(xss: Seq[Seq[_]]): Boolean = { + xss.isEmpty || xss.head.isEmpty && flattensToEmpty(xss.tail) + } final def foreachWithIndex[A, B](xs: List[A])(f: (A, Int) => Unit) { var index = 0 diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 04452c68e5..2bd1ba3fea 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -86,13 +86,12 @@ trait Trees extends reflect.internal.Trees { self: Global => /* Add constructor to template */ // create parameters for as synthetic trees. - var vparamss1 = - vparamss map (vps => vps.map { vd => - 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) - }}) + var vparamss1 = mmap(vparamss) { vd => + atPos(vd.pos.focus) { + val mods = Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) + ValDef(mods withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, vd.rhs.duplicate) + } + } val (edefs, rest) = body span treeInfo.isEarlyDef val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef val gvdefs = evdefs map { @@ -143,11 +142,18 @@ trait Trees extends reflect.internal.Trees { self: Global => * @param body the template statements without primary constructor * and value parameter fields. */ - def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef = + def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef = { + // "if they have symbols they should be owned by `sym`" + assert( + mforall(vparamss)(p => (p.symbol eq NoSymbol) || (p.symbol.owner == sym)), + ((mmap(vparamss)(_.symbol), sym)) + ) + ClassDef(sym, Template(sym.info.parents map TypeTree, if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym), constrMods, vparamss, argss, body, superPos)) + } // --- subcomponents -------------------------------------------------- diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala index fcede04aaf..a29eb3ac6d 100644 --- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala +++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala @@ -124,7 +124,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 && vparamss.tail.isEmpty) + override def definesValue = !isMacro && flattensToEmpty(vparamss) override def resultExtractionCode(req: Request) = if (mods.isPublic) codegenln(name, ": ", req.typeOf(name)) else "" } diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index f6d1e42c32..2574a1d241 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -186,7 +186,7 @@ abstract class Duplicators extends Analyzer { oldClassOwner = oldThis newClassOwner = newThis invalidate(ddef.tparams) - for (vdef <- ddef.vparamss.flatten) { + mforeach(ddef.vparamss) { vdef => invalidate(vdef) vdef.tpe = null } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 539ddfb19c..da32e638d3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -76,7 +76,7 @@ trait Macros { self: Analyzer => 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 { + mfind(vparamss)(_.symbol == sym) match { case Some(macroDefParam) => SingleType(SingleType(NoPrefix, param(macroDefParam)), ExprValue) case _ => @@ -121,7 +121,7 @@ trait Macros { self: Analyzer => 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) + val paramssParams = mmap(vparamss)(param) var paramsss = List[List[List[Symbol]]]() // tparams are no longer part of a signature, they get into macro implementations via context bounds @@ -544,7 +544,7 @@ trait Macros { self: Analyzer => 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)) + val defParamss = mmap(macroDdef.vparamss)(_.symbol) var implParamss = macroImpl.paramss implParamss = transformTypeTagEvidenceParams(implParamss, (param, tparam) => None) -- cgit v1.2.3 From b5d583063e995a2054fa3fde3b190ee4ffa843f5 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Thu, 19 Apr 2012 12:36:20 +0200 Subject: SI-5677, Tiny typo. Fixed. --- src/library/scala/collection/GenTraversableLike.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala index fd03e0f446..4500a849b1 100644 --- a/src/library/scala/collection/GenTraversableLike.scala +++ b/src/library/scala/collection/GenTraversableLike.scala @@ -91,7 +91,7 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with */ def scan[B >: A, That](z: B)(op: (B, B) => B)(implicit cbf: CanBuildFrom[Repr, B, That]): That - /** Produces a collection containing cummulative results of applying the + /** Produces a collection containing cumulative results of applying the * operator going left to right. * * $willNotTerminateInf @@ -106,8 +106,8 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with */ def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That - /** Produces a collection containing cummulative results of applying the operator going right to left. - * The head of the collection is the last cummulative result. + /** Produces a collection containing cumulative results of applying the operator going right to left. + * The head of the collection is the last cumulative result. * $willNotTerminateInf * $orderDependent * -- cgit v1.2.3 From 756dbbc254afef97bf4920292d58645bc7708730 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(-) (limited to 'src') 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 ec9fb824994ac25ebc8395b6b69daccc92e0be5e Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 20 Apr 2012 09:34:12 +0200 Subject: minor fix to macro tracing --- src/compiler/scala/tools/nsc/typechecker/Macros.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index da32e638d3..cbfa61470c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -1020,7 +1020,7 @@ trait Macros { self: Analyzer => 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 + var msg1 = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg if (macroDebug) 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) -- cgit v1.2.3 From be11c92b6e84891f36fd4b271303b49c4aac23c8 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 19 Apr 2012 15:11:58 +0200 Subject: fixes SI-5680 --- lib/scala-compiler.jar.desired.sha1 | 2 +- lib/scala-library.jar.desired.sha1 | 2 +- src/compiler/scala/tools/nsc/transform/Erasure.scala | 2 +- src/library/scala/reflect/ClassTag.scala | 6 +++++- src/library/scala/runtime/ScalaRunTime.scala | 13 ++----------- test/files/run/t5680.check | 3 +++ test/files/run/t5680.scala | 7 +++++++ 7 files changed, 20 insertions(+), 15 deletions(-) create mode 100644 test/files/run/t5680.check create mode 100644 test/files/run/t5680.scala (limited to 'src') diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index 3d5a0edfd5..7479a1861e 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -52e6cc393c953df8c6cbe710f8d62dce6cd1f671 ?scala-compiler.jar +5d99e65aaa8e00c4815e011a8dfc495cb38bdfcc ?scala-compiler.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 028ef2fae2..76914369b5 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -569b35836872765f0b96a6477d7c37a257cc62e7 ?scala-library.jar +53ddaba2c7d56b360eda1a56c3eef5ec23ef14ca ?scala-library.jar diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 5e61359a25..45dacd5c14 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -992,7 +992,7 @@ abstract class Erasure extends AddInterfaces } // Rewrite 5.getClass to ScalaRunTime.anyValClass(5) else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) - global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual))) + global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveClassTag(tree, qual.tpe.widen)))) else tree diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index 06960a5478..860406f205 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -39,7 +39,11 @@ abstract case class ClassTag[T](erasure: jClass[_]) extends ArrayTag[T] { /** 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]]] + // newInstance throws an exception if the erasure is Void.TYPE + // see SI-5680 + val arrayClazz = + if (erasure == java.lang.Void.TYPE) classOf[Array[Unit]] + else java.lang.reflect.Array.newInstance(erasure, 0).getClass.asInstanceOf[jClass[Array[T]]] ClassTag[Array[T]](arrayClazz) } diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 7a932c21bc..d2adc26d66 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -51,17 +51,8 @@ object ScalaRunTime { * e.g. classOf[int], not classOf[java.lang.Integer]. The compiler * rewrites expressions like 5.getClass to come here. */ - def anyValClass[T <: AnyVal](value: T): Class[T] = (value match { - case x: Byte => java.lang.Byte.TYPE - case x: Short => java.lang.Short.TYPE - case x: Char => java.lang.Character.TYPE - case x: Int => java.lang.Integer.TYPE - case x: Long => java.lang.Long.TYPE - case x: Float => java.lang.Float.TYPE - case x: Double => java.lang.Double.TYPE - case x: Boolean => java.lang.Boolean.TYPE - case x: Unit => java.lang.Void.TYPE - }).asInstanceOf[Class[T]] + def anyValClass[T <: AnyVal : ClassManifest](value: T): Class[T] = + classManifest[T].erasure.asInstanceOf[Class[T]] /** Retrieve generic array element */ def array_apply(xs: AnyRef, idx: Int): Any = xs match { diff --git a/test/files/run/t5680.check b/test/files/run/t5680.check new file mode 100644 index 0000000000..9fec3b6505 --- /dev/null +++ b/test/files/run/t5680.check @@ -0,0 +1,3 @@ +[Lscala.runtime.BoxedUnit +() +() diff --git a/test/files/run/t5680.scala b/test/files/run/t5680.scala new file mode 100644 index 0000000000..f61cbd6e20 --- /dev/null +++ b/test/files/run/t5680.scala @@ -0,0 +1,7 @@ +object Test extends App { + val x = Array[Unit]((), ()) + println(x.toString.substring(0, x.toString.indexOf(";"))) + println(x(0)) + x(1) = () + println(x(1)) +} \ No newline at end of file -- cgit v1.2.3 From 766499d60bd3b3790ae915c8927da6f148e91f7a Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 20 Apr 2012 15:57:17 +0200 Subject: a deprecated method that I forgot to restore --- src/library/scala/reflect/ClassTag.scala | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index 06960a5478..1e56f2db57 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -123,6 +123,9 @@ object ClassTag { implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag) + @deprecated("Use apply instead", "2.10.0") + def fromClass[T](clazz: jClass[T]): ClassManifest[T] = apply(clazz) + /** Manifest for the singleton type `value.type'. */ @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = ??? -- cgit v1.2.3 From 56c1f29250842575b2c3324cc8bd606bda3760d5 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 20 Apr 2012 16:53:28 +0100 Subject: Good-bye, scala.dbc. Another deprecated soul passes on to ether world. --- build.xml | 34 --- docs/development/scala.dbc/SQLTypes.dot | 48 ---- project/Build.scala | 12 +- src/build/maven/maven-deploy.xml | 3 - src/build/maven/scala-dbc-pom.xml | 61 ----- src/build/pack.xml | 5 +- src/dbc/scala/dbc/DataType.scala | 69 ------ src/dbc/scala/dbc/Database.scala | 187 -------------- src/dbc/scala/dbc/Syntax.scala | 47 ---- src/dbc/scala/dbc/Utilities.scala | 28 --- src/dbc/scala/dbc/Value.scala | 27 -- src/dbc/scala/dbc/Vendor.scala | 41 --- .../scala/dbc/datatype/ApproximateNumeric.scala | 57 ----- src/dbc/scala/dbc/datatype/Boolean.scala | 31 --- src/dbc/scala/dbc/datatype/Character.scala | 40 --- .../scala/dbc/datatype/CharacterLargeObject.scala | 31 --- src/dbc/scala/dbc/datatype/CharacterString.scala | 24 -- src/dbc/scala/dbc/datatype/CharacterVarying.scala | 41 --- src/dbc/scala/dbc/datatype/ExactNumeric.scala | 65 ----- src/dbc/scala/dbc/datatype/Factory.scala | 250 ------------------- src/dbc/scala/dbc/datatype/Numeric.scala | 32 --- src/dbc/scala/dbc/datatype/String.scala | 24 -- src/dbc/scala/dbc/datatype/Unknown.scala | 34 --- .../scala/dbc/exception/IncompatibleSchema.scala | 19 -- .../scala/dbc/exception/UnsupportedFeature.scala | 16 -- src/dbc/scala/dbc/package.scala | 6 - src/dbc/scala/dbc/result/Field.scala | 63 ----- src/dbc/scala/dbc/result/FieldMetadata.scala | 40 --- src/dbc/scala/dbc/result/Relation.scala | 84 ------- src/dbc/scala/dbc/result/Status.scala | 28 --- src/dbc/scala/dbc/result/Tuple.scala | 42 ---- src/dbc/scala/dbc/statement/AccessMode.scala | 26 -- src/dbc/scala/dbc/statement/DerivedColumn.scala | 38 --- src/dbc/scala/dbc/statement/Expression.scala | 28 --- src/dbc/scala/dbc/statement/Insert.scala | 31 --- src/dbc/scala/dbc/statement/InsertionData.scala | 40 --- src/dbc/scala/dbc/statement/IsolationLevel.scala | 32 --- src/dbc/scala/dbc/statement/JoinType.scala | 56 ----- src/dbc/scala/dbc/statement/Jointure.scala | 45 ---- src/dbc/scala/dbc/statement/Relation.scala | 55 ----- src/dbc/scala/dbc/statement/Select.scala | 99 -------- src/dbc/scala/dbc/statement/SetClause.scala | 21 -- src/dbc/scala/dbc/statement/SetQuantifier.scala | 38 --- src/dbc/scala/dbc/statement/Statement.scala | 16 -- src/dbc/scala/dbc/statement/Status.scala | 32 --- src/dbc/scala/dbc/statement/Table.scala | 38 --- src/dbc/scala/dbc/statement/Transaction.scala | 55 ----- src/dbc/scala/dbc/statement/Update.scala | 47 ---- .../scala/dbc/statement/expression/Aggregate.scala | 35 --- .../dbc/statement/expression/BinaryOperator.scala | 33 --- .../scala/dbc/statement/expression/Constant.scala | 23 -- .../scala/dbc/statement/expression/Default.scala | 22 -- src/dbc/scala/dbc/statement/expression/Field.scala | 40 --- .../dbc/statement/expression/FunctionCall.scala | 33 --- .../scala/dbc/statement/expression/Select.scala | 28 --- .../dbc/statement/expression/SetFunction.scala | 40 --- .../scala/dbc/statement/expression/TypeCast.scala | 32 --- .../dbc/statement/expression/UnaryOperator.scala | 33 --- src/dbc/scala/dbc/syntax/DataTypeUtil.scala | 98 -------- src/dbc/scala/dbc/syntax/Database.scala | 33 --- src/dbc/scala/dbc/syntax/Statement.scala | 274 --------------------- src/dbc/scala/dbc/syntax/StatementExpression.scala | 221 ----------------- src/dbc/scala/dbc/value/ApproximateNumeric.scala | 28 --- src/dbc/scala/dbc/value/Boolean.scala | 27 -- src/dbc/scala/dbc/value/Character.scala | 35 --- src/dbc/scala/dbc/value/CharacterLargeObject.scala | 35 --- src/dbc/scala/dbc/value/CharacterVarying.scala | 35 --- src/dbc/scala/dbc/value/Conversion.scala | 156 ------------ src/dbc/scala/dbc/value/ExactNumeric.scala | 35 --- src/dbc/scala/dbc/value/Factory.scala | 95 ------- src/dbc/scala/dbc/value/Unknown.scala | 27 -- src/dbc/scala/dbc/vendor/PostgreSQL.scala | 29 --- src/intellij/dbc.iml.SAMPLE | 3 - src/intellij/scala-lang.ipr.SAMPLE | 1 - 74 files changed, 6 insertions(+), 3631 deletions(-) delete mode 100644 docs/development/scala.dbc/SQLTypes.dot delete mode 100644 src/build/maven/scala-dbc-pom.xml delete mode 100644 src/dbc/scala/dbc/DataType.scala delete mode 100644 src/dbc/scala/dbc/Database.scala delete mode 100644 src/dbc/scala/dbc/Syntax.scala delete mode 100644 src/dbc/scala/dbc/Utilities.scala delete mode 100644 src/dbc/scala/dbc/Value.scala delete mode 100644 src/dbc/scala/dbc/Vendor.scala delete mode 100644 src/dbc/scala/dbc/datatype/ApproximateNumeric.scala delete mode 100644 src/dbc/scala/dbc/datatype/Boolean.scala delete mode 100644 src/dbc/scala/dbc/datatype/Character.scala delete mode 100644 src/dbc/scala/dbc/datatype/CharacterLargeObject.scala delete mode 100644 src/dbc/scala/dbc/datatype/CharacterString.scala delete mode 100644 src/dbc/scala/dbc/datatype/CharacterVarying.scala delete mode 100644 src/dbc/scala/dbc/datatype/ExactNumeric.scala delete mode 100644 src/dbc/scala/dbc/datatype/Factory.scala delete mode 100644 src/dbc/scala/dbc/datatype/Numeric.scala delete mode 100644 src/dbc/scala/dbc/datatype/String.scala delete mode 100644 src/dbc/scala/dbc/datatype/Unknown.scala delete mode 100644 src/dbc/scala/dbc/exception/IncompatibleSchema.scala delete mode 100644 src/dbc/scala/dbc/exception/UnsupportedFeature.scala delete mode 100644 src/dbc/scala/dbc/package.scala delete mode 100644 src/dbc/scala/dbc/result/Field.scala delete mode 100644 src/dbc/scala/dbc/result/FieldMetadata.scala delete mode 100644 src/dbc/scala/dbc/result/Relation.scala delete mode 100644 src/dbc/scala/dbc/result/Status.scala delete mode 100644 src/dbc/scala/dbc/result/Tuple.scala delete mode 100644 src/dbc/scala/dbc/statement/AccessMode.scala delete mode 100644 src/dbc/scala/dbc/statement/DerivedColumn.scala delete mode 100644 src/dbc/scala/dbc/statement/Expression.scala delete mode 100644 src/dbc/scala/dbc/statement/Insert.scala delete mode 100644 src/dbc/scala/dbc/statement/InsertionData.scala delete mode 100644 src/dbc/scala/dbc/statement/IsolationLevel.scala delete mode 100644 src/dbc/scala/dbc/statement/JoinType.scala delete mode 100644 src/dbc/scala/dbc/statement/Jointure.scala delete mode 100644 src/dbc/scala/dbc/statement/Relation.scala delete mode 100644 src/dbc/scala/dbc/statement/Select.scala delete mode 100644 src/dbc/scala/dbc/statement/SetClause.scala delete mode 100644 src/dbc/scala/dbc/statement/SetQuantifier.scala delete mode 100644 src/dbc/scala/dbc/statement/Statement.scala delete mode 100644 src/dbc/scala/dbc/statement/Status.scala delete mode 100644 src/dbc/scala/dbc/statement/Table.scala delete mode 100644 src/dbc/scala/dbc/statement/Transaction.scala delete mode 100644 src/dbc/scala/dbc/statement/Update.scala delete mode 100644 src/dbc/scala/dbc/statement/expression/Aggregate.scala delete mode 100644 src/dbc/scala/dbc/statement/expression/BinaryOperator.scala delete mode 100644 src/dbc/scala/dbc/statement/expression/Constant.scala delete mode 100644 src/dbc/scala/dbc/statement/expression/Default.scala delete mode 100644 src/dbc/scala/dbc/statement/expression/Field.scala delete mode 100644 src/dbc/scala/dbc/statement/expression/FunctionCall.scala delete mode 100644 src/dbc/scala/dbc/statement/expression/Select.scala delete mode 100644 src/dbc/scala/dbc/statement/expression/SetFunction.scala delete mode 100644 src/dbc/scala/dbc/statement/expression/TypeCast.scala delete mode 100644 src/dbc/scala/dbc/statement/expression/UnaryOperator.scala delete mode 100644 src/dbc/scala/dbc/syntax/DataTypeUtil.scala delete mode 100644 src/dbc/scala/dbc/syntax/Database.scala delete mode 100644 src/dbc/scala/dbc/syntax/Statement.scala delete mode 100644 src/dbc/scala/dbc/syntax/StatementExpression.scala delete mode 100644 src/dbc/scala/dbc/value/ApproximateNumeric.scala delete mode 100644 src/dbc/scala/dbc/value/Boolean.scala delete mode 100644 src/dbc/scala/dbc/value/Character.scala delete mode 100644 src/dbc/scala/dbc/value/CharacterLargeObject.scala delete mode 100644 src/dbc/scala/dbc/value/CharacterVarying.scala delete mode 100644 src/dbc/scala/dbc/value/Conversion.scala delete mode 100644 src/dbc/scala/dbc/value/ExactNumeric.scala delete mode 100644 src/dbc/scala/dbc/value/Factory.scala delete mode 100644 src/dbc/scala/dbc/value/Unknown.scala delete mode 100644 src/dbc/scala/dbc/vendor/PostgreSQL.scala (limited to 'src') diff --git a/build.xml b/build.xml index d2438e3112..610bce2f0d 100644 --- a/build.xml +++ b/build.xml @@ -643,7 +643,6 @@ QUICK BUILD (QUICK) - @@ -689,15 +688,6 @@ QUICK BUILD (QUICK) - - - - - - - - - - @@ -1201,7 +1185,6 @@ BOOTSTRAPPING BUILD (STRAP) - @@ -1246,15 +1229,6 @@ BOOTSTRAPPING BUILD (STRAP) - - - - - @@ -2033,9 +2006,6 @@ DISTRIBUTION - - - @@ -2123,7 +2093,6 @@ STABLE REFERENCE (STARR) - @@ -2225,9 +2194,6 @@ POSITIONS - - - diff --git a/docs/development/scala.dbc/SQLTypes.dot b/docs/development/scala.dbc/SQLTypes.dot deleted file mode 100644 index 77c27cf729..0000000000 --- a/docs/development/scala.dbc/SQLTypes.dot +++ /dev/null @@ -1,48 +0,0 @@ -digraph SQLTypes { - node [shape = record] - DataType [label = "{DataType|nullable: Boolean}"] - StringType [label = "{StringType|maxLength: Int}"] - CharacterStringType [label = "{CharacterStringType|encoding: String}"] - CharacterType [label = "{CharacterType|length: Int}"] - CharacterVaryingType [label = "{CharacterVaryingType|length: Int}"] - CharacterLargeObjectType [label = "CharacterLargeObjectType"] - BinaryStringType [label = "BinaryStringType"] - BinaryType [label = "{BinaryType|length: Int}"] - BinaryVaryingType [label = "{BinaryVaryingType|length: Int}"] - BinaryLargeObjectType [label = "BinaryLargeObjectType"] - BooleanType [label = "BooleanType"] - NumericType [label = "{NumericType|precisionRadix: Int\nprecision: Int}"] - ExactNumericType [label = "{ExactNumericType|scale: Int}"] - ApproximateNumericType [label = "ApproximateNumericType"] - DateTimeType [label = "DateTimeType"] - TimeType [label = "{TimeType|precisionRadix: Int\nsecondScale: Int}"] - TimeWithoutTimezoneType [label = "TimeWithoutTimezoneType"] - TimeWithTimezoneType [label = "TimeWithTimezoneType"] - TimestampType [label = "{TimestampType|precisionRadix: Int\nsecondScale: Int}"] - TimestampWithoutTimezoneType [label = "TimestampWithoutTimezoneType"] - TimestampWithTimezoneType [label = "TimestampWithTimezoneType"] - DateType [label = "DateType"] - IntervalType [label = "{IntervalType|precisionRadix: Int\nsecondScale: Int}"] - StringType -> DataType - BooleanType -> DataType - NumericType -> DataType - DateTimeType -> DataType - IntervalType -> DataType - CharacterStringType -> StringType - BinaryStringType -> StringType - ExactNumericType -> NumericType - ApproximateNumericType -> NumericType - TimeType -> DateTimeType - TimestampType -> DateTimeType - DateType -> DateTimeType - CharacterType -> CharacterStringType - CharacterVaryingType -> CharacterStringType - CharacterLargeObjectType -> CharacterStringType - BinaryType -> BinaryStringType - BinaryVaryingType -> BinaryStringType - BinaryLargeObjectType -> BinaryStringType - TimeWithoutTimezoneType -> TimeType - TimeWithTimezoneType -> TimeType - TimestampWithoutTimezoneType -> TimestampType - TimestampWithTimezoneType -> TimestampType -} diff --git a/project/Build.scala b/project/Build.scala index 9f73563f8e..25fb31cf5b 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -77,9 +77,9 @@ object ScalaBuild extends Build with Layers { ) // Collections of projects to run 'compile' on. - lazy val compiledProjects = Seq(quickLib, quickComp, continuationsLibrary, actors, swing, dbc, forkjoin, fjbg) + lazy val compiledProjects = Seq(quickLib, quickComp, continuationsLibrary, actors, swing, forkjoin, fjbg) // Collection of projects to 'package' and 'publish' together. - lazy val packagedBinaryProjects = Seq(scalaLibrary, scalaCompiler, swing, dbc, continuationsPlugin, jline, scalap) + lazy val packagedBinaryProjects = Seq(scalaLibrary, scalaCompiler, swing, continuationsPlugin, jline, scalap) lazy val partestRunProjects = Seq(testsuite, continuationsTestsuite) private def epflPomExtra = ( @@ -249,7 +249,6 @@ object ScalaBuild extends Build with Layers { // TODO - Actors + swing separate jars... lazy val dependentProjectSettings = settingOverrides ++ Seq(quickScalaInstance, quickScalaLibraryDependency, addCheaterDependency("scala-library")) lazy val actors = Project("actors", file(".")) settings(dependentProjectSettings:_*) dependsOn(forkjoin % "provided") - lazy val dbc = Project("dbc", file(".")) settings(dependentProjectSettings:_*) // TODO - Remove actors dependency from pom... lazy val swing = Project("swing", file(".")) settings(dependentProjectSettings:_*) dependsOn(actors % "provided") // This project will generate man pages (in man1 and html) for scala. @@ -489,7 +488,7 @@ object ScalaBuild extends Build with Layers { genBin <<= genBinTask(genBinRunner, binDir, fullClasspath in Runtime, false), binDir in genBinQuick <<= baseDirectory apply (_ / "target" / "bin"), // Configure the classpath this way to avoid having .jar files and previous layers on the classpath. - fullClasspath in Runtime in genBinQuick <<= Seq(quickComp,quickLib,scalap,actors,swing,dbc,fjbg,jline,forkjoin).map(classDirectory in Compile in _).join.map(Attributed.blankSeq), + fullClasspath in Runtime in genBinQuick <<= Seq(quickComp,quickLib,scalap,actors,swing,fjbg,jline,forkjoin).map(classDirectory in Compile in _).join.map(Attributed.blankSeq), fullClasspath in Runtime in genBinQuick <++= (fullClasspath in Compile in jline), genBinQuick <<= genBinTask(genBinRunner, binDir in genBinQuick, fullClasspath in Runtime in genBinQuick, true), runManmakerMan <<= runManmakerTask(fullClasspath in Runtime in manmaker, runner in manmaker, "scala.tools.docutil.EmitManPage", "man1", ".1"), @@ -518,10 +517,9 @@ object ScalaBuild extends Build with Layers { }, // Add in some more dependencies makeDistMappings <<= (makeDistMappings, - packageBin in swing in Compile, - packageBin in dbc in Compile) map { + packageBin in swing in Compile) map { (dist, s, d) => - dist ++ Seq(s -> "lib/scala-swing.jar", d -> "lib/scala-dbc.jar") + dist ++ Seq(s -> "lib/scala-swing.jar") }, makeDist <<= (makeDistMappings, baseDirectory, streams) map { (maps, dir, s) => s.log.debug("Map = " + maps.mkString("\n")) diff --git a/src/build/maven/maven-deploy.xml b/src/build/maven/maven-deploy.xml index 7f8343a84e..ac0f8f745b 100644 --- a/src/build/maven/maven-deploy.xml +++ b/src/build/maven/maven-deploy.xml @@ -112,7 +112,6 @@ - @@ -171,7 +170,6 @@ - @@ -239,7 +237,6 @@ - diff --git a/src/build/maven/scala-dbc-pom.xml b/src/build/maven/scala-dbc-pom.xml deleted file mode 100644 index aa3d050c1e..0000000000 --- a/src/build/maven/scala-dbc-pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - 4.0.0 - org.scala-lang - scala-dbc - jar - @VERSION@ - Scala Database Connectivity - Connectivity for your DBs - http://www.scala-lang.org/ - 2002 - - LAMP/EPFL - http://lamp.epfl.ch/ - - - - BSD-like - http://www.scala-lang.org/downloads/license.html - - repo - - - - scm:git:git://github.com/scala/scala.git - https://github.com/scala/scala.git - - - JIRA - https://issues.scala-lang.org/ - - - - org.scala-lang - scala-library - @VERSION@ - - - - - scala-tools.org - @RELEASE_REPOSITORY@ - - - scala-tools.org - @SNAPSHOT_REPOSITORY@ - false - - - - - lamp - EPFL LAMP - - - Typesafe - Typesafe, Inc. - - - diff --git a/src/build/pack.xml b/src/build/pack.xml index 3bd4d7a199..f96c6b9799 100644 --- a/src/build/pack.xml +++ b/src/build/pack.xml @@ -137,7 +137,6 @@ MAIN DISTRIBUTION PACKAGING - @@ -202,11 +201,9 @@ MAIN DISTRIBUTION PACKAGING basedir="${build-docs.dir}/continuations-plugin"> - + - diff --git a/src/dbc/scala/dbc/DataType.scala b/src/dbc/scala/dbc/DataType.scala deleted file mode 100644 index 677621e0c0..0000000000 --- a/src/dbc/scala/dbc/DataType.scala +++ /dev/null @@ -1,69 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc; - - -/** An ISO-9075:2003 (SQL) data type. Mappings between SQL types and - * database specific types should be provided by the database driver. - */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class DataType { - - /** Tests whether this datatype is equivalent to another. Usually, two - * types are defined as equivalent if they are equal. Two types can be - * equivalent without being equal if values of those types will be - * encoded in the same native Scala type. - */ - def isEquivalent(datatype: DataType): Boolean; - - /** Tests whether this datatype is equivalent or a subtype of another - * datatype. Type A is said to be subtype of type - * B if any value of type A can be - * represented as a value of type B. - */ - def isSubtypeOf(datatype: DataType): Boolean; - - /** The native Scala type in which values of this SQL type will be - * encoded. - */ - type NativeType <: Any; - - /** The native Scala type in which values of this SQL type will be - * encoded. This must point to the same type as NativeType. - */ - def nativeTypeId: DataType.Id; - - /** Whether the value can take the null value, None when this property is - * unknown. - */ - def nullable: Option[Boolean] = None; - - /** The SQL name of the type */ - def sqlString: String = "UNDEFINED DATA TYPE" - -} - -@deprecated(DbcIsDeprecated, "2.9.0") object DataType { - - type Id = Int; - - val OBJECT : Id = 10; - val BOOLEAN : Id = 20; - val BYTE : Id = 30; - val SHORT : Id = 31; - val INT : Id = 32; - val LONG : Id = 33; - val BIG_INTEGER: Id = 34; - val BIG_DECIMAL: Id = 35; - val FLOAT : Id = 40; - val DOUBLE : Id = 41; - val STRING : Id = 50; - -} diff --git a/src/dbc/scala/dbc/Database.scala b/src/dbc/scala/dbc/Database.scala deleted file mode 100644 index 60e16367e8..0000000000 --- a/src/dbc/scala/dbc/Database.scala +++ /dev/null @@ -1,187 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc - - -import java.sql._ - -/** A link to a database. The Database abstract class must - * be specialised for every different DBMS. - * - * @author Gilles Dubochet - */ -@deprecated(DbcIsDeprecated, "2.9.0") case class Database(dbms: Vendor) { - - class Closed extends Exception {} - - /** A lock used for operations that need to be atomic for this database - * instance. */ - private val lock: scala.concurrent.Lock = new scala.concurrent.Lock() - - /** The vendor of the DBMS that contains this database. */ - private val vendor: Vendor = dbms - - /** The Database connections available to use. */ - private var availableConnections: List[Connection] = Nil - - /** The connections that are currently in use. */ - private var usedConnections: List[Connection] = Nil - - /** Whether the database no longer accepts new connections. */ - private var closing: Boolean = false; - - /** Retrieves a connection from the available connection pool or creates - * a new one. - * - * @return A connection that can be used to access the database. - */ - private def getConnection: Connection = { - if (closing) { - throw new Closed; - } else { - availableConnections match { - case Nil => { - lock.acquire; - val connection = vendor.getConnection; - usedConnections = connection :: usedConnections; - lock.release; - connection - } - case connection :: cs => { - lock.acquire; - availableConnections = cs; - usedConnections = connection :: usedConnections; - lock.release; - connection; - } - } - } - } - - /** Closes a connection to this database. A closed connection might - * also return to the available connection pool if the latter is depleted. - * - * @param connection The connection that should be closed. - */ - private def closeConnection(connection: Connection): Unit = { - if (closing) { - connection.close() - } else { - lock.acquire - usedConnections = usedConnections.filterNot(e => (e.equals(connection))); - if (availableConnections.length < vendor.retainedConnections) - availableConnections = connection :: availableConnections - else - connection.close() - lock.release - } - } - - /** .. - */ - def close() { - closing = true - for (conn <- availableConnections) conn.close() - } - - /** Executes a statement that returns a relation on this database. - * - * @param relationStatement The statement to execute. - * @return The relation returned by the database for this statement. - */ - def executeStatement(relationStatement: statement.Relation): result.Relation = - executeStatement(relationStatement, false); - - /** Executes a statement that returns a relation on this database. - * - * @param relationStatement The statement to execute. - * @param debug Whether debugging information should be printed on the console. - * @return The relation returned by the database for this statement. - */ - def executeStatement(relationStatement: statement.Relation, - debug: Boolean): result.Relation = - new scala.dbc.result.Relation { - val statement = relationStatement - if (debug) Console.println("## " + statement.sqlString) - private val connection = getConnection - val sqlResult = connection.createStatement().executeQuery(statement.sqlString) - closeConnection(connection) - statement.typeCheck(this) - } - - /** Executes a statement that updates the state of the database. - * @param statusStatement The statement to execute. - * @return The status of the database after the statement has been executed. */ - def executeStatement(statusStatement: statement.Status): result.Status[Unit] = - executeStatement(statusStatement, false); - - /** Executes a statement that updates the state of the database. - * - * @param statusStatement The statement to execute. - * @param debug Whether debugging information should be printed on the console. - * @return The status of the database after the statement has been executed. - */ - def executeStatement(statusStatement: statement.Status, - debug: Boolean): result.Status[Unit] = - new scala.dbc.result.Status[Unit] { - val statement = statusStatement; - if (debug) Console.println("## " + statement.sqlString); - def result = () - private val connection = getConnection; - val jdbcStatement: java.sql.Statement = connection.createStatement(); - jdbcStatement.execute(statement.sqlString); - val touchedCount = Some(jdbcStatement.getUpdateCount()); - closeConnection(connection); - } - - /** Executes a list of statements or other operations inside a transaction. - * Only statements are protected in a transaction, other Scala code is not. - * - * @param transactionStatement The transaction to execute as a closure. - * @return The status of the database after the transaction has been executed. - */ - def executeStatement[ResultType](transactionStatement: statement.Transaction[ResultType]): result.Status[ResultType] = - executeStatement(transactionStatement, false); - - /** Executes a list of statements or other operations inside a transaction. - * Only statements are protected in a transaction, other Scala code is not. - * - * @param transactionStatement The transaction to execute as a closure. - * @param debug Whether debugging information should be printed on the console. - * @return The status of the database after the transaction has been executed. - */ - def executeStatement[ResultType](transactionStatement: statement.Transaction[ResultType], debug: Boolean): result.Status[ResultType] = { - new scala.dbc.result.Status[ResultType] { - val touchedCount = None - val statement = transactionStatement - private val connection = getConnection - connection.setAutoCommit(false) - val jdbcStatement: java.sql.Statement = connection.createStatement(); - if (debug) Console.println("## " + transactionStatement.sqlStartString); - jdbcStatement.execute(transactionStatement.sqlStartString); - val result: ResultType = try { - val buffer = transactionStatement.transactionBody(Database.this); - if (debug) Console.println("## " + transactionStatement.sqlCommitString); - jdbcStatement.execute(transactionStatement.sqlCommitString); - buffer - } catch { - case e: Throwable => { - if (debug) Console.println("## " + transactionStatement.sqlAbortString); - jdbcStatement.execute(transactionStatement.sqlAbortString); - throw e - } - } - connection.setAutoCommit(true) - closeConnection(connection) - } - } - -} diff --git a/src/dbc/scala/dbc/Syntax.scala b/src/dbc/scala/dbc/Syntax.scala deleted file mode 100644 index 85cd1c1a1d..0000000000 --- a/src/dbc/scala/dbc/Syntax.scala +++ /dev/null @@ -1,47 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc; - - -import java.math.{BigDecimal, BigInteger}; - - -/** This class .. - * - */ -@deprecated(DbcIsDeprecated, "2.9.0") object Syntax { - - import syntax.DataTypeUtil; - - /* Data types */ - def boolean = DataTypeUtil.boolean; - def tinyint = DataTypeUtil.tinyint; - def smallint = DataTypeUtil.smallint; - def integer = DataTypeUtil.integer; - def bigint = DataTypeUtil.bigint; - def real = DataTypeUtil.real; - - def numeric(precision: Int) = DataTypeUtil.numeric(precision); - def numeric(precision: Int, scale: Int) = DataTypeUtil.numeric(precision, scale); - - def doublePrecision = DataTypeUtil.doublePrecision; - def character(length: Int) = DataTypeUtil.character(length); - def characterVarying(length: Int) = DataTypeUtil.characterVarying(length); - def characterLargeObject = DataTypeUtil.characterLargeObject; - - /* Statements */ - //def select - - /* Other stuff */ - def database (server: String, username: String, password: String): dbc.Database = - syntax.Database.database(server, username, password); - -} diff --git a/src/dbc/scala/dbc/Utilities.scala b/src/dbc/scala/dbc/Utilities.scala deleted file mode 100644 index c37b1bb98d..0000000000 --- a/src/dbc/scala/dbc/Utilities.scala +++ /dev/null @@ -1,28 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc; - - -/** An object offering transformation methods (views) on various values. - * This object's members must be visible in an expression to use value - * auto-conversion. - */ -@deprecated(DbcIsDeprecated, "2.9.0") object Utilities { - - implicit def constantToValue (obj: statement.expression.Constant): Value = - obj.constantValue; - - implicit def valueToConstant (obj: Value): statement.expression.Constant = - new statement.expression.Constant { - val constantValue = obj; - } - -} diff --git a/src/dbc/scala/dbc/Value.scala b/src/dbc/scala/dbc/Value.scala deleted file mode 100644 index a502f51cb5..0000000000 --- a/src/dbc/scala/dbc/Value.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc; - - -/** A SQL-99 value of any type. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Value { - - /** The SQL-99 type of the value. */ - val dataType: DataType; - - type NativeType = dataType.type#NativeType; - - val nativeValue: NativeType; - - /** A SQL-99 compliant string representation of the value. */ - def sqlString: String; - -} diff --git a/src/dbc/scala/dbc/Vendor.scala b/src/dbc/scala/dbc/Vendor.scala deleted file mode 100644 index 68f6102526..0000000000 --- a/src/dbc/scala/dbc/Vendor.scala +++ /dev/null @@ -1,41 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc; - - -import java.sql.{Connection, Driver}; - - -/** This class .. - */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Vendor { - - def nativeDriverClass: Class[_]; - def uri: java.net.URI; - def user: String; - def pass: String; - def nativeProperties: java.util.Properties = { - val properties = new java.util.Properties(); - properties.setProperty("user", user); - properties.setProperty("password", pass); - properties - } - - def retainedConnections: Int; - - def getConnection: Connection = { - val driver = nativeDriverClass.newInstance().asInstanceOf[Driver]; - driver.connect(uri.toString(),nativeProperties) - } - - def urlProtocolString: String; - -} diff --git a/src/dbc/scala/dbc/datatype/ApproximateNumeric.scala b/src/dbc/scala/dbc/datatype/ApproximateNumeric.scala deleted file mode 100644 index 31752e18c7..0000000000 --- a/src/dbc/scala/dbc/datatype/ApproximateNumeric.scala +++ /dev/null @@ -1,57 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -/** A type category for all SQL types that store varying-precision - * numbers. - */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class ApproximateNumeric[Type] ( - override val nativeTypeId: DataType.Id -) extends datatype.Numeric[Type](nativeTypeId) { - - def isEquivalent(datatype: DataType) = datatype match { - case dt: ApproximateNumeric[_] => - (nativeTypeId == dt.nativeTypeId && - precisionRadix == dt.precisionRadix && - precision == dt.precision && - signed == dt.signed) - case _ => - false - } - - def isSubtypeOf (datatype:DataType) = datatype match { - case dt:ApproximateNumeric[_] => - (nativeTypeId == dt.nativeTypeId && - precisionRadix == dt.precisionRadix && - precision <= dt.precision && - signed == dt.signed) - case _ => - false - } - - /** A SQL-99 compliant string representation of the type. - *

Compatibility notice

This method assumes that a real - * uses 32 bits and a double 64. This is not defined in the - * standard but is usually the case. - */ - override def sqlString: java.lang.String = Tuple2(precisionRadix,precision) match { - case Tuple2(2,64) => "REAL" - case Tuple2(2,128) => "DOUBLE PRECISION" - case Tuple2(2,p) => - throw exception.UnsupportedFeature("SQL-99 does not support an approximate numeric type with a binary defined precision other than 16, 32 and 64 bits"); - case Tuple2(10,p) => "FLOAT (" + p.toString() + ")" - case Tuple2(pr,_) => - throw exception.UnsupportedFeature("SQL-99 does not support the precision of an approximate numeric type to be defined in a radix other than 2 or 10"); - } - -} diff --git a/src/dbc/scala/dbc/datatype/Boolean.scala b/src/dbc/scala/dbc/datatype/Boolean.scala deleted file mode 100644 index 4a32ce98f1..0000000000 --- a/src/dbc/scala/dbc/datatype/Boolean.scala +++ /dev/null @@ -1,31 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -/** The SQL type for a truth value. */ -@deprecated(DbcIsDeprecated, "2.9.0") class Boolean extends DataType { - - def isEquivalent (datatype:DataType) = datatype match { - case dt:Boolean => true - case _ => false - } - - def isSubtypeOf (datatype:DataType) = isEquivalent(datatype); - - type NativeType = scala.Boolean; - val nativeTypeId = DataType.BOOLEAN; - - /** A SQL-99 compliant string representation of the type. */ - override def sqlString: java.lang.String = "BOOLEAN"; - -} diff --git a/src/dbc/scala/dbc/datatype/Character.scala b/src/dbc/scala/dbc/datatype/Character.scala deleted file mode 100644 index 02dec06281..0000000000 --- a/src/dbc/scala/dbc/datatype/Character.scala +++ /dev/null @@ -1,40 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -/** A SQL type for a string of characters of arbitrary length with - * arbitrary character set. - */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Character extends CharacterString { - - def isEquivalent(datatype: DataType) = datatype match { - case dt: Character => - length == dt.length && encoding == dt.encoding - case _ => - false - } - - def isSubtypeOf(datatype: DataType) = datatype match { - case dt: Character => - length >= dt.length && encoding == dt.encoding - case _ => - false - } - - /** The length of the string defined in characters. */ - def length: Int; - - /** A SQL-99 compliant string representation of the type. */ - override def sqlString: java.lang.String = "CHARACTER (" + length.toString() + ")"; - -} diff --git a/src/dbc/scala/dbc/datatype/CharacterLargeObject.scala b/src/dbc/scala/dbc/datatype/CharacterLargeObject.scala deleted file mode 100644 index 2c7ef64d66..0000000000 --- a/src/dbc/scala/dbc/datatype/CharacterLargeObject.scala +++ /dev/null @@ -1,31 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -/** A SQL type for an unbounded length string of characters with arbitrary - * character set. */ -@deprecated(DbcIsDeprecated, "2.9.0") class CharacterLargeObject extends CharacterString { - - def isEquivalent (datatype:DataType) = datatype match { - case dt:CharacterLargeObject => { - encoding == dt.encoding - } - case _ => false - } - - def isSubtypeOf (datatype:DataType) = isEquivalent(datatype); - - /** A SQL-99 compliant string representation of the type. */ - override def sqlString: java.lang.String = "CHARACTER LARGE OBJECT"; - -} diff --git a/src/dbc/scala/dbc/datatype/CharacterString.scala b/src/dbc/scala/dbc/datatype/CharacterString.scala deleted file mode 100644 index 54d6e0111f..0000000000 --- a/src/dbc/scala/dbc/datatype/CharacterString.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -/** A type category for all SQL types that store strings of characters. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class CharacterString extends String { - - type NativeType = java.lang.String; - val nativeTypeId = DataType.STRING; - - /** The name of the character set in which the string is encoded. */ - def encoding: Option[java.lang.String] = None; - -} diff --git a/src/dbc/scala/dbc/datatype/CharacterVarying.scala b/src/dbc/scala/dbc/datatype/CharacterVarying.scala deleted file mode 100644 index 9df487579f..0000000000 --- a/src/dbc/scala/dbc/datatype/CharacterVarying.scala +++ /dev/null @@ -1,41 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -/** A SQL type for a varying length string of characters with arbitrary - * maximal length and arbitrary character set. - */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class CharacterVarying extends CharacterString { - - def isEquivalent(datatype: DataType) = datatype match { - case dt: CharacterVarying => - length == dt.length && encoding == dt.encoding - case _ => - false - } - - def isSubtypeOf(datatype: DataType) = datatype match { - case dt: CharacterVarying => - length >= dt.length && encoding == dt.encoding - case _ => - false - } - - /** The maximal length of the string defined in characters. */ - def length: Int; - - /** A SQL-99 compliant string representation of the type. */ - override def sqlString: java.lang.String = - "CHARACTER VARYING (" + length.toString() + ")"; - -} diff --git a/src/dbc/scala/dbc/datatype/ExactNumeric.scala b/src/dbc/scala/dbc/datatype/ExactNumeric.scala deleted file mode 100644 index a578846977..0000000000 --- a/src/dbc/scala/dbc/datatype/ExactNumeric.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -/** A type category for all SQL types that store constant-precision - * numbers. - */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class ExactNumeric[Type]( - override val nativeTypeId: DataType.Id -) extends datatype.Numeric[Type](nativeTypeId) { - - def isEquivalent(datatype: DataType) = datatype match { - case dt: ExactNumeric[_] => - (nativeTypeId == dt.nativeTypeId && - precisionRadix == dt.precisionRadix && - precision == dt.precision && - scale == dt.scale && - signed == dt.signed) - case _ => - false - } - - def isSubtypeOf(datatype: DataType) = datatype match { - case dt: ExactNumeric[_] => - (nativeTypeId == dt.nativeTypeId && - precisionRadix == dt.precisionRadix && - precision <= dt.precision && - scale <= dt.scale && - signed == dt.signed) - case _ => - false - } - - /** The number of digits used after the decimal point. */ - def scale: Int; - - /** A SQL-99 compliant string representation of the type. - *

Compatibility notice

This method assumes that an integer - * uses 32 bits, a small 16 and a big 64. This is not defined in the - * standard but is usually the case. - */ - override def sqlString: java.lang.String = Tuple3(precisionRadix,precision,scale) match { - case Tuple3(2,16,0) => "SMALLINT" - case Tuple3(2,32,0) => "INTEGER" - case Tuple3(2,64,0) => "BIGINT" - case Tuple3(2,java.lang.Integer.MAX_VALUE,0) => "BIGINT" - case Tuple3(2,p,s) => - throw exception.UnsupportedFeature("SQL-99 does not support an exact numeric type with a binary defined precision other than 16, 32 and 64 bits"); - case Tuple3(10,p,0) => "NUMERIC (" + p.toString() + ")" - case Tuple3(10,p,s) => "NUMERIC (" + p.toString() + ", " + s.toString() + ")" - case Tuple3(pr,_,_) => - throw exception.UnsupportedFeature("SQL-99 does not support the precision of an exact numeric type to be defined in a radix other than 2 or 10"); - } - -} diff --git a/src/dbc/scala/dbc/datatype/Factory.scala b/src/dbc/scala/dbc/datatype/Factory.scala deleted file mode 100644 index bb9b3f5b61..0000000000 --- a/src/dbc/scala/dbc/datatype/Factory.scala +++ /dev/null @@ -1,250 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -import java.sql.Types._; -import java.math.BigInteger; -import java.math.BigDecimal; - -@deprecated(DbcIsDeprecated, "2.9.0") object Factory { - - final val java_lang_Integer_SIZE = 32; - final val java_lang_Long_SIZE = 64; - - /** Returns a nullable property formatted as a boolean option */ - def isNullable (metadata:java.sql.ResultSetMetaData, index:Int): Option[scala.Boolean] = - metadata.isNullable(index) match { - case java.sql.ResultSetMetaData.columnNoNulls => Some(false); - case java.sql.ResultSetMetaData.columnNullable => Some(true); - case java.sql.ResultSetMetaData.columnNullableUnknown => None; - } - - /** Returns the binary precision for an integer field. This should only be - * used to find precision for integer numbers. It assumes that - * bytes cannot be used partially (result % 8 = 0). */ - def bytePrecision (precision:Int, signed:scala.Boolean, safe:scala.Boolean): Int = { - val decimalPrecision = precision + (if (safe) 1 else 0); - Pair(signed,decimalPrecision) match { - case Pair(_,0) => java.lang.Integer.MAX_VALUE // That's a bit of a hack. - case Pair(_,dp) if (dp <= 3) => 8 - case Pair(_,dp) if (dp <= 5) => 16 - case Pair(true,dp) if (dp <= 7) => 24 - case Pair(false,dp) if (dp <= 8) => 24 - case Pair(_,dp) if (dp <= 10) => 32 - case Pair(true,dp) if (dp <= 12) => 40 - case Pair(false,dp) if (dp <= 13) => 40 - case Pair(_,dp) if (dp <= 15) => 48 - case Pair(_,dp) if (dp <= 17) => 56 - case Pair(true,dp) if (dp <= 19) => 64 - case Pair(false,dp) if (dp <= 20) => 64 - case Pair(_,dp) if (dp <= 22) => 72 - case Pair(true,dp) if (dp <= 24) => 80 - case Pair(false,dp) if (dp <= 25) => 80 - case Pair(_,dp) if (dp <= 27) => 88 - case Pair(_,dp) if (dp <= 29) => 96 - case Pair(_,dp) if (dp <= 32) => 104 - case Pair(_,dp) if (dp <= 34) => 112 - case Pair(true,dp) if (dp <= 36) => 120 - case Pair(false,dp) if (dp <= 37) => 120 - case Pair(_,dp) if (dp <= 39) => 128 - case _ => java.lang.Integer.MAX_VALUE - } - } - - def create (metadata:java.sql.ResultSetMetaData, index:Int): DataType = { - metadata.getColumnType(index) match { - /* Boolean data types. */ - case BOOLEAN => new datatype.Boolean { - override val nullable = isNullable(metadata,index); - } - case BIT => new datatype.Boolean { - override val nullable = isNullable(metadata,index); - } - /* Fixed precision numeric data types. */ - case DECIMAL => { - Pair(bytePrecision(metadata.getPrecision(index),metadata.isSigned(index),true),metadata.getScale(index) == 0) match { - case Pair(bp,true) if (bp <= java_lang_Integer_SIZE) => - new datatype.ExactNumeric[Int](DataType.INT) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 10; - val precision = metadata.getPrecision(index); - val signed = metadata.isSigned(index); - val scale = metadata.getScale(index); - } - case Pair(bp,true) if (bp <= java_lang_Long_SIZE) => - new datatype.ExactNumeric[Long](DataType.LONG) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 10; - val precision = metadata.getPrecision(index); - val signed = metadata.isSigned(index); - val scale = metadata.getScale(index); - } - case Pair(_,true) => - new datatype.ExactNumeric[BigInteger](DataType.BIG_INTEGER) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 10; - val precision = metadata.getPrecision(index); - val signed = metadata.isSigned(index); - val scale = metadata.getScale(index); - } - case Pair(_,false) => - new datatype.ExactNumeric[BigDecimal](DataType.BIG_DECIMAL) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 10; - val precision = metadata.getPrecision(index); - val signed = metadata.isSigned(index); - val scale = metadata.getScale(index); - } - } - } - case NUMERIC => { - Pair(bytePrecision(metadata.getPrecision(index),metadata.isSigned(index),true),metadata.getScale(index) == 0) match { - case Pair(bp,true) if (bp <= java_lang_Integer_SIZE) => - new datatype.ExactNumeric[Int](DataType.INT) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 10; - val precision = metadata.getPrecision(index); - val signed = metadata.isSigned(index); - val scale = metadata.getScale(index); - } - case Pair(bp,true) if (bp <= java_lang_Long_SIZE) => - new datatype.ExactNumeric[Long](DataType.LONG) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 10; - val precision = metadata.getPrecision(index); - val signed = metadata.isSigned(index); - val scale = metadata.getScale(index); - } - case Pair(_,true) => - new datatype.ExactNumeric[BigInteger](DataType.BIG_INTEGER) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 10; - val precision = metadata.getPrecision(index); - val signed = metadata.isSigned(index); - val scale = metadata.getScale(index); - } - case Pair(_,false) => - new datatype.ExactNumeric[BigDecimal](DataType.BIG_DECIMAL) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 10; - val precision = metadata.getPrecision(index); - val signed = metadata.isSigned(index); - val scale = metadata.getScale(index); - } - } - } - /* Fixed precision integer data types. */ - case BIGINT => - new datatype.ExactNumeric[Long](DataType.LONG) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 2; - val precision = 64; - val signed = metadata.isSigned(index); - val scale = 0; - } - case INTEGER => - new datatype.ExactNumeric[Int](DataType.INT) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 2; - val precision = 32; - val signed = metadata.isSigned(index); - val scale = 0; - } - case SMALLINT => - new datatype.ExactNumeric[Short](DataType.SHORT) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 2; - val precision = 16; - val signed = metadata.isSigned(index); - val scale = 0; - } - case TINYINT => - new datatype.ExactNumeric[Byte](DataType.BYTE) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 2; - val precision = 8; - val signed = metadata.isSigned(index); - val scale = 0; - } - /* Floating point numeric data types. */ - case REAL => - new datatype.ApproximateNumeric[Float](DataType.FLOAT) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 2; - val precision = 64; - val signed = metadata.isSigned(index); - } - case DOUBLE => - new datatype.ApproximateNumeric[Double](DataType.DOUBLE) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 2; - val precision = 128; - val signed = metadata.isSigned(index); - } - case FLOAT => - new datatype.ApproximateNumeric[Double](DataType.DOUBLE) { - override val nullable = isNullable(metadata,index); - val precisionRadix = 2; - val precision = 128; - val signed = metadata.isSigned(index); - } - /* Character string data types. */ - case CHAR => new datatype.Character { - override val nullable = isNullable(metadata,index); - val length = metadata.getColumnDisplaySize(index); - } - case CLOB => new datatype.CharacterLargeObject { - override val nullable = isNullable(metadata,index); - } - case LONGVARCHAR => { - if (metadata.getColumnDisplaySize(index) >= 0) - new datatype.CharacterVarying { - override val nullable = isNullable(metadata,index); - def length = metadata.getColumnDisplaySize(index); - } - else // A PostgreSQL Hack - new datatype.CharacterLargeObject { - override val nullable = isNullable(metadata,index); - } - } - case VARCHAR => { - if (metadata.getColumnDisplaySize(index) >= 0) - new datatype.CharacterVarying { - override val nullable = isNullable(metadata,index); - def length = metadata.getColumnDisplaySize(index); - } - else // A PostgreSQL Hack - new datatype.CharacterLargeObject { - override val nullable = isNullable(metadata,index); - } - } - /* Undefined cases. */ - case OTHER => new datatype.Unknown { - override val nullable = isNullable(metadata, index); - } - /* Unsupported data types. */ - case REF | ARRAY | STRUCT => - sys.error ("I don't support composite data types yet."); - case DATALINK | DISTINCT | JAVA_OBJECT | NULL => - sys.error ("I won't support strange data types."); - /* Unsupported binary string data types. */ - case BINARY | BLOB | LONGVARBINARY | VARBINARY => - sys.error ("I don't support binary string data types yet."); - /* Unsupported date and time data types. */ - case DATE | TIME | TIMESTAMP => - sys.error ("I don't support date and time data types yet."); - /* Default case */ - case x => sys.error ("I don't know about this ("+metadata.getColumnTypeName(index)+") JDBC type.") - } - } -} diff --git a/src/dbc/scala/dbc/datatype/Numeric.scala b/src/dbc/scala/dbc/datatype/Numeric.scala deleted file mode 100644 index c13f454dde..0000000000 --- a/src/dbc/scala/dbc/datatype/Numeric.scala +++ /dev/null @@ -1,32 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -/** A type category for all SQL types that store numbers. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Numeric[Type](_nativeTypeId: DataType.Id) extends DataType { - - type NativeType = Type; - val nativeTypeId = _nativeTypeId; - - /** The radix in which the precision (and scale when appliable) is defined. - * ISO-9075 only allows 2 and 10 for this value. - */ - def precisionRadix: Int; - - /** The number of significant digits for that number. */ - def precision: Int; - - /** Whether the number is signed or not. */ - def signed: scala.Boolean; - -} diff --git a/src/dbc/scala/dbc/datatype/String.scala b/src/dbc/scala/dbc/datatype/String.scala deleted file mode 100644 index 291504f777..0000000000 --- a/src/dbc/scala/dbc/datatype/String.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -/** A type category for all SQL types that store strings of elements. - */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class String extends DataType { - - /** The maximal possible length of the string defined in characters. - * This is an implementation-specific value. - */ - def maxLength: Option[Int] = None; - -} diff --git a/src/dbc/scala/dbc/datatype/Unknown.scala b/src/dbc/scala/dbc/datatype/Unknown.scala deleted file mode 100644 index 14a33c6be9..0000000000 --- a/src/dbc/scala/dbc/datatype/Unknown.scala +++ /dev/null @@ -1,34 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package datatype; - - -/** The SQL type for a truth value. */ -@deprecated(DbcIsDeprecated, "2.9.0") class Unknown extends DataType { - - def isEquivalent(datatype: DataType) = datatype match { - case dt: Unknown => - nativeTypeId == dt.nativeTypeId - case _ => - false - } - - def isSubtypeOf(datatype: DataType) = true; - - type NativeType = AnyRef; - val nativeTypeId = DataType.OBJECT; - - /** A SQL-99 compliant string representation of the type. */ - override def sqlString: java.lang.String = - sys.error("The 'UNKNOWN' data type cannot be represented."); - -} diff --git a/src/dbc/scala/dbc/exception/IncompatibleSchema.scala b/src/dbc/scala/dbc/exception/IncompatibleSchema.scala deleted file mode 100644 index c8d53bbf1a..0000000000 --- a/src/dbc/scala/dbc/exception/IncompatibleSchema.scala +++ /dev/null @@ -1,19 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package exception - - -/** A type category for all SQL types that store constant-precision numbers. */ -@deprecated(DbcIsDeprecated, "2.9.0") case class IncompatibleSchema ( - expectedSchema: List[DataType], - foundSchema: List[DataType] -) extends Exception; diff --git a/src/dbc/scala/dbc/exception/UnsupportedFeature.scala b/src/dbc/scala/dbc/exception/UnsupportedFeature.scala deleted file mode 100644 index dd6f904077..0000000000 --- a/src/dbc/scala/dbc/exception/UnsupportedFeature.scala +++ /dev/null @@ -1,16 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package exception - - -/** A type category for all SQL types that store constant-precision numbers. */ -@deprecated(DbcIsDeprecated, "2.9.0") case class UnsupportedFeature (msg: String) extends Exception; diff --git a/src/dbc/scala/dbc/package.scala b/src/dbc/scala/dbc/package.scala deleted file mode 100644 index b1552e11d3..0000000000 --- a/src/dbc/scala/dbc/package.scala +++ /dev/null @@ -1,6 +0,0 @@ -package scala - -package object dbc { - final val DbcIsDeprecated = - "scala.dbc will be removed after version 2.9. Use an active sql library such as scalaquery instead." -} \ No newline at end of file diff --git a/src/dbc/scala/dbc/result/Field.scala b/src/dbc/scala/dbc/result/Field.scala deleted file mode 100644 index cd3309bb14..0000000000 --- a/src/dbc/scala/dbc/result/Field.scala +++ /dev/null @@ -1,63 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package result - - -import scala.dbc.datatype._ -import scala.dbc.value._ - -/** An ISO-9075:2003 (SQL) table field. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Field { - - /** The content (value) of the field. The type of this value is undefined, - * transformation into a useful type will be done by an automatic view - * function defined in the field object. - */ - def content: Value - - final def value[Type <: Value]: Type = - content.asInstanceOf[Type] - - final def exactNumericValue[NativeType] = - content.asInstanceOf[dbc.value.ExactNumeric[NativeType]] - - final def approximateNumericValue[NativeType] = - content.asInstanceOf[dbc.value.ApproximateNumeric[NativeType]] - - final def booleanValue = - content.asInstanceOf[dbc.value.Boolean] - - final def characterValue = - content.asInstanceOf[dbc.value.Character] - - final def characterLargeObjectValue = - content.asInstanceOf[dbc.value.CharacterLargeObject] - - final def characterVaryingValue = - content.asInstanceOf[dbc.value.CharacterVarying] - - final def unknownValue = - content.asInstanceOf[dbc.value.Unknown] - - /** The tuple that contains this field. */ - def originatingTuple: Tuple - - /** The field metadata attached to this field. */ - def metadata: FieldMetadata - -} - -@deprecated(DbcIsDeprecated, "2.9.0") object Field { - - implicit def fieldToValue (field: Field): Value = field.content - -} diff --git a/src/dbc/scala/dbc/result/FieldMetadata.scala b/src/dbc/scala/dbc/result/FieldMetadata.scala deleted file mode 100644 index 3c2de297d0..0000000000 --- a/src/dbc/scala/dbc/result/FieldMetadata.scala +++ /dev/null @@ -1,40 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package result - - -/** The class FieldMetadata provides informations attached to - * a field about its content and its relationship to the originating database. - */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class FieldMetadata { - - /** The name of the field. */ - def name: String - - /** The index of the field in the tuple. */ - def index: Int - - /** The expected type of the field. This information is used for automatic - * transformation of the field value into a usable type. - */ - def datatype: DataType - - /** The name of the catalog in the database from which the field originates */ - def catalog: String - - /** The name of the schema in the database from which the field originates */ - def schema: String - - /** The name of the table in the database from which the field originates */ - def table: String - -} diff --git a/src/dbc/scala/dbc/result/Relation.scala b/src/dbc/scala/dbc/result/Relation.scala deleted file mode 100644 index 98d653d61e..0000000000 --- a/src/dbc/scala/dbc/result/Relation.scala +++ /dev/null @@ -1,84 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package result - - -/** An ISO-9075:2003 (SQL) table. This is equivalent to a relation in the - * relational model. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Relation -extends collection.AbstractIterable[Tuple] - with Iterable[Tuple] { - - /** The statement that generated this relation. */ - def statement: scala.dbc.statement.Relation - - /** A JDBC result containing this relation. */ - protected def sqlResult: java.sql.ResultSet - - /** A JDBC metadata object attached to the relation. */ - protected def sqlMetadata: java.sql.ResultSetMetaData = sqlResult.getMetaData() - - /** Metadata about all fields in a tuple of the relation. */ - def metadata: List[FieldMetadata] = - for (count <- List.range(1, sqlMetadata.getColumnCount()+1)) yield - new FieldMetadata { - val name: String = sqlMetadata.getColumnName(count) - val index: Int = count - val datatype: DataType = dbc.datatype.Factory.create(sqlMetadata,count) - val catalog: String = sqlMetadata.getCatalogName(count) - val schema: String = sqlMetadata.getSchemaName(count) - val table: String = sqlMetadata.getTableName(count) - } - - /** Metadata about the field at the given index. If there is no such - * field None is returned instead. */ - def metadataFor (index:Int): Option[FieldMetadata] = { - val meta = metadata - if (meta.length > index) - Some(meta(index)) - else - None - } - - /** Metadata about the field with the given column name. If there is no - * such field, None is returned instead. */ - def metadataFor (name:String): Option[FieldMetadata] = - metadata.find(f=>(f.name==name)); - - /** An iterator on the tuples of the relation. - *

Caution

A Relation only has one single iterator, due to limitations - * in DBMS. This means that if this method is called multiple times, all returned - * iterators will share the same state. */ - def iterator: Iterator[Tuple] = new collection.AbstractIterator[Tuple] { - protected val result: java.sql.ResultSet = Relation.this.sqlResult - def hasNext: Boolean = resultNext - private var resultNext = result.next() - def next: Tuple = { - if (resultNext) { - val newTuple = new Tuple { - val me = this - val originatingRelation = Relation.this - val fields: List[Field] = for (fieldMetadata <- metadata) yield - new Field { - val metadata = fieldMetadata - val content = dbc.value.Factory.create(result,metadata.index,metadata.datatype) - val originatingTuple = me - } - } - resultNext = result.next() - newTuple - } - else sys.error("next on empty iterator") - } - } - -} diff --git a/src/dbc/scala/dbc/result/Status.scala b/src/dbc/scala/dbc/result/Status.scala deleted file mode 100644 index d3152a58ab..0000000000 --- a/src/dbc/scala/dbc/result/Status.scala +++ /dev/null @@ -1,28 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package result; - - -import scala.dbc.datatype._; - -/** An object containing the status of a query */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Status[ResultType] { - - /** The statement that generated this status result. */ - def statement: scala.dbc.statement.Statement; - - /** The number of elements modified or added by this statement. */ - def touchedCount: Option[Int]; - - def result: ResultType; - -} diff --git a/src/dbc/scala/dbc/result/Tuple.scala b/src/dbc/scala/dbc/result/Tuple.scala deleted file mode 100644 index 80ab5c22aa..0000000000 --- a/src/dbc/scala/dbc/result/Tuple.scala +++ /dev/null @@ -1,42 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package result; - - -/** An ISO-9075:2003 (SQL) table row. This is equivalent to a tuple in the relational model. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Tuple { - - /** All the fields contained in the tuple. */ - def fields: List[Field]; - - /** The relation that contains the tuple. */ - def originatingRelation: Relation; - - /** The field at the given index. If there is no such field (that is the index is out of bounds), None is returned instead. */ - def apply (index:Int): Field = - try { - fields(index) - } catch { - case e => - throw new java.lang.IndexOutOfBoundsException("Field at index "+index+" does not exist in relation"); - } - - /** The field with the given column name. If there is no such field, None is returned instead. */ - def apply (name:String): Field = { - def findField (fields: List[Field], name:String): Field = fields match { - case Nil => throw new java.lang.IndexOutOfBoundsException("Field '"+name+"' does not exist in relation") - case field :: _ if (field.metadata.name == name) => field - case field :: fields => findField (fields, name) - } - findField (fields, name); - } -} diff --git a/src/dbc/scala/dbc/statement/AccessMode.scala b/src/dbc/scala/dbc/statement/AccessMode.scala deleted file mode 100644 index 885e0012f2..0000000000 --- a/src/dbc/scala/dbc/statement/AccessMode.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class AccessMode { - def sqlString: String -} - -@deprecated(DbcIsDeprecated, "2.9.0") object AccessMode { - case object ReadOnly extends AccessMode { - def sqlString = "READ ONLY" - } - case object ReadWrite extends AccessMode { - def sqlString = "READ WRITE" - } -} diff --git a/src/dbc/scala/dbc/statement/DerivedColumn.scala b/src/dbc/scala/dbc/statement/DerivedColumn.scala deleted file mode 100644 index ae05df986a..0000000000 --- a/src/dbc/scala/dbc/statement/DerivedColumn.scala +++ /dev/null @@ -1,38 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class DerivedColumn { - - /** The value for the column. This value can be of any type but must be - * calculated from fields that appear in a relation that takes part - * in the query. - */ - def valueExpression: Expression - - /** A new name for this field. This name must be unique for the query in - * which the column takes part. - */ - def asClause: Option[String] - - /** A SQL-99 compliant string representation of the derived column - * sub-statement. This only has a meaning inside a select statement. - */ - def sqlString: String = - valueExpression.sqlInnerString + - (asClause match { - case None => "" - case Some(ac) => " AS " + ac - }) - -} diff --git a/src/dbc/scala/dbc/statement/Expression.scala b/src/dbc/scala/dbc/statement/Expression.scala deleted file mode 100644 index c2da91e9ef..0000000000 --- a/src/dbc/scala/dbc/statement/Expression.scala +++ /dev/null @@ -1,28 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -/** An expression that calculates some value from fields. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Expression extends Relation { - - def fieldTypes: List[DataType] = Nil - - /** A SQL-99 compliant string representation of the expression. */ - def sqlString: String = "SELECT " + sqlInnerString - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. - */ - def sqlInnerString: String - -} diff --git a/src/dbc/scala/dbc/statement/Insert.scala b/src/dbc/scala/dbc/statement/Insert.scala deleted file mode 100644 index 189ccec54f..0000000000 --- a/src/dbc/scala/dbc/statement/Insert.scala +++ /dev/null @@ -1,31 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -import scala.dbc.statement.expression._ - -/** An insertion of values into a table. */ -@deprecated(DbcIsDeprecated, "2.9.0") case class Insert(insertionTarget: String, insertionData: InsertionData) - extends Status { - - /** A SQL-99 compliant string representation of the select statement. */ - def sqlString: String = - "INSERT INTO " + insertionTarget + " " + insertionData.sqlString - - /** The name of the table where the data should be added. */ - //def insertionTarget: String - - /** The data that will be added tot he table. */ - //def insertionData: InsertionData - -} diff --git a/src/dbc/scala/dbc/statement/InsertionData.scala b/src/dbc/scala/dbc/statement/InsertionData.scala deleted file mode 100644 index e91ad7efe6..0000000000 --- a/src/dbc/scala/dbc/statement/InsertionData.scala +++ /dev/null @@ -1,40 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -import scala.dbc.statement.expression._ - -/** Data to be inserted into a table in an Insert. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class InsertionData { - def sqlString: String -} - -@deprecated(DbcIsDeprecated, "2.9.0") object InsertionData { - /** Insertion of data resulting from a query on the database. */ - @deprecated(DbcIsDeprecated, "2.9.0") case class Subquery(query: Relation) extends InsertionData { - def sqlString = query.sqlString - } - /** Insertion of data as explicitly defined values. */ - @deprecated(DbcIsDeprecated, "2.9.0") case class Constructor( - columnNames: Option[List[String]], - columnValues: List[Expression] - ) extends InsertionData { - def sqlString = - (columnNames match { - case None => "" - case Some(cn) => cn.mkString(" (",", ",")") - }) + - " VALUES" + - columnValues.map(e => e.sqlInnerString).mkString(" (",", ",")") - } -} diff --git a/src/dbc/scala/dbc/statement/IsolationLevel.scala b/src/dbc/scala/dbc/statement/IsolationLevel.scala deleted file mode 100644 index b31614c3dd..0000000000 --- a/src/dbc/scala/dbc/statement/IsolationLevel.scala +++ /dev/null @@ -1,32 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class IsolationLevel { - def sqlString: String -} - -@deprecated(DbcIsDeprecated, "2.9.0") object IsolationLevel { - case object ReadUncommitted extends IsolationLevel { - def sqlString = "ISOLATION LEVEL READ UNCOMMITTED" - } - case object ReadCommitted extends IsolationLevel { - def sqlString = "ISOLATION LEVEL READ COMMITTED" - } - case object RepeatableRead extends IsolationLevel { - def sqlString = "ISOLATION LEVEL REPEATABLE READ" - } - case object Serializable extends IsolationLevel { - def sqlString = "ISOLATION LEVEL SERIALIZABLE" - } -} diff --git a/src/dbc/scala/dbc/statement/JoinType.scala b/src/dbc/scala/dbc/statement/JoinType.scala deleted file mode 100644 index 698612b10d..0000000000 --- a/src/dbc/scala/dbc/statement/JoinType.scala +++ /dev/null @@ -1,56 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -/** A join behaviour in a Jointure. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class JoinType { - /** A SQL-99 string representation of the join behaviour. */ - def sqlString: String -} - -@deprecated(DbcIsDeprecated, "2.9.0") object JoinType { - - /** A join behaviour where a joined tuple is created only when a - * corresponding tuple exists in both original relations. - */ - case object Inner extends JoinType { - val sqlString = "INNER JOIN" - } - - /** A join behaviour family where a joined tuple is created even when a - * tuple has no corresponding tuple in the other relation. The fields - * populated by values of the other tuple will receive the NULL value. - */ - abstract class Outer extends JoinType - - object Outer { - /** An outer join behaviour where there will be at least on tuple for - * every tuple in the left relation. - */ - case object Left extends Outer { - val sqlString = "LEFT OUTER JOIN" - } - /** An outer join behaviour where there will be at least on tuple for - * every tuple in the right relation. - */ - case object Right extends Outer { - val sqlString = "RIGHT OUTER JOIN" - } - /** An outer join behaviour where there will be at least on tuple for - * every tuple in both right and left relations. - */ - case object Full extends Outer { - val sqlString = "FULL OUTER JOIN" - } - } -} diff --git a/src/dbc/scala/dbc/statement/Jointure.scala b/src/dbc/scala/dbc/statement/Jointure.scala deleted file mode 100644 index 74c871cc3e..0000000000 --- a/src/dbc/scala/dbc/statement/Jointure.scala +++ /dev/null @@ -1,45 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -/** A jointure between two relations. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Jointure extends Relation { - - /** The relation on the left part of the join. */ - def leftRelation: Relation - - /** The relation on the right part of the join. */ - def rightRelation: Relation - - /** The type of the jointure. */ - def joinType: JoinType - - /** The condition on which the jointure needs be done. */ - def joinCondition: Option[Expression] - - /** A SQL-99 compliant string representation of the relation statement. */ - def sqlString: String = "SELECT * FROM " + sqlInnerString - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside a query. - */ - def sqlInnerString: String = - leftRelation.sqlInnerString + " " + - joinType.sqlString + " " + - rightRelation.sqlInnerString + - (joinCondition match { - case Some(jc) => jc.sqlString - case None => "" - }) - -} diff --git a/src/dbc/scala/dbc/statement/Relation.scala b/src/dbc/scala/dbc/statement/Relation.scala deleted file mode 100644 index 787707ee82..0000000000 --- a/src/dbc/scala/dbc/statement/Relation.scala +++ /dev/null @@ -1,55 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement; - - -/** A statement that returns a relation. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Relation extends Statement { - - def isCompatibleType: (DataType,DataType)=>Boolean = - ((dt,wdt)=>dt.isSubtypeOf(wdt)); - - def typeCheck (relation: result.Relation): Unit = { - val sameType: Boolean = ( - relation.metadata.length == fieldTypes.length && - (relation.metadata.zip(fieldTypes).forall({case Pair(field,expectedType) => - isCompatibleType(field.datatype, expectedType)})) - ); - if (!sameType) - throw new exception.IncompatibleSchema(fieldTypes,relation.metadata.map(field=>field.datatype)); - } - - def fieldTypes: List[DataType]; - - def sqlTypeString: String = - if (fieldTypes.isEmpty) - "UNTYPED" - else - fieldTypes.map(dt=>dt.sqlString).mkString("RELATION (",", ",")"); - - /** A SQL-99 compliant string representation of the statement. */ - def sqlString: String; - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. */ - def sqlInnerString: String; - - /** Executes the statement on the given database. */ - def execute (database: scala.dbc.Database): scala.dbc.result.Relation = { - database.executeStatement(this); - } - - def execute (database:scala.dbc.Database, debug:Boolean): scala.dbc.result.Relation = { - database.executeStatement(this,debug); - } - -} diff --git a/src/dbc/scala/dbc/statement/Select.scala b/src/dbc/scala/dbc/statement/Select.scala deleted file mode 100644 index a9ca0212ed..0000000000 --- a/src/dbc/scala/dbc/statement/Select.scala +++ /dev/null @@ -1,99 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -/** A statement that when executed on a database will return a relation. - * The returned relation will be a subset of a table in the database or - * a jointure between such subsets. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Select extends Relation { - - /** Defines if duplicated tuples should be removed from the returned - * relation.

Compatibility notice

Some DBMS (PostgreSQL) allow - * uniqueness constrains on an arbitrary field instead of the entire - * tuple. */ - def setQuantifier: Option[SetQuantifier] - - /** Defines the output fields that a tuple in the returned relation will - * contain, and their content with respect to the tables in the - * database. If the fields are not specified (that is the list is - * empty), all possible input fields will be returned.

Compatibility - * notice

SQL's qualified asterisk select sublist is not - * available. */ - def selectList: List[DerivedColumn] - - /** Defines the relations from which the query will obtain its data.*/ - def fromClause: List[Relation] - - /** Defines condition that must be true in the returned relation's tuples. - * This value expression must return a boolean or boolean-compatible - * value. This condition is applied before any GROUP BY clause. - */ - def whereClause: Option[Expression] - - /** Defines the grouping of the returned relation's tuples. One tuple is - * returned for every group. The value of selectList must - * use aggregate functions for calculation. - */ - def groupByClause: Option[List[Expression]] - - /** Defines conditions that must be true in the returned relation's tuples. - * The value expression must return a boolean can only refer to fields - * that are grouped or to any field from inside an aggregate function. - */ - def havingClause: Option[Expression] - - /* def windowClause: Option[_]; */ - - /** A SQL-99 compliant string representation of the select statement. */ - def sqlString: String = ( - "SELECT" + - (setQuantifier match { - case None => "" - case Some(sq) => " " + sq.sqlString - }) + - (selectList match { - case Nil => " *" - case _ => (" " + selectList.tail.foldLeft(selectList.head.sqlString) - ((name:String, dc:DerivedColumn) => name + ", " + dc.sqlString)) - }) + - (fromClause match { - case Nil => sys.error("Empty from clause is not allowed") - case _ => (" FROM " + fromClause.tail.foldLeft(fromClause.head.sqlInnerString) - ((name:String, rel:Relation) => name + ", " + rel.sqlInnerString)) - }) + - (whereClause match { - case None => "" - case Some(expr) => " WHERE " + expr.sqlInnerString - }) + - (groupByClause match { - case None => "" - case Some(gbl) => gbl match { - case Nil => sys.error("Empty group by clause is not allowed") - case _ => - (" GROUP BY " + - gbl.tail.foldLeft(gbl.head.sqlInnerString) - ((name:String, gb) => name + ", " + gb.sqlInnerString)) - } - }) + - (havingClause match { - case None => "" - case Some(expr) => " HAVING " + expr.sqlString - }) - ); - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside a query. - */ - def sqlInnerString: String = "("+sqlString+")" - -} diff --git a/src/dbc/scala/dbc/statement/SetClause.scala b/src/dbc/scala/dbc/statement/SetClause.scala deleted file mode 100644 index 3af509c026..0000000000 --- a/src/dbc/scala/dbc/statement/SetClause.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -import scala.dbc.statement.expression._ - -/** Data to be inserted into a table in an Insert. */ -@deprecated(DbcIsDeprecated, "2.9.0") case class SetClause(name: String, expr: Expression) { - val value: Pair[String,Expression] = (name, expr) - def sqlString: String = value._1 + " = " + value._2.sqlInnerString -} diff --git a/src/dbc/scala/dbc/statement/SetQuantifier.scala b/src/dbc/scala/dbc/statement/SetQuantifier.scala deleted file mode 100644 index 77a4b79b8d..0000000000 --- a/src/dbc/scala/dbc/statement/SetQuantifier.scala +++ /dev/null @@ -1,38 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -/** A set quantifier that defines the collection type of a relation. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class SetQuantifier { - /** A SQL-99 compliant string representation of the set quantifier. */ - def sqlString: String -} - -@deprecated(DbcIsDeprecated, "2.9.0") object SetQuantifier { - - /** A set quantifier that defines a relation as being a bag. That means - * that duplicates are allowed. - */ - case object AllTuples extends SetQuantifier { - /** A SQL-99 compliant string representation of the set quantifier. */ - def sqlString: String = "ALL" - } - - /** A set quantifier that defines a relation as being a set. That means - * that duplicates are not allowed and will be pruned. - */ - case object DistinctTuples extends SetQuantifier { - /** A SQL-99 compliant string representation of the set quantifier. */ - def sqlString: String = "DISTINCT" - } -} diff --git a/src/dbc/scala/dbc/statement/Statement.scala b/src/dbc/scala/dbc/statement/Statement.scala deleted file mode 100644 index fc5374262d..0000000000 --- a/src/dbc/scala/dbc/statement/Statement.scala +++ /dev/null @@ -1,16 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -/** An ISO-9075:2003 (SQL) statement. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Statement diff --git a/src/dbc/scala/dbc/statement/Status.scala b/src/dbc/scala/dbc/statement/Status.scala deleted file mode 100644 index 0ce64b978d..0000000000 --- a/src/dbc/scala/dbc/statement/Status.scala +++ /dev/null @@ -1,32 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - -import scala.dbc.Database -import scala.dbc.result - -/** A statement that changes the status of the database. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Status extends Statement { - - /** A SQL-99 compliant string representation of the statement. */ - def sqlString: String - - /** Executes the statement on the given database. */ - def execute(database: Database): result.Status[Unit] = { - database.executeStatement(this) - } - - def execute(database: Database, debug: Boolean): result.Status[Unit] = { - database.executeStatement(this, debug) - } - -} diff --git a/src/dbc/scala/dbc/statement/Table.scala b/src/dbc/scala/dbc/statement/Table.scala deleted file mode 100644 index e729f801a3..0000000000 --- a/src/dbc/scala/dbc/statement/Table.scala +++ /dev/null @@ -1,38 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement - - -/** A reference to a table in the database. - * @author Gilles Dubochet - * @version 1.0 */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Table extends Relation { - - /** The name of the table in the database. */ - def tableName: String - - /** The name that the table will be called in the enclosing statement. */ - def tableRename: Option[String] - - /** A SQL-99 compliant string representation of the relation statement. */ - def sqlString: String = "SELECT * FROM " + tableName - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside a query. */ - def sqlInnerString: String = - tableName + - (tableRename match { - case None => "" - case Some(rename) => " AS " + rename - }) - -} diff --git a/src/dbc/scala/dbc/statement/Transaction.scala b/src/dbc/scala/dbc/statement/Transaction.scala deleted file mode 100644 index 1740dae3f9..0000000000 --- a/src/dbc/scala/dbc/statement/Transaction.scala +++ /dev/null @@ -1,55 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement; - - -/** A statement that changes the status of the database. */ -@deprecated(DbcIsDeprecated, "2.9.0") case class Transaction [ResultType] ( - transactionBody: (scala.dbc.Database=>ResultType), - accessMode: Option[AccessMode], - isolationLevel: Option[IsolationLevel] -) extends Statement { - - /** A SQL-99 compliant string representation of the statement. */ - def sqlStartString: String = ( - "START TRANSACTION" + - (Pair(accessMode,isolationLevel) match { - case Pair(None,None) => "" - case Pair(Some(am),None) => " " + am.sqlString - case Pair(None,Some(il)) => " " + il.sqlString - case Pair(Some(am),Some(il)) => " " + am.sqlString + ", " + il.sqlString - }) - ); - - def sqlCommitString: String = { - "COMMIT" - } - - def sqlAbortString: String = { - "ROLLBACK" - } - - //def transactionBody: (()=>Unit); - - //def accessMode: Option[AccessMode]; - - //def isolationLevel: Option[IsolationLevel]; - - def execute (database: scala.dbc.Database): scala.dbc.result.Status[ResultType] = { - database.executeStatement(this); - } - - def execute (database: scala.dbc.Database, debug: Boolean): scala.dbc.result.Status[ResultType] = { - database.executeStatement(this,debug); - } - -} diff --git a/src/dbc/scala/dbc/statement/Update.scala b/src/dbc/scala/dbc/statement/Update.scala deleted file mode 100644 index 836549a4be..0000000000 --- a/src/dbc/scala/dbc/statement/Update.scala +++ /dev/null @@ -1,47 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement; - - -import scala.dbc.statement.expression._; - -/** An update of the state of a table. */ -@deprecated(DbcIsDeprecated, "2.9.0") case class Update ( - updateTarget: String, - setClauses: List[SetClause], - whereClause: Option[Expression] -) extends Status { - - - /** A SQL-99 compliant string representation of the select statement. */ - def sqlString: String = ( - "UPDATE " + - updateTarget + - " SET " + setClauses.map(sc=>sc.sqlString).mkString("",", ","") + - (whereClause match { - case None => "" - case Some(expr) => " WHERE " + expr.sqlString - }) - ); - - /** The name of the table that should be updated. */ - //def updateTarget: String; - - /** The data that will be added tot he table. */ - //def setClauses: List[SetClause]; - - /** Defines condition that must be true in the tuples that will be updated. - * This value expression must return a boolean or boolean-compatible - * value. */ - //def whereClause: Option[scala.dbc.statement.expression.Expression]; - -} diff --git a/src/dbc/scala/dbc/statement/expression/Aggregate.scala b/src/dbc/scala/dbc/statement/expression/Aggregate.scala deleted file mode 100644 index c42bffe20e..0000000000 --- a/src/dbc/scala/dbc/statement/expression/Aggregate.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement -package expression - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Aggregate extends Expression { - - def aggregateName: String; - - def setFunction: SetFunction; - - def filterClause: Option[Expression]; - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. */ - def sqlInnerString: String = ( - aggregateName + - "(" + setFunction.sqlString + ")" + - (filterClause match { - case None => "" - case Some(fc) => " FILTER (WHERE " + fc.sqlString + ")" - }) - ) - -} diff --git a/src/dbc/scala/dbc/statement/expression/BinaryOperator.scala b/src/dbc/scala/dbc/statement/expression/BinaryOperator.scala deleted file mode 100644 index 32f016dbf6..0000000000 --- a/src/dbc/scala/dbc/statement/expression/BinaryOperator.scala +++ /dev/null @@ -1,33 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement -package expression; - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class BinaryOperator extends Expression { - - /** The name of the operator. */ - def operator: String; - - /** The expression applied on the left of the operator. */ - def leftOperand: Expression; - - /** The expression applied on the right of the operator. */ - def rightOperand: Expression; - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. */ - def sqlInnerString: String = { - leftOperand.sqlInnerString + " " + operator + " " + rightOperand.sqlInnerString - } - -} diff --git a/src/dbc/scala/dbc/statement/expression/Constant.scala b/src/dbc/scala/dbc/statement/expression/Constant.scala deleted file mode 100644 index 70ec7819dc..0000000000 --- a/src/dbc/scala/dbc/statement/expression/Constant.scala +++ /dev/null @@ -1,23 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement -package expression; - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Constant extends Expression { - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. */ - def sqlInnerString: String = constantValue.sqlString; - - /** The value of the constant. */ - def constantValue: Value; -} diff --git a/src/dbc/scala/dbc/statement/expression/Default.scala b/src/dbc/scala/dbc/statement/expression/Default.scala deleted file mode 100644 index 78204d0172..0000000000 --- a/src/dbc/scala/dbc/statement/expression/Default.scala +++ /dev/null @@ -1,22 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement -package expression; - - -case object Default extends Expression { - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. */ - def sqlInnerString: String = "DEFAULT"; - -} diff --git a/src/dbc/scala/dbc/statement/expression/Field.scala b/src/dbc/scala/dbc/statement/expression/Field.scala deleted file mode 100644 index 9a90903a99..0000000000 --- a/src/dbc/scala/dbc/statement/expression/Field.scala +++ /dev/null @@ -1,40 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement -package expression; - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Field extends Expression { - - /** The name of the schema in the database where the field is located. */ - def schemaName: Option[String] = None; - - /** The name of the table in the database where the field is located. */ - def tableName: Option[String]; - - /** The name of the field in the database. */ - def fieldName: String; - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. */ - def sqlInnerString: String = ( - (schemaName match { - case None => "" - case Some(sn) => sn + "." - }) + - (tableName match { - case None => "" - case Some(tn) => tn + "." - }) + fieldName - ) - -} diff --git a/src/dbc/scala/dbc/statement/expression/FunctionCall.scala b/src/dbc/scala/dbc/statement/expression/FunctionCall.scala deleted file mode 100644 index 962cf209b9..0000000000 --- a/src/dbc/scala/dbc/statement/expression/FunctionCall.scala +++ /dev/null @@ -1,33 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement -package expression; - - -@deprecated(DbcIsDeprecated, "2.9.0") case class FunctionCall ( - functionName: String, - arguments: List[Expression] -) extends Expression { - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. */ - def sqlInnerString: String = { - functionName + "(" + arguments.mkString("",", ","") + ")" - } - - /** The name of the function to call. */ - //def functionName: String; - - /** A list of all argument expressions to pass to the function, in order. */ - //def arguments: List[Expression]; - -} diff --git a/src/dbc/scala/dbc/statement/expression/Select.scala b/src/dbc/scala/dbc/statement/expression/Select.scala deleted file mode 100644 index 7a6a4a21c4..0000000000 --- a/src/dbc/scala/dbc/statement/expression/Select.scala +++ /dev/null @@ -1,28 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement -package expression; - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Select extends Expression { - - /** The actual select statement */ - def selectStatement: statement.Select; - - /** A SQL-99 compliant string representation of the expression. */ - override def sqlString: String = selectStatement.sqlString; - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. */ - def sqlInnerString: String = "("+selectStatement.sqlString+")"; - -} diff --git a/src/dbc/scala/dbc/statement/expression/SetFunction.scala b/src/dbc/scala/dbc/statement/expression/SetFunction.scala deleted file mode 100644 index 060b2236f2..0000000000 --- a/src/dbc/scala/dbc/statement/expression/SetFunction.scala +++ /dev/null @@ -1,40 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement -package expression; - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class SetFunction { - /** A SQL-99 compliant string representation of the set quantifier. */ - def sqlString: String; -} - -@deprecated(DbcIsDeprecated, "2.9.0") object SetFunction { - abstract class Asterisk extends SetFunction { - def sqlString = "(*)"; - } - abstract class General extends SetFunction { - def setQuantifier: Option[SetQuantifier]; - def valueExpression: Expression; - def sqlString = ( - "(" + - (setQuantifier match { - case None => "" - case Some(sq) => sq.sqlString + " " - }) + - valueExpression.sqlString + ")" - ); - } - abstract class Binary extends SetFunction { - def sqlString = sys.error("Binary set function is not supported yet."); - } -} diff --git a/src/dbc/scala/dbc/statement/expression/TypeCast.scala b/src/dbc/scala/dbc/statement/expression/TypeCast.scala deleted file mode 100644 index dbb8dc1b4d..0000000000 --- a/src/dbc/scala/dbc/statement/expression/TypeCast.scala +++ /dev/null @@ -1,32 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement -package expression; - - -@deprecated(DbcIsDeprecated, "2.9.0") case class TypeCast ( - expression: Expression, - castType: DataType -) extends Expression { - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. */ - def sqlInnerString: String = { - "CAST (" + expression.sqlInnerString + " AS " + castType.sqlString + ")"; - } - - /** The expression that will be casted. */ - //def expression: Expression; - - /** The type to which to cast. */ - //def castType: scala.dbc.datatype.DataType; -} diff --git a/src/dbc/scala/dbc/statement/expression/UnaryOperator.scala b/src/dbc/scala/dbc/statement/expression/UnaryOperator.scala deleted file mode 100644 index 4172c451fb..0000000000 --- a/src/dbc/scala/dbc/statement/expression/UnaryOperator.scala +++ /dev/null @@ -1,33 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package statement -package expression; - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class UnaryOperator extends Expression { - - /** The name of the operator */ - def operator: String; - - /** Whether the operator comes before the operand or not. */ - def operatorIsLeft: Boolean; - - /** The operand applied to the operator. */ - def operand: Expression; - - /** A SQL-99 compliant string representation of the relation sub- - * statement. This only has a meaning inside another statement. */ - def sqlInnerString: String = operatorIsLeft match { - case true => operator + " " + operand.sqlInnerString; - case false => operand.sqlInnerString + " " + operator; - } -} diff --git a/src/dbc/scala/dbc/syntax/DataTypeUtil.scala b/src/dbc/scala/dbc/syntax/DataTypeUtil.scala deleted file mode 100644 index a0ebd1713e..0000000000 --- a/src/dbc/scala/dbc/syntax/DataTypeUtil.scala +++ /dev/null @@ -1,98 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package syntax; - - -import java.math.BigDecimal; -import java.math.BigInteger; - -@deprecated(DbcIsDeprecated, "2.9.0") object DataTypeUtil { - - final val java_lang_Integer_SIZE = 32; - final val java_lang_Long_SIZE = 64; - - def boolean = new datatype.Boolean; - def tinyint = new datatype.ExactNumeric[Byte](dbc.DataType.BYTE) { - val precisionRadix = 2; - val precision = 8; - val signed = true; - val scale = 0; - } - def smallint = new datatype.ExactNumeric[Short](dbc.DataType.SHORT) { - val precisionRadix = 2; - val precision = 16; - val signed = true; - val scale = 0; - } - def integer = new datatype.ExactNumeric[Int](dbc.DataType.INT) { - val precisionRadix = 2; - val precision = 32; - val signed = true; - val scale = 0; - } - def bigint = new datatype.ExactNumeric[Long](dbc.DataType.LONG) { - val precisionRadix = 2; - val precision = 64; - val signed = true; - val scale = 0; - } - def numeric (_precision:Int): DataType = numeric(_precision,0); - def numeric (_precision:Int, _scale:Int): DataType = - Pair(datatype.Factory.bytePrecision(_precision,true,true),_scale == 0) match { - case Pair(bp,true) if (bp <= java_lang_Integer_SIZE) => - new datatype.ExactNumeric[Int](DataType.INT) { - val precisionRadix = 10; - val precision = _precision; - val signed = true; - val scale = 0; - } - case Pair(bp,true) if (bp <= java_lang_Long_SIZE) => - new datatype.ExactNumeric[Long](DataType.LONG) { - val precisionRadix = 10; - val precision = _precision; - val signed = true; - val scale = 0; - } - case Pair(_,true) => - new datatype.ExactNumeric[BigInteger](DataType.BIG_INTEGER) { - val precisionRadix = 10; - val precision = _precision; - val signed = true; - val scale = 0; - } - case Pair(_,false) => - new datatype.ExactNumeric[BigDecimal](DataType.BIG_DECIMAL) { - val precisionRadix = 10; - val precision = _precision; - val signed = true; - val scale = _scale; - } - } - def real = new datatype.ApproximateNumeric[Float](DataType.FLOAT) { - val precisionRadix = 2; - val precision = 64; - val signed = true; - } - def doublePrecision = new datatype.ApproximateNumeric[Double](DataType.DOUBLE) { - val precisionRadix = 2; - val precision = 128; - val signed = true; - } - def character (_length: Int) = new datatype.Character { - val length = _length; - } - def characterVarying (_length: Int) = new datatype.CharacterVarying { - def length = _length; - } - def characterLargeObject = new datatype.CharacterLargeObject; - -} diff --git a/src/dbc/scala/dbc/syntax/Database.scala b/src/dbc/scala/dbc/syntax/Database.scala deleted file mode 100644 index 4357fb7d4c..0000000000 --- a/src/dbc/scala/dbc/syntax/Database.scala +++ /dev/null @@ -1,33 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package syntax; - - -import java.net.URI; - -@deprecated(DbcIsDeprecated, "2.9.0") object Database { - - def database (server:String, username:String, password:String): dbc.Database = { - val uri = new URI(server); - // Java 1.5 if (uri.toString().contains("postgres")) { - if (uri.toString().indexOf("postgres") != -1) { - new dbc.Database(new vendor.PostgreSQL { - val uri = new URI(server); - val user = username; - val pass = password; - }) - } else { - throw new Exception("No DBMS vendor support could be found for the given URI"); - } - } - -} diff --git a/src/dbc/scala/dbc/syntax/Statement.scala b/src/dbc/scala/dbc/syntax/Statement.scala deleted file mode 100644 index baccbfaa64..0000000000 --- a/src/dbc/scala/dbc/syntax/Statement.scala +++ /dev/null @@ -1,274 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package syntax; - - -import java.math.BigDecimal; -import java.math.BigInteger; - -import StatementExpression._; - -/* - -ASSUMPTIONS: - -IMPROVABLE: -For type safety, all types must be defined. If one is missing, none is taken into account. -It is possible to redefine many types or renamings for a field, in that case, - only the last one is taken into account ("a" as "b" as "c" of boolean as "e" of integer - is equivalent to "a" as "e" of integer). - -FIXED: - -*/ - -@deprecated(DbcIsDeprecated, "2.9.0") object Statement { - - // SELECT ZYGOTE ... - - def select: SelectZygote = new SelectZygote { - val setQuantifier = None; - } - def selectBag: SelectZygote = new SelectZygote { - val setQuantifier = Some(statement.SetQuantifier.AllTuples); - } - def selectSet: SelectZygote = new SelectZygote { - val setQuantifier = Some(statement.SetQuantifier.DistinctTuples); - } - - abstract class SelectZygote { - def setQuantifier: Option[statement.SetQuantifier]; - def fields (sdc:SelectDerivedColumns): SelectOf = new SelectOf { - val setQuantifier = SelectZygote.this.setQuantifier; - val selectList = sdc.selectList; - val selectTypes = sdc.selectTypes; - } - } - - abstract class SelectDerivedField { - def fieldValue: StatementField; - def fieldRename: Option[String] = {val x = None; x} - def fieldType: Option[dbc.DataType] = {val x = None; x} - def as (rename:String): SelectDerivedField = new SelectDerivedField { - val fieldValue = SelectDerivedField.this.fieldValue; - override val fieldRename = Some(rename); - override val fieldType = SelectDerivedField.this.fieldType; - } - def of (datatype:dbc.DataType): SelectDerivedField = new SelectDerivedField { - val fieldValue = SelectDerivedField.this.fieldValue; - override val fieldRename = SelectDerivedField.this.fieldRename; - override val fieldType = Some(datatype); - } - } - - implicit def statementFieldToSelectDerivedField (fv:StatementField): SelectDerivedField = new SelectDerivedField { - val fieldValue = fv; - } - - implicit def stringToSelectDerivedField (fv:String): SelectDerivedField = new SelectDerivedField { - val fieldValue: StatementField = StatementExpression.stringToStatementField(fv); - } - - abstract class SelectDerivedColumns { - def selectList: List[statement.DerivedColumn]; - def selectTypes: List[DataType]; - def and (sdc:SelectDerivedColumns): SelectDerivedColumns = new SelectDerivedColumns { - val selectList = SelectDerivedColumns.this.selectList ::: sdc.selectList; - val selectTypes = - if (SelectDerivedColumns.this.selectTypes.isEmpty | sdc.selectTypes.isEmpty) - Nil - else - SelectDerivedColumns.this.selectTypes ::: sdc.selectTypes; - } - } - - implicit def selectDerivedFieldToSelectDerivedColumns (sdf:SelectDerivedField): SelectDerivedColumns = new SelectDerivedColumns { - val selectList = List(new statement.DerivedColumn { - val valueExpression = sdf.fieldValue.toStatement; - val asClause = sdf.fieldRename; - }); - val selectTypes = if (sdf.fieldType.isEmpty) Nil else List(sdf.fieldType.get); - } - - implicit def stringToSelectDerivedColumns (sdfs:String): SelectDerivedColumns = { - val sdf: SelectDerivedField = sdfs; - selectDerivedFieldToSelectDerivedColumns(sdf); - } - - // SELECT OF ... - - abstract class SelectOf { - def setQuantifier: Option[statement.SetQuantifier]; - def selectList: List[statement.DerivedColumn]; - def selectTypes: List[DataType]; - def from (sst:SelectSourceTables): SelectBeyond = new SelectBeyond { - val setQuantifier = SelectOf.this.setQuantifier; - val selectList = SelectOf.this.selectList; - val selectTypes = SelectOf.this.selectTypes; - val fromClause = sst.fromClause; - val whereClause = None; - val groupByClause = None; - val havingClause = None; - } - } - - abstract class SelectSourceTable { - def fromRelation: statement.Relation; - def innerJoin (sst: SelectSourceTable): SelectSourceTable = new SelectSourceTable { - val fromRelation = new statement.Jointure { - val leftRelation = SelectSourceTable.this.fromRelation; - val rightRelation = sst.fromRelation; - val joinType = statement.JoinType.Inner; - val joinCondition = None; - val fieldTypes = leftRelation.fieldTypes ::: rightRelation.fieldTypes; - } - } - def leftOuterJoin (sst: SelectSourceTable): SelectSourceTable = new SelectSourceTable { - val fromRelation = new statement.Jointure { - val leftRelation = SelectSourceTable.this.fromRelation; - val rightRelation = sst.fromRelation; - val joinType = statement.JoinType.Outer.Left; - val joinCondition = None; - val fieldTypes = leftRelation.fieldTypes ::: rightRelation.fieldTypes; - } - } - def rightOuterJoin (sst: SelectSourceTable): SelectSourceTable = new SelectSourceTable { - val fromRelation = new statement.Jointure { - val leftRelation = SelectSourceTable.this.fromRelation; - val rightRelation = sst.fromRelation; - val joinType = statement.JoinType.Outer.Right; - val joinCondition = None; - val fieldTypes = leftRelation.fieldTypes ::: rightRelation.fieldTypes; - } - } - def fullOuterJoin (sst: SelectSourceTable): SelectSourceTable = new SelectSourceTable { - val fromRelation = new statement.Jointure { - val leftRelation = SelectSourceTable.this.fromRelation; - val rightRelation = sst.fromRelation; - val joinType = statement.JoinType.Outer.Full; - val joinCondition = None; - val fieldTypes = leftRelation.fieldTypes ::: rightRelation.fieldTypes; - } - } - } - - implicit def stringToSelectSourceTable (sct:String): SelectSourceTable = new SelectSourceTable { - val fromRelation = new statement.Table { - val tableName = sct; - val tableRename = None; - val fieldTypes = Nil; - } - } - - implicit def selectToSelectSourceTable (sct:statement.Select): SelectSourceTable = new SelectSourceTable { - val fromRelation = sct; - } - - abstract class SelectSourceTables { - def fromClause: List[statement.Relation]; - def join (sct:SelectSourceTable): SelectSourceTables = new SelectSourceTables { - val fromClause = SelectSourceTables.this.fromClause ::: List(sct.fromRelation); - } - } - - implicit def stringToSelectSourceTables (sct:String): SelectSourceTables = new SelectSourceTables { - val fromClause = List(new statement.Table { - val tableName = sct; - val tableRename = None; - val fieldTypes = Nil; - }); - } - - implicit def selectToSelectSourceTables (sct:statement.Select): SelectSourceTables = new SelectSourceTables { - val fromClause = List(sct); - } - - implicit def selectSourceTableToSelectSourceTables (sct:SelectSourceTable): SelectSourceTables = new SelectSourceTables { - val fromClause = List(sct.fromRelation); - } - - // SELECT BEYOND ... - - abstract class SelectBeyond { - def setQuantifier: Option[statement.SetQuantifier]; - def selectList: List[statement.DerivedColumn]; - def selectTypes: List[DataType]; - def fromClause: List[statement.Relation]; - def whereClause: Option[statement.Expression]; - def groupByClause: Option[List[statement.Expression]]; - def havingClause: Option[statement.Expression]; - def where (se:StatementExpression): SelectBeyond = new SelectBeyond { - val setQuantifier = SelectBeyond.this.setQuantifier; - val selectList = SelectBeyond.this.selectList; - val selectTypes = SelectBeyond.this.selectTypes; - val fromClause = SelectBeyond.this.fromClause; - val whereClause = Some(se.toStatement); - val groupByClause = SelectBeyond.this.groupByClause; - val havingClause = SelectBeyond.this.havingClause; - } - def groupBy (sgb:SelectGroupBy): SelectBeyond = new SelectBeyond { - val setQuantifier = SelectBeyond.this.setQuantifier; - val selectList = SelectBeyond.this.selectList; - val selectTypes = SelectBeyond.this.selectTypes; - val fromClause = SelectBeyond.this.fromClause; - val whereClause = SelectBeyond.this.whereClause; - val groupByClause = Some(sgb.groupByClause); - val havingClause = SelectBeyond.this.havingClause; - } - def having (se:StatementExpression): SelectBeyond = new SelectBeyond { - val setQuantifier = SelectBeyond.this.setQuantifier; - val selectList = SelectBeyond.this.selectList; - val selectTypes = SelectBeyond.this.selectTypes; - val fromClause = SelectBeyond.this.fromClause; - val whereClause = SelectBeyond.this.whereClause; - val groupByClause = SelectBeyond.this.groupByClause; - val havingClause = Some(se.toStatement); - } - } - - implicit def selectBeyondToStatementSelect (sb:SelectBeyond): statement.Select = new statement.Select { - val setQuantifier = sb.setQuantifier; - val selectList = sb.selectList; - val fromClause = sb.fromClause; - val whereClause = sb.whereClause; - val groupByClause = sb.groupByClause; - val havingClause = sb.havingClause; - val fieldTypes = sb.selectTypes; - } - - abstract class SelectGroupBy { - def groupByClause: List[statement.Expression]; - def then (se:StatementExpression): SelectGroupBy = new SelectGroupBy { - val groupByClause = - SelectGroupBy.this.groupByClause ::: List(se.toStatement); - } - def then (se:String): SelectGroupBy = new SelectGroupBy { - val groupByClause = - SelectGroupBy.this.groupByClause ::: List(new statement.expression.Field { - val tableName = None; - val fieldName = se; - }); - } - } - - implicit def statementExpressionToSelectGroupBy (se:StatementExpression): SelectGroupBy = new SelectGroupBy { - val groupByClause = List(se.toStatement); - } - - implicit def stringToSelectGroupBy (se:String): SelectGroupBy = new SelectGroupBy { - val groupByClause = List(new statement.expression.Field { - val tableName = None; - val fieldName = se; - }); - } - -} diff --git a/src/dbc/scala/dbc/syntax/StatementExpression.scala b/src/dbc/scala/dbc/syntax/StatementExpression.scala deleted file mode 100644 index 65bb0947f7..0000000000 --- a/src/dbc/scala/dbc/syntax/StatementExpression.scala +++ /dev/null @@ -1,221 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package syntax; - - -import java.math.BigDecimal; -import java.math.BigInteger; - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class StatementExpression { - - def toStatement: statement.Expression; - - def and (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "AND"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def or (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "OR"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def == (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "="; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def < (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "<"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def > (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = ">"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def <= (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "<="; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def >= (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = ">="; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def <> (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "<>"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def isNull: StatementExpression = new StatementExpression { - val toStatement = new statement.expression.UnaryOperator { - val operator = "IS NULL"; - val operatorIsLeft = false; - val operand = StatementExpression.this.toStatement; - } - } - def isNotNull: StatementExpression = new StatementExpression { - val toStatement = new statement.expression.UnaryOperator { - val operator = "IS NOT NULL"; - val operatorIsLeft = false; - val operand = StatementExpression.this.toStatement; - } - } - def + (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "+"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def - (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "-"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def * (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "*"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def / (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "/"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def % (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "%"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def ^ (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "^"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def not : StatementExpression = new StatementExpression { - val toStatement = new statement.expression.UnaryOperator { - val operator = "!"; - val operatorIsLeft = false; - val operand = StatementExpression.this.toStatement; - } - } - def || (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "||"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def like (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "LIKE"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def similar (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "SIMILAR"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = se.toStatement; - } - } - def in (se:statement.Select): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.BinaryOperator { - val operator = "IN"; - val leftOperand = StatementExpression.this.toStatement; - val rightOperand = new statement.expression.Select { - val selectStatement = se; - }; - } - } - -} - -@deprecated(DbcIsDeprecated, "2.9.0") object StatementExpression { - - def not (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.UnaryOperator { - val operator = "NOT"; - val operatorIsLeft = true; - val operand = se.toStatement; - } - } - def abs (se:StatementExpression): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.UnaryOperator { - val operator = "@"; - val operatorIsLeft = true; - val operand = se.toStatement; - } - } - def exists (se:statement.Select): StatementExpression = new StatementExpression { - val toStatement = new statement.expression.UnaryOperator { - val operator = "EXISTS"; - val operatorIsLeft = true; - val operand = new statement.expression.Select { - val selectStatement = se; - }; - } - } - - abstract class StatementField extends StatementExpression { - def fieldName: String; - def tableName: Option[String] = None; - def in (tn:String): StatementField = new StatementField { - val fieldName = StatementField.this.fieldName; - override val tableName = Some(tn); - } - def toStatement: statement.expression.Field = new statement.expression.Field { - override val schemaName = None; - val tableName = StatementField.this.tableName; - val fieldName = StatementField.this.fieldName; - } - } - - implicit def stringToStatementField (ef:String): StatementField = new StatementField { - val fieldName = ef; - } - - - - -} diff --git a/src/dbc/scala/dbc/value/ApproximateNumeric.scala b/src/dbc/scala/dbc/value/ApproximateNumeric.scala deleted file mode 100644 index fa47d8815b..0000000000 --- a/src/dbc/scala/dbc/value/ApproximateNumeric.scala +++ /dev/null @@ -1,28 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package value; - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class ApproximateNumeric [Type] extends Value { - - val dataType: datatype.ApproximateNumeric[Type]; - - def sqlString = nativeValue.toString(); - - } - -@deprecated(DbcIsDeprecated, "2.9.0") object ApproximateNumeric { - - implicit def approximateNumericToFloar (obj:value.ApproximateNumeric[Float]): Float = obj.nativeValue; - implicit def approximateNumericToDouble (obj:value.ApproximateNumeric[Double]): Double = obj.nativeValue; - -} diff --git a/src/dbc/scala/dbc/value/Boolean.scala b/src/dbc/scala/dbc/value/Boolean.scala deleted file mode 100644 index 5221ce2328..0000000000 --- a/src/dbc/scala/dbc/value/Boolean.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package value; - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Boolean extends Value { - - val dataType: datatype.Boolean; - - def sqlString = if (nativeValue) "TRUE" else "FALSE"; - -} - -@deprecated(DbcIsDeprecated, "2.9.0") object Boolean { - - implicit def booleanToBoolean (obj:value.Boolean): scala.Boolean = obj.nativeValue; - -} diff --git a/src/dbc/scala/dbc/value/Character.scala b/src/dbc/scala/dbc/value/Character.scala deleted file mode 100644 index 4ff983c591..0000000000 --- a/src/dbc/scala/dbc/value/Character.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package value; - - -/** A SQL-99 value of type character string. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Character extends Value { - - override val dataType: datatype.Character; - - /** An SQL-99 compliant string representation of the value. */ - def sqlString: String = { - "'" + nativeValue + "'" - } - -} - -/** An object offering transformation methods (views) on the value. - * This object must be visible in an expression to use value auto- - * conversion. */ -@deprecated(DbcIsDeprecated, "2.9.0") object Character { - - /** A character string value as a native string. */ - implicit def characterToString (obj:value.Character): String = obj.nativeValue; - -} diff --git a/src/dbc/scala/dbc/value/CharacterLargeObject.scala b/src/dbc/scala/dbc/value/CharacterLargeObject.scala deleted file mode 100644 index b9e81eb3af..0000000000 --- a/src/dbc/scala/dbc/value/CharacterLargeObject.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package value; - - -/** A SQL-99 value of type character large object. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class CharacterLargeObject extends Value { - - override val dataType: datatype.CharacterLargeObject; - - /** An SQL-99 compliant string representation of the value. */ - def sqlString: String = { - "'" + nativeValue + "'" - } - -} - -/** An object offering transformation methods (views) on the value. - * This object must be visible in an expression to use value auto- - * conversion. */ -@deprecated(DbcIsDeprecated, "2.9.0") object CharacterLargeObject { - - /** A character large object value as a native string. */ - implicit def characterLargeObjectToString (obj:value.CharacterLargeObject): String = obj.nativeValue; - -} diff --git a/src/dbc/scala/dbc/value/CharacterVarying.scala b/src/dbc/scala/dbc/value/CharacterVarying.scala deleted file mode 100644 index 72e7d06362..0000000000 --- a/src/dbc/scala/dbc/value/CharacterVarying.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package value; - - -/** A SQL-99 value of type character varying string. */ -@deprecated(DbcIsDeprecated, "2.9.0") abstract class CharacterVarying extends Value { - - override val dataType: datatype.CharacterVarying; - - /** An SQL-99 compliant string representation of the value. */ - def sqlString: String = { - "'" + nativeValue + "'" - } - -} - -/** An object offering transformation methods (views) on the value. - * This object must be visible in an expression to use value auto- - * conversion. */ -@deprecated(DbcIsDeprecated, "2.9.0") object CharacterVarying { - - /** A character varying string value as a native string. */ - implicit def characterVaryingToString (obj:value.CharacterVarying): String = obj.nativeValue; - -} diff --git a/src/dbc/scala/dbc/value/Conversion.scala b/src/dbc/scala/dbc/value/Conversion.scala deleted file mode 100644 index c9297e37db..0000000000 --- a/src/dbc/scala/dbc/value/Conversion.scala +++ /dev/null @@ -1,156 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package value; - -import java.math._; - -@deprecated(DbcIsDeprecated, "2.9.0") object Conversion { - - class Illegal (msg:String) extends Exception(msg); - - implicit def view1 (value:Value): Byte = { - if (value.dataType.nativeTypeId == DataType.BYTE) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]]; - v.nativeValue - } else { - throw new Illegal("Cannot convert value to byte: "+value) - } - } - - implicit def view2 (value:Value): Short = { - if (value.dataType.nativeTypeId == DataType.BYTE) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]]; - v.nativeValue.toShort - } else if (value.dataType.nativeTypeId == DataType.SHORT) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Short]]; - v.nativeValue - } else { - throw new Illegal("Cannot convert value to short: "+value) - } - } - - implicit def view3 (value:Value): Int = { - if (value.dataType.nativeTypeId == DataType.BYTE) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]]; - v.nativeValue.toInt - } else if (value.dataType.nativeTypeId == DataType.SHORT) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Short]]; - v.nativeValue.toInt - } else if (value.dataType.nativeTypeId == DataType.INT) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Int]]; - v.nativeValue - } else { - throw new Illegal("Cannot convert value to int: "+value) - } - } - - implicit def view4 (value:Value): Long = { - if (value.dataType.nativeTypeId == DataType.BYTE) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]]; - v.nativeValue.toLong - } else if (value.dataType.nativeTypeId == DataType.SHORT) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Short]]; - v.nativeValue.toLong - } else if (value.dataType.nativeTypeId == DataType.INT) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Int]]; - v.nativeValue.toLong - } else if (value.dataType.nativeTypeId == DataType.LONG) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Long]]; - v.nativeValue - } else { - throw new Illegal("Cannot convert value to long: "+value) - } - } - - implicit def view5 (value:Value): BigInteger = { - if (value.dataType.nativeTypeId == DataType.BYTE) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]]; - new BigInteger(v.nativeValue.toString(),10) - } else if (value.dataType.nativeTypeId == DataType.SHORT) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Short]]; - new BigInteger(v.nativeValue.toString(),10) - } else if (value.dataType.nativeTypeId == DataType.INT) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Int]]; - new BigInteger(v.nativeValue.toString(),10) - } else if (value.dataType.nativeTypeId == DataType.LONG) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Long]]; - new BigInteger(v.nativeValue.toString(),10) - } else if (value.dataType.nativeTypeId == DataType.BIG_INTEGER) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[BigInteger]]; - v.nativeValue - } else { - throw new Illegal("Cannot convert value to big integer: "+value) - } - } - - implicit def view6 (value:Value): BigDecimal = { - if (value.dataType.nativeTypeId == DataType.BYTE) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]]; - new BigDecimal(v.nativeValue.toString()) - } else if (value.dataType.nativeTypeId == DataType.SHORT) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Short]]; - new BigDecimal(v.nativeValue.toString()) - } else if (value.dataType.nativeTypeId == DataType.INT) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Int]]; - new BigDecimal(v.nativeValue.toString()) - } else if (value.dataType.nativeTypeId == DataType.LONG) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[Long]]; - new BigDecimal(v.nativeValue.toString()) - } else if (value.dataType.nativeTypeId == DataType.BIG_INTEGER) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[BigInteger]]; - new BigDecimal(v.nativeValue) - } else if (value.dataType.nativeTypeId == DataType.BIG_DECIMAL) { - val v = value.asInstanceOf[dbc.value.ExactNumeric[BigDecimal]]; - v.nativeValue - } else { - throw new Illegal("Cannot convert value to big decimal: "+value) - } - } - - implicit def view7 (value:Value): Float = { - if (value.dataType.nativeTypeId == DataType.FLOAT) { - val v = value.asInstanceOf[dbc.value.ApproximateNumeric[Float]]; - v.nativeValue - } else { - throw new Illegal("Cannot convert value to float: "+value) - } - } - - implicit def view8 (value:Value): Double = { - if (value.dataType.nativeTypeId == DataType.FLOAT) { - val v = value.asInstanceOf[dbc.value.ApproximateNumeric[Float]]; - v.nativeValue.toFloat - } else if (value.dataType.nativeTypeId == DataType.DOUBLE) { - val v = value.asInstanceOf[dbc.value.ApproximateNumeric[Double]]; - v.nativeValue - } else { - throw new Illegal("Cannot convert value to double: "+value) - } - } - - implicit def view9 (value:Value): scala.Boolean = { - if (value.dataType.nativeTypeId == DataType.BOOLEAN) { - val v = value.asInstanceOf[dbc.value.Boolean]; - v.nativeValue - } else { - throw new Illegal("Cannot convert value to boolean: "+value) - } - } - - implicit def view10 (value:Value): String = value match { - case v:dbc.value.Character => v.nativeValue; - case v:dbc.value.CharacterLargeObject => v.nativeValue; - case v:dbc.value.CharacterVarying => v.nativeValue; - case _ => throw new Illegal("Cannot convert value to string") - } - -} diff --git a/src/dbc/scala/dbc/value/ExactNumeric.scala b/src/dbc/scala/dbc/value/ExactNumeric.scala deleted file mode 100644 index 7cd8b89a8c..0000000000 --- a/src/dbc/scala/dbc/value/ExactNumeric.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package value; - - -import java.math.BigInteger; -import java.math.BigDecimal; - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class ExactNumeric [Type] extends Value { - - val dataType: datatype.ExactNumeric[Type]; - - def sqlString = nativeValue.toString(); - -} - -@deprecated(DbcIsDeprecated, "2.9.0") object ExactNumeric { - - implicit def exactNumericToByte (obj:value.ExactNumeric[Byte]): Byte = obj.nativeValue; - implicit def exactNumericToShort (obj:value.ExactNumeric[Short]): Short = obj.nativeValue; - implicit def exactNumericToInt (obj:value.ExactNumeric[Int]): Int = obj.nativeValue; - implicit def exactNumericToLong (obj:value.ExactNumeric[Long]): Long = obj.nativeValue; - implicit def exactNumericToBigInteger (obj:value.ExactNumeric[BigInteger]): BigInteger = obj.nativeValue; - implicit def exactNumericToBigDecimal (obj:value.ExactNumeric[BigDecimal]): BigDecimal = obj.nativeValue; - -} diff --git a/src/dbc/scala/dbc/value/Factory.scala b/src/dbc/scala/dbc/value/Factory.scala deleted file mode 100644 index 2d6101f6de..0000000000 --- a/src/dbc/scala/dbc/value/Factory.scala +++ /dev/null @@ -1,95 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package value; - - -import java.math.BigInteger; -import java.math.BigDecimal; - -@deprecated(DbcIsDeprecated, "2.9.0") object Factory { - - def create (result: java.sql.ResultSet, index: Int, expectedDataType: DataType): Value = { - expectedDataType.nativeTypeId match { - case DataType.OBJECT => - new value.Unknown { - val dataType = expectedDataType.asInstanceOf[datatype.Unknown]; - val nativeValue: AnyRef = result.getObject(index); - } - case DataType.STRING => { - expectedDataType match { - case t:datatype.Character => - new value.Character { - val dataType = t; - val nativeValue: String = result.getString(index); - } - case t:datatype.CharacterVarying => - new value.CharacterVarying { - val dataType = t; - val nativeValue: String = result.getString(index); - } - case t:datatype.CharacterLargeObject => - new value.CharacterLargeObject { - val dataType = t; - val nativeValue: String = result.getString(index); - } - } - } - case DataType.BOOLEAN => - new value.Boolean { - val dataType = expectedDataType.asInstanceOf[datatype.Boolean]; - val nativeValue: scala.Boolean = result.getBoolean(index); - } - case DataType.FLOAT => - new value.ApproximateNumeric[Float] { - val dataType = expectedDataType.asInstanceOf[datatype.ApproximateNumeric[Float]]; - val nativeValue: Float = result.getFloat(index); - } - case DataType.DOUBLE => - new value.ApproximateNumeric[Double] { - val dataType = expectedDataType.asInstanceOf[datatype.ApproximateNumeric[Double]]; - val nativeValue: Double = result.getDouble(index); - } - case DataType.BYTE => - new value.ExactNumeric[Byte] { - val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[Byte]]; - val nativeValue: Byte = result.getByte(index); - } - case DataType.SHORT => - new value.ExactNumeric[Short] { - val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[Short]]; - val nativeValue: Short = result.getShort(index); - } - case DataType.INT => - new value.ExactNumeric[Int] { - val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[Int]]; - val nativeValue: Int = result.getInt(index); - } - case DataType.LONG => - new value.ExactNumeric[Long] { - val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[Long]]; - val nativeValue:Long = result.getLong(index); - } - case DataType.BIG_INTEGER => - new value.ExactNumeric[BigInteger] { - val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[BigInteger]]; - val nativeValue: BigInteger = result.getBigDecimal(index).unscaledValue(); - } - case DataType.BIG_DECIMAL => - new value.ExactNumeric[BigDecimal] { - val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[BigDecimal]]; - val nativeValue: BigDecimal = result.getBigDecimal(index); - } - - } - } - -} diff --git a/src/dbc/scala/dbc/value/Unknown.scala b/src/dbc/scala/dbc/value/Unknown.scala deleted file mode 100644 index 89764a5831..0000000000 --- a/src/dbc/scala/dbc/value/Unknown.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package value; - - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class Unknown extends Value { - - val dataType: datatype.Unknown; - - def sqlString = sys.error("An 'ANY' value cannot be represented."); - -} - -@deprecated(DbcIsDeprecated, "2.9.0") object UnknownType { - - def view (obj:value.Unknown): AnyRef = obj.nativeValue; - -} diff --git a/src/dbc/scala/dbc/vendor/PostgreSQL.scala b/src/dbc/scala/dbc/vendor/PostgreSQL.scala deleted file mode 100644 index ac528d5f82..0000000000 --- a/src/dbc/scala/dbc/vendor/PostgreSQL.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.dbc -package vendor; - - -import compat.Platform - -@deprecated(DbcIsDeprecated, "2.9.0") abstract class PostgreSQL extends Vendor { - - def uri:java.net.URI; - def user:String; - def pass:String; - - val retainedConnections = 5; - - val nativeDriverClass = Platform.getClassForName("org.postgresql.Driver"); - - val urlProtocolString = "jdbc:postgresql:" - -} diff --git a/src/intellij/dbc.iml.SAMPLE b/src/intellij/dbc.iml.SAMPLE index 5a6df4cfaa..d2647cfb26 100644 --- a/src/intellij/dbc.iml.SAMPLE +++ b/src/intellij/dbc.iml.SAMPLE @@ -12,9 +12,6 @@ - - - diff --git a/src/intellij/scala-lang.ipr.SAMPLE b/src/intellij/scala-lang.ipr.SAMPLE index 93b6285cfb..94a9329dd6 100644 --- a/src/intellij/scala-lang.ipr.SAMPLE +++ b/src/intellij/scala-lang.ipr.SAMPLE @@ -197,7 +197,6 @@ - -- cgit v1.2.3 From 89fd256787695774771b5d4509de493271267585 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 20 Apr 2012 19:08:36 +0200 Subject: scala.reflect.api: Reporters => FrontEnds --- .../scala/reflect/internal/FrontEnds.scala | 75 ++++++++++++++++++++++ .../scala/reflect/internal/Reporters.scala | 74 --------------------- .../scala/reflect/internal/SymbolTable.scala | 4 +- .../scala/reflect/makro/runtime/Context.scala | 2 +- .../scala/reflect/makro/runtime/FrontEnds.scala | 44 +++++++++++++ .../scala/reflect/makro/runtime/Reporters.scala | 44 ------------- src/compiler/scala/reflect/runtime/ToolBoxes.scala | 38 +++++------ src/compiler/scala/tools/nsc/Global.scala | 32 ++++----- src/compiler/scala/tools/nsc/ToolBoxes.scala | 8 +-- src/compiler/scala/tools/nsc/ast/DocComments.scala | 4 +- .../scala/tools/nsc/interpreter/IMain.scala | 3 +- .../scala/tools/nsc/symtab/SymbolTable.scala | 3 - src/library/scala/reflect/DummyMirror.scala | 6 +- src/library/scala/reflect/DynamicProxy.scala | 2 +- src/library/scala/reflect/api/FrontEnds.scala | 68 ++++++++++++++++++++ src/library/scala/reflect/api/Reporters.scala | 65 ------------------- src/library/scala/reflect/api/ToolBoxes.scala | 6 +- src/library/scala/reflect/api/Universe.scala | 2 +- src/library/scala/reflect/makro/Context.scala | 2 +- src/library/scala/reflect/makro/FrontEnds.scala | 39 +++++++++++ src/library/scala/reflect/makro/Reporters.scala | 39 ----------- test/files/run/toolbox_console_reporter.scala | 4 +- test/files/run/toolbox_silent_reporter.scala | 2 +- 23 files changed, 279 insertions(+), 287 deletions(-) create mode 100644 src/compiler/scala/reflect/internal/FrontEnds.scala delete mode 100644 src/compiler/scala/reflect/internal/Reporters.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/FrontEnds.scala delete mode 100644 src/compiler/scala/reflect/makro/runtime/Reporters.scala create mode 100644 src/library/scala/reflect/api/FrontEnds.scala delete mode 100644 src/library/scala/reflect/api/Reporters.scala create mode 100644 src/library/scala/reflect/makro/FrontEnds.scala delete mode 100644 src/library/scala/reflect/makro/Reporters.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/FrontEnds.scala b/src/compiler/scala/reflect/internal/FrontEnds.scala new file mode 100644 index 0000000000..74501c7686 --- /dev/null +++ b/src/compiler/scala/reflect/internal/FrontEnds.scala @@ -0,0 +1,75 @@ +package scala.reflect +package internal + +trait FrontEnds { self: SymbolTable => + + import scala.tools.nsc.reporters._ + import scala.tools.nsc.Settings + + def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd = { + val settings = new Settings() + if (minSeverity <= 0) settings.verbose.value = true + if (minSeverity > 1) settings.nowarn.value = true + wrapReporter(new ConsoleReporter(settings)) + } + + abstract class FrontEndToReporterProxy(val frontEnd: FrontEnd) extends AbstractReporter { + import frontEnd.{Severity => ApiSeverity} + val API_INFO = frontEnd.INFO + val API_WARNING = frontEnd.WARNING + val API_ERROR = frontEnd.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 = + frontEnd.log(pos, msg, nscSeverity match { + case NSC_INFO => API_INFO + case NSC_WARNING => API_WARNING + case NSC_ERROR => API_ERROR + }) + + def displayPrompt(): Unit = + frontEnd.interactive() + } + + def wrapFrontEnd(frontEnd: FrontEnd): Reporter = new FrontEndToReporterProxy(frontEnd) { + val settings = new Settings() + settings.verbose.value = true + settings.nowarn.value = false + } + + class ReporterToFrontEndProxy(val reporter: Reporter) extends FrontEnd { + val API_INFO = INFO + val API_WARNING = WARNING + val API_ERROR = ERROR + + override def hasErrors = reporter.hasErrors + override def hasWarnings = reporter.hasWarnings + + def display(info: Info): Unit = info.severity match { + case API_INFO => reporter.info(info.pos, info.msg, false) + case API_WARNING => reporter.warning(info.pos, info.msg) + case API_ERROR => reporter.error(info.pos, info.msg) + } + + def interactive(): Unit = reporter match { + case reporter: AbstractReporter => reporter.displayPrompt() + case _ => // do nothing + } + + override def flush(): Unit = { + super.flush() + reporter.flush() + } + + override def reset(): Unit = { + super.reset() + reporter.reset() + } + } + + def wrapReporter(reporter: Reporter): FrontEnd = new ReporterToFrontEndProxy(reporter) +} diff --git a/src/compiler/scala/reflect/internal/Reporters.scala b/src/compiler/scala/reflect/internal/Reporters.scala deleted file mode 100644 index 20d4a1d026..0000000000 --- a/src/compiler/scala/reflect/internal/Reporters.scala +++ /dev/null @@ -1,74 +0,0 @@ -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/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 0688d13ae5..7d9dd282cf 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -36,7 +36,7 @@ abstract class SymbolTable extends api.Universe with Importers with Required with TreeBuildUtil - with Reporters + with FrontEnds with CapturedVariables with StdAttachments { @@ -53,7 +53,7 @@ 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:") diff --git a/src/compiler/scala/reflect/makro/runtime/Context.scala b/src/compiler/scala/reflect/makro/runtime/Context.scala index 184008658e..15a4118b85 100644 --- a/src/compiler/scala/reflect/makro/runtime/Context.scala +++ b/src/compiler/scala/reflect/makro/runtime/Context.scala @@ -10,7 +10,7 @@ abstract class Context extends scala.reflect.makro.Context with Enclosures with Names with Reifiers - with Reporters + with FrontEnds with Settings with Symbols with Typers diff --git a/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala b/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala new file mode 100644 index 0000000000..7cfa8e80f3 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala @@ -0,0 +1,44 @@ +package scala.reflect.makro +package runtime + +trait FrontEnds { + self: Context => + + import mirror._ + + def frontEnd: FrontEnd = wrapReporter(mirror.reporter) + + def setFrontEnd(frontEnd: FrontEnd): this.type = { + mirror.reporter = wrapFrontEnd(frontEnd) + this + } + + def withFrontEnd[T](frontEnd: FrontEnd)(op: => T): T = { + val old = mirror.reporter + setFrontEnd(frontEnd) + 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/Reporters.scala b/src/compiler/scala/reflect/makro/runtime/Reporters.scala deleted file mode 100644 index 0fd037bdd2..0000000000 --- a/src/compiler/scala/reflect/makro/runtime/Reporters.scala +++ /dev/null @@ -1,44 +0,0 @@ -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/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala index 6d832a590f..21a90326cf 100644 --- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala +++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala @@ -16,14 +16,11 @@ import scala.compat.Platform.EOL trait ToolBoxes extends { self: Universe => - import self.{Reporter => ApiReporter} - import scala.tools.nsc.reporters.{Reporter => NscReporter} + def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = "") = new ToolBox(frontEnd, options) - def mkToolBox(reporter: ApiReporter = mkSilentReporter(), options: String = "") = new ToolBox(reporter, options) + class ToolBox(val frontEnd: FrontEnd, val options: String) extends AbsToolBox { - class ToolBox(val reporter: ApiReporter, val options: String) extends AbsToolBox { - - class ToolBoxGlobal(settings: scala.tools.nsc.Settings, reporter: NscReporter) + class ToolBoxGlobal(settings: scala.tools.nsc.Settings, reporter: Reporter) extends ReflectGlobal(settings, reporter, ToolBox.this.classLoader) { import definitions._ @@ -200,11 +197,7 @@ trait ToolBoxes extends { self: Universe => val run = new Run reporter.reset() run.compileUnits(List(unit), run.namerPhase) - if (reporter.hasErrors) { - var msg = "reflective compilation has failed: " + EOL + EOL - msg += ToolBox.this.reporter.infos map (_.msg) mkString EOL - throw new ToolBoxError(ToolBox.this, msg) - } + throwIfErrors() val className = mdef.symbol.fullName if (settings.debug.value) println("generated: "+className) @@ -250,6 +243,15 @@ trait ToolBoxes extends { self: Universe => settings.Yshowsymkinds.value = saved3 } } + + // reporter doesn't accumulate errors, but the front-end does + def throwIfErrors() = { + if (frontEnd.hasErrors) { + var msg = "reflective compilation has failed: " + EOL + EOL + msg += frontEnd.infos map (_.msg) mkString EOL + throw new ToolBoxError(ToolBox.this, msg) + } + } } // todo. is not going to work with quoted arguments with embedded whitespaces @@ -263,19 +265,13 @@ trait ToolBoxes extends { self: Universe => lazy val compiler: ToolBoxGlobal = { 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 errorFn: String => Unit = msg => frontEnd.log(NoPosition, msg, frontEnd.ERROR) 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) { + val instance = new ToolBoxGlobal(command.settings, new FrontEndToReporterProxy(frontEnd) { val settings = command.settings }) + if (frontEnd.hasErrors) { var msg = "reflective compilation has failed: cannot initialize the compiler: " + EOL + EOL - msg += reporter.infos map (_.msg) mkString EOL + msg += frontEnd.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 diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 6c038162b3..f9cef385dc 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -11,7 +11,7 @@ import compat.Platform.currentTime import scala.tools.util.{ Profiling, PathResolver } import scala.collection.{ mutable, immutable } import io.{ SourceReader, AbstractFile, Path } -import reporters.{ Reporter => NscReporter, ConsoleReporter } +import reporters.{ Reporter, 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 } @@ -31,17 +31,17 @@ import backend.icode.analysis._ import language.postfixOps import reflect.internal.StdAttachments -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 { +class Global(var currentSettings: Settings, var reporter: Reporter) 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 @@ -49,7 +49,7 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S // alternate constructors ------------------------------------------ - def this(reporter: NscReporter) = + def this(reporter: Reporter) = this(new Settings(err => reporter.error(null, err)), reporter) def this(settings: Settings) = @@ -1614,7 +1614,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: NscReporter): Global = { + def fromSettings(settings: Settings, reporter: Reporter): 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. @@ -1622,7 +1622,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[NscReporter]) + val cons = clazz.getConstructor(classOf[Settings], classOf[Reporter]) cons.newInstance(settings, reporter).asInstanceOf[Global] } @@ -1630,7 +1630,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: NscReporter): Global = { + def apply(settings: Settings, reporter: Reporter): Global = { val g = ( if (settings.globalClass.isDefault) null else try fromSettings(settings, reporter) catch { case x => diff --git a/src/compiler/scala/tools/nsc/ToolBoxes.scala b/src/compiler/scala/tools/nsc/ToolBoxes.scala index eb298833b8..5b2b5ff5e9 100644 --- a/src/compiler/scala/tools/nsc/ToolBoxes.scala +++ b/src/compiler/scala/tools/nsc/ToolBoxes.scala @@ -4,11 +4,9 @@ import util.ScalaClassLoader trait ToolBoxes { self: Global => - import self.{Reporter => ApiReporter} + def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = "") = new ToolBox(frontEnd, options) - def mkToolBox(reporter: ApiReporter = mkSilentReporter(), options: String = "") = new ToolBox(reporter, options) - - class ToolBox(val reporter: ApiReporter, val options: String) extends AbsToolBox { + class ToolBox(val frontEnd: FrontEnd, 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 @@ -43,7 +41,7 @@ trait ToolBoxes { self: Global => // 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) + val toolBox = libraryClasspathMirror.mkToolBox(frontEnd.asInstanceOf[libraryClasspathMirror.FrontEnd], options) try toolBox.runExpr(imported) catch { case ex: toolBox.ToolBoxError => diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 8e7eeed3cc..b3ed446563 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 => NscReporter} +import reporters._ import util.{Position, NoPosition} import util.DocStrings._ import scala.reflect.internal.Chars._ @@ -21,8 +21,6 @@ trait DocComments { self: Global => var cookedDocComments = Map[Symbol, String]() - def reporter: NscReporter - /** The raw doc comment map */ val docComments = mutable.HashMap[Symbol, DocComment]() diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 13124e6afc..bfcfa5f2b9 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -13,7 +13,6 @@ 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 @@ -282,7 +281,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: NscReporter): ReplGlobal = { + protected def newCompiler(settings: Settings, reporter: Reporter): ReplGlobal = { settings.outputDirs setSingleOutput virtualDirectory settings.exposeEmptyPackage.value = true new Global(settings, reporter) with ReplGlobal diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala index fb85ebeeb0..75b486ca7d 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala @@ -6,7 +6,4 @@ package scala.tools.nsc package symtab -import ast.{Trees, TreePrinters, DocComments} -import util._ - abstract class SymbolTable extends reflect.internal.SymbolTable \ No newline at end of file diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala index 1fbf36be9d..9607621928 100644 --- a/src/library/scala/reflect/DummyMirror.scala +++ b/src/library/scala/reflect/DummyMirror.scala @@ -161,8 +161,8 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { def wrappingPos(trees: List[Tree]): Position = notSupported() def wrappingPos(default: Position,trees: List[Tree]): Position = notSupported() - // Members declared in scala.reflect.api.Reporters - def mkConsoleReporter(minSeverity: Int): Reporter = notSupported() + // Members declared in scala.reflect.api.FrontEnds + def mkConsoleFrontEnd(minSeverity: Int): FrontEnd = notSupported() // Members declared in scala.reflect.api.Scopes type Scope = DummyScope.type @@ -471,7 +471,7 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { } // Members declared in scala.reflect.api.ToolBoxes - def mkToolBox(reporter: Reporter,options: String): AbsToolBox = notSupported() + def mkToolBox(frontEnd: FrontEnd, options: String): AbsToolBox = notSupported() // Members declared in scala.reflect.api.TreeBuildUtil // type TreeGen = DummyTreeGen.type // [Eugene] cannot compile if uncomment this diff --git a/src/library/scala/reflect/DynamicProxy.scala b/src/library/scala/reflect/DynamicProxy.scala index 02872977f5..3ed17fea41 100644 --- a/src/library/scala/reflect/DynamicProxy.scala +++ b/src/library/scala/reflect/DynamicProxy.scala @@ -43,7 +43,7 @@ trait DynamicProxy extends Dynamic{ def applyDynamicNamed( method:String )( args:(String,DynamicReflectBoxed)* ) : Any = { val class_ = dynamicProxyTarget.getClass var i = 0 - val toolbox = mkToolBox(mkConsoleReporter(),"") + val toolbox = mkToolBox(mkConsoleFrontEnd(),"") val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName ) if(args.size == 0){ invoke( dynamicProxyTarget, symbol )() diff --git a/src/library/scala/reflect/api/FrontEnds.scala b/src/library/scala/reflect/api/FrontEnds.scala new file mode 100644 index 0000000000..2c1f3feff6 --- /dev/null +++ b/src/library/scala/reflect/api/FrontEnds.scala @@ -0,0 +1,68 @@ +package scala.reflect +package api + +trait FrontEnds { self: Universe => + + trait FrontEnd { + 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) + + def hasErrors = ERROR.count > 0 + def hasWarnings = WARNING.count > 0 + + 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 SilentFrontEnd extends FrontEnd { + def display(info: Info) {} + def interactive() {} + } + + /** Creates a UI-less reporter that simply accumulates all the messages + */ + def mkSilentFrontEnd(): FrontEnd = new SilentFrontEnd() + + /** 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 mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Reporters.scala b/src/library/scala/reflect/api/Reporters.scala deleted file mode 100644 index b7428e1599..0000000000 --- a/src/library/scala/reflect/api/Reporters.scala +++ /dev/null @@ -1,65 +0,0 @@ -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/ToolBoxes.scala b/src/library/scala/reflect/api/ToolBoxes.scala index 387ef5163b..aefd6b511c 100644 --- a/src/library/scala/reflect/api/ToolBoxes.scala +++ b/src/library/scala/reflect/api/ToolBoxes.scala @@ -5,17 +5,17 @@ trait ToolBoxes { self: Universe => type ToolBox <: AbsToolBox - def mkToolBox(reporter: Reporter = mkSilentReporter(), options: String = ""): AbsToolBox + def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = ""): AbsToolBox // [Eugene] what do you think about the interface? namely about the ``freeTypes'' part. trait AbsToolBox { - /** UI of the toolbox. + /** Front end 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 + def frontEnd: FrontEnd /** Typechecks a tree using this ToolBox. * This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings. diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala index d1f546608e..2b22839d39 100755 --- a/src/library/scala/reflect/api/Universe.scala +++ b/src/library/scala/reflect/api/Universe.scala @@ -19,7 +19,7 @@ abstract class Universe extends Symbols with ClassLoaders with TreeBuildUtil with ToolBoxes - with Reporters + with FrontEnds with Importers { /** Given an expression, generate a tree that when compiled and executed produces the original tree. diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala index 5ce801e2e6..b304d98a5a 100644 --- a/src/library/scala/reflect/makro/Context.scala +++ b/src/library/scala/reflect/makro/Context.scala @@ -12,7 +12,7 @@ trait Context extends Aliases with Infrastructure with Names with Reifiers - with Reporters + with FrontEnds with Settings with Symbols with Typers diff --git a/src/library/scala/reflect/makro/FrontEnds.scala b/src/library/scala/reflect/makro/FrontEnds.scala new file mode 100644 index 0000000000..a1e24dcea3 --- /dev/null +++ b/src/library/scala/reflect/makro/FrontEnds.scala @@ -0,0 +1,39 @@ +package scala.reflect.makro + +trait FrontEnds { + self: Context => + + import mirror._ + + /** Exposes means to control the compiler UI */ + def frontEnd: FrontEnd + def setFrontEnd(frontEnd: FrontEnd): this.type + def withFrontEnd[T](frontEnd: FrontEnd)(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/Reporters.scala b/src/library/scala/reflect/makro/Reporters.scala deleted file mode 100644 index 7341b0e0b7..0000000000 --- a/src/library/scala/reflect/makro/Reporters.scala +++ /dev/null @@ -1,39 +0,0 @@ -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/test/files/run/toolbox_console_reporter.scala b/test/files/run/toolbox_console_reporter.scala index fd244b40ec..1da9a6bc16 100644 --- a/test/files/run/toolbox_console_reporter.scala +++ b/test/files/run/toolbox_console_reporter.scala @@ -1,10 +1,10 @@ import scala.reflect.mirror._ object Test extends App { - // todo. cannot test this unfortunately, because ConsoleReporter grabs Console.out too early + // todo. cannot test this unfortunately, because ConsoleFrontEnd 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") + //val toolbox = mkToolBox(frontEnd = mkConsoleFrontEnd(), options = "-deprecation") //toolbox.runExpr(reify{ // object Utils { // @deprecated("test", "2.10.0") diff --git a/test/files/run/toolbox_silent_reporter.scala b/test/files/run/toolbox_silent_reporter.scala index 7e9259946b..5f264f7d74 100644 --- a/test/files/run/toolbox_silent_reporter.scala +++ b/test/files/run/toolbox_silent_reporter.scala @@ -11,6 +11,6 @@ object Test extends App { Utils.foo }) println("============compiler messages============") - toolbox.reporter.infos.foreach(println(_)) + toolbox.frontEnd.infos.foreach(println(_)) println("=========================================") } \ No newline at end of file -- cgit v1.2.3 From 1dba0583fabb55757ba141d399bb3e492e358c17 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 21 Apr 2012 19:29:53 +0200 Subject: fixes SI-5689 --- src/compiler/scala/tools/nsc/typechecker/Macros.scala | 2 +- test/files/neg/t5689.check | 7 +++++++ test/files/neg/t5689.flags | 1 + test/files/neg/t5689.scala | 6 ++++++ 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test/files/neg/t5689.check create mode 100644 test/files/neg/t5689.flags create mode 100644 test/files/neg/t5689.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index cbfa61470c..9b4dd09c98 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -427,7 +427,7 @@ trait Macros { self: Analyzer => 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 rettpe = if (!ddef.tpt.isEmpty) typer.typedType(ddef.tpt).tpe else computeMacroDefTypeFromMacroImpl(ddef, macroDef, macroImpl) val (reqparamsss0, reqres0) = macroImplSigs(macroDef, ddef.tparams, ddef.vparamss, rettpe) var reqparamsss = reqparamsss0 diff --git a/test/files/neg/t5689.check b/test/files/neg/t5689.check new file mode 100644 index 0000000000..f286d08cfa --- /dev/null +++ b/test/files/neg/t5689.check @@ -0,0 +1,7 @@ +t5689.scala:4: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(i: c.Expr[Double]): c.Expr[String] + found : (c: scala.reflect.makro.Context)(i: c.Expr[Double]): c.Expr[Int] +type mismatch for return type : c.Expr[String] does not conform to c.Expr[Int] + def returnsString(i: Double): String = macro returnsIntImpl + ^ +one error found diff --git a/test/files/neg/t5689.flags b/test/files/neg/t5689.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/neg/t5689.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/neg/t5689.scala b/test/files/neg/t5689.scala new file mode 100644 index 0000000000..ef7a45b364 --- /dev/null +++ b/test/files/neg/t5689.scala @@ -0,0 +1,6 @@ +import scala.reflect.makro.Context + +object Macros { + def returnsString(i: Double): String = macro returnsIntImpl + def returnsIntImpl(c: Context)(i: c.Expr[Double]): c.Expr[Int] = ??? +} -- cgit v1.2.3 From 8c95273b70288e4e3a547fa43f2dbdb40a71b9ea Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 22 Apr 2012 05:46:50 -0700 Subject: Reflection and reification: Names and Symbols. - Consolidating many islands of name organization. Folds NameManglers into StdNames. Brings more of the string constants together with similar constants. Move name manipulation methods which produce TypeNames into object tpnme rather than nme. - Starting on MethodSymbolApi, ClassSymbolApi, etc so we can put sensible methods on sensible entities. This pushed into Definitions, where I pulled a whole bunch out of the api side (or at least marked my intention to do so -- too many tests use them to make them easy to remove) and on the compiler side, returned something more specific than Symbol a bunch of places. - Added a number of conveniences to Definitions to make it easier to get properly typed symbols. Note: one way in which you might notice having better typed Symbols is with Sets, which have the annoying property of inferring a type based on what they've been constructed with and then hard failing when you test for the presence of a more general type. So this: val mySet = Set(a, b) println(mySet(c)) ..goes from compiling to not compiling if a and b receive more specific types (e.g. they are MethodSymbols) and c is a Symbol or ClassSymbol or whatever. This is easily remedied on a site-by-site basis - create Set[Symbol](...) not Set(...) - but is an interesting and unfortunate consequence of type inference married to invariance. The changes to DummyMirror where things became ??? were driven by the need to lower its tax; type "Nothing" is a lot more forgiving about changes than is any specific symbol type. --- .../scala/reflect/internal/Definitions.scala | 292 ++++++++----- .../scala/reflect/internal/NameManglers.scala | 216 ---------- src/compiler/scala/reflect/internal/Names.scala | 6 +- src/compiler/scala/reflect/internal/Scopes.scala | 2 +- src/compiler/scala/reflect/internal/StdNames.scala | 464 +++++++++++++++------ src/compiler/scala/reflect/internal/Symbols.scala | 73 ++-- src/compiler/scala/reflect/internal/TreeGen.scala | 3 + src/compiler/scala/reflect/internal/Types.scala | 2 +- .../reflect/internal/pickling/UnPickler.scala | 14 +- .../scala/reflect/makro/runtime/Reifiers.scala | 79 ++-- .../scala/reflect/runtime/SynchronizedOps.scala | 2 +- src/compiler/scala/tools/nsc/Global.scala | 2 +- .../tools/nsc/ast/parser/SymbolicXMLBuilder.scala | 13 +- .../scala/tools/nsc/backend/icode/TypeKinds.scala | 2 +- .../scala/tools/nsc/doc/model/ModelFactory.scala | 4 +- .../scala/tools/nsc/interpreter/IMain.scala | 11 +- .../scala/tools/nsc/matching/MatchSupport.scala | 2 +- .../tools/nsc/symtab/classfile/ICodeReader.scala | 2 +- .../scala/tools/nsc/transform/AddInterfaces.scala | 2 +- .../scala/tools/nsc/transform/LambdaLift.scala | 4 +- .../scala/tools/nsc/typechecker/Implicits.scala | 59 +-- .../tools/nsc/typechecker/SuperAccessors.scala | 2 +- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- src/library/scala/reflect/DummyMirror.scala | 159 +++---- src/library/scala/reflect/TagMaterialization.scala | 4 + .../scala/reflect/api/StandardDefinitions.scala | 164 ++++---- src/library/scala/reflect/api/StandardNames.scala | 125 +++--- src/library/scala/reflect/api/Symbols.scala | 149 ++++--- 28 files changed, 985 insertions(+), 874 deletions(-) delete mode 100644 src/compiler/scala/reflect/internal/NameManglers.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 7353e69ab6..24fc7c7cc4 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -15,6 +15,8 @@ import scala.reflect.{ mirror => rm } trait Definitions extends reflect.api.StandardDefinitions { self: SymbolTable => + object definitions extends DefinitionsClass + // [Eugene] find a way to make these non-lazy lazy val ByteTpe = definitions.ByteClass.asType lazy val ShortTpe = definitions.ShortClass.asType @@ -41,34 +43,21 @@ trait Definitions extends reflect.api.StandardDefinitions { */ private type PolyMethodCreator = List[Symbol] => (Option[List[Type]], Type) - private def enterNewClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): Symbol = { + private def enterNewClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): ClassSymbol = { val clazz = owner.newClassSymbol(name, NoPosition, flags) clazz setInfoAndEnter ClassInfoType(parents, newScope, clazz) } - private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): Symbol = { + private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): MethodSymbol = { val msym = owner.newMethod(name.encode, NoPosition, flags) val params = msym.newSyntheticValueParams(formals) msym setInfo MethodType(params, restpe) } - private def enterNewMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): Symbol = + private def enterNewMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): MethodSymbol = owner.info.decls enter newMethod(owner, name, formals, restpe, flags) // the scala value classes trait ValueClassDefinitions { - self: definitions.type => - - private[Definitions] def valueCache(name: Name) = { - val res = ( - if (name.isTypeName) ScalaPackageClass.info member name - else ScalaPackageClass.info member name suchThat (_ hasFlag MODULE) - ) - if (res eq NoSymbol) - abort("Could not find value classes! This is a catastrophic failure. scala " + scala.util.Properties.versionString) - else res - } - private[Definitions] def valueModuleMethod(className: Name, methodName: Name): Symbol = { - valueCache(className.toTermName).moduleClass.tpe member methodName - } + self: DefinitionsClass => import ClassfileConstants._ @@ -94,6 +83,25 @@ trait Definitions extends reflect.api.StandardDefinitions { tpnme.Unit -> VOID_TAG ) + private def catastrophicFailure() = + abort("Could not find value classes! This is a catastrophic failure. scala " + + scala.util.Properties.versionString) + + private def valueClassSymbol(name: TypeName): ClassSymbol = { + getMember(ScalaPackageClass, name) match { + case x: ClassSymbol => x + case _ => catastrophicFailure() + } + } + private def valueClassCompanion(name: TermName): ModuleSymbol = { + getMember(ScalaPackageClass, name) match { + case x: ModuleSymbol => x + case _ => catastrophicFailure() + } + } + private def valueCompanionMember(className: Name, methodName: TermName): MethodSymbol = + getMemberMethod(valueClassCompanion(className.toTermName).moduleClass, methodName) + private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f) private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = syms zip (syms map (x => f(x.name))) toMap private def symbolsMapFilt[T](syms: List[Symbol], p: Name => Boolean, f: Name => T) = symbolsMap(syms filter (x => p(x.name)), f) @@ -106,8 +114,8 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val boxedClass = classesMap(x => getClass(boxedName(x))) lazy val refClass = classesMap(x => getRequiredClass("scala.runtime." + x + "Ref")) lazy val volatileRefClass = classesMap(x => getRequiredClass("scala.runtime.Volatile" + x + "Ref")) - lazy val boxMethod = classesMap(x => valueModuleMethod(x, nme.box)) - lazy val unboxMethod = classesMap(x => valueModuleMethod(x, nme.unbox)) + lazy val boxMethod = classesMap(x => valueCompanionMember(x, nme.box)) + lazy val unboxMethod = classesMap(x => valueCompanionMember(x, nme.unbox)) def isNumericSubClass(sub: Symbol, sup: Symbol) = ( (numericWeight contains sub) @@ -116,27 +124,28 @@ trait Definitions extends reflect.api.StandardDefinitions { ) /** Is symbol a numeric value class? */ - def isNumericValueClass(sym: Symbol): Boolean = - numericWeight contains sym + def isNumericValueClass(sym: Symbol) = ScalaNumericValueClasses contains sym def isGetClass(sym: Symbol) = (sym.name == nme.getClass_) && flattensToEmpty(sym.paramss) - lazy val UnitClass = valueCache(tpnme.Unit) - lazy val ByteClass = valueCache(tpnme.Byte) - lazy val ShortClass = valueCache(tpnme.Short) - lazy val CharClass = valueCache(tpnme.Char) - lazy val IntClass = valueCache(tpnme.Int) - lazy val LongClass = valueCache(tpnme.Long) - lazy val FloatClass = valueCache(tpnme.Float) - lazy val DoubleClass = valueCache(tpnme.Double) - lazy val BooleanClass = valueCache(tpnme.Boolean) + lazy val UnitClass = valueClassSymbol(tpnme.Unit) + lazy val ByteClass = valueClassSymbol(tpnme.Byte) + lazy val ShortClass = valueClassSymbol(tpnme.Short) + lazy val CharClass = valueClassSymbol(tpnme.Char) + lazy val IntClass = valueClassSymbol(tpnme.Int) + lazy val LongClass = valueClassSymbol(tpnme.Long) + lazy val FloatClass = valueClassSymbol(tpnme.Float) + lazy val DoubleClass = valueClassSymbol(tpnme.Double) + lazy val BooleanClass = valueClassSymbol(tpnme.Boolean) lazy val Boolean_and = getMember(BooleanClass, nme.ZAND) lazy val Boolean_or = getMember(BooleanClass, nme.ZOR) lazy val Boolean_not = getMember(BooleanClass, nme.UNARY_!) + lazy val ScalaNumericValueClasses = ScalaValueClasses filterNot Set[Symbol](UnitClass, BooleanClass) + def ScalaValueClassesNoUnit = ScalaValueClasses filterNot (_ eq UnitClass) - def ScalaValueClasses: List[Symbol] = List( + def ScalaValueClasses: List[ClassSymbol] = List( UnitClass, BooleanClass, ByteClass, @@ -148,10 +157,10 @@ trait Definitions extends reflect.api.StandardDefinitions { DoubleClass ) def ScalaValueClassCompanions: List[Symbol] = ScalaValueClasses map (_.companionSymbol) - def ScalaPrimitiveValueClasses: List[Symbol] = ScalaValueClasses + def ScalaPrimitiveValueClasses: List[ClassSymbol] = ScalaValueClasses } - object definitions extends AbsDefinitions with ValueClassDefinitions { + abstract class DefinitionsClass extends AbsDefinitions with ValueClassDefinitions { private var isInitialized = false def isDefinitionsInitialized = isInitialized @@ -207,15 +216,14 @@ trait Definitions extends reflect.api.StandardDefinitions { } // It becomes tricky to create dedicated objects for other symbols because // of initialization order issues. - lazy val JavaLangPackage = getModule(sn.JavaLang) + lazy val JavaLangPackage = getRequiredPackage(sn.JavaLang) lazy val JavaLangPackageClass = JavaLangPackage.moduleClass - lazy val ScalaPackage = getModule(nme.scala_) + lazy val ScalaPackage = getRequiredPackage(nme.scala_) lazy val ScalaPackageClass = ScalaPackage.moduleClass - - lazy val RuntimePackage = getRequiredModule("scala.runtime") + lazy val RuntimePackage = getRequiredPackage("scala.runtime") lazy val RuntimePackageClass = RuntimePackage.moduleClass - lazy val JavaLangEnumClass = getRequiredClass("java.lang.Enum") + lazy val JavaLangEnumClass = requiredClass[java.lang.Enum[_]] // convenient one-argument parameter lists lazy val anyparam = List(AnyClass.tpe) @@ -268,9 +276,9 @@ trait Definitions extends reflect.api.StandardDefinitions { } // top types - lazy val AnyClass = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT) - lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.tpe) - lazy val ObjectClass = getClass(sn.Object) + lazy val AnyClass = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT) + lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.tpe) + lazy val ObjectClass = getRequiredClass(sn.Object.toString) // Note: this is not the type alias AnyRef, it's a companion-like // object used by the @specialize annotation. @@ -278,12 +286,13 @@ trait Definitions extends reflect.api.StandardDefinitions { @deprecated("Use AnyRefModule", "2.10.0") def Predef_AnyRef = AnyRefModule - lazy val AnyValClass = ScalaPackageClass.info member tpnme.AnyVal orElse { + lazy val AnyValClass: ClassSymbol = (ScalaPackageClass.info member tpnme.AnyVal orElse { val anyval = enterNewClass(ScalaPackageClass, tpnme.AnyVal, List(AnyClass.tpe, NotNullClass.tpe), ABSTRACT) val av_constr = anyval.newClassConstructor(NoPosition) anyval.info.decls enter av_constr anyval - } + }).asInstanceOf[ClassSymbol] + lazy val AnyVal_getClass = enterNewMethod(AnyValClass, nme.getClass_, Nil, getClassReturnType(AnyValClass.tpe)) // bottom types @@ -308,24 +317,24 @@ trait Definitions extends reflect.api.StandardDefinitions { } // exceptions and other throwables - lazy val ClassCastExceptionClass = getRequiredClass("java.lang.ClassCastException") + lazy val ClassCastExceptionClass = requiredClass[ClassCastException] lazy val IndexOutOfBoundsExceptionClass = getClass(sn.IOOBException) lazy val InvocationTargetExceptionClass = getClass(sn.InvTargetException) - lazy val MatchErrorClass = getRequiredClass("scala.MatchError") - lazy val NonLocalReturnControlClass = getRequiredClass("scala.runtime.NonLocalReturnControl") + lazy val MatchErrorClass = requiredClass[MatchError] + lazy val NonLocalReturnControlClass = requiredClass[scala.runtime.NonLocalReturnControl[_]] lazy val NullPointerExceptionClass = getClass(sn.NPException) lazy val ThrowableClass = getClass(sn.Throwable) - lazy val UninitializedErrorClass = getRequiredClass("scala.UninitializedFieldError") + lazy val UninitializedErrorClass = requiredClass[UninitializedFieldError] // fundamental reference classes - lazy val PartialFunctionClass = getRequiredClass("scala.PartialFunction") + lazy val PartialFunctionClass = requiredClass[PartialFunction[_,_]] lazy val AbstractPartialFunctionClass = getRequiredClass("scala.runtime.AbstractPartialFunction") lazy val SymbolClass = getRequiredClass("scala.Symbol") - lazy val StringClass = getClass(sn.String) + lazy val StringClass = requiredClass[java.lang.String] lazy val StringModule = StringClass.linkedClassOfClass - lazy val ClassClass = getClass(sn.Class) + lazy val ClassClass = getRequiredClass("java.lang.Class") def Class_getMethod = getMember(ClassClass, nme.getMethod_) - lazy val DynamicClass = getRequiredClass("scala.Dynamic") + lazy val DynamicClass = requiredClass[Dynamic] // fundamental modules lazy val SysPackage = getPackageObject("scala.sys") @@ -336,14 +345,14 @@ trait Definitions extends reflect.api.StandardDefinitions { // Those modules and their module classes lazy val UnqualifiedOwners = UnqualifiedModules.toSet ++ UnqualifiedModules.map(_.moduleClass) - lazy val PredefModule: Symbol = getRequiredModule("scala.Predef") + lazy val PredefModule = requiredModule[scala.Predef.type] lazy val PredefModuleClass = PredefModule.moduleClass - def Predef_classOf = getMember(PredefModule, nme.classOf) - def Predef_identity = getMember(PredefModule, nme.identity) - def Predef_conforms = getMember(PredefModule, nme.conforms) + def Predef_classOf = getMember(PredefModule, nme.classOf) + def Predef_identity = getMember(PredefModule, nme.identity) + def Predef_conforms = getMember(PredefModule, nme.conforms) def Predef_wrapRefArray = getMember(PredefModule, nme.wrapRefArray) - def Predef_??? = getMember(PredefModule, nme.???) + def Predef_??? = getMember(PredefModule, nme.???) /** Is `sym` a member of Predef with the given name? * Note: DON't replace this by sym == Predef_conforms/etc, as Predef_conforms is a `def` @@ -356,8 +365,8 @@ trait Definitions extends reflect.api.StandardDefinitions { /** Specialization. */ - lazy val SpecializableModule = getRequiredModule("scala.Specializable") - lazy val GroupOfSpecializable = SpecializableModule.info.member(newTypeName("Group")) + lazy val SpecializableModule = requiredModule[Specializable] + lazy val GroupOfSpecializable = getMember(SpecializableModule, tpnme.Group) lazy val ConsoleModule: Symbol = getRequiredModule("scala.Console") lazy val ScalaRunTimeModule: Symbol = getRequiredModule("scala.runtime.ScalaRunTime") @@ -379,7 +388,7 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val NotNullClass = getRequiredClass("scala.NotNull") lazy val ScalaNumberClass = getRequiredClass("scala.math.ScalaNumber") lazy val TraitSetterAnnotationClass = getRequiredClass("scala.runtime.TraitSetter") - lazy val DelayedInitClass = getRequiredClass("scala.DelayedInit") + lazy val DelayedInitClass = requiredClass[scala.DelayedInit] def delayedInitMethod = getMember(DelayedInitClass, nme.delayedInit) // a dummy value that communicates that a delayedInit call is compiler-generated // from phase UnCurry to phase Constructors @@ -458,8 +467,8 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val Array_clone = getMember(ArrayClass, nme.clone_) // reflection / structural types - lazy val SoftReferenceClass = getRequiredClass("java.lang.ref.SoftReference") - lazy val WeakReferenceClass = getRequiredClass("java.lang.ref.WeakReference") + lazy val SoftReferenceClass = requiredClass[java.lang.ref.SoftReference[_]] + lazy val WeakReferenceClass = requiredClass[java.lang.ref.WeakReference[_]] lazy val MethodClass = getClass(sn.MethodAsObject) def methodClass_setAccessible = getMember(MethodClass, nme.setAccessible) lazy val EmptyMethodCacheClass = getRequiredClass("scala.runtime.EmptyMethodCache") @@ -473,22 +482,23 @@ trait Definitions extends reflect.api.StandardDefinitions { def Reflect_mirror = getMember(ReflectPackage, nme.mirror) lazy val ExprClass = getMember(getRequiredClass("scala.reflect.api.Exprs"), tpnme.Expr) - def ExprTree = getMember(ExprClass, nme.tree) - def ExprTpe = getMember(ExprClass, nme.tpe) + def ExprTree = getMemberClass(ExprClass, nme.tree) + def ExprTpe = getMemberClass(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 ConcreteTypeTagClass = getMember(TypeTagsClass, tpnme.ConcreteTypeTag) - lazy val ConcreteTypeTagModule = getMember(TypeTagsClass, nme.ConcreteTypeTag) + lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]] + lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]] + lazy val TypeTagsClass = requiredClass[scala.reflect.api.TypeTags] + lazy val TypeTagClass = getMemberClass(TypeTagsClass, tpnme.TypeTag) + lazy val TypeTagModule = getMemberModule(TypeTagsClass, nme.TypeTag) + lazy val ConcreteTypeTagClass = getMemberClass(TypeTagsClass, tpnme.ConcreteTypeTag) + lazy val ConcreteTypeTagModule = getMemberModule(TypeTagsClass, nme.ConcreteTypeTag) + + def ClassTagErasure = getMemberMethod(ClassTagClass, nme.erasure) + def ClassTagTpe = getMemberMethod(ClassTagClass, nme.tpe) + def TypeTagTpe = getMemberMethod(TypeTagClass, nme.tpe) lazy val MacroContextClass = getRequiredClass("scala.reflect.makro.Context") def MacroContextPrefix = getMember(MacroContextClass, nme.prefix) @@ -497,16 +507,16 @@ trait Definitions extends reflect.api.StandardDefinitions { 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_materializeConcreteTypeTag = getMember(MacroInternalPackage, nme.materializeConcreteTypeTag) + def MacroInternal_materializeClassTag = getMemberMethod(MacroInternalPackage, nme.materializeClassTag) + def MacroInternal_materializeTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeTypeTag) + def MacroInternal_materializeConcreteTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeConcreteTypeTag) lazy val ScalaSignatureAnnotation = getRequiredClass("scala.reflect.ScalaSignature") lazy val ScalaLongSignatureAnnotation = getRequiredClass("scala.reflect.ScalaLongSignature") // Option classes - lazy val OptionClass: Symbol = getRequiredClass("scala.Option") - lazy val SomeClass: Symbol = getRequiredClass("scala.Some") + lazy val OptionClass: Symbol = requiredClass[Option[_]] + lazy val SomeClass: Symbol = requiredClass[Some[_]] lazy val NoneModule: Symbol = getRequiredModule("scala.None") lazy val SomeModule: Symbol = getRequiredModule("scala.Some") @@ -618,13 +628,13 @@ trait Definitions extends reflect.api.StandardDefinitions { } def isTupleType(tp: Type) = isTupleTypeDirect(tp.normalize) - lazy val ProductRootClass: Symbol = getRequiredClass("scala.Product") - def Product_productArity = getMember(ProductRootClass, nme.productArity) - def Product_productElement = getMember(ProductRootClass, nme.productElement) - // def Product_productElementName = getMember(ProductRootClass, nme.productElementName) - def Product_iterator = getMember(ProductRootClass, nme.productIterator) - def Product_productPrefix = getMember(ProductRootClass, nme.productPrefix) - def Product_canEqual = getMember(ProductRootClass, nme.canEqual_) + lazy val ProductRootClass: ClassSymbol = requiredClass[scala.Product] + def Product_productArity = getMemberMethod(ProductRootClass, nme.productArity) + def Product_productElement = getMemberMethod(ProductRootClass, nme.productElement) + def Product_iterator = getMemberMethod(ProductRootClass, nme.productIterator) + def Product_productPrefix = getMemberMethod(ProductRootClass, nme.productPrefix) + def Product_canEqual = getMemberMethod(ProductRootClass, nme.canEqual_) + // def Product_productElementName = getMemberMethod(ProductRootClass, nme.productElementName) def productProj(z:Symbol, j: Int): Symbol = getMember(z, nme.productAccessorName(j)) def productProj(n: Int, j: Int): Symbol = productProj(ProductClass(n), j) @@ -949,7 +959,7 @@ trait Definitions extends reflect.api.StandardDefinitions { // Trying to allow for deprecated locations sym.isAliasType && isMetaAnnotation(sym.info.typeSymbol) ) - lazy val metaAnnotations = Set( + lazy val metaAnnotations = Set[Symbol]( FieldTargetClass, ParamTargetClass, GetterTargetClass, SetterTargetClass, BeanGetterTargetClass, BeanSetterTargetClass @@ -968,31 +978,64 @@ trait Definitions extends reflect.api.StandardDefinitions { def getPackageObject(fullname: String): Symbol = getModule(newTermName(fullname)).info member nme.PACKAGE - def getModule(fullname: Name): Symbol = - getModuleOrClass(fullname.toTermName) + def getModule(fullname: Name): ModuleSymbol = + getModuleOrClass(fullname.toTermName) match { + case x: ModuleSymbol => x + case _ => MissingRequirementError.notFound("object " + fullname) + } - def getClass(fullname: Name): Symbol = { - var result = getModuleOrClass(fullname.toTypeName) - while (result.isAliasType) result = result.info.typeSymbol - result + def getPackage(fullname: Name): PackageSymbol = + getModuleOrClass(fullname.toTermName) match { + case x: PackageSymbol => x + case _ => MissingRequirementError.notFound("package " + fullname) + } + @inline private def wrapMissing(body: => Symbol): Symbol = + try body + catch { case _: MissingRequirementError => NoSymbol } + + private def fatalMissingSymbol(owner: Symbol, name: Name, what: String = "member") = { + throw new FatalError(owner + " does not have a " + what + " " + name) } - def getRequiredModule(fullname: String): Symbol = + @deprecated("Use getClassByName", "2.10.0") + def getClass(fullname: Name): Symbol = getClassByName(fullname) + + def getRequiredPackage(fullname: String): PackageSymbol = + getPackage(newTermNameCached(fullname)) + + def getRequiredModule(fullname: String): ModuleSymbol = getModule(newTermNameCached(fullname)) - def getRequiredClass(fullname: String): Symbol = - getClass(newTypeNameCached(fullname)) + + def requiredClass[T: ClassTag] : ClassSymbol = + getRequiredClass(classTag[T].erasure.getName) + + // TODO: What syntax do we think should work here? Say you have an object + // like scala.Predef. You can't say requiredModule[scala.Predef] since there's + // no accompanying Predef class, and if you say requiredModule[scala.Predef.type] + // the name found via the erasure is scala.Predef$. For now I am + // removing the trailing $, but I think that classTag should have + // a method which returns a usable name, one which doesn't expose this + // detail of the backend. + def requiredModule[T: ClassTag] : ModuleSymbol = + getRequiredModule(classTag[T].erasure.getName stripSuffix "$") + + def getRequiredClass(fullname: String): ClassSymbol = + getClassByName(newTypeNameCached(fullname)) match { + case x: ClassSymbol => x + case _ => MissingRequirementError.notFound("class " + fullname) + } def getClassIfDefined(fullname: String): Symbol = getClassIfDefined(newTypeName(fullname)) + def getClassIfDefined(fullname: Name): Symbol = - try getClass(fullname.toTypeName) - catch { case _: MissingRequirementError => NoSymbol } + wrapMissing(getClass(fullname.toTypeName)) def getModuleIfDefined(fullname: String): Symbol = getModuleIfDefined(newTermName(fullname)) + def getModuleIfDefined(fullname: Name): Symbol = - try getModule(fullname.toTermName) - catch { case _: MissingRequirementError => NoSymbol } + wrapMissing(getModule(fullname.toTermName)) def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule) = getMember(owner, newTypeName(name)) @@ -1020,11 +1063,29 @@ trait Definitions extends reflect.api.StandardDefinitions { 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) + } + else fatalMissingSymbol(owner, name) + } + } + def getMemberModule(owner: Symbol, name: Name): ModuleSymbol = { + getMember(owner, name.toTermName) match { + case x: ModuleSymbol => x + case _ => fatalMissingSymbol(owner, name, "member object") + } + } + def getMemberClass(owner: Symbol, name: Name): ClassSymbol = { + getMember(owner, name.toTypeName) match { + case x: ClassSymbol => x + case _ => fatalMissingSymbol(owner, name, "member class") } } + def getMemberMethod(owner: Symbol, name: Name): MethodSymbol = { + getMember(owner, name.toTermName) match { + case x: MethodSymbol => x + case _ => fatalMissingSymbol(owner, name, "method") + } } + def getMemberIfDefined(owner: Symbol, name: Name): Symbol = owner.info.nonPrivateMember(name) @@ -1033,9 +1094,7 @@ trait Definitions extends reflect.api.StandardDefinitions { * know the method in question is uniquely declared in the given owner. */ def getDecl(owner: Symbol, name: Name): Symbol = { - getDeclIfDefined(owner, name) orElse { - throw new FatalError(owner + " does not have a decl " + name) - } + getDeclIfDefined(owner, name) orElse fatalMissingSymbol(owner, name, "decl") } def getDeclIfDefined(owner: Symbol, name: Name): Symbol = owner.info.nonPrivateDecl(name) @@ -1065,10 +1124,16 @@ trait Definitions extends reflect.api.StandardDefinitions { */ private def getModuleOrClass(path: Name): Symbol = getModuleOrClass(path, path.length) - private def newAlias(owner: Symbol, name: TypeName, alias: Type): Symbol = + private def getClassByName(fullname: Name): Symbol = { + var result = getModuleOrClass(fullname.toTypeName) + while (result.isAliasType) result = result.info.typeSymbol + result + } + + private def newAlias(owner: Symbol, name: TypeName, alias: Type): AliasTypeSymbol = owner.newAliasType(name) setInfoAndEnter alias - private def specialPolyClass(name: TypeName, flags: Long)(parentFn: Symbol => Type): Symbol = { + private def specialPolyClass(name: TypeName, flags: Long)(parentFn: Symbol => Type): ClassSymbol = { val clazz = enterNewClass(ScalaPackageClass, name, Nil) val tparam = clazz.newSyntheticTypeParam("T0", flags) val parents = List(AnyRefClass.tpe, parentFn(tparam)) @@ -1076,7 +1141,7 @@ trait Definitions extends reflect.api.StandardDefinitions { clazz setInfo GenPolyType(List(tparam), ClassInfoType(parents, newScope, clazz)) } - def newPolyMethod(typeParamCount: Int, owner: Symbol, name: TermName, flags: Long)(createFn: PolyMethodCreator): Symbol = { + def newPolyMethod(typeParamCount: Int, owner: Symbol, name: TermName, flags: Long)(createFn: PolyMethodCreator): MethodSymbol = { val msym = owner.newMethod(name.encode, NoPosition, flags) val tparams = msym.newSyntheticTypeParams(typeParamCount) val mtpe = createFn(tparams) match { @@ -1089,16 +1154,16 @@ trait Definitions extends reflect.api.StandardDefinitions { /** T1 means one type parameter. */ - def newT1NullaryMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): Symbol = { + def newT1NullaryMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): MethodSymbol = { newPolyMethod(1, owner, name, flags)(tparams => (None, createFn(tparams.head))) } - def newT1NoParamsMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): Symbol = { + def newT1NoParamsMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): MethodSymbol = { newPolyMethod(1, owner, name, flags)(tparams => (Some(Nil), createFn(tparams.head))) } - lazy val boxedClassValues = boxedClass.values.toSet - lazy val isUnbox = unboxMethod.values.toSet - lazy val isBox = boxMethod.values.toSet + lazy val boxedClassValues = boxedClass.values.toSet[Symbol] + lazy val isUnbox = unboxMethod.values.toSet[Symbol] + lazy val isBox = boxMethod.values.toSet[Symbol] /** Is symbol a phantom class for which no runtime representation exists? */ lazy val isPhantomClass = Set[Symbol](AnyClass, AnyValClass, NullClass, NothingClass) @@ -1106,8 +1171,7 @@ trait Definitions extends reflect.api.StandardDefinitions { /** Is the symbol that of a parent which is added during parsing? */ lazy val isPossibleSyntheticParent = ProductClass.toSet[Symbol] + ProductRootClass + SerializableClass - lazy val scalaValueClassesSet = ScalaValueClasses.toSet - private lazy val boxedValueClassesSet = boxedClass.values.toSet + BoxedUnitClass + private lazy val boxedValueClassesSet = boxedClass.values.toSet[Symbol] + BoxedUnitClass /** Is symbol a value class? */ def isPrimitiveValueClass(sym: Symbol) = ScalaValueClasses contains sym diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala deleted file mode 100644 index ac22017569..0000000000 --- a/src/compiler/scala/reflect/internal/NameManglers.scala +++ /dev/null @@ -1,216 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import java.security.MessageDigest -import scala.io.Codec -import Chars.isOperatorPart - -/** A trait to encapsulate name mangling. It's intended for the - * values and methods involved in assembling names out of other names, - * and not for simple synthetically named locals. - */ -trait NameManglers { - self: SymbolTable => - - trait NameManglingCommon { - self: CommonNames => - - val MODULE_SUFFIX_STRING = NameTransformer.MODULE_SUFFIX_STRING - val NAME_JOIN_STRING = NameTransformer.NAME_JOIN_STRING - - val MODULE_SUFFIX_NAME: TermName = newTermName(MODULE_SUFFIX_STRING) - val NAME_JOIN_NAME: TermName = newTermName(NAME_JOIN_STRING) - - def flattenedName(segments: Name*): NameType = compactedString(segments mkString NAME_JOIN_STRING) - - /** - * COMPACTIFY - * - * The hashed name has the form (prefix + marker + md5 + marker + suffix), where - * - prefix/suffix.length = MaxNameLength / 4 - * - md5.length = 32 - * - * We obtain the formula: - * - * FileNameLength = 2*(MaxNameLength / 4) + 2.marker.length + 32 + 6 - * - * (+6 for ".class"). MaxNameLength can therefore be computed as follows: - */ - private final val marker = "$$$$" - private final val MaxNameLength = math.min( - settings.maxClassfileName.value - 6, - 2 * (settings.maxClassfileName.value - 6 - 2*marker.length - 32) - ) - private lazy val md5 = MessageDigest.getInstance("MD5") - private def toMD5(s: String, edge: Int) = { - val prefix = s take edge - val suffix = s takeRight edge - - val cs = s.toArray - val bytes = Codec toUTF8 cs - md5 update bytes - val md5chars = md5.digest() map (b => (b & 0xFF).toHexString) mkString - - prefix + marker + md5chars + marker + suffix - } - private def compactedString(s: String) = - if (s.length <= MaxNameLength) s - else toMD5(s, MaxNameLength / 4) - } - - trait TypeNameMangling extends NameManglingCommon { - self: tpnme.type => - - } - - trait TermNameMangling extends NameManglingCommon { - self: nme.type => - - val IMPL_CLASS_SUFFIX = "$class" - val LOCALDUMMY_PREFIX = " false - case _ => - name.endChar == '=' && name.startChar != '=' && isOperatorPart(name.startChar) - } - - /** The expanded setter name of `name` relative to this class `base` - */ - def expandedSetterName(name: TermName, base: Symbol): TermName = - expandedName(name, base, separator = TRAIT_SETTER_SEPARATOR_STRING) - - /** If `name` is an expandedName name, the original name. - * Otherwise `name` itself. - */ - def originalName(name: Name): Name = { - var i = name.length - while (i >= 2 && !(name(i - 1) == '$' && name(i - 2) == '$')) i -= 1 - if (i >= 2) { - while (i >= 3 && name(i - 3) == '$') i -= 1 - name.subName(i, name.length) - } else name - } - - def unspecializedName(name: Name): Name = ( - if (name endsWith SPECIALIZED_SUFFIX) - name.subName(0, name.lastIndexOf('m') - 1) - else name - ) - - /** Return the original name and the types on which this name - * is specialized. For example, - * {{{ - * splitSpecializedName("foo$mIcD$sp") == ('foo', "I", "D") - * }}} - * `foo$mIcD$sp` is the name of a method specialized on two type - * parameters, the first one belonging to the method itself, on Int, - * and another one belonging to the enclosing class, on Double. - */ - def splitSpecializedName(name: Name): (Name, String, String) = - if (name endsWith SPECIALIZED_SUFFIX) { - val name1 = name dropRight SPECIALIZED_SUFFIX.length - val idxC = name1 lastIndexOf 'c' - val idxM = name1 lastIndexOf 'm' - - (name1.subName(0, idxM - 1), - name1.subName(idxC + 1, name1.length).toString, - name1.subName(idxM + 1, idxC).toString) - } else - (name, "", "") - - def getterName(name: TermName): TermName = if (isLocalName(name)) localToGetter(name) else name - def getterToLocal(name: TermName): TermName = name append LOCAL_SUFFIX_STRING - def getterToSetter(name: TermName): TermName = name append SETTER_SUFFIX - def localToGetter(name: TermName): TermName = name dropRight LOCAL_SUFFIX_STRING.length - - def dropLocalSuffix(name: Name): Name = if (name endsWith ' ') name dropRight 1 else name - - def setterToGetter(name: TermName): TermName = { - val p = name.pos(TRAIT_SETTER_SEPARATOR_STRING) - if (p < name.length) - setterToGetter(name drop (p + TRAIT_SETTER_SEPARATOR_STRING.length)) - else - name.subName(0, name.length - SETTER_SUFFIX.length) - } - - def defaultGetterName(name: Name, pos: Int): TermName = { - val prefix = if (isConstructorName(name)) "init" else name - newTermName(prefix + DEFAULT_GETTER_STRING + pos) - } - def defaultGetterToMethod(name: Name): TermName = { - val p = name.pos(DEFAULT_GETTER_STRING) - if (p < name.length) name.toTermName.subName(0, p) - else name.toTermName - } - - // def anonNumberSuffix(name: Name): Name = { - // ("" + name) lastIndexOf '$' match { - // case -1 => nme.EMPTY - // case idx => - // val s = name drop idx - // if (s.toString forall (_.isDigit)) s - // else nme.EMPTY - // } - // } - - // If the name ends with $nn where nn are - // all digits, strip the $ and the digits. - // Otherwise return the argument. - def stripAnonNumberSuffix(name: Name): Name = { - var pos = name.length - while (pos > 0 && name(pos - 1).isDigit) - pos -= 1 - - if (pos <= 0 || pos == name.length || name(pos - 1) != '$') name - else name.subName(0, pos - 1) - } - - def stripModuleSuffix(name: Name): Name = ( - if (isModuleName(name)) name dropRight MODULE_SUFFIX_STRING.length else name - ) - - def dropSingletonName(name: Name): TypeName = name dropRight SINGLETON_SUFFIX.length toTypeName - def singletonName(name: Name): TypeName = name append SINGLETON_SUFFIX toTypeName - def implClassName(name: Name): TypeName = name append IMPL_CLASS_SUFFIX toTypeName - def interfaceName(implname: Name): TypeName = implname dropRight IMPL_CLASS_SUFFIX.length toTypeName - def localDummyName(clazz: Symbol): TermName = newTermName(LOCALDUMMY_PREFIX + clazz.name + ">") - def superName(name: Name): TermName = newTermName(SUPER_PREFIX_STRING + name) - - /** The name of an accessor for protected symbols. */ - def protName(name: Name): TermName = newTermName(PROTECTED_PREFIX + name) - - /** The name of a setter for protected symbols. Used for inherited Java fields. */ - def protSetterName(name: Name): TermName = newTermName(PROTECTED_SET_PREFIX + name) - } -} diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala index d2b55d9d39..dc89b14869 100644 --- a/src/compiler/scala/reflect/internal/Names.scala +++ b/src/compiler/scala/reflect/internal/Names.scala @@ -356,8 +356,10 @@ trait Names extends api.Names { final def endsWith(char: Char): Boolean = len > 0 && endChar == char final def endsWith(name: String): Boolean = endsWith(newTermName(name)) - def dropRight(n: Int) = subName(0, len - n) - def drop(n: Int) = subName(n, len) + def dropRight(n: Int): ThisNameType = subName(0, len - n) + def drop(n: Int): ThisNameType = subName(n, len) + def stripSuffix(suffix: Name): ThisNameType = + if (this endsWith suffix) dropRight(suffix.length) else thisName def indexOf(ch: Char) = { val idx = pos(ch) diff --git a/src/compiler/scala/reflect/internal/Scopes.scala b/src/compiler/scala/reflect/internal/Scopes.scala index ef48d6102f..36e8ebb212 100644 --- a/src/compiler/scala/reflect/internal/Scopes.scala +++ b/src/compiler/scala/reflect/internal/Scopes.scala @@ -113,7 +113,7 @@ trait Scopes extends api.Scopes { self: SymbolTable => * * @param sym ... */ - def enter(sym: Symbol): Symbol = { enter(newScopeEntry(sym, this)); sym } + def enter[T <: Symbol](sym: T): T = { enter(newScopeEntry(sym, this)); sym } /** enter a symbol, asserting that no symbol with same name exists in scope * diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index c5fe1ecb45..54be83c98f 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -6,27 +6,141 @@ package scala.reflect package internal -import scala.collection.immutable -import NameTransformer.MODULE_SUFFIX_STRING +import java.security.MessageDigest +import Chars.isOperatorPart import annotation.switch import language.implicitConversions +import scala.collection.immutable +import scala.io.Codec -trait StdNames extends NameManglers { self: SymbolTable => +trait StdNames { + self: SymbolTable => def encode(str: String): TermName = newTermNameCached(NameTransformer.encode(str)) implicit def lowerTermNames(n: TermName): String = n.toString - // implicit def stringToTermName(s: String): TermName = newTermName(s) - - /** This should be the first trait in the linearization. */ - trait Keywords { + /** Tensions: would like the keywords to be the very first names entered into the names + * storage so their ids count from 0, which simplifies the parser. Switched to abstract + * classes to avoid all the indirection which is generated with implementation-containing + * traits. Since all these classes use eager vals, that means the constructor with the + * keywords must run first. If it's the top in the superclass chain, then CommonNames + * must inherit from it, which means TypeNames would inherit keywords as well. + * + * Solution: Keywords extends CommonNames and uses early defs to beat the + * CommonNames constructor out of the starting gate. This is its builder. + */ + private class KeywordSetBuilder { private var kws: Set[TermName] = Set() - private def kw(s: String): TermName = { + def apply(s: String): TermName = { val result = newTermNameCached(s) kws = kws + result result } + def result: Set[TermName] = { + val result = kws + kws = null + result + } + } + + private final object compactify extends (String => String) { + val md5 = MessageDigest.getInstance("MD5") + + /** + * COMPACTIFY + * + * The hashed name has the form (prefix + marker + md5 + marker + suffix), where + * - prefix/suffix.length = MaxNameLength / 4 + * - md5.length = 32 + * + * We obtain the formula: + * + * FileNameLength = 2*(MaxNameLength / 4) + 2.marker.length + 32 + 6 + * + * (+6 for ".class"). MaxNameLength can therefore be computed as follows: + */ + val marker = "$$$$" + val MaxNameLength = math.min( + settings.maxClassfileName.value - 6, + 2 * (settings.maxClassfileName.value - 6 - 2*marker.length - 32) + ) + def toMD5(s: String, edge: Int): String = { + val prefix = s take edge + val suffix = s takeRight edge + + val cs = s.toArray + val bytes = Codec toUTF8 cs + md5 update bytes + val md5chars = md5.digest() map (b => (b & 0xFF).toHexString) mkString + + prefix + marker + md5chars + marker + suffix + } + def apply(s: String): String = ( + if (s.length <= MaxNameLength) s + else toMD5(s, MaxNameLength / 4) + ) + } + + abstract class CommonNames { + type NameType <: Name + protected implicit def createNameType(name: String): NameType + + def flattenedName(segments: Name*): NameType = + compactify(segments mkString NAME_JOIN_STRING) + + val MODULE_SUFFIX_STRING: String = NameTransformer.MODULE_SUFFIX_STRING + val NAME_JOIN_STRING: String = NameTransformer.NAME_JOIN_STRING + val SINGLETON_SUFFIX: String = ".type" + + val ANON_CLASS_NAME: NameType = "$anon" + val ANON_FUN_NAME: NameType = "$anonfun" + val EMPTY: NameType = "" + val EMPTY_PACKAGE_NAME: NameType = "" + val IMPL_CLASS_SUFFIX = "$class" + val IMPORT: NameType = "" + val MODULE_SUFFIX_NAME: NameType = MODULE_SUFFIX_STRING + val MODULE_VAR_SUFFIX: NameType = "$module" + val NAME_JOIN_NAME: NameType = NAME_JOIN_STRING + val PACKAGE: NameType = "package" + val ROOT: NameType = "" + val SPECIALIZED_SUFFIX: NameType = "$sp" + + // value types (and AnyRef) are all used as terms as well + // as (at least) arguments to the @specialize annotation. + final val Boolean: NameType = "Boolean" + final val Byte: NameType = "Byte" + final val Char: NameType = "Char" + final val Double: NameType = "Double" + final val Float: NameType = "Float" + final val Int: NameType = "Int" + final val Long: NameType = "Long" + final val Short: NameType = "Short" + final val Unit: NameType = "Unit" + + final val ScalaValueNames: scala.List[NameType] = + scala.List(Byte, Char, Short, Int, Long, Float, Double, Boolean, Unit) + + // some types whose companions we utilize + final val AnyRef: NameType = "AnyRef" + final val Array: NameType = "Array" + 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 ConcreteTypeTag: NameType = "ConcreteTypeTag" + + // fictions we use as both types and terms + final val ERROR: NameType = "" + final val NO_NAME: NameType = "" // formerly NOSYMBOL + final val WILDCARD: NameType = "_" + } + + /** This should be the first trait in the linearization. */ + // abstract class Keywords extends CommonNames { + abstract class Keywords extends { + private val kw = new KeywordSetBuilder final val ABSTRACTkw: TermName = kw("abstract") final val CASEkw: TermName = kw("case") @@ -81,66 +195,20 @@ trait StdNames extends NameManglers { self: SymbolTable => final val HASHkw: TermName = kw("#") final val ATkw: TermName = kw("@") - final val keywords = { - val result = kws.toSet - kws = null - result - } - + final val keywords = kw.result + } with CommonNames { final val javaKeywords = new JavaKeywords() } - trait CommonNames /*extends LibraryCommonNames*/ { - - type NameType <: Name - protected implicit def createNameType(name: String): NameType - - val EMPTY: NameType = "" - val ANON_FUN_NAME: NameType = "$anonfun" - val ANON_CLASS_NAME: NameType = "$anon" - val EMPTY_PACKAGE_NAME: NameType = "" - val IMPORT: NameType = "" - val MODULE_VAR_SUFFIX: NameType = "$module" - val ROOT: NameType = "" - val PACKAGE: NameType = "package" - val SPECIALIZED_SUFFIX: NameType = "$sp" - - // value types (and AnyRef) are all used as terms as well - // as (at least) arguments to the @specialize annotation. - final val Boolean: NameType = "Boolean" - final val Byte: NameType = "Byte" - final val Char: NameType = "Char" - final val Double: NameType = "Double" - final val Float: NameType = "Float" - final val Int: NameType = "Int" - final val Long: NameType = "Long" - final val Short: NameType = "Short" - final val Unit: NameType = "Unit" - - final val ScalaValueNames: scala.List[NameType] = - scala.List(Byte, Char, Short, Int, Long, Float, Double, Boolean, Unit) - - // some types whose companions we utilize - final val AnyRef: NameType = "AnyRef" - final val Array: NameType = "Array" - 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 ConcreteTypeTag: NameType = "ConcreteTypeTag" - - // fictions we use as both types and terms - final val ERROR: NameType = "" - final val NO_NAME: NameType = "" // formerly NOSYMBOL - final val WILDCARD: NameType = "_" - } + abstract class TypeNames extends Keywords { + type NameType = TypeName + protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name) - trait TypeNames extends CommonNames { final val BYNAME_PARAM_CLASS_NAME: NameType = "" final val EQUALS_PATTERN_NAME: NameType = "" final val JAVA_REPEATED_PARAM_CLASS_NAME: NameType = "" final val LOCAL_CHILD: NameType = "" + final val REFINE_CLASS_NAME: NameType = "" final val REPEATED_PARAM_CLASS_NAME: NameType = "" final val WILDCARD_STAR: NameType = "_*" @@ -161,7 +229,7 @@ trait StdNames extends NameManglers { self: SymbolTable => final val Annotation: NameType = "Annotation" final val ClassfileAnnotation: NameType = "ClassfileAnnotation" final val Enum: NameType = "Enum" - + final val Group: NameType = "Group" final val Tree: NameType = "Tree" final val TypeTree: NameType = "TypeTree" @@ -189,34 +257,195 @@ trait StdNames extends NameManglers { self: SymbolTable => final val SignatureATTR: NameType = "Signature" final val SourceFileATTR: NameType = "SourceFile" final val SyntheticATTR: NameType = "Synthetic" + + def dropSingletonName(name: Name): TypeName = name dropRight SINGLETON_SUFFIX.length toTypeName + def singletonName(name: Name): TypeName = name append SINGLETON_SUFFIX toTypeName + def implClassName(name: Name): TypeName = name append IMPL_CLASS_SUFFIX toTypeName + def interfaceName(implname: Name): TypeName = implname dropRight IMPL_CLASS_SUFFIX.length toTypeName } - trait TermNames extends Keywords with CommonNames { + abstract class TermNames extends Keywords { + type NameType = TermName + protected implicit def createNameType(name: String): TermName = newTermNameCached(name) + + /** Base strings from which synthetic names are derived. */ + val BITMAP_PREFIX = "bitmap$" + val CHECK_IF_REFUTABLE_STRING = "check$ifrefutable$" + val DEFAULT_GETTER_STRING = "$default$" + val DO_WHILE_PREFIX = "doWhile$" + val EVIDENCE_PARAM_PREFIX = "evidence$" + val EXCEPTION_RESULT_PREFIX = "exceptionResult" + val EXPAND_SEPARATOR_STRING = "$$" + val INTERPRETER_IMPORT_WRAPPER = "$iw" + val INTERPRETER_LINE_PREFIX = "line" + val INTERPRETER_VAR_PREFIX = "res" + val INTERPRETER_WRAPPER_SUFFIX = "$object" + val LOCALDUMMY_PREFIX = " false + case _ => + name.endChar == '=' && name.startChar != '=' && isOperatorPart(name.startChar) + } + + /** The expanded name of `name` relative to this class `base` with given `separator` + */ + def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName = + newTermNameCached(base.fullName('$') + separator + name) + + /** The expanded setter name of `name` relative to this class `base` + */ + def expandedSetterName(name: TermName, base: Symbol): TermName = + expandedName(name, base, separator = TRAIT_SETTER_SEPARATOR_STRING) + + /** If `name` is an expandedName name, the original name. + * Otherwise `name` itself. + */ + def originalName(name: Name): Name = { + var i = name.length + while (i >= 2 && !(name(i - 1) == '$' && name(i - 2) == '$')) i -= 1 + if (i >= 2) { + while (i >= 3 && name(i - 3) == '$') i -= 1 + name.subName(i, name.length) + } else name + } + + def unspecializedName(name: Name): Name = ( + if (name endsWith SPECIALIZED_SUFFIX) + name.subName(0, name.lastIndexOf('m') - 1) + else name + ) + + /* + def anonNumberSuffix(name: Name): Name = { + ("" + name) lastIndexOf '$' match { + case -1 => nme.EMPTY + case idx => + val s = name drop idx + if (s.toString forall (_.isDigit)) s + else nme.EMPTY + } + } + */ + + /** Return the original name and the types on which this name + * is specialized. For example, + * {{{ + * splitSpecializedName("foo$mIcD$sp") == ('foo', "I", "D") + * }}} + * `foo$mIcD$sp` is the name of a method specialized on two type + * parameters, the first one belonging to the method itself, on Int, + * and another one belonging to the enclosing class, on Double. + */ + def splitSpecializedName(name: Name): (Name, String, String) = + if (name endsWith SPECIALIZED_SUFFIX) { + val name1 = name dropRight SPECIALIZED_SUFFIX.length + val idxC = name1 lastIndexOf 'c' + val idxM = name1 lastIndexOf 'm' + + (name1.subName(0, idxM - 1), + name1.subName(idxC + 1, name1.length).toString, + name1.subName(idxM + 1, idxC).toString) + } else + (name, "", "") + + def getterName(name: TermName): TermName = if (isLocalName(name)) localToGetter(name) else name + def getterToLocal(name: TermName): TermName = name append LOCAL_SUFFIX_STRING + def getterToSetter(name: TermName): TermName = name append SETTER_SUFFIX + def localToGetter(name: TermName): TermName = name dropRight LOCAL_SUFFIX_STRING.length + + def dropLocalSuffix(name: Name): Name = if (name endsWith ' ') name dropRight 1 else name + + def setterToGetter(name: TermName): TermName = { + val p = name.pos(TRAIT_SETTER_SEPARATOR_STRING) + if (p < name.length) + setterToGetter(name drop (p + TRAIT_SETTER_SEPARATOR_STRING.length)) + else + name.subName(0, name.length - SETTER_SUFFIX.length) + } + + def defaultGetterName(name: Name, pos: Int): TermName = { + val prefix = if (isConstructorName(name)) "init" else name + newTermName(prefix + DEFAULT_GETTER_STRING + pos) + } + def defaultGetterToMethod(name: Name): TermName = { + val p = name.pos(DEFAULT_GETTER_STRING) + if (p < name.length) name.toTermName.subName(0, p) + else name.toTermName + } + + // If the name ends with $nn where nn are + // all digits, strip the $ and the digits. + // Otherwise return the argument. + def stripAnonNumberSuffix(name: Name): Name = { + var pos = name.length + while (pos > 0 && name(pos - 1).isDigit) + pos -= 1 + + if (pos <= 0 || pos == name.length || name(pos - 1) != '$') name + else name.subName(0, pos - 1) + } + + def stripModuleSuffix(name: Name): Name = ( + if (isModuleName(name)) name dropRight MODULE_SUFFIX_STRING.length else name + ) + def localDummyName(clazz: Symbol): TermName = newTermName(LOCALDUMMY_PREFIX + clazz.name + ">") + def superName(name: Name): TermName = newTermName(SUPER_PREFIX_STRING + name) + + /** The name of an accessor for protected symbols. */ + def protName(name: Name): TermName = newTermName(PROTECTED_PREFIX + name) + + /** The name of a setter for protected symbols. Used for inherited Java fields. */ + def protSetterName(name: Name): TermName = newTermName(PROTECTED_SET_PREFIX + name) final val Nil: NameType = "Nil" final val Predef: NameType = "Predef" @@ -508,19 +737,11 @@ trait StdNames extends NameManglers { self: SymbolTable => val toInteger: NameType = "toInteger" } - object tpnme extends AbsTypeNames with TypeNames /*with LibraryTypeNames*/ with TypeNameMangling { - type NameType = TypeName - protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name) - - val REFINE_CLASS_NAME: NameType = "" - } + object tpnme extends TypeNames with AbsTypeNames { } /** For fully qualified type names. */ object fulltpnme extends TypeNames { - type NameType = TypeName - protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name) - val RuntimeNothing: NameType = "scala.runtime.Nothing$" val RuntimeNull: NameType = "scala.runtime.Null$" val JavaLangEnum: NameType = "java.lang.Enum" @@ -535,18 +756,9 @@ trait StdNames extends NameManglers { self: SymbolTable => val RuntimeNull = toBinary(fulltpnme.RuntimeNull).toTypeName } - object fullnme extends TermNames { - type NameType = TermName - protected implicit def createNameType(name: String): TermName = newTermNameCached(name) - - val MirrorPackage: NameType = "scala.reflect.mirror" - } - val javanme = nme.javaKeywords - object nme extends AbsTermNames with TermNames /*with LibraryTermNames*/ with TermNameMangling { - type NameType = TermName - protected implicit def createNameType(name: String): TermName = newTermNameCached(name) + object nme extends TermNames with AbsTermNames { /** Translate a String into a list of simple TypeNames and TermNames. * In all segments before the last, type/term is determined by whether @@ -586,40 +798,20 @@ trait StdNames extends NameManglers { self: SymbolTable => def newBitmapName(bitmapPrefix: Name, n: Int) = bitmapPrefix append ("" + n) - val BITMAP_PREFIX: String = "bitmap$" val BITMAP_NORMAL: NameType = BITMAP_PREFIX + "" // initialization bitmap for public/protected lazy vals val BITMAP_TRANSIENT: NameType = BITMAP_PREFIX + "trans$" // initialization bitmap for transient lazy vals val BITMAP_PRIVATE: NameType = BITMAP_PREFIX + "priv$" // initialization bitmap for private lazy vals val BITMAP_CHECKINIT: NameType = BITMAP_PREFIX + "init$" // initialization bitmap for checkinit values val BITMAP_CHECKINIT_TRANSIENT: NameType = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values - /** The expanded name of `name` relative to this class `base` with given `separator` - */ - def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName = - newTermNameCached(base.fullName('$') + separator + name) - def isModuleVarName(name: Name): Boolean = stripAnonNumberSuffix(name) endsWith MODULE_VAR_SUFFIX def moduleVarName(name: TermName): TermName = newTermNameCached("" + name + MODULE_VAR_SUFFIX) - val ROOTPKG: TermName = "_root_" - - /** Base strings from which synthetic names are derived. */ - val CHECK_IF_REFUTABLE_STRING = "check$ifrefutable$" - val DEFAULT_GETTER_STRING = "$default$" - val DO_WHILE_PREFIX = "doWhile$" - val EQEQ_LOCAL_VAR_STRING = "eqEqTemp$" - val EVIDENCE_PARAM_PREFIX = "evidence$" - val EXCEPTION_RESULT_PREFIX = "exceptionResult" - val INTERPRETER_IMPORT_WRAPPER = "$iw" - val INTERPRETER_LINE_PREFIX = "line" - val INTERPRETER_VAR_PREFIX = "res" - val INTERPRETER_WRAPPER_SUFFIX = "$object" - val WHILE_PREFIX = "while$" - - val EQEQ_LOCAL_VAR: TermName = newTermName(EQEQ_LOCAL_VAR_STRING) + val ROOTPKG: TermName = "_root_" + val EQEQ_LOCAL_VAR: TermName = "eqEqTemp$" def getCause = sn.GetCause def getClass_ = sn.GetClass @@ -783,6 +975,11 @@ trait StdNames extends NameManglers { self: SymbolTable => case 22 => nme._22 case _ => newTermName("_" + j) } + + @deprecated("Use a method in tpnme", "2.10.0") def dropSingletonName(name: Name): TypeName = tpnme.dropSingletonName(name) + @deprecated("Use a method in tpnme", "2.10.0") def singletonName(name: Name): TypeName = tpnme.singletonName(name) + @deprecated("Use a method in tpnme", "2.10.0") def implClassName(name: Name): TypeName = tpnme.implClassName(name) + @deprecated("Use a method in tpnme", "2.10.0") def interfaceName(implname: Name): TypeName = tpnme.interfaceName(implname) } abstract class SymbolNames { @@ -816,12 +1013,7 @@ trait StdNames extends NameManglers { self: SymbolTable => } class JavaKeywords { - private var kws: Set[TermName] = Set() - private def kw(s: String): TermName = { - val result = newTermNameCached(s) - kws = kws + result - result - } + private val kw = new KeywordSetBuilder final val ABSTRACTkw: TermName = kw("abstract") final val ASSERTkw: TermName = kw("assert") @@ -874,11 +1066,7 @@ trait StdNames extends NameManglers { self: SymbolTable => final val VOLATILEkw: TermName = kw("volatile") final val WHILEkw: TermName = kw("while") - final val keywords = { - val result = kws.toSet - kws = null - result - } + final val keywords = kw.result } private abstract class JavaNames extends SymbolNames { diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index c9ac929edf..380ceb4bc7 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -232,7 +232,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => newTermSymbol(name, pos, PARAM | newFlags) /** Create local dummy for template (owner of local blocks) */ - final def newLocalDummy(pos: Position) = + final def newLocalDummy(pos: Position): TermSymbol = newTermSymbol(nme.localDummyName(this), pos) setInfo NoType final def newMethod(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol = createMethodSymbol(name, pos, METHOD | newFlags) @@ -240,15 +240,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => newMethod(name, pos, LABEL) /** Propagates ConstrFlags (JAVA, specifically) from owner to constructor. */ - final def newConstructor(pos: Position, newFlags: Long = 0L) = + final def newConstructor(pos: Position, newFlags: Long = 0L): MethodSymbol = newMethod(nme.CONSTRUCTOR, pos, getFlag(ConstrFlags) | newFlags) /** Static constructor with info set. */ - def newStaticConstructor(pos: Position) = + def newStaticConstructor(pos: Position): MethodSymbol = newConstructor(pos, STATIC) setInfo UnitClass.tpe /** Instance constructor with info set. */ - def newClassConstructor(pos: Position) = + def newClassConstructor(pos: Position): MethodSymbol = newConstructor(pos) setInfo MethodType(Nil, this.tpe) def newLinkedModule(clazz: Symbol, newFlags: Long = 0L): ModuleSymbol = { @@ -266,10 +266,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => newModule(name, pos, PackageFlags | newFlags) } - final def newThisSym(name: TermName = nme.this_, pos: Position = NoPosition) = + final def newThisSym(name: TermName = nme.this_, pos: Position = NoPosition): TermSymbol = newTermSymbol(name, pos, SYNTHETIC) - final def newImport(pos: Position) = + final def newImport(pos: Position): TermSymbol = newTermSymbol(nme.IMPORT, pos) final def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = @@ -299,45 +299,45 @@ trait Symbols extends api.Symbols { self: SymbolTable => * * pre.memberType(m) */ - final def newOverloaded(pre: Type, alternatives: List[Symbol]): Symbol = ( + final def newOverloaded(pre: Type, alternatives: List[Symbol]): TermSymbol = ( newTermSymbol(alternatives.head.name.toTermName, alternatives.head.pos, OVERLOADED) setInfo OverloadedType(pre, alternatives) ) - final def newErrorValue(name: TermName) = + final def newErrorValue(name: TermName): TermSymbol = newTermSymbol(name, pos, SYNTHETIC | IS_ERROR) setInfo ErrorType /** Symbol of a type definition type T = ... */ - final def newAliasType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = + final def newAliasType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AliasTypeSymbol = createAliasTypeSymbol(name, pos, newFlags) /** Symbol of an abstract type type T >: ... <: ... */ - final def newAbstractType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = + final def newAbstractType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AbstractTypeSymbol = createAbstractTypeSymbol(name, pos, DEFERRED | newFlags) /** Symbol of a type parameter */ - final def newTypeParameter(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) = + final def newTypeParameter(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = newAbstractType(name, pos, PARAM | newFlags) /** Symbol of an existential type T forSome { ... } */ - final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = + final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = newAbstractType(name, pos, EXISTENTIAL | newFlags) /** Synthetic value parameters when parameter symbols are not available */ - final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[Symbol]] = { + final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[TermSymbol]] = { var cnt = 0 def freshName() = { cnt += 1; nme.syntheticParamName(cnt) } mmap(argtypess)(tp => newValueParameter(freshName(), owner.pos.focus, SYNTHETIC) setInfo tp) } - def newSyntheticTypeParam(): Symbol = newSyntheticTypeParam("T0", 0L) - def newSyntheticTypeParam(name: String, newFlags: Long): Symbol = newTypeParameter(newTypeName(name), NoPosition, newFlags) setInfo TypeBounds.empty - def newSyntheticTypeParams(num: Int): List[Symbol] = (0 until num).toList map (n => newSyntheticTypeParam("T" + n, 0L)) + def newSyntheticTypeParam(): TypeSymbol = newSyntheticTypeParam("T0", 0L) + def newSyntheticTypeParam(name: String, newFlags: Long): TypeSymbol = newTypeParameter(newTypeName(name), NoPosition, newFlags) setInfo TypeBounds.empty + def newSyntheticTypeParams(num: Int): List[TypeSymbol] = (0 until num).toList map (n => newSyntheticTypeParam("T" + n, 0L)) /** Create a new existential type skolem with this symbol its owner, * based on the given symbol and origin. @@ -352,13 +352,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => def newGADTSkolem(name: TypeName, origin: Symbol, info: Type): TypeSkolem = newTypeSkolemSymbol(name, origin, origin.pos, origin.flags & ~(EXISTENTIAL | PARAM) | CASEACCESSOR | SYNTHETIC) setInfo info - final def freshExistential(suffix: String): Symbol = + final def freshExistential(suffix: String): TypeSymbol = newExistential(freshExistentialName(suffix), pos) /** Synthetic value parameters when parameter symbols are not available. * Calling this method multiple times will re-use the same parameter names. */ - final def newSyntheticValueParams(argtypes: List[Type]): List[Symbol] = + final def newSyntheticValueParams(argtypes: List[Type]): List[TermSymbol] = newSyntheticValueParamss(List(argtypes)).head /** Synthetic value parameter when parameter symbol is not available. @@ -372,27 +372,27 @@ trait Symbols extends api.Symbols { self: SymbolTable => * with name `T` in its typeParams list. While type checking the parameters, result type and * body of the method, there's a local copy of `T` which is a TypeSkolem. */ - final def newTypeSkolem: Symbol = + final def newTypeSkolem: TypeSkolem = owner.newTypeSkolemSymbol(name.toTypeName, this, pos, flags) - final def newClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) = + final def newClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = newClassSymbol(name, pos, newFlags) /** A new class with its info set to a ClassInfoType with given scope and parents. */ - def newClassWithInfo(name: TypeName, parents: List[Type], scope: Scope, pos: Position = NoPosition, newFlags: Long = 0L) = { + def newClassWithInfo(name: TypeName, parents: List[Type], scope: Scope, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = { val clazz = newClass(name, pos, newFlags) clazz setInfo ClassInfoType(parents, scope, clazz) } - final def newErrorClass(name: TypeName) = + final def newErrorClass(name: TypeName): ClassSymbol = newClassWithInfo(name, Nil, new ErrorScope(this), pos, SYNTHETIC | IS_ERROR) - final def newModuleClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) = + final def newModuleClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol = newModuleClassSymbol(name, pos, newFlags | MODULE) - final def newAnonymousFunctionClass(pos: Position = NoPosition, newFlags: Long = 0L) = + final def newAnonymousFunctionClass(pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = newClassSymbol(tpnme.ANON_FUN_NAME, pos, FINAL | SYNTHETIC | newFlags) - final def newAnonymousFunctionValue(pos: Position, newFlags: Long = 0L) = + final def newAnonymousFunctionValue(pos: Position, newFlags: Long = 0L): TermSymbol = newTermSymbol(nme.ANON_FUN_NAME, pos, SYNTHETIC | newFlags) setInfo NoType def newImplClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = { @@ -402,11 +402,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Refinement types P { val x: String; type T <: Number } * also have symbols, they are refinementClasses */ - final def newRefinementClass(pos: Position) = createRefinementClassSymbol(pos, 0L) + final def newRefinementClass(pos: Position): RefinementClassSymbol = + createRefinementClassSymbol(pos, 0L) /** Create a new getter for current symbol (which must be a field) */ - final def newGetter: Symbol = ( + final def newGetter: MethodSymbol = ( owner.newMethod(nme.getterName(name.toTermName), NoPosition, getterFlags(flags)) setPrivateWithin privateWithin setInfo MethodType(Nil, tpe) @@ -1654,7 +1655,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * symbol with the same owner, and the name of this symbol with $class * appended to it. */ - final def implClass: Symbol = owner.info.decl(nme.implClassName(name)) + final def implClass: Symbol = owner.info.decl(tpnme.implClassName(name)) /** The class that is logically an outer class of given `clazz`. * This is the enclosing class, except for classes defined locally to constructors, @@ -2242,13 +2243,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** String representation of existentially bound variable */ def existentialToString = if (isSingletonExistential && !settings.debug.value) - "val " + nme.dropSingletonName(name) + ": " + dropSingletonType(info.bounds.hi) + "val " + tpnme.dropSingletonName(name) + ": " + dropSingletonType(info.bounds.hi) else defString } /** A class for term symbols */ class TermSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) - extends Symbol(initOwner, initPos, initName) { + extends Symbol(initOwner, initPos, initName) with TermSymbolApi { private[this] var _referenced: Symbol = NoSymbol privateWithin = NoSymbol @@ -2417,7 +2418,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for module symbols */ class ModuleSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) - extends TermSymbol(initOwner, initPos, initName) with DistinguishingFlag { + extends TermSymbol(initOwner, initPos, initName) with DistinguishingFlag with ModuleSymbolApi { def distinguishingFlag = MODULE private var flatname: TermName = null @@ -2442,14 +2443,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => } class PackageSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TermName) - extends ModuleSymbol(owner0, pos0, name0) with DistinguishingFlag { + extends ModuleSymbol(owner0, pos0, name0) with DistinguishingFlag with PackageSymbolApi { override def distinguishingFlag = super.distinguishingFlag | PACKAGE override def isPackage = true } /** A class for method symbols */ class MethodSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) - extends TermSymbol(initOwner, initPos, initName) with DistinguishingFlag { + extends TermSymbol(initOwner, initPos, initName) with DistinguishingFlag with MethodSymbolApi { def distinguishingFlag = METHOD // MethodSymbols pick up MODULE when trait-owned object accessors are cloned // during mixin composition. @@ -2511,7 +2512,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * of this class. Classes are instances of a subclass. */ abstract class TypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) - extends Symbol(initOwner, initPos, initName) { + extends Symbol(initOwner, initPos, initName) with TypeSymbolApi { privateWithin = NoSymbol private[this] var _rawname: TypeName = initName @@ -2712,7 +2713,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for class symbols */ class ClassSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) - extends TypeSymbol(initOwner, initPos, initName) { + extends TypeSymbol(initOwner, initPos, initName) with ClassSymbolApi { type TypeOfClonedSymbol = ClassSymbol private[this] var flatname: TypeName = _ @@ -2759,7 +2760,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def toInterface: Symbol = ( if (isImplClass) { if (phase.next.erasedTypes) lastParent - else owner.info.decl(nme.interfaceName(name)) + else owner.info.decl(tpnme.interfaceName(name)) } else super.toInterface ) diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala index 1a374b6e59..f30ec67c7e 100644 --- a/src/compiler/scala/reflect/internal/TreeGen.scala +++ b/src/compiler/scala/reflect/internal/TreeGen.scala @@ -48,6 +48,9 @@ abstract class TreeGen extends api.AbsTreeGen { def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree = Apply(mkTypeApply(target, targs map TypeTree), args) + def mkNullaryCall(method: Symbol, targs: List[Type]): Tree = + mkTypeApply(mkAttributedRef(method), targs map TypeTree) + /** 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. diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 7115cafc33..32b09eddeb 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -2310,7 +2310,7 @@ trait Types extends api.Types { self: SymbolTable => else if (sym.isPackageClass || sym.isPackageObjectOrClass) sym.skipPackageObject.fullName + "." else if (isStable && nme.isSingletonName(sym.name)) - nme.dropSingletonName(sym.name) + "." + tpnme.dropSingletonName(sym.name) + "." else super.prefixString ) diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala index f89aa9bf5c..eb4bae78d0 100644 --- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala @@ -816,16 +816,10 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ { throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg) protected def errorMissingRequirement(name: Name, owner: Symbol): Symbol = - missingHook(owner, name) orElse { - val what = if (name.isTypeName) "type" else "value" - MissingRequirementError.notFound( - "while unpickling %s, reference %s %s of %s/%s/%s".format( - filename, - what, name.decode, owner.tpe.widen, - owner.tpe.typeSymbol.ownerChain, - owner.info.members.mkString("\n ", "\n ", "")) - ) - } + missingHook(owner, name) orElse MissingRequirementError.notFound( + "bad reference while unpickling %s: %s not found in %s".format( + filename, name.longString, owner.tpe.widen) + ) def inferMethodAlternative(fun: Tree, argtpes: List[Type], restpe: Type) {} // can't do it; need a compiler for that. diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala index 7c96b568bd..d9a89d0e6d 100644 --- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -12,6 +12,37 @@ trait Reifiers { import mirror._ import definitions._ + private lazy val ClassTagModule = ClassTagClass.companionSymbol + + // [Eugene] imho this logic should be moved into `erasure` + private def calculateTagErasure(tpe: Type) = tpe match { + case tpe if tpe.typeSymbol.isDerivedValueClass => tpe // [Eugene to Martin] is this correct? + case ConstantType(value) => tpe.widen.erasure + case _ => + // [Eugene] magikz. needs review + // necessary to deal with erasures of HK types, typeConstructor won't work + tpe.erasure.normalize match { + // we don't want undets in the result + case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) + case result => result + } + } + private def classTagFromArgument(tpe: Type, arg: Tree) = { + gen.mkMethodCall(ClassTagModule, nme.apply, List(tpe), List(arg)) + // val factory = TypeApply(Select(Ident(ClassTagModule), nme.apply), List(TypeTree(tpe))) + // Apply(factory, List(typeArg)) + } + private def classTagFromErasure(tpe: Type) = { + val erasure = calculateTagErasure(tpe) + classTagFromArgument(tpe, gen.mkNullaryCall(Predef_classOf, List(erasure))) + // val targ = TypeApply(Select(Ident(PredefModule), nme.classOf), List(TypeTree(erasure))) + // classTagFromArgument(tpe, targ) + } + private def typetagIsSynthetic(tree: Tree) = tree match { + case Block(_, _) => true + case _ => tree exists (_ hasSymbolWhich Set(TypeTagModule, ConcreteTypeTagModule)) + } + 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")) @@ -26,40 +57,36 @@ trait Reifiers { reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, requireConcreteTypeTag) def reifyErasure(tpe: Type): Tree = { - val positionBearer = enclosingMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] - val typetagInScope = callsiteTyper.context.withMacrosDisabled(callsiteTyper.resolveTypeTag(positionBearer, singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror), tpe, full = true)) - def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) + val positionBearer = (enclosingMacros.find(_.macroApplication.pos != NoPosition) match { + case None => EmptyTree + case Some(m) => m.macroApplication + }).asInstanceOf[Tree] + + val typetagInScope = callsiteTyper.context.withMacrosDisabled( + callsiteTyper.resolveTypeTag( + positionBearer, + singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror), + tpe, + full = true + ) + ) typetagInScope match { case success if !success.isEmpty && !typetagIsSynthetic(success) => - val factory = TypeApply(Select(Ident(ClassTagModule), nme.apply), List(TypeTree(tpe))) - Apply(factory, List(typetagInScope)) + classTagFromArgument(tpe, typetagInScope) case _ => if (tpe.typeSymbol == ArrayClass) { val componentTpe = tpe.typeArguments(0) val componentTag = callsiteTyper.resolveClassTag(positionBearer, componentTpe) Select(componentTag, nme.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.isSpliceable) throw new ReificationError(enclosingPosition, "tpe %s is an unresolved spliceable type".format(tpe)) - // [Eugene] imho this logic should be moved into `erasure` - var erasure = tpe match { - case tpe if tpe.typeSymbol.isDerivedValueClass => tpe // [Eugene to Martin] is this correct? - case ConstantType(value) => tpe.widen.erasure - case _ => { - // [Eugene] magikz. needs review - var result = tpe.erasure.normalize // necessary to deal with erasures of HK types, typeConstructor won't work - result = result match { - case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) // we don't want undets in the result - case _ => result - } - result - } - } - val factory = TypeApply(Select(Ident(ClassTagModule), nme.apply), List(TypeTree(tpe))) - Apply(factory, List(TypeApply(Select(Ident(PredefModule), nme.classOf), List(TypeTree(erasure))))) } + // [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? + else if (tpe.isSpliceable) { + throw new ReificationError(enclosingPosition, + "tpe %s is an unresolved spliceable type".format(tpe)) + } + else classTagFromErasure(tpe) } } diff --git a/src/compiler/scala/reflect/runtime/SynchronizedOps.scala b/src/compiler/scala/reflect/runtime/SynchronizedOps.scala index dd806beb2a..907c0dd369 100644 --- a/src/compiler/scala/reflect/runtime/SynchronizedOps.scala +++ b/src/compiler/scala/reflect/runtime/SynchronizedOps.scala @@ -39,7 +39,7 @@ trait SynchronizedOps extends internal.SymbolTable trait SynchronizedScope extends Scope { override def isEmpty: Boolean = synchronized { super.isEmpty } override def size: Int = synchronized { super.size } - override def enter(sym: Symbol) = synchronized { super.enter(sym) } + override def enter[T <: Symbol](sym: T): T = synchronized { super.enter(sym) } override def rehash(sym: Symbol, newname: Name) = synchronized { super.rehash(sym, newname) } override def unlink(e: ScopeEntry) = synchronized { super.unlink(e) } override def unlink(sym: Symbol) = synchronized { super.unlink(sym) } diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 6c038162b3..cf024ebacf 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1531,7 +1531,7 @@ class Global(var currentSettings: Settings, var reporter: NscReporter) extends S /** We resolve the class/object ambiguity by passing a type/term name. */ def showDef(fullName: Name, declsOnly: Boolean, ph: Phase) = { - val boringOwners = Set(definitions.AnyClass, definitions.AnyRefClass, definitions.ObjectClass) + val boringOwners = Set[Symbol](definitions.AnyClass, definitions.AnyRefClass, definitions.ObjectClass) def phased[T](body: => T): T = afterPhase(ph)(body) def boringMember(sym: Symbol) = boringOwners(sym.owner) def symString(sym: Symbol) = if (sym.isTerm) sym.defString else sym.toString diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala index 0f2a3e0395..b0204c5971 100755 --- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala @@ -30,7 +30,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { private[parser] var isPattern: Boolean = _ - private trait XMLTypeNames extends TypeNames { + private object xmltypes extends TypeNames { val _Comment: NameType = "Comment" val _Elem: NameType = "Elem" val _EntityRef: NameType = "EntityRef" @@ -45,7 +45,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { val _UnprefixedAttribute: NameType = "UnprefixedAttribute" } - private trait XMLTermNames extends TermNames { + private object xmlterms extends TermNames { val _Null: NameType = "Null" val __Elem: NameType = "Elem" val __Text: NameType = "Text" @@ -57,15 +57,6 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { val _xml: NameType = "xml" } - private object xmltypes extends XMLTypeNames { - type NameType = TypeName - implicit def createNameType(name: String): TypeName = newTypeNameCached(name) - } - private object xmlterms extends XMLTermNames { - type NameType = TermName - implicit def createNameType(name: String): TermName = newTermNameCached(name) - } - import xmltypes.{_Comment, _Elem, _EntityRef, _Group, _MetaData, _NamespaceBinding, _NodeBuffer, _PrefixedAttribute, _ProcInstr, _Text, _Unparsed, _UnprefixedAttribute} diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala index f61f78ebb2..1ec2cf017a 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala @@ -420,7 +420,7 @@ trait TypeKinds { self: ICodes => // between "object PackratParsers$class" and "trait PackratParsers" if (sym.isImplClass) { // pos/spec-List.scala is the sole failure if we don't check for NoSymbol - val traitSym = sym.owner.info.decl(nme.interfaceName(sym.name)) + val traitSym = sym.owner.info.decl(tpnme.interfaceName(sym.name)) if (traitSym != NoSymbol) return REFERENCE(traitSym) } diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 124a7509e8..a6728654cd 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -42,7 +42,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { memberSym.isOmittablePrefix || (closestPackage(memberSym) == closestPackage(templateSym)) } - private lazy val noSubclassCache = Set(AnyClass, AnyRefClass, ObjectClass) + private lazy val noSubclassCache = Set[Symbol](AnyClass, AnyRefClass, ObjectClass) /** */ def makeModel: Option[Universe] = { @@ -675,7 +675,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { } /* Refined types */ case RefinedType(parents, defs) => - val ignoreParents = Set(AnyClass, ObjectClass) + val ignoreParents = Set[Symbol](AnyClass, ObjectClass) val filtParents = parents filterNot (x => ignoreParents(x.typeSymbol)) match { case Nil => parents case ps => ps diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 13124e6afc..e0a98ace9d 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -197,8 +197,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends import global._ import definitions.{ - ScalaPackage, JavaLangPackage, PredefModule, RootClass, - getClassIfDefined, getModuleIfDefined, getRequiredModule, getRequiredClass + ScalaPackage, JavaLangPackage, RootClass, + getClassIfDefined, getModuleIfDefined, getRequiredModule, getRequiredClass, + termMember, typeMember } private implicit def privateTreeOps(t: Tree): List[Tree] = { @@ -807,9 +808,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends */ def resolvePathToSymbol(accessPath: String): Symbol = { val readRoot = getRequiredModule(readPath) // the outermost wrapper - (accessPath split '.').foldLeft(readRoot) { (sym, name) => - if (name == "") sym else - afterTyper(sym.info member newTermName(name)) + (accessPath split '.').foldLeft(readRoot: Symbol) { + case (sym, "") => sym + case (sym, name) => afterTyper(termMember(sym, name)) } } /** We get a bunch of repeated warnings for reasons I haven't diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala index 249f754e8f..72e6f32af1 100644 --- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala +++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala @@ -31,7 +31,7 @@ trait MatchSupport extends ast.TreeDSL { self: ParallelMatching => object Types { import definitions._ - val subrangeTypes = Set(ByteClass, ShortClass, CharClass, IntClass) + val subrangeTypes = Set[Symbol](ByteClass, ShortClass, CharClass, IntClass) implicit class RichType(undecodedTpe: Type) { def tpe = decodedEqualsType(undecodedTpe) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index 775a7a9d38..862a3ffdc7 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -165,7 +165,7 @@ abstract class ICodeReader extends ClassfileParser { else if (name == fulltpnme.RuntimeNull) definitions.NullClass else if (nme.isImplClassName(name)) { - val iface = definitions.getClass(nme.interfaceName(name)) + val iface = definitions.getClass(tpnme.interfaceName(name)) log("forcing " + iface.owner + " at phase: " + phase + " impl: " + iface.implClass) iface.owner.info // force the mixin type-transformer definitions.getClass(name) diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 5a11926048..3581f1b923 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -66,7 +66,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => private def newImplClass(iface: Symbol): Symbol = { val inClass = iface.owner.isClass - val implName = nme.implClassName(iface.name) + val implName = tpnme.implClassName(iface.name) val implFlags = (iface.flags & ~(INTERFACE | lateINTERFACE)) | IMPLCLASS val impl0 = ( diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index 6bddfe8d57..618a1cbba4 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -159,7 +159,7 @@ abstract class LambdaLift extends InfoTransform { // for that failure. There should be exactly one method for any given // entity which always gives the right answer. if (sym.isImplClass) - localImplClasses((sym.owner, nme.interfaceName(sym.name))) = sym + localImplClasses((sym.owner, tpnme.interfaceName(sym.name))) = sym else { renamable addEntry sym if (sym.isTrait) @@ -229,7 +229,7 @@ abstract class LambdaLift extends InfoTransform { def renameTrait(traitSym: Symbol, implSym: Symbol) { val originalImplName = implSym.name renameSym(traitSym) - implSym setName nme.implClassName(traitSym.name) + implSym setName tpnme.implClassName(traitSym.name) debuglog("renaming impl class in step with %s: %s => %s".format(traitSym, originalImplName, implSym.name)) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 651120db4f..f8da6a462d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1121,10 +1121,10 @@ trait Implicits { } // these should be lazy, otherwise we wouldn't be able to compile scala-library with starr - private val TagSymbols = Set(ClassTagClass, TypeTagClass, ConcreteTypeTagClass) - private val TagMaterializers = Map( - ClassTagClass -> MacroInternal_materializeClassTag, - TypeTagClass -> MacroInternal_materializeTypeTag, + private val TagSymbols = Set[Symbol](ClassTagClass, TypeTagClass, ConcreteTypeTagClass) + private val TagMaterializers = Map[Symbol, MethodSymbol]( + ClassTagClass -> MacroInternal_materializeClassTag, + TypeTagClass -> MacroInternal_materializeTypeTag, ConcreteTypeTagClass -> MacroInternal_materializeConcreteTypeTag ) @@ -1140,27 +1140,34 @@ trait Implicits { failure(arg, "failed to typecheck the materialized typetag: %n%s".format(ex.msg), ex.pos) } - 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)) - } - + val prefix = ( + // ClassTags only exist for scala.reflect.mirror, so their materializer + // doesn't care about prefixes + if (tagClass eq ClassTagClass) ( + gen.mkAttributedRef(Reflect_mirror) + setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror) + ) + else pre match { + // [Eugene to Martin] this is the crux of the interaction between + // implicits and reifiers here we need to turn a (supposedly + // path-dependent) type into a tree that will be used as a prefix I'm + // not sure if I've done this right - please, review + case SingleType(prePre, preSym) => + gen.mkAttributedRef(prePre, preSym) setType pre + // necessary only to compile typetags used inside the Universe cake + 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)) + } + ) // 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))) + var materializer = atPos(pos.focus)( + gen.mkMethodCall(TagMaterializers(tagClass), List(tp), List(prefix)) + ) if (settings.XlogImplicits.value) println("materializing requested %s.%s[%s] using %s".format(pre, tagClass.name, tp, materializer)) if (context.macrosEnabled) success(materializer) else failure(materializer, "macros are disabled") @@ -1169,8 +1176,8 @@ trait Implicits { /** The manifest corresponding to type `pt`, provided `pt` is an instance of Manifest. */ private def implicitTagOrOfExpectedType(pt: Type): SearchResult = pt.dealias match { - case TypeRef(pre, sym, args) if TagSymbols(sym) => - tagOfType(pre, args.head, sym) + case TypeRef(pre, sym, arg :: Nil) if TagSymbols(sym) => + tagOfType(pre, arg, sym) case tp@TypeRef(_, sym, _) if sym.isAbstractType => implicitTagOrOfExpectedType(tp.bounds.lo) // #3977: use tp (==pt.dealias), not pt (if pt is a type alias, pt.bounds.lo == pt) case _ => diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 43cbea83ff..d327d9c397 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -134,7 +134,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT // otherwise lead to either a compiler crash or runtime failure. private lazy val isDisallowed = { import definitions._ - Set(Any_isInstanceOf, Object_isInstanceOf, Any_asInstanceOf, Object_asInstanceOf, Object_==, Object_!=, Object_##) + Set[Symbol](Any_isInstanceOf, Object_isInstanceOf, Any_asInstanceOf, Object_asInstanceOf, Object_==, Object_!=, Object_##) } override def transform(tree: Tree): Tree = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 9a59d8f28a..54be9c9a87 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3322,7 +3322,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val typeParams: List[Symbol] = rawSyms map { sym => val name = sym.name match { case x: TypeName => x - case x => nme.singletonName(x) + case x => tpnme.singletonName(x) } val bound = allBounds(sym) val sowner = if (isRawParameter(sym)) context.owner else sym.owner diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala index 1fbf36be9d..c88b137f19 100644 --- a/src/library/scala/reflect/DummyMirror.scala +++ b/src/library/scala/reflect/DummyMirror.scala @@ -192,70 +192,70 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { val UnitTpe: Type = DummyType val definitions: AbsDefinitions = DummyDefinitions object DummyDefinitions extends AbsDefinitions { - def AnyClass: Symbol = DummySymbol - def AnyRefClass: Symbol = DummySymbol - def AnyValClass: Symbol = DummySymbol - def ArrayClass: Symbol = DummySymbol - def ArrayModule: Symbol = DummySymbol - def ArrayModule_overloadedApply: Symbol = DummySymbol - def Array_apply: Symbol = DummySymbol - def Array_clone: Symbol = DummySymbol - def Array_length: Symbol = DummySymbol - def Array_update: Symbol = DummySymbol - def BooleanClass: Symbol = DummySymbol - def ByNameParamClass: Symbol = DummySymbol - def ByteClass: Symbol = DummySymbol - def CharClass: Symbol = DummySymbol - def ClassClass: Symbol = DummySymbol - def ClassTagClass: Symbol = DummySymbol - def ClassTagModule: Symbol = DummySymbol - def ConcreteTypeTagClass: Symbol = DummySymbol - def ConcreteTypeTagModule: Symbol = DummySymbol - def ConsClass: Symbol = DummySymbol - def DoubleClass: Symbol = DummySymbol - def EmptyPackage: Symbol = DummySymbol - def EmptyPackageClass: Symbol = DummySymbol - def FloatClass: Symbol = DummySymbol + def ByNameParamClass = ??? + def JavaRepeatedParamClass = ??? + def RepeatedParamClass = ??? + def AnyClass = ??? + def AnyRefClass = ??? + def AnyValClass = ??? + def ArrayClass = ??? + def ArrayModule = ??? + def ArrayModule_overloadedApply = ??? + def Array_apply = ??? + def Array_clone = ??? + def Array_length = ??? + def Array_update = ??? + def BooleanClass = ??? + def ByteClass = ??? + def CharClass = ??? + def ClassClass = ??? + def ClassTagClass = ??? + def ClassTagModule = ??? + def ConcreteTypeTagClass = ??? + def ConcreteTypeTagModule = ??? + def ConsClass = ??? + def DoubleClass = ??? + def EmptyPackage = ??? + def EmptyPackageClass = ??? + def FloatClass = ??? def FunctionClass: Array[Symbol] = Array() - def IntClass: Symbol = DummySymbol - def IterableClass: Symbol = DummySymbol - def IteratorClass: Symbol = DummySymbol - def IteratorModule: Symbol = DummySymbol - def Iterator_apply: Symbol = DummySymbol - def JavaLangPackage: Symbol = DummySymbol - def JavaLangPackageClass: Symbol = DummySymbol - def JavaRepeatedParamClass: Symbol = DummySymbol - def ListClass: Symbol = DummySymbol - def ListModule: Symbol = DummySymbol - def List_apply: Symbol = DummySymbol - def LongClass: Symbol = DummySymbol - def NilModule: Symbol = DummySymbol - def NoneModule: Symbol = DummySymbol - def NothingClass: Symbol = DummySymbol - def NullClass: Symbol = DummySymbol - def ObjectClass: Symbol = DummySymbol - def OptionClass: Symbol = DummySymbol - def PredefModule: Symbol = DummySymbol + def IntClass = ??? + def IterableClass = ??? + def IteratorClass = ??? + def IteratorModule = ??? + def Iterator_apply = ??? + def JavaLangPackage = ??? + def JavaLangPackageClass = ??? + def ListClass = ??? + def ListModule = ??? + def List_apply = ??? + def LongClass = ??? + def NilModule = ??? + def NoneModule = ??? + def NothingClass = ??? + def NullClass = ??? + def ObjectClass = ??? + def OptionClass = ??? + def PredefModule = ??? def ProductClass: Array[Symbol] = Array() - def RepeatedParamClass: Symbol = DummySymbol - def RootClass: Symbol = DummySymbol - def RootPackage: Symbol = DummySymbol - def ScalaPackage: Symbol = DummySymbol - def ScalaPackageClass: Symbol = DummySymbol - def ScalaPrimitiveValueClasses: List[Symbol] = List() - def SeqClass: Symbol = DummySymbol - def SeqModule: Symbol = DummySymbol - def ShortClass: Symbol = DummySymbol - def SomeClass: Symbol = DummySymbol - def SomeModule: Symbol = DummySymbol - def StringBuilderClass: Symbol = DummySymbol - def StringClass: Symbol = DummySymbol - def SymbolClass: Symbol = DummySymbol - def TraversableClass: Symbol = DummySymbol + def RootClass = ??? + def RootPackage = ??? + def ScalaPackage = ??? + def ScalaPackageClass = ??? + def ScalaPrimitiveValueClasses = Nil + def SeqClass = ??? + def SeqModule = ??? + def ShortClass = ??? + def SomeClass = ??? + def SomeModule = ??? + def StringBuilderClass = ??? + def StringClass = ??? + def SymbolClass = ??? + def TraversableClass = ??? def TupleClass: Array[Symbol] = Array() - def TypeTagClass: Symbol = DummySymbol - def TypeTagModule: Symbol = DummySymbol - def UnitClass: Symbol = DummySymbol + def TypeTagClass = ??? + def TypeTagModule = ??? + def UnitClass = ??? def isNumericValueClass(sym: Symbol): Boolean = notSupported() def isPrimitiveValueClass(sym: Symbol): Boolean = notSupported() def vmClassType(arg: Type): Type = DummyType @@ -382,10 +382,6 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { def setterToGetter(name: TermName): TermName = notSupported() def defaultGetterName(name: Name, pos: Int): TermName = notSupported() def defaultGetterToMethod(name: Name): TermName = notSupported() - def dropSingletonName(name: Name): TypeName = notSupported() - def singletonName(name: Name): TypeName = notSupported() - def implClassName(name: Name): TypeName = notSupported() - def interfaceName(implname: Name): TypeName = notSupported() def localDummyName(clazz: Symbol): TermName = notSupported() def superName(name: Name): TermName = notSupported() } @@ -411,11 +407,16 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { val LOCAL_CHILD: TypeName = DummyName val REPEATED_PARAM_CLASS_NAME: TypeName = DummyName val WILDCARD_STAR: TypeName = DummyName + + def dropSingletonName(name: Name): TypeName = notSupported() + def singletonName(name: Name): TypeName = notSupported() + def implClassName(name: Name): TypeName = notSupported() + def interfaceName(implname: Name): TypeName = notSupported() } // Members declared in scala.reflect.api.Symbols type Symbol = DummySymbol.type - val NoSymbol: Symbol = DummySymbol + val NoSymbol = ??? object DummySymbol extends AbsSymbol { this: Symbol => @@ -477,19 +478,19 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { // type TreeGen = DummyTreeGen.type // [Eugene] cannot compile if uncomment this val gen: TreeGen{val global: DummyMirror.this.type} = DummyTreeGen.asInstanceOf[TreeGen{val global: DummyMirror.this.type}] def modifiersFromInternalFlags(flags: Long,privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers - def newFreeExistential(name: String,info: Type,value: => Any,flags: Long,origin: String): Symbol = DummySymbol - def newFreeTerm(name: String,info: Type,value: => Any,flags: Long,origin: String): Symbol = DummySymbol - def newFreeType(name: String,info: Type,value: => Any,flags: Long,origin: String): Symbol = DummySymbol - def selectOverloadedMethod(owner: Symbol,name: String,index: Int): Symbol = DummySymbol - def selectOverloadedMethodIfDefined(owner: Symbol,name: String,index: Int): Symbol = DummySymbol - def selectTerm(owner: Symbol,name: String): Symbol = DummySymbol - def selectTermIfDefined(owner: Symbol,name: String): Symbol = DummySymbol - def selectType(owner: Symbol,name: String): Symbol = DummySymbol - def selectTypeIfDefined(owner: Symbol,name: String): Symbol = DummySymbol - def staticClass(fullName: String): Symbol = DummySymbol - def staticClassIfDefined(fullName: String): Symbol = DummySymbol - def staticModule(fullName: String): Symbol = DummySymbol - def staticModuleIfDefined(fullName: String): Symbol = DummySymbol + def newFreeExistential(name: String,info: Type,value: => Any,flags: Long,origin: String) = ??? + def newFreeTerm(name: String,info: Type,value: => Any,flags: Long,origin: String) = ??? + def newFreeType(name: String,info: Type,value: => Any,flags: Long,origin: String) = ??? + def selectOverloadedMethod(owner: Symbol,name: String,index: Int) = ??? + def selectOverloadedMethodIfDefined(owner: Symbol,name: String,index: Int) = ??? + def selectTerm(owner: Symbol,name: String) = ??? + def selectTermIfDefined(owner: Symbol,name: String) = ??? + def selectType(owner: Symbol,name: String) = ??? + def selectTypeIfDefined(owner: Symbol,name: String) = ??? + def staticClass(fullName: String) = ??? + def staticClassIfDefined(fullName: String) = ??? + def staticModule(fullName: String) = ??? + def staticModuleIfDefined(fullName: String) = ??? def thisModuleType(fullName: String): Type = DummyType object DummyTreeGen extends AbsTreeGen { val global: Universe = DummyMirror.this diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala index a7237223f1..e8d4571228 100644 --- a/src/library/scala/reflect/TagMaterialization.scala +++ b/src/library/scala/reflect/TagMaterialization.scala @@ -9,6 +9,10 @@ import language.implicitConversions // 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. */ + + /** !!! Some of this code is copy-pasted four places. This situation + * should be resolved ASAP. + */ object TagMaterialization { def materializeClassTag[T: c.TypeTag](c: Context): c.Expr[ClassTag[T]] = { import c.mirror._ diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala index e457bb73e0..21f7c9283b 100755 --- a/src/library/scala/reflect/api/StandardDefinitions.scala +++ b/src/library/scala/reflect/api/StandardDefinitions.scala @@ -6,7 +6,8 @@ package scala.reflect package api -trait StandardDefinitions { self: Universe => +trait StandardTypes { + self: Universe => val ByteTpe: Type val ShortTpe: Type @@ -17,110 +18,119 @@ trait StandardDefinitions { self: Universe => val DoubleTpe: Type val BooleanTpe: Type val UnitTpe: Type + val AnyTpe: Type - val ObjectTpe: Type val AnyValTpe: Type val AnyRefTpe: Type + val ObjectTpe: Type + val NothingTpe: Type val NullTpe: Type val StringTpe: Type +} + +trait StandardDefinitions extends StandardTypes { + self: Universe => val definitions: AbsDefinitions - abstract class AbsDefinitions { - // packages - def RootPackage: Symbol - def RootClass: Symbol - def EmptyPackage: Symbol + // I intend to pull everything in here out of the public API. + trait AbsDefinitionsInternal { + def ArrayModule: Symbol + def ArrayModule_overloadedApply: Symbol + def Array_apply: Symbol + def Array_clone: Symbol + def Array_length: Symbol + def Array_update: Symbol + def ByNameParamClass: Symbol + def ClassTagModule: Symbol + def ConcreteTypeTagModule: Symbol + def ConsClass: Symbol def EmptyPackageClass: Symbol - def ScalaPackage: Symbol - def ScalaPackageClass: Symbol - def JavaLangPackage: Symbol + def FunctionClass : Array[Symbol] + def IterableClass: Symbol + def IteratorClass: Symbol + def IteratorModule: Symbol + def Iterator_apply: Symbol def JavaLangPackageClass: Symbol + def JavaRepeatedParamClass: Symbol + def ListModule: Symbol + def List_apply: Symbol + def NilModule: Symbol + def NoneModule: Symbol + def OptionClass: Symbol + def ProductClass : Array[Symbol] + def RepeatedParamClass: Symbol + def ScalaPackageClass: Symbol + def SeqClass: Symbol + def SeqModule: Symbol + def SomeClass: Symbol + def SomeModule: Symbol + def StringBuilderClass: Symbol + def SymbolClass : Symbol + def TraversableClass: Symbol + def TupleClass : Array[Symbol] + def TypeTagModule: Symbol + def ScalaPrimitiveValueClasses: List[ClassSymbol] + } + + trait AbsDefinitions extends AbsDefinitionsInternal { + // packages + def RootClass: ClassSymbol + def RootPackage: PackageSymbol + def EmptyPackage: PackageSymbol + def ScalaPackage: PackageSymbol + def JavaLangPackage: PackageSymbol // top types - def AnyClass : Symbol - def AnyValClass: Symbol - def AnyRefClass: Symbol - def ObjectClass: Symbol + def AnyClass : ClassSymbol + def AnyValClass: ClassSymbol + def ObjectClass: ClassSymbol + def AnyRefClass: TypeSymbol // bottom types - def NullClass : Symbol - def NothingClass: Symbol + def NullClass : ClassSymbol + def NothingClass: ClassSymbol // the scala value classes - def UnitClass : Symbol - def ByteClass : Symbol - def ShortClass : Symbol - def CharClass : Symbol - def IntClass : Symbol - def LongClass : Symbol - def FloatClass : Symbol - def DoubleClass : Symbol - def BooleanClass: Symbol - def ScalaPrimitiveValueClasses: List[Symbol] - - // fundamental reference classes - def SymbolClass : Symbol - def StringClass : Symbol - def ClassClass : Symbol - - // product, tuple, function - def TupleClass : Array[Symbol] - def ProductClass : Array[Symbol] - def FunctionClass : Array[Symbol] - - // Option classes - def OptionClass: Symbol - def SomeClass: Symbol - def NoneModule: Symbol - def SomeModule: Symbol + def UnitClass : ClassSymbol + def ByteClass : ClassSymbol + def ShortClass : ClassSymbol + def CharClass : ClassSymbol + def IntClass : ClassSymbol + def LongClass : ClassSymbol + def FloatClass : ClassSymbol + def DoubleClass : ClassSymbol + def BooleanClass: ClassSymbol + + // some special classes + def StringClass : ClassSymbol + def ClassClass : ClassSymbol + def ArrayClass: ClassSymbol // collections classes - def ConsClass: Symbol - def IterableClass: Symbol - def IteratorClass: Symbol - def ListClass: Symbol - def SeqClass: Symbol - def StringBuilderClass: Symbol - def TraversableClass: Symbol + def ListClass: ClassSymbol + def ListModule: ModuleSymbol // 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 + def PredefModule: ModuleSymbol // type tags - def ClassTagClass: Symbol - def ClassTagModule: Symbol - def TypeTagClass: Symbol - def TypeTagModule: Symbol - def ConcreteTypeTagClass: Symbol - def ConcreteTypeTagModule: Symbol + def ClassTagClass: ClassSymbol + def TypeTagClass: ClassSymbol + def ConcreteTypeTagClass: ClassSymbol /** 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? + // [Eugene] we already have arg.erasure, right? + // + // [Paul] You misunderstand the method (it could be better named). + // Given List[String], it returns java.lang.Class[List[String]] + // (or the .Net equivalent), not the erasure of List[String]. + // See def ClassType in definitions - that's what it was called before, + // and obviously that name has to go. /** 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 d39d44dd86..60c64f947a 100644 --- a/src/library/scala/reflect/api/StandardNames.scala +++ b/src/library/scala/reflect/api/StandardNames.scala @@ -1,49 +1,64 @@ /* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ +* Copyright 2005-2011 LAMP/EPFL +* @author Martin Odersky +*/ package scala.reflect package api -trait StandardNames { self: Universe => +trait StandardNames { + self: Universe => - abstract class AbsNames { + val nme: AbsTermNames + val tpnme: AbsTypeNames + + trait AbsNames { type NameType <: Name - val EMPTY: NameType - val ANON_FUN_NAME: NameType val ANON_CLASS_NAME: NameType + val ANON_FUN_NAME: NameType + val EMPTY: NameType val EMPTY_PACKAGE_NAME: NameType + val ERROR: NameType val IMPORT: NameType val MODULE_VAR_SUFFIX: NameType - val ROOT: NameType + val NO_NAME: NameType val PACKAGE: NameType + val ROOT: 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 extends AbsNames { + trait AbsTermNames extends AbsNames { val EXPAND_SEPARATOR_STRING: String + val IMPL_CLASS_SUFFIX: String + val INTERPRETER_IMPORT_WRAPPER: String + val INTERPRETER_LINE_PREFIX: String + val INTERPRETER_VAR_PREFIX: String + val INTERPRETER_WRAPPER_SUFFIX: String + val LOCALDUMMY_PREFIX: String + val LOCAL_SUFFIX_STRING: String + val MODULE_SUFFIX_NAME: TermName + val NAME_JOIN_NAME: TermName + val PROTECTED_PREFIX: String + val PROTECTED_SET_PREFIX: String + val SETTER_SUFFIX: TermName + val SINGLETON_SUFFIX: String + val SUPER_PREFIX_STRING: String + val TRAIT_SETTER_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 MIRROR_PREFIX: TermName + val MIRROR_SHORT: TermName val MIRROR_SYMDEF_PREFIX: TermName val MIXIN_CONSTRUCTOR: TermName val MODULE_INSTANCE_FIELD: TermName @@ -62,11 +77,6 @@ trait StandardNames { self: Universe => 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 @@ -93,77 +103,62 @@ trait StandardNames { self: Universe => 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_~ : TermName + val UNARY_+ : TermName + val UNARY_- : TermName + val UNARY_! : TermName - // [Eugene] this doesn't compile. why?! val ??? : 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 isModuleName(name: Name): Boolean + def isOpAssignmentName(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 isSuperAccessorName(name: Name): Boolean + def isTraitSetterName(name: Name): Boolean - def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName + def defaultGetterName(name: Name, pos: Int): TermName + def defaultGetterToMethod(name: Name): TermName + def expandedName(name: TermName, base: Symbol, 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 localDummyName(clazz: Symbol): TermName def localToGetter(name: TermName): TermName + def protName(name: Name): TermName + def protSetterName(name: Name): 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 + def dropLocalSuffix(name: Name): Name + def originalName(name: Name): Name + def stripModuleSuffix(name: Name): Name + def unspecializedName(name: Name): Name + def segments(name: String, assumeTerm: Boolean): List[Name] + def splitSpecializedName(name: Name): (Name, String, String) + } - abstract class AbsTypeNames extends AbsNames { - val REFINE_CLASS_NAME: TypeName + trait AbsTypeNames extends AbsNames { val BYNAME_PARAM_CLASS_NAME: TypeName val EQUALS_PATTERN_NAME: TypeName val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName val LOCAL_CHILD: TypeName + val REFINE_CLASS_NAME: TypeName val REPEATED_PARAM_CLASS_NAME: TypeName val WILDCARD_STAR: TypeName + + def dropSingletonName(name: Name): TypeName + def implClassName(name: Name): TypeName + def interfaceName(implname: Name): TypeName + def singletonName(name: Name): TypeName } } diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index d9293888d9..767246a294 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -4,8 +4,101 @@ package api trait Symbols { self: Universe => type Symbol >: Null <: AbsSymbol + type TypeSymbol <: Symbol with TypeSymbolApi + type TermSymbol <: Symbol with TermSymbolApi + type MethodSymbol <: TermSymbol with MethodSymbolApi + type ModuleSymbol <: TermSymbol with ModuleSymbolApi + type PackageSymbol <: ModuleSymbol with PackageSymbolApi + type ClassSymbol <: TypeSymbol with ClassSymbolApi - abstract class AbsSymbol { this: Symbol => + val NoSymbol: Symbol + + trait TypeSymbolApi { + self: TypeSymbol => + + def name: TypeName + } + trait TermSymbolApi { + self: TermSymbol => + + def name: TermName + } + trait MethodSymbolApi extends TermSymbolApi { + self: MethodSymbol => + } + trait ClassSymbolApi extends TypeSymbolApi { + self: ClassSymbol => + } + trait ModuleSymbolApi extends TermSymbolApi { + self: ModuleSymbol => + } + trait PackageSymbolApi extends ModuleSymbolApi { + self: PackageSymbol => + } + + // I intend to pull everything in here out of the public API. + trait AbsSymbolInternal { + this: Symbol => + + /** 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 !!! not enough reason to have in the api + + /** Low-level operation to set the symbol's flags + * @return the symbol itself + */ + def setInternalFlags(flags: Long): this.type + // needed by LiftCode !!! not enough reason to have in the api + + /** Set symbol's type signature to given type + * @return the symbol itself + */ + def setTypeSignature(tpe: Type): this.type + // needed by LiftCode !!! not enough reason to have in the api + + /** 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 + + /** 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 isSkolem : Boolean + + /** Does this symbol represent a free type captured by reification? + */ + // needed for ones who wish to inspect reified trees + def isFreeType : Boolean + + /** The type signature of this symbol. + * Note if the symbol is a member of a class, one almost always is interested + * in `typeSignatureIn` with a site type instead. + */ + def typeSignature: Type // !!! Since one should almost never use this, let's give it a different name. + + /** A type reference that refers to this type symbol + * Note if symbol is a member of a class, one almost always is interested + * in `asTypeIn` with a site type instead. + * + * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol + * `C`. Then `C.asType` is the type `C[T]`. + * + * By contrast, `C.typeSignature` would be a type signature of form + * `PolyType(ClassInfoType(...))` that describes type parameters, value + * parameters, parent types, and members of `C`. + */ + def asType: Type // !!! Same as typeSignature. + + /** The kind of this symbol; used for debugging */ + def kind: String + } + + trait AbsSymbol extends AbsSymbolInternal { + this: Symbol => /** The position of this symbol */ @@ -177,22 +270,11 @@ trait Symbols { self: Universe => */ def isAbstractType : Boolean - /** 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 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 - def isFreeType : Boolean - /** Is the type parameter represented by this symbol contravariant? */ def isContravariant : Boolean @@ -205,29 +287,10 @@ trait Symbols { self: Universe => */ def isErroneous : Boolean - /** The type signature of this symbol. - * Note if the symbol is a member of a class, one almost always is interested - * in `typeSignatureIn` with a site type instead. - */ - def typeSignature: Type // !!! Since one should almost never use this, let's give it a different name. - /** The type signature of this symbol seen as a member of given type `site`. */ def typeSignatureIn(site: Type): Type - /** A type reference that refers to this type symbol - * Note if symbol is a member of a class, one almost always is interested - * in `asTypeIn` with a site type instead. - * - * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol - * `C`. Then `C.asType` is the type `C[T]`. - * - * By contrast, `C.typeSignature` would be a type signature of form - * `PolyType(ClassInfoType(...))` that describes type parameters, value - * parameters, parent types, and members of `C`. - */ - def asType: Type // !!! Same as typeSignature. - /** A type reference that refers to this type symbol seen * as a member of given type `site`. */ @@ -255,29 +318,5 @@ trait Symbols { self: Universe => def alternatives: List[Symbol] def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol - - /** 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 !!! not enough reason to have in the api - - /** Low-level operation to set the symbol's flags - * @return the symbol itself - */ - def setInternalFlags(flags: Long): this.type // needed by LiftCode !!! not enough reason to have in the api - - /** Set symbol's type signature to given type - * @return the symbol itself - */ - def setTypeSignature(tpe: Type): this.type // needed by LiftCode !!! not enough reason to have in the api - - /** 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 } -- cgit v1.2.3 From e59cadeb9dffa7f221d9f4d2f95466f07e867d50 Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Mon, 23 Apr 2012 01:11:05 +0900 Subject: Scaladoc's tests should work with test/partest Fix SI-5083. --- src/partest/scala/tools/partest/nest/ConsoleRunner.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala index 85060ad633..fb3cab52c4 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala @@ -213,7 +213,12 @@ class ConsoleRunner extends DirectRunner { * @return (success count, failure count) */ def testCheckAll(enabledSets: List[TestSet]): (Int, Int) = { - def kindOf(f: File) = (srcDir relativize Path(f).toCanonical).segments.head + def kindOf(f: File) = { + (srcDir relativize Path(f).toCanonical).segments match { + case (".." :: "scaladoc" :: xs) => xs.head + case xs => xs.head + } + } val (valid, invalid) = testFiles partition (x => testSetKinds contains kindOf(x)) invalid foreach (x => NestUI.failure( -- cgit v1.2.3 From c3b0113f31ca80e08fd609f8b7925dc456456b95 Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Mon, 23 Apr 2012 02:21:32 +0900 Subject: Fix a documentation comment of Product(n)#productElement Fix SI-5168. --- src/build/genprod.scala | 2 +- src/library/scala/Product1.scala | 2 +- src/library/scala/Product10.scala | 2 +- src/library/scala/Product11.scala | 2 +- src/library/scala/Product12.scala | 2 +- src/library/scala/Product13.scala | 2 +- src/library/scala/Product14.scala | 2 +- src/library/scala/Product15.scala | 2 +- src/library/scala/Product16.scala | 2 +- src/library/scala/Product17.scala | 2 +- src/library/scala/Product18.scala | 2 +- src/library/scala/Product19.scala | 2 +- src/library/scala/Product2.scala | 2 +- src/library/scala/Product20.scala | 2 +- src/library/scala/Product21.scala | 2 +- src/library/scala/Product22.scala | 2 +- src/library/scala/Product3.scala | 2 +- src/library/scala/Product4.scala | 2 +- src/library/scala/Product5.scala | 2 +- src/library/scala/Product6.scala | 2 +- src/library/scala/Product7.scala | 2 +- src/library/scala/Product8.scala | 2 +- src/library/scala/Product9.scala | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/build/genprod.scala b/src/build/genprod.scala index 6016f6fb92..1ea0bf7b73 100644 --- a/src/build/genprod.scala +++ b/src/build/genprod.scala @@ -578,7 +578,7 @@ class Product(val i: Int) extends Group("Product") with Arity { * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ """ diff --git a/src/library/scala/Product1.scala b/src/library/scala/Product1.scala index d268b35f60..edd095c5c6 100644 --- a/src/library/scala/Product1.scala +++ b/src/library/scala/Product1.scala @@ -28,7 +28,7 @@ trait Product1[@specialized(Int, Long, Double) +T1] extends Any with Product { * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product10.scala b/src/library/scala/Product10.scala index cae9e5a664..8daefde699 100644 --- a/src/library/scala/Product10.scala +++ b/src/library/scala/Product10.scala @@ -28,7 +28,7 @@ trait Product10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Any w * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product11.scala b/src/library/scala/Product11.scala index 0647b28414..90b4e8013e 100644 --- a/src/library/scala/Product11.scala +++ b/src/library/scala/Product11.scala @@ -28,7 +28,7 @@ trait Product11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product12.scala b/src/library/scala/Product12.scala index a080aafa7a..d5997ea05a 100644 --- a/src/library/scala/Product12.scala +++ b/src/library/scala/Product12.scala @@ -28,7 +28,7 @@ trait Product12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] e * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product13.scala b/src/library/scala/Product13.scala index 425aebf3e7..db8e0f3722 100644 --- a/src/library/scala/Product13.scala +++ b/src/library/scala/Product13.scala @@ -28,7 +28,7 @@ trait Product13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product14.scala b/src/library/scala/Product14.scala index 3d7e4896ef..113c07e8c4 100644 --- a/src/library/scala/Product14.scala +++ b/src/library/scala/Product14.scala @@ -28,7 +28,7 @@ trait Product14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product15.scala b/src/library/scala/Product15.scala index 7bca7a2a1b..a6ad9c7594 100644 --- a/src/library/scala/Product15.scala +++ b/src/library/scala/Product15.scala @@ -28,7 +28,7 @@ trait Product15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product16.scala b/src/library/scala/Product16.scala index c5042cbc90..cbf47ece94 100644 --- a/src/library/scala/Product16.scala +++ b/src/library/scala/Product16.scala @@ -28,7 +28,7 @@ trait Product16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product17.scala b/src/library/scala/Product17.scala index b5651ec712..f56836bfd8 100644 --- a/src/library/scala/Product17.scala +++ b/src/library/scala/Product17.scala @@ -28,7 +28,7 @@ trait Product17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product18.scala b/src/library/scala/Product18.scala index 088a48ae32..5b86bcff65 100644 --- a/src/library/scala/Product18.scala +++ b/src/library/scala/Product18.scala @@ -28,7 +28,7 @@ trait Product18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product19.scala b/src/library/scala/Product19.scala index 4f4a98c6a0..ed4bf36c93 100644 --- a/src/library/scala/Product19.scala +++ b/src/library/scala/Product19.scala @@ -28,7 +28,7 @@ trait Product19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product2.scala b/src/library/scala/Product2.scala index eb67e5d46e..e27e54eff9 100644 --- a/src/library/scala/Product2.scala +++ b/src/library/scala/Product2.scala @@ -28,7 +28,7 @@ trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Doub * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product20.scala b/src/library/scala/Product20.scala index 80f63f1bb4..47437a20af 100644 --- a/src/library/scala/Product20.scala +++ b/src/library/scala/Product20.scala @@ -28,7 +28,7 @@ trait Product20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product21.scala b/src/library/scala/Product21.scala index 7056844271..319d2725c0 100644 --- a/src/library/scala/Product21.scala +++ b/src/library/scala/Product21.scala @@ -28,7 +28,7 @@ trait Product21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product22.scala b/src/library/scala/Product22.scala index 05e95f92dd..6ab3737acd 100644 --- a/src/library/scala/Product22.scala +++ b/src/library/scala/Product22.scala @@ -28,7 +28,7 @@ trait Product22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, + * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product3.scala b/src/library/scala/Product3.scala index 91556bb962..1cfbd7956b 100644 --- a/src/library/scala/Product3.scala +++ b/src/library/scala/Product3.scala @@ -28,7 +28,7 @@ trait Product3[+T1, +T2, +T3] extends Any with Product { * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product4.scala b/src/library/scala/Product4.scala index 1f9070c155..843571fd60 100644 --- a/src/library/scala/Product4.scala +++ b/src/library/scala/Product4.scala @@ -28,7 +28,7 @@ trait Product4[+T1, +T2, +T3, +T4] extends Any with Product { * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product5.scala b/src/library/scala/Product5.scala index 52dd284f55..df73bba3dd 100644 --- a/src/library/scala/Product5.scala +++ b/src/library/scala/Product5.scala @@ -28,7 +28,7 @@ trait Product5[+T1, +T2, +T3, +T4, +T5] extends Any with Product { * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product6.scala b/src/library/scala/Product6.scala index 9624bdbe3e..36906ca54e 100644 --- a/src/library/scala/Product6.scala +++ b/src/library/scala/Product6.scala @@ -28,7 +28,7 @@ trait Product6[+T1, +T2, +T3, +T4, +T5, +T6] extends Any with Product { * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product7.scala b/src/library/scala/Product7.scala index 36d4b149db..e7b2c13ad1 100644 --- a/src/library/scala/Product7.scala +++ b/src/library/scala/Product7.scala @@ -28,7 +28,7 @@ trait Product7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Any with Product { * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product8.scala b/src/library/scala/Product8.scala index 28c78f9c89..916e57ec39 100644 --- a/src/library/scala/Product8.scala +++ b/src/library/scala/Product8.scala @@ -28,7 +28,7 @@ trait Product8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Any with Product * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ diff --git a/src/library/scala/Product9.scala b/src/library/scala/Product9.scala index d69c550abe..d5e72edc0b 100644 --- a/src/library/scala/Product9.scala +++ b/src/library/scala/Product9.scala @@ -28,7 +28,7 @@ trait Product9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Any with Pro * otherwise throws an `IndexOutOfBoundsException`. * * @param n number of the projection to be returned - * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`. + * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`. * @throws IndexOutOfBoundsException */ -- cgit v1.2.3 From 3ddd3486095c3d6a87f723e0ff8187d1b08f5507 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 23 Apr 2012 00:36:12 +0200 Subject: minor fixes to reification --- src/compiler/scala/reflect/reify/phases/Calculate.scala | 1 + test/files/run/t5271_1.check | 1 + test/files/run/t5271_1.scala | 1 + test/files/run/t5271_2.check | 2 ++ test/files/run/t5271_2.scala | 1 + test/files/run/t5271_3.check | 2 ++ test/files/run/t5271_3.scala | 1 + test/pending/run/t5258a.scala | 2 ++ test/pending/run/t5258b.scala | 2 ++ test/pending/run/t5258c.scala | 2 ++ test/pending/run/t5271_1.check | 0 test/pending/run/t5271_1.scala | 7 ------- test/pending/run/t5271_2.check | 1 - test/pending/run/t5271_2.scala | 9 --------- test/pending/run/t5271_3.check | 1 - test/pending/run/t5271_3.scala | 10 ---------- 16 files changed, 15 insertions(+), 28 deletions(-) delete mode 100644 test/pending/run/t5271_1.check delete mode 100644 test/pending/run/t5271_1.scala delete mode 100644 test/pending/run/t5271_2.check delete mode 100644 test/pending/run/t5271_2.scala delete mode 100644 test/pending/run/t5271_3.check delete mode 100644 test/pending/run/t5271_3.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/reify/phases/Calculate.scala b/src/compiler/scala/reflect/reify/phases/Calculate.scala index e4f3fce407..93ef46472e 100644 --- a/src/compiler/scala/reflect/reify/phases/Calculate.scala +++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala @@ -46,6 +46,7 @@ trait Calculate { bindRelatedSymbol(tree.symbol.companionClass, "companionClass") bindRelatedSymbol(tree.symbol.companionModule, "companionModule") Some(tree.symbol) collect { case termSymbol: TermSymbol => bindRelatedSymbol(termSymbol.referenced, "referenced") } + Some(tree) collect { case labelDef: LabelDef => labelDef.params foreach (param => bindRelatedSymbol(param.symbol, "labelParam")) } def bindRelatedSymbol(related: Symbol, name: String): Unit = if (related != null && related != NoSymbol) { if (reifyDebug) println("boundSym (" + name + "): " + related) diff --git a/test/files/run/t5271_1.check b/test/files/run/t5271_1.check index 7a728e5164..5245173228 100644 --- a/test/files/run/t5271_1.check +++ b/test/files/run/t5271_1.check @@ -9,3 +9,4 @@ }; () } +() diff --git a/test/files/run/t5271_1.scala b/test/files/run/t5271_1.scala index 5baa57c290..20cafa6a08 100644 --- a/test/files/run/t5271_1.scala +++ b/test/files/run/t5271_1.scala @@ -7,4 +7,5 @@ object Test extends App { val toolbox = mkToolBox() println(code.tree) + println(code.eval) } diff --git a/test/files/run/t5271_2.check b/test/files/run/t5271_2.check index d8d6edeffc..0765b3a6a4 100644 --- a/test/files/run/t5271_2.check +++ b/test/files/run/t5271_2.check @@ -10,3 +10,5 @@ val c = C.apply(2, 2); scala.this.Predef.println(c.foo.$times(c.bar)) } +4 +() diff --git a/test/files/run/t5271_2.scala b/test/files/run/t5271_2.scala index 9820ebe692..af6491407c 100644 --- a/test/files/run/t5271_2.scala +++ b/test/files/run/t5271_2.scala @@ -9,4 +9,5 @@ object Test extends App { val toolbox = mkToolBox() println(code.tree) + println(code.eval) } diff --git a/test/files/run/t5271_3.check b/test/files/run/t5271_3.check index 1d4f47c5df..2b920a36a8 100644 --- a/test/files/run/t5271_3.check +++ b/test/files/run/t5271_3.check @@ -17,3 +17,5 @@ val c = C.apply(2, 2); scala.this.Predef.println(c.foo.$times(c.bar).$eq$eq(C.qwe)) } +true +() diff --git a/test/files/run/t5271_3.scala b/test/files/run/t5271_3.scala index 5fd94f4a2b..646b10a8e5 100644 --- a/test/files/run/t5271_3.scala +++ b/test/files/run/t5271_3.scala @@ -10,4 +10,5 @@ object Test extends App { val toolbox = mkToolBox() println(code.tree) + println(code.eval) } diff --git a/test/pending/run/t5258a.scala b/test/pending/run/t5258a.scala index 755d135468..127829c724 100644 --- a/test/pending/run/t5258a.scala +++ b/test/pending/run/t5258a.scala @@ -1,3 +1,5 @@ +import scala.reflect.mirror._ + object Test extends App { reify { println(classOf[Int]) diff --git a/test/pending/run/t5258b.scala b/test/pending/run/t5258b.scala index 8ad1ff114e..82555cde96 100644 --- a/test/pending/run/t5258b.scala +++ b/test/pending/run/t5258b.scala @@ -1,3 +1,5 @@ +import scala.reflect.mirror._ + object Test extends App { reify { class C diff --git a/test/pending/run/t5258c.scala b/test/pending/run/t5258c.scala index 1f76391162..a0a1647486 100644 --- a/test/pending/run/t5258c.scala +++ b/test/pending/run/t5258c.scala @@ -1,3 +1,5 @@ +import scala.reflect.mirror._ + object Test extends App { reify { object E extends Enumeration { val foo, bar = Value } diff --git a/test/pending/run/t5271_1.check b/test/pending/run/t5271_1.check deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/pending/run/t5271_1.scala b/test/pending/run/t5271_1.scala deleted file mode 100644 index fae64350e3..0000000000 --- a/test/pending/run/t5271_1.scala +++ /dev/null @@ -1,7 +0,0 @@ -import scala.reflect.mirror._ - -object Test extends App { - reify { - case class C(foo: Int, bar: Int) - }.eval -} diff --git a/test/pending/run/t5271_2.check b/test/pending/run/t5271_2.check deleted file mode 100644 index b8626c4cff..0000000000 --- a/test/pending/run/t5271_2.check +++ /dev/null @@ -1 +0,0 @@ -4 diff --git a/test/pending/run/t5271_2.scala b/test/pending/run/t5271_2.scala deleted file mode 100644 index d25e1fe804..0000000000 --- a/test/pending/run/t5271_2.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.mirror._ - -object Test extends App { - reify { - case class C(foo: Int, bar: Int) - val c = C(2, 2) - println(c.foo * c.bar) - }.eval -} diff --git a/test/pending/run/t5271_3.check b/test/pending/run/t5271_3.check deleted file mode 100644 index f32a5804e2..0000000000 --- a/test/pending/run/t5271_3.check +++ /dev/null @@ -1 +0,0 @@ -true \ No newline at end of file diff --git a/test/pending/run/t5271_3.scala b/test/pending/run/t5271_3.scala deleted file mode 100644 index 65a03ae323..0000000000 --- a/test/pending/run/t5271_3.scala +++ /dev/null @@ -1,10 +0,0 @@ -import scala.reflect.mirror._ - -object Test extends App { - 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) - }.eval -} -- cgit v1.2.3 From 72052b6070cf602b3b84f1ec41df332860e93c3c Mon Sep 17 00:00:00 2001 From: Vojin Jovanovic Date: Mon, 23 Apr 2012 13:15:13 +0200 Subject: Fix for SI-5471 --- src/library/scala/math/Numeric.scala | 4 ++-- test/files/jvm/si5471.check | 2 ++ test/files/jvm/si5471.scala | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 test/files/jvm/si5471.check create mode 100644 test/files/jvm/si5471.scala (limited to 'src') diff --git a/src/library/scala/math/Numeric.scala b/src/library/scala/math/Numeric.scala index 1f4e3c9865..ee62706e49 100644 --- a/src/library/scala/math/Numeric.scala +++ b/src/library/scala/math/Numeric.scala @@ -36,8 +36,8 @@ object Numeric { def fromInt(x: Int): BigInt = BigInt(x) def toInt(x: BigInt): Int = x.intValue def toLong(x: BigInt): Long = x.longValue - def toFloat(x: BigInt): Float = x.longValue.toFloat - def toDouble(x: BigInt): Double = x.longValue.toDouble + def toFloat(x: BigInt): Float = x.floatValue + def toDouble(x: BigInt): Double = x.doubleValue } implicit object BigIntIsIntegral extends BigIntIsIntegral with Ordering.BigIntOrdering diff --git a/test/files/jvm/si5471.check b/test/files/jvm/si5471.check new file mode 100644 index 0000000000..bb101b641b --- /dev/null +++ b/test/files/jvm/si5471.check @@ -0,0 +1,2 @@ +true +true diff --git a/test/files/jvm/si5471.scala b/test/files/jvm/si5471.scala new file mode 100644 index 0000000000..2c8c4205c5 --- /dev/null +++ b/test/files/jvm/si5471.scala @@ -0,0 +1,17 @@ + +object Test { + + def main(args: Array[String]) { + import scala.math.Numeric + import scala.math.Numeric.Implicits._ + + val b = BigInt(Long.MaxValue) + 1 + + def dbl[N :Numeric](n: N) = n.toDouble + def flt[N :Numeric](n: N) = n.toFloat + + println(dbl(b) == b.toDouble) + println(flt(b) == b.toFloat) + } + +} -- cgit v1.2.3 From b47189ad06e027c310d93b071fc8bf15d979225d Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 23 Apr 2012 06:12:57 -0700 Subject: Fix for range positions. You are a fireman, leading a team of firemen on a rescue in a burning building. When you have cleared a room, you place a sticker on the door which says "Room cleared!" If the other firemen see that sticker, they will skip that room, knowing there are no small children or adorable puppies behind it. As the lead fireman, here is what you should not do: run from door to door slapping "Room cleared!" stickers on them all, so the other firemen shrug and go home. Translation: when recursion depends on a condition, if you alter the condition before you recurse, you may not recurse at all. --- src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 88cea2231f..838c7f8abd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -1020,7 +1020,12 @@ class Foo(x: Other) { x._1 } // no error in this order override def traverse(t: Tree) { if (t != EmptyTree && t.pos == NoPosition) { - t.setPos(pos) + t setPos pos + // During a recursive descent traversal which prunes when it sees + // a position, one can't assign the position and THEN recurse. + // Ensuring that all children have compliant range positions. + for (t1 <- t ; if t1 ne t) + t1 setPos pos.makeTransparent } t match { case Function(_, _) if t.symbol == NoSymbol => -- cgit v1.2.3 From 34f0d4f91b41a5d20078cba2492c2170e995e24c Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 23 Apr 2012 17:17:18 +0200 Subject: poor dummy, what have they done to you --- src/library/scala/reflect/DummyMirror.scala | 183 ++++++++++++++++------------ 1 file changed, 107 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala index dd4791e57c..741ff33be2 100644 --- a/src/library/scala/reflect/DummyMirror.scala +++ b/src/library/scala/reflect/DummyMirror.scala @@ -192,70 +192,70 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { val UnitTpe: Type = DummyType val definitions: AbsDefinitions = DummyDefinitions object DummyDefinitions extends AbsDefinitions { - def ByNameParamClass = ??? - def JavaRepeatedParamClass = ??? - def RepeatedParamClass = ??? - def AnyClass = ??? - def AnyRefClass = ??? - def AnyValClass = ??? - def ArrayClass = ??? - def ArrayModule = ??? - def ArrayModule_overloadedApply = ??? - def Array_apply = ??? - def Array_clone = ??? - def Array_length = ??? - def Array_update = ??? - def BooleanClass = ??? - def ByteClass = ??? - def CharClass = ??? - def ClassClass = ??? - def ClassTagClass = ??? - def ClassTagModule = ??? - def ConcreteTypeTagClass = ??? - def ConcreteTypeTagModule = ??? - def ConsClass = ??? - def DoubleClass = ??? - def EmptyPackage = ??? - def EmptyPackageClass = ??? - def FloatClass = ??? + def ByNameParamClass = DummySymbol + def JavaRepeatedParamClass = DummySymbol + def RepeatedParamClass = DummySymbol + def AnyClass = DummyClassSymbol + def AnyRefClass = DummyTypeSymbol + def AnyValClass = DummyClassSymbol + def ArrayClass = DummyClassSymbol + def ArrayModule = DummySymbol + def ArrayModule_overloadedApply = DummySymbol + def Array_apply = DummySymbol + def Array_clone = DummySymbol + def Array_length = DummySymbol + def Array_update = DummySymbol + def BooleanClass = DummyClassSymbol + def ByteClass = DummyClassSymbol + def CharClass = DummyClassSymbol + def ClassClass = DummyClassSymbol + def ClassTagClass = DummyClassSymbol + def ClassTagModule = DummySymbol + def ConcreteTypeTagClass = DummyClassSymbol + def ConcreteTypeTagModule = DummySymbol + def ConsClass = DummySymbol + def DoubleClass = DummyClassSymbol + def EmptyPackage = DummyPackageSymbol + def EmptyPackageClass = DummySymbol + def FloatClass = DummyClassSymbol def FunctionClass: Array[Symbol] = Array() - def IntClass = ??? - def IterableClass = ??? - def IteratorClass = ??? - def IteratorModule = ??? - def Iterator_apply = ??? - def JavaLangPackage = ??? - def JavaLangPackageClass = ??? - def ListClass = ??? - def ListModule = ??? - def List_apply = ??? - def LongClass = ??? - def NilModule = ??? - def NoneModule = ??? - def NothingClass = ??? - def NullClass = ??? - def ObjectClass = ??? - def OptionClass = ??? - def PredefModule = ??? + def IntClass = DummyClassSymbol + def IterableClass = DummySymbol + def IteratorClass = DummySymbol + def IteratorModule = DummySymbol + def Iterator_apply = DummySymbol + def JavaLangPackage = DummyPackageSymbol + def JavaLangPackageClass = DummySymbol + def ListClass = DummyClassSymbol + def ListModule = DummyModuleSymbol + def List_apply = DummySymbol + def LongClass = DummyClassSymbol + def NilModule = DummySymbol + def NoneModule = DummySymbol + def NothingClass = DummyClassSymbol + def NullClass = DummyClassSymbol + def ObjectClass = DummyClassSymbol + def OptionClass = DummySymbol + def PredefModule = DummyModuleSymbol def ProductClass: Array[Symbol] = Array() - def RootClass = ??? - def RootPackage = ??? - def ScalaPackage = ??? - def ScalaPackageClass = ??? + def RootClass = DummyClassSymbol + def RootPackage = DummyPackageSymbol + def ScalaPackage = DummyPackageSymbol + def ScalaPackageClass = DummySymbol def ScalaPrimitiveValueClasses = Nil - def SeqClass = ??? - def SeqModule = ??? - def ShortClass = ??? - def SomeClass = ??? - def SomeModule = ??? - def StringBuilderClass = ??? - def StringClass = ??? - def SymbolClass = ??? - def TraversableClass = ??? + def SeqClass = DummySymbol + def SeqModule = DummySymbol + def ShortClass = DummyClassSymbol + def SomeClass = DummySymbol + def SomeModule = DummySymbol + def StringBuilderClass = DummySymbol + def StringClass = DummyClassSymbol + def SymbolClass = DummySymbol + def TraversableClass = DummySymbol def TupleClass: Array[Symbol] = Array() - def TypeTagClass = ??? - def TypeTagModule = ??? - def UnitClass = ??? + def TypeTagClass = DummyClassSymbol + def TypeTagModule = DummySymbol + def UnitClass = DummyClassSymbol def isNumericValueClass(sym: Symbol): Boolean = notSupported() def isPrimitiveValueClass(sym: Symbol): Boolean = notSupported() def vmClassType(arg: Type): Type = DummyType @@ -415,9 +415,22 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { } // Members declared in scala.reflect.api.Symbols - type Symbol = DummySymbol.type - val NoSymbol = ??? - object DummySymbol extends AbsSymbol { + val NoSymbol = DummySymbol + type Symbol = DummySymbolApi + object DummySymbol extends DummySymbolApi + type TypeSymbol = DummyTypeSymbolApi + object DummyTypeSymbol extends DummyTypeSymbolApi + type TermSymbol = DummyTermSymbolApi + object DummyTermSymbol extends DummyTermSymbolApi + type MethodSymbol = DummyMethodSymbolApi + object DummyMethodSymbol extends DummyMethodSymbolApi + type ModuleSymbol = DummyModuleSymbolApi + object DummyModuleSymbol extends DummyModuleSymbolApi + type PackageSymbol = DummyPackageSymbolApi + object DummyPackageSymbol extends DummyPackageSymbolApi + type ClassSymbol = DummyClassSymbolApi + object DummyClassSymbol extends DummyClassSymbolApi + trait DummySymbolApi extends AbsSymbol { this: Symbol => def pos: Position = notSupported() @@ -470,6 +483,24 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { def setAnnotations(annots: AnnotationInfo*): this.type = notSupported() def kind: String = notSupported() } + trait DummyTypeSymbolApi extends DummySymbolApi with TypeSymbolApi { + this: TypeSymbol => + } + trait DummyTermSymbolApi extends DummySymbolApi with TermSymbolApi { + this: TermSymbol => + } + trait DummyMethodSymbolApi extends DummyTermSymbolApi with MethodSymbolApi { + this: MethodSymbol => + } + trait DummyModuleSymbolApi extends DummyTermSymbolApi with ModuleSymbolApi { + this: ModuleSymbol => + } + trait DummyPackageSymbolApi extends DummyModuleSymbolApi with PackageSymbolApi { + this: PackageSymbol => + } + trait DummyClassSymbolApi extends DummyTypeSymbolApi with ClassSymbolApi { + this: ClassSymbol => + } // Members declared in scala.reflect.api.ToolBoxes def mkToolBox(frontEnd: FrontEnd, options: String): AbsToolBox = notSupported() @@ -478,19 +509,19 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { // type TreeGen = DummyTreeGen.type // [Eugene] cannot compile if uncomment this val gen: TreeGen{val global: DummyMirror.this.type} = DummyTreeGen.asInstanceOf[TreeGen{val global: DummyMirror.this.type}] def modifiersFromInternalFlags(flags: Long,privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers - def newFreeExistential(name: String,info: Type,value: => Any,flags: Long,origin: String) = ??? - def newFreeTerm(name: String,info: Type,value: => Any,flags: Long,origin: String) = ??? - def newFreeType(name: String,info: Type,value: => Any,flags: Long,origin: String) = ??? - def selectOverloadedMethod(owner: Symbol,name: String,index: Int) = ??? - def selectOverloadedMethodIfDefined(owner: Symbol,name: String,index: Int) = ??? - def selectTerm(owner: Symbol,name: String) = ??? - def selectTermIfDefined(owner: Symbol,name: String) = ??? - def selectType(owner: Symbol,name: String) = ??? - def selectTypeIfDefined(owner: Symbol,name: String) = ??? - def staticClass(fullName: String) = ??? - def staticClassIfDefined(fullName: String) = ??? - def staticModule(fullName: String) = ??? - def staticModuleIfDefined(fullName: String) = ??? + def newFreeExistential(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol + def newFreeTerm(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol + def newFreeType(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol + def selectOverloadedMethod(owner: Symbol,name: String,index: Int) = DummySymbol + def selectOverloadedMethodIfDefined(owner: Symbol,name: String,index: Int) = DummySymbol + def selectTerm(owner: Symbol,name: String) = DummySymbol + def selectTermIfDefined(owner: Symbol,name: String) = DummySymbol + def selectType(owner: Symbol,name: String) = DummySymbol + def selectTypeIfDefined(owner: Symbol,name: String) = DummySymbol + def staticClass(fullName: String) = DummySymbol + def staticClassIfDefined(fullName: String) = DummySymbol + def staticModule(fullName: String) = DummySymbol + def staticModuleIfDefined(fullName: String) = DummySymbol def thisModuleType(fullName: String): Type = DummyType object DummyTreeGen extends AbsTreeGen { val global: Universe = DummyMirror.this -- cgit v1.2.3 From 7ec2126fbb1db361dd420e4072c659d65e21e72d Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 23 Apr 2012 08:51:05 -0700 Subject: Revert "Fix for range positions." This reverts commit b47189ad06e027c310d93b071fc8bf15d979225d. This never happened. --- src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 838c7f8abd..88cea2231f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -1020,12 +1020,7 @@ class Foo(x: Other) { x._1 } // no error in this order override def traverse(t: Tree) { if (t != EmptyTree && t.pos == NoPosition) { - t setPos pos - // During a recursive descent traversal which prunes when it sees - // a position, one can't assign the position and THEN recurse. - // Ensuring that all children have compliant range positions. - for (t1 <- t ; if t1 ne t) - t1 setPos pos.makeTransparent + t.setPos(pos) } t match { case Function(_, _) if t.symbol == NoSymbol => -- cgit v1.2.3 From 2b09d8caf5497c4e016a3e1179e5f7e842766176 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 23 Apr 2012 17:51:28 +0200 Subject: rethinks tags * introduces ArrayTag and ErasureTag * all type tags now feature erasure --- lib/scala-compiler.jar.desired.sha1 | 2 +- lib/scala-library.jar.desired.sha1 | 2 +- .../scala/reflect/internal/Definitions.scala | 16 +- src/compiler/scala/reflect/internal/StdNames.scala | 42 ++- src/compiler/scala/reflect/internal/TreeInfo.scala | 6 +- src/compiler/scala/reflect/internal/Types.scala | 21 +- .../scala/reflect/makro/runtime/Reifiers.scala | 123 +------ src/compiler/scala/reflect/reify/Errors.scala | 8 +- src/compiler/scala/reflect/reify/Reifier.scala | 38 +- .../scala/reflect/reify/codegen/Symbols.scala | 2 +- .../scala/reflect/reify/codegen/Types.scala | 18 +- src/compiler/scala/reflect/reify/package.scala | 38 +- .../scala/tools/nsc/interpreter/RichClass.scala | 4 +- .../scala/tools/nsc/transform/Erasure.scala | 10 +- .../scala/tools/nsc/transform/UnCurry.scala | 2 +- .../scala/tools/nsc/typechecker/Implicits.scala | 18 +- .../scala/tools/nsc/typechecker/Macros.scala | 52 ++- .../tools/nsc/typechecker/PatMatVirtualiser.scala | 1 + .../scala/tools/nsc/typechecker/Taggings.scala | 71 ++++ .../scala/tools/nsc/typechecker/Typers.scala | 50 +-- src/compiler/scala/tools/reflect/package.scala | 3 +- src/library/scala/Predef.scala | 26 +- src/library/scala/reflect/ArrayTag.scala | 8 +- src/library/scala/reflect/ClassTag.scala | 206 +++-------- src/library/scala/reflect/DummyMirror.scala | 2 + src/library/scala/reflect/ErasureTag.scala | 23 ++ src/library/scala/reflect/ReflectionUtils.scala | 1 + src/library/scala/reflect/TagMaterialization.scala | 122 ------- src/library/scala/reflect/api/Symbols.scala | 8 + src/library/scala/reflect/api/TypeTags.scala | 246 ++++++------- src/library/scala/reflect/api/Universe.scala | 23 +- src/library/scala/reflect/makro/Context.scala | 21 +- src/library/scala/reflect/makro/Reifiers.scala | 25 +- .../scala/reflect/makro/internal/Utils.scala | 86 +++-- src/library/scala/reflect/package.scala | 5 +- src/library/scala/runtime/ScalaRunTime.scala | 21 +- src/library/scala/util/Marshal.scala | 36 +- test/files/neg/classtags_contextbound_a.check | 2 +- test/files/neg/classtags_contextbound_c.check | 2 +- test/files/neg/classtags_dont_use_typetags.check | 4 + test/files/neg/classtags_dont_use_typetags.scala | 3 + test/files/neg/macro-invalidret-nontree.check | 14 +- .../neg/macro-invalidret-nonuniversetree.check | 14 +- test/files/neg/t5689.check | 2 +- test/files/run/arraytags_basic.check | 36 ++ test/files/run/arraytags_basic.scala | 22 ++ test/files/run/arraytags_core.check | 48 +++ test/files/run/arraytags_core.scala | 50 +++ test/files/run/arraytags_usage.check | 3 + test/files/run/arraytags_usage.scala | 15 + test/files/run/classtags_core.check | 62 ++-- test/files/run/classtags_core.scala | 2 + test/files/run/classtags_multi.check | 5 + test/files/run/classtags_multi.scala | 7 + .../files/run/classtags_use_concretetypetags.scala | 3 + test/files/run/concretetypetags_core.check | 32 ++ test/files/run/concretetypetags_core.scala | 34 ++ test/files/run/concretetypetags_multi.check | 5 + test/files/run/concretetypetags_multi.scala | 7 + test/files/run/erasuretags_abstract.check | 4 + test/files/run/erasuretags_abstract.scala | 9 + test/files/run/erasuretags_basic.check | 24 ++ test/files/run/erasuretags_basic.scala | 21 ++ test/files/run/erasuretags_core.check | 32 ++ test/files/run/erasuretags_core.scala | 34 ++ test/files/run/erasuretags_usage.scala | 12 + test/files/run/groundtypetags_core.check | 30 -- test/files/run/groundtypetags_core.scala | 32 -- .../Impls_Macros_1.scala | 7 - .../run/macro-typecheck-macrosdisabled2.check | 5 + .../run/macro-typecheck-macrosdisabled2.flags | 1 + .../Impls_Macros_1.scala | 29 ++ .../macro-typecheck-macrosdisabled2/Test_2.scala | 4 + .../run/toolbox_typecheck_macrosdisabled2.check | 5 + .../run/toolbox_typecheck_macrosdisabled2.scala | 17 + test/files/run/typetags_core.check | 62 ++-- test/files/run/typetags_core.scala | 2 + test/files/run/typetags_multi.check | 5 + test/files/run/typetags_multi.scala | 7 + test/files/speclib/instrumented.jar.desired.sha1 | 2 +- test/instrumented/boxes.patch | 40 +-- .../library/scala/runtime/BoxesRunTime.java | 384 +++++++++------------ .../library/scala/runtime/ScalaRunTime.scala | 93 ++--- test/instrumented/srt.patch | 17 +- 84 files changed, 1426 insertions(+), 1210 deletions(-) create mode 100644 src/compiler/scala/tools/nsc/typechecker/Taggings.scala create mode 100644 src/library/scala/reflect/ErasureTag.scala delete mode 100644 src/library/scala/reflect/TagMaterialization.scala create mode 100644 test/files/neg/classtags_dont_use_typetags.check create mode 100644 test/files/neg/classtags_dont_use_typetags.scala create mode 100644 test/files/run/arraytags_basic.check create mode 100644 test/files/run/arraytags_basic.scala create mode 100644 test/files/run/arraytags_core.check create mode 100644 test/files/run/arraytags_core.scala create mode 100644 test/files/run/arraytags_usage.check create mode 100644 test/files/run/arraytags_usage.scala create mode 100644 test/files/run/classtags_multi.check create mode 100644 test/files/run/classtags_multi.scala create mode 100644 test/files/run/classtags_use_concretetypetags.scala create mode 100644 test/files/run/concretetypetags_core.check create mode 100644 test/files/run/concretetypetags_core.scala create mode 100644 test/files/run/concretetypetags_multi.check create mode 100644 test/files/run/concretetypetags_multi.scala create mode 100644 test/files/run/erasuretags_abstract.check create mode 100644 test/files/run/erasuretags_abstract.scala create mode 100644 test/files/run/erasuretags_basic.check create mode 100644 test/files/run/erasuretags_basic.scala create mode 100644 test/files/run/erasuretags_core.check create mode 100644 test/files/run/erasuretags_core.scala create mode 100644 test/files/run/erasuretags_usage.scala delete mode 100644 test/files/run/groundtypetags_core.check delete mode 100644 test/files/run/groundtypetags_core.scala create mode 100644 test/files/run/macro-typecheck-macrosdisabled2.check create mode 100644 test/files/run/macro-typecheck-macrosdisabled2.flags create mode 100644 test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala create mode 100644 test/files/run/macro-typecheck-macrosdisabled2/Test_2.scala create mode 100644 test/files/run/toolbox_typecheck_macrosdisabled2.check create mode 100644 test/files/run/toolbox_typecheck_macrosdisabled2.scala create mode 100644 test/files/run/typetags_multi.check create mode 100644 test/files/run/typetags_multi.scala (limited to 'src') diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index 7479a1861e..5a541f8cf3 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -5d99e65aaa8e00c4815e011a8dfc495cb38bdfcc ?scala-compiler.jar +c020eccb8cf37963725985f36b44d070915cf4d2 ?scala-compiler.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 76914369b5..d059e861f0 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -53ddaba2c7d56b360eda1a56c3eef5ec23ef14ca ?scala-library.jar +31c7188cef85c28b84b9ce35bc6780996e5dd139 ?scala-library.jar diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 24fc7c7cc4..28905dd240 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -380,6 +380,8 @@ trait Definitions extends reflect.api.StandardDefinitions { def arrayCloneMethod = getMember(ScalaRunTimeModule, nme.array_clone) def ensureAccessibleMethod = getMember(ScalaRunTimeModule, nme.ensureAccessible) def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements) + def arrayClassMethod = getMember(ScalaRunTimeModule, nme.arrayClass) + def arrayElementClassMethod = getMember(ScalaRunTimeModule, nme.arrayElementClass) // classes with special meanings lazy val StringAddClass = getRequiredClass("scala.runtime.StringAdd") @@ -409,7 +411,7 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN_NAME, 0L)(_ => AnyClass.tpe) lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.tpe)) lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => seqType(tparam.tpe)) - + lazy val MarkerCPSTypes = getClassIfDefined("scala.util.continuations.cpsParam") def isByNameParamType(tp: Type) = tp.typeSymbol == ByNameParamClass @@ -479,7 +481,9 @@ trait Definitions extends reflect.api.StandardDefinitions { // scala.reflect lazy val ReflectPackageClass = getMember(ScalaPackageClass, nme.reflect) lazy val ReflectPackage = getPackageObject("scala.reflect") - def Reflect_mirror = getMember(ReflectPackage, nme.mirror) + def ReflectMirror = getMember(ReflectPackage, nme.mirror) + // [Eugene] is this a good place for ReflectMirrorPrefix? + def ReflectMirrorPrefix = gen.mkAttributedRef(ReflectMirror) setType singleType(ReflectMirror.owner.thisPrefix, ReflectMirror) lazy val ExprClass = getMember(getRequiredClass("scala.reflect.api.Exprs"), tpnme.Expr) def ExprTree = getMemberClass(ExprClass, nme.tree) @@ -488,6 +492,8 @@ 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 ArrayTagClass = requiredClass[scala.reflect.ArrayTag[_]] + lazy val ErasureTagClass = requiredClass[scala.reflect.ErasureTag[_]] lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]] lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]] lazy val TypeTagsClass = requiredClass[scala.reflect.api.TypeTags] @@ -496,7 +502,9 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val ConcreteTypeTagClass = getMemberClass(TypeTagsClass, tpnme.ConcreteTypeTag) lazy val ConcreteTypeTagModule = getMemberModule(TypeTagsClass, nme.ConcreteTypeTag) - def ClassTagErasure = getMemberMethod(ClassTagClass, nme.erasure) + def ArrayTagWrap = getMemberMethod(ArrayTagClass, nme.wrap) + def ArrayTagNewArray = getMemberMethod(ArrayTagClass, nme.newArray) + def ErasureTagErasure = getMemberMethod(ErasureTagClass, nme.erasure) def ClassTagTpe = getMemberMethod(ClassTagClass, nme.tpe) def TypeTagTpe = getMemberMethod(TypeTagClass, nme.tpe) @@ -507,6 +515,8 @@ trait Definitions extends reflect.api.StandardDefinitions { 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_materializeArrayTag = getMemberMethod(MacroInternalPackage, nme.materializeArrayTag) + def MacroInternal_materializeErasureTag = getMemberMethod(MacroInternalPackage, nme.materializeErasureTag) def MacroInternal_materializeClassTag = getMemberMethod(MacroInternalPackage, nme.materializeClassTag) def MacroInternal_materializeTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeTypeTag) def MacroInternal_materializeConcreteTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeConcreteTypeTag) diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 54be83c98f..4ce6afe1f3 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -562,6 +562,8 @@ trait StdNames { val applyOrElse: NameType = "applyOrElse" val args : NameType = "args" val argv : NameType = "argv" + val arrayClass: NameType = "arrayClass" + val arrayElementClass: NameType = "arrayElementClass" val arrayValue: NameType = "arrayValue" val array_apply : NameType = "array_apply" val array_clone : NameType = "array_clone" @@ -628,9 +630,11 @@ trait StdNames { val main: NameType = "main" val manifest: NameType = "manifest" val map: NameType = "map" + val materializeArrayTag: NameType = "materializeArrayTag" val materializeClassTag: NameType = "materializeClassTag" - val materializeTypeTag: NameType = "materializeTypeTag" val materializeConcreteTypeTag: NameType = "materializeConcreteTypeTag" + val materializeErasureTag: NameType= "materializeErasureTag" + val materializeTypeTag: NameType = "materializeTypeTag" val mirror : NameType = "mirror" val moduleClass : NameType = "moduleClass" val name: NameType = "name" @@ -813,10 +817,11 @@ trait StdNames { val ROOTPKG: TermName = "_root_" val EQEQ_LOCAL_VAR: TermName = "eqEqTemp$" - def getCause = sn.GetCause - def getClass_ = sn.GetClass - def getMethod_ = sn.GetMethod - def invoke_ = sn.Invoke + def getCause = sn.GetCause + def getClass_ = sn.GetClass + def getComponentType = sn.GetComponentType + def getMethod_ = sn.GetMethod + def invoke_ = sn.Invoke val ADD = encode("+") val AND = encode("&") @@ -1005,6 +1010,7 @@ trait StdNames { val ForName : TermName val GetCause : TermName val GetClass : TermName + val GetComponentType : TermName val GetMethod : TermName val Invoke : TermName val JavaLang : TermName @@ -1090,12 +1096,13 @@ trait StdNames { final val Throwable: TypeName = "java.lang.Throwable" final val ValueType: TypeName = tpnme.NO_NAME - final val ForName: TermName = newTermName("forName") - final val GetCause: TermName = newTermName("getCause") - final val GetClass: TermName = newTermName("getClass") - final val GetMethod: TermName = newTermName("getMethod") - final val Invoke: TermName = newTermName("invoke") - final val JavaLang: TermName = newTermName("java.lang") + final val ForName: TermName = newTermName("forName") + final val GetCause: TermName = newTermName("getCause") + final val GetClass: TermName = newTermName("getClass") + final val GetComponentType: TermName = newTermName("getComponentType") + final val GetMethod: TermName = newTermName("getMethod") + final val Invoke: TermName = newTermName("invoke") + final val JavaLang: TermName = newTermName("java.lang") val Boxed = immutable.Map[TypeName, TypeName]( tpnme.Boolean -> BoxedBoolean, @@ -1127,12 +1134,13 @@ trait StdNames { final val Throwable: TypeName = "System.Exception" final val ValueType: TypeName = "System.ValueType" - final val ForName: TermName = newTermName("GetType") - final val GetCause: TermName = newTermName("InnerException") /* System.Reflection.TargetInvocationException.InnerException */ - final val GetClass: TermName = newTermName("GetType") - final val GetMethod: TermName = newTermName("GetMethod") - final val Invoke: TermName = newTermName("Invoke") - final val JavaLang: TermName = newTermName("System") + final val ForName: TermName = newTermName("GetType") + final val GetCause: TermName = newTermName("InnerException") /* System.Reflection.TargetInvocationException.InnerException */ + final val GetClass: TermName = newTermName("GetType") + final val GetComponentType: TermName = newTermName("GetElementType") + final val GetMethod: TermName = newTermName("GetMethod") + final val Invoke: TermName = newTermName("Invoke") + final val JavaLang: TermName = newTermName("System") val Boxed = immutable.Map[TypeName, TypeName]( tpnme.Boolean -> "System.Boolean", diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index 937b3ea5d6..48dfe8bcfc 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -676,14 +676,14 @@ abstract class TreeInfo { case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(flags: Long)), Literal(Constant(origin: String))))) if mrRef1.name == nme.MIRROR_SHORT && (newFreeType == newFreeTypeMethod.name || newFreeType == newFreeExistentialMethod.name) => value match { - case Apply(TypeApply(Select(Select(mrRef2 @ Ident(_), typeTag), apply), List(binding)), List(Literal(Constant(null)))) + 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, flags, origin) - case Apply(TypeApply(Select(mrRef2 @ Ident(_), typeTag), List(binding)), List(Literal(Constant(null)))) + 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, flags, origin) case _ => - throw new Error("unsupported free type def: " + showRaw(tree)) + throw new Error("unsupported free type def: %s%n%s".format(value, showRaw(value))) } case _ => None diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 32b09eddeb..815a5c0710 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -264,7 +264,23 @@ trait Types extends api.Types { self: SymbolTable => def nonPrivateDeclaration(name: Name): Symbol = nonPrivateDecl(name) def declarations = decls def typeArguments = typeArgs - def erasure = transformedType(this) + def erasure = this match { + case ConstantType(value) => widen.erasure // [Eugene to Martin] constant types are unaffected by erasure. weird. + case _ => + var result = transformedType(this) + result = result.normalize match { // necessary to deal with erasures of HK types, typeConstructor won't work + case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) // we don't want undets in the result + case _ => result + } + // [Eugene] erasure screws up all ThisTypes for modules into PackageTypeRefs + // we need to unscrew them, or certain typechecks will fail mysteriously + // http://groups.google.com/group/scala-internals/browse_thread/thread/6d3277ae21b6d581 + result = result.map(tpe => tpe match { + case tpe: PackageTypeRef => ThisType(tpe.sym) + case _ => tpe + }) + result + } def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to) // [Eugene] to be discussed and refactored @@ -1342,7 +1358,8 @@ trait Types extends api.Types { self: SymbolTable => if (period != currentPeriod) { tpe.underlyingPeriod = currentPeriod if (!isValid(period)) { - tpe.underlyingCache = tpe.pre.memberType(tpe.sym).resultType; + // [Eugene to Paul] needs review + tpe.underlyingCache = if (tpe.sym == NoSymbol) ThisType(RootClass) else tpe.pre.memberType(tpe.sym).resultType; assert(tpe.underlyingCache ne tpe, tpe) } } diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala index d9a89d0e6d..1c5af4b752 100644 --- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -12,124 +12,23 @@ trait Reifiers { import mirror._ import definitions._ - private lazy val ClassTagModule = ClassTagClass.companionSymbol + lazy val reflectMirrorPrefix: Tree = ReflectMirrorPrefix - // [Eugene] imho this logic should be moved into `erasure` - private def calculateTagErasure(tpe: Type) = tpe match { - case tpe if tpe.typeSymbol.isDerivedValueClass => tpe // [Eugene to Martin] is this correct? - case ConstantType(value) => tpe.widen.erasure - case _ => - // [Eugene] magikz. needs review - // necessary to deal with erasures of HK types, typeConstructor won't work - tpe.erasure.normalize match { - // we don't want undets in the result - case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) - case result => result - } - } - private def classTagFromArgument(tpe: Type, arg: Tree) = { - gen.mkMethodCall(ClassTagModule, nme.apply, List(tpe), List(arg)) - // val factory = TypeApply(Select(Ident(ClassTagModule), nme.apply), List(TypeTree(tpe))) - // Apply(factory, List(typeArg)) - } - private def classTagFromErasure(tpe: Type) = { - val erasure = calculateTagErasure(tpe) - classTagFromArgument(tpe, gen.mkNullaryCall(Predef_classOf, List(erasure))) - // val targ = TypeApply(Select(Ident(PredefModule), nme.classOf), List(TypeTree(erasure))) - // classTagFromArgument(tpe, targ) - } - private def typetagIsSynthetic(tree: Tree) = tree match { - case Block(_, _) => true - case _ => tree exists (_ hasSymbolWhich Set(TypeTagModule, ConcreteTypeTagModule)) + def reifyTree(prefix: Tree, tree: Tree): Tree = { + val result = scala.reflect.reify.`package`.reifyTree(mirror)(callsiteTyper, prefix, tree) + logFreeVars(enclosingPosition, result) + result } - 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 reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): Tree = { + val result = scala.reflect.reify.`package`.reifyType(mirror)(callsiteTyper, prefix, tpe, dontSpliceAtTopLevel, concrete) + logFreeVars(enclosingPosition, result) + result } - def reifyTree(prefix: Tree, tree: Tree): Tree = - reifyTopLevel(prefix, tree) - - def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree = - reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, requireConcreteTypeTag) - - def reifyErasure(tpe: Type): Tree = { - val positionBearer = (enclosingMacros.find(_.macroApplication.pos != NoPosition) match { - case None => EmptyTree - case Some(m) => m.macroApplication - }).asInstanceOf[Tree] - - val typetagInScope = callsiteTyper.context.withMacrosDisabled( - callsiteTyper.resolveTypeTag( - positionBearer, - singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror), - tpe, - full = true - ) - ) - typetagInScope match { - case success if !success.isEmpty && !typetagIsSynthetic(success) => - classTagFromArgument(tpe, typetagInScope) - case _ => - if (tpe.typeSymbol == ArrayClass) { - val componentTpe = tpe.typeArguments(0) - val componentTag = callsiteTyper.resolveClassTag(positionBearer, componentTpe) - Select(componentTag, nme.wrap) - } - // [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? - else if (tpe.isSpliceable) { - throw new ReificationError(enclosingPosition, - "tpe %s is an unresolved spliceable type".format(tpe)) - } - else classTagFromErasure(tpe) - } - } + def reifyErasure(tpe: Type, concrete: Boolean = true): Tree = + scala.reflect.reify.`package`.reifyErasure(mirror)(callsiteTyper, tpe, concrete) def unreifyTree(tree: Tree): Tree = Select(tree, definitions.ExprEval) - - 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, requireConcreteTypeTag) - - try { - val result = reifier.reified - logFreeVars(enclosingPosition, 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/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala index 30c6c06c7b..1a881455f2 100644 --- a/src/compiler/scala/reflect/reify/Errors.scala +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -1,7 +1,8 @@ package scala.reflect package reify -import scala.tools.nsc.Global +import scala.reflect.makro.ReificationError +import scala.reflect.makro.UnexpectedReificationError trait Errors { self: Reifier => @@ -9,9 +10,6 @@ trait Errors { 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) @@ -60,4 +58,4 @@ trait Errors { 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/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala index c89ebf0d39..fea825358e 100644 --- a/src/compiler/scala/reflect/reify/Reifier.scala +++ b/src/compiler/scala/reflect/reify/Reifier.scala @@ -2,6 +2,8 @@ package scala.reflect package reify import scala.tools.nsc.Global +import scala.reflect.makro.ReificationError +import scala.reflect.makro.UnexpectedReificationError /** 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. @@ -21,7 +23,7 @@ abstract class Reifier extends Phases val prefix: Tree val reifee: Any val dontSpliceAtTopLevel: Boolean - val requireConcreteTypeTag: Boolean + val concrete: Boolean /** * For ``reifee'' and other reification parameters, generate a tree of the form @@ -47,15 +49,6 @@ abstract class Reifier extends Phases if (prefix exists (_.isErroneous)) CannotReifyErroneousPrefix(prefix) if (prefix.tpe == null) CannotReifyUntypedPrefix(prefix) - def reifyErasure(tpe: Type): Tree = { - val result = typer.resolveClassTag(positionBearer, tpe) - if (result == EmptyTree) throw new Error("cannot reify erasure for %s: ".format(tpe)) - result match { - case Apply(TypeApply(Select(_, _), _), List(clazz)) => clazz - case _ => Select(result, nme.erasure) - } - } - val rtree = reifee match { case tree: Tree => reifyTrace("reifying = ")(if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) @@ -81,11 +74,11 @@ abstract class Reifier extends Phases if (tree.tpe exists (sub => sub.typeSymbol.isLocalToReifee)) CannotReifyReifeeThatHasTypeLocalToReifee(tree) - val manifestedType = typer.packedType(tree, NoSymbol) - val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule - val tagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) - val exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType))) - val tagArgs = if (definitelyConcrete) List(reify(manifestedType), reifyErasure(manifestedType)) else List(reify(manifestedType)) + val taggedType = typer.packedType(tree, NoSymbol) + val tagModule = if (reificationIsConcrete) ConcreteTypeTagModule else TypeTagModule + val tagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(taggedType))) + val exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(taggedType))) + val tagArgs = List(reify(taggedType), reifyErasure(mirror)(typer, taggedType, concrete = false)) Apply(Apply(exprCtor, List(rtree)), List(Apply(tagCtor, tagArgs))) case tpe: Type => @@ -93,10 +86,10 @@ abstract class Reifier extends Phases reifyTrace("prefix = ")(prefix) val rtree = reify(tpe) - val manifestedType = tpe - val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule - val ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) - val args = if (definitelyConcrete) List(rtree, reifyErasure(manifestedType)) else List(rtree) + val taggedType = tpe + val tagModule = if (reificationIsConcrete) ConcreteTypeTagModule else TypeTagModule + val ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(taggedType))) + val args = List(rtree, reifyErasure(mirror)(typer, taggedType, concrete = false)) Apply(ctor, args) case _ => @@ -137,9 +130,16 @@ abstract class Reifier extends Phases // 4) trivial tree splice inlining in Reify (Trees.scala) // 5) trivial type splice inlining in Reify (Types.scala) val freevarBindings = symbolTable collect { case entry @ FreeDef(_, _, binding, _, _) => binding.symbol } toSet + // [Eugene] yeah, ugly and extremely brittle, but we do need to do resetAttrs. will be fixed later + var importantSymbols = Set[Symbol](PredefModule, ScalaRunTimeModule) + importantSymbols ++= importantSymbols map (_.companionSymbol) + importantSymbols ++= importantSymbols map (_.moduleClass) + importantSymbols ++= importantSymbols map (_.linkedClassOfClass) + def importantSymbol(sym: Symbol): Boolean = sym != null && sym != NoSymbol && importantSymbols(sym) val untyped = resetAllAttrs(wrapped, leaveAlone = { case ValDef(_, mr, _, _) if mr == nme.MIRROR_SHORT => true case tree if freevarBindings contains tree.symbol => true + case tree if importantSymbol(tree.symbol) => true case _ => false }) diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala index 7f8b9c53b6..21a08b7efb 100644 --- a/src/compiler/scala/reflect/reify/codegen/Symbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala @@ -76,7 +76,7 @@ trait Symbols { 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)))) + val phantomTypeTag = Apply(TypeApply(Select(Ident(nme.MIRROR_SHORT), nme.TypeTag), List(value)), List(Literal(Constant(null)), Literal(Constant(null)))) val flavor = if (sym.isExistential) nme.newFreeExistential else nme.newFreeType locallyReify(sym, name, mirrorCall(flavor, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(sym.flags), reify(origin(sym)))) } diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala index e2a2a69828..841ec61e60 100644 --- a/src/compiler/scala/reflect/reify/codegen/Types.scala +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -65,11 +65,11 @@ trait Types { private var spliceTypesEnabled = !dontSpliceAtTopLevel /** Keeps track of whether this reification contains abstract type parameters */ - private var _definitelyConcrete = true - def definitelyConcrete = _definitelyConcrete - def definitelyConcrete_=(value: Boolean) { - _definitelyConcrete = value - if (!value && requireConcreteTypeTag) { + private var _reificationIsConcrete = true + def reificationIsConcrete = _reificationIsConcrete + def reificationIsConcrete_=(value: Boolean) { + _reificationIsConcrete = value + if (!value && concrete) { assert(current.isInstanceOf[Type], current) val offender = current.asInstanceOf[Type] CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(offender) @@ -89,7 +89,7 @@ trait Types { if (reifyDebug) println("splicing " + tpe) if (spliceTypesEnabled) { - var tagClass = if (requireConcreteTypeTag) ConcreteTypeTagClass else TypeTagClass + var tagClass = if (concrete) ConcreteTypeTagClass else TypeTagClass val tagTpe = singleType(prefix.tpe, prefix.tpe member tagClass.name) // [Eugene] this should be enough for an abstract type, right? @@ -99,13 +99,13 @@ trait Types { // 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)) - typer.resolveTypeTag(positionBearer, prefix.tpe, tpe, requireConcreteTypeTag) match { + typer.resolveTypeTag(positionBearer.pos, prefix.tpe, tpe, concrete) match { case failure if failure.isEmpty => if (reifyDebug) println("implicit search was fruitless") EmptyTree case success => if (reifyDebug) println("implicit search has produced a result: " + success) - definitelyConcrete &= requireConcreteTypeTag + reificationIsConcrete &= concrete var splice = Select(success, nme.tpe) splice match { case InlinedTypeSplice(_, inlinedSymbolTable, tpe) => @@ -123,7 +123,7 @@ trait Types { if (reifyDebug) println("splicing has been cancelled: spliceTypesEnabled = false") } - definitelyConcrete = false + reificationIsConcrete = false } spliceTypesEnabled = true diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index 85cf92fe2f..fa11c6313d 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -1,14 +1,16 @@ package scala.reflect import scala.tools.nsc.Global +import scala.reflect.makro.ReificationError +import scala.reflect.makro.UnexpectedReificationError package object reify { - def mkReifier(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Reifier { val mirror: global.type } = { + private def mkReifier(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): Reifier { val mirror: global.type } = { val typer1: typer.type = typer val prefix1: prefix.type = prefix val reifee1 = reifee val dontSpliceAtTopLevel1 = dontSpliceAtTopLevel - val requireConcreteTypeTag1 = requireConcreteTypeTag + val concrete1 = concrete new { val mirror: global.type = global @@ -16,7 +18,37 @@ package object reify { val prefix = prefix1 val reifee = reifee1 val dontSpliceAtTopLevel = dontSpliceAtTopLevel1 - val requireConcreteTypeTag = requireConcreteTypeTag1 + val concrete = concrete1 } with Reifier } + + def reifyTree(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, tree: global.Tree): global.Tree = + mkReifier(global)(typer, prefix, tree, false, false).reified.asInstanceOf[global.Tree] + + def reifyType(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, tpe: global.Type, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): global.Tree = + mkReifier(global)(typer, prefix, tpe, dontSpliceAtTopLevel, concrete).reified.asInstanceOf[global.Tree] + + def reifyErasure(global: Global)(typer0: global.analyzer.Typer, tpe: global.Type, concrete: Boolean = true): global.Tree = { + import global._ + import definitions._ + val positionBearer = analyzer.openMacros.find(_.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] + val inScope = typer0.context.withMacrosDisabled(typer0.resolveErasureTag(positionBearer.pos, tpe, concrete = concrete), typer0.resolveArrayTag(positionBearer.pos, tpe)) + inScope match { + case (success, _) if !success.isEmpty => + Select(success, nme.erasure) + case (_, success) if !success.isEmpty => + gen.mkMethodCall(arrayElementClassMethod, List(success)) + case _ => + if (tpe.typeSymbol == ArrayClass) { + val componentTpe = tpe.typeArguments(0) + val componentErasure = reifyErasure(global)(typer0, componentTpe, concrete) + gen.mkMethodCall(arrayClassMethod, List(componentErasure)) + } else { + if (tpe.isSpliceable && concrete) throw new ReificationError(positionBearer.pos, "tpe %s is an unresolved spliceable type".format(tpe)) + var erasure = tpe.erasure + if (tpe.typeSymbol.isDerivedValueClass && global.phase.id < global.currentRun.erasurePhase.id) erasure = tpe + gen.mkNullaryCall(Predef_classOf, List(erasure)) + } + } + } } diff --git a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala index b1bee6ce93..3d4d22063e 100644 --- a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala +++ b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala @@ -6,8 +6,10 @@ package scala.tools.nsc package interpreter +import scala.reflect.{mirror => rm} + class RichClass[T](val clazz: Class[T]) { - def toManifest: Manifest[T] = Manifest[T](ClassManifest[T](clazz).tpe) + def toManifest: Manifest[T] = Manifest[T](rm.classToType(clazz)) def toTypeString: String = TypeStrings.fromClazz(clazz) // Sadly isAnonymousClass does not return true for scala anonymous diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 45dacd5c14..c766b52159 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -617,8 +617,12 @@ abstract class Erasure extends AddInterfaces // See SI-4731 for one example of how this occurs. log("Attempted to cast to Unit: " + tree) tree.duplicate setType pt - } - else gen.mkAttributedCast(tree, pt) + } else if (tree.tpe != null && tree.tpe.typeSymbol == ArrayClass && pt.typeSymbol == ArrayClass) { + // See SI-2386 for one example of when this might be necessary. + val needsExtraCast = isScalaValueType(tree.tpe.typeArgs.head) && !isScalaValueType(pt.typeArgs.head) + val tree1 = if (needsExtraCast) gen.mkRuntimeCall(nme.toObjectArray, List(tree)) else tree + gen.mkAttributedCast(tree1, pt) + } else gen.mkAttributedCast(tree, pt) } /** Adapt `tree` to expected type `pt`. @@ -992,7 +996,7 @@ abstract class Erasure extends AddInterfaces } // Rewrite 5.getClass to ScalaRunTime.anyValClass(5) else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) - global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveClassTag(tree, qual.tpe.widen)))) + global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveErasureTag(tree.pos, qual.tpe.widen, true)))) else tree diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 6b894a724f..35e26b39b5 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -486,7 +486,7 @@ abstract class UnCurry extends InfoTransform val toArraySym = tree.tpe member nme.toArray assert(toArraySym != NoSymbol) def getClassTag(tp: Type): Tree = { - val tag = localTyper.resolveClassTag(tree, tp) + val tag = localTyper.resolveArrayTag(tree.pos, tp) // Don't want bottom types getting any further than this (SI-4024) if (tp.typeSymbol.isBottomClass) getClassTag(AnyClass.tpe) else if (!tag.isEmpty) tag diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index f8da6a462d..3f4e941ec6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1120,9 +1120,10 @@ trait Implicits { implicitInfoss1 } - // these should be lazy, otherwise we wouldn't be able to compile scala-library with starr - private val TagSymbols = Set[Symbol](ClassTagClass, TypeTagClass, ConcreteTypeTagClass) - private val TagMaterializers = Map[Symbol, MethodSymbol]( + private def TagSymbols = TagMaterializers.keySet + private val TagMaterializers = Map[Symbol, Symbol]( + ArrayTagClass -> MacroInternal_materializeArrayTag, + ErasureTagClass -> MacroInternal_materializeErasureTag, ClassTagClass -> MacroInternal_materializeClassTag, TypeTagClass -> MacroInternal_materializeTypeTag, ConcreteTypeTagClass -> MacroInternal_materializeConcreteTypeTag @@ -1143,10 +1144,7 @@ trait Implicits { val prefix = ( // ClassTags only exist for scala.reflect.mirror, so their materializer // doesn't care about prefixes - if (tagClass eq ClassTagClass) ( - gen.mkAttributedRef(Reflect_mirror) - setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror) - ) + if ((tagClass eq ArrayTagClass) || (tagClass eq ErasureTagClass) || (tagClass eq ClassTagClass)) ReflectMirrorPrefix else pre match { // [Eugene to Martin] this is the crux of the interaction between // implicits and reifiers here we need to turn a (supposedly @@ -1173,7 +1171,7 @@ trait Implicits { else failure(materializer, "macros are disabled") } - /** The manifest corresponding to type `pt`, provided `pt` is an instance of Manifest. + /** The tag corresponding to type `pt`, provided `pt` is a flavor of a tag. */ private def implicitTagOrOfExpectedType(pt: Type): SearchResult = pt.dealias match { case TypeRef(pre, sym, arg :: Nil) if TagSymbols(sym) => @@ -1183,13 +1181,13 @@ trait Implicits { case _ => searchImplicit(implicitsOfExpectedType, false) // shouldn't we pass `pt` to `implicitsOfExpectedType`, or is the recursive case - // for an abstract type really only meant for manifests? + // for an abstract type really only meant for tags? } /** The result of the implicit search: * First search implicits visible in current context. * If that fails, search implicits in expected type `pt`. - * // [Eugene] the following two lines should be deleted after we migrate delegate manifest materialization to implicit macros + * // [Eugene] the following two lines should be deleted after we migrate delegate tag materialization to implicit macros * If that fails, and `pt` is an instance of a ClassTag, try to construct a class tag. * If that fails, and `pt` is an instance of a TypeTag, try to construct a type tag. * If all fails return SearchFailure diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 9b4dd09c98..5d4cd0be77 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -155,7 +155,7 @@ trait Macros { self: Analyzer => case TypeRef(SingleType(NoPrefix, contextParam), sym, List(tparam)) => var wannabe = sym while (wannabe.isAliasType) wannabe = wannabe.info.typeSymbol - if (wannabe != definitions.TypeTagClass) + if (wannabe != definitions.TypeTagClass && wannabe != definitions.ConcreteTypeTagClass) List(param) else transform(param, tparam.typeSymbol) map (_ :: Nil) getOrElse Nil @@ -353,6 +353,16 @@ trait Macros { self: Analyzer => if (actparamss.length != reqparamss.length) compatibilityError("number of parameter sections differ") + def checkSubType(slot: String, reqtpe: Type, acttpe: Type): Unit = { + val ok = if (macroDebug) { + if (reqtpe eq acttpe) println(reqtpe + " <: " + acttpe + "?" + EOL + "true") + withTypesExplained(reqtpe <:< acttpe) + } else reqtpe <:< acttpe + if (!ok) { + compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, reqtpe.toString.abbreviateCoreAliases, acttpe.toString.abbreviateCoreAliases)) + } + } + if (!hasErrors) { try { for ((rparams, aparams) <- reqparamss zip actparamss) { @@ -378,27 +388,19 @@ trait Macros { self: Analyzer => 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) - } + checkSubType("parameter " + rparam.name, rparam.tpe, 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)) - } + checkSubType("return type", atpe, reqres) } if (!hasErrors) { val targs = solvedTypes(tvars, tparams, tparams map varianceInType(actres), false, @@ -873,9 +875,8 @@ trait Macros { self: Analyzer => // 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 resolved = collection.mutable.Map[Symbol, Type]() + paramss = transformTypeTagEvidenceParams(paramss, (param, tparam) => { val TypeApply(_, implRefTargs) = ann.args(0) var implRefTarg = implRefTargs(tparam.paramPos).tpe.typeSymbol val tpe = if (implRefTarg.isTypeParameterOrSkolem) { @@ -892,12 +893,27 @@ trait Macros { self: Analyzer => } else implRefTarg.tpe if (macroDebug) println("resolved tparam %s as %s".format(tparam, tpe)) - tpe - }) map (tpe => { - val ttag = TypeTag(tpe) + resolved(tparam) = tpe + param.tpe.typeSymbol match { + case sym if sym == definitions.TypeTagClass => + // do nothing + case sym if sym == definitions.ConcreteTypeTagClass => + if (!tpe.isConcrete) context.abort(context.enclosingPosition, "cannot create ConcreteTypeTag from a type %s having unresolved type parameters".format(tpe)) + // otherwise do nothing + case _ => + throw new Error("unsupported tpe: %s".format(tpe)) + } + Some(tparam) + }) + val tags = paramss.last takeWhile (_.isType) map (resolved(_)) map (tpe => { + // generally speaking, it's impossible to calculate erasure from a tpe here + // the tpe might be compiled by this run, so its jClass might not exist yet + // hence I just pass `null` instead and leave this puzzle to macro programmers + val ttag = TypeTag(tpe, null) if (ttag.isConcrete) ttag.toConcrete else ttag }) - argss = argss.dropRight(1) :+ (evidences ++ argss.last) + if (paramss.lastOption map (params => !params.isEmpty && params.forall(_.isType)) getOrElse false) argss = argss :+ Nil + argss = argss.dropRight(1) :+ (tags ++ argss.last) // todo. add support for context bounds in argss assert(argss.length == paramss.length, "argss: %s, paramss: %s".format(argss, paramss)) val rawArgss = for ((as, ps) <- argss zip paramss) yield { diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 88cea2231f..02e53cb624 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -828,6 +828,7 @@ class Foo(x: Other) { x._1 } // no error in this order 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)) + // [Eugene to Adriaan] use `resolveErasureTag` instead of `findManifest`. please, provide a meaningful position // if (opt.experimental && containsUnchecked(expectedTp)) { // if (dynamic) { // val expectedTpTagTree = findManifest(expectedTp, true) diff --git a/src/compiler/scala/tools/nsc/typechecker/Taggings.scala b/src/compiler/scala/tools/nsc/typechecker/Taggings.scala new file mode 100644 index 0000000000..d276b39f16 --- /dev/null +++ b/src/compiler/scala/tools/nsc/typechecker/Taggings.scala @@ -0,0 +1,71 @@ +package scala.tools.nsc +package typechecker + +trait Taggings { + self: Analyzer => + + import global._ + import definitions._ + + trait Tagging { + self: Typer => + + private def resolveTag(pos: Position, taggedTp: Type) = beforeTyper { + inferImplicit( + EmptyTree, + taggedTp, + /*reportAmbiguous =*/ true, + /*isView =*/ false, + /*context =*/ context, + /*saveAmbiguousDivergent =*/ true, + /*pos =*/ pos + ).tree + } + + /** Finds in scope or materializes an ArrayTag. + * Should be used instead of ClassTag or ClassManifest every time compiler needs to create an array. + * + * @param pos Position for error reporting. Please, provide meaningful value. + * @param tp Type we're looking an ArrayTag for, e.g. resolveArrayTag(pos, IntClass.tpe) will look for ArrayTag[Int]. + * + * @returns Tree that represents an `scala.reflect.ArrayTag` for `tp` if everything is okay. + * EmptyTree if the result contains unresolved (i.e. not spliced) type parameters and abstract type members. + */ + def resolveArrayTag(pos: Position, tp: Type): Tree = { + val taggedTp = appliedType(ArrayTagClass.typeConstructor, List(tp)) + resolveTag(pos, taggedTp) + } + + /** Finds in scope or materializes an ErasureTag (if `concrete` is false) or a ClassTag (if `concrete` is true). + * Should be used instead of ClassTag or ClassManifest every time compiler needs to persist an erasure. + * + * @param pos Position for error reporting. Please, provide meaningful value. + * @param tp Type we're looking an ErasureTag for, e.g. resolveErasureTag(pos, IntClass.tpe, true) will look for ClassTag[Int]. + * @param concrete If true then the result must not contain unresolved (i.e. not spliced) type parameters and abstract type members. + * If false then the function will always succeed (abstract types will be erased to their upper bounds). + * + * @returns Tree that represents an `scala.reflect.ErasureTag` for `tp` if everything is okay. + * EmptyTree if `concrete` is true and the result contains unresolved (i.e. not spliced) type parameters and abstract type members. + */ + def resolveErasureTag(pos: Position, tp: Type, concrete: Boolean): Tree = { + val taggedTp = appliedType(if (concrete) ClassTagClass.typeConstructor else ErasureTagClass.typeConstructor, List(tp)) + resolveTag(pos, taggedTp) + } + + /** Finds in scope or materializes a TypeTag (if `concrete` is false) or a ConcreteTypeTag (if `concrete` is true). + * + * @param pos Position for error reporting. Please, provide meaningful value. + * @param pre Prefix that represents a universe this type tag will be bound to. + * @param tp Type we're looking a TypeTag for, e.g. resolveTypeTag(pos, reflectMirrorPrefix, IntClass.tpe, false) will look for scala.reflect.mirror.TypeTag[Int]. + * @param concrete If true then the result must not contain unresolved (i.e. not spliced) type parameters and abstract type members. + * If false then the function will always succeed (abstract types will be reified as free types). + * + * @returns Tree that represents a `scala.reflect.TypeTag` for `tp` if everything is okay. + * EmptyTree if `concrete` is true and the result contains unresolved (i.e. not spliced) type parameters and abstract type members. + */ + def resolveTypeTag(pos: Position, pre: Type, tp: Type, concrete: Boolean): Tree = { + val taggedTp = appliedType(singleType(pre, pre member (if (concrete) ConcreteTypeTagClass else TypeTagClass).name), List(tp)) + resolveTag(pos, taggedTp) + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 54be9c9a87..ba6a363095 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -26,7 +26,7 @@ import util.Statistics._ * @author Martin Odersky * @version 1.0 */ -trait Typers extends Modes with Adaptations with PatMatVirtualiser { +trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser { self: Analyzer => import global._ @@ -83,7 +83,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { private def isPastTyper = phase.id > currentRun.typerPhase.id - abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with TyperContextErrors { + abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with Tagging with TyperContextErrors { import context0.unit import typeDebug.{ ptTree, ptBlock, ptLine } import TyperErrorGen._ @@ -830,11 +830,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { context.undetparams = inferExprInstance(tree, context.extractUndetparams(), pt, // approximate types that depend on arguments since dependency on implicit argument is like dependency on type parameter mt.approximate, - // if we are looking for a manifest, instantiate type to Nothing anyway, - // as we would get ambiguity errors otherwise. Example - // Looking for a manifest of Nil: This has many potential types, - // so we need to instantiate to minimal type List[Nothing]. - keepNothings = false, // retract Nothing's that indicate failure, ambiguities in manifests are dealt with in manifestOfType + keepNothings = false, useWeaklyCompatible = true) // #3808 } @@ -3103,7 +3099,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (annInfo.atp.isErroneous) { hasError = true; None } else Some(NestedAnnotArg(annInfo)) - // use of Array.apply[T: ClassManifest](xs: T*): Array[T] + // use of Array.apply[T: ArrayTag](xs: T*): Array[T] // and Array.apply(x: Int, xs: Int*): Array[Int] (and similar) case Apply(fun, args) => val typedFun = typed(fun, forFunMode(mode), WildcardType) @@ -4840,12 +4836,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // [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) + val newArrayApp = atPos(tree.pos) { + val tag = resolveArrayTag(tree.pos, tagType) if (tag.isEmpty) MissingClassTagError(tree, tagType) else new ApplyToImplicitArgs(Select(tag, nme.newArray), args) - } - typed(newArrayApp, mode, pt) + } + typed(newArrayApp, mode, pt) case tree1 => tree1 } @@ -5210,36 +5206,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case None => typed(tree, mode, pt) } - // `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(ClassTagClass.typeConstructor, List(tp)), - /*reportAmbiguous =*/ true, - /*isView =*/ false, - /*context =*/ context, - /*saveAmbiguousDivergent =*/ true, - /*pos =*/ tree.pos - ).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) ConcreteTypeTagClass 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/reflect/package.scala b/src/compiler/scala/tools/reflect/package.scala index f5c836a4e9..744bf9b226 100644 --- a/src/compiler/scala/tools/reflect/package.scala +++ b/src/compiler/scala/tools/reflect/package.scala @@ -7,6 +7,7 @@ package scala.tools import java.lang.reflect.Method import java.{ lang => jl } +import scala.reflect.{mirror => rm} package object reflect { def nameAndArity(m: Method) = (m.getName, m.getParameterTypes.size) @@ -27,7 +28,7 @@ package object reflect { } } - def zeroOfClass(clazz: Class[_]) = zeroOf(Manifest(ClassManifest(clazz).tpe)) + def zeroOfClass(clazz: Class[_]) = zeroOf(Manifest(rm.classToType(clazz))) 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 15e007528b..093f972f72 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -119,20 +119,24 @@ 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 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 + type ArrayTag[T] = scala.reflect.ArrayTag[T] + type ErasureTag[T] = scala.reflect.ErasureTag[T] + 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 ConcreteTypeTag = scala.reflect.ConcreteTypeTag + 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 concreteTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag - def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag + def arrayTag[T](implicit atag: ArrayTag[T]) = atag + def erasureTag[T](implicit etag: ErasureTag[T]) = etag + 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/ArrayTag.scala b/src/library/scala/reflect/ArrayTag.scala index 8df7fe5f4e..ba0c075723 100644 --- a/src/library/scala/reflect/ArrayTag.scala +++ b/src/library/scala/reflect/ArrayTag.scala @@ -3,11 +3,17 @@ 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. * + * Implicit in the contract of `ArrayTag[T]` is the fact that `T` + * cannot contain unresolved references to type parameters or abstract types. + * * Scala library provides a standard implementation of this trait, - * `ClassTag[T]` that explicitly carries the `java.lang.Class` erasure of type T. + * `ClassTag[T]` that explicitly carries the `java.lang.Class` erasure of type T + * and uses Java reflection to instantiate arrays. * * 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. + * + * @see [[scala.reflect.api.TypeTags]] */ @annotation.implicitNotFound(msg = "No ArrayTag available for ${T}") trait ArrayTag[T] { diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index 142025f600..e485691747 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -3,6 +3,7 @@ package scala.reflect import java.lang.{ Class => jClass } import scala.reflect.{ mirror => rm } import language.{implicitConversions, existentials} +import scala.runtime.ScalaRunTime.arrayClass /** A `ClassTag[T]` wraps a Java class, which can be accessed via the `erasure` method. * @@ -18,34 +19,17 @@ import language.{implicitConversions, existentials} * 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 + * (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). + * + * @see [[scala.reflect.api.TypeTags]] + */ @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) +trait ClassTag[T] extends ArrayTag[T] with ErasureTag[T] with Equals with Serializable { + // 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 /** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */ - def wrap: ClassTag[Array[T]] = { - // newInstance throws an exception if the erasure is Void.TYPE - // see SI-5680 - val arrayClazz = - if (erasure == java.lang.Void.TYPE) classOf[Array[Unit]] - else java.lang.reflect.Array.newInstance(erasure, 0).getClass.asInstanceOf[jClass[Array[T]]] - ClassTag[Array[T]](arrayClazz) - } + def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(erasure)) /** Produces a new array with element type `T` and length `len` */ def newArray(len: Int): Array[T] = @@ -61,31 +45,39 @@ abstract case class ClassTag[T](erasure: jClass[_]) extends ArrayTag[T] { case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] case _ => java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] } + + /** case class accessories */ + override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] + override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.erasure == x.asInstanceOf[ClassTag[_]].erasure + override def hashCode = scala.runtime.ScalaRunTime.hash(erasure) + override def toString = "ClassTag[" + erasure + "]" } object ClassTag { + private val NothingTYPE = classOf[scala.runtime.Nothing$] + private val NullTYPE = classOf[scala.runtime.Null$] 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 { + val Byte : ClassTag[scala.Byte] = new ClassTag[scala.Byte]{ def erasure = java.lang.Byte.TYPE; private def readResolve() = ClassTag.Byte } + val Short : ClassTag[scala.Short] = new ClassTag[scala.Short]{ def erasure = java.lang.Short.TYPE; private def readResolve() = ClassTag.Short } + val Char : ClassTag[scala.Char] = new ClassTag[scala.Char]{ def erasure = java.lang.Character.TYPE; private def readResolve() = ClassTag.Char } + val Int : ClassTag[scala.Int] = new ClassTag[scala.Int]{ def erasure = java.lang.Integer.TYPE; private def readResolve() = ClassTag.Int } + val Long : ClassTag[scala.Long] = new ClassTag[scala.Long]{ def erasure = java.lang.Long.TYPE; private def readResolve() = ClassTag.Long } + val Float : ClassTag[scala.Float] = new ClassTag[scala.Float]{ def erasure = java.lang.Float.TYPE; private def readResolve() = ClassTag.Float } + val Double : ClassTag[scala.Double] = new ClassTag[scala.Double]{ def erasure = java.lang.Double.TYPE; private def readResolve() = ClassTag.Double } + val Boolean : ClassTag[scala.Boolean] = new ClassTag[scala.Boolean]{ def erasure = java.lang.Boolean.TYPE; private def readResolve() = ClassTag.Boolean } + val Unit : ClassTag[scala.Unit] = new ClassTag[scala.Unit]{ def erasure = java.lang.Void.TYPE; private def readResolve() = ClassTag.Unit } + val Any : ClassTag[scala.Any] = new ClassTag[scala.Any]{ def erasure = ObjectTYPE; private def readResolve() = ClassTag.Any } + val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object]{ def erasure = ObjectTYPE; private def readResolve() = ClassTag.Object } + val AnyVal : ClassTag[scala.AnyVal] = new ClassTag[scala.AnyVal]{ def erasure = ObjectTYPE; private def readResolve() = ClassTag.AnyVal } + val AnyRef : ClassTag[scala.AnyRef] = new ClassTag[scala.AnyRef]{ def erasure = ObjectTYPE; private def readResolve() = ClassTag.AnyRef } + val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing]{ def erasure = NothingTYPE; private def readResolve() = ClassTag.Nothing } + val Null : ClassTag[scala.Null] = new ClassTag[scala.Null]{ def erasure = NullTYPE; private def readResolve() = ClassTag.Null } + val String : ClassTag[java.lang.String] = new ClassTag[java.lang.String]{ def erasure = StringTYPE; private def readResolve() = ClassTag.String } + + def apply[T](erasure1: jClass[_]): ClassTag[T] = + erasure1 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]] @@ -97,128 +89,8 @@ object ClassTag { 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)) + case _ => new ClassTag[T]{ def erasure = erasure1 } } - def apply[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = - if (ttag.erasure != null) ClassTag[T](ttag.erasure) - else ClassTag[T](ttag.tpe) - - implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag) - - @deprecated("Use apply instead", "2.10.0") - def fromClass[T](clazz: jClass[T]): ClassManifest[T] = apply(clazz) - - /** Manifest for the singleton type `value.type'. */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = ??? - - /** 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) - */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def classType[T <: AnyRef](clazz: jClass[_]): ClassManifest[T] = ClassTag[T](clazz) - - /** ClassManifest for the class type `clazz[args]', where `clazz' is - * a top-level or static class and `args` are its type arguments */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def classType[T <: AnyRef](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](clazz) - - /** ClassManifest for the class type `clazz[args]', where `clazz' is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def classType[T <: AnyRef](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](clazz) - - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match { - case x: ConcreteTypeTag[_] => ClassManifest[Array[T]](x.erasure) - case _ => Object.asInstanceOf[ClassManifest[Array[T]]] // was there in 2.9.x - } - - /** 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. */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def abstractType[T](prefix: OptManifest[_], name: String, clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](clazz) - - /** 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 - */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def abstractType[T](prefix: OptManifest[_], name: String, upperbound: ClassManifest[_], args: OptManifest[_]*): ClassManifest[T] = ClassTag[T](upperbound.erasure) - - 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() - } -} - + def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.erasure) +} \ No newline at end of file diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala index dd4791e57c..8b2ddde2a1 100644 --- a/src/library/scala/reflect/DummyMirror.scala +++ b/src/library/scala/reflect/DummyMirror.scala @@ -430,6 +430,8 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { def fullName: String = notSupported() def id: Int = notSupported() def orElse[T](alt: => Symbol): Symbol = notSupported() + def filter(cond: Symbol => Boolean): Symbol = notSupported() + def suchThat(cond: Symbol => Boolean): Symbol = notSupported() def privateWithin: Symbol = notSupported() def companionSymbol: Symbol = notSupported() def moduleClass: Symbol = notSupported() diff --git a/src/library/scala/reflect/ErasureTag.scala b/src/library/scala/reflect/ErasureTag.scala new file mode 100644 index 0000000000..f95451fab2 --- /dev/null +++ b/src/library/scala/reflect/ErasureTag.scala @@ -0,0 +1,23 @@ +package scala.reflect + +import java.lang.{Class => jClass} + +/** An `ErasureTag[T]` is a descriptor that is requested by the compiler every time + * when it needs to persist an erasure of a type. + * + * Scala library provides a standard implementation of this trait, + * `TypeTag[T]` that carries the `java.lang.Class` erasure for arbitrary types. + * + * However other platforms may reimplement this trait as they see fit + * and then expose the implementation via an implicit macro. + * + * If you need to guarantee that the type does not contain + * references to type parameters or abstract types, use `ClassTag[T]`. + * + * @see [[scala.reflect.api.TypeTags]] + */ +@annotation.implicitNotFound(msg = "No ErasureTag available for ${T}") +trait ErasureTag[T] { + /** Returns an erasure of type `T` */ + def erasure: jClass[_] +} diff --git a/src/library/scala/reflect/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala index 79a42f6ec4..6ea69cb80d 100644 --- a/src/library/scala/reflect/ReflectionUtils.scala +++ b/src/library/scala/reflect/ReflectionUtils.scala @@ -5,6 +5,7 @@ package scala.reflect +import java.lang.{Class => jClass} import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException } /** A few java-reflection oriented utility functions useful during reflection bootstrapping. diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala deleted file mode 100644 index e8d4571228..0000000000 --- a/src/library/scala/reflect/TagMaterialization.scala +++ /dev/null @@ -1,122 +0,0 @@ -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 -// 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. */ - - /** !!! Some of this code is copy-pasted four places. This situation - * should be resolved ASAP. - */ -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, requireConcreteTypeTag = false) - } - - 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, requireConcreteTypeTag = 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 ConcreteTypeTagClass = selectType(TypeTagsClass, "ConcreteTypeTag") - val ConcreteTypeTagModule = selectTerm(TypeTagsClass, "ConcreteTypeTag") - - def materializeClassTag(tpe: Type): Tree = - materializeTag(c.reflectMirrorPrefix, tpe, ClassTagModule, c.reifyErasure(tpe)) - - def materializeTypeTag(tpe: Type, requireConcreteTypeTag: Boolean): Tree = { - def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix - val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule - materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)) - } - - private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = { - val result = - tpe match { - case coreTpe if coreTags contains coreTpe => - Select(Select(prefix, tagModule.name), coreTags(coreTpe)) - case _ => - try materializer - 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/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index 767246a294..dbd264c0ab 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -148,6 +148,14 @@ trait Symbols { self: Universe => */ def orElse[T](alt: => Symbol): Symbol + /** ... + */ + def filter(cond: Symbol => Boolean): Symbol + + /** ... + */ + def suchThat(cond: Symbol => Boolean): Symbol + /** * Set when symbol has a modifier of the form private[X], NoSymbol otherwise. * diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index b90475b15a..c58b0fcec2 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -6,7 +6,6 @@ package scala.reflect package api -import scala.reflect.{ mirror => rm } import java.lang.{ Class => jClass } import language.implicitConversions @@ -15,22 +14,41 @@ import language.implicitConversions * 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: + * === Overview === + * + * Type tags are organized in a hierarchy of five classes: + * [[scala.reflect.ArrayTag]], [[scala.reflect.ErasureTag]], [[scala.reflect.ClassTag]], * [[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#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. + * An [[scala.reflect.ArrayTag]] value carries knowledge about how to build an array of elements of type T. + * Typically such operation is performed by storing an erasure and instantiating arrays via Java reflection, + * but [[scala.reflect.ArrayTag]] only defines an interface, not an implementation, hence it only contains the factory methods + * `newArray` and `wrap` that can be used to build, correspondingly, single-dimensional and multi-dimensional arrays. * - * 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.ConcreteTypeTag, - * Whereas scala.reflect.mirror.TypeTag is approximated by the previous notion of [[scala.reflect.OptManifest]]. + * An [[scala.reflect.ErasureTag]] value wraps a Java class, which can be accessed via the `erasure` method. + * This notion, previously embodied in a [[scala.reflect.ClassManifest]] together with the notion of array creation, + * deserves a concept of itself. Quite often (e.g. for serialization or classloader introspection) it's useful to + * know an erasure, and only it, so we've implemented this notion in [[scala.reflect.ErasureTag]]. * - * 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. + * A [[scala.reflect.ClassTag]] is a standard implementation of both [[scala.reflect.ArrayTag]] and [[scala.reflect.ErasureTag]]. + * It guarantees that the source type T did not to contain any references to type parameters or abstract types. + * [[scala.reflect.ClassTag]] corresponds to a previous notion of [[scala.reflect.ClassManifest]]. * + * A [[scala.reflect.api.Universe#TypeTag]] value wraps a full Scala type in its tpe field. + * A [[scala.reflect.api.Universe#ConcreteTypeTag]] value is a [[scala.reflect.api.Universe#TypeTag]] + * that is guaranteed not to contain any references to type parameters or abstract types. + * Both flavors of TypeTags also carry an erasure, so [[scala.reflect.api.Universe#TypeTag]] is also an [[scala.reflect.ErasureTag]], + * and [[scala.reflect.api.Universe#ConcreteTypeTag]] is additionally an [[scala.reflect.ArrayTag]] and a [[scala.reflect.ClassTag]] + * + * It is recommended to use the tag supertypes of to precisely express your intent, i.e.: + * use ArrayTag when you want to construct arrays, + * use ErasureTag when you need an erasure and don't mind it being generated for untagged abstract types, + * use ClassTag only when you need an erasure of a type that doesn't refer to untagged abstract types. + * + * === Splicing === + * + * Tags can be spliced, i.e. if compiler generates a tag for a type that contains references to tagged + * type parameters or abstract type members, it will retrieve the corresponding tag and embed it into the result. * An example that illustrates the TypeTag embedding, consider the following function: * * import reflect.mirror._ @@ -44,6 +62,54 @@ import language.implicitConversions * 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. + * + * === ErasureTag vs ClassTag and TypeTag vs ConcreteTypeTag === + * + * Be careful with ErasureTag and TypeTag, because they will reify types even if these types are abstract. + * This makes it easy to forget to tag one of the methods in the call chain and discover it much later in the runtime + * by getting cryptic errors far away from their source. For example, consider the following snippet: + * + * def bind[T: TypeTag](name: String, value: T): IR.Result = bind((name, value)) + * def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value) + * object NamedParam { + * implicit def namedValue[T: TypeTag](name: String, x: T): NamedParam = apply(name, x) + * def apply[T: TypeTag](name: String, x: T): NamedParam = new Typed[T](name, x) + * } + * + * This fragment of Scala REPL implementation defines a `bind` function that carries a named value along with its type + * into the heart of the REPL. Using a [[scala.reflect.api.Universe#TypeTag]] here is reasonable, because it is desirable + * to work with all types, even if they are type parameters or abstract type members. + * + * However if any of the three `TypeTag` context bounds is omitted, the resulting code will be incorrect, + * because the missing `TypeTag` will be transparently generated by the compiler, carrying meaningless information. + * Most likely, this problem will manifest itself elsewhere, making debugging complicated. + * If `TypeTag` context bounds were replaced with `ConcreteTypeTag`, then such errors would be reported statically. + * But in that case we wouldn't be able to use `bind` in arbitrary contexts. + * + * === Backward compatibility === + * + * 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.ConcreteTypeTag, + * Whereas scala.reflect.mirror.TypeTag is approximated by the previous notion of [[scala.reflect.OptManifest]]. + * + * In Scala 2.10, manifests are deprecated, so it's adviseable to migrate them to tags, + * because manifests might be removed in the next major release. + * + * In most cases it will be enough to replace ClassManifests with ClassTags and Manifests with ConcreteTypeTags, + * however there are a few caveats: + * + * 1) The notion of OptManifest is no longer supported. Tags can reify arbitrary types, so they are always available. + * // [Eugene] it might be useful, though, to guard against abstractness of the incoming type. + * + * 2) There's no equivalent for AnyValManifest. Consider comparing your tag with one of the core tags + * (defined in the corresponding companion objects) to find out whether it represents a primitive value class. + * + * 3) There's no replacement for factory methods defined in `ClassManifest` and `Manifest` companion objects. + * Consider assembling corresponding types using reflection API provided by Java (for classes) and Scala (for types). + * + * 4) Certain manifest functions (such as `<:<`, `>:>` and `typeArguments`) weren't included in the tag API. + * Consider using reflection API provided by Java (for classes) and Scala (for types) instead. */ trait TypeTags { self: Universe => @@ -56,25 +122,20 @@ trait TypeTags { self: Universe => * @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 isConcrete = tpe.isConcrete - def notConcrete = !isConcrete - def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe) - - override def toString = { - if (!self.isInstanceOf[DummyMirror]) { - var prefix = if (isConcrete) "ConcreteTypeTag" else "TypeTag" - if (prefix != this.productPrefix) prefix = "*" + prefix - prefix + "[" + tpe + "]" - } else { - this.productPrefix + "[?]" - } - } + trait TypeTag[T] extends ErasureTag[T] with Equals with Serializable { + + def tpe: Type + def sym: Symbol = tpe.typeSymbol + + def isConcrete: Boolean = tpe.isConcrete + def notConcrete: Boolean = !isConcrete + def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe, erasure) + + /** case class accessories */ + override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]] + override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.tpe == x.asInstanceOf[TypeTag[_]].tpe + override def hashCode = scala.runtime.ScalaRunTime.hash(tpe) + override def toString = if (!self.isInstanceOf[DummyMirror]) (if (isConcrete) "*ConcreteTypeTag" else "TypeTag") + "[" + tpe + "]" else "TypeTag[?]" } object TypeTag { @@ -95,8 +156,10 @@ trait TypeTags { self: Universe => val Null : TypeTag[scala.Null] = ConcreteTypeTag.Null val String : TypeTag[java.lang.String] = ConcreteTypeTag.String - def apply[T](tpe: Type): TypeTag[T] = - tpe match { + // todo. uncomment after I redo the starr + // def apply[T](tpe1: Type, erasure1: jClass[_]): TypeTag[T] = + def apply[T](tpe1: Type, erasure1: jClass[_]): TypeTag[T] = + tpe1 match { case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]] case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]] case CharTpe => TypeTag.Char.asInstanceOf[TypeTag[T]] @@ -113,8 +176,10 @@ trait TypeTags { self: Universe => 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) {} + case _ => new TypeTag[T]{ def tpe = tpe1; def erasure = erasure1 } } + + def unapply[T](ttag: TypeTag[T]): Option[Type] = Some(ttag.tpe) } /** @@ -124,36 +189,40 @@ trait TypeTags { self: Universe => * @see [[scala.reflect.api.TypeTags]] */ @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}") - abstract class ConcreteTypeTag[T](tpe: Type, val erasure: jClass[_]) extends TypeTag[T](tpe) { + trait ConcreteTypeTag[T] extends TypeTag[T] with ClassTag[T] with Equals with Serializable { if (!self.isInstanceOf[DummyMirror]) { -// 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 (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" + + /** case class accessories */ + override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]] // this is done on purpose. TypeTag(tpe) and ConcreteTypeTag(tpe) should be equal if tpe's are equal + override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.tpe == x.asInstanceOf[TypeTag[_]].tpe + override def hashCode = scala.runtime.ScalaRunTime.hash(tpe) + override def toString = if (!self.isInstanceOf[DummyMirror]) "ConcreteTypeTag[" + tpe + "]" else "ConcreteTypeTag[?]" } object ConcreteTypeTag { - val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe, ClassTag.Byte.erasure) { private def readResolve() = ConcreteTypeTag.Byte } - val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe, ClassTag.Short.erasure) { private def readResolve() = ConcreteTypeTag.Short } - val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe, ClassTag.Char.erasure) { private def readResolve() = ConcreteTypeTag.Char } - val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe, ClassTag.Int.erasure) { private def readResolve() = ConcreteTypeTag.Int } - val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe, ClassTag.Long.erasure) { private def readResolve() = ConcreteTypeTag.Long } - val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe, ClassTag.Float.erasure) { private def readResolve() = ConcreteTypeTag.Float } - val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe, ClassTag.Double.erasure) { private def readResolve() = ConcreteTypeTag.Double } - val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe, ClassTag.Boolean.erasure) { private def readResolve() = ConcreteTypeTag.Boolean } - val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe, ClassTag.Unit.erasure) { private def readResolve() = ConcreteTypeTag.Unit } - val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe, ClassTag.Any.erasure) { private def readResolve() = ConcreteTypeTag.Any } - val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe, ClassTag.Object.erasure) { private def readResolve() = ConcreteTypeTag.Object } - val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe, ClassTag.AnyVal.erasure) { private def readResolve() = ConcreteTypeTag.AnyVal } - val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe, ClassTag.AnyRef.erasure) { private def readResolve() = ConcreteTypeTag.AnyRef } - val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe, ClassTag.Nothing.erasure) { private def readResolve() = ConcreteTypeTag.Nothing } - val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe, ClassTag.Null.erasure) { private def readResolve() = ConcreteTypeTag.Null } - val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe, ClassTag.String.erasure) { private def readResolve() = ConcreteTypeTag.String } - - def apply[T](tpe: Type, erasure: jClass[_] = null): ConcreteTypeTag[T] = - tpe match { + val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte]{ def tpe = ByteTpe; def erasure = ClassTag.Byte.erasure; private def readResolve() = ConcreteTypeTag.Byte } + val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short]{ def tpe = ShortTpe; def erasure = ClassTag.Short.erasure; private def readResolve() = ConcreteTypeTag.Short } + val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char]{ def tpe = CharTpe; def erasure = ClassTag.Char.erasure; private def readResolve() = ConcreteTypeTag.Char } + val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int]{ def tpe = IntTpe; def erasure = ClassTag.Int.erasure; private def readResolve() = ConcreteTypeTag.Int } + val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long]{ def tpe = LongTpe; def erasure = ClassTag.Long.erasure; private def readResolve() = ConcreteTypeTag.Long } + val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float]{ def tpe = FloatTpe; def erasure = ClassTag.Float.erasure; private def readResolve() = ConcreteTypeTag.Float } + val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double]{ def tpe = DoubleTpe; def erasure = ClassTag.Double.erasure; private def readResolve() = ConcreteTypeTag.Double } + val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean]{ def tpe = BooleanTpe; def erasure = ClassTag.Boolean.erasure; private def readResolve() = ConcreteTypeTag.Boolean } + val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit]{ def tpe = UnitTpe; def erasure = ClassTag.Unit.erasure; private def readResolve() = ConcreteTypeTag.Unit } + val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any]{ def tpe = AnyTpe; def erasure = ClassTag.Any.erasure; private def readResolve() = ConcreteTypeTag.Any } + val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object]{ def tpe = ObjectTpe; def erasure = ClassTag.Object.erasure; private def readResolve() = ConcreteTypeTag.Object } + val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal]{ def tpe = AnyValTpe; def erasure = ClassTag.AnyVal.erasure; private def readResolve() = ConcreteTypeTag.AnyVal } + val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef]{ def tpe = AnyRefTpe; def erasure = ClassTag.AnyRef.erasure; private def readResolve() = ConcreteTypeTag.AnyRef } + val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing]{ def tpe = NothingTpe; def erasure = ClassTag.Nothing.erasure; private def readResolve() = ConcreteTypeTag.Nothing } + val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null]{ def tpe = NullTpe; def erasure = ClassTag.Null.erasure; private def readResolve() = ConcreteTypeTag.Null } + val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String]{ def tpe = StringTpe; def erasure = ClassTag.String.erasure; private def readResolve() = ConcreteTypeTag.String } + + // todo. uncomment after I redo the starr + // def apply[T](tpe1: Type, erasure1: jClass[_]): ConcreteTypeTag[T] = + def apply[T](tpe1: Type, erasure1: jClass[_] = null): ConcreteTypeTag[T] = + tpe1 match { case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]] case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]] case CharTpe => ConcreteTypeTag.Char.asInstanceOf[ConcreteTypeTag[T]] @@ -170,69 +239,10 @@ trait TypeTags { self: Universe => 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, erasure) {} + case _ => new ConcreteTypeTag[T]{ def tpe = tpe1; def erasure = erasure1 } } def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None - - implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[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.ConcreteTypeTag[T]) extends ClassTag.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.ConcreteTypeTag(targ)) - } - - /** Manifest for the singleton type `value.type'. */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = Manifest[T](???, value.getClass) - - /** 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) - */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def classType[T](clazz: Predef.Class[_]): Manifest[T] = Manifest[T](???, clazz) - - /** Manifest for the class type `clazz', where `clazz' is - * a top-level or static class and args are its type arguments. */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = Manifest[T](???, clazz) - - /** Manifest for the class type `clazz[args]', where `clazz' is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = Manifest[T](???, clazz) - - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = Manifest[Array[T]](???, arg.asInstanceOf[Manifest[T]].arrayManifest.erasure) - - /** 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. */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def abstractType[T](prefix: Manifest[_], name: String, clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = Manifest[T](???, clazz) - - /** Manifest for the unknown type `_ >: L <: U' in an existential. - */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = Manifest[T](???, upperBound.erasure) - - /** Manifest for the intersection type `parents_0 with ... with parents_n'. */ - @deprecated("Manifests aka type tags now support arbitrary types. Build a manifest directly from the type instead", "2.10.0") - def intersectionType[T](parents: Manifest[_]*): Manifest[T] = Manifest[T](???, parents.head.erasure) } // incantations for summoning diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala index 2b22839d39..2a7445c41c 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 @@ -65,25 +66,7 @@ abstract class Universe extends Symbols 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 - } - } + import scala.reflect.makro.internal._ + cc.materializeExpr(cc.prefix, expr) } } diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala index b304d98a5a..668d239087 100644 --- a/src/library/scala/reflect/makro/Context.scala +++ b/src/library/scala/reflect/makro/Context.scala @@ -34,28 +34,11 @@ trait Context extends Aliases object Context { def reify[T](cc: Context{ type PrefixType = Context })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = { import cc.mirror._ + import scala.reflect.makro.internal._ // [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 - } - } + cc.materializeExpr(prefix, expr) } } diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala index b9e82e0387..ae6669946c 100644 --- a/src/library/scala/reflect/makro/Reifiers.scala +++ b/src/library/scala/reflect/makro/Reifiers.scala @@ -46,11 +46,12 @@ 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, requireConcreteTypeTag: Boolean = false): Tree + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): Tree /** Given a type, generate a tree that when compiled and executed produces the erasure of the original type. + * If ``concrete'' is true, then this function will bail on types, whose erasure includes abstract types (like `ClassTag` does). */ - def reifyErasure(tpe: Type): Tree + def reifyErasure(tpe: Type, concrete: Boolean = true): Tree /** Undoes reification of a tree. * @@ -67,20 +68,10 @@ trait Reifiers { * 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)] - } +// made these guys non path-dependent, otherwise exception handling quickly becomes a mess - /** Wraps an unexpected error during reification - */ - type UnexpectedReificationError <: Throwable - val UnexpectedReificationError: UnexpectedReificationErrorExtractor - abstract class UnexpectedReificationErrorExtractor { - def unapply(error: UnexpectedReificationError): Option[(Position, String, Throwable)] - } -} +case class ReificationError(var pos: reflect.api.Position, val msg: String) extends Throwable(msg) + +case class UnexpectedReificationError(val pos: reflect.api.Position, val msg: String, val cause: Throwable = null) extends Throwable(msg) \ No newline at end of file diff --git a/src/library/scala/reflect/makro/internal/Utils.scala b/src/library/scala/reflect/makro/internal/Utils.scala index 604bba10b6..a8a2c98715 100644 --- a/src/library/scala/reflect/makro/internal/Utils.scala +++ b/src/library/scala/reflect/makro/internal/Utils.scala @@ -6,6 +6,20 @@ import language.experimental.macros /** 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 materializeArrayTag[T](u: Universe): ArrayTag[T] = macro materializeArrayTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeArrayTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[ArrayTag[T]] = + c.Expr[Nothing](c.materializeArrayTag(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 materializeErasureTag[T](u: Universe): ErasureTag[T] = macro materializeErasureTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeErasureTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[ErasureTag[T]] = + c.Expr[Nothing](c.materializeErasureTag(u.tree, implicitly[c.TypeTag[T]].tpe, concrete = false))(c.TypeTag.Nothing) + /** 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] @@ -18,14 +32,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, requireConcreteTypeTag = false))(c.TypeTag.Nothing) + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, concrete = 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) + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, concrete = 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 @@ -53,14 +67,27 @@ package internal { AnyValClass.asType -> newTermName("AnyVal"), AnyRefClass.asType -> newTermName("AnyRef"), NothingClass.asType -> newTermName("Nothing"), - NullClass.asType -> newTermName("Null")) + NullClass.asType -> newTermName("Null"), + StringClass.asType -> newTermName("String")) + + // todo. the following two methods won't be necessary once we implement implicit macro generators for tags + + def materializeArrayTag(prefix: Tree, tpe: Type): Tree = + materializeClassTag(prefix, tpe) + + def materializeErasureTag(prefix: Tree, tpe: Type, concrete: Boolean): Tree = + if (concrete) materializeClassTag(prefix, tpe) else materializeTypeTag(prefix, tpe, concrete = false) def materializeClassTag(prefix: Tree, tpe: Type): Tree = - materializeTag(prefix, tpe, ClassTagModule, c.reifyErasure(tpe)) + materializeTag(prefix, tpe, ClassTagModule, { + val erasure = c.reifyErasure(tpe, concrete = true) + val factory = TypeApply(Select(Ident(ClassTagModule), "apply"), List(TypeTree(tpe))) + Apply(factory, List(erasure)) + }) - def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { - val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule - materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)) + def materializeTypeTag(prefix: Tree, tpe: Type, concrete: Boolean): Tree = { + val tagModule = if (concrete) ConcreteTypeTagModule else TypeTagModule + materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, concrete = concrete)) } private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = { @@ -70,32 +97,30 @@ package internal { val ref = if (tagModule.owner.isPackageClass) Ident(tagModule) else Select(prefix, tagModule.name) Select(ref, coreTags(coreTpe)) case _ => - try materializer - 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 - } - } + translatingReificationErrors(materializer) } try c.typeCheck(result) - catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + catch { case terr @ c.TypeError(pos, msg) => failTag(terr) } + } + + def materializeExpr(prefix: Tree, expr: Tree): Tree = { + val result = translatingReificationErrors(c.reifyTree(prefix, expr)) + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => failExpr(terr) } + } + + private def translatingReificationErrors(materializer: => Tree): Tree = { + try materializer + catch { + case ReificationError(pos, msg) => + c.error(pos.asInstanceOf[c.Position], msg) // this cast is a very small price for the sanity of exception handling + EmptyTree + case UnexpectedReificationError(pos, err, cause) if cause != null => + throw cause + } } - private def fail(reason: Any): Nothing = { + private def failTag(reason: Any): Nothing = { val Apply(TypeApply(fun, List(tpeTree)), _) = c.macroApplication val tpe = tpeTree.tpe val PolyType(_, MethodType(_, tagTpe)) = fun.tpe @@ -104,5 +129,8 @@ package internal { 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)) } + + private def failExpr(reason: Any): Nothing = + c.abort(c.enclosingPosition, "Cannot materialize Expr because:\n" + reason) } } diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 0958f2ce9a..640cad6c21 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -65,8 +65,11 @@ package object reflect { @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.TypeTag.Nothing.tpe) + lazy val NoManifest = TypeTag.Nothing + // ArrayTag trait is defined separately from the mirror + // ErasureTag trait is defined separately from the mirror + // ConcreteErasureTag trait is defined separately from the mirror // ClassTag class is defined separately from the mirror type TypeTag[T] = scala.reflect.mirror.TypeTag[T] type ConcreteTypeTag[T] = scala.reflect.mirror.ConcreteTypeTag[T] diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index d2adc26d66..9d67644d61 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -47,12 +47,29 @@ object ScalaRunTime { names.toSet } + /** Return the class object representing an array with element class `clazz`. + */ + def arrayClass(clazz: Class[_]): Class[_] = { + // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 + if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] + else java.lang.reflect.Array.newInstance(clazz, 0).getClass + } + + /** Return the class object representing elements in arrays described by a given schematic. + */ + def arrayElementClass(schematic: Any): Class[_] = schematic match { + case cls: Class[_] => cls.getComponentType + case tag: ClassTag[_] => tag.erasure + case tag: ArrayTag[_] => tag.newArray(0).getClass.getComponentType + case _ => throw new UnsupportedOperationException("unsupported schematic %s (%s)".format(schematic, if (schematic == null) "null" else schematic.getClass)) + } + /** Return the class object representing an unboxed value type, * e.g. classOf[int], not classOf[java.lang.Integer]. The compiler * rewrites expressions like 5.getClass to come here. */ - def anyValClass[T <: AnyVal : ClassManifest](value: T): Class[T] = - classManifest[T].erasure.asInstanceOf[Class[T]] + def anyValClass[T <: AnyVal : ClassTag](value: T): Class[T] = + classTag[T].erasure.asInstanceOf[Class[T]] /** Retrieve generic array element */ def array_apply(xs: AnyRef, idx: Int): Any = xs match { diff --git a/src/library/scala/util/Marshal.scala b/src/library/scala/util/Marshal.scala index c2269cde45..6eb58e8570 100644 --- a/src/library/scala/util/Marshal.scala +++ b/src/library/scala/util/Marshal.scala @@ -11,19 +11,19 @@ package scala.util /** - * Marshalling of Scala objects using Scala manifests. + * Marshalling of Scala objects using Scala tags. * * @author Stephane Micheloud * @version 1.0 */ object Marshal { import java.io._ - import scala.reflect.ClassManifest + import scala.reflect.ClassTag - def dump[A](o: A)(implicit m: ClassManifest[A]): Array[Byte] = { + def dump[A](o: A)(implicit t: ClassTag[A]): Array[Byte] = { val ba = new ByteArrayOutputStream(512) val out = new ObjectOutputStream(ba) - out.writeObject(m) + out.writeObject(t) out.writeObject(o) out.close() ba.toByteArray() @@ -32,20 +32,20 @@ object Marshal { @throws(classOf[IOException]) @throws(classOf[ClassCastException]) @throws(classOf[ClassNotFoundException]) - def load[A](buffer: Array[Byte])(implicit expected: ClassManifest[A]): A = { + def load[A](buffer: Array[Byte])(implicit expected: ClassTag[A]): A = { val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) - val found = in.readObject.asInstanceOf[ClassManifest[_]] - // todo. [Eugene] needs review, since ClassManifests no longer capture typeArguments - if (found.tpe <:< expected.tpe) { - val o = in.readObject.asInstanceOf[A] - in.close() - o - } else { - in.close() - throw new ClassCastException("type mismatch;"+ - "\n found : "+found+ - "\n required: "+expected) + val found = in.readObject.asInstanceOf[ClassTag[_]] + try { + // [Eugene] needs review + // previously was: found <:< expected + found.erasure.asSubclass(expected.erasure) + in.readObject.asInstanceOf[A] + } catch { + case _: ClassCastException => + in.close() + throw new ClassCastException("type mismatch;"+ + "\n found : "+found+ + "\n required: "+expected) } } - -} +} \ No newline at end of file diff --git a/test/files/neg/classtags_contextbound_a.check b/test/files/neg/classtags_contextbound_a.check index f4b6ff5af1..a4fd37506d 100644 --- a/test/files/neg/classtags_contextbound_a.check +++ b/test/files/neg/classtags_contextbound_a.check @@ -1,4 +1,4 @@ -classtags_contextbound_a.scala:2: error: No ClassTag available for T +classtags_contextbound_a.scala:2: error: No ArrayTag available for T def foo[T] = Array[T]() ^ one error found diff --git a/test/files/neg/classtags_contextbound_c.check b/test/files/neg/classtags_contextbound_c.check index 54f630862a..a1c5eddfe1 100644 --- a/test/files/neg/classtags_contextbound_c.check +++ b/test/files/neg/classtags_contextbound_c.check @@ -1,4 +1,4 @@ -classtags_contextbound_c.scala:2: error: No ClassTag available for T +classtags_contextbound_c.scala:2: error: No ArrayTag available for T def mkArray[T] = Array[T]() ^ one error found diff --git a/test/files/neg/classtags_dont_use_typetags.check b/test/files/neg/classtags_dont_use_typetags.check new file mode 100644 index 0000000000..c7d2fba35b --- /dev/null +++ b/test/files/neg/classtags_dont_use_typetags.check @@ -0,0 +1,4 @@ +classtags_dont_use_typetags.scala:2: error: No ArrayTag available for T + def foo[T: TypeTag] = Array[T]() + ^ +one error found diff --git a/test/files/neg/classtags_dont_use_typetags.scala b/test/files/neg/classtags_dont_use_typetags.scala new file mode 100644 index 0000000000..0f675f71aa --- /dev/null +++ b/test/files/neg/classtags_dont_use_typetags.scala @@ -0,0 +1,3 @@ +object Test extends App { + def foo[T: TypeTag] = Array[T]() +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nontree.check b/test/files/neg/macro-invalidret-nontree.check index 7fcc396463..0b793cf421 100644 --- a/test/files/neg/macro-invalidret-nontree.check +++ b/test/files/neg/macro-invalidret-nontree.check @@ -1,7 +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 +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: Int does not conform to c.Expr[Any] + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidret-nonuniversetree.check b/test/files/neg/macro-invalidret-nonuniversetree.check index a97d6daaa9..4fc06b5ceb 100644 --- a/test/files/neg/macro-invalidret-nonuniversetree.check +++ b/test/files/neg/macro-invalidret-nonuniversetree.check @@ -1,7 +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 +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: reflect.mirror.Literal does not conform to c.Expr[Any] + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/t5689.check b/test/files/neg/t5689.check index f286d08cfa..6abc4c13f6 100644 --- a/test/files/neg/t5689.check +++ b/test/files/neg/t5689.check @@ -1,7 +1,7 @@ t5689.scala:4: error: macro implementation has wrong shape: required: (c: scala.reflect.makro.Context)(i: c.Expr[Double]): c.Expr[String] found : (c: scala.reflect.makro.Context)(i: c.Expr[Double]): c.Expr[Int] -type mismatch for return type : c.Expr[String] does not conform to c.Expr[Int] +type mismatch for return type: c.Expr[Int] does not conform to c.Expr[String] def returnsString(i: Double): String = macro returnsIntImpl ^ one error found diff --git a/test/files/run/arraytags_basic.check b/test/files/run/arraytags_basic.check new file mode 100644 index 0000000000..92816b91bd --- /dev/null +++ b/test/files/run/arraytags_basic.check @@ -0,0 +1,36 @@ +class [I +class [[I +class [[[I +class [Lscala.collection.immutable.List; +class [[Lscala.collection.immutable.List; +class [[[Lscala.collection.immutable.List; +class [Lscala.collection.immutable.List; +class [[Lscala.collection.immutable.List; +class [[[Lscala.collection.immutable.List; +class [Lscala.collection.immutable.Map; +class [[Lscala.collection.immutable.Map; +class [[[Lscala.collection.immutable.Map; +class [[I +class [[[I +class [[[[I +class [[Lscala.collection.immutable.List; +class [[[Lscala.collection.immutable.List; +class [[[[Lscala.collection.immutable.List; +class [[Lscala.collection.immutable.List; +class [[[Lscala.collection.immutable.List; +class [[[[Lscala.collection.immutable.List; +class [[Lscala.collection.immutable.Map; +class [[[Lscala.collection.immutable.Map; +class [[[[Lscala.collection.immutable.Map; +class [[[I +class [[[[I +class [[[[[I +class [[[Lscala.collection.immutable.List; +class [[[[Lscala.collection.immutable.List; +class [[[[[Lscala.collection.immutable.List; +class [[[Lscala.collection.immutable.List; +class [[[[Lscala.collection.immutable.List; +class [[[[[Lscala.collection.immutable.List; +class [[[Lscala.collection.immutable.Map; +class [[[[Lscala.collection.immutable.Map; +class [[[[[Lscala.collection.immutable.Map; diff --git a/test/files/run/arraytags_basic.scala b/test/files/run/arraytags_basic.scala new file mode 100644 index 0000000000..edc20e9bc1 --- /dev/null +++ b/test/files/run/arraytags_basic.scala @@ -0,0 +1,22 @@ +object Test extends App { + def test[T: ArrayTag] = { + println(implicitly[ArrayTag[T]].newArray(10).getClass) + println(implicitly[ArrayTag[T]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[T]]].wrap.newArray(10).getClass) + } + + test[Int] + test[List[Int]] + test[List[String]] + test[Map[Int, String]] + + test[Array[Int]] + test[Array[List[Int]]] + test[Array[List[String]]] + test[Array[Map[Int, String]]] + + test[Array[Array[Int]]] + test[Array[Array[List[Int]]]] + test[Array[Array[List[String]]]] + test[Array[Array[Map[Int, String]]]] +} \ No newline at end of file diff --git a/test/files/run/arraytags_core.check b/test/files/run/arraytags_core.check new file mode 100644 index 0000000000..82ed84ad78 --- /dev/null +++ b/test/files/run/arraytags_core.check @@ -0,0 +1,48 @@ +class [B +class [[B +class [[[B +class [S +class [[S +class [[[S +class [C +class [[C +class [[[C +class [I +class [[I +class [[[I +class [J +class [[J +class [[[J +class [F +class [[F +class [[[F +class [D +class [[D +class [[[D +class [Z +class [[Z +class [[[Z +class [Lscala.runtime.BoxedUnit; +class [[Lscala.runtime.BoxedUnit; +class [[[Lscala.runtime.BoxedUnit; +class [Ljava.lang.Object; +class [[Ljava.lang.Object; +class [[[Ljava.lang.Object; +class [Ljava.lang.Object; +class [[Ljava.lang.Object; +class [[[Ljava.lang.Object; +class [Ljava.lang.Object; +class [[Ljava.lang.Object; +class [[[Ljava.lang.Object; +class [Ljava.lang.Object; +class [[Ljava.lang.Object; +class [[[Ljava.lang.Object; +class [Lscala.runtime.Null$; +class [[Lscala.runtime.Null$; +class [[[Lscala.runtime.Null$; +class [Lscala.runtime.Nothing$; +class [[Lscala.runtime.Nothing$; +class [[[Lscala.runtime.Nothing$; +class [Ljava.lang.String; +class [[Ljava.lang.String; +class [[[Ljava.lang.String; diff --git a/test/files/run/arraytags_core.scala b/test/files/run/arraytags_core.scala new file mode 100644 index 0000000000..a59ae24f30 --- /dev/null +++ b/test/files/run/arraytags_core.scala @@ -0,0 +1,50 @@ +object Test extends App { + println(implicitly[ArrayTag[Byte]].newArray(10).getClass) + println(implicitly[ArrayTag[Byte]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Byte]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Short]].newArray(10).getClass) + println(implicitly[ArrayTag[Short]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Short]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Char]].newArray(10).getClass) + println(implicitly[ArrayTag[Char]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Char]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Int]].newArray(10).getClass) + println(implicitly[ArrayTag[Int]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Int]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Long]].newArray(10).getClass) + println(implicitly[ArrayTag[Long]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Long]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Float]].newArray(10).getClass) + println(implicitly[ArrayTag[Float]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Float]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Double]].newArray(10).getClass) + println(implicitly[ArrayTag[Double]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Double]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Boolean]].newArray(10).getClass) + println(implicitly[ArrayTag[Boolean]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Boolean]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Unit]].newArray(10).getClass) + println(implicitly[ArrayTag[Unit]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Unit]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Any]].newArray(10).getClass) + println(implicitly[ArrayTag[Any]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Any]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Object]].newArray(10).getClass) + println(implicitly[ArrayTag[Object]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Object]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[AnyVal]].newArray(10).getClass) + println(implicitly[ArrayTag[AnyVal]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[AnyVal]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[AnyRef]].newArray(10).getClass) + println(implicitly[ArrayTag[AnyRef]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[AnyRef]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Null]].newArray(10).getClass) + println(implicitly[ArrayTag[Null]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Null]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Nothing]].newArray(10).getClass) + println(implicitly[ArrayTag[Nothing]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[Nothing]]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[String]].newArray(10).getClass) + println(implicitly[ArrayTag[String]].wrap.newArray(10).getClass) + println(implicitly[ArrayTag[Array[String]]].wrap.newArray(10).getClass) +} \ No newline at end of file diff --git a/test/files/run/arraytags_usage.check b/test/files/run/arraytags_usage.check new file mode 100644 index 0000000000..b1d02b7bfe --- /dev/null +++ b/test/files/run/arraytags_usage.check @@ -0,0 +1,3 @@ +class [I +class [I +class [I diff --git a/test/files/run/arraytags_usage.scala b/test/files/run/arraytags_usage.scala new file mode 100644 index 0000000000..60b0a8f218 --- /dev/null +++ b/test/files/run/arraytags_usage.scala @@ -0,0 +1,15 @@ +object Test extends App { + def foo[T] = { + class MyArrayTag extends ArrayTag[T] { + def wrap: ArrayTag[Array[T]] = ??? + def newArray(len: Int): Array[T] = new Array[Int](len).asInstanceOf[Array[T]] + } + + implicit val tag = new MyArrayTag() + println(Array[T]().getClass) + } + + foo[Int] + foo[String] + foo[Array[String]] +} \ No newline at end of file diff --git a/test/files/run/classtags_core.check b/test/files/run/classtags_core.check index ce5a893b08..ebccfcd54c 100644 --- a/test/files/run/classtags_core.check +++ b/test/files/run/classtags_core.check @@ -1,30 +1,32 @@ -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) +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 scala.runtime.Null$] +true +ClassTag[class scala.runtime.Nothing$] +true +ClassTag[class java.lang.String] diff --git a/test/files/run/classtags_core.scala b/test/files/run/classtags_core.scala index 45c54b1fe0..9f2031377d 100644 --- a/test/files/run/classtags_core.scala +++ b/test/files/run/classtags_core.scala @@ -29,4 +29,6 @@ object Test extends App { println(implicitly[ClassTag[Null]]) println(implicitly[ClassTag[Nothing]] eq ClassTag.Nothing) println(implicitly[ClassTag[Nothing]]) + println(implicitly[ClassTag[String]] eq ClassTag.String) + println(implicitly[ClassTag[String]]) } \ No newline at end of file diff --git a/test/files/run/classtags_multi.check b/test/files/run/classtags_multi.check new file mode 100644 index 0000000000..3a7f16c3a0 --- /dev/null +++ b/test/files/run/classtags_multi.check @@ -0,0 +1,5 @@ +ClassTag[int] +ClassTag[class [I] +ClassTag[class [[I] +ClassTag[class [[[I] +ClassTag[class [[[[I] diff --git a/test/files/run/classtags_multi.scala b/test/files/run/classtags_multi.scala new file mode 100644 index 0000000000..5aafb55223 --- /dev/null +++ b/test/files/run/classtags_multi.scala @@ -0,0 +1,7 @@ +object Test extends App { + println(classTag[Int]) + println(classTag[Array[Int]]) + println(classTag[Array[Array[Int]]]) + println(classTag[Array[Array[Array[Int]]]]) + println(classTag[Array[Array[Array[Array[Int]]]]]) +} \ No newline at end of file diff --git a/test/files/run/classtags_use_concretetypetags.scala b/test/files/run/classtags_use_concretetypetags.scala new file mode 100644 index 0000000000..57e7085cec --- /dev/null +++ b/test/files/run/classtags_use_concretetypetags.scala @@ -0,0 +1,3 @@ +object Test extends App { + def foo[T: ConcreteTypeTag] = Array[T]() +} \ No newline at end of file diff --git a/test/files/run/concretetypetags_core.check b/test/files/run/concretetypetags_core.check new file mode 100644 index 0000000000..f124aa6a35 --- /dev/null +++ b/test/files/run/concretetypetags_core.check @@ -0,0 +1,32 @@ +true +ConcreteTypeTag[Byte] +true +ConcreteTypeTag[Short] +true +ConcreteTypeTag[Char] +true +ConcreteTypeTag[Int] +true +ConcreteTypeTag[Long] +true +ConcreteTypeTag[Float] +true +ConcreteTypeTag[Double] +true +ConcreteTypeTag[Boolean] +true +ConcreteTypeTag[Unit] +true +ConcreteTypeTag[Any] +true +ConcreteTypeTag[Object] +true +ConcreteTypeTag[AnyVal] +true +ConcreteTypeTag[AnyRef] +true +ConcreteTypeTag[Null] +true +ConcreteTypeTag[Nothing] +true +ConcreteTypeTag[String] diff --git a/test/files/run/concretetypetags_core.scala b/test/files/run/concretetypetags_core.scala new file mode 100644 index 0000000000..b6cfea3895 --- /dev/null +++ b/test/files/run/concretetypetags_core.scala @@ -0,0 +1,34 @@ +object Test extends App { + 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]]) + println(implicitly[ConcreteTypeTag[String]] eq ConcreteTypeTag.String) + println(implicitly[ConcreteTypeTag[String]]) +} \ No newline at end of file diff --git a/test/files/run/concretetypetags_multi.check b/test/files/run/concretetypetags_multi.check new file mode 100644 index 0000000000..613106985c --- /dev/null +++ b/test/files/run/concretetypetags_multi.check @@ -0,0 +1,5 @@ +ConcreteTypeTag[Int] +ConcreteTypeTag[Array[Int]] +ConcreteTypeTag[Array[Array[Int]]] +ConcreteTypeTag[Array[Array[Array[Int]]]] +ConcreteTypeTag[Array[Array[Array[Array[Int]]]]] diff --git a/test/files/run/concretetypetags_multi.scala b/test/files/run/concretetypetags_multi.scala new file mode 100644 index 0000000000..7e19d7db34 --- /dev/null +++ b/test/files/run/concretetypetags_multi.scala @@ -0,0 +1,7 @@ +object Test extends App { + println(concreteTypeTag[Int]) + println(concreteTypeTag[Array[Int]]) + println(concreteTypeTag[Array[Array[Int]]]) + println(concreteTypeTag[Array[Array[Array[Int]]]]) + println(concreteTypeTag[Array[Array[Array[Array[Int]]]]]) +} \ No newline at end of file diff --git a/test/files/run/erasuretags_abstract.check b/test/files/run/erasuretags_abstract.check new file mode 100644 index 0000000000..17e7204664 --- /dev/null +++ b/test/files/run/erasuretags_abstract.check @@ -0,0 +1,4 @@ +class java.lang.Object +class java.lang.Object +class java.lang.Object +int diff --git a/test/files/run/erasuretags_abstract.scala b/test/files/run/erasuretags_abstract.scala new file mode 100644 index 0000000000..8e4ad0d090 --- /dev/null +++ b/test/files/run/erasuretags_abstract.scala @@ -0,0 +1,9 @@ +object Test extends App { + def foo1[T] = erasureTag[T] + println(foo1[Int].erasure) + println(foo1[String].erasure) + println(foo1[Array[Int]].erasure) + + def foo2[T <: Int] = erasureTag[T] + println(foo2[Int].erasure) +} \ No newline at end of file diff --git a/test/files/run/erasuretags_basic.check b/test/files/run/erasuretags_basic.check new file mode 100644 index 0000000000..c02a4d32af --- /dev/null +++ b/test/files/run/erasuretags_basic.check @@ -0,0 +1,24 @@ +int +class [I +class scala.collection.immutable.List +class [Lscala.collection.immutable.List; +class scala.collection.immutable.List +class [Lscala.collection.immutable.List; +interface scala.collection.immutable.Map +class [Lscala.collection.immutable.Map; +class [I +class [[I +class [Lscala.collection.immutable.List; +class [[Lscala.collection.immutable.List; +class [Lscala.collection.immutable.List; +class [[Lscala.collection.immutable.List; +class [Lscala.collection.immutable.Map; +class [[Lscala.collection.immutable.Map; +class [[I +class [[[I +class [[Lscala.collection.immutable.List; +class [[[Lscala.collection.immutable.List; +class [[Lscala.collection.immutable.List; +class [[[Lscala.collection.immutable.List; +class [[Lscala.collection.immutable.Map; +class [[[Lscala.collection.immutable.Map; diff --git a/test/files/run/erasuretags_basic.scala b/test/files/run/erasuretags_basic.scala new file mode 100644 index 0000000000..d894fdf2e9 --- /dev/null +++ b/test/files/run/erasuretags_basic.scala @@ -0,0 +1,21 @@ +object Test extends App { + def test[T: ErasureTag] = { + println(implicitly[ErasureTag[T]].erasure) + println(implicitly[ErasureTag[Array[T]]].erasure) + } + + test[Int] + test[List[Int]] + test[List[String]] + test[Map[Int, String]] + + test[Array[Int]] + test[Array[List[Int]]] + test[Array[List[String]]] + test[Array[Map[Int, String]]] + + test[Array[Array[Int]]] + test[Array[Array[List[Int]]]] + test[Array[Array[List[String]]]] + test[Array[Array[Map[Int, String]]]] +} \ No newline at end of file diff --git a/test/files/run/erasuretags_core.check b/test/files/run/erasuretags_core.check new file mode 100644 index 0000000000..2c544678d1 --- /dev/null +++ b/test/files/run/erasuretags_core.check @@ -0,0 +1,32 @@ +byte +class [B +short +class [S +char +class [C +int +class [I +long +class [J +float +class [F +double +class [D +boolean +class [Z +void +class [Lscala.runtime.BoxedUnit; +class java.lang.Object +class [Ljava.lang.Object; +class java.lang.Object +class [Ljava.lang.Object; +class java.lang.Object +class [Ljava.lang.Object; +class java.lang.Object +class [Ljava.lang.Object; +class scala.runtime.Null$ +class [Lscala.runtime.Null$; +class scala.runtime.Nothing$ +class [Lscala.runtime.Nothing$; +class java.lang.String +class [Ljava.lang.String; diff --git a/test/files/run/erasuretags_core.scala b/test/files/run/erasuretags_core.scala new file mode 100644 index 0000000000..5ed06dcd31 --- /dev/null +++ b/test/files/run/erasuretags_core.scala @@ -0,0 +1,34 @@ +object Test extends App { + println(implicitly[ErasureTag[Byte]].erasure) + println(implicitly[ErasureTag[Array[Byte]]].erasure) + println(implicitly[ErasureTag[Short]].erasure) + println(implicitly[ErasureTag[Array[Short]]].erasure) + println(implicitly[ErasureTag[Char]].erasure) + println(implicitly[ErasureTag[Array[Char]]].erasure) + println(implicitly[ErasureTag[Int]].erasure) + println(implicitly[ErasureTag[Array[Int]]].erasure) + println(implicitly[ErasureTag[Long]].erasure) + println(implicitly[ErasureTag[Array[Long]]].erasure) + println(implicitly[ErasureTag[Float]].erasure) + println(implicitly[ErasureTag[Array[Float]]].erasure) + println(implicitly[ErasureTag[Double]].erasure) + println(implicitly[ErasureTag[Array[Double]]].erasure) + println(implicitly[ErasureTag[Boolean]].erasure) + println(implicitly[ErasureTag[Array[Boolean]]].erasure) + println(implicitly[ErasureTag[Unit]].erasure) + println(implicitly[ErasureTag[Array[Unit]]].erasure) + println(implicitly[ErasureTag[Any]].erasure) + println(implicitly[ErasureTag[Array[Any]]].erasure) + println(implicitly[ErasureTag[Object]].erasure) + println(implicitly[ErasureTag[Array[Object]]].erasure) + println(implicitly[ErasureTag[AnyVal]].erasure) + println(implicitly[ErasureTag[Array[AnyVal]]].erasure) + println(implicitly[ErasureTag[AnyRef]].erasure) + println(implicitly[ErasureTag[Array[AnyRef]]].erasure) + println(implicitly[ErasureTag[Null]].erasure) + println(implicitly[ErasureTag[Array[Null]]].erasure) + println(implicitly[ErasureTag[Nothing]].erasure) + println(implicitly[ErasureTag[Array[Nothing]]].erasure) + println(implicitly[ErasureTag[String]].erasure) + println(implicitly[ErasureTag[Array[String]]].erasure) +} \ No newline at end of file diff --git a/test/files/run/erasuretags_usage.scala b/test/files/run/erasuretags_usage.scala new file mode 100644 index 0000000000..16e53af071 --- /dev/null +++ b/test/files/run/erasuretags_usage.scala @@ -0,0 +1,12 @@ +object Test extends App { + def foo[T] = { + class MyErasureTag(_erasure: Class[_]) extends ErasureTag[T] { + def erasure: Class[T] = _erasure.asInstanceOf[Class[T]] + } + + implicit val tag = new MyErasureTag(classOf[Int]) + println(typeTag[T]) + println(typeTag[T].tpe) + println(typeTag[T].erasure) + } +} \ No newline at end of file diff --git a/test/files/run/groundtypetags_core.check b/test/files/run/groundtypetags_core.check deleted file mode 100644 index 62fcb481ae..0000000000 --- a/test/files/run/groundtypetags_core.check +++ /dev/null @@ -1,30 +0,0 @@ -true -ConcreteTypeTag[Byte] -true -ConcreteTypeTag[Short] -true -ConcreteTypeTag[Char] -true -ConcreteTypeTag[Int] -true -ConcreteTypeTag[Long] -true -ConcreteTypeTag[Float] -true -ConcreteTypeTag[Double] -true -ConcreteTypeTag[Boolean] -true -ConcreteTypeTag[Unit] -true -ConcreteTypeTag[Any] -true -ConcreteTypeTag[Object] -true -ConcreteTypeTag[AnyVal] -true -ConcreteTypeTag[AnyRef] -true -ConcreteTypeTag[Null] -true -ConcreteTypeTag[Nothing] diff --git a/test/files/run/groundtypetags_core.scala b/test/files/run/groundtypetags_core.scala deleted file mode 100644 index 8b81a0c795..0000000000 --- a/test/files/run/groundtypetags_core.scala +++ /dev/null @@ -1,32 +0,0 @@ -object Test extends App { - 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-typecheck-macrosdisabled/Impls_Macros_1.scala b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala index a1f124f790..3de9367994 100644 --- a/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala +++ b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala @@ -4,13 +4,6 @@ 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) - //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) diff --git a/test/files/run/macro-typecheck-macrosdisabled2.check b/test/files/run/macro-typecheck-macrosdisabled2.check new file mode 100644 index 0000000000..02da6ad0c7 --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled2.check @@ -0,0 +1,5 @@ +{ + val $mr: reflect.mirror.type = scala.reflect.`package`.mirror; + $mr.Expr.apply[Array[Int]]($mr.Apply.apply($mr.Select.apply($mr.Select.apply($mr.Ident($mr.staticModule("scala")), $mr.newTermName("Array")), $mr.newTermName("apply")), scala.collection.immutable.List.apply[$mr.Literal]($mr.Literal.apply($mr.Constant.apply(2)))))($mr.ConcreteTypeTag.apply[Array[Int]]($mr.TypeRef.apply($mr.thisModuleType("scala"), $mr.staticClass("scala.Array"), scala.collection.immutable.List.apply[$mr.Type]($mr.staticClass("scala.Int").asTypeConstructor)), ScalaRunTime.this.arrayClass(classOf[scala.Int]))) +} +mr.reify[Array[Int]](scala.Array.apply(2)) diff --git a/test/files/run/macro-typecheck-macrosdisabled2.flags b/test/files/run/macro-typecheck-macrosdisabled2.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled2.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala b/test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala new file mode 100644 index 0000000000..1b840a6204 --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala @@ -0,0 +1,29 @@ +import scala.reflect.makro.Context + +object Macros { + def impl_with_macros_enabled(c: Context) = { + import c.mirror._ + + val mr = Select(Select(Select(Ident(newTermName("scala")), newTermName("reflect")), newTermName("package")), newTermName("mirror")) + val tree1 = Apply(Select(mr, newTermName("reify")), List(Apply(Select(Ident(newTermName("scala")), newTermName("Array")), 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) + + val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Apply(Select(Ident(newTermName("scala")), newTermName("Array")), 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-macrosdisabled2/Test_2.scala b/test/files/run/macro-typecheck-macrosdisabled2/Test_2.scala new file mode 100644 index 0000000000..bdba39195b --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled2/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/toolbox_typecheck_macrosdisabled2.check b/test/files/run/toolbox_typecheck_macrosdisabled2.check new file mode 100644 index 0000000000..271139b031 --- /dev/null +++ b/test/files/run/toolbox_typecheck_macrosdisabled2.check @@ -0,0 +1,5 @@ +{ + val $mr: mr.type = mr; + $mr.Expr.apply[Array[Int]]($mr.Apply.apply($mr.Select.apply($mr.Select.apply($mr.Ident($mr.staticModule("scala")), $mr.newTermName("Array")), $mr.newTermName("apply")), scala.collection.immutable.List.apply[$mr.Literal]($mr.Literal.apply($mr.Constant.apply(2)))))($mr.ConcreteTypeTag.apply[Array[Int]]($mr.TypeRef.apply($mr.thisModuleType("scala"), $mr.staticClass("scala.Array"), scala.collection.immutable.List.apply[$mr.Type]($mr.staticClass("scala.Int").asTypeConstructor)), ScalaRunTime.this.arrayClass(classOf[scala.Int]))) +} +mr.reify[Array[Int]](scala.Array.apply(2)) diff --git a/test/files/run/toolbox_typecheck_macrosdisabled2.scala b/test/files/run/toolbox_typecheck_macrosdisabled2.scala new file mode 100644 index 0000000000..b4c76d0600 --- /dev/null +++ b/test/files/run/toolbox_typecheck_macrosdisabled2.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) + + val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Apply(Select(Ident(newTermName("scala")), newTermName("Array")), List(Literal(Constant(2)))))) + val ttree1 = toolbox.typeCheck(tree1, withMacrosDisabled = false) + println(ttree1) + + val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Apply(Select(Ident(newTermName("scala")), newTermName("Array")), List(Literal(Constant(2)))))) + val ttree2 = toolbox.typeCheck(tree2, withMacrosDisabled = true) + println(ttree2) +} diff --git a/test/files/run/typetags_core.check b/test/files/run/typetags_core.check index 62fcb481ae..f124aa6a35 100644 --- a/test/files/run/typetags_core.check +++ b/test/files/run/typetags_core.check @@ -1,30 +1,32 @@ -true -ConcreteTypeTag[Byte] -true -ConcreteTypeTag[Short] -true -ConcreteTypeTag[Char] -true -ConcreteTypeTag[Int] -true -ConcreteTypeTag[Long] -true -ConcreteTypeTag[Float] -true -ConcreteTypeTag[Double] -true -ConcreteTypeTag[Boolean] -true -ConcreteTypeTag[Unit] -true -ConcreteTypeTag[Any] -true -ConcreteTypeTag[Object] -true -ConcreteTypeTag[AnyVal] -true -ConcreteTypeTag[AnyRef] -true -ConcreteTypeTag[Null] -true -ConcreteTypeTag[Nothing] +true +ConcreteTypeTag[Byte] +true +ConcreteTypeTag[Short] +true +ConcreteTypeTag[Char] +true +ConcreteTypeTag[Int] +true +ConcreteTypeTag[Long] +true +ConcreteTypeTag[Float] +true +ConcreteTypeTag[Double] +true +ConcreteTypeTag[Boolean] +true +ConcreteTypeTag[Unit] +true +ConcreteTypeTag[Any] +true +ConcreteTypeTag[Object] +true +ConcreteTypeTag[AnyVal] +true +ConcreteTypeTag[AnyRef] +true +ConcreteTypeTag[Null] +true +ConcreteTypeTag[Nothing] +true +ConcreteTypeTag[String] diff --git a/test/files/run/typetags_core.scala b/test/files/run/typetags_core.scala index 883c54b9a8..7d6be16379 100644 --- a/test/files/run/typetags_core.scala +++ b/test/files/run/typetags_core.scala @@ -29,4 +29,6 @@ object Test extends App { println(implicitly[TypeTag[Null]]) println(implicitly[TypeTag[Nothing]] eq TypeTag.Nothing) println(implicitly[TypeTag[Nothing]]) + println(implicitly[TypeTag[String]] eq TypeTag.String) + println(implicitly[TypeTag[String]]) } \ No newline at end of file diff --git a/test/files/run/typetags_multi.check b/test/files/run/typetags_multi.check new file mode 100644 index 0000000000..613106985c --- /dev/null +++ b/test/files/run/typetags_multi.check @@ -0,0 +1,5 @@ +ConcreteTypeTag[Int] +ConcreteTypeTag[Array[Int]] +ConcreteTypeTag[Array[Array[Int]]] +ConcreteTypeTag[Array[Array[Array[Int]]]] +ConcreteTypeTag[Array[Array[Array[Array[Int]]]]] diff --git a/test/files/run/typetags_multi.scala b/test/files/run/typetags_multi.scala new file mode 100644 index 0000000000..868edc2b2a --- /dev/null +++ b/test/files/run/typetags_multi.scala @@ -0,0 +1,7 @@ +object Test extends App { + println(typeTag[Int]) + println(typeTag[Array[Int]]) + println(typeTag[Array[Array[Int]]]) + println(typeTag[Array[Array[Array[Int]]]]) + println(typeTag[Array[Array[Array[Array[Int]]]]]) +} \ No newline at end of file diff --git a/test/files/speclib/instrumented.jar.desired.sha1 b/test/files/speclib/instrumented.jar.desired.sha1 index 2d4cd04a92..a7da67429e 100644 --- a/test/files/speclib/instrumented.jar.desired.sha1 +++ b/test/files/speclib/instrumented.jar.desired.sha1 @@ -1 +1 @@ -d83c6bf3765ab1378943020a8d9cda8851604ffa ?instrumented.jar +15f200d9f0f25f9fd871bad2ebb4ba5cfc671db4 ?instrumented.jar diff --git a/test/instrumented/boxes.patch b/test/instrumented/boxes.patch index 11c5b37aa8..6c5ff23f9f 100644 --- a/test/instrumented/boxes.patch +++ b/test/instrumented/boxes.patch @@ -1,7 +1,8 @@ -9a10,11 +9c9 +< +--- > /* INSTRUMENTED VERSION */ -> -50a53,61 +51a52,59 > public static int booleanBoxCount = 0; > public static int characterBoxCount = 0; > public static int byteBoxCount = 0; @@ -10,20 +11,19 @@ > public static int longBoxCount = 0; > public static int floatBoxCount = 0; > public static int doubleBoxCount = 0; -> -51a63 -> booleanBoxCount++; -55a68 -> characterBoxCount++; -59a73 -> byteBoxCount++; -63a78 -> shortBoxCount++; -67a83 -> integerBoxCount++; -71a88 -> longBoxCount++; -75a93 -> floatBoxCount++; -79a98 -> doubleBoxCount++; +53a62 +> booleanBoxCount += 1; +57a67 +> characterBoxCount += 1; +61a72 +> byteBoxCount += 1; +65a77 +> shortBoxCount += 1; +69a82 +> integerBoxCount += 1; +73a87 +> longBoxCount += 1; +77a92 +> floatBoxCount += 1; +83a99 +> doubleBoxCount += 1; diff --git a/test/instrumented/library/scala/runtime/BoxesRunTime.java b/test/instrumented/library/scala/runtime/BoxesRunTime.java index f06f86f2f2..172ed8ee14 100644 --- a/test/instrumented/library/scala/runtime/BoxesRunTime.java +++ b/test/instrumented/library/scala/runtime/BoxesRunTime.java @@ -6,10 +6,8 @@ ** |/ ** \* */ - /* INSTRUMENTED VERSION */ - package scala.runtime; import java.io.*; @@ -33,14 +31,16 @@ public final class BoxesRunTime { private static final int CHAR = 0, BYTE = 1, SHORT = 2, INT = 3, LONG = 4, FLOAT = 5, DOUBLE = 6, OTHER = 7; + /** We don't need to return BYTE and SHORT, as everything which might + * care widens to INT. + */ private static int typeCode(Object a) { if (a instanceof java.lang.Integer) return INT; - if (a instanceof java.lang.Byte) return BYTE; - if (a instanceof java.lang.Character) return CHAR; - if (a instanceof java.lang.Long) return LONG; if (a instanceof java.lang.Double) return DOUBLE; - if (a instanceof java.lang.Short) return SHORT; + if (a instanceof java.lang.Long) return LONG; + if (a instanceof java.lang.Character) return CHAR; if (a instanceof java.lang.Float) return FLOAT; + if ((a instanceof java.lang.Byte) || (a instanceof java.lang.Short)) return INT; return OTHER; } @@ -49,7 +49,6 @@ public final class BoxesRunTime } /* BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING */ - public static int booleanBoxCount = 0; public static int characterBoxCount = 0; public static int byteBoxCount = 0; @@ -58,46 +57,46 @@ public final class BoxesRunTime public static int longBoxCount = 0; public static int floatBoxCount = 0; public static int doubleBoxCount = 0; - + public static java.lang.Boolean boxToBoolean(boolean b) { - booleanBoxCount++; + booleanBoxCount += 1; return java.lang.Boolean.valueOf(b); } public static java.lang.Character boxToCharacter(char c) { - characterBoxCount++; + characterBoxCount += 1; return java.lang.Character.valueOf(c); } public static java.lang.Byte boxToByte(byte b) { - byteBoxCount++; + byteBoxCount += 1; return java.lang.Byte.valueOf(b); } public static java.lang.Short boxToShort(short s) { - shortBoxCount++; + shortBoxCount += 1; return java.lang.Short.valueOf(s); } public static java.lang.Integer boxToInteger(int i) { - integerBoxCount++; + integerBoxCount += 1; return java.lang.Integer.valueOf(i); } public static java.lang.Long boxToLong(long l) { - longBoxCount++; + longBoxCount += 1; return java.lang.Long.valueOf(l); } public static java.lang.Float boxToFloat(float f) { - floatBoxCount++; + floatBoxCount += 1; return java.lang.Float.valueOf(f); } public static java.lang.Double boxToDouble(double d) { - doubleBoxCount++; // System.out.println("box " + d); // (new Throwable()).printStackTrace(); + doubleBoxCount += 1; return java.lang.Double.valueOf(d); } @@ -138,15 +137,6 @@ public final class BoxesRunTime /* COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON */ - private static int eqTypeCode(Number a) { - if ((a instanceof java.lang.Integer) || (a instanceof java.lang.Byte)) return INT; - if (a instanceof java.lang.Long) return LONG; - if (a instanceof java.lang.Double) return DOUBLE; - if (a instanceof java.lang.Short) return INT; - if (a instanceof java.lang.Float) return FLOAT; - return OTHER; - } - public static boolean equals(Object x, Object y) { if (x == y) return true; return equals2(x, y); @@ -178,8 +168,8 @@ public final class BoxesRunTime } public static boolean equalsNumNum(java.lang.Number xn, java.lang.Number yn) { - int xcode = eqTypeCode(xn); - int ycode = eqTypeCode(yn); + int xcode = typeCode(xn); + int ycode = typeCode(yn); switch (ycode > xcode ? ycode : xcode) { case INT: return xn.intValue() == yn.intValue(); @@ -211,8 +201,11 @@ public final class BoxesRunTime } private static boolean equalsNumChar(java.lang.Number xn, java.lang.Character yc) { + if (yc == null) + return xn == null; + char ch = yc.charValue(); - switch (eqTypeCode(xn)) { + switch (typeCode(xn)) { case INT: return xn.intValue() == ch; case LONG: @@ -222,9 +215,6 @@ public final class BoxesRunTime case DOUBLE: return xn.doubleValue() == ch; default: - if (xn == null) - return yc == null; - return xn.equals(yc); } } @@ -290,6 +280,31 @@ public final class BoxesRunTime else return a.hashCode(); } + private static int unboxCharOrInt(Object arg1, int code) { + if (code == CHAR) + return ((java.lang.Character) arg1).charValue(); + else + return ((java.lang.Number) arg1).intValue(); + } + private static long unboxCharOrLong(Object arg1, int code) { + if (code == CHAR) + return ((java.lang.Character) arg1).charValue(); + else + return ((java.lang.Number) arg1).longValue(); + } + private static float unboxCharOrFloat(Object arg1, int code) { + if (code == CHAR) + return ((java.lang.Character) arg1).charValue(); + else + return ((java.lang.Number) arg1).floatValue(); + } + private static double unboxCharOrDouble(Object arg1, int code) { + if (code == CHAR) + return ((java.lang.Character) arg1).charValue(); + else + return ((java.lang.Number) arg1).doubleValue(); + } + /* OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS */ /** arg1 + arg2 */ @@ -298,24 +313,16 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 + val2); + return boxToInteger(unboxCharOrInt(arg1, code1) + unboxCharOrInt(arg2, code2)); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 + val2); + return boxToLong(unboxCharOrLong(arg1, code1) + unboxCharOrLong(arg2, code2)); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); - return boxToFloat(val1 + val2); + return boxToFloat(unboxCharOrFloat(arg1, code1) + unboxCharOrFloat(arg2, code2)); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); - return boxToDouble(val1 + val2); + return boxToDouble(unboxCharOrDouble(arg1, code1) + unboxCharOrDouble(arg2, code2)); } throw new NoSuchMethodException(); } @@ -326,24 +333,16 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 - val2); + return boxToInteger(unboxCharOrInt(arg1, code1) - unboxCharOrInt(arg2, code2)); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 - val2); + return boxToLong(unboxCharOrLong(arg1, code1) - unboxCharOrLong(arg2, code2)); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); - return boxToFloat(val1 - val2); + return boxToFloat(unboxCharOrFloat(arg1, code1) - unboxCharOrFloat(arg2, code2)); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); - return boxToDouble(val1 - val2); + return boxToDouble(unboxCharOrDouble(arg1, code1) - unboxCharOrDouble(arg2, code2)); } throw new NoSuchMethodException(); } @@ -354,24 +353,16 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 * val2); + return boxToInteger(unboxCharOrInt(arg1, code1) * unboxCharOrInt(arg2, code2)); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 * val2); + return boxToLong(unboxCharOrLong(arg1, code1) * unboxCharOrLong(arg2, code2)); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); - return boxToFloat(val1 * val2); + return boxToFloat(unboxCharOrFloat(arg1, code1) * unboxCharOrFloat(arg2, code2)); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); - return boxToDouble(val1 * val2); + return boxToDouble(unboxCharOrDouble(arg1, code1) * unboxCharOrDouble(arg2, code2)); } throw new NoSuchMethodException(); } @@ -381,26 +372,16 @@ public final class BoxesRunTime int code1 = typeCode(arg1); int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; - if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 / val2); - } - if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 / val2); - } - if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); - return boxToFloat(val1 / val2); - } - if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); - return boxToDouble(val1 / val2); - } + + if (maxcode <= INT) + return boxToInteger(unboxCharOrInt(arg1, code1) / unboxCharOrInt(arg2, code2)); + if (maxcode <= LONG) + return boxToLong(unboxCharOrLong(arg1, code1) / unboxCharOrLong(arg2, code2)); + if (maxcode <= FLOAT) + return boxToFloat(unboxCharOrFloat(arg1, code1) / unboxCharOrFloat(arg2, code2)); + if (maxcode <= DOUBLE) + return boxToDouble(unboxCharOrDouble(arg1, code1) / unboxCharOrDouble(arg2, code2)); + throw new NoSuchMethodException(); } @@ -409,26 +390,16 @@ public final class BoxesRunTime int code1 = typeCode(arg1); int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; - if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 % val2); - } - if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 % val2); - } - if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); - return boxToFloat(val1 % val2); - } - if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); - return boxToDouble(val1 % val2); - } + + if (maxcode <= INT) + return boxToInteger(unboxCharOrInt(arg1, code1) % unboxCharOrInt(arg2, code2)); + if (maxcode <= LONG) + return boxToLong(unboxCharOrLong(arg1, code1) % unboxCharOrLong(arg2, code2)); + if (maxcode <= FLOAT) + return boxToFloat(unboxCharOrFloat(arg1, code1) % unboxCharOrFloat(arg2, code2)); + if (maxcode <= DOUBLE) + return boxToDouble(unboxCharOrDouble(arg1, code1) % unboxCharOrDouble(arg2, code2)); + throw new NoSuchMethodException(); } @@ -437,24 +408,24 @@ public final class BoxesRunTime int code1 = typeCode(arg1); int code2 = typeCode(arg2); if (code1 <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); + int val1 = unboxCharOrInt(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToInteger(val1 >> val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToInteger(val1 >> val2); } } if (code1 <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); + long val1 = unboxCharOrLong(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToLong(val1 >> val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToLong(val1 >> val2); } } @@ -466,24 +437,24 @@ public final class BoxesRunTime int code1 = typeCode(arg1); int code2 = typeCode(arg2); if (code1 <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); + int val1 = unboxCharOrInt(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToInteger(val1 << val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToInteger(val1 << val2); } } if (code1 <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); + long val1 = unboxCharOrLong(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToLong(val1 << val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToLong(val1 << val2); } } @@ -495,24 +466,24 @@ public final class BoxesRunTime int code1 = typeCode(arg1); int code2 = typeCode(arg2); if (code1 <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); + int val1 = unboxCharOrInt(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToInteger(val1 >>> val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToInteger(val1 >>> val2); } } if (code1 <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); + long val1 = unboxCharOrLong(arg1, code1); if (code2 <= INT) { - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val2 = unboxCharOrInt(arg2, code2); return boxToLong(val1 >>> val2); } if (code2 <= LONG) { - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val2 = unboxCharOrLong(arg2, code2); return boxToLong(val1 >>> val2); } } @@ -523,19 +494,19 @@ public final class BoxesRunTime public static Object negate(Object arg) throws NoSuchMethodException { int code = typeCode(arg); if (code <= INT) { - int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue(); + int val = unboxCharOrInt(arg, code); return boxToInteger(-val); } if (code <= LONG) { - long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue(); + long val = unboxCharOrLong(arg, code); return boxToLong(-val); } if (code <= FLOAT) { - float val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).floatValue(); + float val = unboxCharOrFloat(arg, code); return boxToFloat(-val); } if (code <= DOUBLE) { - double val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).doubleValue(); + double val = unboxCharOrDouble(arg, code); return boxToDouble(-val); } throw new NoSuchMethodException(); @@ -545,20 +516,16 @@ public final class BoxesRunTime public static Object positive(Object arg) throws NoSuchMethodException { int code = typeCode(arg); if (code <= INT) { - int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue(); - return boxToInteger(+val); + return boxToInteger(+unboxCharOrInt(arg, code)); } if (code <= LONG) { - long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue(); - return boxToLong(+val); + return boxToLong(+unboxCharOrLong(arg, code)); } if (code <= FLOAT) { - float val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).floatValue(); - return boxToFloat(+val); + return boxToFloat(+unboxCharOrFloat(arg, code)); } if (code <= DOUBLE) { - double val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).doubleValue(); - return boxToDouble(+val); + return boxToDouble(+unboxCharOrDouble(arg, code)); } throw new NoSuchMethodException(); } @@ -566,72 +533,60 @@ public final class BoxesRunTime /** arg1 & arg2 */ public static Object takeAnd(Object arg1, Object arg2) throws NoSuchMethodException { if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) { - if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) { + if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) + return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue()); + else throw new NoSuchMethodException(); - } - return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue()); } int code1 = typeCode(arg1); int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; - if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 & val2); - } - if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 & val2); - } + + if (maxcode <= INT) + return boxToInteger(unboxCharOrInt(arg1, code1) & unboxCharOrInt(arg2, code2)); + if (maxcode <= LONG) + return boxToLong(unboxCharOrLong(arg1, code1) & unboxCharOrLong(arg2, code2)); + throw new NoSuchMethodException(); } /** arg1 | arg2 */ public static Object takeOr(Object arg1, Object arg2) throws NoSuchMethodException { if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) { - if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) { + if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) + return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() | ((java.lang.Boolean) arg2).booleanValue()); + else throw new NoSuchMethodException(); - } - return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() | ((java.lang.Boolean) arg2).booleanValue()); } int code1 = typeCode(arg1); int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; - if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 | val2); - } - if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 | val2); - } + + if (maxcode <= INT) + return boxToInteger(unboxCharOrInt(arg1, code1) | unboxCharOrInt(arg2, code2)); + if (maxcode <= LONG) + return boxToLong(unboxCharOrLong(arg1, code1) | unboxCharOrLong(arg2, code2)); + throw new NoSuchMethodException(); } /** arg1 ^ arg2 */ public static Object takeXor(Object arg1, Object arg2) throws NoSuchMethodException { if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) { - if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) { + if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) + return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() ^ ((java.lang.Boolean) arg2).booleanValue()); + else throw new NoSuchMethodException(); - } - return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() ^ ((java.lang.Boolean) arg2).booleanValue()); } int code1 = typeCode(arg1); int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; - if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); - return boxToInteger(val1 ^ val2); - } - if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); - return boxToLong(val1 ^ val2); - } + + if (maxcode <= INT) + return boxToInteger(unboxCharOrInt(arg1, code1) ^ unboxCharOrInt(arg2, code2)); + if (maxcode <= LONG) + return boxToLong(unboxCharOrLong(arg1, code1) ^ unboxCharOrLong(arg2, code2)); + throw new NoSuchMethodException(); } @@ -655,12 +610,10 @@ public final class BoxesRunTime public static Object complement(Object arg) throws NoSuchMethodException { int code = typeCode(arg); if (code <= INT) { - int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue(); - return boxToInteger(~val); + return boxToInteger(~unboxCharOrInt(arg, code)); } if (code <= LONG) { - long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue(); - return boxToLong(~val); + return boxToLong(~unboxCharOrLong(arg, code)); } throw new NoSuchMethodException(); } @@ -686,23 +639,23 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val1 = unboxCharOrInt(arg1, code1); + int val2 = unboxCharOrInt(arg2, code2); return boxToBoolean(val1 < val2); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val1 = unboxCharOrLong(arg1, code1); + long val2 = unboxCharOrLong(arg2, code2); return boxToBoolean(val1 < val2); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); + float val1 = unboxCharOrFloat(arg1, code1); + float val2 = unboxCharOrFloat(arg2, code2); return boxToBoolean(val1 < val2); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); + double val1 = unboxCharOrDouble(arg1, code1); + double val2 = unboxCharOrDouble(arg2, code2); return boxToBoolean(val1 < val2); } throw new NoSuchMethodException(); @@ -713,23 +666,23 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val1 = unboxCharOrInt(arg1, code1); + int val2 = unboxCharOrInt(arg2, code2); return boxToBoolean(val1 <= val2); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val1 = unboxCharOrLong(arg1, code1); + long val2 = unboxCharOrLong(arg2, code2); return boxToBoolean(val1 <= val2); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); + float val1 = unboxCharOrFloat(arg1, code1); + float val2 = unboxCharOrFloat(arg2, code2); return boxToBoolean(val1 <= val2); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); + double val1 = unboxCharOrDouble(arg1, code1); + double val2 = unboxCharOrDouble(arg2, code2); return boxToBoolean(val1 <= val2); } throw new NoSuchMethodException(); @@ -740,23 +693,23 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val1 = unboxCharOrInt(arg1, code1); + int val2 = unboxCharOrInt(arg2, code2); return boxToBoolean(val1 >= val2); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val1 = unboxCharOrLong(arg1, code1); + long val2 = unboxCharOrLong(arg2, code2); return boxToBoolean(val1 >= val2); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); + float val1 = unboxCharOrFloat(arg1, code1); + float val2 = unboxCharOrFloat(arg2, code2); return boxToBoolean(val1 >= val2); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); + double val1 = unboxCharOrDouble(arg1, code1); + double val2 = unboxCharOrDouble(arg2, code2); return boxToBoolean(val1 >= val2); } throw new NoSuchMethodException(); @@ -767,33 +720,30 @@ public final class BoxesRunTime int code2 = typeCode(arg2); int maxcode = (code1 < code2) ? code2 : code1; if (maxcode <= INT) { - int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue(); - int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue(); + int val1 = unboxCharOrInt(arg1, code1); + int val2 = unboxCharOrInt(arg2, code2); return boxToBoolean(val1 > val2); } if (maxcode <= LONG) { - long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue(); - long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue(); + long val1 = unboxCharOrLong(arg1, code1); + long val2 = unboxCharOrLong(arg2, code2); return boxToBoolean(val1 > val2); } if (maxcode <= FLOAT) { - float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue(); - float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue(); + float val1 = unboxCharOrFloat(arg1, code1); + float val2 = unboxCharOrFloat(arg2, code2); return boxToBoolean(val1 > val2); } if (maxcode <= DOUBLE) { - double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue(); - double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue(); + double val1 = unboxCharOrDouble(arg1, code1); + double val2 = unboxCharOrDouble(arg2, code2); return boxToBoolean(val1 > val2); } throw new NoSuchMethodException(); } - + public static boolean isBoxedNumberOrBoolean(Object arg) { - if (arg instanceof java.lang.Boolean) - return true; - else - return isBoxedNumber(arg); + return (arg instanceof java.lang.Boolean) || isBoxedNumber(arg); } public static boolean isBoxedNumber(Object arg) { return ( diff --git a/test/instrumented/library/scala/runtime/ScalaRunTime.scala b/test/instrumented/library/scala/runtime/ScalaRunTime.scala index 9eb93a418d..63908fcc29 100644 --- a/test/instrumented/library/scala/runtime/ScalaRunTime.scala +++ b/test/instrumented/library/scala/runtime/ScalaRunTime.scala @@ -6,9 +6,9 @@ ** |/ ** \* */ -package scala.runtime /* INSTRUMENTED VERSION */ +package scala.runtime import scala.collection.{ Seq, IndexedSeq, TraversableView, AbstractIterator } import scala.collection.mutable.WrappedArray @@ -33,10 +33,7 @@ object ScalaRunTime { clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) def isValueClass(clazz: Class[_]) = clazz.isPrimitive() - var arrayApplyCount = 0 - var arrayUpdateCount = 0 - - 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 @@ -52,56 +49,68 @@ object ScalaRunTime { names.toSet } + /** Return the class object representing an array with element class `clazz`. + */ + def arrayClass(clazz: Class[_]): Class[_] = { + // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 + if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] + else java.lang.reflect.Array.newInstance(clazz, 0).getClass + } + + /** Return the class object representing elements in arrays described by a given schematic. + */ + def arrayElementClass(schematic: Any): Class[_] = schematic match { + case cls: Class[_] => cls.getComponentType + case tag: ClassTag[_] => tag.erasure + case tag: ArrayTag[_] => tag.newArray(0).getClass.getComponentType + case _ => throw new UnsupportedOperationException("unsupported schematic %s (%s)".format(schematic, if (schematic == null) "null" else schematic.getClass)) + } + /** Return the class object representing an unboxed value type, * e.g. classOf[int], not classOf[java.lang.Integer]. The compiler * rewrites expressions like 5.getClass to come here. */ - def anyValClass[T <: AnyVal](value: T): Class[T] = (value match { - case x: Byte => java.lang.Byte.TYPE - case x: Short => java.lang.Short.TYPE - case x: Char => java.lang.Character.TYPE - case x: Int => java.lang.Integer.TYPE - case x: Long => java.lang.Long.TYPE - case x: Float => java.lang.Float.TYPE - case x: Double => java.lang.Double.TYPE - case x: Boolean => java.lang.Boolean.TYPE - case x: Unit => java.lang.Void.TYPE - }).asInstanceOf[Class[T]] + def anyValClass[T <: AnyVal : ClassTag](value: T): Class[T] = + classTag[T].erasure.asInstanceOf[Class[T]] + + var arrayApplyCount = 0 /** Retrieve generic array element */ def array_apply(xs: AnyRef, idx: Int): Any = { arrayApplyCount += 1 xs match { - case x: Array[AnyRef] => x(idx).asInstanceOf[Any] - case x: Array[Int] => x(idx).asInstanceOf[Any] - case x: Array[Double] => x(idx).asInstanceOf[Any] - case x: Array[Long] => x(idx).asInstanceOf[Any] - case x: Array[Float] => x(idx).asInstanceOf[Any] - case x: Array[Char] => x(idx).asInstanceOf[Any] - case x: Array[Byte] => x(idx).asInstanceOf[Any] - case x: Array[Short] => x(idx).asInstanceOf[Any] - case x: Array[Boolean] => x(idx).asInstanceOf[Any] - case x: Array[Unit] => x(idx).asInstanceOf[Any] - case null => throw new NullPointerException - } + case x: Array[AnyRef] => x(idx).asInstanceOf[Any] + case x: Array[Int] => x(idx).asInstanceOf[Any] + case x: Array[Double] => x(idx).asInstanceOf[Any] + case x: Array[Long] => x(idx).asInstanceOf[Any] + case x: Array[Float] => x(idx).asInstanceOf[Any] + case x: Array[Char] => x(idx).asInstanceOf[Any] + case x: Array[Byte] => x(idx).asInstanceOf[Any] + case x: Array[Short] => x(idx).asInstanceOf[Any] + case x: Array[Boolean] => x(idx).asInstanceOf[Any] + case x: Array[Unit] => x(idx).asInstanceOf[Any] + case null => throw new NullPointerException + } } + var arrayUpdateCount = 0 + /** update generic array element */ def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { arrayUpdateCount += 1 xs match { - case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] - case x: Array[Int] => x(idx) = value.asInstanceOf[Int] - case x: Array[Double] => x(idx) = value.asInstanceOf[Double] - case x: Array[Long] => x(idx) = value.asInstanceOf[Long] - case x: Array[Float] => x(idx) = value.asInstanceOf[Float] - case x: Array[Char] => x(idx) = value.asInstanceOf[Char] - case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] - case x: Array[Short] => x(idx) = value.asInstanceOf[Short] - case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] - case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] - case null => throw new NullPointerException - } + case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] + case x: Array[Int] => x(idx) = value.asInstanceOf[Int] + case x: Array[Double] => x(idx) = value.asInstanceOf[Double] + case x: Array[Long] => x(idx) = value.asInstanceOf[Long] + case x: Array[Float] => x(idx) = value.asInstanceOf[Float] + case x: Array[Char] => x(idx) = value.asInstanceOf[Char] + case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] + case x: Array[Short] => x(idx) = value.asInstanceOf[Short] + case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] + case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] + case null => throw new NullPointerException + } } /** Get generic array length */ @@ -340,14 +349,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/test/instrumented/srt.patch b/test/instrumented/srt.patch index 2f472ff1c0..8d08550165 100644 --- a/test/instrumented/srt.patch +++ b/test/instrumented/srt.patch @@ -1,23 +1,26 @@ 9a10,11 > /* INSTRUMENTED VERSION */ -> -33a36,38 +> +43c45,48 +< def isTuple(x: Any) = x != null && tupleNames(x.getClass.getName) +--- > var arrayApplyCount = 0 > var arrayUpdateCount = 0 -> -35c40,42 +> +> def isTuple(x: Any) = tupleNames(x.getClass.getName) +75c80,82 < def array_apply(xs: AnyRef, idx: Int): Any = xs match { --- > def array_apply(xs: AnyRef, idx: Int): Any = { > arrayApplyCount += 1 > xs match { -47a55 +87a95 > } -50c58,60 +90c98,100 < def array_update(xs: AnyRef, idx: Int, value: Any): Unit = xs match { --- > def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { > arrayUpdateCount += 1 > xs match { -62a73 +101a112 > } -- cgit v1.2.3 From 0f0144c74088e396fc1440166bed5a7c6d5f44f4 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 23 Apr 2012 16:04:56 +0200 Subject: migrates stdlib and compiler to tags * all usages of ClassManifest and Manifest are replaced with tags * all manifest tests are replaced with tag tests --- .../scala/reflect/internal/AnnotationInfos.scala | 3 +- .../scala/reflect/internal/Definitions.scala | 4 +- .../reflect/internal/pickling/UnPickler.scala | 4 +- .../scala/reflect/internal/util/Origins.scala | 2 +- src/compiler/scala/reflect/runtime/Mirror.scala | 2 +- src/compiler/scala/tools/cmd/FromString.scala | 6 +- src/compiler/scala/tools/nsc/Phases.scala | 2 +- src/compiler/scala/tools/nsc/doc/Settings.scala | 15 +- .../scala/tools/nsc/doc/html/SyntaxHigh.scala | 8 +- .../doc/model/ModelFactoryImplicitSupport.scala | 14 +- .../scala/tools/nsc/interpreter/ILoop.scala | 4 +- .../scala/tools/nsc/interpreter/ILoopInit.scala | 2 +- .../scala/tools/nsc/interpreter/IMain.scala | 23 +- .../scala/tools/nsc/interpreter/NamedParam.scala | 12 +- .../scala/tools/nsc/interpreter/Power.scala | 43 +- .../scala/tools/nsc/interpreter/ReplVals.scala | 25 +- .../scala/tools/nsc/interpreter/RichClass.scala | 10 +- .../scala/tools/nsc/interpreter/TypeStrings.scala | 20 +- .../scala/tools/nsc/io/ClassAndJarInfo.scala | 6 +- src/compiler/scala/tools/nsc/io/Pickler.scala | 2 +- .../scala/tools/nsc/settings/MutableSettings.scala | 4 +- .../scala/tools/nsc/transform/CleanUp.scala | 2 +- .../scala/tools/nsc/transform/Erasure.scala | 1 + .../tools/nsc/typechecker/ContextErrors.scala | 2 +- .../tools/nsc/typechecker/MethodSynthesis.scala | 30 +- .../tools/nsc/typechecker/NamesDefaults.scala | 4 +- .../tools/nsc/typechecker/SyntheticMethods.scala | 2 +- src/compiler/scala/tools/nsc/util/ClassPath.scala | 12 +- .../scala/tools/nsc/util/ScalaClassLoader.scala | 10 +- src/compiler/scala/tools/reflect/Invoked.scala | 2 +- src/compiler/scala/tools/reflect/UniversalFn.scala | 4 +- src/compiler/scala/tools/reflect/package.scala | 23 +- src/detach/library/scala/remoting/Channel.scala | 32 +- src/library/scala/Array.scala | 54 +- .../scala/collection/GenTraversableOnce.scala | 6 +- src/library/scala/collection/Traversable.scala | 2 +- src/library/scala/collection/TraversableOnce.scala | 2 +- .../scala/collection/TraversableProxyLike.scala | 2 +- .../generic/ArrayTagTraversableFactory.scala | 31 + .../generic/ClassManifestTraversableFactory.scala | 31 - .../generic/GenericArrayTagCompanion.scala | 32 + .../GenericArrayTagTraversableTemplate.scala | 30 + .../generic/GenericClassManifestCompanion.scala | 32 - .../GenericClassManifestTraversableTemplate.scala | 26 - .../collection/generic/TraversableForwarder.scala | 2 +- src/library/scala/collection/generic/package.scala | 9 + .../scala/collection/immutable/PagedSeq.scala | 10 +- .../scala/collection/immutable/StringLike.scala | 2 +- .../collection/interfaces/IterableMethods.scala | 1 - .../scala/collection/interfaces/SeqMethods.scala | 1 - .../scala/collection/interfaces/SetMethods.scala | 1 - .../interfaces/TraversableOnceMethods.scala | 2 +- .../scala/collection/mutable/ArrayBuilder.scala | 17 +- .../scala/collection/mutable/ArrayOps.scala | 27 +- .../scala/collection/mutable/ArrayStack.scala | 2 +- .../scala/collection/mutable/FlatArray.scala | 28 +- .../scala/collection/mutable/UnrolledBuffer.scala | 14 +- .../scala/collection/mutable/WrappedArray.scala | 43 +- .../collection/mutable/WrappedArrayBuilder.scala | 16 +- .../collection/parallel/ParIterableLike.scala | 20 +- .../collection/parallel/mutable/ParArray.scala | 4 +- .../mutable/UnrolledParArrayCombiner.scala | 2 +- src/library/scala/concurrent/Future.scala | 36 +- src/library/scala/reflect/DummyMirror.scala | 3 +- .../scala/reflect/api/AnnotationInfos.scala | 2 +- src/library/scala/util/Marshal.scala | 2 +- src/library/scala/util/Sorting.scala | 16 +- src/library/scala/util/control/Exception.scala | 6 +- src/partest/scala/tools/partest/CompilerTest.scala | 11 +- src/partest/scala/tools/partest/SigTest.scala | 24 +- src/scalacheck/org/scalacheck/Arbitrary.scala | 2 +- src/scalacheck/org/scalacheck/util/Buildable.scala | 2 +- src/swing/scala/swing/Font.scala.disabled | 32 +- .../parallel/benchmarks/arrays/Resetting.scala | 8 +- .../parallel_array/MatrixMultiplication.scala | 26 +- test/disabled/presentation/akka.check | 24 +- .../presentation/akka/src/akka/actor/Actor.scala | 4 +- .../akka/src/akka/actor/ActorRef.scala | 16 +- .../akka/src/akka/actor/ActorRegistry.scala | 30 +- .../akka/src/akka/event/EventHandler.scala | 4 +- .../src/akka/remoteinterface/RemoteInterface.scala | 4 +- .../presentation/akka/src/akka/util/Helpers.scala | 2 +- test/disabled/presentation/simple-tests.check | 2 +- test/files/jvm/manifests-new.check | 58 ++ test/files/jvm/manifests-new.scala | 109 ++++ test/files/jvm/manifests.check | 56 -- test/files/jvm/manifests.scala | 112 ---- test/files/jvm/serialization-new.check | 313 ++++++++++ test/files/jvm/serialization-new.scala | 651 +++++++++++++++++++++ test/files/jvm/serialization.check | 313 ---------- test/files/jvm/serialization.scala | 651 --------------------- test/files/neg/t2386.check | 4 - test/files/neg/t2386.scala | 3 - test/files/neg/t3692-new.check | 4 + test/files/neg/t3692-new.flags | 1 + test/files/neg/t3692-new.scala | 19 + test/files/neg/t3692.check | 11 - test/files/neg/t3692.flags | 1 - test/files/neg/t3692.scala | 19 - test/files/neg/t5452-new.check | 8 + test/files/neg/t5452-new.scala | 29 + test/files/neg/t5452.check | 8 - test/files/neg/t5452.scala | 29 - test/files/pos/contextbounds-implicits-new.scala | 8 + test/files/pos/contextbounds-implicits.scala | 8 - test/files/pos/implicits-new.scala | 89 +++ test/files/pos/implicits.scala | 89 --- test/files/pos/manifest1-new.scala | 21 + test/files/pos/manifest1.scala | 21 - test/files/pos/nothing_manifest_disambig-new.scala | 10 + test/files/pos/nothing_manifest_disambig.scala | 10 - test/files/pos/spec-constr-new.scala | 7 + test/files/pos/spec-constr.scala | 7 - test/files/pos/spec-doubledef-new.scala | 28 + test/files/pos/spec-doubledef.scala | 28 - test/files/pos/spec-fields-new.scala | 10 + test/files/pos/spec-fields.scala | 10 - test/files/pos/spec-params-new.scala | 32 + test/files/pos/spec-params.scala | 32 - test/files/pos/spec-sparsearray-new.scala | 24 + test/files/pos/spec-sparsearray.scala | 24 - test/files/pos/t1381-new.scala | 31 + test/files/pos/t1381.scala | 31 - test/files/pos/t2795-new.scala | 17 + test/files/pos/t2795.scala | 17 - test/files/pos/t3363-new.scala | 18 + test/files/pos/t3363.scala | 18 - test/files/pos/t3498-new.scala | 15 + test/files/pos/t3498.scala | 15 - test/files/presentation/ide-bug-1000531.check | 2 +- test/files/run/arrayclone-new.scala | 106 ++++ test/files/run/arrayclone.scala | 106 ---- test/files/run/ctries-new/DumbHash.scala | 14 + test/files/run/ctries-new/Wrap.scala | 9 + test/files/run/ctries-new/concmap.scala | 188 ++++++ test/files/run/ctries-new/iterator.scala | 289 +++++++++ test/files/run/ctries-new/lnode.scala | 61 ++ test/files/run/ctries-new/main.scala | 45 ++ test/files/run/ctries-new/snapshot.scala | 267 +++++++++ test/files/run/ctries/DumbHash.scala | 14 - test/files/run/ctries/Wrap.scala | 9 - test/files/run/ctries/concmap.scala | 188 ------ test/files/run/ctries/iterator.scala | 289 --------- test/files/run/ctries/lnode.scala | 61 -- test/files/run/ctries/main.scala | 45 -- test/files/run/ctries/snapshot.scala | 267 --------- test/files/run/existentials3-new.check | 24 + test/files/run/existentials3-new.scala | 78 +++ test/files/run/existentials3.check | 24 - test/files/run/existentials3.scala | 79 --- test/files/run/getClassTest-new.check | 18 + test/files/run/getClassTest-new.scala | 66 +++ test/files/run/getClassTest.check | 18 - test/files/run/getClassTest.scala | 66 --- test/files/run/manifests-new.scala | 147 +++++ test/files/run/manifests.scala | 149 ----- test/files/run/patmat_unapp_abstype-new.check | 4 + test/files/run/patmat_unapp_abstype-new.flags | 1 + test/files/run/patmat_unapp_abstype-new.scala | 83 +++ test/files/run/patmat_unapp_abstype.check | 4 - test/files/run/patmat_unapp_abstype.flags | 1 - test/files/run/patmat_unapp_abstype.scala | 83 --- test/files/run/primitive-sigs-2-new.check | 7 + test/files/run/primitive-sigs-2-new.scala | 31 + test/files/run/primitive-sigs-2.check | 7 - test/files/run/primitive-sigs-2.scala | 39 -- test/files/run/reflection-implClass-new.scala | 38 ++ test/files/run/reflection-implClass.scala | 38 -- test/files/run/reify_implicits-new.check | 1 + test/files/run/reify_implicits-new.scala | 14 + test/files/run/reify_implicits.check | 1 - test/files/run/reify_implicits.scala | 14 - test/files/run/repl-power.check | 64 +- test/files/run/repl-power.scala | 3 +- test/files/run/t0421-new.check | 3 + test/files/run/t0421-new.scala | 30 + test/files/run/t0421.check | 3 - test/files/run/t0421.scala | 30 - test/files/run/t0677-new.scala | 8 + test/files/run/t0677.scala | 8 - test/files/run/t1195-new.check | 6 + test/files/run/t1195-new.scala | 26 + test/files/run/t1195.check | 6 - test/files/run/t1195.scala | 26 - test/files/run/t2236-new.scala | 17 + test/files/run/t2236.scala | 17 - test/files/run/t2386-new.check | 2 + test/files/run/t2386-new.scala | 5 + test/files/run/t3507-new.check | 1 + test/files/run/t3507-new.scala | 15 + test/files/run/t3507.check | 1 - test/files/run/t3507.scala | 15 - test/files/run/t3758.check | 6 - test/files/run/t3758.scala | 10 - test/files/run/t4110-new.check | 2 + test/files/run/t4110-new.scala | 11 + test/files/run/t4110.check | 2 - test/files/run/t4110.scala | 11 - test/files/scalacheck/array-new.scala | 36 ++ test/files/scalacheck/array.scala | 37 -- test/files/specialized/spec-matrix-new.check | 2 + test/files/specialized/spec-matrix-new.scala | 80 +++ test/files/specialized/spec-matrix.check | 2 - test/files/specialized/spec-matrix.scala | 80 --- test/pending/pos/inference.scala | 20 +- test/pending/shootout/meteor.scala | 64 +- test/scaladoc/resources/implicits-base-res.scala | 3 +- 207 files changed, 3851 insertions(+), 3855 deletions(-) create mode 100644 src/library/scala/collection/generic/ArrayTagTraversableFactory.scala delete mode 100644 src/library/scala/collection/generic/ClassManifestTraversableFactory.scala create mode 100644 src/library/scala/collection/generic/GenericArrayTagCompanion.scala create mode 100644 src/library/scala/collection/generic/GenericArrayTagTraversableTemplate.scala delete mode 100644 src/library/scala/collection/generic/GenericClassManifestCompanion.scala delete mode 100644 src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala create mode 100644 test/files/jvm/manifests-new.check create mode 100644 test/files/jvm/manifests-new.scala delete mode 100644 test/files/jvm/manifests.check delete mode 100644 test/files/jvm/manifests.scala create mode 100644 test/files/jvm/serialization-new.check create mode 100644 test/files/jvm/serialization-new.scala delete mode 100644 test/files/jvm/serialization.check delete mode 100644 test/files/jvm/serialization.scala delete mode 100644 test/files/neg/t2386.check delete mode 100644 test/files/neg/t2386.scala create mode 100644 test/files/neg/t3692-new.check create mode 100644 test/files/neg/t3692-new.flags create mode 100644 test/files/neg/t3692-new.scala delete mode 100644 test/files/neg/t3692.check delete mode 100644 test/files/neg/t3692.flags delete mode 100644 test/files/neg/t3692.scala create mode 100644 test/files/neg/t5452-new.check create mode 100644 test/files/neg/t5452-new.scala delete mode 100644 test/files/neg/t5452.check delete mode 100644 test/files/neg/t5452.scala create mode 100644 test/files/pos/contextbounds-implicits-new.scala delete mode 100644 test/files/pos/contextbounds-implicits.scala create mode 100644 test/files/pos/implicits-new.scala delete mode 100644 test/files/pos/implicits.scala create mode 100644 test/files/pos/manifest1-new.scala delete mode 100644 test/files/pos/manifest1.scala create mode 100644 test/files/pos/nothing_manifest_disambig-new.scala delete mode 100644 test/files/pos/nothing_manifest_disambig.scala create mode 100644 test/files/pos/spec-constr-new.scala delete mode 100644 test/files/pos/spec-constr.scala create mode 100644 test/files/pos/spec-doubledef-new.scala delete mode 100644 test/files/pos/spec-doubledef.scala create mode 100644 test/files/pos/spec-fields-new.scala delete mode 100644 test/files/pos/spec-fields.scala create mode 100644 test/files/pos/spec-params-new.scala delete mode 100644 test/files/pos/spec-params.scala create mode 100644 test/files/pos/spec-sparsearray-new.scala delete mode 100644 test/files/pos/spec-sparsearray.scala create mode 100644 test/files/pos/t1381-new.scala delete mode 100644 test/files/pos/t1381.scala create mode 100644 test/files/pos/t2795-new.scala delete mode 100644 test/files/pos/t2795.scala create mode 100644 test/files/pos/t3363-new.scala delete mode 100755 test/files/pos/t3363.scala create mode 100644 test/files/pos/t3498-new.scala delete mode 100644 test/files/pos/t3498.scala create mode 100644 test/files/run/arrayclone-new.scala delete mode 100644 test/files/run/arrayclone.scala create mode 100644 test/files/run/ctries-new/DumbHash.scala create mode 100644 test/files/run/ctries-new/Wrap.scala create mode 100644 test/files/run/ctries-new/concmap.scala create mode 100644 test/files/run/ctries-new/iterator.scala create mode 100644 test/files/run/ctries-new/lnode.scala create mode 100644 test/files/run/ctries-new/main.scala create mode 100644 test/files/run/ctries-new/snapshot.scala delete mode 100644 test/files/run/ctries/DumbHash.scala delete mode 100644 test/files/run/ctries/Wrap.scala delete mode 100644 test/files/run/ctries/concmap.scala delete mode 100644 test/files/run/ctries/iterator.scala delete mode 100644 test/files/run/ctries/lnode.scala delete mode 100644 test/files/run/ctries/main.scala delete mode 100644 test/files/run/ctries/snapshot.scala create mode 100644 test/files/run/existentials3-new.check create mode 100644 test/files/run/existentials3-new.scala delete mode 100644 test/files/run/existentials3.check delete mode 100644 test/files/run/existentials3.scala create mode 100644 test/files/run/getClassTest-new.check create mode 100644 test/files/run/getClassTest-new.scala delete mode 100644 test/files/run/getClassTest.check delete mode 100644 test/files/run/getClassTest.scala create mode 100644 test/files/run/manifests-new.scala delete mode 100644 test/files/run/manifests.scala create mode 100644 test/files/run/patmat_unapp_abstype-new.check create mode 100644 test/files/run/patmat_unapp_abstype-new.flags create mode 100644 test/files/run/patmat_unapp_abstype-new.scala delete mode 100644 test/files/run/patmat_unapp_abstype.check delete mode 100644 test/files/run/patmat_unapp_abstype.flags delete mode 100644 test/files/run/patmat_unapp_abstype.scala create mode 100644 test/files/run/primitive-sigs-2-new.check create mode 100644 test/files/run/primitive-sigs-2-new.scala delete mode 100644 test/files/run/primitive-sigs-2.check delete mode 100644 test/files/run/primitive-sigs-2.scala create mode 100644 test/files/run/reflection-implClass-new.scala delete mode 100644 test/files/run/reflection-implClass.scala create mode 100644 test/files/run/reify_implicits-new.check create mode 100644 test/files/run/reify_implicits-new.scala delete mode 100644 test/files/run/reify_implicits.check delete mode 100644 test/files/run/reify_implicits.scala create mode 100644 test/files/run/t0421-new.check create mode 100644 test/files/run/t0421-new.scala delete mode 100644 test/files/run/t0421.check delete mode 100644 test/files/run/t0421.scala create mode 100644 test/files/run/t0677-new.scala delete mode 100644 test/files/run/t0677.scala create mode 100644 test/files/run/t1195-new.check create mode 100644 test/files/run/t1195-new.scala delete mode 100644 test/files/run/t1195.check delete mode 100644 test/files/run/t1195.scala create mode 100644 test/files/run/t2236-new.scala delete mode 100755 test/files/run/t2236.scala create mode 100644 test/files/run/t2386-new.check create mode 100644 test/files/run/t2386-new.scala create mode 100644 test/files/run/t3507-new.check create mode 100644 test/files/run/t3507-new.scala delete mode 100644 test/files/run/t3507.check delete mode 100644 test/files/run/t3507.scala delete mode 100644 test/files/run/t3758.check delete mode 100644 test/files/run/t3758.scala create mode 100644 test/files/run/t4110-new.check create mode 100644 test/files/run/t4110-new.scala delete mode 100644 test/files/run/t4110.check delete mode 100644 test/files/run/t4110.scala create mode 100644 test/files/scalacheck/array-new.scala delete mode 100644 test/files/scalacheck/array.scala create mode 100644 test/files/specialized/spec-matrix-new.check create mode 100644 test/files/specialized/spec-matrix-new.scala delete mode 100644 test/files/specialized/spec-matrix.check delete mode 100644 test/files/specialized/spec-matrix.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala index b86c62661a..fe0175fe72 100644 --- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala +++ b/src/compiler/scala/reflect/internal/AnnotationInfos.scala @@ -260,8 +260,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable => } } - lazy val classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] = - reflect.ClassManifest[ClassfileAnnotArg](classOf[ClassfileAnnotArg]) + lazy val classfileAnnotArgTag: ArrayTag[ClassfileAnnotArg] = arrayTag[ClassfileAnnotArg] object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil) } diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 28905dd240..29eb573b64 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -534,9 +534,9 @@ trait Definitions extends reflect.api.StandardDefinitions { // private lazy val importerFromRm = self.mkImporter(rm) private lazy val importerFromRm = self.mkImporter(rm).asInstanceOf[self.Importer { val from: rm.type }] - def manifestToType(m: Manifest[_]): Type = importerFromRm.importType(m.tpe) + def compilerTypeFromTag(t: rm.TypeTag[_]): Type = importerFromRm.importType(t.tpe) - def manifestToSymbol(m: Manifest[_]): Symbol = importerFromRm.importSymbol(m.tpe.typeSymbol) + def compilerSymbolFromTag(t: rm.TypeTag[_]): Symbol = importerFromRm.importSymbol(t.sym) // The given symbol represents either String.+ or StringAdd.+ def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+ diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala index eb4bae78d0..fd3fac1b37 100644 --- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala @@ -447,7 +447,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ { private def readArrayAnnot() = { readByte() // skip the `annotargarray` tag val end = readNat() + readIndex - until(end, () => readClassfileAnnotArg(readNat())).toArray(classfileAnnotArgManifest) + until(end, () => readClassfileAnnotArg(readNat())).toArray(classfileAnnotArgTag) } protected def readClassfileAnnotArg(i: Int): ClassfileAnnotArg = bytes(index(i)) match { case ANNOTINFO => NestedAnnotArg(at(i, readAnnotation)) @@ -843,7 +843,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ { atPhase(p) (sym setInfo tp) if (currentRunId != definedAtRunId) sym.setInfo(adaptToNewRunMap(tp)) - } + } catch { case e: MissingRequirementError => throw toTypeError(e) } diff --git a/src/compiler/scala/reflect/internal/util/Origins.scala b/src/compiler/scala/reflect/internal/util/Origins.scala index b9985c8f50..19b3adda9d 100644 --- a/src/compiler/scala/reflect/internal/util/Origins.scala +++ b/src/compiler/scala/reflect/internal/util/Origins.scala @@ -88,7 +88,7 @@ object Origins { sys.addShutdownHook(counters foreach (_.purge())) } - def apply[T: Manifest](tag: String): Origins = apply(tag, manifest[T].erasure) + def apply[T: ClassTag](tag: String): Origins = apply(tag, classTag[T].erasure) def apply(tag: String, clazz: Class[_]): Origins = apply(tag, new OneLine(clazz)) def apply(tag: String, orElse: => Origins): Origins = { counters find (_.tag == tag) getOrElse { diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala index 20024ed058..bf4bc83bea 100644 --- a/src/compiler/scala/reflect/runtime/Mirror.scala +++ b/src/compiler/scala/reflect/runtime/Mirror.scala @@ -25,7 +25,7 @@ class Mirror(var classLoader: ClassLoader) extends Universe with api.Mirror { def symbolOfInstance(obj: Any): Symbol = classToScala(obj.getClass) def typeOfInstance(obj: Any): Type = typeToScala(obj.getClass) // to do add getClass/getType for instances of primitive types, probably like this: - // def getClass[T <: AnyVal : Manifest](x: T): Symbol = manifest[T].getClass + // def getClass[T <: AnyVal : ClassTag](x: T): Symbol = classTag[T].sym def getValueOfField(receiver: AnyRef, field: Symbol): Any = { fieldToJava(field).get(receiver) diff --git a/src/compiler/scala/tools/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala index 9592e7a716..91356b3c19 100644 --- a/src/compiler/scala/tools/cmd/FromString.scala +++ b/src/compiler/scala/tools/cmd/FromString.scala @@ -7,19 +7,19 @@ package scala.tools package cmd import nsc.io.{ Path, File, Directory } -import scala.reflect.Manifest +import scala.reflect.TypeTag /** 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: Manifest[T]) extends PartialFunction[String, T] { +abstract class FromString[+T](implicit t: TypeTag[T]) extends PartialFunction[String, T] { def apply(s: String): T def isDefinedAt(s: String): Boolean = true def zero: T = apply("") - def targetString: String = m.toString + def targetString: String = t.toString } object FromString { diff --git a/src/compiler/scala/tools/nsc/Phases.scala b/src/compiler/scala/tools/nsc/Phases.scala index 1fa576afb6..aa0ea1bdd8 100644 --- a/src/compiler/scala/tools/nsc/Phases.scala +++ b/src/compiler/scala/tools/nsc/Phases.scala @@ -14,7 +14,7 @@ object Phases { /** A class for tracking something about each phase. */ - class Model[T: Manifest] { + class Model[T] { case class Cell(ph: Phase, value: T) { def name = ph.name def id = ph.id diff --git a/src/compiler/scala/tools/nsc/doc/Settings.scala b/src/compiler/scala/tools/nsc/doc/Settings.scala index 17bfb7d21d..d3a1d47de8 100644 --- a/src/compiler/scala/tools/nsc/doc/Settings.scala +++ b/src/compiler/scala/tools/nsc/doc/Settings.scala @@ -150,12 +150,15 @@ class Settings(error: String => Unit) extends scala.tools.nsc.Settings(error) { * 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")) + (".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")) + + (".scala.reflect.ClassTag" -> ((tparam: String) => tparam + " is accompanied by a ClassTag, which is a runtime representation of its type that survives erasure")) + + (".scala.reflect.TypeTag" -> ((tparam: String) => tparam + " is accompanied by a TypeTag, which is a runtime representation of its type that survives erasure")) + + (".scala.reflect.ConcreteTypeTag" -> ((tparam: String) => tparam + " is accompanied by an ConcreteTypeTag, which is a runtime representation of a concrete type that survives erasure")) /** * Set of classes to exclude from index and diagrams diff --git a/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala b/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala index f67abc58da..3ff973ec66 100644 --- a/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala +++ b/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala @@ -41,13 +41,13 @@ private[html] object SyntaxHigh { /** Standard library classes/objects, sorted alphabetically */ val standards = Array ( "Any", "AnyRef", "AnyVal", "App", "Application", "Array", - "Boolean", "Byte", "Char", "Class", "Console", "Double", - "Enumeration", "Float", "Function", "Int", + "Boolean", "Byte", "Char", "Class", "ClassTag", "ClassManifest", "ConcreteTypeTag", + "Console", "Double", "Enumeration", "Float", "Function", "Int", "List", "Long", "Manifest", "Map", - "None", "Nothing", "Null", "Object", "Option", + "NoManifest", "None", "Nothing", "Null", "Object", "Option", "OptManifest", "Pair", "Predef", "Seq", "Set", "Short", "Some", "String", "Symbol", - "Triple", "Unit") + "Triple", "TypeTag", "Unit") def apply(data: String): NodeSeq = { val buf = data.getBytes diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 4e03dc8788..61f3670f5f 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -137,7 +137,7 @@ trait ModelFactoryImplicitSupport { // Members inherited by implicit conversions cannot override actual members memberSyms = memberSyms.filterNot((sym1: Symbol) => - existingMembers.exists(sym2 => sym1.name == sym2.name && + existingMembers.exists(sym2 => sym1.name == sym2.name && !isDistinguishableFrom(toType.memberInfo(sym1), sym.info.memberInfo(sym2)))) debug(" -> full type: " + toType) @@ -199,12 +199,12 @@ trait ModelFactoryImplicitSupport { * 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 + * def pimpA[T3 <: Long, T4](a: A[Int, Foo[Bar[X]], T3, T4])(implicit ev1: TypeTag[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 + * * there must be evidence of Numeric[T4] and a TypeTag[T4] within scope * - the final type is PimpedA and A therefore inherits a couple of members from pimpedA * * How? @@ -504,14 +504,14 @@ trait ModelFactoryImplicitSupport { * 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 + * 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 = + 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: + 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 :) diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index 9279d37464..297d6ad1b9 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -1053,11 +1053,11 @@ object ILoop { // provide the enclosing type T // in order to set up the interpreter's classpath and parent class loader properly - def breakIf[T: Manifest](assertion: => Boolean, args: NamedParam*): Unit = + def breakIf[T: ClassTag](assertion: => Boolean, args: NamedParam*): Unit = if (assertion) break[T](args.toList) // start a repl, binding supplied args - def break[T: Manifest](args: List[NamedParam]): Unit = savingContextLoader { + def break[T: ClassTag](args: List[NamedParam]): Unit = savingContextLoader { val msg = if (args.isEmpty) "" else " Binding " + args.size + " value%s.".format( if (args.size == 1) "" else "s" ) diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala b/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala index 2f02748e8f..6a9654732b 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala @@ -100,7 +100,7 @@ trait ILoopInit { withLock { while (!initIsComplete) initLoopCondition.await() } } // private def warningsThunks = List( - // () => intp.bind("lastWarnings", "" + manifest[List[(Position, String)]], intp.lastWarnings _), + // () => intp.bind("lastWarnings", "" + typeTag[List[(Position, String)]], intp.lastWarnings _), // ) protected def postInitThunks = List[Option[() => Unit]]( diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 923fc867a9..3d77344091 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -351,7 +351,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends 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 far we have only used the default mirror to create a few tags for the compiler // so it shouldn't be in conflict with our classloader, especially since it respects its parent scala.reflect.mirror.classLoader = classLoader } @@ -667,7 +667,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends result } def directBind(p: NamedParam): IR.Result = directBind(p.name, p.tpe, p.value) - def directBind[T: Manifest](name: String, value: T): IR.Result = directBind((name, value)) + def directBind[T: ClassTag](name: String, value: T): IR.Result = directBind((name, value)) def rebind(p: NamedParam): IR.Result = { val name = p.name @@ -683,12 +683,12 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends if (ids.isEmpty) IR.Success else interpret("import " + ids.mkString(", ")) - def quietBind(p: NamedParam): IR.Result = beQuietDuring(bind(p)) - def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value) - def bind[T: Manifest](name: String, value: T): IR.Result = bind((name, value)) - def bindSyntheticValue(x: Any): IR.Result = bindValue(freshInternalVarName(), x) - def bindValue(x: Any): IR.Result = bindValue(freshUserVarName(), x) - def bindValue(name: String, x: Any): IR.Result = bind(name, TypeStrings.fromValue(x), x) + def quietBind(p: NamedParam): IR.Result = beQuietDuring(bind(p)) + def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value) + def bind[T: TypeTag](name: String, value: T): IR.Result = bind((name, value)) + def bindSyntheticValue(x: Any): IR.Result = bindValue(freshInternalVarName(), x) + def bindValue(x: Any): IR.Result = bindValue(freshUserVarName(), x) + def bindValue(name: String, x: Any): IR.Result = bind(name, TypeStrings.fromValue(x), x) /** Reset this interpreter, forgetting all user-specified requests. */ def reset() { @@ -1185,9 +1185,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends val termname = newTypeName(name) findName(termname) orElse getModuleIfDefined(termname) } - def types[T: ClassManifest] : Symbol = types(classManifest[T].erasure.getName) - def terms[T: ClassManifest] : Symbol = terms(classManifest[T].erasure.getName) - def apply[T: ClassManifest] : Symbol = apply(classManifest[T].erasure.getName) + // [Eugene to Paul] possibly you could make use of TypeTags here + def types[T: ClassTag] : Symbol = types(classTag[T].erasure.getName) + def terms[T: ClassTag] : Symbol = terms(classTag[T].erasure.getName) + def apply[T: ClassTag] : Symbol = apply(classTag[T].erasure.getName) def classSymbols = allDefSymbols collect { case x: ClassSymbol => x } def methodSymbols = allDefSymbols collect { case x: MethodSymbol => x } diff --git a/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala b/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala index e2b1bf34d6..a3cbfffc3b 100644 --- a/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala +++ b/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala @@ -13,19 +13,19 @@ trait NamedParamCreator { protected def freshName: () => String def apply(name: String, tpe: String, value: Any): NamedParam = NamedParamClass(name, tpe, value) - def apply[T: Manifest](name: String, x: T): NamedParam = new Typed[T](name, x) - def apply[T: Manifest](x: T): NamedParam = apply(freshName(), x) + def apply[T: TypeTag](name: String, x: T): NamedParam = new Typed[T](name, x) + def apply[T: TypeTag](x: T): NamedParam = apply(freshName(), x) def clazz(name: String, x: Any): NamedParam = new Untyped(name, x) def clazz(x: Any): NamedParam = clazz(freshName(), x) - implicit def namedValue[T: Manifest](name: String, x: T): NamedParam = apply(name, x) - implicit def tuple[T: Manifest](pair: (String, T)): NamedParam = apply(pair._1, pair._2) + implicit def namedValue[T: TypeTag](name: String, x: T): NamedParam = apply(name, x) + implicit def tuple[T: TypeTag](pair: (String, T)): NamedParam = apply(pair._1, pair._2) } object NamedParam extends NamedParamCreator { - class Typed[T: Manifest](val name: String, val value: T) extends NamedParam { - val tpe = TypeStrings.fromManifest[T] + class Typed[T: TypeTag](val name: String, val value: T) extends NamedParam { + val tpe = TypeStrings.fromTag[T] } class Untyped(val name: String, val value: Any) extends NamedParam { val tpe = TypeStrings.fromValue(value) diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index 2cb034f7ab..01ace0e984 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Power.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala @@ -42,10 +42,10 @@ Lost after 18/flatten { /** A class for methods to be injected into the intp in power mode. */ -class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: ReplValsImpl) { +class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplValsImpl) { import intp.{ beQuietDuring, typeOfExpression, interpret, parse } import intp.global._ - import definitions.{ manifestToType, manifestToSymbol, getClassIfDefined, getModuleIfDefined } + import definitions.{ compilerTypeFromTag, compilerSymbolFromTag, getClassIfDefined, getModuleIfDefined } abstract class SymSlurper { def isKeep(sym: Symbol): Boolean @@ -162,7 +162,7 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl } trait LowPriorityInternalInfo { - implicit def apply[T: Manifest] : InternalInfo[T] = new InternalInfo[T](None) + implicit def apply[T: TypeTag] : InternalInfo[T] = new InternalInfo[T](None) } object InternalInfo extends LowPriorityInternalInfo { } @@ -173,21 +173,21 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl * of the conveniences exist on that wrapper. */ trait LowPriorityInternalInfoWrapper { - implicit def apply[T: Manifest] : InternalInfoWrapper[T] = new InternalInfoWrapper[T](None) + implicit def apply[T: TypeTag] : InternalInfoWrapper[T] = new InternalInfoWrapper[T](None) } object InternalInfoWrapper extends LowPriorityInternalInfoWrapper { } - class InternalInfoWrapper[T: Manifest](value: Option[T] = None) { + class InternalInfoWrapper[T: TypeTag](value: Option[T] = None) { def ? : InternalInfo[T] = new InternalInfo[T](value) } /** Todos... - * translate manifest type arguments into applied types + * translate tag type arguments into applied types * customizable symbol filter (had to hardcode no-spec to reduce noise) */ - class InternalInfo[T: Manifest](value: Option[T] = None) { - private def newInfo[U: Manifest](value: U): InternalInfo[U] = new InternalInfo[U](Some(value)) + class InternalInfo[T: TypeTag](value: Option[T] = None) { + private def newInfo[U: TypeTag](value: U): InternalInfo[U] = new InternalInfo[U](Some(value)) private def isSpecialized(s: Symbol) = s.name.toString contains "$mc" private def isImplClass(s: Symbol) = s.name.toString endsWith "$class" @@ -198,8 +198,8 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl || s.isAnonOrRefinementClass || s.isAnonymousFunction ) - def symbol = manifestToSymbol(fullManifest) - def tpe = manifestToType(fullManifest) + def symbol = compilerSymbolFromTag(tag) + def tpe = compilerTypeFromTag(tag) def name = symbol.name def companion = symbol.companionSymbol def info = symbol.info @@ -226,8 +226,8 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl def pkgClasses = pkgMembers filter (s => s.isClass && s.isDefinedInPackage) def pkgSymbols = new PackageSlurper(pkgClass).slurp() filterNot excludeMember - def fullManifest = manifest[T] - def erasure = fullManifest.erasure + def tag = typeTag[T] + def erasure = tag.erasure def shortClass = erasure.getName split "[$.]" last def baseClasses = tpe.baseClasses @@ -236,9 +236,9 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl def ancestorDeclares(name: String) = ancestors filter (_.info member newTermName(name) ne NoSymbol) def baseTypes = tpe.baseTypeSeq.toList - def <:<[U: Manifest](other: U) = tpe <:< newInfo(other).tpe - def lub[U: Manifest](other: U) = intp.global.lub(List(tpe, newInfo(other).tpe)) - def glb[U: Manifest](other: U) = intp.global.glb(List(tpe, newInfo(other).tpe)) + def <:<[U: TypeTag](other: U) = tpe <:< newInfo(other).tpe + def lub[U: TypeTag](other: U) = intp.global.lub(List(tpe, newInfo(other).tpe)) + def glb[U: TypeTag](other: U) = intp.global.glb(List(tpe, newInfo(other).tpe)) override def toString = value match { case Some(x) => "%s (%s)".format(x, shortClass) @@ -366,7 +366,7 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl implicit lazy val powerSymbolOrdering: Ordering[Symbol] = Ordering[Name] on (_.name) implicit lazy val powerTypeOrdering: Ordering[Type] = Ordering[Symbol] on (_.typeSymbol) - implicit def replInternalInfo[T: Manifest](x: T): InternalInfoWrapper[T] = new InternalInfoWrapper[T](Some(x)) + implicit def replInternalInfo[T: TypeTag](x: T): InternalInfoWrapper[T] = new InternalInfoWrapper[T](Some(x)) implicit def replEnhancedStrings(s: String): RichReplString = new RichReplString(s) implicit def replMultiPrinting[T: Prettifier](xs: TraversableOnce[T]): MultiPrettifierClass[T] = new MultiPrettifierClass[T](xs.toSeq) @@ -381,10 +381,13 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl } trait ReplUtilities { - def module[T: Manifest] = getModuleIfDefined(manifest[T].erasure.getName stripSuffix nme.MODULE_SUFFIX_STRING) - def clazz[T: Manifest] = getClassIfDefined(manifest[T].erasure.getName) - def info[T: Manifest] = InternalInfo[T] - def ?[T: Manifest] = InternalInfo[T] + // [Eugene to Paul] needs review! + // def module[T: TypeTag] = getModuleIfDefined(typeTag[T].erasure.getName stripSuffix nme.MODULE_SUFFIX_STRING) + // def clazz[T: TypeTag] = getClassIfDefined(typeTag[T].erasure.getName) + def module[T: TypeTag] = typeTag[T].sym.suchThat(_.isPackage) + def clazz[T: TypeTag] = typeTag[T].sym.suchThat(_.isClass) + def info[T: TypeTag] = InternalInfo[T] + def ?[T: TypeTag] = InternalInfo[T] def url(s: String) = { try new URL(s) catch { case _: MalformedURLException => diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala index 4efab7e260..280247f20c 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala @@ -6,6 +6,7 @@ package scala.tools.nsc package interpreter +import scala.reflect.{mirror => rm} import language.implicitConversions /** A class which the repl utilizes to expose predefined objects. @@ -39,8 +40,8 @@ class StdReplVals(final val r: ILoop) extends ReplVals { class ReplImplicits extends power.Implicits2 { import intp.global._ - private val manifestFn = ReplVals.mkManifestToType[intp.global.type](global) - implicit def mkManifestToType(sym: Symbol) = manifestFn(sym) + private val tagFn = ReplVals.mkCompilerTypeFromTag[intp.global.type](global) + implicit def mkCompilerTypeFromTag(sym: Symbol) = tagFn(sym) } final lazy val replImplicits = new ReplImplicits @@ -53,29 +54,29 @@ object ReplVals { * not being seen as the same type as bar.global.Type even though * the globals are the same. Dependent method types to the rescue. */ - def mkManifestToType[T <: Global](global: T) = { + def mkCompilerTypeFromTag[T <: Global](global: T) = { import global._ import definitions._ - /** We can't use definitions.manifestToType directly because we're passing + /** We can't use definitions.compilerTypeFromTag directly because we're passing * it to map and the compiler refuses to perform eta expansion on a method * with a dependent return type. (Can this be relaxed?) To get around this * I have this forwarder which widens the type and then cast the result back * to the dependent type. */ - def manifestToType(m: Manifest[_]): Global#Type = - definitions.manifestToType(m) + def compilerTypeFromTag(t: rm.TypeTag[_]): Global#Type = + definitions.compilerTypeFromTag(t) - class AppliedTypeFromManifests(sym: Symbol) { - def apply[M](implicit m1: Manifest[M]): Type = + class AppliedTypeFromTags(sym: Symbol) { + def apply[M](implicit m1: rm.TypeTag[M]): Type = if (sym eq NoSymbol) NoType - else appliedType(sym, manifestToType(m1).asInstanceOf[Type]) + else appliedType(sym, compilerTypeFromTag(m1).asInstanceOf[Type]) - def apply[M1, M2](implicit m1: Manifest[M1], m2: Manifest[M2]): Type = + def apply[M1, M2](implicit m1: rm.TypeTag[M1], m2: rm.TypeTag[M2]): Type = if (sym eq NoSymbol) NoType - else appliedType(sym, manifestToType(m1).asInstanceOf[Type], manifestToType(m2).asInstanceOf[Type]) + else appliedType(sym, compilerTypeFromTag(m1).asInstanceOf[Type], compilerTypeFromTag(m2).asInstanceOf[Type]) } - (sym: Symbol) => new AppliedTypeFromManifests(sym) + (sym: Symbol) => new AppliedTypeFromTags(sym) } } diff --git a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala index 3d4d22063e..2e735e3b9b 100644 --- a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala +++ b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala @@ -6,10 +6,8 @@ package scala.tools.nsc package interpreter -import scala.reflect.{mirror => rm} - class RichClass[T](val clazz: Class[T]) { - def toManifest: Manifest[T] = Manifest[T](rm.classToType(clazz)) + def toTag: ClassTag[T] = ClassTag[T](clazz) def toTypeString: String = TypeStrings.fromClazz(clazz) // Sadly isAnonymousClass does not return true for scala anonymous @@ -21,9 +19,9 @@ class RichClass[T](val clazz: Class[T]) { ) /** It's not easy... to be... me... */ - def supermans: List[Manifest[_]] = supers map (_.toManifest) - def superNames: List[String] = supers map (_.getName) - def interfaces: List[JClass] = supers filter (_.isInterface) + def supermans: List[ClassTag[_]] = supers map (_.toTag) + def superNames: List[String] = supers map (_.getName) + def interfaces: List[JClass] = supers filter (_.isInterface) def hasAncestorName(f: String => Boolean) = superNames exists f def hasAncestor(f: JClass => Boolean) = supers exists f diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala index 9ba75d9166..5d5123811e 100644 --- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala +++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala @@ -192,8 +192,8 @@ trait TypeStrings { else enclClass.getName + "." + (name stripPrefix enclPre) ) } - def scalaName(m: ClassManifest[_]): String = scalaName(m.erasure) - def anyClass(x: Any): JClass = if (x == null) null else x.getClass + def scalaName(m: ClassTag[_]): String = scalaName(m.erasure) + def anyClass(x: Any): JClass = if (x == null) null else x.getClass private def brackets(tps: String*): String = if (tps.isEmpty) "" @@ -209,25 +209,25 @@ trait TypeStrings { brackets(clazz.getTypeParameters map tvarString: _*) } - private def tparamString[T: Manifest] : String = { + private def tparamString[T: TypeTag] : String = { // [Eugene to Paul] needs review!! - def typeArguments: List[rm.Type] = manifest[T].tpe.typeArguments + def typeArguments: List[rm.Type] = typeTag[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 + * can be a lot more precise, but right now the tags have a habit of * introducing material which is not syntactically valid as scala source. * When this happens it breaks the repl. It would be nice if we mandated - * that manifest toString methods (or some other method, since it's bad + * that tag toString methods (or some other method, since it's bad * practice to rely on toString for correctness) generated the VALID string * representation of the type. */ - def fromTypedValue[T: Manifest](x: T): String = fromManifest[T] - def fromValue(value: Any): String = if (value == null) "Null" else fromClazz(anyClass(value)) - def fromClazz(clazz: JClass): String = scalaName(clazz) + tparamString(clazz) - def fromManifest[T: Manifest] : String = scalaName(manifest[T].erasure) + tparamString[T] + def fromTypedValue[T: TypeTag](x: T): String = fromTag[T] + def fromValue(value: Any): String = if (value == null) "Null" else fromClazz(anyClass(value)) + def fromClazz(clazz: JClass): String = scalaName(clazz) + tparamString(clazz) + def fromTag[T: TypeTag] : String = scalaName(typeTag[T].erasure) + tparamString[T] /** Reducing fully qualified noise for some common packages. */ diff --git a/src/compiler/scala/tools/nsc/io/ClassAndJarInfo.scala b/src/compiler/scala/tools/nsc/io/ClassAndJarInfo.scala index d0a0b17494..c9ed535841 100644 --- a/src/compiler/scala/tools/nsc/io/ClassAndJarInfo.scala +++ b/src/compiler/scala/tools/nsc/io/ClassAndJarInfo.scala @@ -13,9 +13,9 @@ import collection.JavaConverters._ /** A convenience class for finding the jar with the bytecode for * a given Class object and similar common tasks. */ -class ClassAndJarInfo[T: ClassManifest] { - val man = classManifest[T] - def clazz = man.erasure +class ClassAndJarInfo[T: ClassTag] { + val tag = classTag[T] + def clazz = tag.erasure def internalName = clazz.getName.replace('.', '/') def resourceURL = new URLClassLoader(Array[URL]()) getResource internalName + ".class" diff --git a/src/compiler/scala/tools/nsc/io/Pickler.scala b/src/compiler/scala/tools/nsc/io/Pickler.scala index 86c7ca7b9a..416b84eec6 100644 --- a/src/compiler/scala/tools/nsc/io/Pickler.scala +++ b/src/compiler/scala/tools/nsc/io/Pickler.scala @@ -416,7 +416,7 @@ object Pickler { iterPickler[T] .wrapped { Vector() ++ _ } { _.iterator } .labelled ("scala.Vector") /** A pickler for array values */ - implicit def array[T : ClassManifest : Pickler]: Pickler[Array[T]] = + implicit def array[T : ClassTag : Pickler]: Pickler[Array[T]] = iterPickler[T] .wrapped { _.toArray} { _.iterator } .labelled ("scala.Array") } diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index a52e3b8bbe..c4dd9a2a36 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -183,8 +183,8 @@ class MutableSettings(val errorFn: String => Unit) * The class loader defining `T` should provide resources `app.class.path` * and `boot.class.path`. These resources should contain the application * and boot classpaths in the same form as would be passed on the command line.*/ - def embeddedDefaults[T: Manifest]: Unit = - embeddedDefaults(implicitly[Manifest[T]].erasure.getClassLoader) + def embeddedDefaults[T: ClassTag]: Unit = + embeddedDefaults(classTag[T].erasure.getClassLoader) /** Initializes these settings for embedded use by a class from the given class loader. * The class loader for `T` should provide resources `app.class.path` diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index fd15d92e37..bf01e142c9 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -611,7 +611,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { val ntree = typedWithPos(tree.pos)(safeREF(staticFieldSym)) super.transform(ntree) - // This transform replaces Array(Predef.wrapArray(Array(...)), ) + // This transform replaces Array(Predef.wrapArray(Array(...)), ) // with just Array(...) case Apply(appMeth, List(Apply(wrapRefArrayMeth, List(array)), _)) if (wrapRefArrayMeth.symbol == Predef_wrapRefArray && diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index c766b52159..338c39dc5f 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -668,6 +668,7 @@ abstract class Erasure extends AddInterfaces */ private def adaptMember(tree: Tree): Tree = { //Console.println("adaptMember: " + tree); + val x = 2 + 2 tree match { case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) if tree.symbol == Any_asInstanceOf => diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 8d26f66370..c13be0e39d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -861,7 +861,7 @@ trait ContextErrors { // (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" + // while our error will present 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 diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 9e06cbe0d3..4c71772929 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 scala.reflect.{ mirror => rm } import language.higherKinds /** Logic related to method synthesis which involves cooperation between @@ -21,50 +22,51 @@ trait MethodSynthesis { import CODE._ object synthesisUtil { - type M[T] = Manifest[T] - type CM[T] = ClassManifest[T] + type CTT[T] = rm.ConcreteTypeTag[T] + type CT[T] = ClassTag[T] def ValOrDefDef(sym: Symbol, body: Tree) = if (sym.isLazy) ValDef(sym, body) else DefDef(sym, body) - def applyTypeInternal(manifests: List[M[_]]): Type = { + def applyTypeInternal(tags: List[CTT[_]]): Type = { // [Eugene to Paul] needs review!! - val symbols = manifests map manifestToSymbol + val symbols = tags map compilerSymbolFromTag val container :: args = symbols val tparams = container.typeConstructor.typeParams // Conservative at present - if manifests were more usable this could do a lot more. - require(symbols forall (_ ne NoSymbol), "Must find all manifests: " + symbols) + // [Eugene to Paul] all right, they are now. what do you have in mind? + require(symbols forall (_ ne NoSymbol), "Must find all tags: " + symbols) require(container.owner.isPackageClass, "Container must be a top-level class in a package: " + container) require(tparams.size == args.size, "Arguments must match type constructor arity: " + tparams + ", " + args) appliedType(container, args map (_.tpe): _*) } - def companionType[T](implicit m: M[T]) = + def companionType[T](implicit m: CTT[T]) = getRequiredModule(m.erasure.getName).tpe // Use these like `applyType[List, Int]` or `applyType[Map, Int, String]` - def applyType[CC](implicit m1: M[CC]): Type = + def applyType[CC](implicit m1: CTT[CC]): Type = applyTypeInternal(List(m1)) - def applyType[CC[X1], X1](implicit m1: M[CC[_]], m2: M[X1]): Type = + def applyType[CC[X1], X1](implicit m1: CTT[CC[_]], m2: CTT[X1]): Type = applyTypeInternal(List(m1, m2)) - def applyType[CC[X1, X2], X1, X2](implicit m1: M[CC[_,_]], m2: M[X1], m3: M[X2]): Type = + def applyType[CC[X1, X2], X1, X2](implicit m1: CTT[CC[_,_]], m2: CTT[X1], m3: CTT[X2]): Type = applyTypeInternal(List(m1, m2, m3)) - def applyType[CC[X1, X2, X3], X1, X2, X3](implicit m1: M[CC[_,_,_]], m2: M[X1], m3: M[X2], m4: M[X3]): Type = + def applyType[CC[X1, X2, X3], X1, X2, X3](implicit m1: CTT[CC[_,_,_]], m2: CTT[X1], m3: CTT[X2], m4: CTT[X3]): Type = applyTypeInternal(List(m1, m2, m3, m4)) - def newMethodType[F](owner: Symbol)(implicit m: Manifest[F]): Type = { - val fnSymbol = manifestToSymbol(m) - assert(fnSymbol isSubClass FunctionClass(m.tpe.typeArguments.size - 1), (owner, m)) + def newMethodType[F](owner: Symbol)(implicit t: CTT[F]): Type = { + val fnSymbol = compilerSymbolFromTag(t) + assert(fnSymbol isSubClass FunctionClass(t.tpe.typeArguments.size - 1), (owner, t)) // [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 formals = compilerTypeFromTag(t).typeArguments val params = owner newSyntheticValueParams formals MethodType(params, formals.last) } diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index be269cf4b2..3d9fc67389 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -39,14 +39,14 @@ trait NamesDefaults { self: Analyzer => def isNamed(arg: Tree) = nameOf(arg).isDefined /** @param pos maps indices from old to new */ - def reorderArgs[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = { + def reorderArgs[T: ArrayTag](args: List[T], pos: Int => Int): List[T] = { val res = new Array[T](args.length) foreachWithIndex(args)((arg, index) => res(pos(index)) = arg) res.toList } /** @param pos maps indices from new to old (!) */ - def reorderArgsInv[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = { + def reorderArgsInv[T: ArrayTag](args: List[T], pos: Int => Int): List[T] = { val argsArray = args.toArray (argsArray.indices map (i => argsArray(pos(i)))).toList } diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 868c236ee9..31d064c824 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -74,7 +74,7 @@ trait SyntheticMethods extends ast.TreeDSL { // Option[Int] { def productIterator: Iterator[String] } // // appearing legitimately, but this breaks invariant places - // like Manifests and Arrays which are not robust and infer things + // like Tags and Arrays which are not robust and infer things // which they shouldn't. val accessorLub = ( if (opt.experimental) { diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 5dd9ce0e02..48ec941b50 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -26,12 +26,12 @@ object ClassPath { def scalaLibrary = locate[Option[_]] def scalaCompiler = locate[Global] - 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 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) + def infoFor[T](value: T) = info(value.getClass) + def info[T](clazz: Class[T]) = new ClassAndJarInfo()(ClassTag[T](clazz)) + def info[T: ClassTag] = new ClassAndJarInfo[T] + def locate[T: ClassTag] = info[T].rootClasspath + def locateJar[T: ClassTag] = info[T].rootPossibles find (x => isJarOrZip(x)) map (x => File(x)) + def locateDir[T: ClassTag] = info[T].rootPossibles find (_.isDirectory) map (_.toDirectory) /** Expand single path entry */ private def expandS(pattern: String): List[String] = { diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala index 700fe0c1a6..120cceb238 100644 --- a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala +++ b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala @@ -67,8 +67,8 @@ trait ScalaClassLoader extends JClassLoader { result } - def constructorsOf[T <: AnyRef : Manifest]: List[Constructor[T]] = - manifest[T].erasure.getConstructors.toList map (_.asInstanceOf[Constructor[T]]) + def constructorsOf[T <: AnyRef : ClassTag]: List[Constructor[T]] = + classTag[T].erasure.getConstructors.toList map (_.asInstanceOf[Constructor[T]]) /** The actual bytes for a class file, or an empty array if it can't be found. */ def classBytes(className: String): Array[Byte] = classAsStream(className) match { @@ -125,9 +125,9 @@ object ScalaClassLoader { def bootLoader = apply(null) def contextChain = loaderChain(contextLoader) - def pathToErasure[T: ClassManifest] = pathToClass(classManifest[T].erasure) - def pathToClass(clazz: Class[_]) = clazz.getName.replace('.', JFile.separatorChar) + ".class" - def locate[T: ClassManifest] = contextLoader getResource pathToErasure[T] + def pathToErasure[T: ClassTag] = pathToClass(classTag[T].erasure) + def pathToClass(clazz: Class[_]) = clazz.getName.replace('.', JFile.separatorChar) + ".class" + def locate[T: ClassTag] = contextLoader getResource pathToErasure[T] /** Tries to guess the classpath by type matching the context classloader * and its parents, looking for any classloaders which will reveal their diff --git a/src/compiler/scala/tools/reflect/Invoked.scala b/src/compiler/scala/tools/reflect/Invoked.scala index 30c6201a0d..516c6b9bf6 100644 --- a/src/compiler/scala/tools/reflect/Invoked.scala +++ b/src/compiler/scala/tools/reflect/Invoked.scala @@ -16,7 +16,7 @@ class Invoked private (val proxy: AnyRef, val m: Method, val args: List[AnyRef]) def name = m.getName def arity = m.getParameterTypes.size def returnType = m.getReturnType - def returns[T: Manifest] = returnType == manifest[T].erasure + def returns[T: ClassTag] = returnType == classTag[T].erasure def invokeOn(target: AnyRef) = m.invoke(target, args: _*) def isObjectMethod = Set("toString", "equals", "hashCode") contains name diff --git a/src/compiler/scala/tools/reflect/UniversalFn.scala b/src/compiler/scala/tools/reflect/UniversalFn.scala index 9ccd580560..b0c2a19021 100644 --- a/src/compiler/scala/tools/reflect/UniversalFn.scala +++ b/src/compiler/scala/tools/reflect/UniversalFn.scala @@ -26,8 +26,8 @@ class UniversalFn private (val closure: AnyRef, val method: Method) extends (Seq * them to this universal function. Will throw an exception in the * face of any bad data. */ - def as[T: Manifest] : T = { - val clazz = manifest[T].erasure + def as[T: ClassTag] : T = { + val clazz = classTag[T].erasure require(clazz.isInterface, "Type argument must be an interface.") val interfaceMethods = clazz.getDeclaredMethods.toSet diff --git a/src/compiler/scala/tools/reflect/package.scala b/src/compiler/scala/tools/reflect/package.scala index 744bf9b226..0b0c0905cb 100644 --- a/src/compiler/scala/tools/reflect/package.scala +++ b/src/compiler/scala/tools/reflect/package.scala @@ -7,7 +7,6 @@ package scala.tools import java.lang.reflect.Method import java.{ lang => jl } -import scala.reflect.{mirror => rm} package object reflect { def nameAndArity(m: Method) = (m.getName, m.getParameterTypes.size) @@ -28,17 +27,17 @@ package object reflect { } } - def zeroOfClass(clazz: Class[_]) = zeroOf(Manifest(rm.classToType(clazz))) - 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 - else if (m == manifest[Char] || m == manifest[jl.Character]) 0.toChar: jl.Character - else if (m == manifest[Byte] || m == manifest[jl.Byte]) 0.toByte: jl.Byte - else if (m == manifest[Short] || m == manifest[jl.Short]) 0.toShort: jl.Short - else if (m == manifest[Int] || m == manifest[jl.Integer]) 0: jl.Integer - else if (m == manifest[Long] || m == manifest[jl.Long]) 0l: jl.Long - else if (m == manifest[Float] || m == manifest[jl.Float]) 0f: jl.Float - else if (m == manifest[Double] || m == manifest[jl.Double]) 0d: jl.Double + def zeroOfClass(clazz: Class[_]) = zeroOf(ClassTag(clazz)) + def zeroOf[T](implicit t: ClassTag[T]): AnyRef = { + if (t == classTag[Boolean] || t == classTag[jl.Boolean]) false: jl.Boolean + else if (t == classTag[Unit] || t == classTag[jl.Void] || t == classTag[scala.runtime.BoxedUnit]) scala.runtime.BoxedUnit.UNIT + else if (t == classTag[Char] || t == classTag[jl.Character]) 0.toChar: jl.Character + else if (t == classTag[Byte] || t == classTag[jl.Byte]) 0.toByte: jl.Byte + else if (t == classTag[Short] || t == classTag[jl.Short]) 0.toShort: jl.Short + else if (t == classTag[Int] || t == classTag[jl.Integer]) 0: jl.Integer + else if (t == classTag[Long] || t == classTag[jl.Long]) 0l: jl.Long + else if (t == classTag[Float] || t == classTag[jl.Float]) 0f: jl.Float + else if (t == classTag[Double] || t == classTag[jl.Double]) 0d: jl.Double else null } } diff --git a/src/detach/library/scala/remoting/Channel.scala b/src/detach/library/scala/remoting/Channel.scala index 541e45a477..54b8fb100e 100644 --- a/src/detach/library/scala/remoting/Channel.scala +++ b/src/detach/library/scala/remoting/Channel.scala @@ -116,20 +116,20 @@ class Channel protected (socket: Socket) { * the expected type. */ @throws(classOf[ChannelException]) - def receive[T](implicit expected: reflect.Manifest[T]): T = { - val found = in.readObject().asInstanceOf[reflect.Manifest[_]] + def receive[T](implicit expected: reflect.ClassTag[T]): T = { + val found = in.readObject().asInstanceOf[reflect.ClassTag[_]] info("receive: found="+found+", expected="+expected) - import scala.reflect.Manifest + import scala.reflect.ClassTag val x = found match { - case Manifest.Unit => () - case Manifest.Boolean => in.readBoolean() - case Manifest.Byte => in.readByte() - case Manifest.Char => in.readChar() - case Manifest.Short => in.readShort() - case Manifest.Int => in.readInt() - case Manifest.Long => in.readLong() - case Manifest.Float => in.readFloat() - case Manifest.Double => in.readDouble() + case ClassTag.Unit => () + case ClassTag.Boolean => in.readBoolean() + case ClassTag.Byte => in.readByte() + case ClassTag.Char => in.readChar() + case ClassTag.Short => in.readShort() + case ClassTag.Int => in.readInt() + case ClassTag.Long => in.readLong() + case ClassTag.Float => in.readFloat() + case ClassTag.Double => in.readDouble() case _ => in.readObject() } val res = if (found <:< expected) @@ -144,12 +144,12 @@ class Channel protected (socket: Socket) { /** ? method may throw either an * ClassNotFoundException or an IOException. */ - def ?[T](implicit m: reflect.Manifest[T]): T = receive[T](m) + def ?[T](implicit t: reflect.ClassTag[T]): T = receive[T](t) /** send method may throw an IOException. */ - def send[T](x: T)(implicit m: reflect.Manifest[T]) { - out writeObject m + def send[T](x: T)(implicit t: reflect.ClassTag[T]) { + out writeObject t x match { case x: Unit => // nop case x: Boolean => out writeBoolean x @@ -168,7 +168,7 @@ class Channel protected (socket: Socket) { /** ! method may throw an IOException. */ - def ![T](x: T)(implicit m: reflect.Manifest[T]) { send(x)(m) } + def ![T](x: T)(implicit m: reflect.ClassTag[T]) { send(x)(m) } def close() { try { socket.close() } diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala index 5b8ebde308..fd61cfd0a1 100644 --- a/src/library/scala/Array.scala +++ b/src/library/scala/Array.scala @@ -12,17 +12,17 @@ import scala.collection.generic._ import scala.collection.{ mutable, immutable } import mutable.{ ArrayBuilder, ArraySeq } import compat.Platform.arraycopy -import scala.reflect.ClassManifest +import scala.reflect.ArrayTag import scala.runtime.ScalaRunTime.{ array_apply, array_update } /** Contains a fallback builder for arrays when the element type - * does not have a class manifest. In that case a generic array is built. + * does not have a class tag. In that case a generic array is built. */ class FallbackArrayBuilding { /** A builder factory that generates a generic array. * Called instead of `Array.newBuilder` if the element type of an array - * does not have a class manifest. Note that fallbackBuilder factory + * does not have a class tag. Note that fallbackBuilder factory * needs an implicit parameter (otherwise it would not be dominated in * implicit search by `Array.canBuildFrom`). We make sure that * implicit search is always successful. @@ -48,16 +48,16 @@ class FallbackArrayBuilding { * @version 1.0 */ object Array extends FallbackArrayBuilding { - implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[Array[_], T, Array[T]] = + implicit def canBuildFrom[T](implicit t: ArrayTag[T]): CanBuildFrom[Array[_], T, Array[T]] = new CanBuildFrom[Array[_], T, Array[T]] { - def apply(from: Array[_]) = ArrayBuilder.make[T]()(m) - def apply() = ArrayBuilder.make[T]()(m) + def apply(from: Array[_]) = ArrayBuilder.make[T]()(t) + def apply() = ArrayBuilder.make[T]()(t) } /** * Returns a new [[scala.collection.mutable.ArrayBuilder]]. */ - def newBuilder[T](implicit m: ClassManifest[T]): ArrayBuilder[T] = ArrayBuilder.make[T]()(m) + def newBuilder[T](implicit t: ArrayTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T]()(t) private def slowcopy(src : AnyRef, srcPos : Int, @@ -98,14 +98,14 @@ object Array extends FallbackArrayBuilding { } /** Returns an array of length 0 */ - def empty[T: ClassManifest]: Array[T] = new Array[T](0) + def empty[T: ArrayTag]: Array[T] = new Array[T](0) /** Creates an array with given elements. * * @param xs the elements to put in the array * @return an array containing all elements from xs. */ - def apply[T: ClassManifest](xs: T*): Array[T] = { + def apply[T: ArrayTag](xs: T*): Array[T] = { val array = new Array[T](xs.length) var i = 0 for (x <- xs.iterator) { array(i) = x; i += 1 } @@ -194,23 +194,23 @@ object Array extends FallbackArrayBuilding { } /** Creates array with given dimensions */ - def ofDim[T: ClassManifest](n1: Int): Array[T] = + def ofDim[T: ArrayTag](n1: Int): Array[T] = new Array[T](n1) /** Creates a 2-dimensional array */ - def ofDim[T: ClassManifest](n1: Int, n2: Int): Array[Array[T]] = { + def ofDim[T: ArrayTag](n1: Int, n2: Int): Array[Array[T]] = { val arr: Array[Array[T]] = (new Array[Array[T]](n1): Array[Array[T]]) for (i <- 0 until n1) arr(i) = new Array[T](n2) arr // tabulate(n1)(_ => ofDim[T](n2)) } /** Creates a 3-dimensional array */ - def ofDim[T: ClassManifest](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = + def ofDim[T: ArrayTag](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = tabulate(n1)(_ => ofDim[T](n2, n3)) /** Creates a 4-dimensional array */ - def ofDim[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = + def ofDim[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = tabulate(n1)(_ => ofDim[T](n2, n3, n4)) /** Creates a 5-dimensional array */ - def ofDim[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = + def ofDim[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = tabulate(n1)(_ => ofDim[T](n2, n3, n4, n5)) /** Concatenates all arrays into a single array. @@ -218,7 +218,7 @@ object Array extends FallbackArrayBuilding { * @param xss the given arrays * @return the array created from concatenating `xss` */ - def concat[T: ClassManifest](xss: Array[T]*): Array[T] = { + def concat[T: ArrayTag](xss: Array[T]*): Array[T] = { val b = newBuilder[T] b.sizeHint(xss.map(_.size).sum) for (xs <- xss) b ++= xs @@ -239,7 +239,7 @@ object Array extends FallbackArrayBuilding { * @return an Array of size n, where each element contains the result of computing * `elem`. */ - def fill[T: ClassManifest](n: Int)(elem: => T): Array[T] = { + def fill[T: ArrayTag](n: Int)(elem: => T): Array[T] = { val b = newBuilder[T] b.sizeHint(n) var i = 0 @@ -257,7 +257,7 @@ object Array extends FallbackArrayBuilding { * @param n2 the number of elements in the 2nd dimension * @param elem the element computation */ - def fill[T: ClassManifest](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = + def fill[T: ArrayTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = tabulate(n1)(_ => fill(n2)(elem)) /** Returns a three-dimensional array that contains the results of some element @@ -268,7 +268,7 @@ object Array extends FallbackArrayBuilding { * @param n3 the number of elements in the 3nd dimension * @param elem the element computation */ - def fill[T: ClassManifest](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] = + def fill[T: ArrayTag](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] = tabulate(n1)(_ => fill(n2, n3)(elem)) /** Returns a four-dimensional array that contains the results of some element @@ -280,7 +280,7 @@ object Array extends FallbackArrayBuilding { * @param n4 the number of elements in the 4th dimension * @param elem the element computation */ - def fill[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] = + def fill[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] = tabulate(n1)(_ => fill(n2, n3, n4)(elem)) /** Returns a five-dimensional array that contains the results of some element @@ -293,7 +293,7 @@ object Array extends FallbackArrayBuilding { * @param n5 the number of elements in the 5th dimension * @param elem the element computation */ - def fill[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] = + def fill[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] = tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem)) /** Returns an array containing values of a given function over a range of integer @@ -303,7 +303,7 @@ object Array extends FallbackArrayBuilding { * @param f The function computing element values * @return A traversable consisting of elements `f(0),f(1), ..., f(n - 1)` */ - def tabulate[T: ClassManifest](n: Int)(f: Int => T): Array[T] = { + def tabulate[T: ArrayTag](n: Int)(f: Int => T): Array[T] = { val b = newBuilder[T] b.sizeHint(n) var i = 0 @@ -321,7 +321,7 @@ object Array extends FallbackArrayBuilding { * @param n2 the number of elements in the 2nd dimension * @param f The function computing element values */ - def tabulate[T: ClassManifest](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = + def tabulate[T: ArrayTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) /** Returns a three-dimensional array containing values of a given function @@ -332,7 +332,7 @@ object Array extends FallbackArrayBuilding { * @param n3 the number of elements in the 3rd dimension * @param f The function computing element values */ - def tabulate[T: ClassManifest](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] = + def tabulate[T: ArrayTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] = tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) /** Returns a four-dimensional array containing values of a given function @@ -344,7 +344,7 @@ object Array extends FallbackArrayBuilding { * @param n4 the number of elements in the 4th dimension * @param f The function computing element values */ - def tabulate[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] = + def tabulate[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] = tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) /** Returns a five-dimensional array containing values of a given function @@ -357,7 +357,7 @@ object Array extends FallbackArrayBuilding { * @param n5 the number of elements in the 5th dimension * @param f The function computing element values */ - def tabulate[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] = + def tabulate[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] = tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) /** Returns an array containing a sequence of increasing integers in a range. @@ -396,7 +396,7 @@ object Array extends FallbackArrayBuilding { * @param f the function that is repeatedly applied * @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...` */ - def iterate[T: ClassManifest](start: T, len: Int)(f: T => T): Array[T] = { + def iterate[T: ArrayTag](start: T, len: Int)(f: T => T): Array[T] = { val b = newBuilder[T] if (len > 0) { @@ -476,7 +476,7 @@ object Array extends FallbackArrayBuilding { * @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. + * `That` is either `Array[B]` if an ArrayTag 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`. diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala index a7ec7618b7..fd8595ccb8 100644 --- a/src/library/scala/collection/GenTraversableOnce.scala +++ b/src/library/scala/collection/GenTraversableOnce.scala @@ -459,7 +459,7 @@ trait GenTraversableOnce[+A] extends Any { /** Converts this $coll to an array. * - * @tparam B the type of the elements of the array. A `ClassManifest` for + * @tparam B the type of the elements of the array. An `ArrayTag` for * this type must be available. * @return an array containing all elements of this $coll. * @@ -469,9 +469,9 @@ trait GenTraversableOnce[+A] extends Any { * $willNotTerminateInf * * @return an array containing all elements of this $coll. - * A `ClassManifest` must be available for the element type of this $coll. + * An `ArrayTag` must be available for the element type of this $coll. */ - def toArray[A1 >: A: ClassManifest]: Array[A1] + def toArray[A1 >: A: ArrayTag]: Array[A1] /** Converts this $coll to a list. * $willNotTerminateInf diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala index 3fba3dfa79..a65be3ffcc 100644 --- a/src/library/scala/collection/Traversable.scala +++ b/src/library/scala/collection/Traversable.scala @@ -75,7 +75,7 @@ trait Traversable[+A] extends TraversableLike[A, Traversable[A]] override def copyToBuffer[B >: A](dest: Buffer[B]) override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) override def copyToArray[B >: A](xs: Array[B], start: Int) - override def toArray[B >: A : ClassManifest]: Array[B] + override def toArray[B >: A : ArrayTag]: Array[B] override def toList: List[A] override def toIterable: Iterable[A] override def toSeq: Seq[A] diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index e68ef9e4de..5b5cee7f1b 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -229,7 +229,7 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { def copyToArray[B >: A](xs: Array[B]): Unit = copyToArray(xs, 0, xs.length) - def toArray[B >: A : ClassManifest]: Array[B] = { + def toArray[B >: A : ArrayTag]: Array[B] = { if (isTraversableAgain) { val result = new Array[B](size) copyToArray(result, 0) diff --git a/src/library/scala/collection/TraversableProxyLike.scala b/src/library/scala/collection/TraversableProxyLike.scala index e7e797391e..20880e369d 100644 --- a/src/library/scala/collection/TraversableProxyLike.scala +++ b/src/library/scala/collection/TraversableProxyLike.scala @@ -73,7 +73,7 @@ trait TraversableProxyLike[+A, +Repr <: TraversableLike[A, Repr] with Traversabl override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) = self.copyToArray(xs, start, len) override def copyToArray[B >: A](xs: Array[B], start: Int) = self.copyToArray(xs, start) override def copyToArray[B >: A](xs: Array[B]) = self.copyToArray(xs) - override def toArray[B >: A: ClassManifest]: Array[B] = self.toArray + override def toArray[B >: A: ArrayTag]: Array[B] = self.toArray override def toList: List[A] = self.toList override def toIterable: Iterable[A] = self.toIterable override def toSeq: Seq[A] = self.toSeq diff --git a/src/library/scala/collection/generic/ArrayTagTraversableFactory.scala b/src/library/scala/collection/generic/ArrayTagTraversableFactory.scala new file mode 100644 index 0000000000..d9ab17559e --- /dev/null +++ b/src/library/scala/collection/generic/ArrayTagTraversableFactory.scala @@ -0,0 +1,31 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2010-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.collection +package generic + +import language.higherKinds + +/** A template for companion objects of `ClassTagTraversable` and + * subclasses thereof. + * + * @define coll collection + * @define Coll Traversable + * @define genericCanBuildFromInfo + * The standard `CanBuildFrom` instance for $Coll objects. + * @author Aleksandar Prokopec + * @since 2.8 + */ +abstract class ArrayTagTraversableFactory[CC[X] <: Traversable[X] with GenericArrayTagTraversableTemplate[X, CC]] + extends GenericArrayTagCompanion[CC] { + + class GenericCanBuildFrom[A](implicit tag: ArrayTag[A]) extends CanBuildFrom[CC[_], A, CC[A]] { + def apply(from: CC[_]) = from.genericArrayTagBuilder[A] + def apply = newBuilder[A] + } +} diff --git a/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala b/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala deleted file mode 100644 index e418ca623f..0000000000 --- a/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala +++ /dev/null @@ -1,31 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2010-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.collection -package generic - -import language.higherKinds - -/** A template for companion objects of `ClassManifestTraversable` and - * subclasses thereof. - * - * @define coll collection - * @define Coll Traversable - * @define genericCanBuildFromInfo - * The standard `CanBuildFrom` instance for $Coll objects. - * @author Aleksandar Prokopec - * @since 2.8 - */ -abstract class ClassManifestTraversableFactory[CC[X] <: Traversable[X] with GenericClassManifestTraversableTemplate[X, CC]] - extends GenericClassManifestCompanion[CC] { - - class GenericCanBuildFrom[A](implicit manif: ClassManifest[A]) extends CanBuildFrom[CC[_], A, CC[A]] { - def apply(from: CC[_]) = from.genericClassManifestBuilder[A] - def apply = newBuilder[A] - } -} diff --git a/src/library/scala/collection/generic/GenericArrayTagCompanion.scala b/src/library/scala/collection/generic/GenericArrayTagCompanion.scala new file mode 100644 index 0000000000..959adbce6d --- /dev/null +++ b/src/library/scala/collection/generic/GenericArrayTagCompanion.scala @@ -0,0 +1,32 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.collection +package generic + +import mutable.Builder +import language.higherKinds + +/** This class represents companions of classes which require ArrayTags + * for their element types. + * + * @author Aleksandar Prokopec + */ +abstract class GenericArrayTagCompanion[+CC[X] <: Traversable[X]] { + type Coll = CC[_] + + def newBuilder[A](implicit ord: ArrayTag[A]): Builder[A, CC[A]] + + def empty[A: ArrayTag]: CC[A] = newBuilder[A].result + + def apply[A](elems: A*)(implicit ord: ArrayTag[A]): CC[A] = { + val b = newBuilder[A] + b ++= elems + b.result + } +} diff --git a/src/library/scala/collection/generic/GenericArrayTagTraversableTemplate.scala b/src/library/scala/collection/generic/GenericArrayTagTraversableTemplate.scala new file mode 100644 index 0000000000..ac84683c59 --- /dev/null +++ b/src/library/scala/collection/generic/GenericArrayTagTraversableTemplate.scala @@ -0,0 +1,30 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2010-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.collection +package generic + +import mutable.Builder +import annotation.unchecked.uncheckedVariance +import language.higherKinds + +/** This trait represents collections classes which require array + * tags for their element types. + * + * @author Aleksandar Prokopec + * @since 2.8 + */ +trait GenericArrayTagTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBuilder[A, CC[A] @uncheckedVariance] { + implicit protected[this] val tag: ArrayTag[A] + def arrayTagCompanion: GenericArrayTagCompanion[CC] + def genericArrayTagBuilder[B](implicit tag: ArrayTag[B]): Builder[B, CC[B]] = arrayTagCompanion.newBuilder[B] + @deprecated("use arrayTagCompanion instead", "2.10.0") + def classManifestCompanion: GenericClassManifestCompanion[CC] = arrayTagCompanion + @deprecated("use genericArrayTagBuilder instead", "2.10.0") + def genericClassManifestBuilder[B](implicit manifest: ClassManifest[B]): Builder[B, CC[B]] = genericArrayTagBuilder[B](manifest) +} diff --git a/src/library/scala/collection/generic/GenericClassManifestCompanion.scala b/src/library/scala/collection/generic/GenericClassManifestCompanion.scala deleted file mode 100644 index f357091361..0000000000 --- a/src/library/scala/collection/generic/GenericClassManifestCompanion.scala +++ /dev/null @@ -1,32 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.collection -package generic - -import mutable.Builder -import language.higherKinds - -/** This class represents companions of classes which require ClassManifests - * for their element types. - * - * @author Aleksandar Prokopec - */ -abstract class GenericClassManifestCompanion[+CC[X] <: Traversable[X]] { - type Coll = CC[_] - - def newBuilder[A](implicit ord: ClassManifest[A]): Builder[A, CC[A]] - - def empty[A: ClassManifest]: CC[A] = newBuilder[A].result - - def apply[A](elems: A*)(implicit ord: ClassManifest[A]): CC[A] = { - val b = newBuilder[A] - b ++= elems - b.result - } -} diff --git a/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala b/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala deleted file mode 100644 index 1a5db4bab2..0000000000 --- a/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2010-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.collection -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. - * - * @author Aleksandar Prokopec - * @since 2.8 - */ -trait GenericClassManifestTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBuilder[A, CC[A] @uncheckedVariance] { - implicit protected[this] val manifest: ClassManifest[A] - def classManifestCompanion: GenericClassManifestCompanion[CC] - def genericClassManifestBuilder[B](implicit man: ClassManifest[B]): Builder[B, CC[B]] = classManifestCompanion.newBuilder[B] -} diff --git a/src/library/scala/collection/generic/TraversableForwarder.scala b/src/library/scala/collection/generic/TraversableForwarder.scala index 3d723a1feb..3d5bc2704f 100644 --- a/src/library/scala/collection/generic/TraversableForwarder.scala +++ b/src/library/scala/collection/generic/TraversableForwarder.scala @@ -57,7 +57,7 @@ trait TraversableForwarder[+A] extends Traversable[A] { override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) = underlying.copyToArray(xs, start, len) override def copyToArray[B >: A](xs: Array[B], start: Int) = underlying.copyToArray(xs, start) override def copyToArray[B >: A](xs: Array[B]) = underlying.copyToArray(xs) - override def toArray[B >: A: ClassManifest]: Array[B] = underlying.toArray + override def toArray[B >: A: ArrayTag]: Array[B] = underlying.toArray override def toList: List[A] = underlying.toList override def toIterable: Iterable[A] = underlying.toIterable override def toSeq: Seq[A] = underlying.toSeq diff --git a/src/library/scala/collection/generic/package.scala b/src/library/scala/collection/generic/package.scala index 0457fef227..32006b4bf0 100644 --- a/src/library/scala/collection/generic/package.scala +++ b/src/library/scala/collection/generic/package.scala @@ -3,4 +3,13 @@ import generic.CanBuildFrom package object generic { type CanBuild[-Elem, +To] = CanBuildFrom[Nothing, Elem, To] + + @deprecated("use ArrayTagTraversableFactory instead", "2.10.0") + type ClassManifestTraversableFactory[CC[X] <: Traversable[X] with GenericClassManifestTraversableTemplate[X, CC]] = ArrayTagTraversableFactory[CC] + + @deprecated("use GenericArrayTagCompanion instead", "2.10.0") + type GenericClassManifestCompanion[+CC[X] <: Traversable[X]] = GenericArrayTagCompanion[CC] + + @deprecated("use GenericArrayTagTraversableTemplate instead", "2.10.0") + type GenericClassManifestTraversableTemplate[+A, +CC[X] <: Traversable[X]] = GenericArrayTagTraversableTemplate[A, CC] } \ No newline at end of file diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala index 97c7c789f8..68c75ee586 100644 --- a/src/library/scala/collection/immutable/PagedSeq.scala +++ b/src/library/scala/collection/immutable/PagedSeq.scala @@ -25,7 +25,7 @@ object PagedSeq { final val UndeterminedEnd = Int.MaxValue /** Constructs a paged sequence from an iterator */ - def fromIterator[T: ClassManifest](source: Iterator[T]): PagedSeq[T] = + def fromIterator[T: ArrayTag](source: Iterator[T]): PagedSeq[T] = new PagedSeq[T]((data: Array[T], start: Int, len: Int) => { var i = 0 while (i < len && source.hasNext) { @@ -36,7 +36,7 @@ object PagedSeq { }) /** Constructs a paged sequence from an iterable */ - def fromIterable[T: ClassManifest](source: Iterable[T]): PagedSeq[T] = + def fromIterable[T: ArrayTag](source: Iterable[T]): PagedSeq[T] = fromIterator(source.iterator) /** Constructs a paged character sequence from a string iterator */ @@ -115,7 +115,7 @@ import PagedSeq._ * It returns the number of elements produced, or -1 if end of logical input stream was reached * before reading any element. * - * @tparam T the type of the elements contained in this paged sequence, with a `ClassManifest` context bound. + * @tparam T the type of the elements contained in this paged sequence, with an `ArrayTag` context bound. * * @author Martin Odersky * @since 2.7 @@ -124,7 +124,7 @@ import PagedSeq._ * @define mayNotTerminateInf * @define willNotTerminateInf */ -class PagedSeq[T: ClassManifest] protected( +class PagedSeq[T: ArrayTag] protected( more: (Array[T], Int, Int) => Int, first1: Page[T], start: Int, @@ -205,7 +205,7 @@ extends scala.collection.AbstractSeq[T] /** Page containing up to PageSize characters of the input sequence. */ -private class Page[T: ClassManifest](val num: Int) { +private class Page[T: ArrayTag](val num: Int) { private final val PageSize = 4096 diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index 06f09f359f..52032a1cde 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -239,7 +239,7 @@ self => else throw new IllegalArgumentException("For input string: \"null\"") - override def toArray[B >: Char : ClassManifest]: Array[B] = + override def toArray[B >: Char : ArrayTag]: Array[B] = toString.toCharArray.asInstanceOf[Array[B]] private def unwrapArg(arg: Any): AnyRef = arg match { diff --git a/src/library/scala/collection/interfaces/IterableMethods.scala b/src/library/scala/collection/interfaces/IterableMethods.scala index 2054922e59..8efc3fe6f9 100644 --- a/src/library/scala/collection/interfaces/IterableMethods.scala +++ b/src/library/scala/collection/interfaces/IterableMethods.scala @@ -11,7 +11,6 @@ package interfaces import generic._ import mutable.Buffer -import scala.reflect.ClassManifest import annotation.unchecked.uncheckedVariance /** diff --git a/src/library/scala/collection/interfaces/SeqMethods.scala b/src/library/scala/collection/interfaces/SeqMethods.scala index 1f5b08d036..4327073d21 100644 --- a/src/library/scala/collection/interfaces/SeqMethods.scala +++ b/src/library/scala/collection/interfaces/SeqMethods.scala @@ -11,7 +11,6 @@ package interfaces import generic._ import mutable.Buffer -import scala.reflect.ClassManifest /** * @since 2.8 diff --git a/src/library/scala/collection/interfaces/SetMethods.scala b/src/library/scala/collection/interfaces/SetMethods.scala index ffe141ed82..3b6214f45c 100644 --- a/src/library/scala/collection/interfaces/SetMethods.scala +++ b/src/library/scala/collection/interfaces/SetMethods.scala @@ -11,7 +11,6 @@ package interfaces import generic._ import mutable.Buffer -import scala.reflect.ClassManifest import annotation.unchecked.uncheckedVariance /** diff --git a/src/library/scala/collection/interfaces/TraversableOnceMethods.scala b/src/library/scala/collection/interfaces/TraversableOnceMethods.scala index 471e977134..543d59d118 100644 --- a/src/library/scala/collection/interfaces/TraversableOnceMethods.scala +++ b/src/library/scala/collection/interfaces/TraversableOnceMethods.scala @@ -46,7 +46,7 @@ trait TraversableOnceMethods[+A] { def copyToBuffer[B >: A](dest: mutable.Buffer[B]): Unit // conversions - def toArray[B >: A : ClassManifest]: Array[B] + def toArray[B >: A : ArrayTag]: Array[B] def toBuffer[B >: A]: mutable.Buffer[B] def toIndexedSeq: immutable.IndexedSeq[A] def toIterable: Iterable[A] diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala index e396b0695e..293e85a97e 100644 --- a/src/library/scala/collection/mutable/ArrayBuilder.scala +++ b/src/library/scala/collection/mutable/ArrayBuilder.scala @@ -12,7 +12,8 @@ package scala.collection package mutable import generic._ -import scala.reflect.ClassManifest +import scala.reflect.ArrayTag +import scala.runtime.ScalaRunTime /** A builder class for arrays. * @@ -30,12 +31,12 @@ object ArrayBuilder { /** Creates a new arraybuilder of type `T`. * - * @tparam T type of the elements for the array builder, with a `ClassManifest` context bound. + * @tparam T type of the elements for the array builder, with a `ArrayTag` context bound. * @return a new empty array builder. */ - def make[T: ClassManifest](): ArrayBuilder[T] = { - val manifest = implicitly[ClassManifest[T]] - val erasure = manifest.erasure + def make[T: ArrayTag](): ArrayBuilder[T] = { + val tag = implicitly[ArrayTag[T]] + val erasure = ScalaRunTime.arrayElementClass(tag) erasure match { case java.lang.Byte.TYPE => new ArrayBuilder.ofByte().asInstanceOf[ArrayBuilder[T]] case java.lang.Short.TYPE => new ArrayBuilder.ofShort().asInstanceOf[ArrayBuilder[T]] @@ -46,15 +47,15 @@ object ArrayBuilder { 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]] + case _ => new ArrayBuilder.ofRef[T with AnyRef]()(tag.asInstanceOf[ArrayTag[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]] } } /** A class for array builders for arrays of reference types. * - * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassManifest` context bound. + * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ArrayTag` context bound. */ - class ofRef[T <: AnyRef : ClassManifest] extends ArrayBuilder[T] { + class ofRef[T <: AnyRef : ArrayTag] extends ArrayBuilder[T] { private var elems: Array[T] = _ private var capacity: Int = 0 diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index 875030ade0..5f0e1e1071 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -12,7 +12,8 @@ package scala.collection package mutable import compat.Platform.arraycopy -import scala.reflect.ClassManifest +import scala.reflect.ArrayTag +import scala.runtime.ScalaRunTime._ import parallel.mutable.ParArray @@ -37,10 +38,8 @@ import parallel.mutable.ParArray */ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParallelizable[T, ParArray[T]] { - private def rowBuilder[U]: Builder[U, Array[U]] = - Array.newBuilder( - ClassManifest[U]( - repr.getClass.getComponentType.getComponentType)) + private def elementClass: Class[_] = + arrayElementClass(repr.getClass) override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) { var l = math.min(len, repr.length) @@ -48,11 +47,13 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza Array.copy(repr, 0, xs, start, l) } - override def toArray[U >: T : ClassManifest]: Array[U] = - if (implicitly[ClassManifest[U]].erasure eq repr.getClass.getComponentType) + override def toArray[U >: T : ArrayTag]: Array[U] = { + val thatElementClass = arrayElementClass(implicitly[ArrayTag[U]]) + if (elementClass eq thatElementClass) repr.asInstanceOf[Array[U]] else super.toArray[U] + } override def par = ParArray.handoff(repr) @@ -63,7 +64,7 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza * @param asArray A function that converts elements of this array to rows - arrays of type `U`. * @return An array obtained by concatenating rows of this array. */ - def flatten[U, To](implicit asTrav: T => collection.Traversable[U], m: ClassManifest[U]): Array[U] = { + def flatten[U, To](implicit asTrav: T => collection.Traversable[U], m: ArrayTag[U]): Array[U] = { val b = Array.newBuilder[U] b.sizeHint(map{case is: collection.IndexedSeq[_] => is.size case _ => 0}.sum) for (xs <- this) @@ -78,7 +79,8 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza * @return An array obtained by replacing elements of this arrays with rows the represent. */ def transpose[U](implicit asArray: T => Array[U]): Array[Array[U]] = { - val bs = asArray(head) map (_ => rowBuilder[U]) + def mkRowBuilder() = Array.newBuilder(ClassTag[U](arrayElementClass(elementClass))) + val bs = asArray(head) map (_ => mkRowBuilder()) for (xs <- this) { var i = 0 for (x <- asArray(xs)) { @@ -86,9 +88,7 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza i += 1 } } - val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder( - ClassManifest[Array[U]]( - repr.getClass.getComponentType)) + val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(ClassTag[Array[U]](elementClass)) for (b <- bs) bb += b.result bb.result } @@ -109,8 +109,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[T](repr.getClass.getComponentType)) + override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](arrayElementClass(repr.getClass))) def length: Int = repr.length def apply(index: Int): T = repr(index) diff --git a/src/library/scala/collection/mutable/ArrayStack.scala b/src/library/scala/collection/mutable/ArrayStack.scala index f5287312b9..b3a0534826 100644 --- a/src/library/scala/collection/mutable/ArrayStack.scala +++ b/src/library/scala/collection/mutable/ArrayStack.scala @@ -21,7 +21,7 @@ object ArrayStack extends SeqFactory[ArrayStack] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, ArrayStack[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] def newBuilder[A]: Builder[A, ArrayStack[A]] = new ArrayStack[A] def empty: ArrayStack[Nothing] = new ArrayStack() - def apply[A: ClassManifest](elems: A*): ArrayStack[A] = { + def apply[A: ArrayTag](elems: A*): ArrayStack[A] = { val els: Array[AnyRef] = elems.reverseMap(_.asInstanceOf[AnyRef])(breakOut) if (els.length == 0) new ArrayStack() else new ArrayStack[A](els, els.length) diff --git a/src/library/scala/collection/mutable/FlatArray.scala b/src/library/scala/collection/mutable/FlatArray.scala index 3e43b66ecf..5b4b5e777f 100644 --- a/src/library/scala/collection/mutable/FlatArray.scala +++ b/src/library/scala/collection/mutable/FlatArray.scala @@ -11,7 +11,7 @@ package scala.collection package mutable -import scala.reflect.ClassManifest +import scala.reflect.ArrayTag import generic.CanBuildFrom /** @@ -62,16 +62,16 @@ object FlatArray { def ofDim[Boxed, Unboxed](size:Int) (implicit boxings: BoxingConversions[Boxed, Unboxed], - manifest: ClassManifest[Unboxed]): FlatArray[Boxed] = { + tag: ArrayTag[Unboxed]): FlatArray[Boxed] = { val elems = Array.ofDim[Unboxed](size) - new FlatArray.Impl(elems, boxings, manifest) + new FlatArray.Impl(elems, boxings, tag) } def empty[Boxed, Unboxed](implicit boxings: BoxingConversions[Boxed, Unboxed], - elemManifest: ClassManifest[Unboxed]): FlatArray[Boxed] = apply() + elemTag: ArrayTag[Unboxed]): FlatArray[Boxed] = apply() def apply[Boxed, Unboxed](elems: Boxed*) - (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): FlatArray[Boxed] = { + (implicit boxings: BoxingConversions[Boxed, Unboxed], elemTag: ArrayTag[Unboxed]): FlatArray[Boxed] = { val b = newBuilder[Boxed, Unboxed] b.sizeHint(elems.length) b ++= elems @@ -79,13 +79,13 @@ object FlatArray { } def newBuilder[Boxed, Unboxed] - (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): Builder[Boxed, FlatArray[Boxed]] = - new Bldr[Boxed, Unboxed](boxings, elemManifest) + (implicit boxings: BoxingConversions[Boxed, Unboxed], elemTag: ArrayTag[Unboxed]): Builder[Boxed, FlatArray[Boxed]] = + new Bldr[Boxed, Unboxed](boxings, elemTag) implicit def canBuildFrom[Boxed, Unboxed]( implicit boxings: BoxingConversions[Boxed, Unboxed], - elemManifest: ClassManifest[Unboxed]): CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] = + elemTag: ArrayTag[Unboxed]): CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] = new CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] { def apply(from: FlatArray[_]): Builder[Boxed, FlatArray[Boxed]] = newBuilder[Boxed, Unboxed] @@ -93,14 +93,14 @@ object FlatArray { newBuilder[Boxed, Unboxed] } - private class Bldr[Boxed, Unboxed](boxings: BoxingConversions[Boxed, Unboxed], manifest: ClassManifest[Unboxed]) extends Builder[Boxed, FlatArray[Boxed]] { + private class Bldr[Boxed, Unboxed](boxings: BoxingConversions[Boxed, Unboxed], tag: ArrayTag[Unboxed]) extends Builder[Boxed, FlatArray[Boxed]] { private var elems: Array[Unboxed] = _ private var capacity: Int = 0 private var size: Int = 0 private def resize(size: Int) { - val newelems = manifest.newArray(size) + val newelems = tag.newArray(size) if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) elems = newelems capacity = size @@ -131,14 +131,14 @@ object FlatArray { def result(): FlatArray[Boxed] = { if (capacity == 0 || capacity != size) resize(size) - new FlatArray.Impl(elems, boxings, manifest) + new FlatArray.Impl(elems, boxings, tag) } } private class Impl[Boxed, Unboxed]( elems: Array[Unboxed], boxings: BoxingConversions[Boxed, Unboxed], - elemManifest: ClassManifest[Unboxed]) extends FlatArray[Boxed] { + elemTag: ArrayTag[Unboxed]) extends FlatArray[Boxed] { def length = elems.length @@ -149,9 +149,9 @@ object FlatArray { /** Creates new builder for this collection ==> move to subclasses */ override protected[this] def newBuilder: Builder[Boxed, FlatArray[Boxed]] = - new Bldr[Boxed, Unboxed](boxings, elemManifest) + new Bldr[Boxed, Unboxed](boxings, elemTag) /** Clones this object, including the underlying Array. */ - override def clone: FlatArray[Boxed] = new Impl[Boxed, Unboxed](elems.clone(), boxings, elemManifest) + override def clone: FlatArray[Boxed] = new Impl[Boxed, Unboxed](elems.clone(), boxings, elemTag) } } diff --git a/src/library/scala/collection/mutable/UnrolledBuffer.scala b/src/library/scala/collection/mutable/UnrolledBuffer.scala index 09e6088782..889768d471 100644 --- a/src/library/scala/collection/mutable/UnrolledBuffer.scala +++ b/src/library/scala/collection/mutable/UnrolledBuffer.scala @@ -41,11 +41,11 @@ import annotation.tailrec * */ @SerialVersionUID(1L) -class UnrolledBuffer[T](implicit val manifest: ClassManifest[T]) +class UnrolledBuffer[T](implicit val tag: ArrayTag[T]) extends collection.mutable.AbstractBuffer[T] with collection.mutable.Buffer[T] with collection.mutable.BufferLike[T, UnrolledBuffer[T]] - with GenericClassManifestTraversableTemplate[T, UnrolledBuffer] + with GenericArrayTagTraversableTemplate[T, UnrolledBuffer] with collection.mutable.Builder[T, UnrolledBuffer[T]] with Serializable { @@ -67,7 +67,7 @@ extends collection.mutable.AbstractBuffer[T] private[collection] def calcNextLength(sz: Int) = sz - def classManifestCompanion = UnrolledBuffer + def arrayTagCompanion = UnrolledBuffer /** Concatenates the targer unrolled buffer to this unrolled buffer. * @@ -183,11 +183,11 @@ extends collection.mutable.AbstractBuffer[T] } -object UnrolledBuffer extends ClassManifestTraversableFactory[UnrolledBuffer] { +object UnrolledBuffer extends ArrayTagTraversableFactory[UnrolledBuffer] { /** $genericCanBuildFromInfo */ - implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[Coll, T, UnrolledBuffer[T]] = + implicit def canBuildFrom[T](implicit t: ArrayTag[T]): CanBuildFrom[Coll, T, UnrolledBuffer[T]] = new GenericCanBuildFrom[T] - def newBuilder[T](implicit m: ClassManifest[T]): Builder[T, UnrolledBuffer[T]] = new UnrolledBuffer[T] + def newBuilder[T](implicit t: ArrayTag[T]): Builder[T, UnrolledBuffer[T]] = new UnrolledBuffer[T] val waterline = 50 val waterlineDelim = 100 @@ -195,7 +195,7 @@ object UnrolledBuffer extends ClassManifestTraversableFactory[UnrolledBuffer] { /** Unrolled buffer node. */ - class Unrolled[T: ClassManifest] private[collection] (var size: Int, var array: Array[T], var next: Unrolled[T], val buff: UnrolledBuffer[T] = null) { + class Unrolled[T: ArrayTag] private[collection] (var size: Int, var array: Array[T], var next: Unrolled[T], val buff: UnrolledBuffer[T] = null) { private[collection] def this() = this(0, new Array[T](unrolledlength), null, null) private[collection] def this(b: UnrolledBuffer[T]) = this(0, new Array[T](unrolledlength), null, b) diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala index fac4eb77bb..5e20f4ec61 100644 --- a/src/library/scala/collection/mutable/WrappedArray.scala +++ b/src/library/scala/collection/mutable/WrappedArray.scala @@ -11,7 +11,8 @@ package scala.collection package mutable -import scala.reflect.ClassManifest +import scala.reflect.ArrayTag +import scala.runtime.ScalaRunTime._ import scala.collection.generic._ import scala.collection.parallel.mutable.ParArray @@ -40,8 +41,11 @@ extends AbstractSeq[T] override protected[this] def thisCollection: WrappedArray[T] = this override protected[this] def toCollection(repr: WrappedArray[T]): WrappedArray[T] = repr - /** The manifest of the element type */ - def elemManifest: ClassManifest[T] + /** The tag of the element type */ + def elemTag: ArrayTag[T] + + @deprecated("use elemTag instead", "2.10.0") + def elemManifest: ClassManifest[T] = ClassManifest[T](arrayElementClass(elemTag)) /** The length of the array */ def length: Int @@ -57,11 +61,16 @@ extends AbstractSeq[T] override def par = ParArray.handoff(array) - override def toArray[U >: T : ClassManifest]: Array[U] = - if (implicitly[ClassManifest[U]].erasure eq array.getClass.getComponentType) + private def elementClass: Class[_] = + arrayElementClass(repr.getClass) + + override def toArray[U >: T : ArrayTag]: Array[U] = { + val thatElementClass = arrayElementClass(implicitly[ArrayTag[U]]) + if (elementClass eq thatElementClass) array.asInstanceOf[Array[U]] else super.toArray[U] + } override def stringPrefix = "WrappedArray" @@ -71,7 +80,7 @@ extends AbstractSeq[T] /** Creates new builder for this collection ==> move to subclasses */ override protected[this] def newBuilder: Builder[T, WrappedArray[T]] = - new WrappedArrayBuilder[T](elemManifest) + new WrappedArrayBuilder[T](elemTag) } @@ -101,7 +110,7 @@ object WrappedArray { case x: Array[Unit] => new ofUnit(x) }).asInstanceOf[WrappedArray[T]] - implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[WrappedArray[_], T, WrappedArray[T]] = + implicit def canBuildFrom[T](implicit m: ArrayTag[T]): CanBuildFrom[WrappedArray[_], T, WrappedArray[T]] = new CanBuildFrom[WrappedArray[_], T, WrappedArray[T]] { def apply(from: WrappedArray[_]): Builder[T, WrappedArray[T]] = ArrayBuilder.make[T]()(m) mapResult WrappedArray.make[T] @@ -112,70 +121,70 @@ 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[T](array.getClass.getComponentType) + lazy val elemTag = ClassTag[T](arrayElementClass(array.getClass)) def length: Int = array.length def apply(index: Int): T = array(index).asInstanceOf[T] def update(index: Int, elem: T) { array(index) = elem } } final class ofByte(val array: Array[Byte]) extends WrappedArray[Byte] with Serializable { - def elemManifest = ClassManifest.Byte + def elemTag = ClassTag.Byte def length: Int = array.length def apply(index: Int): Byte = array(index) def update(index: Int, elem: Byte) { array(index) = elem } } final class ofShort(val array: Array[Short]) extends WrappedArray[Short] with Serializable { - def elemManifest = ClassManifest.Short + def elemTag = ClassTag.Short def length: Int = array.length def apply(index: Int): Short = array(index) def update(index: Int, elem: Short) { array(index) = elem } } final class ofChar(val array: Array[Char]) extends WrappedArray[Char] with Serializable { - def elemManifest = ClassManifest.Char + def elemTag = ClassTag.Char def length: Int = array.length def apply(index: Int): Char = array(index) def update(index: Int, elem: Char) { array(index) = elem } } final class ofInt(val array: Array[Int]) extends WrappedArray[Int] with Serializable { - def elemManifest = ClassManifest.Int + def elemTag = ClassTag.Int def length: Int = array.length def apply(index: Int): Int = array(index) def update(index: Int, elem: Int) { array(index) = elem } } final class ofLong(val array: Array[Long]) extends WrappedArray[Long] with Serializable { - def elemManifest = ClassManifest.Long + def elemTag = ClassTag.Long def length: Int = array.length def apply(index: Int): Long = array(index) def update(index: Int, elem: Long) { array(index) = elem } } final class ofFloat(val array: Array[Float]) extends WrappedArray[Float] with Serializable { - def elemManifest = ClassManifest.Float + def elemTag = ClassTag.Float def length: Int = array.length def apply(index: Int): Float = array(index) def update(index: Int, elem: Float) { array(index) = elem } } final class ofDouble(val array: Array[Double]) extends WrappedArray[Double] with Serializable { - def elemManifest = ClassManifest.Double + def elemTag = ClassTag.Double def length: Int = array.length def apply(index: Int): Double = array(index) def update(index: Int, elem: Double) { array(index) = elem } } final class ofBoolean(val array: Array[Boolean]) extends WrappedArray[Boolean] with Serializable { - def elemManifest = ClassManifest.Boolean + def elemTag = ClassTag.Boolean def length: Int = array.length def apply(index: Int): Boolean = array(index) def update(index: Int, elem: Boolean) { array(index) = elem } } final class ofUnit(val array: Array[Unit]) extends WrappedArray[Unit] with Serializable { - def elemManifest = ClassManifest.Unit + def elemTag = ClassTag.Unit def length: Int = array.length def apply(index: Int): Unit = array(index) def update(index: Int, elem: Unit) { array(index) = elem } diff --git a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala index fce65468e9..99a0b0ede3 100644 --- a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala +++ b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala @@ -12,23 +12,27 @@ package scala.collection package mutable import generic._ -import scala.reflect.ClassManifest +import scala.reflect.ArrayTag +import scala.runtime.ScalaRunTime._ /** A builder class for arrays. * - * @tparam A type of elements that can be added to this builder. - * @param manifest class manifest for objects of type `A`. + * @tparam A type of elements that can be added to this builder. + * @param tag class tag for objects of type `A`. * * @since 2.8 */ -class WrappedArrayBuilder[A](manifest: ClassManifest[A]) extends Builder[A, WrappedArray[A]] { +class WrappedArrayBuilder[A](tag: ArrayTag[A]) extends Builder[A, WrappedArray[A]] { + + @deprecated("use tag instead", "2.10.0") + val manifest: ArrayTag[A] = tag private var elems: WrappedArray[A] = _ private var capacity: Int = 0 private var size: Int = 0 private def mkArray(size: Int): WrappedArray[A] = { - val erasure = manifest.erasure + val erasure = arrayElementClass(tag) 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]] @@ -39,7 +43,7 @@ class WrappedArrayBuilder[A](manifest: ClassManifest[A]) extends Builder[A, Wrap 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]] + case _ => new WrappedArray.ofRef[A with AnyRef](tag.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/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala index 5bf338f560..014b9b1a42 100644 --- a/src/library/scala/collection/parallel/ParIterableLike.scala +++ b/src/library/scala/collection/parallel/ParIterableLike.scala @@ -155,15 +155,15 @@ extends GenIterableLike[T, Repr] with HasNewCombiner[T, Repr] { self: ParIterableLike[T, Repr, Sequential] => - + @transient @volatile private var _tasksupport = defaultTaskSupport - + protected def initTaskSupport() { _tasksupport = defaultTaskSupport } - + def tasksupport = { val ts = _tasksupport if (ts eq null) { @@ -171,9 +171,9 @@ self: ParIterableLike[T, Repr, Sequential] => defaultTaskSupport } else ts } - + def tasksupport_=(ts: TaskSupport) = _tasksupport = ts - + def seq: Sequential def repr: Repr = this.asInstanceOf[Repr] @@ -240,7 +240,7 @@ self: ParIterableLike[T, Repr, Sequential] => trait BuilderOps[Elem, To] { trait Otherwise[Cmb] { - def otherwise(notbody: => Unit)(implicit m: ClassManifest[Cmb]): Unit + def otherwise(notbody: => Unit)(implicit t: ClassTag[Cmb]): Unit } def ifIs[Cmb](isbody: Cmb => Unit): Otherwise[Cmb] @@ -282,8 +282,8 @@ self: ParIterableLike[T, Repr, Sequential] => protected implicit def builder2ops[Elem, To](cb: Builder[Elem, To]) = new BuilderOps[Elem, To] { def ifIs[Cmb](isbody: Cmb => Unit) = new Otherwise[Cmb] { - def otherwise(notbody: => Unit)(implicit m: ClassManifest[Cmb]) { - if (cb.getClass == m.erasure) isbody(cb.asInstanceOf[Cmb]) else notbody + def otherwise(notbody: => Unit)(implicit t: ClassTag[Cmb]) { + if (cb.getClass == t.erasure) isbody(cb.asInstanceOf[Cmb]) else notbody } } def isCombiner = cb.isInstanceOf[Combiner[_, _]] @@ -754,7 +754,7 @@ self: ParIterableLike[T, Repr, Sequential] => cntx.setIndexFlag(Int.MaxValue) tasksupport.executeAndWaitResult( new Span(0, pred, combinerFactory, combinerFactory, splitter assign cntx) mapResult { - _._2.resultWithTaskSupport + _._2.resultWithTaskSupport } ) } @@ -802,7 +802,7 @@ self: ParIterableLike[T, Repr, Sequential] => def size = splitter.remaining } - override def toArray[U >: T: ClassManifest]: Array[U] = { + override def toArray[U >: T: ArrayTag]: Array[U] = { val arr = new Array[U](size) copyToArray(arr) arr diff --git a/src/library/scala/collection/parallel/mutable/ParArray.scala b/src/library/scala/collection/parallel/mutable/ParArray.scala index 8cc0b95997..92ba701f7c 100644 --- a/src/library/scala/collection/parallel/mutable/ParArray.scala +++ b/src/library/scala/collection/parallel/mutable/ParArray.scala @@ -676,7 +676,7 @@ self => private def readObject(in: java.io.ObjectInputStream) { in.defaultReadObject - + // get raw array from arrayseq array = arrayseq.array.asInstanceOf[Array[Any]] } @@ -706,7 +706,7 @@ object ParArray extends ParFactory[ParArray] { case _ => new ParArray[T](new ExposedArraySeq[T](runtime.ScalaRunTime.toObjectArray(arr), sz)) } - def createFromCopy[T <: AnyRef : ClassManifest](arr: Array[T]): ParArray[T] = { + def createFromCopy[T <: AnyRef : ArrayTag](arr: Array[T]): ParArray[T] = { val newarr = new Array[T](arr.length) Array.copy(arr, 0, newarr, 0, arr.length) handoff(newarr) diff --git a/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala b/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala index 410b542a68..43d40776bf 100644 --- a/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala +++ b/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala @@ -26,7 +26,7 @@ import scala.collection.parallel.Task -private[mutable] class DoublingUnrolledBuffer[T](implicit m: ClassManifest[T]) extends UnrolledBuffer[T]()(m) { +private[mutable] class DoublingUnrolledBuffer[T](implicit t: ArrayTag[T]) extends UnrolledBuffer[T]()(t) { override def calcNextLength(sz: Int) = if (sz < 10000) sz * 2 else sz protected override def newUnrolled = new Unrolled[T](0, new Array[T](4), null, this) } diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 9aaf05dbd6..def086bc03 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -134,26 +134,26 @@ trait Future[+T] extends Awaitable[T] { /** Creates a new promise. */ protected def newPromise[S]: Promise[S] - + /** Returns whether the future has already been completed with * a value or an exception. - * + * * $nonDeterministic - * + * * @return `true` if the future is already completed, `false` otherwise */ def isCompleted: Boolean - + /** The value of this `Future`. - * + * * If the future is not completed the returned value will be `None`. * If the future is completed the value will be `Some(Success(t))` * if it contains a valid result, or `Some(Failure(error))` if it contains * an exception. */ def value: Option[Either[Throwable, T]] - - + + /* Projections */ /** Returns a failed projection of this future. @@ -421,11 +421,11 @@ trait Future[+T] extends Awaitable[T] { } p.future } - + /** Creates a new `Future[S]` which is completed with this `Future`'s result if * that conforms to `S`'s erased type or a `ClassCastException` otherwise. */ - def mapTo[S](implicit m: Manifest[S]): Future[S] = { + def mapTo[S](implicit tag: ClassTag[S]): Future[S] = { import java.{ lang => jl } val toBoxed = Map[Class[_], Class[_]]( classOf[Boolean] -> classOf[jl.Boolean], @@ -444,20 +444,20 @@ trait Future[+T] extends Awaitable[T] { } val p = newPromise[S] - + onComplete { case l: Left[Throwable, _] => p complete l.asInstanceOf[Either[Throwable, S]] case Right(t) => p complete (try { - Right(boxedType(m.erasure).cast(t).asInstanceOf[S]) + Right(boxedType(tag.erasure).cast(t).asInstanceOf[S]) } catch { case e: ClassCastException => Left(e) }) } - + p.future } - + /** Applies the side-effecting function to the result of this future, and returns * a new future with the result of this future. * @@ -591,7 +591,7 @@ object Future { * The fold is performed on the thread where the last future is completed, * the result will be the first failure of any of the futures, or any failure in the actual fold, * or the result of the fold. - * + * * Example: * {{{ * val result = Await.result(Future.fold(futures)(0)(_ + _), 5 seconds) @@ -603,7 +603,7 @@ object Future { } /** Initiates a fold over the supplied futures where the fold-zero is the result value of the `Future` that's completed first. - * + * * Example: * {{{ * val result = Await.result(Futures.reduce(futures)(_ + _), 5 seconds) @@ -613,11 +613,11 @@ object Future { if (futures.isEmpty) Promise[R].failure(new NoSuchElementException("reduce attempted on empty collection")).future else sequence(futures).map(_ reduceLeft op) } - + /** Transforms a `Traversable[A]` into a `Future[Traversable[B]]` using the provided function `A => Future[B]`. * This is useful for performing a parallel map. For example, to apply a function to all items of a list * in parallel: - * + * * {{{ * val myFutureList = Future.traverse(myList)(x => Future(myFunc(x))) * }}} @@ -627,7 +627,7 @@ object Future { val fb = fn(a.asInstanceOf[A]) for (r <- fr; b <- fb) yield (r += b) }.map(_.result) - + } diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala index 8b2ddde2a1..276237fce4 100644 --- a/src/library/scala/reflect/DummyMirror.scala +++ b/src/library/scala/reflect/DummyMirror.scala @@ -5,9 +5,10 @@ import scala.reflect.api.Attachment import scala.reflect.api.Modifier import scala.reflect.api.Universe +// todo. make Dummy objects not equal to themselves class DummyMirror(cl: ClassLoader) extends api.Mirror { // Members declared in scala.reflect.api.AnnotationInfos - implicit def classfileAnnotArgManifest: scala.reflect.ClassManifest[ClassfileAnnotArg] = notSupported() + implicit def classfileAnnotArgTag: scala.reflect.ClassTag[ClassfileAnnotArg] = notSupported() type AnnotationInfo = DummyAnnotationInfo.type object DummyAnnotationInfo val AnnotationInfo: AnnotationInfoExtractor = DummyAnnotationInfoExtractor diff --git a/src/library/scala/reflect/api/AnnotationInfos.scala b/src/library/scala/reflect/api/AnnotationInfos.scala index 96a65606e5..cc1c4d2b6b 100755 --- a/src/library/scala/reflect/api/AnnotationInfos.scala +++ b/src/library/scala/reflect/api/AnnotationInfos.scala @@ -12,7 +12,7 @@ trait AnnotationInfos { self: Universe => } type ClassfileAnnotArg <: AnyRef - implicit def classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] // need a precise manifest to pass to UnPickle's toArray call + implicit def classfileAnnotArgTag: ArrayTag[ClassfileAnnotArg] // need a precise tag to pass to UnPickle's toArray call type LiteralAnnotArg <: ClassfileAnnotArg val LiteralAnnotArg: LiteralAnnotArgExtractor diff --git a/src/library/scala/util/Marshal.scala b/src/library/scala/util/Marshal.scala index 6eb58e8570..e2ebe7851c 100644 --- a/src/library/scala/util/Marshal.scala +++ b/src/library/scala/util/Marshal.scala @@ -48,4 +48,4 @@ object Marshal { "\n required: "+expected) } } -} \ No newline at end of file +} diff --git a/src/library/scala/util/Sorting.scala b/src/library/scala/util/Sorting.scala index bf460a118f..7d98e57741 100644 --- a/src/library/scala/util/Sorting.scala +++ b/src/library/scala/util/Sorting.scala @@ -8,7 +8,7 @@ package scala.util -import scala.reflect.ClassManifest +import scala.reflect.ClassTag import scala.math.Ordering /** The Sorting object provides functions that can sort various kinds of @@ -39,14 +39,14 @@ object Sorting { /** Sort an array of K where K is Ordered, preserving the existing order * where the values are equal. */ - def stableSort[K: ClassManifest: Ordering](a: Array[K]) { + def stableSort[K: ArrayTag: Ordering](a: Array[K]) { stableSort(a, 0, a.length-1, new Array[K](a.length), Ordering[K].lt _) } /** Sorts an array of `K` given an ordering function `f`. * `f` should return `true` iff its first parameter is strictly less than its second parameter. */ - def stableSort[K: ClassManifest](a: Array[K], f: (K, K) => Boolean) { + def stableSort[K: ArrayTag](a: Array[K], f: (K, K) => Boolean) { stableSort(a, 0, a.length-1, new Array[K](a.length), f) } @@ -57,14 +57,14 @@ object Sorting { * @param f the comparison function. * @return the sorted sequence of items. */ - def stableSort[K: ClassManifest](a: Seq[K], f: (K, K) => Boolean): Array[K] = { + def stableSort[K: ArrayTag](a: Seq[K], f: (K, K) => Boolean): Array[K] = { val ret = a.toArray stableSort(ret, f) ret } /** Sorts an arbitrary sequence of items that are viewable as ordered. */ - def stableSort[K: ClassManifest: Ordering](a: Seq[K]): Array[K] = + def stableSort[K: ArrayTag: Ordering](a: Seq[K]): Array[K] = stableSort(a, Ordering[K].lt _) /** Stably sorts a sequence of items given an extraction function that will @@ -74,8 +74,8 @@ object Sorting { * @param f the comparison function. * @return the sorted sequence of items. */ - def stableSort[K: ClassManifest, M: Ordering](a: Seq[K], f: K => M): Array[K] = - stableSort(a)(implicitly[ClassManifest[K]], Ordering[M] on f) + def stableSort[K: ArrayTag, M: Ordering](a: Seq[K], f: K => M): Array[K] = + stableSort(a)(implicitly[ArrayTag[K]], Ordering[M] on f) private def sort1[K: Ordering](x: Array[K], off: Int, len: Int) { val ord = Ordering[K] @@ -498,7 +498,7 @@ object Sorting { sort2(off, len) } - private def stableSort[K : ClassManifest](a: Array[K], lo: Int, hi: Int, scratch: Array[K], f: (K,K) => Boolean) { + private def stableSort[K : ArrayTag](a: Array[K], lo: Int, hi: Int, scratch: Array[K], f: (K,K) => Boolean) { if (lo < hi) { val mid = (lo+hi) / 2 stableSort(a, lo, mid, scratch, f) diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala index 1cae8088f5..38f4abb20a 100644 --- a/src/library/scala/util/control/Exception.scala +++ b/src/library/scala/util/control/Exception.scala @@ -30,9 +30,9 @@ import language.implicitConversions object Exception { type Catcher[+T] = PartialFunction[Throwable, T] - def mkCatcher[Ex <: Throwable: ClassManifest, T](isDef: Ex => Boolean, f: Ex => T) = new Catcher[T] { + def mkCatcher[Ex <: Throwable: ClassTag, T](isDef: Ex => Boolean, f: Ex => T) = new Catcher[T] { private def downcast(x: Throwable): Option[Ex] = - if (classManifest[Ex].erasure.isAssignableFrom(x.getClass)) Some(x.asInstanceOf[Ex]) + if (classTag[Ex].erasure.isAssignableFrom(x.getClass)) Some(x.asInstanceOf[Ex]) else None def isDefinedAt(x: Throwable) = downcast(x) exists isDef @@ -41,7 +41,7 @@ object Exception { def mkThrowableCatcher[T](isDef: Throwable => Boolean, f: Throwable => T) = mkCatcher(isDef, f) - implicit def throwableSubtypeToCatcher[Ex <: Throwable: ClassManifest, T](pf: PartialFunction[Ex, T]) = + implicit def throwableSubtypeToCatcher[Ex <: Throwable: ClassTag, T](pf: PartialFunction[Ex, T]) = mkCatcher(pf.isDefinedAt _, pf.apply _) /** !!! Not at all sure of every factor which goes into this, diff --git a/src/partest/scala/tools/partest/CompilerTest.scala b/src/partest/scala/tools/partest/CompilerTest.scala index aaea4416dd..86678760be 100644 --- a/src/partest/scala/tools/partest/CompilerTest.scala +++ b/src/partest/scala/tools/partest/CompilerTest.scala @@ -5,6 +5,7 @@ package scala.tools.partest +import scala.reflect.{mirror => rm} import scala.tools.nsc._ /** For testing compiler internals directly. @@ -29,13 +30,13 @@ abstract class CompilerTest extends DirectTest { // Override at least one of these... def code = "" def sources: List[String] = List(code) - + // Utility functions - + class MkType(sym: Symbol) { - def apply[M](implicit m1: Manifest[M]): Type = + def apply[M](implicit t: rm.TypeTag[M]): Type = if (sym eq NoSymbol) NoType - else appliedType(sym, manifestToType(m1)) + else appliedType(sym, compilerTypeFromTag(t)) } implicit def mkMkType(sym: Symbol) = new MkType(sym) @@ -47,7 +48,7 @@ abstract class CompilerTest extends DirectTest { } loop(Set(), List(root)) } - + class SymsInPackage(pkgName: String) { def pkg = getRequiredModule(pkgName) def classes = allMembers(pkg) filter (_.isClass) diff --git a/src/partest/scala/tools/partest/SigTest.scala b/src/partest/scala/tools/partest/SigTest.scala index 072ec006f9..999d901d21 100644 --- a/src/partest/scala/tools/partest/SigTest.scala +++ b/src/partest/scala/tools/partest/SigTest.scala @@ -20,31 +20,31 @@ trait SigTest { def isObjectMethodName(name: String) = classOf[Object].getMethods exists (_.getName == name) - def fields[T: ClassManifest](p: JField => Boolean) = { - val cl = classManifest[T].erasure + def fields[T: ClassTag](p: JField => Boolean) = { + val cl = classTag[T].erasure val fs = (cl.getFields ++ cl.getDeclaredFields).distinct sortBy (_.getName) fs filter p } - def methods[T: ClassManifest](p: JMethod => Boolean) = { - val cl = classManifest[T].erasure + def methods[T: ClassTag](p: JMethod => Boolean) = { + val cl = classTag[T].erasure val ms = (cl.getMethods ++ cl.getDeclaredMethods).distinct sortBy (x => (x.getName, x.isBridge)) ms filter p } - def allFields[T: ClassManifest]() = fields[T](_ => true) - def allMethods[T: ClassManifest]() = methods[T](m => !isObjectMethodName(m.getName)) - def fieldsNamed[T: ClassManifest](name: String) = fields[T](_.getName == name) - def methodsNamed[T: ClassManifest](name: String) = methods[T](_.getName == name) + def allFields[T: ClassTag]() = fields[T](_ => true) + def allMethods[T: ClassTag]() = methods[T](m => !isObjectMethodName(m.getName)) + def fieldsNamed[T: ClassTag](name: String) = fields[T](_.getName == name) + def methodsNamed[T: ClassTag](name: String) = methods[T](_.getName == name) - def allGenericStrings[T: ClassManifest]() = + def allGenericStrings[T: ClassTag]() = (allMethods[T]() map mstr) ++ (allFields[T]() map fstr) - def genericStrings[T: ClassManifest](name: String) = + def genericStrings[T: ClassTag](name: String) = (methodsNamed[T](name) map mstr) ++ (fieldsNamed[T](name) map fstr) - def show[T: ClassManifest](name: String = "") = { - println(classManifest[T].erasure.getName) + def show[T: ClassTag](name: String = "") = { + println(classTag[T].erasure.getName) if (name == "") allGenericStrings[T]() foreach println else genericStrings[T](name) foreach println } diff --git a/src/scalacheck/org/scalacheck/Arbitrary.scala b/src/scalacheck/org/scalacheck/Arbitrary.scala index 91d56b0aec..9bb235f917 100644 --- a/src/scalacheck/org/scalacheck/Arbitrary.scala +++ b/src/scalacheck/org/scalacheck/Arbitrary.scala @@ -263,7 +263,7 @@ object Arbitrary { ): Arbitrary[C[T]] = Arbitrary(containerOf[C,T](arbitrary[T])) /** Arbitrary instance of any array. */ - implicit def arbArray[T](implicit a: Arbitrary[T], c: ClassManifest[T] + implicit def arbArray[T](implicit a: Arbitrary[T], c: ClassTag[T] ): Arbitrary[Array[T]] = Arbitrary(containerOf[Array,T](arbitrary[T])) diff --git a/src/scalacheck/org/scalacheck/util/Buildable.scala b/src/scalacheck/org/scalacheck/util/Buildable.scala index 6378e72d4f..662bc6146b 100644 --- a/src/scalacheck/org/scalacheck/util/Buildable.scala +++ b/src/scalacheck/org/scalacheck/util/Buildable.scala @@ -30,7 +30,7 @@ object Buildable { def builder = (new mutable.ListBuffer[T]).mapResult(_.toStream) } - implicit def buildableArray[T](implicit cm: ClassManifest[T]) = + implicit def buildableArray[T](implicit t: ClassTag[T]) = new Buildable[T,Array] { def builder = mutable.ArrayBuilder.make[T] } diff --git a/src/swing/scala/swing/Font.scala.disabled b/src/swing/scala/swing/Font.scala.disabled index 6eebd667bd..9e21eb859c 100644 --- a/src/swing/scala/swing/Font.scala.disabled +++ b/src/swing/scala/swing/Font.scala.disabled @@ -1,36 +1,36 @@ package scala.swing -/*object Font { - def apply(fontFormat: Int, fontFile: java.io.File) = java.awt.Font.createFont(fontFormat, fontFile) - def apply(fontFormat: Int, fontStream: java.io.InputStream) = java.awt.Font.createFont(fontFormat, fontStream) +/*object Font { + def apply(fontFormat: Int, fontFile: java.io.File) = java.awt.Font.createFont(fontFormat, fontFile) + def apply(fontFormat: Int, fontStream: java.io.InputStream) = java.awt.Font.createFont(fontFormat, fontStream) def decode(str: String) = java.awt.Font.decode(str) - + /* TODO: finish implementation /** * See [java.awt.Font.getFont]. */ - def get(attributes: Map[_ <: java.text.AttributedCharacterIterator.Attribute, _]) = + def get(attributes: Map[_ <: java.text.AttributedCharacterIterator.Attribute, _]) = java.awt.Font.getFont(ImmutableMapWrapper(attributes)) - + import java.{util => ju} - private case class ImmutableMapWrapper[A, B](underlying : Map[A, B])(m : ClassManifest[A]) extends ju.AbstractMap[A, B] { + private case class ImmutableMapWrapper[A, B](underlying : Map[A, B])(t : ClassTag[A]) extends ju.AbstractMap[A, B] { self => override def size = underlying.size - override def put(k : A, v : B) = + override def put(k : A, v : B) = throw new UnsupportedOperationException("This is a wrapper that does not support mutation") - override def remove(k : AnyRef) = + override def remove(k : AnyRef) = throw new UnsupportedOperationException("This is a wrapper that does not support mutation") - + override def entrySet : ju.Set[ju.Map.Entry[A, B]] = new ju.AbstractSet[ju.Map.Entry[A, B]] { def size = self.size def iterator = new ju.Iterator[ju.Map.Entry[A, B]] { val ui = underlying.iterator var prev : Option[A] = None - + def hasNext = ui.hasNext - + def next = { val (k, v) = ui.next prev = Some(k) @@ -44,7 +44,7 @@ package scala.swing } } } - + def remove = prev match { case Some(k) => val v = self.remove(k.asInstanceOf[AnyRef]) ; prev = None ; v case _ => throw new IllegalStateException("next must be called at least once before remove") @@ -53,7 +53,7 @@ package scala.swing } } */ - + /** * See [java.awt.Font.getFont]. */ @@ -62,9 +62,9 @@ package scala.swing * See [java.awt.Font.getFont]. */ def get(nm: String, font: Font) = java.awt.Font.getFont(nm, font) - + def Insets(x: Int, y: Int, width: Int, height: Int) = new Insets(x, y, width, height) def Rectangle(x: Int, y: Int, width: Int, height: Int) = new Insets(x, y, width, height) def Point(x: Int, y: Int) = new Point(x, y) - def Dimension(x: Int, y: Int) = new Dimension(x, y) + def Dimension(x: Int, y: Int) = new Dimension(x, y) }*/ \ No newline at end of file diff --git a/test/benchmarks/src/scala/collection/parallel/benchmarks/arrays/Resetting.scala b/test/benchmarks/src/scala/collection/parallel/benchmarks/arrays/Resetting.scala index e6feb59fcd..22d2107f62 100644 --- a/test/benchmarks/src/scala/collection/parallel/benchmarks/arrays/Resetting.scala +++ b/test/benchmarks/src/scala/collection/parallel/benchmarks/arrays/Resetting.scala @@ -4,19 +4,19 @@ package scala.collection.parallel.benchmarks.arrays import scala.collection.parallel.benchmarks._ -abstract class Resetting[T: Manifest](elemcreate: Int => T, sz: Int, p: Int, what: String) +abstract class Resetting[T: ClassTag](elemcreate: Int => T, sz: Int, p: Int, what: String) extends Bench { val size = sz val parallelism = p val runWhat = what - + var anyarray: Array[Any] = null var castarray: AnyRef = null var gencastarray: Array[T] = null var manifarray: Array[T] = null - + reset - + def reset = what match { case "any" => anyarray = new Array[Any](sz) diff --git a/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/MatrixMultiplication.scala b/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/MatrixMultiplication.scala index 5f902ff483..6d5b189c3a 100644 --- a/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/MatrixMultiplication.scala +++ b/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/MatrixMultiplication.scala @@ -16,54 +16,54 @@ class MatrixMultiplication(sz: Int, p: Int, what: String) extends Resettable(sz, p, what, new Cont(_), new Array[Any](_), classOf[Cont]) { def companion = MatrixMultiplication collection.parallel.tasksupport.environment = forkjoinpool - + val a = Matrix.unit[Int](sz) val b = Matrix.unit[Int](sz) var c = new Matrix[Int](sz) - + def runpar = c = a * b //{ c.assignProduct(a, b) } //; println("--------"); c.output } def runseq = throw new UnsupportedOperationException def comparisonMap = collection.Map() - - class Matrix[T](n: Int)(implicit num: Numeric[T], man: Manifest[T]) { + + class Matrix[T](n: Int)(implicit num: Numeric[T], tag: ClassTag[T]) { val array = new Array[T](n * n) - + def apply(y: Int, x: Int) = array(y * n + x) - + def update(y: Int, x: Int, elem: T) = array(y * n + x) = elem - + def *(b: Matrix[T]) = { val m = new Matrix[T](n) m.assignProduct(this, b) m } - + def assignProduct(a: Matrix[T], b: Matrix[T]) = { val range = ParRange(0, n * n, 1, false) for (i <- range) this(i / n, i % n) = calcProduct(a, b, i / n, i % n); } - + private def calcProduct(a: Matrix[T], b: Matrix[T], y: Int, x: Int): T = { import num._ var sum = zero for (i <- 0 until n) sum += a(y, i) * b(i, x) sum } - + def output = for (y <- 0 until n) { for (x <- 0 until n) print(this(y, x)) println } } - + object Matrix { - def unit[T](n: Int)(implicit num: Numeric[T], man: Manifest[T]) = { + def unit[T](n: Int)(implicit num: Numeric[T], tag: ClassTag[T]) = { val m = new Matrix[T](n) for (i <- 0 until n) m(i, i) = num.one m } } - + } diff --git a/test/disabled/presentation/akka.check b/test/disabled/presentation/akka.check index 9cd20ffb1c..5105d85a00 100644 --- a/test/disabled/presentation/akka.check +++ b/test/disabled/presentation/akka.check @@ -153,11 +153,11 @@ retrieved 131 members `method spawn(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef` `method spawnLink(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef` `method spawnLinkRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef` -`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: Manifest[T])akka.actor.ActorRef` -`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: Manifest[T])akka.actor.ActorRef` +`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: ClassTag[T])akka.actor.ActorRef` +`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: ClassTag[T])akka.actor.ActorRef` `method spawnRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef` -`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: Manifest[T])akka.actor.ActorRef` -`method spawn[T <: akka.actor.Actor](implicit evidence$1: Manifest[T])akka.actor.ActorRef` +`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: ClassTag[T])akka.actor.ActorRef` +`method spawn[T <: akka.actor.Actor](implicit evidence$1: ClassTag[T])akka.actor.ActorRef` `method start()akka.actor.ActorRef` `method startLink(actorRef: akka.actor.ActorRef)Unit` `method stop()Unit` @@ -286,11 +286,11 @@ retrieved 131 members `method spawn(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef` `method spawnLink(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef` `method spawnLinkRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef` -`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: Manifest[T])akka.actor.ActorRef` -`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: Manifest[T])akka.actor.ActorRef` +`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: ClassTag[T])akka.actor.ActorRef` +`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: ClassTag[T])akka.actor.ActorRef` `method spawnRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef` -`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: Manifest[T])akka.actor.ActorRef` -`method spawn[T <: akka.actor.Actor](implicit evidence$1: Manifest[T])akka.actor.ActorRef` +`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: ClassTag[T])akka.actor.ActorRef` +`method spawn[T <: akka.actor.Actor](implicit evidence$1: ClassTag[T])akka.actor.ActorRef` `method start()akka.actor.ActorRef` `method startLink(actorRef: akka.actor.ActorRef)Unit` `method stop()Unit` @@ -419,11 +419,11 @@ retrieved 131 members `method spawn(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef` `method spawnLink(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef` `method spawnLinkRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef` -`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: Manifest[T])akka.actor.ActorRef` -`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: Manifest[T])akka.actor.ActorRef` +`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: ClassTag[T])akka.actor.ActorRef` +`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: ClassTag[T])akka.actor.ActorRef` `method spawnRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef` -`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: Manifest[T])akka.actor.ActorRef` -`method spawn[T <: akka.actor.Actor](implicit evidence$1: Manifest[T])akka.actor.ActorRef` +`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: ClassTag[T])akka.actor.ActorRef` +`method spawn[T <: akka.actor.Actor](implicit evidence$1: ClassTag[T])akka.actor.ActorRef` `method start()akka.actor.ActorRef` `method startLink(actorRef: akka.actor.ActorRef)Unit` `method stop()Unit` diff --git a/test/disabled/presentation/akka/src/akka/actor/Actor.scala b/test/disabled/presentation/akka/src/akka/actor/Actor.scala index b955c4c38b..b9bc51b635 100644 --- a/test/disabled/presentation/akka/src/akka/actor/Actor.scala +++ b/test/disabled/presentation/akka/src/akka/actor/Actor.scala @@ -135,7 +135,7 @@ object Actor extends ListenerManagement { * val actor = actorOf[MyActor].start() * */ - def actorOf[T <: Actor: Manifest]: ActorRef = actorOf(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]]) + def actorOf[T <: Actor: ClassTag]: ActorRef = actorOf(classTag[T].erasure.asInstanceOf[Class[_ <: Actor]]) /** Creates an ActorRef out of the Actor of the specified Class. *
@@ -481,7 +481,7 @@ private[actor] class AnyOptionAsTypedOption(anyOption: Option[Any]) {
   /** Convenience helper to cast the given Option of Any to an Option of the given type. Will swallow a possible
    *  ClassCastException and return None in that case.
    */
-  def asSilently[T: Manifest]: Option[T] = narrowSilently[T](anyOption)
+  def asSilently[T: ClassTag]: Option[T] = narrowSilently[T](anyOption)
 }
 
 /** Marker interface for proxyable actors (such as typed actor).
diff --git a/test/disabled/presentation/akka/src/akka/actor/ActorRef.scala b/test/disabled/presentation/akka/src/akka/actor/ActorRef.scala
index ff67c9468e..da0b63006a 100644
--- a/test/disabled/presentation/akka/src/akka/actor/ActorRef.scala
+++ b/test/disabled/presentation/akka/src/akka/actor/ActorRef.scala
@@ -1406,28 +1406,28 @@ trait ScalaActorRef extends ActorRefShared { ref: ActorRef =>
   /**
    * Atomically create (from actor class) and start an actor.
    */
-  def spawn[T <: Actor: Manifest]: ActorRef =
-    spawn(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]])
+  def spawn[T <: Actor: ClassTag]: ActorRef =
+    spawn(classTag[T].erasure.asInstanceOf[Class[_ <: Actor]])
 
   /**
    * Atomically create (from actor class), start and make an actor remote.
    */
-  def spawnRemote[T <: Actor: Manifest](hostname: String, port: Int, timeout: Long): ActorRef = {
+  def spawnRemote[T <: Actor: ClassTag](hostname: String, port: Int, timeout: Long): ActorRef = {
     ensureRemotingEnabled
-    spawnRemote(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]], hostname, port, timeout)
+    spawnRemote(classTag[T].erasure.asInstanceOf[Class[_ <: Actor]], hostname, port, timeout)
   }
 
   /**
    * Atomically create (from actor class), start and link an actor.
    */
-  def spawnLink[T <: Actor: Manifest]: ActorRef =
-    spawnLink(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]])
+  def spawnLink[T <: Actor: ClassTag]: ActorRef =
+    spawnLink(classTag[T].erasure.asInstanceOf[Class[_ <: Actor]])
 
   /**
    * Atomically create (from actor class), start, link and make an actor remote.
    */
-  def spawnLinkRemote[T <: Actor: Manifest](hostname: String, port: Int, timeout: Long): ActorRef = {
+  def spawnLinkRemote[T <: Actor: ClassTag](hostname: String, port: Int, timeout: Long): ActorRef = {
     ensureRemotingEnabled
-    spawnLinkRemote(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]], hostname, port, timeout)
+    spawnLinkRemote(classTag[T].erasure.asInstanceOf[Class[_ <: Actor]], hostname, port, timeout)
   }
 }
diff --git a/test/disabled/presentation/akka/src/akka/actor/ActorRegistry.scala b/test/disabled/presentation/akka/src/akka/actor/ActorRegistry.scala
index df335dc8b4..5d649fcd36 100644
--- a/test/disabled/presentation/akka/src/akka/actor/ActorRegistry.scala
+++ b/test/disabled/presentation/akka/src/akka/actor/ActorRegistry.scala
@@ -5,7 +5,7 @@
 package akka.actor
 
 import scala.collection.mutable.{ ListBuffer, Map }
-import scala.reflect.Manifest
+import scala.reflect.ArrayTag
 
 import java.util.concurrent.{ ConcurrentSkipListSet, ConcurrentHashMap }
 import java.util.{ Set => JSet }
@@ -74,10 +74,10 @@ final class ActorRegistry private[actor] () extends ListenerManagement {
   }
 
   /**
-   * Finds all actors that are subtypes of the class passed in as the Manifest argument and supporting passed message.
+   * Finds all actors that are subtypes of the class passed in as the ClassTag argument and supporting passed message.
    */
-  def actorsFor[T <: Actor](message: Any)(implicit manifest: Manifest[T]): Array[ActorRef] =
-    filter(a => manifest.erasure.isAssignableFrom(a.actor.getClass) && a.isDefinedAt(message))
+  def actorsFor[T <: Actor](message: Any)(implicit classTag: ClassTag[T]): Array[ActorRef] =
+    filter(a => classTag.erasure.isAssignableFrom(a.actor.getClass) && a.isDefinedAt(message))
 
   /**
    * Finds all actors that satisfy a predicate.
@@ -93,16 +93,16 @@ final class ActorRegistry private[actor] () extends ListenerManagement {
   }
 
   /**
-   * Finds all actors that are subtypes of the class passed in as the Manifest argument.
+   * Finds all actors that are subtypes of the class passed in as the ClassTag argument.
    */
-  def actorsFor[T <: Actor](implicit manifest: Manifest[T]): Array[ActorRef] =
-    actorsFor[T](manifest.erasure.asInstanceOf[Class[T]])
+  def actorsFor[T <: Actor](implicit classTag: ClassTag[T]): Array[ActorRef] =
+    actorsFor[T](classTag.erasure.asInstanceOf[Class[T]])
 
   /**
    * Finds any actor that matches T. Very expensive, traverses ALL alive actors.
    */
-  def actorFor[T <: Actor](implicit manifest: Manifest[T]): Option[ActorRef] =
-    find({ case a: ActorRef if manifest.erasure.isAssignableFrom(a.actor.getClass) => a })
+  def actorFor[T <: Actor](implicit classTag: ClassTag[T]): Option[ActorRef] =
+    find({ case a: ActorRef if classTag.erasure.isAssignableFrom(a.actor.getClass) => a })
 
   /**
    * Finds all actors of type or sub-type specified by the class passed in as the Class argument.
@@ -166,21 +166,21 @@ final class ActorRegistry private[actor] () extends ListenerManagement {
   }
 
   /**
-   * Finds all typed actors that are subtypes of the class passed in as the Manifest argument.
+   * Finds all typed actors that are subtypes of the class passed in as the ClassTag argument.
    */
-  def typedActorsFor[T <: AnyRef](implicit manifest: Manifest[T]): Array[AnyRef] = {
+  def typedActorsFor[T <: AnyRef](implicit classTag: ClassTag[T]): Array[AnyRef] = {
     TypedActorModule.ensureEnabled
-    typedActorsFor[T](manifest.erasure.asInstanceOf[Class[T]])
+    typedActorsFor[T](classTag.erasure.asInstanceOf[Class[T]])
   }
 
   /**
    * Finds any typed actor that matches T.
    */
-  def typedActorFor[T <: AnyRef](implicit manifest: Manifest[T]): Option[AnyRef] = {
+  def typedActorFor[T <: AnyRef](implicit classTag: ClassTag[T]): Option[AnyRef] = {
     TypedActorModule.ensureEnabled
     def predicate(proxy: AnyRef): Boolean = {
       val actorRef = TypedActorModule.typedActorObjectInstance.get.actorFor(proxy)
-      actorRef.isDefined && manifest.erasure.isAssignableFrom(actorRef.get.actor.getClass)
+      actorRef.isDefined && classTag.erasure.isAssignableFrom(actorRef.get.actor.getClass)
     }
     findTypedActor({ case a: Some[AnyRef] if predicate(a.get) => a })
   }
@@ -279,7 +279,7 @@ final class ActorRegistry private[actor] () extends ListenerManagement {
  *
  * @author Viktor Klang
  */
-class Index[K <: AnyRef, V <: AnyRef: Manifest] {
+class Index[K <: AnyRef, V <: AnyRef: ArrayTag] {
   private val Naught = Array[V]() //Nil for Arrays
   private val container = new ConcurrentHashMap[K, JSet[V]]
   private val emptySet = new ConcurrentSkipListSet[V]
diff --git a/test/disabled/presentation/akka/src/akka/event/EventHandler.scala b/test/disabled/presentation/akka/src/akka/event/EventHandler.scala
index f3176b7c21..af2fee6c47 100644
--- a/test/disabled/presentation/akka/src/akka/event/EventHandler.scala
+++ b/test/disabled/presentation/akka/src/akka/event/EventHandler.scala
@@ -115,8 +115,8 @@ object EventHandler extends ListenerManagement {
       notifyListeners(event)
   }
 
-  def notify[T <: Event: ClassManifest](event: => T) {
-    if (level >= levelFor(classManifest[T].erasure.asInstanceOf[Class[_ <: Event]])) notifyListeners(event)
+  def notify[T <: Event: ClassTag](event: => T) {
+    if (level >= levelFor(classTag[T].erasure.asInstanceOf[Class[_ <: Event]])) notifyListeners(event)
   }
 
   def error(cause: Throwable, instance: AnyRef, message: => String) {
diff --git a/test/disabled/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala b/test/disabled/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala
index 0c5da82294..5219c49dcb 100644
--- a/test/disabled/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala
+++ b/test/disabled/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala
@@ -206,8 +206,8 @@ abstract class RemoteSupport extends ListenerManagement with RemoteServerModule
    * 
*/ @deprecated("Will be removed after 1.1", "1.1") - def actorOf[T <: Actor: Manifest](host: String, port: Int): ActorRef = - clientManagedActorOf(() => createActorFromClass(manifest.erasure), host, port) + def actorOf[T <: Actor: ClassTag](host: String, port: Int): ActorRef = + clientManagedActorOf(() => createActorFromClass(classTag[T].erasure), host, port) protected def createActorFromClass(clazz: Class[_]): Actor = { import ReflectiveAccess.{ createInstance, noParams, noArgs } diff --git a/test/disabled/presentation/akka/src/akka/util/Helpers.scala b/test/disabled/presentation/akka/src/akka/util/Helpers.scala index 48477426c9..0ff45408d0 100644 --- a/test/disabled/presentation/akka/src/akka/util/Helpers.scala +++ b/test/disabled/presentation/akka/src/akka/util/Helpers.scala @@ -37,7 +37,7 @@ object Helpers { * Convenience helper to cast the given Option of Any to an Option of the given type. Will swallow a possible * ClassCastException and return None in that case. */ - def narrowSilently[T: Manifest](o: Option[Any]): Option[T] = + def narrowSilently[T: ClassTag](o: Option[Any]): Option[T] = try { narrow(o) } catch { diff --git a/test/disabled/presentation/simple-tests.check b/test/disabled/presentation/simple-tests.check index b90dfce77c..cdb80ed987 100644 --- a/test/disabled/presentation/simple-tests.check +++ b/test/disabled/presentation/simple-tests.check @@ -244,7 +244,7 @@ TypeMember(method disable,(s: Tester.this.settings.Setting)scala.collection.muta TypeMember(value disable,Tester.this.settings.MultiStringSetting,false,true,) TypeMember(value elidebelow,Tester.this.settings.IntSetting,false,true,) TypeMember(method embeddedDefaults,(loader: java.lang.ClassLoader)Unit,true,true,) -TypeMember(method embeddedDefaults,[T](implicit evidence$1: Manifest[T])Unit,true,true,) +TypeMember(method embeddedDefaults,[T](implicit evidence$1: ClassTag[T])Unit,true,true,) TypeMember(value encoding,Tester.this.settings.StringSetting,false,true,) TypeMember(method ensuring,(cond: (scala.tools.nsc.Settings) => Boolean,msg: => Any)scala.tools.nsc.Settings,true,false,method any2Ensuring) TypeMember(method ensuring,(cond: (scala.tools.nsc.Settings) => Boolean)scala.tools.nsc.Settings,true,false,method any2Ensuring) diff --git a/test/files/jvm/manifests-new.check b/test/files/jvm/manifests-new.check new file mode 100644 index 0000000000..9fca856970 --- /dev/null +++ b/test/files/jvm/manifests-new.check @@ -0,0 +1,58 @@ +x=(), t=ConcreteTypeTag[Unit], k=TypeRef, s=class Unit +x=true, t=ConcreteTypeTag[Boolean], k=TypeRef, s=class Boolean +x=a, t=ConcreteTypeTag[Char], k=TypeRef, s=class Char +x=1, t=ConcreteTypeTag[Int], k=TypeRef, s=class Int +x=abc, t=ConcreteTypeTag[String], k=TypeRef, s=class String +x='abc, t=ConcreteTypeTag[Symbol], k=TypeRef, s=class Symbol + +x=List(()), t=ConcreteTypeTag[List[Unit]], k=TypeRef, s=class List +x=List(true), t=ConcreteTypeTag[List[Boolean]], k=TypeRef, s=class List +x=List(1), t=ConcreteTypeTag[List[Int]], k=TypeRef, s=class List +x=List(abc), t=ConcreteTypeTag[List[String]], k=TypeRef, s=class List +x=List('abc), t=ConcreteTypeTag[List[Symbol]], k=TypeRef, s=class List + +x=[Z, t=ConcreteTypeTag[Array[Boolean]], k=TypeRef, s=class Array +x=[C, t=ConcreteTypeTag[Array[Char]], k=TypeRef, s=class Array +x=[I, t=ConcreteTypeTag[Array[Int]], k=TypeRef, s=class Array +x=[Ljava.lang.String;, t=ConcreteTypeTag[Array[String]], k=TypeRef, s=class Array +x=[Lscala.Symbol;, t=ConcreteTypeTag[Array[Symbol]], k=TypeRef, s=class Array + +x=((),()), t=ConcreteTypeTag[(Unit, Unit)], k=TypeRef, s=class Tuple2 +x=(true,false), t=ConcreteTypeTag[(Boolean, Boolean)], k=TypeRef, s=class Tuple2 +x=(1,2), t=ConcreteTypeTag[(Int, Int)], k=TypeRef, s=class Tuple2 +x=(abc,xyz), t=ConcreteTypeTag[(String, String)], k=TypeRef, s=class Tuple2 +x=('abc,'xyz), t=ConcreteTypeTag[(Symbol, Symbol)], k=TypeRef, s=class Tuple2 + +x=Test$, t=ConcreteTypeTag[Test.type], k=TypeRef, s=object Test +x=scala.collection.immutable.List$, t=ConcreteTypeTag[scala.collection.immutable.List.type], k=TypeRef, s=object List + +x=Foo, t=ConcreteTypeTag[Foo[Int]], k=TypeRef, s=class Foo +x=Foo, t=ConcreteTypeTag[Foo[List[Int]]], k=TypeRef, s=class Foo +x=Foo, t=ConcreteTypeTag[Foo[Foo[Int]]], k=TypeRef, s=class Foo +x=Foo, t=ConcreteTypeTag[Foo[List[Foo[Int]]]], k=TypeRef, s=class Foo + +x=Test1$$anon$1, t=ConcreteTypeTag[Bar[String]], k=RefinedType, s= +x=Test1$$anon$2, t=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-new.scala b/test/files/jvm/manifests-new.scala new file mode 100644 index 0000000000..d02f6ee608 --- /dev/null +++ b/test/files/jvm/manifests-new.scala @@ -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() + + 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 t: reflect.ClassTag[Array[T]]) = + load[Array[T]](x)(t).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 t: ConcreteTypeTag[T]) { + // todo. type tags are not yet serializable +// val t1: ConcreteTypeTag[T] = read(write(t)) + val t1: ConcreteTypeTag[T] = t + val x1 = x.toString.replaceAll("@[0-9a-z]+$", "") + println("x="+x1+", t="+t1+", k="+t1.tpe.kind+", s="+t1.sym.toString) + } +} diff --git a/test/files/jvm/manifests.check b/test/files/jvm/manifests.check deleted file mode 100644 index be8ec2bb5b..0000000000 --- a/test/files/jvm/manifests.check +++ /dev/null @@ -1,56 +0,0 @@ -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.scala b/test/files/jvm/manifests.scala deleted file mode 100644 index 935427f5d4..0000000000 --- a/test/files/jvm/manifests.scala +++ /dev/null @@ -1,112 +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" }); - {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/serialization-new.check b/test/files/jvm/serialization-new.check new file mode 100644 index 0000000000..fa51c6a879 --- /dev/null +++ b/test/files/jvm/serialization-new.check @@ -0,0 +1,313 @@ +a1 = Array[1,2,3] +_a1 = Array[1,2,3] +arrayEquals(a1, _a1): true + +e1 = Left(1) +_e1 = Left(1) +e1 eq _e1: false, _e1 eq e1: false +e1 equals _e1: true, _e1 equals e1: true + +x7 = RoundingMode +y7 = RoundingMode +x7 eq y7: true, y7 eq x7: true +x7 equals y7: true, y7 equals x7: true + +x8 = WeekDay +y8 = WeekDay +x8 eq y8: true, y8 eq x8: true +x8 equals y8: true, y8 equals x8: true + +x9 = UP +y9 = UP +x9 eq y9: true, y9 eq x9: true +x9 equals y9: true, y9 equals x9: true + +x10 = Monday +y10 = Monday +x10 eq y10: true, y10 eq x10: true +x10 equals y10: true, y10 equals x10: true + +x9 eq x10: false, x10 eq x9: false +x9 equals x10: false, x10 equals x9: false +x9 eq y10: false, y10 eq x9: false +x9 equals y10: false, y10 equals x9: false + +f1 = +_f1 = +f1(2): 4, _f1(2): 4 + +xs0 = List(1, 2, 3) +_xs0 = List(1, 2, 3) +xs0 eq _xs0: false, _xs0 eq xs0: false +xs0 equals _xs0: true, _xs0 equals xs0: true + +xs1 = List() +_xs1 = List() +xs1 eq _xs1: true, _xs1 eq xs1: true + +o1 = None +_o1 = None +o1 eq _o1: true, _o1 eq o1: true + +o2 = Some(1) +_o2 = Some(1) +o2 eq _o2: false, _o2 eq o2: false +o2 equals _o2: true, _o2 equals o2: true + +s1 = 'hello +_s1 = 'hello +s1 eq _s1: true, _s1 eq s1: true +s1 equals _s1: true, _s1 equals s1: true + +t1 = (BannerLimit,12345) +_t1 = (BannerLimit,12345) +t1 eq _t1: false, _t1 eq t1: false +t1 equals _t1: true, _t1 equals t1: true + +x = BitSet(1, 2) +y = BitSet(1, 2) +x equals y: true, y equals x: true + +x = BitSet(2, 3) +y = BitSet(2, 3) +x equals y: true, y equals x: true + +x = Map(1 -> A, 2 -> B, 3 -> C) +y = Map(1 -> A, 2 -> B, 3 -> C) +x equals y: true, y equals x: true + +x = Set(1, 2) +y = Set(1, 2) +x equals y: true, y equals x: true + +x = List((buffers,20), (layers,2), (title,3)) +y = List((buffers,20), (layers,2), (title,3)) +x equals y: true, y equals x: true + +x = Map(buffers -> 20, layers -> 2, title -> 3) +y = Map(buffers -> 20, layers -> 2, title -> 3) +x equals y: true, y equals x: true + +x = ListSet(5, 3) +y = ListSet(5, 3) +x equals y: true, y equals x: true + +x = Queue(a, b, c) +y = Queue(a, b, c) +x equals y: true, y equals x: true + +x = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) +y = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) +x equals y: true, y equals x: true + +x = NumericRange(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) +y = NumericRange(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) +x equals y: true, y equals x: true + +x = Map(1 -> A, 2 -> B, 3 -> C) +y = Map(1 -> A, 2 -> B, 3 -> C) +x equals y: true, y equals x: true + +x = TreeSet(1, 2, 3) +y = TreeSet(1, 2, 3) +x equals y: true, y equals x: true + +x = Stack(c, b, a) +y = Stack(c, b, a) +x equals y: true, y equals x: true + +x = Stream(0, ?) +y = Stream(0, ?) +x equals y: true, y equals x: true + +x = Map(42 -> FortyTwo) +y = Map(42 -> FortyTwo) +x equals y: true, y equals x: true + +x = TreeSet(0, 2) +y = TreeSet(0, 2) +x equals y: true, y equals x: true + +x = Vector('a, 'b, 'c) +y = Vector('a, 'b, 'c) +x equals y: true, y equals x: true + +x = ArrayBuffer(one, two) +y = ArrayBuffer(one, two) +x equals y: true, y equals x: true + +x = ArrayBuilder.ofLong +y = ArrayBuilder.ofLong +x equals y: true, y equals x: true + +x = ArrayBuilder.ofFloat +y = ArrayBuilder.ofFloat +x equals y: true, y equals x: true + +x = ArraySeq(1, 2, 3) +y = ArraySeq(1, 2, 3) +x equals y: true, y equals x: true + +x = ArrayStack(3, 2, 20) +y = ArrayStack(3, 2, 20) +x equals y: true, y equals x: true + +x = BitSet(0, 8, 9) +y = BitSet(0, 8, 9) +x equals y: true, y equals x: true + +x = Map(A -> 1, C -> 3, B -> 2) +y = Map(A -> 1, C -> 3, B -> 2) +x equals y: true, y equals x: true + +x = Set(buffers, title, layers) +y = Set(buffers, title, layers) +x equals y: true, y equals x: true + +x = History() +y = History() +x equals y: true, y equals x: true + +x = ListBuffer(white, black) +y = ListBuffer(white, black) +x equals y: true, y equals x: true + +x = Queue(20, 2, 3) +y = Queue(20, 2, 3) +x equals y: true, y equals x: true + +x = Stack(3, 2, 20) +y = Stack(3, 2, 20) +x equals y: true, y equals x: true + +x = abc +y = abc +x equals y: true, y equals x: true + +x = WrappedArray(1, 2, 3) +y = WrappedArray(1, 2, 3) +x equals y: true, y equals x: true + +x = TreeSet(1, 2, 3) +y = TreeSet(1, 2, 3) +x equals y: true, y equals x: true + +x = TrieMap(1 -> one, 2 -> two, 3 -> three) +y = TrieMap(1 -> one, 2 -> two, 3 -> three) +x equals y: true, y equals x: true + +x = xml:src="hello" +y = xml:src="hello" +x equals y: true, y equals x: true + +x = +y = +x equals y: true, y equals x: true + +x = title +y = title +x equals y: true, y equals x: true + +x = + + + + + + + + + + + + + + + + +
Last NameFirst Name
Tom 20
Bob 22
James 19
+ + +y = + + + + + + + + + + + + + + + + +
Last NameFirst Name
Tom 20
Bob 22
James 19
+ + +x equals y: true, y equals x: true + +x = Tim +y = Tim +x equals y: true, y equals x: true + +x = Bob +y = Bob +x equals y: true, y equals x: true + +x = John +y = John +x equals y: true, y equals x: true + +x = Bill +y = Bill +x equals y: true, y equals x: true + +x = Paul +y = Paul +x equals y: true, y equals x: true + +1 +2 +1 +2 + +x = UnrolledBuffer(one, two) +y = UnrolledBuffer(one, two) +x equals y: true, y equals x: true + +x = ParArray(abc, def, etc) +y = ParArray(abc, def, etc) +x equals y: true, y equals x: true + +x = ParHashMap(2 -> 4, 1 -> 2) +y = ParHashMap(2 -> 4, 1 -> 2) +x equals y: true, y equals x: true + +x = ParTrieMap(1 -> 2, 2 -> 4) +y = ParTrieMap(1 -> 2, 2 -> 4) +x equals y: true, y equals x: true + +x = ParHashSet(1, 2, 3) +y = ParHashSet(1, 2, 3) +x equals y: true, y equals x: true + +x = ParRange(0, 1, 2, 3, 4) +y = ParRange(0, 1, 2, 3, 4) +x equals y: true, y equals x: true + +x = ParRange(0, 1, 2, 3) +y = ParRange(0, 1, 2, 3) +x equals y: true, y equals x: true + +x = ParMap(5 -> 1, 10 -> 2) +y = ParMap(5 -> 1, 10 -> 2) +x equals y: true, y equals x: true + +x = ParSet(two, one) +y = ParSet(two, one) +x equals y: true, y equals x: true + diff --git a/test/files/jvm/serialization-new.scala b/test/files/jvm/serialization-new.scala new file mode 100644 index 0000000000..bb971fdf36 --- /dev/null +++ b/test/files/jvm/serialization-new.scala @@ -0,0 +1,651 @@ +//############################################################################ +// Serialization +//############################################################################ + +object Serialize { + @throws(classOf[java.io.IOException]) + def write[A](o: A): Array[Byte] = { + val ba = new java.io.ByteArrayOutputStream(512) + val out = new java.io.ObjectOutputStream(ba) + out.writeObject(o) + out.close() + ba.toByteArray() + } + @throws(classOf[java.io.IOException]) + @throws(classOf[ClassNotFoundException]) + def read[A](buffer: Array[Byte]): A = { + val in = + new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(buffer)) + in.readObject().asInstanceOf[A] + } + def check[A, B](x: A, y: B) { + println("x = " + x) + println("y = " + y) + println("x equals y: " + (x equals y) + ", y equals x: " + (y equals x)) + assert((x equals y) && (y equals x)) + println() + } +} +import Serialize._ + +//############################################################################ +// Test classes in package "scala" + +object Test1_scala { + + private def arrayToString[A](arr: Array[A]): String = + arr.mkString("Array[",",","]") + + private def arrayEquals[A, B](a1: Array[A], a2: Array[B]): Boolean = + (a1.length == a2.length) && + (Iterator.range(0, a1.length) forall { i => a1(i) == a2(i) }) + + object WeekDay extends Enumeration { + type WeekDay = Value + val Monday, Tuesday, Wednesday, Thusday, Friday, Saturday, Sunday = Value + } + import WeekDay._, BigDecimal._, RoundingMode._ + + // in alphabetic order + try { + // Array + val a1 = Array(1, 2, 3) + val _a1: Array[Int] = read(write(a1)) + println("a1 = " + arrayToString(a1)) + println("_a1 = " + arrayToString(_a1)) + println("arrayEquals(a1, _a1): " + arrayEquals(a1, _a1)) + println() + + // Either + val e1 = Left(1) + val _e1: Either[Int, String] = read(write(e1)) + println("e1 = " + e1) + println("_e1 = " + _e1) + println("e1 eq _e1: " + (e1 eq _e1) + ", _e1 eq e1: " + (_e1 eq e1)) + println("e1 equals _e1: " + (e1 equals _e1) + ", _e1 equals e1: " + (_e1 equals e1)) + println() + + // Enumeration + val x7 = BigDecimal.RoundingMode + val y7: RoundingMode.type = read(write(x7)) + println("x7 = " + x7) + println("y7 = " + y7) + println("x7 eq y7: " + (x7 eq y7) + ", y7 eq x7: " + (y7 eq x7)) + println("x7 equals y7: " + (x7 equals y7) + ", y7 equals x7: " + (y7 equals x7)) + println() + + val x8 = WeekDay + val y8: WeekDay.type = read(write(x8)) + println("x8 = " + x8) + println("y8 = " + y8) + println("x8 eq y8: " + (x8 eq y8) + ", y8 eq x8: " + (y8 eq x8)) + println("x8 equals y8: " + (x8 equals y8) + ", y8 equals x8: " + (y8 equals x8)) + println() + + val x9 = UP + val y9: RoundingMode = read(write(x9)) + println("x9 = " + x9) + println("y9 = " + y9) + println("x9 eq y9: " + (x9 eq y9) + ", y9 eq x9: " + (y9 eq x9)) + println("x9 equals y9: " + (x9 equals y9) + ", y9 equals x9: " + (y9 equals x9)) + println() + + val x10 = Monday + val y10: WeekDay = read(write(x10)) + println("x10 = " + x10) + println("y10 = " + y10) + println("x10 eq y10: " + (x10 eq y10) + ", y10 eq x10: " + (y10 eq x10)) + println("x10 equals y10: " + (x10 equals y10) + ", y10 equals x10: " + (y10 equals x10)) + println() + + println("x9 eq x10: " + (x9 eq x10) + ", x10 eq x9: " + (x10 eq x9)) + println("x9 equals x10: " + (x9 equals x10) + ", x10 equals x9: " + (x10 equals x9)) + println("x9 eq y10: " + (x9 eq y10) + ", y10 eq x9: " + (y10 eq x9)) + println("x9 equals y10: " + (x9 equals y10) + ", y10 equals x9: " + (y10 equals x9)) + println() + + // Function + val f1 = { x: Int => 2 * x } + val _f1: Function[Int, Int] = read(write(f1)) + println("f1 = ") + println("_f1 = ") + println("f1(2): " + f1(2) + ", _f1(2): " + _f1(2)) + println() + + // List + val xs0 = List(1, 2, 3) + val _xs0: List[Int] = read(write(xs0)) + println("xs0 = " + xs0) + println("_xs0 = " + _xs0) + println("xs0 eq _xs0: " + (xs0 eq _xs0) + ", _xs0 eq xs0: " + (_xs0 eq xs0)) + println("xs0 equals _xs0: " + (xs0 equals _xs0) + ", _xs0 equals xs0: " + (_xs0 equals xs0)) + println() + + val xs1 = Nil + val _xs1: List[Nothing] = read(write(xs1)) + println("xs1 = " + xs1) + println("_xs1 = " + _xs1) + println("xs1 eq _xs1: " + (xs1 eq _xs1) + ", _xs1 eq xs1: " + (_xs1 eq xs1)) + println() + + // Option + val o1 = None + val _o1: Option[Nothing] = read(write(o1)) + println("o1 = " + o1) + println("_o1 = " + _o1) + println("o1 eq _o1: " + (o1 eq _o1) + ", _o1 eq o1: " + (_o1 eq o1)) + println() + + val o2 = Some(1) + val _o2: Option[Int] = read(write(o2)) + println("o2 = " + o2) + println("_o2 = " + _o2) + println("o2 eq _o2: " + (o2 eq _o2) + ", _o2 eq o2: " + (_o2 eq o2)) + println("o2 equals _o2: " + (o2 equals _o2) + ", _o2 equals o2: " + (_o2 equals o2)) + println() +/* + // Responder + val r1 = Responder.constant("xyz") + val _r1: Responder[String] = read(write(r1)) + check(r1, _r1) +*/ + // Symbol + val s1 = 'hello + val _s1: Symbol = read(write(s1)) + println("s1 = " + s1) + println("_s1 = " + _s1) + println("s1 eq _s1: " + (s1 eq _s1) + ", _s1 eq s1: " + (_s1 eq s1)) + println("s1 equals _s1: " + (s1 equals _s1) + ", _s1 equals s1: " + (_s1 equals s1)) + println() + + // Tuple + val t1 = ("BannerLimit", 12345) + val _t1: (String, Int) = read(write(t1)) + println("t1 = " + t1) + println("_t1 = " + _t1) + println("t1 eq _t1: " + (t1 eq _t1) + ", _t1 eq t1: " + (_t1 eq t1)) + println("t1 equals _t1: " + (t1 equals _t1) + ", _t1 equals t1: " + (_t1 equals t1)) + println() + } + catch { + case e: Exception => + println("Error in Test1_scala: " + e) + throw e + } +} + +//############################################################################ +// Test classes in package "scala.collection.immutable" + +object Test2_immutable { + import scala.collection.immutable.{ + BitSet, HashMap, HashSet, ListMap, ListSet, Queue, Range, SortedMap, + SortedSet, Stack, Stream, TreeMap, TreeSet, Vector} + + // in alphabetic order + try { + // BitSet + val bs1 = BitSet.empty + 1 + 2 + val _bs1: BitSet = read(write(bs1)) + check(bs1, _bs1) + + val bs2 = { + val bs = new collection.mutable.BitSet() + bs += 2; bs += 3 + bs.toImmutable + } + val _bs2: BitSet = read(write(bs2)) + check(bs2, _bs2) + + // HashMap + val hm1 = new HashMap[Int, String] + (1 -> "A", 2 -> "B", 3 -> "C") + val _hm1: HashMap[Int, String] = read(write(hm1)) + check(hm1, _hm1) + + // HashSet + val hs1 = new HashSet[Int] + 1 + 2 + val _hs1: HashSet[Int] = read(write(hs1)) + check(hs1, _hs1) + + // List + val xs1 = List(("buffers", 20), ("layers", 2), ("title", 3)) + val _xs1: List[(String, Int)] = read(write(xs1)) + check(xs1, _xs1) + + // ListMap + val lm1 = new ListMap[String, Int] + ("buffers" -> 20, "layers" -> 2, "title" -> 3) + val _lm1: ListMap[String, Int] = read(write(lm1)) + check(lm1, _lm1) + + // ListSet + val ls1 = new ListSet[Int] + 3 + 5 + val _ls1: ListSet[Int] = read(write(ls1)) + check(ls1, _ls1) + + // Queue + val q1 = Queue("a", "b", "c") + val _q1: Queue[String] = read(write(q1)) + check(q1, _q1) + + // Range + val r1 = 0 until 10 + val _r1: Range = read(write(r1)) + check(r1, _r1) + + val r2 = Range.Long(0L, 10L, 1) + val _r2: r2.type = read(write(r2)) + check(r2, _r2) + + // SortedMap + val sm1 = SortedMap.empty[Int, String] + (2 -> "B", 3 -> "C", 1 -> "A") + val _sm1: SortedMap[Int, String] = read(write(sm1)) + check(sm1, _sm1) + + // SortedSet + val ss1 = SortedSet.empty[Int] + 2 + 3 + 1 + val _ss1: SortedSet[Int] = read(write(ss1)) + check(ss1, _ss1) + + // Stack + val s1 = new Stack().push("a", "b", "c") + val _s1: Stack[String] = read(write(s1)) + check(s1, _s1) + + // Stream + val st1 = Stream.range(0, 10) + val _st1: Stream[Int] = read(write(st1)) + check(st1, _st1) + + // TreeMap + val tm1 = new TreeMap[Int, String] + (42 -> "FortyTwo") + val _tm1: TreeMap[Int, String] = read(write(tm1)) + check(tm1, _tm1) + + // TreeSet + val ts1 = new TreeSet[Int]() + 2 + 0 + val _ts1: TreeSet[Int] = read(write(ts1)) + check(ts1, _ts1) + + // Vector + val v1 = Vector('a, 'b, 'c) + val _v1: Vector[Symbol] = read(write(v1)) + check(v1, _v1) + } + catch { + case e: Exception => + println("Error in Test2_immutable: " + e) + throw e + } +} + +//############################################################################ +// Test classes in package "scala.collection.mutable" + +object Test3_mutable { + import scala.reflect.ArrayTag + import scala.collection.mutable.{ + ArrayBuffer, ArrayBuilder, ArraySeq, ArrayStack, BitSet, DoubleLinkedList, + HashMap, HashSet, History, LinkedList, ListBuffer, Publisher, Queue, + Stack, StringBuilder, WrappedArray, TreeSet} + import scala.collection.concurrent.TrieMap + + // in alphabetic order + try { + // ArrayBuffer + val ab1 = new ArrayBuffer[String] + ab1 ++= List("one", "two") + val _ab1: ArrayBuffer[String] = read(write(ab1)) + check(ab1, _ab1) + + // ArrayBuilder + val abu1 = ArrayBuilder.make[Long] + val _abu1: ArrayBuilder[ArrayTag[Long]] = read(write(abu1)) + check(abu1, _abu1) + + val abu2 = ArrayBuilder.make[Float] + val _abu2: ArrayBuilder[ArrayTag[Float]] = read(write(abu2)) + check(abu2, _abu2) + + // ArraySeq + val aq1 = ArraySeq(1, 2, 3) + val _aq1: ArraySeq[Int] = read(write(aq1)) + check(aq1, _aq1) + + // ArrayStack + val as1 = new ArrayStack[Int] + as1 ++= List(20, 2, 3).iterator + val _as1: ArrayStack[Int] = read(write(as1)) + check(as1, _as1) + + // BitSet + val bs1 = new BitSet() + bs1 += 0 + bs1 += 8 + bs1 += 9 + val _bs1: BitSet = read(write(bs1)) + check(bs1, _bs1) +/* + // DoubleLinkedList + val dl1 = new DoubleLinkedList[Int](2, null) + dl1.append(new DoubleLinkedList(3, null)) + val _dl1: DoubleLinkedList[Int] = read(write(dl1)) + check(dl1, _dl1) +*/ + // HashMap + val hm1 = new HashMap[String, Int] + hm1 ++= List(("A", 1), ("B", 2), ("C", 3)).iterator + val _hm1: HashMap[String, Int] = read(write(hm1)) + check(hm1, _hm1) + + // HashSet + val hs1 = new HashSet[String] + hs1 ++= List("layers", "buffers", "title").iterator + val _hs1: HashSet[String] = read(write(hs1)) + check(hs1, _hs1) + + val h1 = new History[String, Int] + val _h1: History[String, Int] = read(write(h1)) + check(h1, _h1) +/* + // LinkedList + val ll1 = new LinkedList[Int](2, null) + ll1.append(new LinkedList(3, null)) + val _ll1: LinkedList[Int] = read(write(ll1)) + check(ll1, _ll1) +*/ + // ListBuffer + val lb1 = new ListBuffer[String] + lb1 ++= List("white", "black") + val _lb1: ListBuffer[String] = read(write(lb1)) + check(lb1, _lb1) + + // Queue + val q1 = new Queue[Int] + q1 ++= List(20, 2, 3).iterator + val _q1: Queue[Int] = read(write(q1)) + check(q1, _q1) + + // Stack + val s1 = new Stack[Int] + s1 pushAll q1 + val _s1: Stack[Int] = read(write(s1)) + check(s1, _s1) + + // StringBuilder + val sb1 = new StringBuilder + sb1 append "abc" + val _sb1: StringBuilder = read(write(sb1)) + check(sb1, _sb1) + + // WrappedArray + val wa1 = WrappedArray.make(Array(1, 2, 3)) + val _wa1: WrappedArray[Int] = read(write(wa1)) + check(wa1, _wa1) + + // TreeSet + val ts1 = TreeSet[Int]() ++= Array(1, 2, 3) + val _ts1: TreeSet[Int] = read(write(ts1)) + check(ts1, _ts1) + + // concurrent.TrieMap + val ct1 = TrieMap[Int, String]() ++= Array(1 -> "one", 2 -> "two", 3 -> "three") + val _ct1: TrieMap[Int, String] = read(write(ct1)) + check(ct1, _ct1) + } + catch { + case e: Exception => + println("Error in Test3_mutable: " + e) + throw e + } +} + + +//############################################################################ +// Test classes in package "scala.xml" + +object Test4_xml { + import scala.xml.{Attribute, Document, Elem, Null, PrefixedAttribute, Text} + + case class Person(name: String, age: Int) + + try { + // Attribute + val a1 = new PrefixedAttribute("xml", "src", Text("hello"), Null) + val _a1: Attribute = read(write(a1)) + check(a1, _a1) + + // Document + val d1 = new Document + d1.docElem = + d1.encoding = Some("UTF-8") + val _d1: Document = read(write(d1)) + check(d1, _d1) + + // Elem + val e1 = title; + val _e1: Elem = read(write(e1)) + check(e1, _e1) + + class AddressBook(a: Person*) { + private val people: List[Person] = a.toList + def toXHTML = + + + + + + { for (p <- people) yield + + + + } +
Last NameFirst Name
{ p.name } { p.age.toString() }
; + } + + val people = new AddressBook( + Person("Tom", 20), + Person("Bob", 22), + Person("James", 19)) + + val e2 = + + + { people.toXHTML } + + ; + val _e2: Elem = read(write(e2)) + check(e2, _e2) + } + catch { + case e: Exception => + println("Error in Test4_xml: " + e) + throw e + } +} + +//############################################################################ +// Test user-defined classes WITHOUT nesting + +class Person(_name: String) extends Serializable { + private var name = _name + override def toString() = name + override def equals(that: Any): Boolean = + that.isInstanceOf[Person] && + (name == that.asInstanceOf[Person].name) +} + +class Employee(_name: String) extends Serializable { + private var name = _name + override def toString() = name +} + +object bob extends Employee("Bob") + +object Test5 { + val x1 = new Person("Tim") + val x2 = bob + + try { + val y1: Person = read(write(x1)) + val y2: Employee = read(write(x2)) + + check(x1, y1) + check(x2, y2) + } + catch { + case e: Exception => + println("Error in Test5: " + e) + } +} + +//############################################################################ +// Test user-defined classes WITH nesting + +object Test6 { + object bill extends Employee("Bill") { + val x = paul + } + object paul extends Person("Paul") { + val x = 4 // bill; => StackOverflowException !!! + } + val x1 = new Person("John") + val x2 = bill + val x3 = paul + + try { + val y1: Person = read(write(x1)) + val y2: Employee = read(write(x2)) + val y3: Person = read(write(x3)) + + check(x1, y1) + check(x2, y2) + check(x3, y3) + } + catch { + case e: Exception => + println("Error in Test6: " + e) + } +} + +//############################################################################ +// Nested objects cannot get readresolve automatically because after deserialization +// they would be null (they are treated as lazy vals) +class Outer extends Serializable { + object Inner extends Serializable +} + +object Test7 { + val x = new Outer + x.Inner // initialize + val y:Outer = read(write(x)) + if (y.Inner == null) + println("Inner object is null") +} + +// Verify that transient lazy vals don't get serialized +class WithTransient extends Serializable { + @transient lazy val a1 = 1 + @transient private lazy val a2 = 2 + @transient object B extends Serializable + @transient private object C extends Serializable + + def test = { + println(a1) + println(a2) + if (B == null || C == null) + println("Transient nested object failed to serialize properly") + } +} + +object Test8 { + val x = new WithTransient + x.test + try { + val y:WithTransient = read(write(x)) + y.test + } + catch { + case e: Exception => + println("Error in Test8: " + e) + } +} + +//############################################################################ +// Test code + +object Test { + def main(args: Array[String]) { + Test1_scala + Test2_immutable + Test3_mutable + Test4_xml + Test5 + Test6 + Test7 + Test8 + Test9_parallel + } +} + +//############################################################################ + + +//############################################################################ +// Test classes in package "scala.collection.parallel" and subpackages +object Test9_parallel { + import scala.collection.parallel._ + + try { + println() + + // UnrolledBuffer + val ub = new collection.mutable.UnrolledBuffer[String] + ub ++= List("one", "two") + val _ub: collection.mutable.UnrolledBuffer[String] = read(write(ub)) + check(ub, _ub) + + // mutable.ParArray + val pa = mutable.ParArray("abc", "def", "etc") + val _pa: mutable.ParArray[String] = read(write(pa)) + check(pa, _pa) + + // mutable.ParHashMap + val mpm = mutable.ParHashMap(1 -> 2, 2 -> 4) + val _mpm: mutable.ParHashMap[Int, Int] = read(write(mpm)) + check(mpm, _mpm) + + // mutable.ParTrieMap + val mpc = mutable.ParTrieMap(1 -> 2, 2 -> 4) + val _mpc: mutable.ParTrieMap[Int, Int] = read(write(mpc)) + check(mpc, _mpc) + + // mutable.ParHashSet + val mps = mutable.ParHashSet(1, 2, 3) + val _mps: mutable.ParHashSet[Int] = read(write(mps)) + check(mps, _mps) + + // immutable.ParRange + val pr1 = immutable.ParRange(0, 4, 1, true) + val _pr1: immutable.ParRange = read(write(pr1)) + check(pr1, _pr1) + + val pr2 = immutable.ParRange(0, 4, 1, false) + val _pr2: immutable.ParRange = read(write(pr2)) + check(pr2, _pr2) + + // immutable.ParHashMap + val ipm = immutable.ParHashMap(5 -> 1, 10 -> 2) + val _ipm: immutable.ParHashMap[Int, Int] = read(write(ipm)) + check(ipm, _ipm) + + // immutable.ParHashSet + val ips = immutable.ParHashSet("one", "two") + val _ips: immutable.ParHashSet[String] = read(write(ips)) + check(ips, _ips) + + } catch { + case e: Exception => + println("Error in Test5_parallel: " + e) + throw e + } +} diff --git a/test/files/jvm/serialization.check b/test/files/jvm/serialization.check deleted file mode 100644 index fa51c6a879..0000000000 --- a/test/files/jvm/serialization.check +++ /dev/null @@ -1,313 +0,0 @@ -a1 = Array[1,2,3] -_a1 = Array[1,2,3] -arrayEquals(a1, _a1): true - -e1 = Left(1) -_e1 = Left(1) -e1 eq _e1: false, _e1 eq e1: false -e1 equals _e1: true, _e1 equals e1: true - -x7 = RoundingMode -y7 = RoundingMode -x7 eq y7: true, y7 eq x7: true -x7 equals y7: true, y7 equals x7: true - -x8 = WeekDay -y8 = WeekDay -x8 eq y8: true, y8 eq x8: true -x8 equals y8: true, y8 equals x8: true - -x9 = UP -y9 = UP -x9 eq y9: true, y9 eq x9: true -x9 equals y9: true, y9 equals x9: true - -x10 = Monday -y10 = Monday -x10 eq y10: true, y10 eq x10: true -x10 equals y10: true, y10 equals x10: true - -x9 eq x10: false, x10 eq x9: false -x9 equals x10: false, x10 equals x9: false -x9 eq y10: false, y10 eq x9: false -x9 equals y10: false, y10 equals x9: false - -f1 = -_f1 = -f1(2): 4, _f1(2): 4 - -xs0 = List(1, 2, 3) -_xs0 = List(1, 2, 3) -xs0 eq _xs0: false, _xs0 eq xs0: false -xs0 equals _xs0: true, _xs0 equals xs0: true - -xs1 = List() -_xs1 = List() -xs1 eq _xs1: true, _xs1 eq xs1: true - -o1 = None -_o1 = None -o1 eq _o1: true, _o1 eq o1: true - -o2 = Some(1) -_o2 = Some(1) -o2 eq _o2: false, _o2 eq o2: false -o2 equals _o2: true, _o2 equals o2: true - -s1 = 'hello -_s1 = 'hello -s1 eq _s1: true, _s1 eq s1: true -s1 equals _s1: true, _s1 equals s1: true - -t1 = (BannerLimit,12345) -_t1 = (BannerLimit,12345) -t1 eq _t1: false, _t1 eq t1: false -t1 equals _t1: true, _t1 equals t1: true - -x = BitSet(1, 2) -y = BitSet(1, 2) -x equals y: true, y equals x: true - -x = BitSet(2, 3) -y = BitSet(2, 3) -x equals y: true, y equals x: true - -x = Map(1 -> A, 2 -> B, 3 -> C) -y = Map(1 -> A, 2 -> B, 3 -> C) -x equals y: true, y equals x: true - -x = Set(1, 2) -y = Set(1, 2) -x equals y: true, y equals x: true - -x = List((buffers,20), (layers,2), (title,3)) -y = List((buffers,20), (layers,2), (title,3)) -x equals y: true, y equals x: true - -x = Map(buffers -> 20, layers -> 2, title -> 3) -y = Map(buffers -> 20, layers -> 2, title -> 3) -x equals y: true, y equals x: true - -x = ListSet(5, 3) -y = ListSet(5, 3) -x equals y: true, y equals x: true - -x = Queue(a, b, c) -y = Queue(a, b, c) -x equals y: true, y equals x: true - -x = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) -y = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) -x equals y: true, y equals x: true - -x = NumericRange(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) -y = NumericRange(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) -x equals y: true, y equals x: true - -x = Map(1 -> A, 2 -> B, 3 -> C) -y = Map(1 -> A, 2 -> B, 3 -> C) -x equals y: true, y equals x: true - -x = TreeSet(1, 2, 3) -y = TreeSet(1, 2, 3) -x equals y: true, y equals x: true - -x = Stack(c, b, a) -y = Stack(c, b, a) -x equals y: true, y equals x: true - -x = Stream(0, ?) -y = Stream(0, ?) -x equals y: true, y equals x: true - -x = Map(42 -> FortyTwo) -y = Map(42 -> FortyTwo) -x equals y: true, y equals x: true - -x = TreeSet(0, 2) -y = TreeSet(0, 2) -x equals y: true, y equals x: true - -x = Vector('a, 'b, 'c) -y = Vector('a, 'b, 'c) -x equals y: true, y equals x: true - -x = ArrayBuffer(one, two) -y = ArrayBuffer(one, two) -x equals y: true, y equals x: true - -x = ArrayBuilder.ofLong -y = ArrayBuilder.ofLong -x equals y: true, y equals x: true - -x = ArrayBuilder.ofFloat -y = ArrayBuilder.ofFloat -x equals y: true, y equals x: true - -x = ArraySeq(1, 2, 3) -y = ArraySeq(1, 2, 3) -x equals y: true, y equals x: true - -x = ArrayStack(3, 2, 20) -y = ArrayStack(3, 2, 20) -x equals y: true, y equals x: true - -x = BitSet(0, 8, 9) -y = BitSet(0, 8, 9) -x equals y: true, y equals x: true - -x = Map(A -> 1, C -> 3, B -> 2) -y = Map(A -> 1, C -> 3, B -> 2) -x equals y: true, y equals x: true - -x = Set(buffers, title, layers) -y = Set(buffers, title, layers) -x equals y: true, y equals x: true - -x = History() -y = History() -x equals y: true, y equals x: true - -x = ListBuffer(white, black) -y = ListBuffer(white, black) -x equals y: true, y equals x: true - -x = Queue(20, 2, 3) -y = Queue(20, 2, 3) -x equals y: true, y equals x: true - -x = Stack(3, 2, 20) -y = Stack(3, 2, 20) -x equals y: true, y equals x: true - -x = abc -y = abc -x equals y: true, y equals x: true - -x = WrappedArray(1, 2, 3) -y = WrappedArray(1, 2, 3) -x equals y: true, y equals x: true - -x = TreeSet(1, 2, 3) -y = TreeSet(1, 2, 3) -x equals y: true, y equals x: true - -x = TrieMap(1 -> one, 2 -> two, 3 -> three) -y = TrieMap(1 -> one, 2 -> two, 3 -> three) -x equals y: true, y equals x: true - -x = xml:src="hello" -y = xml:src="hello" -x equals y: true, y equals x: true - -x = -y = -x equals y: true, y equals x: true - -x = title -y = title -x equals y: true, y equals x: true - -x = - - - - - - - - - - - - - - - - -
Last NameFirst Name
Tom 20
Bob 22
James 19
- - -y = - - - - - - - - - - - - - - - - -
Last NameFirst Name
Tom 20
Bob 22
James 19
- - -x equals y: true, y equals x: true - -x = Tim -y = Tim -x equals y: true, y equals x: true - -x = Bob -y = Bob -x equals y: true, y equals x: true - -x = John -y = John -x equals y: true, y equals x: true - -x = Bill -y = Bill -x equals y: true, y equals x: true - -x = Paul -y = Paul -x equals y: true, y equals x: true - -1 -2 -1 -2 - -x = UnrolledBuffer(one, two) -y = UnrolledBuffer(one, two) -x equals y: true, y equals x: true - -x = ParArray(abc, def, etc) -y = ParArray(abc, def, etc) -x equals y: true, y equals x: true - -x = ParHashMap(2 -> 4, 1 -> 2) -y = ParHashMap(2 -> 4, 1 -> 2) -x equals y: true, y equals x: true - -x = ParTrieMap(1 -> 2, 2 -> 4) -y = ParTrieMap(1 -> 2, 2 -> 4) -x equals y: true, y equals x: true - -x = ParHashSet(1, 2, 3) -y = ParHashSet(1, 2, 3) -x equals y: true, y equals x: true - -x = ParRange(0, 1, 2, 3, 4) -y = ParRange(0, 1, 2, 3, 4) -x equals y: true, y equals x: true - -x = ParRange(0, 1, 2, 3) -y = ParRange(0, 1, 2, 3) -x equals y: true, y equals x: true - -x = ParMap(5 -> 1, 10 -> 2) -y = ParMap(5 -> 1, 10 -> 2) -x equals y: true, y equals x: true - -x = ParSet(two, one) -y = ParSet(two, one) -x equals y: true, y equals x: true - diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala deleted file mode 100644 index 9c2f2acdbf..0000000000 --- a/test/files/jvm/serialization.scala +++ /dev/null @@ -1,651 +0,0 @@ -//############################################################################ -// Serialization -//############################################################################ - -object Serialize { - @throws(classOf[java.io.IOException]) - def write[A](o: A): Array[Byte] = { - val ba = new java.io.ByteArrayOutputStream(512) - val out = new java.io.ObjectOutputStream(ba) - out.writeObject(o) - out.close() - ba.toByteArray() - } - @throws(classOf[java.io.IOException]) - @throws(classOf[ClassNotFoundException]) - def read[A](buffer: Array[Byte]): A = { - val in = - new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(buffer)) - in.readObject().asInstanceOf[A] - } - def check[A, B](x: A, y: B) { - println("x = " + x) - println("y = " + y) - println("x equals y: " + (x equals y) + ", y equals x: " + (y equals x)) - assert((x equals y) && (y equals x)) - println() - } -} -import Serialize._ - -//############################################################################ -// Test classes in package "scala" - -object Test1_scala { - - private def arrayToString[A](arr: Array[A]): String = - arr.mkString("Array[",",","]") - - private def arrayEquals[A, B](a1: Array[A], a2: Array[B]): Boolean = - (a1.length == a2.length) && - (Iterator.range(0, a1.length) forall { i => a1(i) == a2(i) }) - - object WeekDay extends Enumeration { - type WeekDay = Value - val Monday, Tuesday, Wednesday, Thusday, Friday, Saturday, Sunday = Value - } - import WeekDay._, BigDecimal._, RoundingMode._ - - // in alphabetic order - try { - // Array - val a1 = Array(1, 2, 3) - val _a1: Array[Int] = read(write(a1)) - println("a1 = " + arrayToString(a1)) - println("_a1 = " + arrayToString(_a1)) - println("arrayEquals(a1, _a1): " + arrayEquals(a1, _a1)) - println() - - // Either - val e1 = Left(1) - val _e1: Either[Int, String] = read(write(e1)) - println("e1 = " + e1) - println("_e1 = " + _e1) - println("e1 eq _e1: " + (e1 eq _e1) + ", _e1 eq e1: " + (_e1 eq e1)) - println("e1 equals _e1: " + (e1 equals _e1) + ", _e1 equals e1: " + (_e1 equals e1)) - println() - - // Enumeration - val x7 = BigDecimal.RoundingMode - val y7: RoundingMode.type = read(write(x7)) - println("x7 = " + x7) - println("y7 = " + y7) - println("x7 eq y7: " + (x7 eq y7) + ", y7 eq x7: " + (y7 eq x7)) - println("x7 equals y7: " + (x7 equals y7) + ", y7 equals x7: " + (y7 equals x7)) - println() - - val x8 = WeekDay - val y8: WeekDay.type = read(write(x8)) - println("x8 = " + x8) - println("y8 = " + y8) - println("x8 eq y8: " + (x8 eq y8) + ", y8 eq x8: " + (y8 eq x8)) - println("x8 equals y8: " + (x8 equals y8) + ", y8 equals x8: " + (y8 equals x8)) - println() - - val x9 = UP - val y9: RoundingMode = read(write(x9)) - println("x9 = " + x9) - println("y9 = " + y9) - println("x9 eq y9: " + (x9 eq y9) + ", y9 eq x9: " + (y9 eq x9)) - println("x9 equals y9: " + (x9 equals y9) + ", y9 equals x9: " + (y9 equals x9)) - println() - - val x10 = Monday - val y10: WeekDay = read(write(x10)) - println("x10 = " + x10) - println("y10 = " + y10) - println("x10 eq y10: " + (x10 eq y10) + ", y10 eq x10: " + (y10 eq x10)) - println("x10 equals y10: " + (x10 equals y10) + ", y10 equals x10: " + (y10 equals x10)) - println() - - println("x9 eq x10: " + (x9 eq x10) + ", x10 eq x9: " + (x10 eq x9)) - println("x9 equals x10: " + (x9 equals x10) + ", x10 equals x9: " + (x10 equals x9)) - println("x9 eq y10: " + (x9 eq y10) + ", y10 eq x9: " + (y10 eq x9)) - println("x9 equals y10: " + (x9 equals y10) + ", y10 equals x9: " + (y10 equals x9)) - println() - - // Function - val f1 = { x: Int => 2 * x } - val _f1: Function[Int, Int] = read(write(f1)) - println("f1 = ") - println("_f1 = ") - println("f1(2): " + f1(2) + ", _f1(2): " + _f1(2)) - println() - - // List - val xs0 = List(1, 2, 3) - val _xs0: List[Int] = read(write(xs0)) - println("xs0 = " + xs0) - println("_xs0 = " + _xs0) - println("xs0 eq _xs0: " + (xs0 eq _xs0) + ", _xs0 eq xs0: " + (_xs0 eq xs0)) - println("xs0 equals _xs0: " + (xs0 equals _xs0) + ", _xs0 equals xs0: " + (_xs0 equals xs0)) - println() - - val xs1 = Nil - val _xs1: List[Nothing] = read(write(xs1)) - println("xs1 = " + xs1) - println("_xs1 = " + _xs1) - println("xs1 eq _xs1: " + (xs1 eq _xs1) + ", _xs1 eq xs1: " + (_xs1 eq xs1)) - println() - - // Option - val o1 = None - val _o1: Option[Nothing] = read(write(o1)) - println("o1 = " + o1) - println("_o1 = " + _o1) - println("o1 eq _o1: " + (o1 eq _o1) + ", _o1 eq o1: " + (_o1 eq o1)) - println() - - val o2 = Some(1) - val _o2: Option[Int] = read(write(o2)) - println("o2 = " + o2) - println("_o2 = " + _o2) - println("o2 eq _o2: " + (o2 eq _o2) + ", _o2 eq o2: " + (_o2 eq o2)) - println("o2 equals _o2: " + (o2 equals _o2) + ", _o2 equals o2: " + (_o2 equals o2)) - println() -/* - // Responder - val r1 = Responder.constant("xyz") - val _r1: Responder[String] = read(write(r1)) - check(r1, _r1) -*/ - // Symbol - val s1 = 'hello - val _s1: Symbol = read(write(s1)) - println("s1 = " + s1) - println("_s1 = " + _s1) - println("s1 eq _s1: " + (s1 eq _s1) + ", _s1 eq s1: " + (_s1 eq s1)) - println("s1 equals _s1: " + (s1 equals _s1) + ", _s1 equals s1: " + (_s1 equals s1)) - println() - - // Tuple - val t1 = ("BannerLimit", 12345) - val _t1: (String, Int) = read(write(t1)) - println("t1 = " + t1) - println("_t1 = " + _t1) - println("t1 eq _t1: " + (t1 eq _t1) + ", _t1 eq t1: " + (_t1 eq t1)) - println("t1 equals _t1: " + (t1 equals _t1) + ", _t1 equals t1: " + (_t1 equals t1)) - println() - } - catch { - case e: Exception => - println("Error in Test1_scala: " + e) - throw e - } -} - -//############################################################################ -// Test classes in package "scala.collection.immutable" - -object Test2_immutable { - import scala.collection.immutable.{ - BitSet, HashMap, HashSet, ListMap, ListSet, Queue, Range, SortedMap, - SortedSet, Stack, Stream, TreeMap, TreeSet, Vector} - - // in alphabetic order - try { - // BitSet - val bs1 = BitSet.empty + 1 + 2 - val _bs1: BitSet = read(write(bs1)) - check(bs1, _bs1) - - val bs2 = { - val bs = new collection.mutable.BitSet() - bs += 2; bs += 3 - bs.toImmutable - } - val _bs2: BitSet = read(write(bs2)) - check(bs2, _bs2) - - // HashMap - val hm1 = new HashMap[Int, String] + (1 -> "A", 2 -> "B", 3 -> "C") - val _hm1: HashMap[Int, String] = read(write(hm1)) - check(hm1, _hm1) - - // HashSet - val hs1 = new HashSet[Int] + 1 + 2 - val _hs1: HashSet[Int] = read(write(hs1)) - check(hs1, _hs1) - - // List - val xs1 = List(("buffers", 20), ("layers", 2), ("title", 3)) - val _xs1: List[(String, Int)] = read(write(xs1)) - check(xs1, _xs1) - - // ListMap - val lm1 = new ListMap[String, Int] + ("buffers" -> 20, "layers" -> 2, "title" -> 3) - val _lm1: ListMap[String, Int] = read(write(lm1)) - check(lm1, _lm1) - - // ListSet - val ls1 = new ListSet[Int] + 3 + 5 - val _ls1: ListSet[Int] = read(write(ls1)) - check(ls1, _ls1) - - // Queue - val q1 = Queue("a", "b", "c") - val _q1: Queue[String] = read(write(q1)) - check(q1, _q1) - - // Range - val r1 = 0 until 10 - val _r1: Range = read(write(r1)) - check(r1, _r1) - - val r2 = Range.Long(0L, 10L, 1) - val _r2: r2.type = read(write(r2)) - check(r2, _r2) - - // SortedMap - val sm1 = SortedMap.empty[Int, String] + (2 -> "B", 3 -> "C", 1 -> "A") - val _sm1: SortedMap[Int, String] = read(write(sm1)) - check(sm1, _sm1) - - // SortedSet - val ss1 = SortedSet.empty[Int] + 2 + 3 + 1 - val _ss1: SortedSet[Int] = read(write(ss1)) - check(ss1, _ss1) - - // Stack - val s1 = new Stack().push("a", "b", "c") - val _s1: Stack[String] = read(write(s1)) - check(s1, _s1) - - // Stream - val st1 = Stream.range(0, 10) - val _st1: Stream[Int] = read(write(st1)) - check(st1, _st1) - - // TreeMap - val tm1 = new TreeMap[Int, String] + (42 -> "FortyTwo") - val _tm1: TreeMap[Int, String] = read(write(tm1)) - check(tm1, _tm1) - - // TreeSet - val ts1 = new TreeSet[Int]() + 2 + 0 - val _ts1: TreeSet[Int] = read(write(ts1)) - check(ts1, _ts1) - - // Vector - val v1 = Vector('a, 'b, 'c) - val _v1: Vector[Symbol] = read(write(v1)) - check(v1, _v1) - } - catch { - case e: Exception => - println("Error in Test2_immutable: " + e) - throw e - } -} - -//############################################################################ -// Test classes in package "scala.collection.mutable" - -object Test3_mutable { - import scala.reflect.ClassManifest - import scala.collection.mutable.{ - ArrayBuffer, ArrayBuilder, ArraySeq, ArrayStack, BitSet, DoubleLinkedList, - HashMap, HashSet, History, LinkedList, ListBuffer, Publisher, Queue, - Stack, StringBuilder, WrappedArray, TreeSet} - import scala.collection.concurrent.TrieMap - - // in alphabetic order - try { - // ArrayBuffer - val ab1 = new ArrayBuffer[String] - ab1 ++= List("one", "two") - val _ab1: ArrayBuffer[String] = read(write(ab1)) - check(ab1, _ab1) - - // ArrayBuilder - val abu1 = ArrayBuilder.make[Long] - val _abu1: ArrayBuilder[ClassManifest[Long]] = read(write(abu1)) - check(abu1, _abu1) - - val abu2 = ArrayBuilder.make[Float] - val _abu2: ArrayBuilder[ClassManifest[Float]] = read(write(abu2)) - check(abu2, _abu2) - - // ArraySeq - val aq1 = ArraySeq(1, 2, 3) - val _aq1: ArraySeq[Int] = read(write(aq1)) - check(aq1, _aq1) - - // ArrayStack - val as1 = new ArrayStack[Int] - as1 ++= List(20, 2, 3).iterator - val _as1: ArrayStack[Int] = read(write(as1)) - check(as1, _as1) - - // BitSet - val bs1 = new BitSet() - bs1 += 0 - bs1 += 8 - bs1 += 9 - val _bs1: BitSet = read(write(bs1)) - check(bs1, _bs1) -/* - // DoubleLinkedList - val dl1 = new DoubleLinkedList[Int](2, null) - dl1.append(new DoubleLinkedList(3, null)) - val _dl1: DoubleLinkedList[Int] = read(write(dl1)) - check(dl1, _dl1) -*/ - // HashMap - val hm1 = new HashMap[String, Int] - hm1 ++= List(("A", 1), ("B", 2), ("C", 3)).iterator - val _hm1: HashMap[String, Int] = read(write(hm1)) - check(hm1, _hm1) - - // HashSet - val hs1 = new HashSet[String] - hs1 ++= List("layers", "buffers", "title").iterator - val _hs1: HashSet[String] = read(write(hs1)) - check(hs1, _hs1) - - val h1 = new History[String, Int] - val _h1: History[String, Int] = read(write(h1)) - check(h1, _h1) -/* - // LinkedList - val ll1 = new LinkedList[Int](2, null) - ll1.append(new LinkedList(3, null)) - val _ll1: LinkedList[Int] = read(write(ll1)) - check(ll1, _ll1) -*/ - // ListBuffer - val lb1 = new ListBuffer[String] - lb1 ++= List("white", "black") - val _lb1: ListBuffer[String] = read(write(lb1)) - check(lb1, _lb1) - - // Queue - val q1 = new Queue[Int] - q1 ++= List(20, 2, 3).iterator - val _q1: Queue[Int] = read(write(q1)) - check(q1, _q1) - - // Stack - val s1 = new Stack[Int] - s1 pushAll q1 - val _s1: Stack[Int] = read(write(s1)) - check(s1, _s1) - - // StringBuilder - val sb1 = new StringBuilder - sb1 append "abc" - val _sb1: StringBuilder = read(write(sb1)) - check(sb1, _sb1) - - // WrappedArray - val wa1 = WrappedArray.make(Array(1, 2, 3)) - val _wa1: WrappedArray[Int] = read(write(wa1)) - check(wa1, _wa1) - - // TreeSet - val ts1 = TreeSet[Int]() ++= Array(1, 2, 3) - val _ts1: TreeSet[Int] = read(write(ts1)) - check(ts1, _ts1) - - // concurrent.TrieMap - val ct1 = TrieMap[Int, String]() ++= Array(1 -> "one", 2 -> "two", 3 -> "three") - val _ct1: TrieMap[Int, String] = read(write(ct1)) - check(ct1, _ct1) - } - catch { - case e: Exception => - println("Error in Test3_mutable: " + e) - throw e - } -} - - -//############################################################################ -// Test classes in package "scala.xml" - -object Test4_xml { - import scala.xml.{Attribute, Document, Elem, Null, PrefixedAttribute, Text} - - case class Person(name: String, age: Int) - - try { - // Attribute - val a1 = new PrefixedAttribute("xml", "src", Text("hello"), Null) - val _a1: Attribute = read(write(a1)) - check(a1, _a1) - - // Document - val d1 = new Document - d1.docElem = - d1.encoding = Some("UTF-8") - val _d1: Document = read(write(d1)) - check(d1, _d1) - - // Elem - val e1 = title; - val _e1: Elem = read(write(e1)) - check(e1, _e1) - - class AddressBook(a: Person*) { - private val people: List[Person] = a.toList - def toXHTML = - - - - - - { for (p <- people) yield - - - - } -
Last NameFirst Name
{ p.name } { p.age.toString() }
; - } - - val people = new AddressBook( - Person("Tom", 20), - Person("Bob", 22), - Person("James", 19)) - - val e2 = - - - { people.toXHTML } - - ; - val _e2: Elem = read(write(e2)) - check(e2, _e2) - } - catch { - case e: Exception => - println("Error in Test4_xml: " + e) - throw e - } -} - -//############################################################################ -// Test user-defined classes WITHOUT nesting - -class Person(_name: String) extends Serializable { - private var name = _name - override def toString() = name - override def equals(that: Any): Boolean = - that.isInstanceOf[Person] && - (name == that.asInstanceOf[Person].name) -} - -class Employee(_name: String) extends Serializable { - private var name = _name - override def toString() = name -} - -object bob extends Employee("Bob") - -object Test5 { - val x1 = new Person("Tim") - val x2 = bob - - try { - val y1: Person = read(write(x1)) - val y2: Employee = read(write(x2)) - - check(x1, y1) - check(x2, y2) - } - catch { - case e: Exception => - println("Error in Test5: " + e) - } -} - -//############################################################################ -// Test user-defined classes WITH nesting - -object Test6 { - object bill extends Employee("Bill") { - val x = paul - } - object paul extends Person("Paul") { - val x = 4 // bill; => StackOverflowException !!! - } - val x1 = new Person("John") - val x2 = bill - val x3 = paul - - try { - val y1: Person = read(write(x1)) - val y2: Employee = read(write(x2)) - val y3: Person = read(write(x3)) - - check(x1, y1) - check(x2, y2) - check(x3, y3) - } - catch { - case e: Exception => - println("Error in Test6: " + e) - } -} - -//############################################################################ -// Nested objects cannot get readresolve automatically because after deserialization -// they would be null (they are treated as lazy vals) -class Outer extends Serializable { - object Inner extends Serializable -} - -object Test7 { - val x = new Outer - x.Inner // initialize - val y:Outer = read(write(x)) - if (y.Inner == null) - println("Inner object is null") -} - -// Verify that transient lazy vals don't get serialized -class WithTransient extends Serializable { - @transient lazy val a1 = 1 - @transient private lazy val a2 = 2 - @transient object B extends Serializable - @transient private object C extends Serializable - - def test = { - println(a1) - println(a2) - if (B == null || C == null) - println("Transient nested object failed to serialize properly") - } -} - -object Test8 { - val x = new WithTransient - x.test - try { - val y:WithTransient = read(write(x)) - y.test - } - catch { - case e: Exception => - println("Error in Test8: " + e) - } -} - -//############################################################################ -// Test code - -object Test { - def main(args: Array[String]) { - Test1_scala - Test2_immutable - Test3_mutable - Test4_xml - Test5 - Test6 - Test7 - Test8 - Test9_parallel - } -} - -//############################################################################ - - -//############################################################################ -// Test classes in package "scala.collection.parallel" and subpackages -object Test9_parallel { - import scala.collection.parallel._ - - try { - println() - - // UnrolledBuffer - val ub = new collection.mutable.UnrolledBuffer[String] - ub ++= List("one", "two") - val _ub: collection.mutable.UnrolledBuffer[String] = read(write(ub)) - check(ub, _ub) - - // mutable.ParArray - val pa = mutable.ParArray("abc", "def", "etc") - val _pa: mutable.ParArray[String] = read(write(pa)) - check(pa, _pa) - - // mutable.ParHashMap - val mpm = mutable.ParHashMap(1 -> 2, 2 -> 4) - val _mpm: mutable.ParHashMap[Int, Int] = read(write(mpm)) - check(mpm, _mpm) - - // mutable.ParTrieMap - val mpc = mutable.ParTrieMap(1 -> 2, 2 -> 4) - val _mpc: mutable.ParTrieMap[Int, Int] = read(write(mpc)) - check(mpc, _mpc) - - // mutable.ParHashSet - val mps = mutable.ParHashSet(1, 2, 3) - val _mps: mutable.ParHashSet[Int] = read(write(mps)) - check(mps, _mps) - - // immutable.ParRange - val pr1 = immutable.ParRange(0, 4, 1, true) - val _pr1: immutable.ParRange = read(write(pr1)) - check(pr1, _pr1) - - val pr2 = immutable.ParRange(0, 4, 1, false) - val _pr2: immutable.ParRange = read(write(pr2)) - check(pr2, _pr2) - - // immutable.ParHashMap - val ipm = immutable.ParHashMap(5 -> 1, 10 -> 2) - val _ipm: immutable.ParHashMap[Int, Int] = read(write(ipm)) - check(ipm, _ipm) - - // immutable.ParHashSet - val ips = immutable.ParHashSet("one", "two") - val _ips: immutable.ParHashSet[String] = read(write(ips)) - check(ips, _ips) - - } catch { - case e: Exception => - println("Error in Test5_parallel: " + e) - throw e - } -} diff --git a/test/files/neg/t2386.check b/test/files/neg/t2386.check deleted file mode 100644 index f70f12535f..0000000000 --- a/test/files/neg/t2386.check +++ /dev/null @@ -1,4 +0,0 @@ -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/t2386.scala b/test/files/neg/t2386.scala deleted file mode 100644 index 56146cc5c3..0000000000 --- a/test/files/neg/t2386.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test { - val a = Array(Array(1, 2), Array("a","b")) -} diff --git a/test/files/neg/t3692-new.check b/test/files/neg/t3692-new.check new file mode 100644 index 0000000000..e013daca74 --- /dev/null +++ b/test/files/neg/t3692-new.check @@ -0,0 +1,4 @@ +t3692-new.scala:15: error: unreachable code + case m2: Map[T, Int] => new java.util.HashMap[T, Integer] + ^ +one error found diff --git a/test/files/neg/t3692-new.flags b/test/files/neg/t3692-new.flags new file mode 100644 index 0000000000..82becdfbfd --- /dev/null +++ b/test/files/neg/t3692-new.flags @@ -0,0 +1 @@ + -Xoldpatmat \ No newline at end of file diff --git a/test/files/neg/t3692-new.scala b/test/files/neg/t3692-new.scala new file mode 100644 index 0000000000..46874b02e3 --- /dev/null +++ b/test/files/neg/t3692-new.scala @@ -0,0 +1,19 @@ +import java.lang.Integer + +object Tester { + def main(args: Array[String]) = { + val map = Map("John" -> 1, "Josh" -> 2) + new Tester().toJavaMap(map) + } +} + +class Tester { + private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: ClassTag[T], m2: ClassTag[V]): java.util.Map[_, _] = { + map match { + case m0: Map[Int, Int] => new java.util.HashMap[Integer, Integer] + case m1: Map[Int, V] => new java.util.HashMap[Integer, V] + case m2: Map[T, Int] => new java.util.HashMap[T, Integer] + case _ => new java.util.HashMap[T, V] + } + } +} \ No newline at end of file diff --git a/test/files/neg/t3692.check b/test/files/neg/t3692.check deleted file mode 100644 index d83abd31e2..0000000000 --- a/test/files/neg/t3692.check +++ /dev/null @@ -1,11 +0,0 @@ -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.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 - case m2: Map[T, Int] => new java.util.HashMap[T, Integer] - ^ -two warnings found -one error found diff --git a/test/files/neg/t3692.flags b/test/files/neg/t3692.flags deleted file mode 100644 index 82becdfbfd..0000000000 --- a/test/files/neg/t3692.flags +++ /dev/null @@ -1 +0,0 @@ - -Xoldpatmat \ No newline at end of file diff --git a/test/files/neg/t3692.scala b/test/files/neg/t3692.scala deleted file mode 100644 index 151535ae94..0000000000 --- a/test/files/neg/t3692.scala +++ /dev/null @@ -1,19 +0,0 @@ -import java.lang.Integer - -object ManifestTester { - def main(args: Array[String]) = { - val map = Map("John" -> 1, "Josh" -> 2) - new ManifestTester().toJavaMap(map) - } -} - -class ManifestTester { - private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = { - map match { - case m0: Map[Int, Int] => new java.util.HashMap[Integer, Integer] - case m1: Map[Int, V] => new java.util.HashMap[Integer, V] - case m2: Map[T, Int] => new java.util.HashMap[T, Integer] - case _ => new java.util.HashMap[T, V] - } - } -} \ No newline at end of file diff --git a/test/files/neg/t5452-new.check b/test/files/neg/t5452-new.check new file mode 100644 index 0000000000..bbd3734f74 --- /dev/null +++ b/test/files/neg/t5452-new.check @@ -0,0 +1,8 @@ +t5452-new.scala:28: error: overloaded method value apply with alternatives: + ()Queryable[CoffeesTable] + (t: Tree)(implicit evidence$2: ClassTag[CoffeesTable])Nothing + (implicit evidence$1: ClassTag[CoffeesTable])Nothing + cannot be applied to (Queryable[CoffeesTable]) + Queryable[CoffeesTable]( q.treeFilter(null) ) + ^ +one error found diff --git a/test/files/neg/t5452-new.scala b/test/files/neg/t5452-new.scala new file mode 100644 index 0000000000..c829de7d7c --- /dev/null +++ b/test/files/neg/t5452-new.scala @@ -0,0 +1,29 @@ +// /scala/trac/5452/a.scala +// Mon Feb 13 22:52:36 PST 2012 + +// import scala.reflect.mirror._ + +trait Tree + +object Bip { + def ??? = sys.error("") +} +import Bip._ + +case class Queryable[T]() { + def treeFilter( t:Tree ) : Queryable[T] = ??? +} + +object Queryable { + def apply[T:ClassTag] = ??? + def apply[T:ClassTag]( t:Tree ) = ??? +} + +trait CoffeesTable{ + def sales : Int +} + +object Test extends App{ + val q = new Queryable[CoffeesTable] + Queryable[CoffeesTable]( q.treeFilter(null) ) +} diff --git a/test/files/neg/t5452.check b/test/files/neg/t5452.check deleted file mode 100644 index 2f35a45509..0000000000 --- a/test/files/neg/t5452.check +++ /dev/null @@ -1,8 +0,0 @@ -t5452.scala:28: error: overloaded method value apply with alternatives: - ()Queryable[CoffeesTable] - (t: Tree)(implicit evidence$2: Manifest[CoffeesTable])Nothing - (implicit evidence$1: Manifest[CoffeesTable])Nothing - cannot be applied to (Queryable[CoffeesTable]) - Queryable[CoffeesTable]( q.treeFilter(null) ) - ^ -one error found diff --git a/test/files/neg/t5452.scala b/test/files/neg/t5452.scala deleted file mode 100644 index 1032db7a4b..0000000000 --- a/test/files/neg/t5452.scala +++ /dev/null @@ -1,29 +0,0 @@ -// /scala/trac/5452/a.scala -// Mon Feb 13 22:52:36 PST 2012 - -// import scala.reflect.mirror._ - -trait Tree - -object Bip { - def ??? = sys.error("") -} -import Bip._ - -case class Queryable[T]() { - def treeFilter( t:Tree ) : Queryable[T] = ??? -} - -object Queryable { - def apply[T:Manifest] = ??? - def apply[T:Manifest]( t:Tree ) = ??? -} - -trait CoffeesTable{ - def sales : Int -} - -object Test extends App{ - val q = new Queryable[CoffeesTable] - Queryable[CoffeesTable]( q.treeFilter(null) ) -} diff --git a/test/files/pos/contextbounds-implicits-new.scala b/test/files/pos/contextbounds-implicits-new.scala new file mode 100644 index 0000000000..71b3cca36f --- /dev/null +++ b/test/files/pos/contextbounds-implicits-new.scala @@ -0,0 +1,8 @@ +/* Tests implicit parameters in the presence of context bounds. + * See Section 7.4 of the Scala Language Specification. + */ +class C { + + def f[T: TypeTag, S: TypeTag](x: T, y: S)(implicit p: C) { } + +} diff --git a/test/files/pos/contextbounds-implicits.scala b/test/files/pos/contextbounds-implicits.scala deleted file mode 100644 index f9113ee320..0000000000 --- a/test/files/pos/contextbounds-implicits.scala +++ /dev/null @@ -1,8 +0,0 @@ -/* Tests implicit parameters in the presence of context bounds. - * See Section 7.4 of the Scala Language Specification. - */ -class C { - - def f[T: Manifest, S: Manifest](x: T, y: S)(implicit p: C) { } - -} diff --git a/test/files/pos/implicits-new.scala b/test/files/pos/implicits-new.scala new file mode 100644 index 0000000000..7eb7e100c3 --- /dev/null +++ b/test/files/pos/implicits-new.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: ArrayTag](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[ConcreteTypeTag[Class[_]]]) +} 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/manifest1-new.scala b/test/files/pos/manifest1-new.scala new file mode 100644 index 0000000000..645bd42665 --- /dev/null +++ b/test/files/pos/manifest1-new.scala @@ -0,0 +1,21 @@ +import scala.reflect.TypeTag + +object Test { + def foo[T](x: T)(implicit m: TypeTag[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: TypeTag[T]; val x: T } + val stringm = implicitly[TypeTag[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 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/nothing_manifest_disambig-new.scala b/test/files/pos/nothing_manifest_disambig-new.scala new file mode 100644 index 0000000000..a60b0fdbf8 --- /dev/null +++ b/test/files/pos/nothing_manifest_disambig-new.scala @@ -0,0 +1,10 @@ +object Test { + def mani[T: TypeTag](xs: T) = xs + mani(List()) + + def listElMani[T: TypeTag](xs: List[T]) = xs + listElMani(List()) + + def foo[A, C](m : C)(implicit ev: C <:< Traversable[A], mani: TypeTag[A]): (C, A, TypeTag[A]) = (m, m.head, mani) + foo(List(1,2,3)) +} \ No newline at end of file diff --git a/test/files/pos/nothing_manifest_disambig.scala b/test/files/pos/nothing_manifest_disambig.scala deleted file mode 100644 index 076742033f..0000000000 --- a/test/files/pos/nothing_manifest_disambig.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Test { - def mani[T: Manifest](xs: T) = xs - mani(List()) - - def listElMani[T: Manifest](xs: List[T]) = xs - listElMani(List()) - - def foo[A, C](m : C)(implicit ev: C <:< Traversable[A], mani: Manifest[A]): (C, A, Manifest[A]) = (m, m.head, mani) - foo(List(1,2,3)) -} \ No newline at end of file diff --git a/test/files/pos/spec-constr-new.scala b/test/files/pos/spec-constr-new.scala new file mode 100644 index 0000000000..7cd02b0680 --- /dev/null +++ b/test/files/pos/spec-constr-new.scala @@ -0,0 +1,7 @@ +class SparseArray2[@specialized(Int) T:ArrayTag](val maxSize: Int, initialLength:Int = 3) { + private var data = new Array[T](initialLength); + private var index = new Array[Int](initialLength); + + // comment out to compile correctly + data.length + 3; +} diff --git a/test/files/pos/spec-constr.scala b/test/files/pos/spec-constr.scala deleted file mode 100644 index e908b65a41..0000000000 --- a/test/files/pos/spec-constr.scala +++ /dev/null @@ -1,7 +0,0 @@ -class SparseArray2[@specialized(Int) T:ClassManifest](val maxSize: Int, initialLength:Int = 3) { - private var data = new Array[T](initialLength); - private var index = new Array[Int](initialLength); - - // comment out to compile correctly - data.length + 3; -} diff --git a/test/files/pos/spec-doubledef-new.scala b/test/files/pos/spec-doubledef-new.scala new file mode 100644 index 0000000000..33f1e82b6e --- /dev/null +++ b/test/files/pos/spec-doubledef-new.scala @@ -0,0 +1,28 @@ +object Test { + def fn[@specialized T, @specialized U](t : T => Int, u : U => Int) : T = + null.asInstanceOf[T] +} + +trait A[@specialized(Int) T] { + var value: T + def getWith[@specialized(Int) Z](f: T => Z) = f(value) +} + +class C extends A[Int] { + var value = 10 + override def getWith[@specialized(Int) Z](f: Int => Z) = f(value) +} + +abstract class B[T, @specialized(scala.Int) U : TypeTag, @specialized(scala.Int) V <% Ordered[V]] { + val u: U + val v: V + + def f(t: T, v2: V): Pair[U, V] = { + val m: Array[U] = null + if (m.isEmpty) { + Pair(u, v) + } else { + Pair(u, v2) + } + } +} diff --git a/test/files/pos/spec-doubledef.scala b/test/files/pos/spec-doubledef.scala deleted file mode 100644 index 86b0d857d3..0000000000 --- a/test/files/pos/spec-doubledef.scala +++ /dev/null @@ -1,28 +0,0 @@ -object Test { - def fn[@specialized T, @specialized U](t : T => Int, u : U => Int) : T = - null.asInstanceOf[T] -} - -trait A[@specialized(Int) T] { - var value: T - def getWith[@specialized(Int) Z](f: T => Z) = f(value) -} - -class C extends A[Int] { - var value = 10 - override def getWith[@specialized(Int) Z](f: Int => Z) = f(value) -} - -abstract class B[T, @specialized(scala.Int) U : Manifest, @specialized(scala.Int) V <% Ordered[V]] { - val u: U - val v: V - - def f(t: T, v2: V): Pair[U, V] = { - val m: Array[U] = null - if (m.isEmpty) { - Pair(u, v) - } else { - Pair(u, v2) - } - } -} diff --git a/test/files/pos/spec-fields-new.scala b/test/files/pos/spec-fields-new.scala new file mode 100644 index 0000000000..ddd8bd6624 --- /dev/null +++ b/test/files/pos/spec-fields-new.scala @@ -0,0 +1,10 @@ +abstract class Foo[@specialized T: ArrayTag, U <: Ordered[U]](x: T, size: Int) { + var y: T + var z: T = x + + def initialSize = 16 + val array = new Array[T](initialSize + size) + + def getZ = z + def setZ(zz: T) = z = zz +} diff --git a/test/files/pos/spec-fields.scala b/test/files/pos/spec-fields.scala deleted file mode 100644 index 26a8c4ffbd..0000000000 --- a/test/files/pos/spec-fields.scala +++ /dev/null @@ -1,10 +0,0 @@ -abstract class Foo[@specialized T: ClassManifest, U <: Ordered[U]](x: T, size: Int) { - var y: T - var z: T = x - - def initialSize = 16 - val array = new Array[T](initialSize + size) - - def getZ = z - def setZ(zz: T) = z = zz -} diff --git a/test/files/pos/spec-params-new.scala b/test/files/pos/spec-params-new.scala new file mode 100644 index 0000000000..5fe0c82d40 --- /dev/null +++ b/test/files/pos/spec-params-new.scala @@ -0,0 +1,32 @@ +class Foo[@specialized A: ArrayTag] { + + // conflicting in bounds, expect a normalized member calling m + // and bridge + implementation in specialized subclasses + // and overloads here according to specialization on A + def m1[@specialized B <: A](x: B, y: A) = + goal(x) + + // conflicting, unsolvable, expect a warning + def m2[@specialized B <: String](x: B) = x.concat("a") + + // conflicting in bounds, no mention of other spec members + // expect an overload here plus implementation in + // compatible specialized subclasses + def m3[@specialized B >: A](x: B) = () + + // non-conflicting, expect a normalized overload implementation here + def m4[@specialized T, U <: Ordered[T]](x: T, y: U) = () + + // non-conflicting, expect a normalized overload implementation here + def m5[@specialized B](x: B) = x + + // non-conflicting, expect a normalized implementation here + // and specialized implementations for all expansions in specialized subclasses + def m6[@specialized B](x: B, y: A) = + goal(y) + + def goal(x: A) = { + val xs = new Array[A](1) + xs(0) = x + } +} diff --git a/test/files/pos/spec-params.scala b/test/files/pos/spec-params.scala deleted file mode 100644 index f522512846..0000000000 --- a/test/files/pos/spec-params.scala +++ /dev/null @@ -1,32 +0,0 @@ -class Foo[@specialized A: ClassManifest] { - - // conflicting in bounds, expect a normalized member calling m - // and bridge + implementation in specialized subclasses - // and overloads here according to specialization on A - def m1[@specialized B <: A](x: B, y: A) = - goal(x) - - // conflicting, unsolvable, expect a warning - def m2[@specialized B <: String](x: B) = x.concat("a") - - // conflicting in bounds, no mention of other spec members - // expect an overload here plus implementation in - // compatible specialized subclasses - def m3[@specialized B >: A](x: B) = () - - // non-conflicting, expect a normalized overload implementation here - def m4[@specialized T, U <: Ordered[T]](x: T, y: U) = () - - // non-conflicting, expect a normalized overload implementation here - def m5[@specialized B](x: B) = x - - // non-conflicting, expect a normalized implementation here - // and specialized implementations for all expansions in specialized subclasses - def m6[@specialized B](x: B, y: A) = - goal(y) - - def goal(x: A) = { - val xs = new Array[A](1) - xs(0) = x - } -} diff --git a/test/files/pos/spec-sparsearray-new.scala b/test/files/pos/spec-sparsearray-new.scala new file mode 100644 index 0000000000..0659bf7926 --- /dev/null +++ b/test/files/pos/spec-sparsearray-new.scala @@ -0,0 +1,24 @@ +import scala.collection.mutable.MapLike + +class SparseArray[@specialized(Int) T:ArrayTag] extends collection.mutable.Map[Int,T] with collection.mutable.MapLike[Int,T,SparseArray[T]] { + override def get(x: Int) = { + val ind = findOffset(x) + if(ind < 0) None else Some(error("ignore")) + } + + /** + * Returns the offset into index and data for the requested vector + * index. If the requested index is not found, the return value is + * negative and can be converted into an insertion point with -(rv+1). + */ + private def findOffset(i : Int) : Int = { + error("impl doesn't matter") + } + + override def apply(i : Int) : T = { error("ignore") } + override def update(i : Int, value : T) = error("ignore") + override def empty = new SparseArray[T] + def -=(ind: Int) = error("ignore") + def +=(kv: (Int,T)) = error("ignore") + override final def iterator = error("ignore") +} diff --git a/test/files/pos/spec-sparsearray.scala b/test/files/pos/spec-sparsearray.scala deleted file mode 100644 index ea7710a785..0000000000 --- a/test/files/pos/spec-sparsearray.scala +++ /dev/null @@ -1,24 +0,0 @@ -import scala.collection.mutable.MapLike - -class SparseArray[@specialized(Int) T:ClassManifest] extends collection.mutable.Map[Int,T] with collection.mutable.MapLike[Int,T,SparseArray[T]] { - override def get(x: Int) = { - val ind = findOffset(x) - if(ind < 0) None else Some(error("ignore")) - } - - /** - * Returns the offset into index and data for the requested vector - * index. If the requested index is not found, the return value is - * negative and can be converted into an insertion point with -(rv+1). - */ - private def findOffset(i : Int) : Int = { - error("impl doesn't matter") - } - - override def apply(i : Int) : T = { error("ignore") } - override def update(i : Int, value : T) = error("ignore") - override def empty = new SparseArray[T] - def -=(ind: Int) = error("ignore") - def +=(kv: (Int,T)) = error("ignore") - override final def iterator = error("ignore") -} diff --git a/test/files/pos/t1381-new.scala b/test/files/pos/t1381-new.scala new file mode 100644 index 0000000000..8781ef4fdb --- /dev/null +++ b/test/files/pos/t1381-new.scala @@ -0,0 +1,31 @@ +import scala.reflect.TypeTag + +class D[V <: Variable] + +class ID[V<:IV] extends D[V] { + type E = V#ValueType + def index(value:E) : Int = 0 + // Comment this out to eliminate crash. Or see below + def index(values:E*) : Iterable[Int] = null +} + +abstract class Variable { + type VT <: Variable + def d : D[VT] = null +} + +abstract class PV[T](initval:T) extends Variable { + type VT <: PV[T] + type ValueType = T +} + +trait IV extends Variable { + type ValueType +} + +abstract class EV[T](initval:T) extends PV[T](initval) with IV { + type VT <: EV[T] + override def d : ID[VT] = null + // Comment this out to eliminate crash + protected var indx = d.index(initval) +} diff --git a/test/files/pos/t1381.scala b/test/files/pos/t1381.scala deleted file mode 100644 index 0762891898..0000000000 --- a/test/files/pos/t1381.scala +++ /dev/null @@ -1,31 +0,0 @@ -import scala.reflect.Manifest - -class D[V <: Variable] - -class ID[V<:IV] extends D[V] { - type E = V#ValueType - def index(value:E) : Int = 0 - // Comment this out to eliminate crash. Or see below - def index(values:E*) : Iterable[Int] = null -} - -abstract class Variable { - type VT <: Variable - def d : D[VT] = null -} - -abstract class PV[T](initval:T) extends Variable { - type VT <: PV[T] - type ValueType = T -} - -trait IV extends Variable { - type ValueType -} - -abstract class EV[T](initval:T) extends PV[T](initval) with IV { - type VT <: EV[T] - override def d : ID[VT] = null - // Comment this out to eliminate crash - protected var indx = d.index(initval) -} diff --git a/test/files/pos/t2795-new.scala b/test/files/pos/t2795-new.scala new file mode 100644 index 0000000000..af9c4e8b1c --- /dev/null +++ b/test/files/pos/t2795-new.scala @@ -0,0 +1,17 @@ +package t1 + +trait Element[T] { +} + +trait Config { + type T <: Element[T] + implicit val m: ArrayTag[T] + // XXX Following works fine: + // type T <: Element[_] +} + +trait Transform { self: Config => + def processBlock(block: Array[T]): Unit = { + var X = new Array[T](1) + } +} diff --git a/test/files/pos/t2795.scala b/test/files/pos/t2795.scala deleted file mode 100644 index 935cb1f444..0000000000 --- a/test/files/pos/t2795.scala +++ /dev/null @@ -1,17 +0,0 @@ -package t1 - -trait Element[T] { -} - -trait Config { - type T <: Element[T] - implicit val m: ClassManifest[T] - // XXX Following works fine: - // type T <: Element[_] -} - -trait Transform { self: Config => - def processBlock(block: Array[T]): Unit = { - var X = new Array[T](1) - } -} diff --git a/test/files/pos/t3363-new.scala b/test/files/pos/t3363-new.scala new file mode 100644 index 0000000000..270462745c --- /dev/null +++ b/test/files/pos/t3363-new.scala @@ -0,0 +1,18 @@ +object TestCase { + + //now matter if you put (abstract) class or trait it will fail in all cases + trait MapOps[T] + + //if fs was reduced to List (generic type with one parameter) then the code compiles + //if you inherit from MapOps[T] instead of MapOps[F] then code compiles fine + implicit def map2ops[T,F](fs: Map[T,F]) = new MapOps[F] { + //if you remove this line, then code compiles + lazy val m: TypeTag[T] = error("just something to make it compile") + def is(xs: List[T]) = List(xs) + } + + def main(args: Array[String]) { + println(Map(1 -> "2") is List(2)) + } + + } diff --git a/test/files/pos/t3363.scala b/test/files/pos/t3363.scala deleted file mode 100755 index bae54084ea..0000000000 --- a/test/files/pos/t3363.scala +++ /dev/null @@ -1,18 +0,0 @@ -object TestCase { - - //now matter if you put (abstract) class or trait it will fail in all cases - trait MapOps[T] - - //if fs was reduced to List (generic type with one parameter) then the code compiles - //if you inherit from MapOps[T] instead of MapOps[F] then code compiles fine - implicit def map2ops[T,F](fs: Map[T,F]) = new MapOps[F] { - //if you remove this line, then code compiles - lazy val m: Manifest[T] = error("just something to make it compile") - def is(xs: List[T]) = List(xs) - } - - def main(args: Array[String]) { - println(Map(1 -> "2") is List(2)) - } - - } diff --git a/test/files/pos/t3498-new.scala b/test/files/pos/t3498-new.scala new file mode 100644 index 0000000000..653c50042a --- /dev/null +++ b/test/files/pos/t3498-new.scala @@ -0,0 +1,15 @@ +abstract class A[T, @specialized(scala.Int) U : ArrayTag] { + def f(state: T): Array[U] +} + +abstract class B extends A[ Array[Byte], Int ] { + type T = Array[Byte] + type U = Int + + val N = 0 + + def f(state: T): Array[U] = + { + new Array[U](N + state(N)) + } +} \ No newline at end of file diff --git a/test/files/pos/t3498.scala b/test/files/pos/t3498.scala deleted file mode 100644 index bcc90ca64c..0000000000 --- a/test/files/pos/t3498.scala +++ /dev/null @@ -1,15 +0,0 @@ -abstract class A[T, @specialized(scala.Int) U : Manifest] { - def f(state: T): Array[U] -} - -abstract class B extends A[ Array[Byte], Int ] { - type T = Array[Byte] - type U = Int - - val N = 0 - - def f(state: T): Array[U] = - { - new Array[U](N + state(N)) - } -} \ No newline at end of file diff --git a/test/files/presentation/ide-bug-1000531.check b/test/files/presentation/ide-bug-1000531.check index ae202001eb..2b48a80d38 100644 --- a/test/files/presentation/ide-bug-1000531.check +++ b/test/files/presentation/ide-bug-1000531.check @@ -99,7 +99,7 @@ retrieved 123 members `method synchronized[T0](x$1: T0)T0` `method take(n: Int)Iterator[B]` `method takeWhile(p: B => Boolean)Iterator[B]` -`method toArray[B >: B](implicit evidence$1: ClassManifest[B])Array[B]` +`method toArray[B >: B](implicit evidence$1: ArrayTag[B])Array[B]` `method toBuffer[B >: B]=> scala.collection.mutable.Buffer[B]` `method toIndexedSeq=> scala.collection.immutable.IndexedSeq[B]` `method toIterable=> Iterable[B]` diff --git a/test/files/run/arrayclone-new.scala b/test/files/run/arrayclone-new.scala new file mode 100644 index 0000000000..a4ba021409 --- /dev/null +++ b/test/files/run/arrayclone-new.scala @@ -0,0 +1,106 @@ +object Test extends App{ + BooleanArrayClone; + ByteArrayClone; + ShortArrayClone; + CharArrayClone; + IntArrayClone; + LongArrayClone; + FloatArrayClone; + DoubleArrayClone; + ObjectArrayClone; + PolymorphicArrayClone; +} + +object BooleanArrayClone{ + val it : Array[Boolean] = Array(true, false); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = false; + assert(it(0) == true) +} + +object ByteArrayClone{ + val it : Array[Byte] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object ShortArrayClone{ + val it : Array[Short] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object CharArrayClone{ + val it : Array[Char] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object IntArrayClone{ + val it : Array[Int] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object LongArrayClone{ + val it : Array[Long] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object FloatArrayClone{ + val it : Array[Float] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object DoubleArrayClone{ + val it : Array[Double] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object ObjectArrayClone{ + val it : Array[String] = Array("1", "0"); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = "0"; + assert(it(0) == "1") +} + +object PolymorphicArrayClone{ + def testIt[T](it : Array[T], one : T, zero : T) = { + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = zero; + assert(it(0) == one) + } + + testIt(Array("one", "two"), "one", "two"); + + class Mangler[T: ArrayTag](ts : T*){ + // this will always be a BoxedAnyArray even after we've unboxed its contents. + val it = ts.toArray[T]; + } + + val mangled = new Mangler[Int](0, 1); + + val y : Array[Int] = mangled.it; // make sure it's unboxed + + testIt(mangled.it, 0, 1); +} diff --git a/test/files/run/arrayclone.scala b/test/files/run/arrayclone.scala deleted file mode 100644 index c9f7556b47..0000000000 --- a/test/files/run/arrayclone.scala +++ /dev/null @@ -1,106 +0,0 @@ -object Test extends App{ - BooleanArrayClone; - ByteArrayClone; - ShortArrayClone; - CharArrayClone; - IntArrayClone; - LongArrayClone; - FloatArrayClone; - DoubleArrayClone; - ObjectArrayClone; - PolymorphicArrayClone; -} - -object BooleanArrayClone{ - val it : Array[Boolean] = Array(true, false); - val cloned = it.clone(); - assert(cloned.sameElements(it)); - cloned(0) = false; - assert(it(0) == true) -} - -object ByteArrayClone{ - val it : Array[Byte] = Array(1, 0); - val cloned = it.clone(); - assert(cloned.sameElements(it)); - cloned(0) = 0; - assert(it(0) == 1) -} - -object ShortArrayClone{ - val it : Array[Short] = Array(1, 0); - val cloned = it.clone(); - assert(cloned.sameElements(it)); - cloned(0) = 0; - assert(it(0) == 1) -} - -object CharArrayClone{ - val it : Array[Char] = Array(1, 0); - val cloned = it.clone(); - assert(cloned.sameElements(it)); - cloned(0) = 0; - assert(it(0) == 1) -} - -object IntArrayClone{ - val it : Array[Int] = Array(1, 0); - val cloned = it.clone(); - assert(cloned.sameElements(it)); - cloned(0) = 0; - assert(it(0) == 1) -} - -object LongArrayClone{ - val it : Array[Long] = Array(1, 0); - val cloned = it.clone(); - assert(cloned.sameElements(it)); - cloned(0) = 0; - assert(it(0) == 1) -} - -object FloatArrayClone{ - val it : Array[Float] = Array(1, 0); - val cloned = it.clone(); - assert(cloned.sameElements(it)); - cloned(0) = 0; - assert(it(0) == 1) -} - -object DoubleArrayClone{ - val it : Array[Double] = Array(1, 0); - val cloned = it.clone(); - assert(cloned.sameElements(it)); - cloned(0) = 0; - assert(it(0) == 1) -} - -object ObjectArrayClone{ - val it : Array[String] = Array("1", "0"); - val cloned = it.clone(); - assert(cloned.sameElements(it)); - cloned(0) = "0"; - assert(it(0) == "1") -} - -object PolymorphicArrayClone{ - def testIt[T](it : Array[T], one : T, zero : T) = { - val cloned = it.clone(); - assert(cloned.sameElements(it)); - cloned(0) = zero; - assert(it(0) == one) - } - - testIt(Array("one", "two"), "one", "two"); - - class Mangler[T: Manifest](ts : T*){ - // this will always be a BoxedAnyArray even after we've unboxed its contents. - val it = ts.toArray[T]; - } - - val mangled = new Mangler[Int](0, 1); - - val y : Array[Int] = mangled.it; // make sure it's unboxed - - testIt(mangled.it, 0, 1); -} diff --git a/test/files/run/ctries-new/DumbHash.scala b/test/files/run/ctries-new/DumbHash.scala new file mode 100644 index 0000000000..8ef325b67c --- /dev/null +++ b/test/files/run/ctries-new/DumbHash.scala @@ -0,0 +1,14 @@ + + + + + + +class DumbHash(val i: Int) { + override def equals(other: Any) = other match { + case that: DumbHash => that.i == this.i + case _ => false + } + override def hashCode = i % 5 + override def toString = "DH(%s)".format(i) +} diff --git a/test/files/run/ctries-new/Wrap.scala b/test/files/run/ctries-new/Wrap.scala new file mode 100644 index 0000000000..7b645c1612 --- /dev/null +++ b/test/files/run/ctries-new/Wrap.scala @@ -0,0 +1,9 @@ + + + + + + +case class Wrap(i: Int) { + override def hashCode = i * 0x9e3775cd +} diff --git a/test/files/run/ctries-new/concmap.scala b/test/files/run/ctries-new/concmap.scala new file mode 100644 index 0000000000..3ec0256afb --- /dev/null +++ b/test/files/run/ctries-new/concmap.scala @@ -0,0 +1,188 @@ + + + +import collection.concurrent.TrieMap + + +object ConcurrentMapSpec extends Spec { + + val initsz = 500 + val secondsz = 750 + + def test() { + "support put" in { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until initsz) assert(ct.put(new Wrap(i), i) == None) + for (i <- 0 until initsz) assert(ct.put(new Wrap(i), -i) == Some(i)) + } + + "support put if absent" in { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until initsz) ct.update(new Wrap(i), i) + for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i)) + for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i)) + for (i <- initsz until secondsz) assert(ct.putIfAbsent(new Wrap(i), -i) == None) + for (i <- initsz until secondsz) assert(ct.putIfAbsent(new Wrap(i), i) == Some(-i)) + } + + "support remove if mapped to a specific value" in { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until initsz) ct.update(new Wrap(i), i) + for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), -i - 1) == false) + for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == true) + for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == false) + } + + "support replace if mapped to a specific value" in { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until initsz) ct.update(new Wrap(i), i) + for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i - 1, -i - 2) == false) + for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == true) + for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == false) + for (i <- initsz until secondsz) assert(ct.replace(new Wrap(i), i, 0) == false) + } + + "support replace if present" in { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until initsz) ct.update(new Wrap(i), i) + for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i) == Some(i)) + for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i) == Some(-i)) + for (i <- initsz until secondsz) assert(ct.replace(new Wrap(i), i) == None) + } + + def assertEqual(a: Any, b: Any) = { + if (a != b) println(a, b) + assert(a == b) + } + + "support replace if mapped to a specific value, using several threads" in { + val ct = new TrieMap[Wrap, Int] + val sz = 55000 + for (i <- 0 until sz) ct.update(new Wrap(i), i) + + class Updater(index: Int, offs: Int) extends Thread { + override def run() { + var repeats = 0 + for (i <- 0 until sz) { + val j = (offs + i) % sz + var k = Int.MaxValue + do { + if (k != Int.MaxValue) repeats += 1 + k = ct.lookup(new Wrap(j)) + } while (!ct.replace(new Wrap(j), k, -k)) + } + //println("Thread %d repeats: %d".format(index, repeats)) + } + } + + val threads = for (i <- 0 until 16) yield new Updater(i, sz / 32 * i) + threads.foreach(_.start()) + threads.foreach(_.join()) + + for (i <- 0 until sz) assertEqual(ct(new Wrap(i)), i) + + val threads2 = for (i <- 0 until 15) yield new Updater(i, sz / 32 * i) + threads2.foreach(_.start()) + threads2.foreach(_.join()) + + for (i <- 0 until sz) assertEqual(ct(new Wrap(i)), -i) + } + + "support put if absent, several threads" in { + val ct = new TrieMap[Wrap, Int] + val sz = 110000 + + class Updater(offs: Int) extends Thread { + override def run() { + for (i <- 0 until sz) { + val j = (offs + i) % sz + ct.putIfAbsent(new Wrap(j), j) + assert(ct.lookup(new Wrap(j)) == j) + } + } + } + + val threads = for (i <- 0 until 16) yield new Updater(sz / 32 * i) + threads.foreach(_.start()) + threads.foreach(_.join()) + + for (i <- 0 until sz) assert(ct(new Wrap(i)) == i) + } + + "support remove if mapped to a specific value, several threads" in { + val ct = new TrieMap[Wrap, Int] + val sz = 55000 + for (i <- 0 until sz) ct.update(new Wrap(i), i) + + class Remover(offs: Int) extends Thread { + override def run() { + for (i <- 0 until sz) { + val j = (offs + i) % sz + ct.remove(new Wrap(j), j) + assert(ct.get(new Wrap(j)) == None) + } + } + } + + val threads = for (i <- 0 until 16) yield new Remover(sz / 32 * i) + threads.foreach(_.start()) + threads.foreach(_.join()) + + for (i <- 0 until sz) assert(ct.get(new Wrap(i)) == None) + } + + "have all or none of the elements depending on the oddity" in { + val ct = new TrieMap[Wrap, Int] + val sz = 65000 + for (i <- 0 until sz) ct(new Wrap(i)) = i + + class Modifier(index: Int, offs: Int) extends Thread { + override def run() { + for (j <- 0 until sz) { + val i = (offs + j) % sz + var success = false + do { + if (ct.contains(new Wrap(i))) { + success = ct.remove(new Wrap(i)) != None + } else { + success = ct.putIfAbsent(new Wrap(i), i) == None + } + } while (!success) + } + } + } + + def modify(n: Int) = { + val threads = for (i <- 0 until n) yield new Modifier(i, sz / n * i) + threads.foreach(_.start()) + threads.foreach(_.join()) + } + + modify(16) + for (i <- 0 until sz) assertEqual(ct.get(new Wrap(i)), Some(i)) + modify(15) + for (i <- 0 until sz) assertEqual(ct.get(new Wrap(i)), None) + } + + "compute size correctly" in { + val ct = new TrieMap[Wrap, Int] + val sz = 36450 + for (i <- 0 until sz) ct(new Wrap(i)) = i + + assertEqual(ct.size, sz) + assertEqual(ct.size, sz) + } + + "compute size correctly in parallel" in { + val ct = new TrieMap[Wrap, Int] + val sz = 36450 + for (i <- 0 until sz) ct(new Wrap(i)) = i + val pct = ct.par + + assertEqual(pct.size, sz) + assertEqual(pct.size, sz) + } + + } + +} diff --git a/test/files/run/ctries-new/iterator.scala b/test/files/run/ctries-new/iterator.scala new file mode 100644 index 0000000000..b953a40e00 --- /dev/null +++ b/test/files/run/ctries-new/iterator.scala @@ -0,0 +1,289 @@ + + + + +import collection._ +import collection.concurrent.TrieMap + + + +object IteratorSpec extends Spec { + + def test() { + "work for an empty trie" in { + val ct = new TrieMap + val it = ct.iterator + + it.hasNext shouldEqual (false) + evaluating { it.next() }.shouldProduce [NoSuchElementException] + } + + def nonEmptyIteratorCheck(sz: Int) { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct.put(new Wrap(i), i) + + val it = ct.iterator + val tracker = mutable.Map[Wrap, Int]() + for (i <- 0 until sz) { + assert(it.hasNext == true) + tracker += it.next + } + + it.hasNext shouldEqual (false) + evaluating { it.next() }.shouldProduce [NoSuchElementException] + tracker.size shouldEqual (sz) + tracker shouldEqual (ct) + } + + "work for a 1 element trie" in { + nonEmptyIteratorCheck(1) + } + + "work for a 2 element trie" in { + nonEmptyIteratorCheck(2) + } + + "work for a 3 element trie" in { + nonEmptyIteratorCheck(3) + } + + "work for a 5 element trie" in { + nonEmptyIteratorCheck(5) + } + + "work for a 10 element trie" in { + nonEmptyIteratorCheck(10) + } + + "work for a 20 element trie" in { + nonEmptyIteratorCheck(20) + } + + "work for a 50 element trie" in { + nonEmptyIteratorCheck(50) + } + + "work for a 100 element trie" in { + nonEmptyIteratorCheck(100) + } + + "work for a 1k element trie" in { + nonEmptyIteratorCheck(1000) + } + + "work for a 5k element trie" in { + nonEmptyIteratorCheck(5000) + } + + "work for a 75k element trie" in { + nonEmptyIteratorCheck(75000) + } + + "work for a 250k element trie" in { + nonEmptyIteratorCheck(500000) + } + + def nonEmptyCollideCheck(sz: Int) { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until sz) ct.put(new DumbHash(i), i) + + val it = ct.iterator + val tracker = mutable.Map[DumbHash, Int]() + for (i <- 0 until sz) { + assert(it.hasNext == true) + tracker += it.next + } + + it.hasNext shouldEqual (false) + evaluating { it.next() }.shouldProduce [NoSuchElementException] + tracker.size shouldEqual (sz) + tracker shouldEqual (ct) + } + + "work for colliding hashcodes, 2 element trie" in { + nonEmptyCollideCheck(2) + } + + "work for colliding hashcodes, 3 element trie" in { + nonEmptyCollideCheck(3) + } + + "work for colliding hashcodes, 5 element trie" in { + nonEmptyCollideCheck(5) + } + + "work for colliding hashcodes, 10 element trie" in { + nonEmptyCollideCheck(10) + } + + "work for colliding hashcodes, 100 element trie" in { + nonEmptyCollideCheck(100) + } + + "work for colliding hashcodes, 500 element trie" in { + nonEmptyCollideCheck(500) + } + + "work for colliding hashcodes, 5k element trie" in { + nonEmptyCollideCheck(5000) + } + + def assertEqual(a: Map[Wrap, Int], b: Map[Wrap, Int]) { + if (a != b) { + println(a.size + " vs " + b.size) + // println(a) + // println(b) + // println(a.toSeq.sortBy((x: (Wrap, Int)) => x._1.i)) + // println(b.toSeq.sortBy((x: (Wrap, Int)) => x._1.i)) + } + assert(a == b) + } + + "be consistent when taken with concurrent modifications" in { + val sz = 25000 + val W = 15 + val S = 5 + val checks = 5 + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct.put(new Wrap(i), i) + + class Modifier extends Thread { + override def run() { + for (i <- 0 until sz) ct.putIfAbsent(new Wrap(i), i) match { + case Some(_) => ct.remove(new Wrap(i)) + case None => + } + } + } + + def consistentIteration(ct: TrieMap[Wrap, Int], checks: Int) { + class Iter extends Thread { + override def run() { + val snap = ct.readOnlySnapshot() + val initial = mutable.Map[Wrap, Int]() + for (kv <- snap) initial += kv + + for (i <- 0 until checks) { + assertEqual(snap.iterator.toMap, initial) + } + } + } + + val iter = new Iter + iter.start() + iter.join() + } + + val threads = for (_ <- 0 until W) yield new Modifier + threads.foreach(_.start()) + for (_ <- 0 until S) consistentIteration(ct, checks) + threads.foreach(_.join()) + } + + "be consistent with a concurrent removal with a well defined order" in { + val sz = 150000 + val sgroupsize = 10 + val sgroupnum = 5 + val removerslowdown = 50 + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct.put(new Wrap(i), i) + + class Remover extends Thread { + override def run() { + for (i <- 0 until sz) { + assert(ct.remove(new Wrap(i)) == Some(i)) + for (i <- 0 until removerslowdown) ct.get(new Wrap(i)) // slow down, mate + } + //println("done removing") + } + } + + def consistentIteration(it: Iterator[(Wrap, Int)]) = { + class Iter extends Thread { + override def run() { + val elems = it.toBuffer + if (elems.nonEmpty) { + val minelem = elems.minBy((x: (Wrap, Int)) => x._1.i)._1.i + assert(elems.forall(_._1.i >= minelem)) + } + } + } + new Iter + } + + val remover = new Remover + remover.start() + for (_ <- 0 until sgroupnum) { + val iters = for (_ <- 0 until sgroupsize) yield consistentIteration(ct.iterator) + iters.foreach(_.start()) + iters.foreach(_.join()) + } + //println("done with iterators") + remover.join() + } + + "be consistent with a concurrent insertion with a well defined order" in { + val sz = 150000 + val sgroupsize = 10 + val sgroupnum = 10 + val inserterslowdown = 50 + val ct = new TrieMap[Wrap, Int] + + class Inserter extends Thread { + override def run() { + for (i <- 0 until sz) { + assert(ct.put(new Wrap(i), i) == None) + for (i <- 0 until inserterslowdown) ct.get(new Wrap(i)) // slow down, mate + } + //println("done inserting") + } + } + + def consistentIteration(it: Iterator[(Wrap, Int)]) = { + class Iter extends Thread { + override def run() { + val elems = it.toSeq + if (elems.nonEmpty) { + val maxelem = elems.maxBy((x: (Wrap, Int)) => x._1.i)._1.i + assert(elems.forall(_._1.i <= maxelem)) + } + } + } + new Iter + } + + val inserter = new Inserter + inserter.start() + for (_ <- 0 until sgroupnum) { + val iters = for (_ <- 0 until sgroupsize) yield consistentIteration(ct.iterator) + iters.foreach(_.start()) + iters.foreach(_.join()) + } + //println("done with iterators") + inserter.join() + } + + "work on a yet unevaluated snapshot" in { + val sz = 50000 + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct.update(new Wrap(i), i) + + val snap = ct.snapshot() + val it = snap.iterator + + while (it.hasNext) it.next() + } + + "be duplicated" in { + val sz = 50 + val ct = collection.parallel.mutable.ParTrieMap((0 until sz) zip (0 until sz): _*) + val it = ct.splitter + for (_ <- 0 until (sz / 2)) it.next() + val dupit = it.dup + + it.toList shouldEqual dupit.toList + } + + } + +} diff --git a/test/files/run/ctries-new/lnode.scala b/test/files/run/ctries-new/lnode.scala new file mode 100644 index 0000000000..92a31088e5 --- /dev/null +++ b/test/files/run/ctries-new/lnode.scala @@ -0,0 +1,61 @@ + + + +import collection.concurrent.TrieMap + + +object LNodeSpec extends Spec { + + val initsz = 1500 + val secondsz = 1750 + + def test() { + "accept elements with the same hash codes" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) ct.update(new DumbHash(i), i) + } + + "lookup elements with the same hash codes" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) ct.update(new DumbHash(i), i) + for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == Some(i)) + for (i <- initsz until secondsz) assert(ct.get(new DumbHash(i)) == None) + } + + "remove elements with the same hash codes" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) ct.update(new DumbHash(i), i) + for (i <- 0 until initsz) { + val remelem = ct.remove(new DumbHash(i)) + assert(remelem == Some(i), "removing " + i + " yields " + remelem) + } + for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == None) + } + + "put elements with the same hash codes if absent" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) ct.put(new DumbHash(i), i) + for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i) + for (i <- 0 until initsz) assert(ct.putIfAbsent(new DumbHash(i), i) == Some(i)) + for (i <- initsz until secondsz) assert(ct.putIfAbsent(new DumbHash(i), i) == None) + for (i <- initsz until secondsz) assert(ct.lookup(new DumbHash(i)) == i) + } + + "replace elements with the same hash codes" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None) + for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i) + for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i) == Some(i)) + for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == -i) + for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i, i) == true) + } + + "remove elements with the same hash codes if mapped to a specific value" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None) + for (i <- 0 until initsz) assert(ct.remove(new DumbHash(i), i) == true) + } + + } + +} diff --git a/test/files/run/ctries-new/main.scala b/test/files/run/ctries-new/main.scala new file mode 100644 index 0000000000..1d40dab6c5 --- /dev/null +++ b/test/files/run/ctries-new/main.scala @@ -0,0 +1,45 @@ + + + + + + + +object Test { + + def main(args: Array[String]) { + ConcurrentMapSpec.test() + IteratorSpec.test() + LNodeSpec.test() + SnapshotSpec.test() + } + +} + + +trait Spec { + + implicit def str2ops(s: String) = new { + def in[U](body: =>U) { + // just execute body + body + } + } + + implicit def any2ops(a: Any) = new { + def shouldEqual(other: Any) = assert(a == other) + } + + def evaluating[U](body: =>U) = new { + def shouldProduce[T <: Throwable: ClassTag]() = { + var produced = false + try body + catch { + case e => if (e.getClass == implicitly[ClassTag[T]].erasure) produced = true + } finally { + assert(produced, "Did not produce exception of type: " + implicitly[ClassTag[T]]) + } + } + } + +} diff --git a/test/files/run/ctries-new/snapshot.scala b/test/files/run/ctries-new/snapshot.scala new file mode 100644 index 0000000000..5fe77d445b --- /dev/null +++ b/test/files/run/ctries-new/snapshot.scala @@ -0,0 +1,267 @@ + + + + +import collection._ +import collection.concurrent.TrieMap + + + +object SnapshotSpec extends Spec { + + def test() { + "support snapshots" in { + val ctn = new TrieMap + ctn.snapshot() + ctn.readOnlySnapshot() + + val ct = new TrieMap[Int, Int] + for (i <- 0 until 100) ct.put(i, i) + ct.snapshot() + ct.readOnlySnapshot() + } + + "empty 2 quiescent snapshots in isolation" in { + val sz = 4000 + + class Worker(trie: TrieMap[Wrap, Int]) extends Thread { + override def run() { + for (i <- 0 until sz) { + assert(trie.remove(new Wrap(i)) == Some(i)) + for (j <- 0 until sz) + if (j <= i) assert(trie.get(new Wrap(j)) == None) + else assert(trie.get(new Wrap(j)) == Some(j)) + } + } + } + + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct.put(new Wrap(i), i) + val snapt = ct.snapshot() + + val original = new Worker(ct) + val snapshot = new Worker(snapt) + original.start() + snapshot.start() + original.join() + snapshot.join() + + for (i <- 0 until sz) { + assert(ct.get(new Wrap(i)) == None) + assert(snapt.get(new Wrap(i)) == None) + } + } + + def consistentReadOnly(name: String, readonly: Map[Wrap, Int], sz: Int, N: Int) { + @volatile var e: Exception = null + + // reads possible entries once and stores them + // then reads all these N more times to check if the + // state stayed the same + class Reader(trie: Map[Wrap, Int]) extends Thread { + setName("Reader " + name) + + override def run() = + try check() + catch { + case ex: Exception => e = ex + } + + def check() { + val initial = mutable.Map[Wrap, Int]() + for (i <- 0 until sz) trie.get(new Wrap(i)) match { + case Some(i) => initial.put(new Wrap(i), i) + case None => // do nothing + } + + for (k <- 0 until N) { + for (i <- 0 until sz) { + val tres = trie.get(new Wrap(i)) + val ires = initial.get(new Wrap(i)) + if (tres != ires) println(i, "initially: " + ires, "traversal %d: %s".format(k, tres)) + assert(tres == ires) + } + } + } + } + + val reader = new Reader(readonly) + reader.start() + reader.join() + + if (e ne null) { + e.printStackTrace() + throw e + } + } + + // traverses the trie `rep` times and modifies each entry + class Modifier(trie: TrieMap[Wrap, Int], index: Int, rep: Int, sz: Int) extends Thread { + setName("Modifier %d".format(index)) + + override def run() { + for (k <- 0 until rep) { + for (i <- 0 until sz) trie.putIfAbsent(new Wrap(i), i) match { + case Some(_) => trie.remove(new Wrap(i)) + case None => // do nothing + } + } + } + } + + // removes all the elements from the trie + class Remover(trie: TrieMap[Wrap, Int], index: Int, totremovers: Int, sz: Int) extends Thread { + setName("Remover %d".format(index)) + + override def run() { + for (i <- 0 until sz) trie.remove(new Wrap((i + sz / totremovers * index) % sz)) + } + } + + "have a consistent quiescent read-only snapshot" in { + val sz = 10000 + val N = 100 + val W = 10 + + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct(new Wrap(i)) = i + val readonly = ct.readOnlySnapshot() + val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) + + threads.foreach(_.start()) + consistentReadOnly("qm", readonly, sz, N) + threads.foreach(_.join()) + } + + // now, we check non-quiescent snapshots, as these permit situations + // where a thread is caught in the middle of the update when a snapshot is taken + + "have a consistent non-quiescent read-only snapshot, concurrent with removes only" in { + val sz = 1250 + val W = 100 + val S = 5000 + + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct(new Wrap(i)) = i + val threads = for (i <- 0 until W) yield new Remover(ct, i, W, sz) + + threads.foreach(_.start()) + for (i <- 0 until S) consistentReadOnly("non-qr", ct.readOnlySnapshot(), sz, 5) + threads.foreach(_.join()) + } + + "have a consistent non-quiescent read-only snapshot, concurrent with modifications" in { + val sz = 1000 + val N = 7000 + val W = 10 + val S = 7000 + + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct(new Wrap(i)) = i + val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) + + threads.foreach(_.start()) + for (i <- 0 until S) consistentReadOnly("non-qm", ct.readOnlySnapshot(), sz, 5) + threads.foreach(_.join()) + } + + def consistentNonReadOnly(name: String, trie: TrieMap[Wrap, Int], sz: Int, N: Int) { + @volatile var e: Exception = null + + // reads possible entries once and stores them + // then reads all these N more times to check if the + // state stayed the same + class Worker extends Thread { + setName("Worker " + name) + + override def run() = + try check() + catch { + case ex: Exception => e = ex + } + + def check() { + val initial = mutable.Map[Wrap, Int]() + for (i <- 0 until sz) trie.get(new Wrap(i)) match { + case Some(i) => initial.put(new Wrap(i), i) + case None => // do nothing + } + + for (k <- 0 until N) { + // modify + for ((key, value) <- initial) { + val oldv = if (k % 2 == 0) value else -value + val newv = -oldv + trie.replace(key, oldv, newv) + } + + // check + for (i <- 0 until sz) if (initial.contains(new Wrap(i))) { + val expected = if (k % 2 == 0) -i else i + //println(trie.get(new Wrap(i))) + assert(trie.get(new Wrap(i)) == Some(expected)) + } else { + assert(trie.get(new Wrap(i)) == None) + } + } + } + } + + val worker = new Worker + worker.start() + worker.join() + + if (e ne null) { + e.printStackTrace() + throw e + } + } + + "have a consistent non-quiescent snapshot, concurrent with modifications" in { + val sz = 9000 + val N = 1000 + val W = 10 + val S = 400 + + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct(new Wrap(i)) = i + val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) + + threads.foreach(_.start()) + for (i <- 0 until S) { + consistentReadOnly("non-qm", ct.snapshot(), sz, 5) + consistentNonReadOnly("non-qsnap", ct.snapshot(), sz, 5) + } + threads.foreach(_.join()) + } + + "work when many concurrent snapshots are taken, concurrent with modifications" in { + val sz = 12000 + val W = 10 + val S = 10 + val modifytimes = 1200 + val snaptimes = 600 + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct(new Wrap(i)) = i + + class Snapshooter extends Thread { + setName("Snapshooter") + override def run() { + for (k <- 0 until snaptimes) { + val snap = ct.snapshot() + for (i <- 0 until sz) snap.remove(new Wrap(i)) + for (i <- 0 until sz) assert(!snap.contains(new Wrap(i))) + } + } + } + + val mods = for (i <- 0 until W) yield new Modifier(ct, i, modifytimes, sz) + val shooters = for (i <- 0 until S) yield new Snapshooter + val threads = mods ++ shooters + threads.foreach(_.start()) + threads.foreach(_.join()) + } + + } + +} diff --git a/test/files/run/ctries/DumbHash.scala b/test/files/run/ctries/DumbHash.scala deleted file mode 100644 index 8ef325b67c..0000000000 --- a/test/files/run/ctries/DumbHash.scala +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - -class DumbHash(val i: Int) { - override def equals(other: Any) = other match { - case that: DumbHash => that.i == this.i - case _ => false - } - override def hashCode = i % 5 - override def toString = "DH(%s)".format(i) -} diff --git a/test/files/run/ctries/Wrap.scala b/test/files/run/ctries/Wrap.scala deleted file mode 100644 index 7b645c1612..0000000000 --- a/test/files/run/ctries/Wrap.scala +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - -case class Wrap(i: Int) { - override def hashCode = i * 0x9e3775cd -} diff --git a/test/files/run/ctries/concmap.scala b/test/files/run/ctries/concmap.scala deleted file mode 100644 index 3ec0256afb..0000000000 --- a/test/files/run/ctries/concmap.scala +++ /dev/null @@ -1,188 +0,0 @@ - - - -import collection.concurrent.TrieMap - - -object ConcurrentMapSpec extends Spec { - - val initsz = 500 - val secondsz = 750 - - def test() { - "support put" in { - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until initsz) assert(ct.put(new Wrap(i), i) == None) - for (i <- 0 until initsz) assert(ct.put(new Wrap(i), -i) == Some(i)) - } - - "support put if absent" in { - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until initsz) ct.update(new Wrap(i), i) - for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i)) - for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i)) - for (i <- initsz until secondsz) assert(ct.putIfAbsent(new Wrap(i), -i) == None) - for (i <- initsz until secondsz) assert(ct.putIfAbsent(new Wrap(i), i) == Some(-i)) - } - - "support remove if mapped to a specific value" in { - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until initsz) ct.update(new Wrap(i), i) - for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), -i - 1) == false) - for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == true) - for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == false) - } - - "support replace if mapped to a specific value" in { - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until initsz) ct.update(new Wrap(i), i) - for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i - 1, -i - 2) == false) - for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == true) - for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == false) - for (i <- initsz until secondsz) assert(ct.replace(new Wrap(i), i, 0) == false) - } - - "support replace if present" in { - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until initsz) ct.update(new Wrap(i), i) - for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i) == Some(i)) - for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i) == Some(-i)) - for (i <- initsz until secondsz) assert(ct.replace(new Wrap(i), i) == None) - } - - def assertEqual(a: Any, b: Any) = { - if (a != b) println(a, b) - assert(a == b) - } - - "support replace if mapped to a specific value, using several threads" in { - val ct = new TrieMap[Wrap, Int] - val sz = 55000 - for (i <- 0 until sz) ct.update(new Wrap(i), i) - - class Updater(index: Int, offs: Int) extends Thread { - override def run() { - var repeats = 0 - for (i <- 0 until sz) { - val j = (offs + i) % sz - var k = Int.MaxValue - do { - if (k != Int.MaxValue) repeats += 1 - k = ct.lookup(new Wrap(j)) - } while (!ct.replace(new Wrap(j), k, -k)) - } - //println("Thread %d repeats: %d".format(index, repeats)) - } - } - - val threads = for (i <- 0 until 16) yield new Updater(i, sz / 32 * i) - threads.foreach(_.start()) - threads.foreach(_.join()) - - for (i <- 0 until sz) assertEqual(ct(new Wrap(i)), i) - - val threads2 = for (i <- 0 until 15) yield new Updater(i, sz / 32 * i) - threads2.foreach(_.start()) - threads2.foreach(_.join()) - - for (i <- 0 until sz) assertEqual(ct(new Wrap(i)), -i) - } - - "support put if absent, several threads" in { - val ct = new TrieMap[Wrap, Int] - val sz = 110000 - - class Updater(offs: Int) extends Thread { - override def run() { - for (i <- 0 until sz) { - val j = (offs + i) % sz - ct.putIfAbsent(new Wrap(j), j) - assert(ct.lookup(new Wrap(j)) == j) - } - } - } - - val threads = for (i <- 0 until 16) yield new Updater(sz / 32 * i) - threads.foreach(_.start()) - threads.foreach(_.join()) - - for (i <- 0 until sz) assert(ct(new Wrap(i)) == i) - } - - "support remove if mapped to a specific value, several threads" in { - val ct = new TrieMap[Wrap, Int] - val sz = 55000 - for (i <- 0 until sz) ct.update(new Wrap(i), i) - - class Remover(offs: Int) extends Thread { - override def run() { - for (i <- 0 until sz) { - val j = (offs + i) % sz - ct.remove(new Wrap(j), j) - assert(ct.get(new Wrap(j)) == None) - } - } - } - - val threads = for (i <- 0 until 16) yield new Remover(sz / 32 * i) - threads.foreach(_.start()) - threads.foreach(_.join()) - - for (i <- 0 until sz) assert(ct.get(new Wrap(i)) == None) - } - - "have all or none of the elements depending on the oddity" in { - val ct = new TrieMap[Wrap, Int] - val sz = 65000 - for (i <- 0 until sz) ct(new Wrap(i)) = i - - class Modifier(index: Int, offs: Int) extends Thread { - override def run() { - for (j <- 0 until sz) { - val i = (offs + j) % sz - var success = false - do { - if (ct.contains(new Wrap(i))) { - success = ct.remove(new Wrap(i)) != None - } else { - success = ct.putIfAbsent(new Wrap(i), i) == None - } - } while (!success) - } - } - } - - def modify(n: Int) = { - val threads = for (i <- 0 until n) yield new Modifier(i, sz / n * i) - threads.foreach(_.start()) - threads.foreach(_.join()) - } - - modify(16) - for (i <- 0 until sz) assertEqual(ct.get(new Wrap(i)), Some(i)) - modify(15) - for (i <- 0 until sz) assertEqual(ct.get(new Wrap(i)), None) - } - - "compute size correctly" in { - val ct = new TrieMap[Wrap, Int] - val sz = 36450 - for (i <- 0 until sz) ct(new Wrap(i)) = i - - assertEqual(ct.size, sz) - assertEqual(ct.size, sz) - } - - "compute size correctly in parallel" in { - val ct = new TrieMap[Wrap, Int] - val sz = 36450 - for (i <- 0 until sz) ct(new Wrap(i)) = i - val pct = ct.par - - assertEqual(pct.size, sz) - assertEqual(pct.size, sz) - } - - } - -} diff --git a/test/files/run/ctries/iterator.scala b/test/files/run/ctries/iterator.scala deleted file mode 100644 index b953a40e00..0000000000 --- a/test/files/run/ctries/iterator.scala +++ /dev/null @@ -1,289 +0,0 @@ - - - - -import collection._ -import collection.concurrent.TrieMap - - - -object IteratorSpec extends Spec { - - def test() { - "work for an empty trie" in { - val ct = new TrieMap - val it = ct.iterator - - it.hasNext shouldEqual (false) - evaluating { it.next() }.shouldProduce [NoSuchElementException] - } - - def nonEmptyIteratorCheck(sz: Int) { - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until sz) ct.put(new Wrap(i), i) - - val it = ct.iterator - val tracker = mutable.Map[Wrap, Int]() - for (i <- 0 until sz) { - assert(it.hasNext == true) - tracker += it.next - } - - it.hasNext shouldEqual (false) - evaluating { it.next() }.shouldProduce [NoSuchElementException] - tracker.size shouldEqual (sz) - tracker shouldEqual (ct) - } - - "work for a 1 element trie" in { - nonEmptyIteratorCheck(1) - } - - "work for a 2 element trie" in { - nonEmptyIteratorCheck(2) - } - - "work for a 3 element trie" in { - nonEmptyIteratorCheck(3) - } - - "work for a 5 element trie" in { - nonEmptyIteratorCheck(5) - } - - "work for a 10 element trie" in { - nonEmptyIteratorCheck(10) - } - - "work for a 20 element trie" in { - nonEmptyIteratorCheck(20) - } - - "work for a 50 element trie" in { - nonEmptyIteratorCheck(50) - } - - "work for a 100 element trie" in { - nonEmptyIteratorCheck(100) - } - - "work for a 1k element trie" in { - nonEmptyIteratorCheck(1000) - } - - "work for a 5k element trie" in { - nonEmptyIteratorCheck(5000) - } - - "work for a 75k element trie" in { - nonEmptyIteratorCheck(75000) - } - - "work for a 250k element trie" in { - nonEmptyIteratorCheck(500000) - } - - def nonEmptyCollideCheck(sz: Int) { - val ct = new TrieMap[DumbHash, Int] - for (i <- 0 until sz) ct.put(new DumbHash(i), i) - - val it = ct.iterator - val tracker = mutable.Map[DumbHash, Int]() - for (i <- 0 until sz) { - assert(it.hasNext == true) - tracker += it.next - } - - it.hasNext shouldEqual (false) - evaluating { it.next() }.shouldProduce [NoSuchElementException] - tracker.size shouldEqual (sz) - tracker shouldEqual (ct) - } - - "work for colliding hashcodes, 2 element trie" in { - nonEmptyCollideCheck(2) - } - - "work for colliding hashcodes, 3 element trie" in { - nonEmptyCollideCheck(3) - } - - "work for colliding hashcodes, 5 element trie" in { - nonEmptyCollideCheck(5) - } - - "work for colliding hashcodes, 10 element trie" in { - nonEmptyCollideCheck(10) - } - - "work for colliding hashcodes, 100 element trie" in { - nonEmptyCollideCheck(100) - } - - "work for colliding hashcodes, 500 element trie" in { - nonEmptyCollideCheck(500) - } - - "work for colliding hashcodes, 5k element trie" in { - nonEmptyCollideCheck(5000) - } - - def assertEqual(a: Map[Wrap, Int], b: Map[Wrap, Int]) { - if (a != b) { - println(a.size + " vs " + b.size) - // println(a) - // println(b) - // println(a.toSeq.sortBy((x: (Wrap, Int)) => x._1.i)) - // println(b.toSeq.sortBy((x: (Wrap, Int)) => x._1.i)) - } - assert(a == b) - } - - "be consistent when taken with concurrent modifications" in { - val sz = 25000 - val W = 15 - val S = 5 - val checks = 5 - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until sz) ct.put(new Wrap(i), i) - - class Modifier extends Thread { - override def run() { - for (i <- 0 until sz) ct.putIfAbsent(new Wrap(i), i) match { - case Some(_) => ct.remove(new Wrap(i)) - case None => - } - } - } - - def consistentIteration(ct: TrieMap[Wrap, Int], checks: Int) { - class Iter extends Thread { - override def run() { - val snap = ct.readOnlySnapshot() - val initial = mutable.Map[Wrap, Int]() - for (kv <- snap) initial += kv - - for (i <- 0 until checks) { - assertEqual(snap.iterator.toMap, initial) - } - } - } - - val iter = new Iter - iter.start() - iter.join() - } - - val threads = for (_ <- 0 until W) yield new Modifier - threads.foreach(_.start()) - for (_ <- 0 until S) consistentIteration(ct, checks) - threads.foreach(_.join()) - } - - "be consistent with a concurrent removal with a well defined order" in { - val sz = 150000 - val sgroupsize = 10 - val sgroupnum = 5 - val removerslowdown = 50 - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until sz) ct.put(new Wrap(i), i) - - class Remover extends Thread { - override def run() { - for (i <- 0 until sz) { - assert(ct.remove(new Wrap(i)) == Some(i)) - for (i <- 0 until removerslowdown) ct.get(new Wrap(i)) // slow down, mate - } - //println("done removing") - } - } - - def consistentIteration(it: Iterator[(Wrap, Int)]) = { - class Iter extends Thread { - override def run() { - val elems = it.toBuffer - if (elems.nonEmpty) { - val minelem = elems.minBy((x: (Wrap, Int)) => x._1.i)._1.i - assert(elems.forall(_._1.i >= minelem)) - } - } - } - new Iter - } - - val remover = new Remover - remover.start() - for (_ <- 0 until sgroupnum) { - val iters = for (_ <- 0 until sgroupsize) yield consistentIteration(ct.iterator) - iters.foreach(_.start()) - iters.foreach(_.join()) - } - //println("done with iterators") - remover.join() - } - - "be consistent with a concurrent insertion with a well defined order" in { - val sz = 150000 - val sgroupsize = 10 - val sgroupnum = 10 - val inserterslowdown = 50 - val ct = new TrieMap[Wrap, Int] - - class Inserter extends Thread { - override def run() { - for (i <- 0 until sz) { - assert(ct.put(new Wrap(i), i) == None) - for (i <- 0 until inserterslowdown) ct.get(new Wrap(i)) // slow down, mate - } - //println("done inserting") - } - } - - def consistentIteration(it: Iterator[(Wrap, Int)]) = { - class Iter extends Thread { - override def run() { - val elems = it.toSeq - if (elems.nonEmpty) { - val maxelem = elems.maxBy((x: (Wrap, Int)) => x._1.i)._1.i - assert(elems.forall(_._1.i <= maxelem)) - } - } - } - new Iter - } - - val inserter = new Inserter - inserter.start() - for (_ <- 0 until sgroupnum) { - val iters = for (_ <- 0 until sgroupsize) yield consistentIteration(ct.iterator) - iters.foreach(_.start()) - iters.foreach(_.join()) - } - //println("done with iterators") - inserter.join() - } - - "work on a yet unevaluated snapshot" in { - val sz = 50000 - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until sz) ct.update(new Wrap(i), i) - - val snap = ct.snapshot() - val it = snap.iterator - - while (it.hasNext) it.next() - } - - "be duplicated" in { - val sz = 50 - val ct = collection.parallel.mutable.ParTrieMap((0 until sz) zip (0 until sz): _*) - val it = ct.splitter - for (_ <- 0 until (sz / 2)) it.next() - val dupit = it.dup - - it.toList shouldEqual dupit.toList - } - - } - -} diff --git a/test/files/run/ctries/lnode.scala b/test/files/run/ctries/lnode.scala deleted file mode 100644 index 92a31088e5..0000000000 --- a/test/files/run/ctries/lnode.scala +++ /dev/null @@ -1,61 +0,0 @@ - - - -import collection.concurrent.TrieMap - - -object LNodeSpec extends Spec { - - val initsz = 1500 - val secondsz = 1750 - - def test() { - "accept elements with the same hash codes" in { - val ct = new TrieMap[DumbHash, Int] - for (i <- 0 until initsz) ct.update(new DumbHash(i), i) - } - - "lookup elements with the same hash codes" in { - val ct = new TrieMap[DumbHash, Int] - for (i <- 0 until initsz) ct.update(new DumbHash(i), i) - for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == Some(i)) - for (i <- initsz until secondsz) assert(ct.get(new DumbHash(i)) == None) - } - - "remove elements with the same hash codes" in { - val ct = new TrieMap[DumbHash, Int] - for (i <- 0 until initsz) ct.update(new DumbHash(i), i) - for (i <- 0 until initsz) { - val remelem = ct.remove(new DumbHash(i)) - assert(remelem == Some(i), "removing " + i + " yields " + remelem) - } - for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == None) - } - - "put elements with the same hash codes if absent" in { - val ct = new TrieMap[DumbHash, Int] - for (i <- 0 until initsz) ct.put(new DumbHash(i), i) - for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i) - for (i <- 0 until initsz) assert(ct.putIfAbsent(new DumbHash(i), i) == Some(i)) - for (i <- initsz until secondsz) assert(ct.putIfAbsent(new DumbHash(i), i) == None) - for (i <- initsz until secondsz) assert(ct.lookup(new DumbHash(i)) == i) - } - - "replace elements with the same hash codes" in { - val ct = new TrieMap[DumbHash, Int] - for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None) - for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i) - for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i) == Some(i)) - for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == -i) - for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i, i) == true) - } - - "remove elements with the same hash codes if mapped to a specific value" in { - val ct = new TrieMap[DumbHash, Int] - for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None) - for (i <- 0 until initsz) assert(ct.remove(new DumbHash(i), i) == true) - } - - } - -} diff --git a/test/files/run/ctries/main.scala b/test/files/run/ctries/main.scala deleted file mode 100644 index 8db7fcef54..0000000000 --- a/test/files/run/ctries/main.scala +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - -object Test { - - def main(args: Array[String]) { - ConcurrentMapSpec.test() - IteratorSpec.test() - LNodeSpec.test() - SnapshotSpec.test() - } - -} - - -trait Spec { - - implicit def str2ops(s: String) = new { - def in[U](body: =>U) { - // just execute body - body - } - } - - implicit def any2ops(a: Any) = new { - def shouldEqual(other: Any) = assert(a == other) - } - - def evaluating[U](body: =>U) = new { - def shouldProduce[T <: Throwable: ClassManifest]() = { - var produced = false - try body - catch { - case e => if (e.getClass == implicitly[ClassManifest[T]].erasure) produced = true - } finally { - assert(produced, "Did not produce exception of type: " + implicitly[ClassManifest[T]]) - } - } - } - -} diff --git a/test/files/run/ctries/snapshot.scala b/test/files/run/ctries/snapshot.scala deleted file mode 100644 index 5fe77d445b..0000000000 --- a/test/files/run/ctries/snapshot.scala +++ /dev/null @@ -1,267 +0,0 @@ - - - - -import collection._ -import collection.concurrent.TrieMap - - - -object SnapshotSpec extends Spec { - - def test() { - "support snapshots" in { - val ctn = new TrieMap - ctn.snapshot() - ctn.readOnlySnapshot() - - val ct = new TrieMap[Int, Int] - for (i <- 0 until 100) ct.put(i, i) - ct.snapshot() - ct.readOnlySnapshot() - } - - "empty 2 quiescent snapshots in isolation" in { - val sz = 4000 - - class Worker(trie: TrieMap[Wrap, Int]) extends Thread { - override def run() { - for (i <- 0 until sz) { - assert(trie.remove(new Wrap(i)) == Some(i)) - for (j <- 0 until sz) - if (j <= i) assert(trie.get(new Wrap(j)) == None) - else assert(trie.get(new Wrap(j)) == Some(j)) - } - } - } - - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until sz) ct.put(new Wrap(i), i) - val snapt = ct.snapshot() - - val original = new Worker(ct) - val snapshot = new Worker(snapt) - original.start() - snapshot.start() - original.join() - snapshot.join() - - for (i <- 0 until sz) { - assert(ct.get(new Wrap(i)) == None) - assert(snapt.get(new Wrap(i)) == None) - } - } - - def consistentReadOnly(name: String, readonly: Map[Wrap, Int], sz: Int, N: Int) { - @volatile var e: Exception = null - - // reads possible entries once and stores them - // then reads all these N more times to check if the - // state stayed the same - class Reader(trie: Map[Wrap, Int]) extends Thread { - setName("Reader " + name) - - override def run() = - try check() - catch { - case ex: Exception => e = ex - } - - def check() { - val initial = mutable.Map[Wrap, Int]() - for (i <- 0 until sz) trie.get(new Wrap(i)) match { - case Some(i) => initial.put(new Wrap(i), i) - case None => // do nothing - } - - for (k <- 0 until N) { - for (i <- 0 until sz) { - val tres = trie.get(new Wrap(i)) - val ires = initial.get(new Wrap(i)) - if (tres != ires) println(i, "initially: " + ires, "traversal %d: %s".format(k, tres)) - assert(tres == ires) - } - } - } - } - - val reader = new Reader(readonly) - reader.start() - reader.join() - - if (e ne null) { - e.printStackTrace() - throw e - } - } - - // traverses the trie `rep` times and modifies each entry - class Modifier(trie: TrieMap[Wrap, Int], index: Int, rep: Int, sz: Int) extends Thread { - setName("Modifier %d".format(index)) - - override def run() { - for (k <- 0 until rep) { - for (i <- 0 until sz) trie.putIfAbsent(new Wrap(i), i) match { - case Some(_) => trie.remove(new Wrap(i)) - case None => // do nothing - } - } - } - } - - // removes all the elements from the trie - class Remover(trie: TrieMap[Wrap, Int], index: Int, totremovers: Int, sz: Int) extends Thread { - setName("Remover %d".format(index)) - - override def run() { - for (i <- 0 until sz) trie.remove(new Wrap((i + sz / totremovers * index) % sz)) - } - } - - "have a consistent quiescent read-only snapshot" in { - val sz = 10000 - val N = 100 - val W = 10 - - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until sz) ct(new Wrap(i)) = i - val readonly = ct.readOnlySnapshot() - val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) - - threads.foreach(_.start()) - consistentReadOnly("qm", readonly, sz, N) - threads.foreach(_.join()) - } - - // now, we check non-quiescent snapshots, as these permit situations - // where a thread is caught in the middle of the update when a snapshot is taken - - "have a consistent non-quiescent read-only snapshot, concurrent with removes only" in { - val sz = 1250 - val W = 100 - val S = 5000 - - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until sz) ct(new Wrap(i)) = i - val threads = for (i <- 0 until W) yield new Remover(ct, i, W, sz) - - threads.foreach(_.start()) - for (i <- 0 until S) consistentReadOnly("non-qr", ct.readOnlySnapshot(), sz, 5) - threads.foreach(_.join()) - } - - "have a consistent non-quiescent read-only snapshot, concurrent with modifications" in { - val sz = 1000 - val N = 7000 - val W = 10 - val S = 7000 - - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until sz) ct(new Wrap(i)) = i - val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) - - threads.foreach(_.start()) - for (i <- 0 until S) consistentReadOnly("non-qm", ct.readOnlySnapshot(), sz, 5) - threads.foreach(_.join()) - } - - def consistentNonReadOnly(name: String, trie: TrieMap[Wrap, Int], sz: Int, N: Int) { - @volatile var e: Exception = null - - // reads possible entries once and stores them - // then reads all these N more times to check if the - // state stayed the same - class Worker extends Thread { - setName("Worker " + name) - - override def run() = - try check() - catch { - case ex: Exception => e = ex - } - - def check() { - val initial = mutable.Map[Wrap, Int]() - for (i <- 0 until sz) trie.get(new Wrap(i)) match { - case Some(i) => initial.put(new Wrap(i), i) - case None => // do nothing - } - - for (k <- 0 until N) { - // modify - for ((key, value) <- initial) { - val oldv = if (k % 2 == 0) value else -value - val newv = -oldv - trie.replace(key, oldv, newv) - } - - // check - for (i <- 0 until sz) if (initial.contains(new Wrap(i))) { - val expected = if (k % 2 == 0) -i else i - //println(trie.get(new Wrap(i))) - assert(trie.get(new Wrap(i)) == Some(expected)) - } else { - assert(trie.get(new Wrap(i)) == None) - } - } - } - } - - val worker = new Worker - worker.start() - worker.join() - - if (e ne null) { - e.printStackTrace() - throw e - } - } - - "have a consistent non-quiescent snapshot, concurrent with modifications" in { - val sz = 9000 - val N = 1000 - val W = 10 - val S = 400 - - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until sz) ct(new Wrap(i)) = i - val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) - - threads.foreach(_.start()) - for (i <- 0 until S) { - consistentReadOnly("non-qm", ct.snapshot(), sz, 5) - consistentNonReadOnly("non-qsnap", ct.snapshot(), sz, 5) - } - threads.foreach(_.join()) - } - - "work when many concurrent snapshots are taken, concurrent with modifications" in { - val sz = 12000 - val W = 10 - val S = 10 - val modifytimes = 1200 - val snaptimes = 600 - val ct = new TrieMap[Wrap, Int] - for (i <- 0 until sz) ct(new Wrap(i)) = i - - class Snapshooter extends Thread { - setName("Snapshooter") - override def run() { - for (k <- 0 until snaptimes) { - val snap = ct.snapshot() - for (i <- 0 until sz) snap.remove(new Wrap(i)) - for (i <- 0 until sz) assert(!snap.contains(new Wrap(i))) - } - } - } - - val mods = for (i <- 0 until W) yield new Modifier(ct, i, modifytimes, sz) - val shooters = for (i <- 0 until S) yield new Snapshooter - val threads = mods ++ shooters - threads.foreach(_.start()) - threads.foreach(_.join()) - } - - } - -} diff --git a/test/files/run/existentials3-new.check b/test/files/run/existentials3-new.check new file mode 100644 index 0000000000..66674fbbd6 --- /dev/null +++ b/test/files/run/existentials3-new.check @@ -0,0 +1,24 @@ +ConcreteTypeTag[Bar.type], t=AbstractTypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton +ConcreteTypeTag[Bar], t=AbstractTypeRef, 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=AbstractTypeRef, s= <: B with Test.ToS +ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with A with Test.ToS +TypeTag[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=AbstractTypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton +ConcreteTypeTag[Bar], t=AbstractTypeRef, 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=AbstractTypeRef, s= <: B with Test.ToS +ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with A with Test.ToS +TypeTag[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-new.scala b/test/files/run/existentials3-new.scala new file mode 100644 index 0000000000..32129a04c6 --- /dev/null +++ b/test/files/run/existentials3-new.scala @@ -0,0 +1,78 @@ +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]) + + // tags do 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) + 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.check b/test/files/run/existentials3.check deleted file mode 100644 index e2c9382ab4..0000000000 --- a/test/files/run/existentials3.check +++ /dev/null @@ -1,24 +0,0 @@ -ConcreteTypeTag[Bar.type], t=AbstractTypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton -ConcreteTypeTag[Bar], t=AbstractTypeRef, 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=AbstractTypeRef, s= <: B with Test.ToS -ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with A with Test.ToS -TypeTag[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=AbstractTypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton -ConcreteTypeTag[Bar], t=AbstractTypeRef, 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=AbstractTypeRef, s= <: B with Test.ToS -ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with A with Test.ToS -TypeTag[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.scala b/test/files/run/existentials3.scala deleted file mode 100644 index d6d5612687..0000000000 --- a/test/files/run/existentials3.scala +++ /dev/null @@ -1,79 +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 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/getClassTest-new.check b/test/files/run/getClassTest-new.check new file mode 100644 index 0000000000..94e86c3889 --- /dev/null +++ b/test/files/run/getClassTest-new.check @@ -0,0 +1,18 @@ +f1: java.lang.Class +f2: java.lang.Class +f3: java.lang.Class +f4: java.lang.Class +f5: java.lang.Class +f0: T +f1: class java.lang.Object +f2: class java.lang.Object +f3: class AnyRefs$A +f4: class AnyRefs$B +f5: class java.lang.Object +f6: class java.lang.Object +f7: class AnyRefs$A +f8: class AnyRefs$B +f1: java.lang.Class +f2: java.lang.Class +f3: java.lang.Class +f4: java.lang.Class diff --git a/test/files/run/getClassTest-new.scala b/test/files/run/getClassTest-new.scala new file mode 100644 index 0000000000..89778ca2d3 --- /dev/null +++ b/test/files/run/getClassTest-new.scala @@ -0,0 +1,66 @@ +class AnyVals { + def f1 = (5: Any).getClass + def f2 = (5: AnyVal).getClass + def f3 = 5.getClass + def f4 = (5: java.lang.Integer).getClass + def f5 = (5.asInstanceOf[AnyRef]).getClass + + // scalap says: + // + // def f1 : java.lang.Class[?0] forSome {type ?0} = { /* compiled code */ } + // def f2 : java.lang.Class[?0] forSome {type ?0} = { /* compiled code */ } + // def f3 : java.lang.Class[scala.Int] = { /* compiled code */ } + // def f4 : java.lang.Class[?0] forSome {type ?0 <: java.lang.Integer} = { /* compiled code */ } + // def f5 : java.lang.Class[?0] forSome {type ?0 <: scala.AnyRef} = { /* compiled code */ } + // + // java generic signature says: + // + // f1: java.lang.Class + // f2: java.lang.Class + // f3: java.lang.Class + // f4: java.lang.Class + // f5: java.lang.Class +} + +class AnyRefs { + class A + class B extends A + + def f1 = (new B: Any).getClass().newInstance() + def f2 = (new B: AnyRef).getClass().newInstance() + def f3 = (new B: A).getClass().newInstance() + def f4 = (new B: B).getClass().newInstance() + + def f0[T >: B] = (new B: T).getClass().newInstance() + + def f5 = f0[Any] + def f6 = f0[AnyRef] + def f7 = f0[A] + def f8 = f0[B] +} + +class MoreAnyRefs { + trait A + trait B + + // don't leak anon/refinements + def f1 = (new A with B { }).getClass() + def f2 = (new B with A { }).getClass() + def f3 = (new { def bippy() = 5 }).getClass() + def f4 = (new A { def bippy() = 5 }).getClass() +} + +object Test { + def returnTypes[T: ClassTag] = ( + classTag[T].erasure.getMethods.toList + filter (_.getName startsWith "f") + sortBy (_.getName) + map (m => m.getName + ": " + m.getGenericReturnType.toString) + ) + + def main(args: Array[String]): Unit = { + returnTypes[AnyVals] foreach println + returnTypes[AnyRefs] foreach println + returnTypes[MoreAnyRefs] foreach println + } +} diff --git a/test/files/run/getClassTest.check b/test/files/run/getClassTest.check deleted file mode 100644 index 94e86c3889..0000000000 --- a/test/files/run/getClassTest.check +++ /dev/null @@ -1,18 +0,0 @@ -f1: java.lang.Class -f2: java.lang.Class -f3: java.lang.Class -f4: java.lang.Class -f5: java.lang.Class -f0: T -f1: class java.lang.Object -f2: class java.lang.Object -f3: class AnyRefs$A -f4: class AnyRefs$B -f5: class java.lang.Object -f6: class java.lang.Object -f7: class AnyRefs$A -f8: class AnyRefs$B -f1: java.lang.Class -f2: java.lang.Class -f3: java.lang.Class -f4: java.lang.Class diff --git a/test/files/run/getClassTest.scala b/test/files/run/getClassTest.scala deleted file mode 100644 index 2485cd2c71..0000000000 --- a/test/files/run/getClassTest.scala +++ /dev/null @@ -1,66 +0,0 @@ -class AnyVals { - def f1 = (5: Any).getClass - def f2 = (5: AnyVal).getClass - def f3 = 5.getClass - def f4 = (5: java.lang.Integer).getClass - def f5 = (5.asInstanceOf[AnyRef]).getClass - - // scalap says: - // - // def f1 : java.lang.Class[?0] forSome {type ?0} = { /* compiled code */ } - // def f2 : java.lang.Class[?0] forSome {type ?0} = { /* compiled code */ } - // def f3 : java.lang.Class[scala.Int] = { /* compiled code */ } - // def f4 : java.lang.Class[?0] forSome {type ?0 <: java.lang.Integer} = { /* compiled code */ } - // def f5 : java.lang.Class[?0] forSome {type ?0 <: scala.AnyRef} = { /* compiled code */ } - // - // java generic signature says: - // - // f1: java.lang.Class - // f2: java.lang.Class - // f3: java.lang.Class - // f4: java.lang.Class - // f5: java.lang.Class -} - -class AnyRefs { - class A - class B extends A - - def f1 = (new B: Any).getClass().newInstance() - def f2 = (new B: AnyRef).getClass().newInstance() - def f3 = (new B: A).getClass().newInstance() - def f4 = (new B: B).getClass().newInstance() - - def f0[T >: B] = (new B: T).getClass().newInstance() - - def f5 = f0[Any] - def f6 = f0[AnyRef] - def f7 = f0[A] - def f8 = f0[B] -} - -class MoreAnyRefs { - trait A - trait B - - // don't leak anon/refinements - def f1 = (new A with B { }).getClass() - def f2 = (new B with A { }).getClass() - def f3 = (new { def bippy() = 5 }).getClass() - def f4 = (new A { def bippy() = 5 }).getClass() -} - -object Test { - def returnTypes[T: Manifest] = ( - manifest[T].erasure.getMethods.toList - filter (_.getName startsWith "f") - sortBy (_.getName) - map (m => m.getName + ": " + m.getGenericReturnType.toString) - ) - - def main(args: Array[String]): Unit = { - returnTypes[AnyVals] foreach println - returnTypes[AnyRefs] foreach println - returnTypes[MoreAnyRefs] foreach println - } -} diff --git a/test/files/run/manifests-new.scala b/test/files/run/manifests-new.scala new file mode 100644 index 0000000000..4485ce9124 --- /dev/null +++ b/test/files/run/manifests-new.scala @@ -0,0 +1,147 @@ +object Test +{ + object Variances extends Enumeration { + 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: TypeTag[T], ev2: TypeTag[U], ev3: TypeTag[CC[T]], ev4: TypeTag[CC[U]]) { + + 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) + else expected match { + case CO => showsCovariance && !showsContravariance && !showsInvariance + case IN => showsInvariance && !showsCovariance && !showsContravariance + case CONTRA => showsContravariance && !showsCovariance && !showsInvariance + } + } + + def showsCovariance[T, U, CC[_]](implicit ev1: TypeTag[T], ev2: TypeTag[U], ev3: TypeTag[CC[T]], ev4: TypeTag[CC[U]]) = + new VarianceTester[T, U, CC](CO) showsExpectedVariance + + def showsInvariance[T, U, CC[_]](implicit ev1: TypeTag[T], ev2: TypeTag[U], ev3: TypeTag[CC[T]], ev4: TypeTag[CC[U]]) = + new VarianceTester[T, U, CC](IN) showsExpectedVariance + + def showsContravariance[T, U, CC[_]](implicit ev1: TypeTag[T], ev2: TypeTag[U], ev3: TypeTag[CC[T]], ev4: TypeTag[CC[U]]) = + new VarianceTester[T, U, CC](CONTRA) showsExpectedVariance + + def typeCompare[T, U](implicit ev1: TypeTag[T], ev2: TypeTag[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: TypeTag] = List( + typeTag[T].tpe <:< typeTag[Any].tpe, + typeTag[T].tpe <:< typeTag[AnyRef].tpe, + !(typeTag[T].tpe <:< typeTag[AnyVal].tpe) + ) foreach (assert(_, "assertAnyRef")) + + def assertAnyVal[T: TypeTag] = List( + typeTag[T].tpe <:< typeTag[Any].tpe, + !(typeTag[T].tpe <:< typeTag[AnyRef].tpe), + typeTag[T].tpe <:< typeTag[AnyVal].tpe + ) foreach (assert(_, "assertAnyVal")) + + def assertSameType[T: TypeTag, U: TypeTag] = assert(typeCompare[T, U] == SAME, "assertSameType") + def assertSuperType[T: TypeTag, U: TypeTag] = assert(typeCompare[T, U] == SUPER, "assertSuperType") + def assertSubType[T: TypeTag, U: TypeTag] = assert(typeCompare[T, U] == SUB, "assertSubType") + def assertNoRelationship[T: TypeTag, U: TypeTag] = assert(typeCompare[T, U] == NONE, "assertNoRelationship") + + def testVariancesVia[T: TypeTag, U: TypeTag] = assert( + typeCompare[T, U] == SUB && + showsCovariance[T, U, List] && + showsInvariance[T, U, Set], + "testVariancesVia" + ) + + def runAllTests = { + assertAnyVal[AnyVal] + assertAnyVal[Unit] + assertAnyVal[Int] + assertAnyVal[Double] + assertAnyVal[Boolean] + assertAnyVal[Char] + + assertAnyRef[AnyRef] + assertAnyRef[java.lang.Object] + assertAnyRef[java.lang.Integer] + assertAnyRef[java.lang.Double] + assertAnyRef[java.lang.Boolean] + assertAnyRef[java.lang.Character] + assertAnyRef[String] + assertAnyRef[scala.List[String]] + assertAnyRef[scala.List[_]] + + // variance doesn't work yet + // testVariancesVia[String, Any] + // testVariancesVia[String, AnyRef] + + 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] + assertSubType[Nothing, AnyRef] + assertSubType[Nothing, String] + assertSubType[Nothing, List[String]] + assertSubType[Nothing, Null] + assertSameType[Nothing, Nothing] + + // Null + assertSubType[Null, Any] + assertNoRelationship[Null, AnyVal] + assertSubType[Null, AnyRef] + assertSubType[Null, String] + assertSubType[Null, List[String]] + assertSameType[Null, Null] + assertSuperType[Null, Nothing] + + // Any + assertSameType[Any, Any] + assertSuperType[Any, AnyVal] + assertSuperType[Any, AnyRef] + assertSuperType[Any, String] + assertSuperType[Any, List[String]] + assertSuperType[Any, Null] + assertSuperType[Any, Nothing] + + // Misc unrelated types + assertNoRelationship[Unit, AnyRef] + assertNoRelationship[Unit, Int] + assertNoRelationship[Int, Long] + assertNoRelationship[Boolean, String] + assertNoRelationship[List[Boolean], List[String]] + assertNoRelationship[Set[Boolean], Set[String]] + } + + def main(args: Array[String]): Unit = runAllTests +} diff --git a/test/files/run/manifests.scala b/test/files/run/manifests.scala deleted file mode 100644 index 2d64bf18a9..0000000000 --- a/test/files/run/manifests.scala +++ /dev/null @@ -1,149 +0,0 @@ -object Test -{ - object Variances extends Enumeration { - 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.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) - else expected match { - case CO => showsCovariance && !showsContravariance && !showsInvariance - case IN => showsInvariance && !showsCovariance && !showsContravariance - 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]) = { - (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].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].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 && - showsCovariance[T, U, List] && - showsInvariance[T, U, Set], - "testVariancesVia" - ) - - def runAllTests = { - assertAnyVal[AnyVal] - assertAnyVal[Unit] - assertAnyVal[Int] - assertAnyVal[Double] - assertAnyVal[Boolean] - assertAnyVal[Char] - - assertAnyRef[AnyRef] - assertAnyRef[java.lang.Object] - assertAnyRef[java.lang.Integer] - assertAnyRef[java.lang.Double] - assertAnyRef[java.lang.Boolean] - assertAnyRef[java.lang.Character] - assertAnyRef[String] - assertAnyRef[scala.List[String]] - assertAnyRef[scala.List[_]] - - // variance doesn't work yet - // testVariancesVia[String, Any] - // testVariancesVia[String, AnyRef] - - 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] - assertSubType[Nothing, AnyRef] - assertSubType[Nothing, String] - assertSubType[Nothing, List[String]] - assertSubType[Nothing, Null] - assertSameType[Nothing, Nothing] - - // Null - assertSubType[Null, Any] - assertNoRelationship[Null, AnyVal] - assertSubType[Null, AnyRef] - assertSubType[Null, String] - assertSubType[Null, List[String]] - assertSameType[Null, Null] - assertSuperType[Null, Nothing] - - // Any - assertSameType[Any, Any] - assertSuperType[Any, AnyVal] - assertSuperType[Any, AnyRef] - assertSuperType[Any, String] - assertSuperType[Any, List[String]] - assertSuperType[Any, Null] - assertSuperType[Any, Nothing] - - // Misc unrelated types - assertNoRelationship[Unit, AnyRef] - assertNoRelationship[Unit, Int] - assertNoRelationship[Int, Long] - assertNoRelationship[Boolean, String] - assertNoRelationship[List[Boolean], List[String]] - assertNoRelationship[Set[Boolean], Set[String]] - } - - def main(args: Array[String]): Unit = runAllTests -} diff --git a/test/files/run/patmat_unapp_abstype-new.check b/test/files/run/patmat_unapp_abstype-new.check new file mode 100644 index 0000000000..72239d16cd --- /dev/null +++ b/test/files/run/patmat_unapp_abstype-new.check @@ -0,0 +1,4 @@ +TypeRef +none of the above +Bar +Foo diff --git a/test/files/run/patmat_unapp_abstype-new.flags b/test/files/run/patmat_unapp_abstype-new.flags new file mode 100644 index 0000000000..ba80cad69b --- /dev/null +++ b/test/files/run/patmat_unapp_abstype-new.flags @@ -0,0 +1 @@ +-Xoldpatmat diff --git a/test/files/run/patmat_unapp_abstype-new.scala b/test/files/run/patmat_unapp_abstype-new.scala new file mode 100644 index 0000000000..45496f08a2 --- /dev/null +++ b/test/files/run/patmat_unapp_abstype-new.scala @@ -0,0 +1,83 @@ +// abstract types and extractors, oh my! +trait TypesAPI { + trait Type + + // an alternative fix (implemented in the virtual pattern matcher, is to replace the isInstanceOf by a manifest-based run-time test) + // that's what typeRefMani is for + type TypeRef <: Type //; implicit def typeRefMani: Manifest[TypeRef] + val TypeRef: TypeRefExtractor; trait TypeRefExtractor { + def apply(x: Int): TypeRef + def unapply(x: TypeRef): Option[(Int)] + } + + // just for illustration, should follow the same pattern as TypeRef + case class MethodType(n: Int) extends Type +} + +// user should not be exposed to the implementation +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") + } + } +} + +trait TypesImpl extends TypesAPI { + object TypeRef extends TypeRefExtractor // this will have a bridged unapply(x: Type) = unapply(x.asInstanceOf[TypeRef]) + case class TypeRef(n: Int) extends Type // this has a bridge from TypesAPI#Type to TypesImpl#TypeRef + // --> the cast in the bridge will fail because the pattern matcher can't type test against the abstract types in TypesUser + //lazy val typeRefMani = manifest[TypeRef] +} + +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() +} diff --git a/test/files/run/patmat_unapp_abstype.check b/test/files/run/patmat_unapp_abstype.check deleted file mode 100644 index 72239d16cd..0000000000 --- a/test/files/run/patmat_unapp_abstype.check +++ /dev/null @@ -1,4 +0,0 @@ -TypeRef -none of the above -Bar -Foo diff --git a/test/files/run/patmat_unapp_abstype.flags b/test/files/run/patmat_unapp_abstype.flags deleted file mode 100644 index ba80cad69b..0000000000 --- a/test/files/run/patmat_unapp_abstype.flags +++ /dev/null @@ -1 +0,0 @@ --Xoldpatmat diff --git a/test/files/run/patmat_unapp_abstype.scala b/test/files/run/patmat_unapp_abstype.scala deleted file mode 100644 index 45496f08a2..0000000000 --- a/test/files/run/patmat_unapp_abstype.scala +++ /dev/null @@ -1,83 +0,0 @@ -// abstract types and extractors, oh my! -trait TypesAPI { - trait Type - - // an alternative fix (implemented in the virtual pattern matcher, is to replace the isInstanceOf by a manifest-based run-time test) - // that's what typeRefMani is for - type TypeRef <: Type //; implicit def typeRefMani: Manifest[TypeRef] - val TypeRef: TypeRefExtractor; trait TypeRefExtractor { - def apply(x: Int): TypeRef - def unapply(x: TypeRef): Option[(Int)] - } - - // just for illustration, should follow the same pattern as TypeRef - case class MethodType(n: Int) extends Type -} - -// user should not be exposed to the implementation -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") - } - } -} - -trait TypesImpl extends TypesAPI { - object TypeRef extends TypeRefExtractor // this will have a bridged unapply(x: Type) = unapply(x.asInstanceOf[TypeRef]) - case class TypeRef(n: Int) extends Type // this has a bridge from TypesAPI#Type to TypesImpl#TypeRef - // --> the cast in the bridge will fail because the pattern matcher can't type test against the abstract types in TypesUser - //lazy val typeRefMani = manifest[TypeRef] -} - -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() -} diff --git a/test/files/run/primitive-sigs-2-new.check b/test/files/run/primitive-sigs-2-new.check new file mode 100644 index 0000000000..b82ddbeaff --- /dev/null +++ b/test/files/run/primitive-sigs-2-new.check @@ -0,0 +1,7 @@ +T +List(A, char, class java.lang.Object) +a +public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.ArrayTag) +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/primitive-sigs-2-new.scala b/test/files/run/primitive-sigs-2-new.scala new file mode 100644 index 0000000000..7e13014cb2 --- /dev/null +++ b/test/files/run/primitive-sigs-2-new.scala @@ -0,0 +1,31 @@ +import java.{ lang => jl } + +trait T[A] { + def f(): A +} +class C extends T[Char] { + def f(): Char = 'a' +} +class Arr { + def arr1(xs: Array[Int]): List[Int] = xs.toList + def arr2(xs: Array[jl.Character]): List[jl.Character] = xs.toList + def arr3(xss: Array[Array[Float]]): Array[Float] = xss map (_.sum) + def arr4[T: ArrayTag](xss: Array[Array[T]]): Array[T] = xss map (_.head) +} + +object Test { + val c1: Class[_] = classOf[T[_]] + val c2: Class[_] = classOf[C] + val c3: Class[_] = classOf[Arr] + + val c1m = c1.getMethods.toList filter (_.getName == "f") map (_.getGenericReturnType.toString) + val c2m = c2.getMethods.toList filter (_.getName == "f") map (_.getGenericReturnType.toString) + val c3m = c3.getDeclaredMethods.toList map (_.toGenericString) + + def main(args: Array[String]): Unit = { + println(c2.getGenericInterfaces.map(_.toString).sorted mkString " ") + println(c1m ++ c2m sorted) + println(new C f) + c3m.sorted foreach println + } +} diff --git a/test/files/run/primitive-sigs-2.check b/test/files/run/primitive-sigs-2.check deleted file mode 100644 index 1b6e24ed20..0000000000 --- a/test/files/run/primitive-sigs-2.check +++ /dev/null @@ -1,7 +0,0 @@ -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$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/primitive-sigs-2.scala b/test/files/run/primitive-sigs-2.scala deleted file mode 100644 index b7152f7e3d..0000000000 --- a/test/files/run/primitive-sigs-2.scala +++ /dev/null @@ -1,39 +0,0 @@ -import java.{ lang => jl } - -trait T[A] { - def f(): A -} -class C extends T[Char] { - def f(): Char = 'a' -} -class Arr { - def arr1(xs: Array[Int]): List[Int] = xs.toList - def arr2(xs: Array[jl.Character]): List[jl.Character] = xs.toList - def arr3(xss: Array[Array[Float]]): Array[Float] = xss map (_.sum) - // This gets a signature like - // public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.Manifest) - // - // instead of the more appealing version from the past - // public T[] Arr.arr4(T[][],scala.reflect.Manifest) - // - // because java inflict's its reference-only generic-arrays on us. - // - def arr4[T: Manifest](xss: Array[Array[T]]): Array[T] = xss map (_.head) -} - -object Test { - val c1: Class[_] = classOf[T[_]] - val c2: Class[_] = classOf[C] - val c3: Class[_] = classOf[Arr] - - val c1m = c1.getMethods.toList filter (_.getName == "f") map (_.getGenericReturnType.toString) - val c2m = c2.getMethods.toList filter (_.getName == "f") map (_.getGenericReturnType.toString) - val c3m = c3.getDeclaredMethods.toList map (_.toGenericString) - - def main(args: Array[String]): Unit = { - println(c2.getGenericInterfaces.map(_.toString).sorted mkString " ") - println(c1m ++ c2m sorted) - println(new C f) - c3m.sorted foreach println - } -} diff --git a/test/files/run/reflection-implClass-new.scala b/test/files/run/reflection-implClass-new.scala new file mode 100644 index 0000000000..27374f2106 --- /dev/null +++ b/test/files/run/reflection-implClass-new.scala @@ -0,0 +1,38 @@ +/** + * Tries to load a symbol for the `Foo$class` using Scala reflection. + * Since trait implementation classes do not get pickling information + * symbol for them should be created using fallback mechanism + * that exposes Java reflection information dressed up in + * a Scala symbol. + */ +object Test extends App with Outer { + import scala.reflect.mirror + + assert(mirror.classToSymbol(classTag[Foo].erasure).typeSignature.declaration(mirror.newTermName("bar")).typeSignature == + mirror.classToSymbol(classTag[Bar].erasure).typeSignature.declaration(mirror.newTermName("foo")).typeSignature) + + val s1 = implClass(classTag[Foo].erasure) + assert(s1 != mirror.NoSymbol) + assert(s1.typeSignature != mirror.NoType) + assert(s1.companionSymbol.typeSignature != mirror.NoType) + assert(s1.companionSymbol.typeSignature.declaration(mirror.newTermName("bar")) != mirror.NoSymbol) + val s2 = implClass(classTag[Bar].erasure) + assert(s2 != mirror.NoSymbol) + assert(s2.typeSignature != mirror.NoType) + assert(s2.companionSymbol.typeSignature != mirror.NoType) + assert(s2.companionSymbol.typeSignature.declaration(mirror.newTermName("foo")) != mirror.NoSymbol) + def implClass(clazz: Class[_]) = { + val implClass = Class.forName(clazz.getName + "$class") + mirror.classToSymbol(implClass) + } +} + +trait Foo { + def bar = 1 +} + +trait Outer { + trait Bar { + def foo = 1 + } +} diff --git a/test/files/run/reflection-implClass.scala b/test/files/run/reflection-implClass.scala deleted file mode 100644 index 7718b52f33..0000000000 --- a/test/files/run/reflection-implClass.scala +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Tries to load a symbol for the `Foo$class` using Scala reflection. - * Since trait implementation classes do not get pickling information - * symbol for them should be created using fallback mechanism - * that exposes Java reflection information dressed up in - * a Scala symbol. - */ -object Test extends App with Outer { - import scala.reflect.mirror - - assert(mirror.classToSymbol(manifest[Foo].erasure).typeSignature.declaration(mirror.newTermName("bar")).typeSignature == - mirror.classToSymbol(manifest[Bar].erasure).typeSignature.declaration(mirror.newTermName("foo")).typeSignature) - - val s1 = implClass(manifest[Foo].erasure) - assert(s1 != mirror.NoSymbol) - assert(s1.typeSignature != mirror.NoType) - assert(s1.companionSymbol.typeSignature != mirror.NoType) - assert(s1.companionSymbol.typeSignature.declaration(mirror.newTermName("bar")) != mirror.NoSymbol) - val s2 = implClass(manifest[Bar].erasure) - assert(s2 != mirror.NoSymbol) - assert(s2.typeSignature != mirror.NoType) - assert(s2.companionSymbol.typeSignature != mirror.NoType) - assert(s2.companionSymbol.typeSignature.declaration(mirror.newTermName("foo")) != mirror.NoSymbol) - def implClass(clazz: Class[_]) = { - val implClass = Class.forName(clazz.getName + "$class") - mirror.classToSymbol(implClass) - } -} - -trait Foo { - def bar = 1 -} - -trait Outer { - trait Bar { - def foo = 1 - } -} diff --git a/test/files/run/reify_implicits-new.check b/test/files/run/reify_implicits-new.check new file mode 100644 index 0000000000..e3aeb20f6b --- /dev/null +++ b/test/files/run/reify_implicits-new.check @@ -0,0 +1 @@ +x = List(1, 2, 3, 4) diff --git a/test/files/run/reify_implicits-new.scala b/test/files/run/reify_implicits-new.scala new file mode 100644 index 0000000000..69198391d1 --- /dev/null +++ b/test/files/run/reify_implicits-new.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + reify { + implicit def arrayWrapper[A : ArrayTag](x: Array[A]) = + new { + def sort(p: (A, A) => Boolean) = { + util.Sorting.stableSort(x, p); x + } + } + val x = Array(2, 3, 1, 4) + println("x = "+ x.sort((x: Int, y: Int) => x < y).toList) + }.eval +} diff --git a/test/files/run/reify_implicits.check b/test/files/run/reify_implicits.check deleted file mode 100644 index e3aeb20f6b..0000000000 --- a/test/files/run/reify_implicits.check +++ /dev/null @@ -1 +0,0 @@ -x = List(1, 2, 3, 4) diff --git a/test/files/run/reify_implicits.scala b/test/files/run/reify_implicits.scala deleted file mode 100644 index 60971c3cfb..0000000000 --- a/test/files/run/reify_implicits.scala +++ /dev/null @@ -1,14 +0,0 @@ -import scala.reflect.mirror._ - -object Test extends App { - reify { - implicit def arrayWrapper[A : ClassManifest](x: Array[A]) = - new { - def sort(p: (A, A) => Boolean) = { - util.Sorting.stableSort(x, p); x - } - } - val x = Array(2, 3, 1, 4) - println("x = "+ x.sort((x: Int, y: Int) => x < y).toList) - }.eval -} diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check index 1e7b6f0cd8..c509434116 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 tags +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/repl-power.scala b/test/files/run/repl-power.scala index 27da3df106..f7c88c63ff 100644 --- a/test/files/run/repl-power.scala +++ b/test/files/run/repl-power.scala @@ -5,10 +5,9 @@ object Test extends ReplTest { :power // guarding against "error: reference to global is ambiguous" global.emptyValDef // "it is imported twice in the same scope by ..." -val tp = ArrayClass[scala.util.Random] // magic with manifests +val tp = ArrayClass[scala.util.Random] // magic with tags tp.memberType(Array_apply) // evidence val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl typed(m).tpe // typed is in scope """.trim } - diff --git a/test/files/run/t0421-new.check b/test/files/run/t0421-new.check new file mode 100644 index 0000000000..cdcf042f19 --- /dev/null +++ b/test/files/run/t0421-new.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31.0)] +[Array(24.0, 32.0)] diff --git a/test/files/run/t0421-new.scala b/test/files/run/t0421-new.scala new file mode 100644 index 0000000000..7de6b7f2c4 --- /dev/null +++ b/test/files/run/t0421-new.scala @@ -0,0 +1,30 @@ +// ticket #421 +object Test extends App { + + def transpose[A: ArrayTag](xss: Array[Array[A]]) = { + for (i <- Array.range(0, xss(0).length)) yield + for (xs <- xss) yield xs(i) + } + + def scalprod(xs: Array[Double], ys: Array[Double]) = { + var acc = 0.0 + for ((x, y) <- xs zip ys) acc = acc + x * y + acc + } + + def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { + val ysst = transpose(yss) + val ysst1: Array[Array[Double]] = yss.transpose + assert(ysst.deep == ysst1.deep) + for (xs <- xss) yield + for (yst <- ysst) yield + scalprod(xs, yst) + } + + val a1 = Array(Array(0, 2, 4), Array(1, 3, 5)) + println(transpose(a1).deep.mkString("[", ",", "]")) + + println(matmul(Array(Array(2, 3)), Array(Array(5), Array(7))).deep.mkString("[", ",", "]")) + + println(matmul(Array(Array(4)), Array(Array(6, 8))).deep.mkString("[", ",", "]")) +} diff --git a/test/files/run/t0421.check b/test/files/run/t0421.check deleted file mode 100644 index cdcf042f19..0000000000 --- a/test/files/run/t0421.check +++ /dev/null @@ -1,3 +0,0 @@ -[Array(0, 1),Array(2, 3),Array(4, 5)] -[Array(31.0)] -[Array(24.0, 32.0)] diff --git a/test/files/run/t0421.scala b/test/files/run/t0421.scala deleted file mode 100644 index 8d51013924..0000000000 --- a/test/files/run/t0421.scala +++ /dev/null @@ -1,30 +0,0 @@ -// ticket #421 -object Test extends App { - - def transpose[A: ClassManifest](xss: Array[Array[A]]) = { - for (i <- Array.range(0, xss(0).length)) yield - for (xs <- xss) yield xs(i) - } - - def scalprod(xs: Array[Double], ys: Array[Double]) = { - var acc = 0.0 - for ((x, y) <- xs zip ys) acc = acc + x * y - acc - } - - def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { - val ysst = transpose(yss) - val ysst1: Array[Array[Double]] = yss.transpose - assert(ysst.deep == ysst1.deep) - for (xs <- xss) yield - for (yst <- ysst) yield - scalprod(xs, yst) - } - - val a1 = Array(Array(0, 2, 4), Array(1, 3, 5)) - println(transpose(a1).deep.mkString("[", ",", "]")) - - println(matmul(Array(Array(2, 3)), Array(Array(5), Array(7))).deep.mkString("[", ",", "]")) - - println(matmul(Array(Array(4)), Array(Array(6, 8))).deep.mkString("[", ",", "]")) -} diff --git a/test/files/run/t0677-new.scala b/test/files/run/t0677-new.scala new file mode 100644 index 0000000000..bf7a3971dc --- /dev/null +++ b/test/files/run/t0677-new.scala @@ -0,0 +1,8 @@ +object Test extends App { + class X[T: ArrayTag] { + val a = Array.ofDim[T](3, 4) + } + val x = new X[String] + x.a(1)(2) = "hello" + assert(x.a(1)(2) == "hello") +} diff --git a/test/files/run/t0677.scala b/test/files/run/t0677.scala deleted file mode 100644 index 6c8a3a7e99..0000000000 --- a/test/files/run/t0677.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Test extends App { - class X[T: ClassManifest] { - val a = Array.ofDim[T](3, 4) - } - val x = new X[String] - x.a(1)(2) = "hello" - assert(x.a(1)(2) == "hello") -} diff --git a/test/files/run/t1195-new.check b/test/files/run/t1195-new.check new file mode 100644 index 0000000000..554e3fd03d --- /dev/null +++ b/test/files/run/t1195-new.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-new.scala b/test/files/run/t1195-new.scala new file mode 100644 index 0000000000..6f28a4a167 --- /dev/null +++ b/test/files/run/t1195-new.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: TypeTag](x: T) = println(typeTag[T] + ", underlying = " + typeTag[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.check b/test/files/run/t1195.check deleted file mode 100644 index 554e3fd03d..0000000000 --- a/test/files/run/t1195.check +++ /dev/null @@ -1,6 +0,0 @@ -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.scala b/test/files/run/t1195.scala deleted file mode 100644 index 93b1dcbd07..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] + ", 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/t2236-new.scala b/test/files/run/t2236-new.scala new file mode 100644 index 0000000000..bbabe8e7d9 --- /dev/null +++ b/test/files/run/t2236-new.scala @@ -0,0 +1,17 @@ +class T[A](implicit val m:TypeTag[A]) +class Foo +class Bar extends T[Foo] +object Test extends App { + new Bar +} + +object EvidenceTest { + trait E[T] + trait A[T] { implicit val e: E[T] = null } + class B[T : E] extends A[T] { override val e = null } + + def f[T] { + implicit val e: E[T] = null + new B[T]{} + } +} diff --git a/test/files/run/t2236.scala b/test/files/run/t2236.scala deleted file mode 100755 index 64ed18c805..0000000000 --- a/test/files/run/t2236.scala +++ /dev/null @@ -1,17 +0,0 @@ -class T[A](implicit val m:Manifest[A]) -class Foo -class Bar extends T[Foo] -object Test extends App { - new Bar -} - -object EvidenceTest { - trait E[T] - trait A[T] { implicit val e: E[T] = null } - class B[T : E] extends A[T] { override val e = null } - - def f[T] { - implicit val e: E[T] = null - new B[T]{} - } -} diff --git a/test/files/run/t2386-new.check b/test/files/run/t2386-new.check new file mode 100644 index 0000000000..98e226f946 --- /dev/null +++ b/test/files/run/t2386-new.check @@ -0,0 +1,2 @@ +a(0) = Array(1, 2) +a(1) = Array("a", "b") diff --git a/test/files/run/t2386-new.scala b/test/files/run/t2386-new.scala new file mode 100644 index 0000000000..15d1859759 --- /dev/null +++ b/test/files/run/t2386-new.scala @@ -0,0 +1,5 @@ +object Test extends App { + val a = Array(Array(1, 2), Array("a","b")) + println("a(0) = Array(" + (a(0) mkString ", ") + ")") + println("a(1) = Array(" + (a(1) map (s => "\"" + s + "\"") mkString ", ") + ")") +} diff --git a/test/files/run/t3507-new.check b/test/files/run/t3507-new.check new file mode 100644 index 0000000000..6e4fa4170e --- /dev/null +++ b/test/files/run/t3507-new.check @@ -0,0 +1 @@ +ConcreteTypeTag[_1.b.c.type] diff --git a/test/files/run/t3507-new.scala b/test/files/run/t3507-new.scala new file mode 100644 index 0000000000..c7a529e8b8 --- /dev/null +++ b/test/files/run/t3507-new.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: TypeTag](x: T) = println(typeTag[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/t3507.check b/test/files/run/t3507.check deleted file mode 100644 index 6e4fa4170e..0000000000 --- a/test/files/run/t3507.check +++ /dev/null @@ -1 +0,0 @@ -ConcreteTypeTag[_1.b.c.type] diff --git a/test/files/run/t3507.scala b/test/files/run/t3507.scala deleted file mode 100644 index 3cdd40a881..0000000000 --- a/test/files/run/t3507.scala +++ /dev/null @@ -1,15 +0,0 @@ -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/t3758.check b/test/files/run/t3758.check deleted file mode 100644 index 9c6ab655a3..0000000000 --- a/test/files/run/t3758.check +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index 10bfb5724b..0000000000 --- a/test/files/run/t3758.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Test { - def main(args: Array[String]): Unit = { - 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-new.check b/test/files/run/t4110-new.check new file mode 100644 index 0000000000..28f220e1fe --- /dev/null +++ b/test/files/run/t4110-new.check @@ -0,0 +1,2 @@ +ConcreteTypeTag[Test.A with Test.B] +ConcreteTypeTag[Test.A with Test.B] diff --git a/test/files/run/t4110-new.scala b/test/files/run/t4110-new.scala new file mode 100644 index 0000000000..3285b82c61 --- /dev/null +++ b/test/files/run/t4110-new.scala @@ -0,0 +1,11 @@ +object Test extends App { + def inferredType[T : TypeTag](v : T) = println(typeTag[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.check b/test/files/run/t4110.check deleted file mode 100644 index 28f220e1fe..0000000000 --- a/test/files/run/t4110.check +++ /dev/null @@ -1,2 +0,0 @@ -ConcreteTypeTag[Test.A with Test.B] -ConcreteTypeTag[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/scalacheck/array-new.scala b/test/files/scalacheck/array-new.scala new file mode 100644 index 0000000000..18d577ca6d --- /dev/null +++ b/test/files/scalacheck/array-new.scala @@ -0,0 +1,36 @@ +import org.scalacheck._ +import Prop._ +import Gen._ +import Arbitrary._ +import util._ +import Buildable._ +import scala.collection.mutable.ArraySeq + +object Test extends Properties("Array") { + /** At this moment the authentic scalacheck Array Builder/Arb bits are commented out. + */ + implicit def arbArray[T](implicit a: Arbitrary[T], m: ArrayTag[T]): Arbitrary[Array[T]] = + Arbitrary(containerOf[List,T](arbitrary[T]) map (_.toArray)) + + val arrGen: Gen[Array[_]] = oneOf( + arbitrary[Array[Int]], + arbitrary[Array[Array[Int]]], + arbitrary[Array[List[String]]], + arbitrary[Array[String]], + arbitrary[Array[Boolean]], + arbitrary[Array[AnyVal]] + ) + + // inspired by #1857 and #2352 + property("eq/ne") = forAll(arrGen, arrGen) { (c1, c2) => + (c1 eq c2) || (c1 ne c2) + } + + // inspired by #2299 + def smallInt = choose(1, 10) + property("ofDim") = forAll(smallInt, smallInt, smallInt) { (i1, i2, i3) => + val arr = Array.ofDim[String](i1, i2, i3) + val flattened = arr flatMap (x => x) flatMap (x => x) + flattened.length == i1 * i2 * i3 + } +} diff --git a/test/files/scalacheck/array.scala b/test/files/scalacheck/array.scala deleted file mode 100644 index f262bc6320..0000000000 --- a/test/files/scalacheck/array.scala +++ /dev/null @@ -1,37 +0,0 @@ -import org.scalacheck._ -import Prop._ -import Gen._ -import Arbitrary._ -import util._ -import Buildable._ -import scala.collection.mutable.ArraySeq - -object Test extends Properties("Array") { - /** At this moment the authentic scalacheck Array Builder/Arb bits are commented out. - */ - implicit def arbArray[T](implicit a: Arbitrary[T], m: Manifest[T]): Arbitrary[Array[T]] = - Arbitrary(containerOf[List,T](arbitrary[T]) map (_.toArray)) - - val arrGen: Gen[Array[_]] = oneOf( - arbitrary[Array[Int]], - arbitrary[Array[Array[Int]]], - arbitrary[Array[List[String]]], - arbitrary[Array[String]], - arbitrary[Array[Boolean]], - arbitrary[Array[AnyVal]] - ) - - // inspired by #1857 and #2352 - property("eq/ne") = forAll(arrGen, arrGen) { (c1, c2) => - (c1 eq c2) || (c1 ne c2) - } - - // inspired by #2299 - def smallInt = choose(1, 10) - property("ofDim") = forAll(smallInt, smallInt, smallInt) { (i1, i2, i3) => - val arr = Array.ofDim[String](i1, i2, i3) - val flattened = arr flatMap (x => x) flatMap (x => x) - flattened.length == i1 * i2 * i3 - } -} - diff --git a/test/files/specialized/spec-matrix-new.check b/test/files/specialized/spec-matrix-new.check new file mode 100644 index 0000000000..5ec3e84597 --- /dev/null +++ b/test/files/specialized/spec-matrix-new.check @@ -0,0 +1,2 @@ +251437.0 +Boxed doubles: 1 diff --git a/test/files/specialized/spec-matrix-new.scala b/test/files/specialized/spec-matrix-new.scala new file mode 100644 index 0000000000..65b46e8d48 --- /dev/null +++ b/test/files/specialized/spec-matrix-new.scala @@ -0,0 +1,80 @@ +/** Test matrix multiplication with specialization. + */ + +class Matrix[@specialized A: ArrayTag](val rows: Int, val cols: Int) { + private val arr: Array[Array[A]] = Array.ofDim[A](rows, cols) + + def apply(i: Int, j: Int): A = { + if (i < 0 || i >= rows || j < 0 || j >= cols) + throw new NoSuchElementException("Indexes out of bounds: " + (i, j)) + + arr(i)(j) + } + + def update(i: Int, j: Int, e: A) { + arr(i)(j) = e + } + + def rowsIterator: Iterator[Array[A]] = new Iterator[Array[A]] { + var idx = 0; + def hasNext = idx < rows + def next = { + idx += 1 + arr(idx - 1) + } + } +} + +object Test { + def main(args: Array[String]) { + val m = randomMatrix(200, 100) + val n = randomMatrix(100, 200) + + val p = mult(m, n) + println(p(0, 0)) + println("Boxed doubles: " + runtime.BoxesRunTime.doubleBoxCount) +// println("Boxed integers: " + runtime.BoxesRunTime.integerBoxCount) + } + + def randomMatrix(n: Int, m: Int) = { + val r = new util.Random(10) + val x = new Matrix[Double](n, m) + for (i <- 0 until n; j <- 0 until m) + x(i, j) = (r.nextInt % 1000).toDouble + x + } + + def printMatrix[Double](m: Matrix[Double]) { + for (i <- 0 until m.rows) { + for (j <- 0 until m.cols) + print("%5.3f ".format(m(i, j))) + println + } + } + + def multTag[@specialized(Int) T](m: Matrix[T], n: Matrix[T])(implicit at: ArrayTag[T], num: Numeric[T]) { + val p = new Matrix[T](m.rows, n.cols) + import num._ + + for (i <- 0 until m.rows) + for (j <- 0 until n.cols) { + var sum = num.zero + for (k <- 0 until n.rows) + sum += m(i, k) * n(k, j) + p(i, j) = sum + } + } + + def mult(m: Matrix[Double], n: Matrix[Double]) = { + val p = new Matrix[Double](m.rows, n.cols) + + for (i <- 0 until m.rows) + for (j <- 0 until n.cols) { + var sum = 0.0 + for (k <- 0 until n.rows) + sum += m(i, k) * n(k, j) + p(i, j) = sum + } + p + } +} diff --git a/test/files/specialized/spec-matrix.check b/test/files/specialized/spec-matrix.check deleted file mode 100644 index 5ec3e84597..0000000000 --- a/test/files/specialized/spec-matrix.check +++ /dev/null @@ -1,2 +0,0 @@ -251437.0 -Boxed doubles: 1 diff --git a/test/files/specialized/spec-matrix.scala b/test/files/specialized/spec-matrix.scala deleted file mode 100644 index 98735c8c03..0000000000 --- a/test/files/specialized/spec-matrix.scala +++ /dev/null @@ -1,80 +0,0 @@ -/** Test matrix multiplication with specialization. - */ - -class Matrix[@specialized A: ClassManifest](val rows: Int, val cols: Int) { - private val arr: Array[Array[A]] = Array.ofDim[A](rows, cols) - - def apply(i: Int, j: Int): A = { - if (i < 0 || i >= rows || j < 0 || j >= cols) - throw new NoSuchElementException("Indexes out of bounds: " + (i, j)) - - arr(i)(j) - } - - def update(i: Int, j: Int, e: A) { - arr(i)(j) = e - } - - def rowsIterator: Iterator[Array[A]] = new Iterator[Array[A]] { - var idx = 0; - def hasNext = idx < rows - def next = { - idx += 1 - arr(idx - 1) - } - } -} - -object Test { - def main(args: Array[String]) { - val m = randomMatrix(200, 100) - val n = randomMatrix(100, 200) - - val p = mult(m, n) - println(p(0, 0)) - println("Boxed doubles: " + runtime.BoxesRunTime.doubleBoxCount) -// println("Boxed integers: " + runtime.BoxesRunTime.integerBoxCount) - } - - def randomMatrix(n: Int, m: Int) = { - val r = new util.Random(10) - val x = new Matrix[Double](n, m) - for (i <- 0 until n; j <- 0 until m) - x(i, j) = (r.nextInt % 1000).toDouble - x - } - - def printMatrix[Double](m: Matrix[Double]) { - for (i <- 0 until m.rows) { - for (j <- 0 until m.cols) - print("%5.3f ".format(m(i, j))) - println - } - } - - def multManifest[@specialized(Int) T](m: Matrix[T], n: Matrix[T])(implicit cm: ClassManifest[T], num: Numeric[T]) { - val p = new Matrix[T](m.rows, n.cols) - import num._ - - for (i <- 0 until m.rows) - for (j <- 0 until n.cols) { - var sum = num.zero - for (k <- 0 until n.rows) - sum += m(i, k) * n(k, j) - p(i, j) = sum - } - } - - def mult(m: Matrix[Double], n: Matrix[Double]) = { - val p = new Matrix[Double](m.rows, n.cols) - - for (i <- 0 until m.rows) - for (j <- 0 until n.cols) { - var sum = 0.0 - for (k <- 0 until n.rows) - sum += m(i, k) * n(k, j) - p(i, j) = sum - } - p - } -} diff --git a/test/pending/pos/inference.scala b/test/pending/pos/inference.scala index d28d003435..3672351fca 100644 --- a/test/pending/pos/inference.scala +++ b/test/pending/pos/inference.scala @@ -1,15 +1,15 @@ // inference illuminator object Test { - class D1[T1 : Manifest, T2 <: T1 : Manifest](x: T1) { println(manifest[(T1, T2)]) } - class D2[T1 : Manifest, T2 >: T1 : Manifest](x: T1) { println(manifest[(T1, T2)]) } - class D3[+T1 : Manifest, T2 <: T1 : Manifest](x: T1) { println(manifest[(T1, T2)]) } - class D4[-T1 : Manifest, T2 >: T1 : Manifest](x: T1) { println(manifest[(T1, T2)]) } - - class E1[T1 : Manifest, T2 <: T1 : Manifest](x: D1[T1, T2]) { println(manifest[(T1, T2)]) } - class E2[T1 : Manifest, T2 >: T1 : Manifest](x: D2[T1, T2]) { println(manifest[(T1, T2)]) } - class E3[+T1 : Manifest, T2 <: T1 : Manifest](x: D3[T1, T2]) { println(manifest[(T1, T2)]) } - class E4[-T1 : Manifest, T2 >: T1 : Manifest](x: D4[T1, T2]) { println(manifest[(T1, T2)]) } - + class D1[T1 : TypeTag, T2 <: T1 : TypeTag](x: T1) { println(typeTag[(T1, T2)]) } + class D2[T1 : TypeTag, T2 >: T1 : TypeTag](x: T1) { println(typeTag[(T1, T2)]) } + class D3[+T1 : TypeTag, T2 <: T1 : TypeTag](x: T1) { println(typeTag[(T1, T2)]) } + class D4[-T1 : TypeTag, T2 >: T1 : TypeTag](x: T1) { println(typeTag[(T1, T2)]) } + + class E1[T1 : TypeTag, T2 <: T1 : TypeTag](x: D1[T1, T2]) { println(typeTag[(T1, T2)]) } + class E2[T1 : TypeTag, T2 >: T1 : TypeTag](x: D2[T1, T2]) { println(typeTag[(T1, T2)]) } + class E3[+T1 : TypeTag, T2 <: T1 : TypeTag](x: D3[T1, T2]) { println(typeTag[(T1, T2)]) } + class E4[-T1 : TypeTag, T2 >: T1 : TypeTag](x: D4[T1, T2]) { println(typeTag[(T1, T2)]) } + def main(args: Array[String]): Unit = { // WHY YOU NO LIKE NOTHING SO MUCH SCALAC? val d1 = new D1(5) diff --git a/test/pending/shootout/meteor.scala b/test/pending/shootout/meteor.scala index 2fd702753a..154695533b 100644 --- a/test/pending/shootout/meteor.scala +++ b/test/pending/shootout/meteor.scala @@ -19,7 +19,7 @@ object meteor { -// Solver.scala +// Solver.scala // import scala.collection.mutable._ final class Solver (n: Int) { @@ -29,8 +29,8 @@ final class Solver (n: Int) { private val board = new Board() - val pieces = Array( - new Piece(0), new Piece(1), new Piece(2), new Piece(3), new Piece(4), + val pieces = Array( + new Piece(0), new Piece(1), new Piece(2), new Piece(3), new Piece(4), new Piece(5), new Piece(6), new Piece(7), new Piece(8), new Piece(9) ) val unplaced = new BitSet(pieces.length) @@ -71,8 +71,8 @@ final class Solver (n: Int) { private def puzzleSolved() = { val b = board.asString - if (first == null){ - first = b; last = b + if (first == null){ + first = b; last = b } else { if (b < first){ first = b } else { if (b > last){ last = b } } } @@ -81,7 +81,7 @@ final class Solver (n: Int) { private def shouldPrune() = { board.unmark - !board.cells.forall(c => c.contiguousEmptyCells % Piece.size == 0) + !board.cells.forall(c => c.contiguousEmptyCells % Piece.size == 0) } @@ -108,8 +108,8 @@ final class Solver (n: Int) { } /* - def printPieces() = - for (i <- Iterator.range(0,Board.pieces)) pieces(i).print + def printPieces() = + for (i <- Iterator.range(0,Board.pieces)) pieces(i).print */ } @@ -126,7 +126,7 @@ object Board { val size = rows * cols } -final class Board { +final class Board { val cells = boardCells() val cellsPieceWillFill = new Array[BoardCell](Piece.size) @@ -134,9 +134,9 @@ final class Board { def unmark() = for (c <- cells) c.unmark - def asString() = - new String( cells map( - c => if (c.piece == null) '-'.toByte + def asString() = + new String( cells map( + c => if (c.piece == null) '-'.toByte else (c.piece.number + 48).toByte )) def firstEmptyCellIndex() = cells.findIndexOf(c => c.isEmpty) @@ -144,13 +144,13 @@ final class Board { def add(pieceIndex: Int, boardIndex: Int, p: Piece) = { cellCount = 0 p.unmark - + find( p.cells(pieceIndex), cells(boardIndex)) - val boardHasSpace = cellCount == Piece.size && - cellsPieceWillFill.forall(c => c.isEmpty) + val boardHasSpace = cellCount == Piece.size && + cellsPieceWillFill.forall(c => c.isEmpty) - if (boardHasSpace) cellsPieceWillFill.foreach(c => c.piece = p) + if (boardHasSpace) cellsPieceWillFill.foreach(c => c.piece = p) boardHasSpace } @@ -180,10 +180,10 @@ final class Board { if (row % 2 == 1) { if (!isLast) c.next(Cell.NE) = a(i-(Board.cols-1)) - c.next(Cell.NW) = a(i-Board.cols) + c.next(Cell.NW) = a(i-Board.cols) if (row != m) { if (!isLast) c.next(Cell.SE) = a(i+(Board.cols+1)) - c.next(Cell.SW) = a(i+Board.cols) + c.next(Cell.SW) = a(i+Board.cols) } } else { if (row != 0) { @@ -212,9 +212,9 @@ final class Board { Console.print(i + "\t") for (j <- Iterator.range(0,Cell.sides)){ val c = cells(i).next(j) - if (c == null) - Console.print("-- ") - else + if (c == null) + Console.print("-- ") + else Console.printf("{0,number,00} ")(c.number) } Console.println("") @@ -241,7 +241,7 @@ final class Piece(_number: Int) { val number = _number val cells = for (i <- Array.range(0,Piece.size)) yield new PieceCell() - { + { number match { case 0 => make0 case 1 => make1 @@ -252,7 +252,7 @@ final class Piece(_number: Int) { case 6 => make6 case 7 => make7 case 8 => make8 - case 9 => make9 + case 9 => make9 } } @@ -395,12 +395,12 @@ final class Piece(_number: Int) { Console.print(i + "\t") for (j <- Iterator.range(0,Cell.sides)){ val c = cells(i).next(j) - if (c == null) - Console.print("-- ") - else + if (c == null) + Console.print("-- ") + else for (k <- Iterator.range(0,Piece.size)){ if (cells(k) == c) Console.printf(" {0,number,0} ")(k) - } + } } Console.println("") } @@ -418,13 +418,13 @@ final class Piece(_number: Int) { object Cell { val NW = 0; val NE = 1 val W = 2; val E = 3 - val SW = 4; val SE = 5 + val SW = 4; val SE = 5 val sides = 6 } abstract class Cell { - implicit def m: Manifest[T] + implicit def t: ClassTag[T] type T val next = new Array[T](Cell.sides) var marked = false @@ -437,7 +437,7 @@ abstract class Cell { final class BoardCell(_number: Int) extends { type T = BoardCell - implicit val m = manifest[BoardCell] + implicit val t = classTag[BoardCell] } with Cell { val number = _number var piece: Piece = _ @@ -448,10 +448,10 @@ final class BoardCell(_number: Int) extends { def contiguousEmptyCells(): Int = { if (!marked && isEmpty){ mark - var count = 1 + var count = 1 for (neighbour <- next) - if (neighbour != null && neighbour.isEmpty) + if (neighbour != null && neighbour.isEmpty) count = count + neighbour.contiguousEmptyCells count } else { 0 } diff --git a/test/scaladoc/resources/implicits-base-res.scala b/test/scaladoc/resources/implicits-base-res.scala index 3e3d0f01a6..65d7bdf67c 100644 --- a/test/scaladoc/resources/implicits-base-res.scala +++ b/test/scaladoc/resources/implicits-base-res.scala @@ -137,6 +137,8 @@ class ManifestA[W: Manifest](a: A[W]) { def convToManifestA(x: W): W = sys.error("dunno") } +// [Eugene to Vlad] how do I test typetags here? + /** MyTraversableOps class
* - checks if any abstract members are added - should not happen! */ @@ -144,4 +146,3 @@ trait MyTraversableOps[S] { /** The convToTraversableOps: S documentation... */ def convToTraversableOps(x: S): S } - -- cgit v1.2.3 From f54e5c8bbdd719b5c9375c64c2f66b841984456e Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sun, 22 Apr 2012 18:49:09 +0200 Subject: resurrects manifests in their pre-2.10 glory --- .../scala/reflect/internal/Definitions.scala | 7 + src/compiler/scala/tools/nsc/ast/TreeGen.scala | 16 + .../scala/tools/nsc/typechecker/Implicits.scala | 107 +++- src/library/scala/Predef.scala | 11 +- .../scala/collection/mutable/WrappedArray.scala | 2 +- src/library/scala/reflect/ClassManifest.scala | 242 ++++++++ src/library/scala/reflect/Manifest.scala | 259 ++++++++ src/library/scala/reflect/NoManifest.scala | 16 + src/library/scala/reflect/OptManifest.scala | 18 + src/library/scala/reflect/package.scala | 14 - test/files/jvm/manifests-old.check | 55 ++ test/files/jvm/manifests-old.scala | 109 ++++ test/files/jvm/serialization.check | 313 ++++++++++ test/files/jvm/serialization.scala | 651 +++++++++++++++++++++ test/files/neg/t3507-old.check | 4 + test/files/neg/t3507-old.scala | 15 + test/files/neg/t3692-old.check | 8 + test/files/neg/t3692-old.flags | 1 + test/files/neg/t3692-old.scala | 19 + test/files/neg/t5452-old.check | 8 + test/files/neg/t5452-old.scala | 29 + test/files/pos/contextbounds-implicits-old.scala | 8 + test/files/pos/implicits-old.scala | 89 +++ test/files/pos/manifest1-old.scala | 21 + test/files/pos/nothing_manifest_disambig-old.scala | 10 + test/files/pos/spec-constr-old.scala | 7 + test/files/pos/spec-doubledef-old.scala | 28 + test/files/pos/spec-fields-old.scala | 10 + test/files/pos/spec-params-old.scala | 32 + test/files/pos/spec-sparsearray-old.scala | 24 + test/files/pos/t1381-old.scala | 31 + test/files/pos/t2795-old.scala | 17 + test/files/pos/t3363-old.scala | 18 + test/files/pos/t3498-old.scala | 15 + test/files/run/arrayclone-old.scala | 106 ++++ test/files/run/ctries-old/DumbHash.scala | 14 + test/files/run/ctries-old/Wrap.scala | 9 + test/files/run/ctries-old/concmap.scala | 188 ++++++ test/files/run/ctries-old/iterator.scala | 289 +++++++++ test/files/run/ctries-old/lnode.scala | 61 ++ test/files/run/ctries-old/main.scala | 45 ++ test/files/run/ctries-old/snapshot.scala | 267 +++++++++ test/files/run/existentials3-old.check | 22 + test/files/run/existentials3-old.scala | 73 +++ test/files/run/getClassTest-old.check | 18 + test/files/run/getClassTest-old.scala | 66 +++ test/files/run/manifests-old.scala | 147 +++++ test/files/run/patmat_unapp_abstype-old.check | 4 + test/files/run/patmat_unapp_abstype-old.flags | 1 + test/files/run/patmat_unapp_abstype-old.scala | 83 +++ test/files/run/primitive-sigs-2-old.check | 7 + test/files/run/primitive-sigs-2-old.scala | 39 ++ test/files/run/reflection-implClass-old.scala | 38 ++ test/files/run/reify_implicits-old.check | 1 + test/files/run/reify_implicits-old.scala | 14 + test/files/run/t0421-old.check | 3 + test/files/run/t0421-old.scala | 30 + test/files/run/t0677-old.scala | 8 + test/files/run/t1195-old.check | 6 + test/files/run/t1195-old.scala | 26 + test/files/run/t2236-old.scala | 17 + test/files/run/t3758-old.scala | 10 + test/files/run/t4110-old.check | 2 + test/files/run/t4110-old.scala | 11 + test/files/scalacheck/array-old.scala | 37 ++ test/files/specialized/spec-matrix-old.check | 2 + test/files/specialized/spec-matrix-old.scala | 80 +++ 67 files changed, 3913 insertions(+), 25 deletions(-) create mode 100644 src/library/scala/reflect/ClassManifest.scala create mode 100644 src/library/scala/reflect/Manifest.scala create mode 100644 src/library/scala/reflect/NoManifest.scala create mode 100644 src/library/scala/reflect/OptManifest.scala create mode 100644 test/files/jvm/manifests-old.check create mode 100644 test/files/jvm/manifests-old.scala create mode 100644 test/files/jvm/serialization.check create mode 100644 test/files/jvm/serialization.scala create mode 100644 test/files/neg/t3507-old.check create mode 100644 test/files/neg/t3507-old.scala create mode 100644 test/files/neg/t3692-old.check create mode 100644 test/files/neg/t3692-old.flags create mode 100644 test/files/neg/t3692-old.scala create mode 100644 test/files/neg/t5452-old.check create mode 100644 test/files/neg/t5452-old.scala create mode 100644 test/files/pos/contextbounds-implicits-old.scala create mode 100644 test/files/pos/implicits-old.scala create mode 100644 test/files/pos/manifest1-old.scala create mode 100644 test/files/pos/nothing_manifest_disambig-old.scala create mode 100644 test/files/pos/spec-constr-old.scala create mode 100644 test/files/pos/spec-doubledef-old.scala create mode 100644 test/files/pos/spec-fields-old.scala create mode 100644 test/files/pos/spec-params-old.scala create mode 100644 test/files/pos/spec-sparsearray-old.scala create mode 100644 test/files/pos/t1381-old.scala create mode 100644 test/files/pos/t2795-old.scala create mode 100644 test/files/pos/t3363-old.scala create mode 100644 test/files/pos/t3498-old.scala create mode 100644 test/files/run/arrayclone-old.scala create mode 100644 test/files/run/ctries-old/DumbHash.scala create mode 100644 test/files/run/ctries-old/Wrap.scala create mode 100644 test/files/run/ctries-old/concmap.scala create mode 100644 test/files/run/ctries-old/iterator.scala create mode 100644 test/files/run/ctries-old/lnode.scala create mode 100644 test/files/run/ctries-old/main.scala create mode 100644 test/files/run/ctries-old/snapshot.scala create mode 100644 test/files/run/existentials3-old.check create mode 100644 test/files/run/existentials3-old.scala create mode 100644 test/files/run/getClassTest-old.check create mode 100644 test/files/run/getClassTest-old.scala create mode 100644 test/files/run/manifests-old.scala create mode 100644 test/files/run/patmat_unapp_abstype-old.check create mode 100644 test/files/run/patmat_unapp_abstype-old.flags create mode 100644 test/files/run/patmat_unapp_abstype-old.scala create mode 100644 test/files/run/primitive-sigs-2-old.check create mode 100644 test/files/run/primitive-sigs-2-old.scala create mode 100644 test/files/run/reflection-implClass-old.scala create mode 100644 test/files/run/reify_implicits-old.check create mode 100644 test/files/run/reify_implicits-old.scala create mode 100644 test/files/run/t0421-old.check create mode 100644 test/files/run/t0421-old.scala create mode 100644 test/files/run/t0677-old.scala create mode 100644 test/files/run/t1195-old.check create mode 100644 test/files/run/t1195-old.scala create mode 100644 test/files/run/t2236-old.scala create mode 100644 test/files/run/t3758-old.scala create mode 100644 test/files/run/t4110-old.check create mode 100644 test/files/run/t4110-old.scala create mode 100644 test/files/scalacheck/array-old.scala create mode 100644 test/files/specialized/spec-matrix-old.check create mode 100644 test/files/specialized/spec-matrix-old.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 29eb573b64..6cb935edad 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -485,6 +485,13 @@ trait Definitions extends reflect.api.StandardDefinitions { // [Eugene] is this a good place for ReflectMirrorPrefix? def ReflectMirrorPrefix = gen.mkAttributedRef(ReflectMirror) setType singleType(ReflectMirror.owner.thisPrefix, ReflectMirror) + 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 = getMemberClass(ExprClass, nme.tree) def ExprTpe = getMemberClass(ExprClass, nme.tpe) diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index d3e64811d3..978d83616b 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -177,6 +177,22 @@ 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/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 3f4e941ec6..fadb691cb6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1129,7 +1129,10 @@ trait Implicits { ConcreteTypeTagClass -> MacroInternal_materializeConcreteTypeTag ) - def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = { + /** Creates a tree will produce a tag of the requested flavor. + * An EmptyTree is returned if materialization fails. + */ + private def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = { def success(arg: Tree) = try { val tree1 = typed(atPos(pos.focus)(arg)) @@ -1171,9 +1174,111 @@ trait Implicits { else failure(materializer, "macros are disabled") } + private val ManifestSymbols = Set[Symbol](PartialManifestClass, FullManifestClass, OptManifestClass) + + /** 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 + } + + /** Creates a tree representing one of the singleton manifests.*/ + def findSingletonManifest(name: String) = typedPos(tree.pos.focus) { + Select(gen.mkAttributedRef(FullManifestModule), name) + } + + /** 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) +*/ + } + } + + mot(tp, Nil, Nil) + } + + def wrapResult(tree: Tree): SearchResult = + if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter) + /** The tag corresponding to type `pt`, provided `pt` is a flavor of a tag. */ private def implicitTagOrOfExpectedType(pt: Type): SearchResult = pt.dealias match { + case TypeRef(pre, sym, arg :: Nil) if ManifestSymbols(sym) => + manifestOfType(arg, sym == FullManifestClass) match { + case SearchFailure if sym == OptManifestClass => wrapResult(gen.mkAttributedRef(NoManifest)) + case result => result + } case TypeRef(pre, sym, arg :: Nil) if TagSymbols(sym) => tagOfType(pre, arg, sym) case tp@TypeRef(_, sym, _) if sym.isAbstractType => diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 093f972f72..d2aa3a8b34 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -100,19 +100,12 @@ 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] - @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.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.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 + val Manifest = scala.reflect.Manifest + val NoManifest = scala.reflect.NoManifest def manifest[T](implicit m: Manifest[T]) = m def classManifest[T](implicit m: ClassManifest[T]) = m diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala index 5e20f4ec61..9d170b2832 100644 --- a/src/library/scala/collection/mutable/WrappedArray.scala +++ b/src/library/scala/collection/mutable/WrappedArray.scala @@ -45,7 +45,7 @@ extends AbstractSeq[T] def elemTag: ArrayTag[T] @deprecated("use elemTag instead", "2.10.0") - def elemManifest: ClassManifest[T] = ClassManifest[T](arrayElementClass(elemTag)) + def elemManifest: ClassManifest[T] = ClassManifest.fromClass[T](arrayElementClass(elemTag).asInstanceOf[Class[T]]) /** The length of the array */ def length: Int diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala new file mode 100644 index 0000000000..43e043fd40 --- /dev/null +++ b/src/library/scala/reflect/ClassManifest.scala @@ -0,0 +1,242 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +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. + */ +@deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") +trait ClassManifest[T] extends OptManifest[T] with ClassTag[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[_] + + 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 + + override 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) + + override 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. + */ +@deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") +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 <: AnyRef](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 <: AnyRef](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 <: AnyRef](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 */ +private class ClassTypeManifest[T <: AnyRef]( + 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 +} \ No newline at end of file diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala new file mode 100644 index 0000000000..da029f046d --- /dev/null +++ b/src/library/scala/reflect/Manifest.scala @@ -0,0 +1,259 @@ +/* __ *\ +** ________ ___ / / ___ 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}.") +@deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") +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.## +} + +@deprecated("Use type tags and manually check the corresponding class or type instead", "2.10.0") +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. + */ +@deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") +object Manifest { + 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 <:<(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 <:<(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 <:<(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 <:<(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 <:<(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 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) + + private abstract class PhantomManifest[T](override val toString: String) extends ClassTypeManifest[T](None, classOf[java.lang.Object], Nil) { + override def equals(that: Any): Boolean = 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 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 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 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 def toString = parents.mkString(" with ") + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/NoManifest.scala b/src/library/scala/reflect/NoManifest.scala new file mode 100644 index 0000000000..7b8037272c --- /dev/null +++ b/src/library/scala/reflect/NoManifest.scala @@ -0,0 +1,16 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.reflect + +/** One of the branches of an [[scala.reflect.OptManifest]]. + */ +@deprecated("Use `@scala.reflect.TypeTag` instead", "2.10.0") +object NoManifest extends OptManifest[Nothing] with Serializable { + override def toString = "" +} \ No newline at end of file diff --git a/src/library/scala/reflect/OptManifest.scala b/src/library/scala/reflect/OptManifest.scala new file mode 100644 index 0000000000..46f23c4e22 --- /dev/null +++ b/src/library/scala/reflect/OptManifest.scala @@ -0,0 +1,18 @@ +/* __ *\ +** ________ ___ / / ___ 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 + */ +@deprecated("Use `@scala.reflect.TypeTag` instead", "2.10.0") +trait OptManifest[+T] extends Serializable \ No newline at end of file diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 640cad6c21..0e6350183f 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -53,20 +53,6 @@ package object reflect { @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.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.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") - lazy val NoManifest = TypeTag.Nothing - // ArrayTag trait is defined separately from the mirror // ErasureTag trait is defined separately from the mirror // ConcreteErasureTag trait is defined separately from the mirror diff --git a/test/files/jvm/manifests-old.check b/test/files/jvm/manifests-old.check new file mode 100644 index 0000000000..54f504b929 --- /dev/null +++ b/test/files/jvm/manifests-old.check @@ -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-old.scala b/test/files/jvm/manifests-old.scala new file mode 100644 index 0000000000..241966fd9d --- /dev/null +++ b/test/files/jvm/manifests-old.scala @@ -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/jvm/serialization.check b/test/files/jvm/serialization.check new file mode 100644 index 0000000000..fa51c6a879 --- /dev/null +++ b/test/files/jvm/serialization.check @@ -0,0 +1,313 @@ +a1 = Array[1,2,3] +_a1 = Array[1,2,3] +arrayEquals(a1, _a1): true + +e1 = Left(1) +_e1 = Left(1) +e1 eq _e1: false, _e1 eq e1: false +e1 equals _e1: true, _e1 equals e1: true + +x7 = RoundingMode +y7 = RoundingMode +x7 eq y7: true, y7 eq x7: true +x7 equals y7: true, y7 equals x7: true + +x8 = WeekDay +y8 = WeekDay +x8 eq y8: true, y8 eq x8: true +x8 equals y8: true, y8 equals x8: true + +x9 = UP +y9 = UP +x9 eq y9: true, y9 eq x9: true +x9 equals y9: true, y9 equals x9: true + +x10 = Monday +y10 = Monday +x10 eq y10: true, y10 eq x10: true +x10 equals y10: true, y10 equals x10: true + +x9 eq x10: false, x10 eq x9: false +x9 equals x10: false, x10 equals x9: false +x9 eq y10: false, y10 eq x9: false +x9 equals y10: false, y10 equals x9: false + +f1 = +_f1 = +f1(2): 4, _f1(2): 4 + +xs0 = List(1, 2, 3) +_xs0 = List(1, 2, 3) +xs0 eq _xs0: false, _xs0 eq xs0: false +xs0 equals _xs0: true, _xs0 equals xs0: true + +xs1 = List() +_xs1 = List() +xs1 eq _xs1: true, _xs1 eq xs1: true + +o1 = None +_o1 = None +o1 eq _o1: true, _o1 eq o1: true + +o2 = Some(1) +_o2 = Some(1) +o2 eq _o2: false, _o2 eq o2: false +o2 equals _o2: true, _o2 equals o2: true + +s1 = 'hello +_s1 = 'hello +s1 eq _s1: true, _s1 eq s1: true +s1 equals _s1: true, _s1 equals s1: true + +t1 = (BannerLimit,12345) +_t1 = (BannerLimit,12345) +t1 eq _t1: false, _t1 eq t1: false +t1 equals _t1: true, _t1 equals t1: true + +x = BitSet(1, 2) +y = BitSet(1, 2) +x equals y: true, y equals x: true + +x = BitSet(2, 3) +y = BitSet(2, 3) +x equals y: true, y equals x: true + +x = Map(1 -> A, 2 -> B, 3 -> C) +y = Map(1 -> A, 2 -> B, 3 -> C) +x equals y: true, y equals x: true + +x = Set(1, 2) +y = Set(1, 2) +x equals y: true, y equals x: true + +x = List((buffers,20), (layers,2), (title,3)) +y = List((buffers,20), (layers,2), (title,3)) +x equals y: true, y equals x: true + +x = Map(buffers -> 20, layers -> 2, title -> 3) +y = Map(buffers -> 20, layers -> 2, title -> 3) +x equals y: true, y equals x: true + +x = ListSet(5, 3) +y = ListSet(5, 3) +x equals y: true, y equals x: true + +x = Queue(a, b, c) +y = Queue(a, b, c) +x equals y: true, y equals x: true + +x = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) +y = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) +x equals y: true, y equals x: true + +x = NumericRange(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) +y = NumericRange(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) +x equals y: true, y equals x: true + +x = Map(1 -> A, 2 -> B, 3 -> C) +y = Map(1 -> A, 2 -> B, 3 -> C) +x equals y: true, y equals x: true + +x = TreeSet(1, 2, 3) +y = TreeSet(1, 2, 3) +x equals y: true, y equals x: true + +x = Stack(c, b, a) +y = Stack(c, b, a) +x equals y: true, y equals x: true + +x = Stream(0, ?) +y = Stream(0, ?) +x equals y: true, y equals x: true + +x = Map(42 -> FortyTwo) +y = Map(42 -> FortyTwo) +x equals y: true, y equals x: true + +x = TreeSet(0, 2) +y = TreeSet(0, 2) +x equals y: true, y equals x: true + +x = Vector('a, 'b, 'c) +y = Vector('a, 'b, 'c) +x equals y: true, y equals x: true + +x = ArrayBuffer(one, two) +y = ArrayBuffer(one, two) +x equals y: true, y equals x: true + +x = ArrayBuilder.ofLong +y = ArrayBuilder.ofLong +x equals y: true, y equals x: true + +x = ArrayBuilder.ofFloat +y = ArrayBuilder.ofFloat +x equals y: true, y equals x: true + +x = ArraySeq(1, 2, 3) +y = ArraySeq(1, 2, 3) +x equals y: true, y equals x: true + +x = ArrayStack(3, 2, 20) +y = ArrayStack(3, 2, 20) +x equals y: true, y equals x: true + +x = BitSet(0, 8, 9) +y = BitSet(0, 8, 9) +x equals y: true, y equals x: true + +x = Map(A -> 1, C -> 3, B -> 2) +y = Map(A -> 1, C -> 3, B -> 2) +x equals y: true, y equals x: true + +x = Set(buffers, title, layers) +y = Set(buffers, title, layers) +x equals y: true, y equals x: true + +x = History() +y = History() +x equals y: true, y equals x: true + +x = ListBuffer(white, black) +y = ListBuffer(white, black) +x equals y: true, y equals x: true + +x = Queue(20, 2, 3) +y = Queue(20, 2, 3) +x equals y: true, y equals x: true + +x = Stack(3, 2, 20) +y = Stack(3, 2, 20) +x equals y: true, y equals x: true + +x = abc +y = abc +x equals y: true, y equals x: true + +x = WrappedArray(1, 2, 3) +y = WrappedArray(1, 2, 3) +x equals y: true, y equals x: true + +x = TreeSet(1, 2, 3) +y = TreeSet(1, 2, 3) +x equals y: true, y equals x: true + +x = TrieMap(1 -> one, 2 -> two, 3 -> three) +y = TrieMap(1 -> one, 2 -> two, 3 -> three) +x equals y: true, y equals x: true + +x = xml:src="hello" +y = xml:src="hello" +x equals y: true, y equals x: true + +x = +y = +x equals y: true, y equals x: true + +x = title +y = title +x equals y: true, y equals x: true + +x = + + + + + + + + + + + + + + + + +
Last NameFirst Name
Tom 20
Bob 22
James 19
+ + +y = + + + + + + + + + + + + + + + + +
Last NameFirst Name
Tom 20
Bob 22
James 19
+ + +x equals y: true, y equals x: true + +x = Tim +y = Tim +x equals y: true, y equals x: true + +x = Bob +y = Bob +x equals y: true, y equals x: true + +x = John +y = John +x equals y: true, y equals x: true + +x = Bill +y = Bill +x equals y: true, y equals x: true + +x = Paul +y = Paul +x equals y: true, y equals x: true + +1 +2 +1 +2 + +x = UnrolledBuffer(one, two) +y = UnrolledBuffer(one, two) +x equals y: true, y equals x: true + +x = ParArray(abc, def, etc) +y = ParArray(abc, def, etc) +x equals y: true, y equals x: true + +x = ParHashMap(2 -> 4, 1 -> 2) +y = ParHashMap(2 -> 4, 1 -> 2) +x equals y: true, y equals x: true + +x = ParTrieMap(1 -> 2, 2 -> 4) +y = ParTrieMap(1 -> 2, 2 -> 4) +x equals y: true, y equals x: true + +x = ParHashSet(1, 2, 3) +y = ParHashSet(1, 2, 3) +x equals y: true, y equals x: true + +x = ParRange(0, 1, 2, 3, 4) +y = ParRange(0, 1, 2, 3, 4) +x equals y: true, y equals x: true + +x = ParRange(0, 1, 2, 3) +y = ParRange(0, 1, 2, 3) +x equals y: true, y equals x: true + +x = ParMap(5 -> 1, 10 -> 2) +y = ParMap(5 -> 1, 10 -> 2) +x equals y: true, y equals x: true + +x = ParSet(two, one) +y = ParSet(two, one) +x equals y: true, y equals x: true + diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala new file mode 100644 index 0000000000..9c2f2acdbf --- /dev/null +++ b/test/files/jvm/serialization.scala @@ -0,0 +1,651 @@ +//############################################################################ +// Serialization +//############################################################################ + +object Serialize { + @throws(classOf[java.io.IOException]) + def write[A](o: A): Array[Byte] = { + val ba = new java.io.ByteArrayOutputStream(512) + val out = new java.io.ObjectOutputStream(ba) + out.writeObject(o) + out.close() + ba.toByteArray() + } + @throws(classOf[java.io.IOException]) + @throws(classOf[ClassNotFoundException]) + def read[A](buffer: Array[Byte]): A = { + val in = + new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(buffer)) + in.readObject().asInstanceOf[A] + } + def check[A, B](x: A, y: B) { + println("x = " + x) + println("y = " + y) + println("x equals y: " + (x equals y) + ", y equals x: " + (y equals x)) + assert((x equals y) && (y equals x)) + println() + } +} +import Serialize._ + +//############################################################################ +// Test classes in package "scala" + +object Test1_scala { + + private def arrayToString[A](arr: Array[A]): String = + arr.mkString("Array[",",","]") + + private def arrayEquals[A, B](a1: Array[A], a2: Array[B]): Boolean = + (a1.length == a2.length) && + (Iterator.range(0, a1.length) forall { i => a1(i) == a2(i) }) + + object WeekDay extends Enumeration { + type WeekDay = Value + val Monday, Tuesday, Wednesday, Thusday, Friday, Saturday, Sunday = Value + } + import WeekDay._, BigDecimal._, RoundingMode._ + + // in alphabetic order + try { + // Array + val a1 = Array(1, 2, 3) + val _a1: Array[Int] = read(write(a1)) + println("a1 = " + arrayToString(a1)) + println("_a1 = " + arrayToString(_a1)) + println("arrayEquals(a1, _a1): " + arrayEquals(a1, _a1)) + println() + + // Either + val e1 = Left(1) + val _e1: Either[Int, String] = read(write(e1)) + println("e1 = " + e1) + println("_e1 = " + _e1) + println("e1 eq _e1: " + (e1 eq _e1) + ", _e1 eq e1: " + (_e1 eq e1)) + println("e1 equals _e1: " + (e1 equals _e1) + ", _e1 equals e1: " + (_e1 equals e1)) + println() + + // Enumeration + val x7 = BigDecimal.RoundingMode + val y7: RoundingMode.type = read(write(x7)) + println("x7 = " + x7) + println("y7 = " + y7) + println("x7 eq y7: " + (x7 eq y7) + ", y7 eq x7: " + (y7 eq x7)) + println("x7 equals y7: " + (x7 equals y7) + ", y7 equals x7: " + (y7 equals x7)) + println() + + val x8 = WeekDay + val y8: WeekDay.type = read(write(x8)) + println("x8 = " + x8) + println("y8 = " + y8) + println("x8 eq y8: " + (x8 eq y8) + ", y8 eq x8: " + (y8 eq x8)) + println("x8 equals y8: " + (x8 equals y8) + ", y8 equals x8: " + (y8 equals x8)) + println() + + val x9 = UP + val y9: RoundingMode = read(write(x9)) + println("x9 = " + x9) + println("y9 = " + y9) + println("x9 eq y9: " + (x9 eq y9) + ", y9 eq x9: " + (y9 eq x9)) + println("x9 equals y9: " + (x9 equals y9) + ", y9 equals x9: " + (y9 equals x9)) + println() + + val x10 = Monday + val y10: WeekDay = read(write(x10)) + println("x10 = " + x10) + println("y10 = " + y10) + println("x10 eq y10: " + (x10 eq y10) + ", y10 eq x10: " + (y10 eq x10)) + println("x10 equals y10: " + (x10 equals y10) + ", y10 equals x10: " + (y10 equals x10)) + println() + + println("x9 eq x10: " + (x9 eq x10) + ", x10 eq x9: " + (x10 eq x9)) + println("x9 equals x10: " + (x9 equals x10) + ", x10 equals x9: " + (x10 equals x9)) + println("x9 eq y10: " + (x9 eq y10) + ", y10 eq x9: " + (y10 eq x9)) + println("x9 equals y10: " + (x9 equals y10) + ", y10 equals x9: " + (y10 equals x9)) + println() + + // Function + val f1 = { x: Int => 2 * x } + val _f1: Function[Int, Int] = read(write(f1)) + println("f1 = ") + println("_f1 = ") + println("f1(2): " + f1(2) + ", _f1(2): " + _f1(2)) + println() + + // List + val xs0 = List(1, 2, 3) + val _xs0: List[Int] = read(write(xs0)) + println("xs0 = " + xs0) + println("_xs0 = " + _xs0) + println("xs0 eq _xs0: " + (xs0 eq _xs0) + ", _xs0 eq xs0: " + (_xs0 eq xs0)) + println("xs0 equals _xs0: " + (xs0 equals _xs0) + ", _xs0 equals xs0: " + (_xs0 equals xs0)) + println() + + val xs1 = Nil + val _xs1: List[Nothing] = read(write(xs1)) + println("xs1 = " + xs1) + println("_xs1 = " + _xs1) + println("xs1 eq _xs1: " + (xs1 eq _xs1) + ", _xs1 eq xs1: " + (_xs1 eq xs1)) + println() + + // Option + val o1 = None + val _o1: Option[Nothing] = read(write(o1)) + println("o1 = " + o1) + println("_o1 = " + _o1) + println("o1 eq _o1: " + (o1 eq _o1) + ", _o1 eq o1: " + (_o1 eq o1)) + println() + + val o2 = Some(1) + val _o2: Option[Int] = read(write(o2)) + println("o2 = " + o2) + println("_o2 = " + _o2) + println("o2 eq _o2: " + (o2 eq _o2) + ", _o2 eq o2: " + (_o2 eq o2)) + println("o2 equals _o2: " + (o2 equals _o2) + ", _o2 equals o2: " + (_o2 equals o2)) + println() +/* + // Responder + val r1 = Responder.constant("xyz") + val _r1: Responder[String] = read(write(r1)) + check(r1, _r1) +*/ + // Symbol + val s1 = 'hello + val _s1: Symbol = read(write(s1)) + println("s1 = " + s1) + println("_s1 = " + _s1) + println("s1 eq _s1: " + (s1 eq _s1) + ", _s1 eq s1: " + (_s1 eq s1)) + println("s1 equals _s1: " + (s1 equals _s1) + ", _s1 equals s1: " + (_s1 equals s1)) + println() + + // Tuple + val t1 = ("BannerLimit", 12345) + val _t1: (String, Int) = read(write(t1)) + println("t1 = " + t1) + println("_t1 = " + _t1) + println("t1 eq _t1: " + (t1 eq _t1) + ", _t1 eq t1: " + (_t1 eq t1)) + println("t1 equals _t1: " + (t1 equals _t1) + ", _t1 equals t1: " + (_t1 equals t1)) + println() + } + catch { + case e: Exception => + println("Error in Test1_scala: " + e) + throw e + } +} + +//############################################################################ +// Test classes in package "scala.collection.immutable" + +object Test2_immutable { + import scala.collection.immutable.{ + BitSet, HashMap, HashSet, ListMap, ListSet, Queue, Range, SortedMap, + SortedSet, Stack, Stream, TreeMap, TreeSet, Vector} + + // in alphabetic order + try { + // BitSet + val bs1 = BitSet.empty + 1 + 2 + val _bs1: BitSet = read(write(bs1)) + check(bs1, _bs1) + + val bs2 = { + val bs = new collection.mutable.BitSet() + bs += 2; bs += 3 + bs.toImmutable + } + val _bs2: BitSet = read(write(bs2)) + check(bs2, _bs2) + + // HashMap + val hm1 = new HashMap[Int, String] + (1 -> "A", 2 -> "B", 3 -> "C") + val _hm1: HashMap[Int, String] = read(write(hm1)) + check(hm1, _hm1) + + // HashSet + val hs1 = new HashSet[Int] + 1 + 2 + val _hs1: HashSet[Int] = read(write(hs1)) + check(hs1, _hs1) + + // List + val xs1 = List(("buffers", 20), ("layers", 2), ("title", 3)) + val _xs1: List[(String, Int)] = read(write(xs1)) + check(xs1, _xs1) + + // ListMap + val lm1 = new ListMap[String, Int] + ("buffers" -> 20, "layers" -> 2, "title" -> 3) + val _lm1: ListMap[String, Int] = read(write(lm1)) + check(lm1, _lm1) + + // ListSet + val ls1 = new ListSet[Int] + 3 + 5 + val _ls1: ListSet[Int] = read(write(ls1)) + check(ls1, _ls1) + + // Queue + val q1 = Queue("a", "b", "c") + val _q1: Queue[String] = read(write(q1)) + check(q1, _q1) + + // Range + val r1 = 0 until 10 + val _r1: Range = read(write(r1)) + check(r1, _r1) + + val r2 = Range.Long(0L, 10L, 1) + val _r2: r2.type = read(write(r2)) + check(r2, _r2) + + // SortedMap + val sm1 = SortedMap.empty[Int, String] + (2 -> "B", 3 -> "C", 1 -> "A") + val _sm1: SortedMap[Int, String] = read(write(sm1)) + check(sm1, _sm1) + + // SortedSet + val ss1 = SortedSet.empty[Int] + 2 + 3 + 1 + val _ss1: SortedSet[Int] = read(write(ss1)) + check(ss1, _ss1) + + // Stack + val s1 = new Stack().push("a", "b", "c") + val _s1: Stack[String] = read(write(s1)) + check(s1, _s1) + + // Stream + val st1 = Stream.range(0, 10) + val _st1: Stream[Int] = read(write(st1)) + check(st1, _st1) + + // TreeMap + val tm1 = new TreeMap[Int, String] + (42 -> "FortyTwo") + val _tm1: TreeMap[Int, String] = read(write(tm1)) + check(tm1, _tm1) + + // TreeSet + val ts1 = new TreeSet[Int]() + 2 + 0 + val _ts1: TreeSet[Int] = read(write(ts1)) + check(ts1, _ts1) + + // Vector + val v1 = Vector('a, 'b, 'c) + val _v1: Vector[Symbol] = read(write(v1)) + check(v1, _v1) + } + catch { + case e: Exception => + println("Error in Test2_immutable: " + e) + throw e + } +} + +//############################################################################ +// Test classes in package "scala.collection.mutable" + +object Test3_mutable { + import scala.reflect.ClassManifest + import scala.collection.mutable.{ + ArrayBuffer, ArrayBuilder, ArraySeq, ArrayStack, BitSet, DoubleLinkedList, + HashMap, HashSet, History, LinkedList, ListBuffer, Publisher, Queue, + Stack, StringBuilder, WrappedArray, TreeSet} + import scala.collection.concurrent.TrieMap + + // in alphabetic order + try { + // ArrayBuffer + val ab1 = new ArrayBuffer[String] + ab1 ++= List("one", "two") + val _ab1: ArrayBuffer[String] = read(write(ab1)) + check(ab1, _ab1) + + // ArrayBuilder + val abu1 = ArrayBuilder.make[Long] + val _abu1: ArrayBuilder[ClassManifest[Long]] = read(write(abu1)) + check(abu1, _abu1) + + val abu2 = ArrayBuilder.make[Float] + val _abu2: ArrayBuilder[ClassManifest[Float]] = read(write(abu2)) + check(abu2, _abu2) + + // ArraySeq + val aq1 = ArraySeq(1, 2, 3) + val _aq1: ArraySeq[Int] = read(write(aq1)) + check(aq1, _aq1) + + // ArrayStack + val as1 = new ArrayStack[Int] + as1 ++= List(20, 2, 3).iterator + val _as1: ArrayStack[Int] = read(write(as1)) + check(as1, _as1) + + // BitSet + val bs1 = new BitSet() + bs1 += 0 + bs1 += 8 + bs1 += 9 + val _bs1: BitSet = read(write(bs1)) + check(bs1, _bs1) +/* + // DoubleLinkedList + val dl1 = new DoubleLinkedList[Int](2, null) + dl1.append(new DoubleLinkedList(3, null)) + val _dl1: DoubleLinkedList[Int] = read(write(dl1)) + check(dl1, _dl1) +*/ + // HashMap + val hm1 = new HashMap[String, Int] + hm1 ++= List(("A", 1), ("B", 2), ("C", 3)).iterator + val _hm1: HashMap[String, Int] = read(write(hm1)) + check(hm1, _hm1) + + // HashSet + val hs1 = new HashSet[String] + hs1 ++= List("layers", "buffers", "title").iterator + val _hs1: HashSet[String] = read(write(hs1)) + check(hs1, _hs1) + + val h1 = new History[String, Int] + val _h1: History[String, Int] = read(write(h1)) + check(h1, _h1) +/* + // LinkedList + val ll1 = new LinkedList[Int](2, null) + ll1.append(new LinkedList(3, null)) + val _ll1: LinkedList[Int] = read(write(ll1)) + check(ll1, _ll1) +*/ + // ListBuffer + val lb1 = new ListBuffer[String] + lb1 ++= List("white", "black") + val _lb1: ListBuffer[String] = read(write(lb1)) + check(lb1, _lb1) + + // Queue + val q1 = new Queue[Int] + q1 ++= List(20, 2, 3).iterator + val _q1: Queue[Int] = read(write(q1)) + check(q1, _q1) + + // Stack + val s1 = new Stack[Int] + s1 pushAll q1 + val _s1: Stack[Int] = read(write(s1)) + check(s1, _s1) + + // StringBuilder + val sb1 = new StringBuilder + sb1 append "abc" + val _sb1: StringBuilder = read(write(sb1)) + check(sb1, _sb1) + + // WrappedArray + val wa1 = WrappedArray.make(Array(1, 2, 3)) + val _wa1: WrappedArray[Int] = read(write(wa1)) + check(wa1, _wa1) + + // TreeSet + val ts1 = TreeSet[Int]() ++= Array(1, 2, 3) + val _ts1: TreeSet[Int] = read(write(ts1)) + check(ts1, _ts1) + + // concurrent.TrieMap + val ct1 = TrieMap[Int, String]() ++= Array(1 -> "one", 2 -> "two", 3 -> "three") + val _ct1: TrieMap[Int, String] = read(write(ct1)) + check(ct1, _ct1) + } + catch { + case e: Exception => + println("Error in Test3_mutable: " + e) + throw e + } +} + + +//############################################################################ +// Test classes in package "scala.xml" + +object Test4_xml { + import scala.xml.{Attribute, Document, Elem, Null, PrefixedAttribute, Text} + + case class Person(name: String, age: Int) + + try { + // Attribute + val a1 = new PrefixedAttribute("xml", "src", Text("hello"), Null) + val _a1: Attribute = read(write(a1)) + check(a1, _a1) + + // Document + val d1 = new Document + d1.docElem = + d1.encoding = Some("UTF-8") + val _d1: Document = read(write(d1)) + check(d1, _d1) + + // Elem + val e1 = title; + val _e1: Elem = read(write(e1)) + check(e1, _e1) + + class AddressBook(a: Person*) { + private val people: List[Person] = a.toList + def toXHTML = + + + + + + { for (p <- people) yield + + + + } +
Last NameFirst Name
{ p.name } { p.age.toString() }
; + } + + val people = new AddressBook( + Person("Tom", 20), + Person("Bob", 22), + Person("James", 19)) + + val e2 = + + + { people.toXHTML } + + ; + val _e2: Elem = read(write(e2)) + check(e2, _e2) + } + catch { + case e: Exception => + println("Error in Test4_xml: " + e) + throw e + } +} + +//############################################################################ +// Test user-defined classes WITHOUT nesting + +class Person(_name: String) extends Serializable { + private var name = _name + override def toString() = name + override def equals(that: Any): Boolean = + that.isInstanceOf[Person] && + (name == that.asInstanceOf[Person].name) +} + +class Employee(_name: String) extends Serializable { + private var name = _name + override def toString() = name +} + +object bob extends Employee("Bob") + +object Test5 { + val x1 = new Person("Tim") + val x2 = bob + + try { + val y1: Person = read(write(x1)) + val y2: Employee = read(write(x2)) + + check(x1, y1) + check(x2, y2) + } + catch { + case e: Exception => + println("Error in Test5: " + e) + } +} + +//############################################################################ +// Test user-defined classes WITH nesting + +object Test6 { + object bill extends Employee("Bill") { + val x = paul + } + object paul extends Person("Paul") { + val x = 4 // bill; => StackOverflowException !!! + } + val x1 = new Person("John") + val x2 = bill + val x3 = paul + + try { + val y1: Person = read(write(x1)) + val y2: Employee = read(write(x2)) + val y3: Person = read(write(x3)) + + check(x1, y1) + check(x2, y2) + check(x3, y3) + } + catch { + case e: Exception => + println("Error in Test6: " + e) + } +} + +//############################################################################ +// Nested objects cannot get readresolve automatically because after deserialization +// they would be null (they are treated as lazy vals) +class Outer extends Serializable { + object Inner extends Serializable +} + +object Test7 { + val x = new Outer + x.Inner // initialize + val y:Outer = read(write(x)) + if (y.Inner == null) + println("Inner object is null") +} + +// Verify that transient lazy vals don't get serialized +class WithTransient extends Serializable { + @transient lazy val a1 = 1 + @transient private lazy val a2 = 2 + @transient object B extends Serializable + @transient private object C extends Serializable + + def test = { + println(a1) + println(a2) + if (B == null || C == null) + println("Transient nested object failed to serialize properly") + } +} + +object Test8 { + val x = new WithTransient + x.test + try { + val y:WithTransient = read(write(x)) + y.test + } + catch { + case e: Exception => + println("Error in Test8: " + e) + } +} + +//############################################################################ +// Test code + +object Test { + def main(args: Array[String]) { + Test1_scala + Test2_immutable + Test3_mutable + Test4_xml + Test5 + Test6 + Test7 + Test8 + Test9_parallel + } +} + +//############################################################################ + + +//############################################################################ +// Test classes in package "scala.collection.parallel" and subpackages +object Test9_parallel { + import scala.collection.parallel._ + + try { + println() + + // UnrolledBuffer + val ub = new collection.mutable.UnrolledBuffer[String] + ub ++= List("one", "two") + val _ub: collection.mutable.UnrolledBuffer[String] = read(write(ub)) + check(ub, _ub) + + // mutable.ParArray + val pa = mutable.ParArray("abc", "def", "etc") + val _pa: mutable.ParArray[String] = read(write(pa)) + check(pa, _pa) + + // mutable.ParHashMap + val mpm = mutable.ParHashMap(1 -> 2, 2 -> 4) + val _mpm: mutable.ParHashMap[Int, Int] = read(write(mpm)) + check(mpm, _mpm) + + // mutable.ParTrieMap + val mpc = mutable.ParTrieMap(1 -> 2, 2 -> 4) + val _mpc: mutable.ParTrieMap[Int, Int] = read(write(mpc)) + check(mpc, _mpc) + + // mutable.ParHashSet + val mps = mutable.ParHashSet(1, 2, 3) + val _mps: mutable.ParHashSet[Int] = read(write(mps)) + check(mps, _mps) + + // immutable.ParRange + val pr1 = immutable.ParRange(0, 4, 1, true) + val _pr1: immutable.ParRange = read(write(pr1)) + check(pr1, _pr1) + + val pr2 = immutable.ParRange(0, 4, 1, false) + val _pr2: immutable.ParRange = read(write(pr2)) + check(pr2, _pr2) + + // immutable.ParHashMap + val ipm = immutable.ParHashMap(5 -> 1, 10 -> 2) + val _ipm: immutable.ParHashMap[Int, Int] = read(write(ipm)) + check(ipm, _ipm) + + // immutable.ParHashSet + val ips = immutable.ParHashSet("one", "two") + val _ips: immutable.ParHashSet[String] = read(write(ips)) + check(ips, _ips) + + } catch { + case e: Exception => + println("Error in Test5_parallel: " + e) + throw e + } +} diff --git a/test/files/neg/t3507-old.check b/test/files/neg/t3507-old.check new file mode 100644 index 0000000000..5c58444cb3 --- /dev/null +++ b/test/files/neg/t3507-old.check @@ -0,0 +1,4 @@ +t3507-old.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 diff --git a/test/files/neg/t3507-old.scala b/test/files/neg/t3507-old.scala new file mode 100644 index 0000000000..32688d3934 --- /dev/null +++ b/test/files/neg/t3507-old.scala @@ -0,0 +1,15 @@ +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/neg/t3692-old.check b/test/files/neg/t3692-old.check new file mode 100644 index 0000000000..9da7033239 --- /dev/null +++ b/test/files/neg/t3692-old.check @@ -0,0 +1,8 @@ +t3692-old.scala:6: warning: object Manifest in package reflect is deprecated: Use `@scala.reflect.ConcreteTypeTag` instead + new ManifestTester().toJavaMap(map) + ^ +t3692-old.scala:15: error: unreachable code + case m2: Map[T, Int] => new java.util.HashMap[T, Integer] + ^ +one warning found +one error found diff --git a/test/files/neg/t3692-old.flags b/test/files/neg/t3692-old.flags new file mode 100644 index 0000000000..82becdfbfd --- /dev/null +++ b/test/files/neg/t3692-old.flags @@ -0,0 +1 @@ + -Xoldpatmat \ No newline at end of file diff --git a/test/files/neg/t3692-old.scala b/test/files/neg/t3692-old.scala new file mode 100644 index 0000000000..151535ae94 --- /dev/null +++ b/test/files/neg/t3692-old.scala @@ -0,0 +1,19 @@ +import java.lang.Integer + +object ManifestTester { + def main(args: Array[String]) = { + val map = Map("John" -> 1, "Josh" -> 2) + new ManifestTester().toJavaMap(map) + } +} + +class ManifestTester { + private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = { + map match { + case m0: Map[Int, Int] => new java.util.HashMap[Integer, Integer] + case m1: Map[Int, V] => new java.util.HashMap[Integer, V] + case m2: Map[T, Int] => new java.util.HashMap[T, Integer] + case _ => new java.util.HashMap[T, V] + } + } +} \ No newline at end of file diff --git a/test/files/neg/t5452-old.check b/test/files/neg/t5452-old.check new file mode 100644 index 0000000000..e5872a5759 --- /dev/null +++ b/test/files/neg/t5452-old.check @@ -0,0 +1,8 @@ +t5452-old.scala:28: error: overloaded method value apply with alternatives: + ()Queryable[CoffeesTable] + (t: Tree)(implicit evidence$2: Manifest[CoffeesTable])Nothing + (implicit evidence$1: Manifest[CoffeesTable])Nothing + cannot be applied to (Queryable[CoffeesTable]) + Queryable[CoffeesTable]( q.treeFilter(null) ) + ^ +one error found diff --git a/test/files/neg/t5452-old.scala b/test/files/neg/t5452-old.scala new file mode 100644 index 0000000000..1032db7a4b --- /dev/null +++ b/test/files/neg/t5452-old.scala @@ -0,0 +1,29 @@ +// /scala/trac/5452/a.scala +// Mon Feb 13 22:52:36 PST 2012 + +// import scala.reflect.mirror._ + +trait Tree + +object Bip { + def ??? = sys.error("") +} +import Bip._ + +case class Queryable[T]() { + def treeFilter( t:Tree ) : Queryable[T] = ??? +} + +object Queryable { + def apply[T:Manifest] = ??? + def apply[T:Manifest]( t:Tree ) = ??? +} + +trait CoffeesTable{ + def sales : Int +} + +object Test extends App{ + val q = new Queryable[CoffeesTable] + Queryable[CoffeesTable]( q.treeFilter(null) ) +} diff --git a/test/files/pos/contextbounds-implicits-old.scala b/test/files/pos/contextbounds-implicits-old.scala new file mode 100644 index 0000000000..f9113ee320 --- /dev/null +++ b/test/files/pos/contextbounds-implicits-old.scala @@ -0,0 +1,8 @@ +/* Tests implicit parameters in the presence of context bounds. + * See Section 7.4 of the Scala Language Specification. + */ +class C { + + def f[T: Manifest, S: Manifest](x: T, y: S)(implicit p: C) { } + +} diff --git a/test/files/pos/implicits-old.scala b/test/files/pos/implicits-old.scala new file mode 100644 index 0000000000..2c01dd0ba8 --- /dev/null +++ b/test/files/pos/implicits-old.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/manifest1-old.scala b/test/files/pos/manifest1-old.scala new file mode 100644 index 0000000000..8901aa7437 --- /dev/null +++ b/test/files/pos/manifest1-old.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/nothing_manifest_disambig-old.scala b/test/files/pos/nothing_manifest_disambig-old.scala new file mode 100644 index 0000000000..076742033f --- /dev/null +++ b/test/files/pos/nothing_manifest_disambig-old.scala @@ -0,0 +1,10 @@ +object Test { + def mani[T: Manifest](xs: T) = xs + mani(List()) + + def listElMani[T: Manifest](xs: List[T]) = xs + listElMani(List()) + + def foo[A, C](m : C)(implicit ev: C <:< Traversable[A], mani: Manifest[A]): (C, A, Manifest[A]) = (m, m.head, mani) + foo(List(1,2,3)) +} \ No newline at end of file diff --git a/test/files/pos/spec-constr-old.scala b/test/files/pos/spec-constr-old.scala new file mode 100644 index 0000000000..e908b65a41 --- /dev/null +++ b/test/files/pos/spec-constr-old.scala @@ -0,0 +1,7 @@ +class SparseArray2[@specialized(Int) T:ClassManifest](val maxSize: Int, initialLength:Int = 3) { + private var data = new Array[T](initialLength); + private var index = new Array[Int](initialLength); + + // comment out to compile correctly + data.length + 3; +} diff --git a/test/files/pos/spec-doubledef-old.scala b/test/files/pos/spec-doubledef-old.scala new file mode 100644 index 0000000000..86b0d857d3 --- /dev/null +++ b/test/files/pos/spec-doubledef-old.scala @@ -0,0 +1,28 @@ +object Test { + def fn[@specialized T, @specialized U](t : T => Int, u : U => Int) : T = + null.asInstanceOf[T] +} + +trait A[@specialized(Int) T] { + var value: T + def getWith[@specialized(Int) Z](f: T => Z) = f(value) +} + +class C extends A[Int] { + var value = 10 + override def getWith[@specialized(Int) Z](f: Int => Z) = f(value) +} + +abstract class B[T, @specialized(scala.Int) U : Manifest, @specialized(scala.Int) V <% Ordered[V]] { + val u: U + val v: V + + def f(t: T, v2: V): Pair[U, V] = { + val m: Array[U] = null + if (m.isEmpty) { + Pair(u, v) + } else { + Pair(u, v2) + } + } +} diff --git a/test/files/pos/spec-fields-old.scala b/test/files/pos/spec-fields-old.scala new file mode 100644 index 0000000000..26a8c4ffbd --- /dev/null +++ b/test/files/pos/spec-fields-old.scala @@ -0,0 +1,10 @@ +abstract class Foo[@specialized T: ClassManifest, U <: Ordered[U]](x: T, size: Int) { + var y: T + var z: T = x + + def initialSize = 16 + val array = new Array[T](initialSize + size) + + def getZ = z + def setZ(zz: T) = z = zz +} diff --git a/test/files/pos/spec-params-old.scala b/test/files/pos/spec-params-old.scala new file mode 100644 index 0000000000..f522512846 --- /dev/null +++ b/test/files/pos/spec-params-old.scala @@ -0,0 +1,32 @@ +class Foo[@specialized A: ClassManifest] { + + // conflicting in bounds, expect a normalized member calling m + // and bridge + implementation in specialized subclasses + // and overloads here according to specialization on A + def m1[@specialized B <: A](x: B, y: A) = + goal(x) + + // conflicting, unsolvable, expect a warning + def m2[@specialized B <: String](x: B) = x.concat("a") + + // conflicting in bounds, no mention of other spec members + // expect an overload here plus implementation in + // compatible specialized subclasses + def m3[@specialized B >: A](x: B) = () + + // non-conflicting, expect a normalized overload implementation here + def m4[@specialized T, U <: Ordered[T]](x: T, y: U) = () + + // non-conflicting, expect a normalized overload implementation here + def m5[@specialized B](x: B) = x + + // non-conflicting, expect a normalized implementation here + // and specialized implementations for all expansions in specialized subclasses + def m6[@specialized B](x: B, y: A) = + goal(y) + + def goal(x: A) = { + val xs = new Array[A](1) + xs(0) = x + } +} diff --git a/test/files/pos/spec-sparsearray-old.scala b/test/files/pos/spec-sparsearray-old.scala new file mode 100644 index 0000000000..ea7710a785 --- /dev/null +++ b/test/files/pos/spec-sparsearray-old.scala @@ -0,0 +1,24 @@ +import scala.collection.mutable.MapLike + +class SparseArray[@specialized(Int) T:ClassManifest] extends collection.mutable.Map[Int,T] with collection.mutable.MapLike[Int,T,SparseArray[T]] { + override def get(x: Int) = { + val ind = findOffset(x) + if(ind < 0) None else Some(error("ignore")) + } + + /** + * Returns the offset into index and data for the requested vector + * index. If the requested index is not found, the return value is + * negative and can be converted into an insertion point with -(rv+1). + */ + private def findOffset(i : Int) : Int = { + error("impl doesn't matter") + } + + override def apply(i : Int) : T = { error("ignore") } + override def update(i : Int, value : T) = error("ignore") + override def empty = new SparseArray[T] + def -=(ind: Int) = error("ignore") + def +=(kv: (Int,T)) = error("ignore") + override final def iterator = error("ignore") +} diff --git a/test/files/pos/t1381-old.scala b/test/files/pos/t1381-old.scala new file mode 100644 index 0000000000..0762891898 --- /dev/null +++ b/test/files/pos/t1381-old.scala @@ -0,0 +1,31 @@ +import scala.reflect.Manifest + +class D[V <: Variable] + +class ID[V<:IV] extends D[V] { + type E = V#ValueType + def index(value:E) : Int = 0 + // Comment this out to eliminate crash. Or see below + def index(values:E*) : Iterable[Int] = null +} + +abstract class Variable { + type VT <: Variable + def d : D[VT] = null +} + +abstract class PV[T](initval:T) extends Variable { + type VT <: PV[T] + type ValueType = T +} + +trait IV extends Variable { + type ValueType +} + +abstract class EV[T](initval:T) extends PV[T](initval) with IV { + type VT <: EV[T] + override def d : ID[VT] = null + // Comment this out to eliminate crash + protected var indx = d.index(initval) +} diff --git a/test/files/pos/t2795-old.scala b/test/files/pos/t2795-old.scala new file mode 100644 index 0000000000..935cb1f444 --- /dev/null +++ b/test/files/pos/t2795-old.scala @@ -0,0 +1,17 @@ +package t1 + +trait Element[T] { +} + +trait Config { + type T <: Element[T] + implicit val m: ClassManifest[T] + // XXX Following works fine: + // type T <: Element[_] +} + +trait Transform { self: Config => + def processBlock(block: Array[T]): Unit = { + var X = new Array[T](1) + } +} diff --git a/test/files/pos/t3363-old.scala b/test/files/pos/t3363-old.scala new file mode 100644 index 0000000000..bae54084ea --- /dev/null +++ b/test/files/pos/t3363-old.scala @@ -0,0 +1,18 @@ +object TestCase { + + //now matter if you put (abstract) class or trait it will fail in all cases + trait MapOps[T] + + //if fs was reduced to List (generic type with one parameter) then the code compiles + //if you inherit from MapOps[T] instead of MapOps[F] then code compiles fine + implicit def map2ops[T,F](fs: Map[T,F]) = new MapOps[F] { + //if you remove this line, then code compiles + lazy val m: Manifest[T] = error("just something to make it compile") + def is(xs: List[T]) = List(xs) + } + + def main(args: Array[String]) { + println(Map(1 -> "2") is List(2)) + } + + } diff --git a/test/files/pos/t3498-old.scala b/test/files/pos/t3498-old.scala new file mode 100644 index 0000000000..bcc90ca64c --- /dev/null +++ b/test/files/pos/t3498-old.scala @@ -0,0 +1,15 @@ +abstract class A[T, @specialized(scala.Int) U : Manifest] { + def f(state: T): Array[U] +} + +abstract class B extends A[ Array[Byte], Int ] { + type T = Array[Byte] + type U = Int + + val N = 0 + + def f(state: T): Array[U] = + { + new Array[U](N + state(N)) + } +} \ No newline at end of file diff --git a/test/files/run/arrayclone-old.scala b/test/files/run/arrayclone-old.scala new file mode 100644 index 0000000000..c9f7556b47 --- /dev/null +++ b/test/files/run/arrayclone-old.scala @@ -0,0 +1,106 @@ +object Test extends App{ + BooleanArrayClone; + ByteArrayClone; + ShortArrayClone; + CharArrayClone; + IntArrayClone; + LongArrayClone; + FloatArrayClone; + DoubleArrayClone; + ObjectArrayClone; + PolymorphicArrayClone; +} + +object BooleanArrayClone{ + val it : Array[Boolean] = Array(true, false); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = false; + assert(it(0) == true) +} + +object ByteArrayClone{ + val it : Array[Byte] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object ShortArrayClone{ + val it : Array[Short] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object CharArrayClone{ + val it : Array[Char] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object IntArrayClone{ + val it : Array[Int] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object LongArrayClone{ + val it : Array[Long] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object FloatArrayClone{ + val it : Array[Float] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object DoubleArrayClone{ + val it : Array[Double] = Array(1, 0); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = 0; + assert(it(0) == 1) +} + +object ObjectArrayClone{ + val it : Array[String] = Array("1", "0"); + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = "0"; + assert(it(0) == "1") +} + +object PolymorphicArrayClone{ + def testIt[T](it : Array[T], one : T, zero : T) = { + val cloned = it.clone(); + assert(cloned.sameElements(it)); + cloned(0) = zero; + assert(it(0) == one) + } + + testIt(Array("one", "two"), "one", "two"); + + class Mangler[T: Manifest](ts : T*){ + // this will always be a BoxedAnyArray even after we've unboxed its contents. + val it = ts.toArray[T]; + } + + val mangled = new Mangler[Int](0, 1); + + val y : Array[Int] = mangled.it; // make sure it's unboxed + + testIt(mangled.it, 0, 1); +} diff --git a/test/files/run/ctries-old/DumbHash.scala b/test/files/run/ctries-old/DumbHash.scala new file mode 100644 index 0000000000..8ef325b67c --- /dev/null +++ b/test/files/run/ctries-old/DumbHash.scala @@ -0,0 +1,14 @@ + + + + + + +class DumbHash(val i: Int) { + override def equals(other: Any) = other match { + case that: DumbHash => that.i == this.i + case _ => false + } + override def hashCode = i % 5 + override def toString = "DH(%s)".format(i) +} diff --git a/test/files/run/ctries-old/Wrap.scala b/test/files/run/ctries-old/Wrap.scala new file mode 100644 index 0000000000..7b645c1612 --- /dev/null +++ b/test/files/run/ctries-old/Wrap.scala @@ -0,0 +1,9 @@ + + + + + + +case class Wrap(i: Int) { + override def hashCode = i * 0x9e3775cd +} diff --git a/test/files/run/ctries-old/concmap.scala b/test/files/run/ctries-old/concmap.scala new file mode 100644 index 0000000000..3ec0256afb --- /dev/null +++ b/test/files/run/ctries-old/concmap.scala @@ -0,0 +1,188 @@ + + + +import collection.concurrent.TrieMap + + +object ConcurrentMapSpec extends Spec { + + val initsz = 500 + val secondsz = 750 + + def test() { + "support put" in { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until initsz) assert(ct.put(new Wrap(i), i) == None) + for (i <- 0 until initsz) assert(ct.put(new Wrap(i), -i) == Some(i)) + } + + "support put if absent" in { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until initsz) ct.update(new Wrap(i), i) + for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i)) + for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i)) + for (i <- initsz until secondsz) assert(ct.putIfAbsent(new Wrap(i), -i) == None) + for (i <- initsz until secondsz) assert(ct.putIfAbsent(new Wrap(i), i) == Some(-i)) + } + + "support remove if mapped to a specific value" in { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until initsz) ct.update(new Wrap(i), i) + for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), -i - 1) == false) + for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == true) + for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == false) + } + + "support replace if mapped to a specific value" in { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until initsz) ct.update(new Wrap(i), i) + for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i - 1, -i - 2) == false) + for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == true) + for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == false) + for (i <- initsz until secondsz) assert(ct.replace(new Wrap(i), i, 0) == false) + } + + "support replace if present" in { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until initsz) ct.update(new Wrap(i), i) + for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i) == Some(i)) + for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i) == Some(-i)) + for (i <- initsz until secondsz) assert(ct.replace(new Wrap(i), i) == None) + } + + def assertEqual(a: Any, b: Any) = { + if (a != b) println(a, b) + assert(a == b) + } + + "support replace if mapped to a specific value, using several threads" in { + val ct = new TrieMap[Wrap, Int] + val sz = 55000 + for (i <- 0 until sz) ct.update(new Wrap(i), i) + + class Updater(index: Int, offs: Int) extends Thread { + override def run() { + var repeats = 0 + for (i <- 0 until sz) { + val j = (offs + i) % sz + var k = Int.MaxValue + do { + if (k != Int.MaxValue) repeats += 1 + k = ct.lookup(new Wrap(j)) + } while (!ct.replace(new Wrap(j), k, -k)) + } + //println("Thread %d repeats: %d".format(index, repeats)) + } + } + + val threads = for (i <- 0 until 16) yield new Updater(i, sz / 32 * i) + threads.foreach(_.start()) + threads.foreach(_.join()) + + for (i <- 0 until sz) assertEqual(ct(new Wrap(i)), i) + + val threads2 = for (i <- 0 until 15) yield new Updater(i, sz / 32 * i) + threads2.foreach(_.start()) + threads2.foreach(_.join()) + + for (i <- 0 until sz) assertEqual(ct(new Wrap(i)), -i) + } + + "support put if absent, several threads" in { + val ct = new TrieMap[Wrap, Int] + val sz = 110000 + + class Updater(offs: Int) extends Thread { + override def run() { + for (i <- 0 until sz) { + val j = (offs + i) % sz + ct.putIfAbsent(new Wrap(j), j) + assert(ct.lookup(new Wrap(j)) == j) + } + } + } + + val threads = for (i <- 0 until 16) yield new Updater(sz / 32 * i) + threads.foreach(_.start()) + threads.foreach(_.join()) + + for (i <- 0 until sz) assert(ct(new Wrap(i)) == i) + } + + "support remove if mapped to a specific value, several threads" in { + val ct = new TrieMap[Wrap, Int] + val sz = 55000 + for (i <- 0 until sz) ct.update(new Wrap(i), i) + + class Remover(offs: Int) extends Thread { + override def run() { + for (i <- 0 until sz) { + val j = (offs + i) % sz + ct.remove(new Wrap(j), j) + assert(ct.get(new Wrap(j)) == None) + } + } + } + + val threads = for (i <- 0 until 16) yield new Remover(sz / 32 * i) + threads.foreach(_.start()) + threads.foreach(_.join()) + + for (i <- 0 until sz) assert(ct.get(new Wrap(i)) == None) + } + + "have all or none of the elements depending on the oddity" in { + val ct = new TrieMap[Wrap, Int] + val sz = 65000 + for (i <- 0 until sz) ct(new Wrap(i)) = i + + class Modifier(index: Int, offs: Int) extends Thread { + override def run() { + for (j <- 0 until sz) { + val i = (offs + j) % sz + var success = false + do { + if (ct.contains(new Wrap(i))) { + success = ct.remove(new Wrap(i)) != None + } else { + success = ct.putIfAbsent(new Wrap(i), i) == None + } + } while (!success) + } + } + } + + def modify(n: Int) = { + val threads = for (i <- 0 until n) yield new Modifier(i, sz / n * i) + threads.foreach(_.start()) + threads.foreach(_.join()) + } + + modify(16) + for (i <- 0 until sz) assertEqual(ct.get(new Wrap(i)), Some(i)) + modify(15) + for (i <- 0 until sz) assertEqual(ct.get(new Wrap(i)), None) + } + + "compute size correctly" in { + val ct = new TrieMap[Wrap, Int] + val sz = 36450 + for (i <- 0 until sz) ct(new Wrap(i)) = i + + assertEqual(ct.size, sz) + assertEqual(ct.size, sz) + } + + "compute size correctly in parallel" in { + val ct = new TrieMap[Wrap, Int] + val sz = 36450 + for (i <- 0 until sz) ct(new Wrap(i)) = i + val pct = ct.par + + assertEqual(pct.size, sz) + assertEqual(pct.size, sz) + } + + } + +} diff --git a/test/files/run/ctries-old/iterator.scala b/test/files/run/ctries-old/iterator.scala new file mode 100644 index 0000000000..b953a40e00 --- /dev/null +++ b/test/files/run/ctries-old/iterator.scala @@ -0,0 +1,289 @@ + + + + +import collection._ +import collection.concurrent.TrieMap + + + +object IteratorSpec extends Spec { + + def test() { + "work for an empty trie" in { + val ct = new TrieMap + val it = ct.iterator + + it.hasNext shouldEqual (false) + evaluating { it.next() }.shouldProduce [NoSuchElementException] + } + + def nonEmptyIteratorCheck(sz: Int) { + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct.put(new Wrap(i), i) + + val it = ct.iterator + val tracker = mutable.Map[Wrap, Int]() + for (i <- 0 until sz) { + assert(it.hasNext == true) + tracker += it.next + } + + it.hasNext shouldEqual (false) + evaluating { it.next() }.shouldProduce [NoSuchElementException] + tracker.size shouldEqual (sz) + tracker shouldEqual (ct) + } + + "work for a 1 element trie" in { + nonEmptyIteratorCheck(1) + } + + "work for a 2 element trie" in { + nonEmptyIteratorCheck(2) + } + + "work for a 3 element trie" in { + nonEmptyIteratorCheck(3) + } + + "work for a 5 element trie" in { + nonEmptyIteratorCheck(5) + } + + "work for a 10 element trie" in { + nonEmptyIteratorCheck(10) + } + + "work for a 20 element trie" in { + nonEmptyIteratorCheck(20) + } + + "work for a 50 element trie" in { + nonEmptyIteratorCheck(50) + } + + "work for a 100 element trie" in { + nonEmptyIteratorCheck(100) + } + + "work for a 1k element trie" in { + nonEmptyIteratorCheck(1000) + } + + "work for a 5k element trie" in { + nonEmptyIteratorCheck(5000) + } + + "work for a 75k element trie" in { + nonEmptyIteratorCheck(75000) + } + + "work for a 250k element trie" in { + nonEmptyIteratorCheck(500000) + } + + def nonEmptyCollideCheck(sz: Int) { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until sz) ct.put(new DumbHash(i), i) + + val it = ct.iterator + val tracker = mutable.Map[DumbHash, Int]() + for (i <- 0 until sz) { + assert(it.hasNext == true) + tracker += it.next + } + + it.hasNext shouldEqual (false) + evaluating { it.next() }.shouldProduce [NoSuchElementException] + tracker.size shouldEqual (sz) + tracker shouldEqual (ct) + } + + "work for colliding hashcodes, 2 element trie" in { + nonEmptyCollideCheck(2) + } + + "work for colliding hashcodes, 3 element trie" in { + nonEmptyCollideCheck(3) + } + + "work for colliding hashcodes, 5 element trie" in { + nonEmptyCollideCheck(5) + } + + "work for colliding hashcodes, 10 element trie" in { + nonEmptyCollideCheck(10) + } + + "work for colliding hashcodes, 100 element trie" in { + nonEmptyCollideCheck(100) + } + + "work for colliding hashcodes, 500 element trie" in { + nonEmptyCollideCheck(500) + } + + "work for colliding hashcodes, 5k element trie" in { + nonEmptyCollideCheck(5000) + } + + def assertEqual(a: Map[Wrap, Int], b: Map[Wrap, Int]) { + if (a != b) { + println(a.size + " vs " + b.size) + // println(a) + // println(b) + // println(a.toSeq.sortBy((x: (Wrap, Int)) => x._1.i)) + // println(b.toSeq.sortBy((x: (Wrap, Int)) => x._1.i)) + } + assert(a == b) + } + + "be consistent when taken with concurrent modifications" in { + val sz = 25000 + val W = 15 + val S = 5 + val checks = 5 + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct.put(new Wrap(i), i) + + class Modifier extends Thread { + override def run() { + for (i <- 0 until sz) ct.putIfAbsent(new Wrap(i), i) match { + case Some(_) => ct.remove(new Wrap(i)) + case None => + } + } + } + + def consistentIteration(ct: TrieMap[Wrap, Int], checks: Int) { + class Iter extends Thread { + override def run() { + val snap = ct.readOnlySnapshot() + val initial = mutable.Map[Wrap, Int]() + for (kv <- snap) initial += kv + + for (i <- 0 until checks) { + assertEqual(snap.iterator.toMap, initial) + } + } + } + + val iter = new Iter + iter.start() + iter.join() + } + + val threads = for (_ <- 0 until W) yield new Modifier + threads.foreach(_.start()) + for (_ <- 0 until S) consistentIteration(ct, checks) + threads.foreach(_.join()) + } + + "be consistent with a concurrent removal with a well defined order" in { + val sz = 150000 + val sgroupsize = 10 + val sgroupnum = 5 + val removerslowdown = 50 + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct.put(new Wrap(i), i) + + class Remover extends Thread { + override def run() { + for (i <- 0 until sz) { + assert(ct.remove(new Wrap(i)) == Some(i)) + for (i <- 0 until removerslowdown) ct.get(new Wrap(i)) // slow down, mate + } + //println("done removing") + } + } + + def consistentIteration(it: Iterator[(Wrap, Int)]) = { + class Iter extends Thread { + override def run() { + val elems = it.toBuffer + if (elems.nonEmpty) { + val minelem = elems.minBy((x: (Wrap, Int)) => x._1.i)._1.i + assert(elems.forall(_._1.i >= minelem)) + } + } + } + new Iter + } + + val remover = new Remover + remover.start() + for (_ <- 0 until sgroupnum) { + val iters = for (_ <- 0 until sgroupsize) yield consistentIteration(ct.iterator) + iters.foreach(_.start()) + iters.foreach(_.join()) + } + //println("done with iterators") + remover.join() + } + + "be consistent with a concurrent insertion with a well defined order" in { + val sz = 150000 + val sgroupsize = 10 + val sgroupnum = 10 + val inserterslowdown = 50 + val ct = new TrieMap[Wrap, Int] + + class Inserter extends Thread { + override def run() { + for (i <- 0 until sz) { + assert(ct.put(new Wrap(i), i) == None) + for (i <- 0 until inserterslowdown) ct.get(new Wrap(i)) // slow down, mate + } + //println("done inserting") + } + } + + def consistentIteration(it: Iterator[(Wrap, Int)]) = { + class Iter extends Thread { + override def run() { + val elems = it.toSeq + if (elems.nonEmpty) { + val maxelem = elems.maxBy((x: (Wrap, Int)) => x._1.i)._1.i + assert(elems.forall(_._1.i <= maxelem)) + } + } + } + new Iter + } + + val inserter = new Inserter + inserter.start() + for (_ <- 0 until sgroupnum) { + val iters = for (_ <- 0 until sgroupsize) yield consistentIteration(ct.iterator) + iters.foreach(_.start()) + iters.foreach(_.join()) + } + //println("done with iterators") + inserter.join() + } + + "work on a yet unevaluated snapshot" in { + val sz = 50000 + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct.update(new Wrap(i), i) + + val snap = ct.snapshot() + val it = snap.iterator + + while (it.hasNext) it.next() + } + + "be duplicated" in { + val sz = 50 + val ct = collection.parallel.mutable.ParTrieMap((0 until sz) zip (0 until sz): _*) + val it = ct.splitter + for (_ <- 0 until (sz / 2)) it.next() + val dupit = it.dup + + it.toList shouldEqual dupit.toList + } + + } + +} diff --git a/test/files/run/ctries-old/lnode.scala b/test/files/run/ctries-old/lnode.scala new file mode 100644 index 0000000000..92a31088e5 --- /dev/null +++ b/test/files/run/ctries-old/lnode.scala @@ -0,0 +1,61 @@ + + + +import collection.concurrent.TrieMap + + +object LNodeSpec extends Spec { + + val initsz = 1500 + val secondsz = 1750 + + def test() { + "accept elements with the same hash codes" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) ct.update(new DumbHash(i), i) + } + + "lookup elements with the same hash codes" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) ct.update(new DumbHash(i), i) + for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == Some(i)) + for (i <- initsz until secondsz) assert(ct.get(new DumbHash(i)) == None) + } + + "remove elements with the same hash codes" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) ct.update(new DumbHash(i), i) + for (i <- 0 until initsz) { + val remelem = ct.remove(new DumbHash(i)) + assert(remelem == Some(i), "removing " + i + " yields " + remelem) + } + for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == None) + } + + "put elements with the same hash codes if absent" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) ct.put(new DumbHash(i), i) + for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i) + for (i <- 0 until initsz) assert(ct.putIfAbsent(new DumbHash(i), i) == Some(i)) + for (i <- initsz until secondsz) assert(ct.putIfAbsent(new DumbHash(i), i) == None) + for (i <- initsz until secondsz) assert(ct.lookup(new DumbHash(i)) == i) + } + + "replace elements with the same hash codes" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None) + for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i) + for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i) == Some(i)) + for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == -i) + for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i, i) == true) + } + + "remove elements with the same hash codes if mapped to a specific value" in { + val ct = new TrieMap[DumbHash, Int] + for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None) + for (i <- 0 until initsz) assert(ct.remove(new DumbHash(i), i) == true) + } + + } + +} diff --git a/test/files/run/ctries-old/main.scala b/test/files/run/ctries-old/main.scala new file mode 100644 index 0000000000..8db7fcef54 --- /dev/null +++ b/test/files/run/ctries-old/main.scala @@ -0,0 +1,45 @@ + + + + + + + +object Test { + + def main(args: Array[String]) { + ConcurrentMapSpec.test() + IteratorSpec.test() + LNodeSpec.test() + SnapshotSpec.test() + } + +} + + +trait Spec { + + implicit def str2ops(s: String) = new { + def in[U](body: =>U) { + // just execute body + body + } + } + + implicit def any2ops(a: Any) = new { + def shouldEqual(other: Any) = assert(a == other) + } + + def evaluating[U](body: =>U) = new { + def shouldProduce[T <: Throwable: ClassManifest]() = { + var produced = false + try body + catch { + case e => if (e.getClass == implicitly[ClassManifest[T]].erasure) produced = true + } finally { + assert(produced, "Did not produce exception of type: " + implicitly[ClassManifest[T]]) + } + } + } + +} diff --git a/test/files/run/ctries-old/snapshot.scala b/test/files/run/ctries-old/snapshot.scala new file mode 100644 index 0000000000..5fe77d445b --- /dev/null +++ b/test/files/run/ctries-old/snapshot.scala @@ -0,0 +1,267 @@ + + + + +import collection._ +import collection.concurrent.TrieMap + + + +object SnapshotSpec extends Spec { + + def test() { + "support snapshots" in { + val ctn = new TrieMap + ctn.snapshot() + ctn.readOnlySnapshot() + + val ct = new TrieMap[Int, Int] + for (i <- 0 until 100) ct.put(i, i) + ct.snapshot() + ct.readOnlySnapshot() + } + + "empty 2 quiescent snapshots in isolation" in { + val sz = 4000 + + class Worker(trie: TrieMap[Wrap, Int]) extends Thread { + override def run() { + for (i <- 0 until sz) { + assert(trie.remove(new Wrap(i)) == Some(i)) + for (j <- 0 until sz) + if (j <= i) assert(trie.get(new Wrap(j)) == None) + else assert(trie.get(new Wrap(j)) == Some(j)) + } + } + } + + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct.put(new Wrap(i), i) + val snapt = ct.snapshot() + + val original = new Worker(ct) + val snapshot = new Worker(snapt) + original.start() + snapshot.start() + original.join() + snapshot.join() + + for (i <- 0 until sz) { + assert(ct.get(new Wrap(i)) == None) + assert(snapt.get(new Wrap(i)) == None) + } + } + + def consistentReadOnly(name: String, readonly: Map[Wrap, Int], sz: Int, N: Int) { + @volatile var e: Exception = null + + // reads possible entries once and stores them + // then reads all these N more times to check if the + // state stayed the same + class Reader(trie: Map[Wrap, Int]) extends Thread { + setName("Reader " + name) + + override def run() = + try check() + catch { + case ex: Exception => e = ex + } + + def check() { + val initial = mutable.Map[Wrap, Int]() + for (i <- 0 until sz) trie.get(new Wrap(i)) match { + case Some(i) => initial.put(new Wrap(i), i) + case None => // do nothing + } + + for (k <- 0 until N) { + for (i <- 0 until sz) { + val tres = trie.get(new Wrap(i)) + val ires = initial.get(new Wrap(i)) + if (tres != ires) println(i, "initially: " + ires, "traversal %d: %s".format(k, tres)) + assert(tres == ires) + } + } + } + } + + val reader = new Reader(readonly) + reader.start() + reader.join() + + if (e ne null) { + e.printStackTrace() + throw e + } + } + + // traverses the trie `rep` times and modifies each entry + class Modifier(trie: TrieMap[Wrap, Int], index: Int, rep: Int, sz: Int) extends Thread { + setName("Modifier %d".format(index)) + + override def run() { + for (k <- 0 until rep) { + for (i <- 0 until sz) trie.putIfAbsent(new Wrap(i), i) match { + case Some(_) => trie.remove(new Wrap(i)) + case None => // do nothing + } + } + } + } + + // removes all the elements from the trie + class Remover(trie: TrieMap[Wrap, Int], index: Int, totremovers: Int, sz: Int) extends Thread { + setName("Remover %d".format(index)) + + override def run() { + for (i <- 0 until sz) trie.remove(new Wrap((i + sz / totremovers * index) % sz)) + } + } + + "have a consistent quiescent read-only snapshot" in { + val sz = 10000 + val N = 100 + val W = 10 + + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct(new Wrap(i)) = i + val readonly = ct.readOnlySnapshot() + val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) + + threads.foreach(_.start()) + consistentReadOnly("qm", readonly, sz, N) + threads.foreach(_.join()) + } + + // now, we check non-quiescent snapshots, as these permit situations + // where a thread is caught in the middle of the update when a snapshot is taken + + "have a consistent non-quiescent read-only snapshot, concurrent with removes only" in { + val sz = 1250 + val W = 100 + val S = 5000 + + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct(new Wrap(i)) = i + val threads = for (i <- 0 until W) yield new Remover(ct, i, W, sz) + + threads.foreach(_.start()) + for (i <- 0 until S) consistentReadOnly("non-qr", ct.readOnlySnapshot(), sz, 5) + threads.foreach(_.join()) + } + + "have a consistent non-quiescent read-only snapshot, concurrent with modifications" in { + val sz = 1000 + val N = 7000 + val W = 10 + val S = 7000 + + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct(new Wrap(i)) = i + val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) + + threads.foreach(_.start()) + for (i <- 0 until S) consistentReadOnly("non-qm", ct.readOnlySnapshot(), sz, 5) + threads.foreach(_.join()) + } + + def consistentNonReadOnly(name: String, trie: TrieMap[Wrap, Int], sz: Int, N: Int) { + @volatile var e: Exception = null + + // reads possible entries once and stores them + // then reads all these N more times to check if the + // state stayed the same + class Worker extends Thread { + setName("Worker " + name) + + override def run() = + try check() + catch { + case ex: Exception => e = ex + } + + def check() { + val initial = mutable.Map[Wrap, Int]() + for (i <- 0 until sz) trie.get(new Wrap(i)) match { + case Some(i) => initial.put(new Wrap(i), i) + case None => // do nothing + } + + for (k <- 0 until N) { + // modify + for ((key, value) <- initial) { + val oldv = if (k % 2 == 0) value else -value + val newv = -oldv + trie.replace(key, oldv, newv) + } + + // check + for (i <- 0 until sz) if (initial.contains(new Wrap(i))) { + val expected = if (k % 2 == 0) -i else i + //println(trie.get(new Wrap(i))) + assert(trie.get(new Wrap(i)) == Some(expected)) + } else { + assert(trie.get(new Wrap(i)) == None) + } + } + } + } + + val worker = new Worker + worker.start() + worker.join() + + if (e ne null) { + e.printStackTrace() + throw e + } + } + + "have a consistent non-quiescent snapshot, concurrent with modifications" in { + val sz = 9000 + val N = 1000 + val W = 10 + val S = 400 + + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct(new Wrap(i)) = i + val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz) + + threads.foreach(_.start()) + for (i <- 0 until S) { + consistentReadOnly("non-qm", ct.snapshot(), sz, 5) + consistentNonReadOnly("non-qsnap", ct.snapshot(), sz, 5) + } + threads.foreach(_.join()) + } + + "work when many concurrent snapshots are taken, concurrent with modifications" in { + val sz = 12000 + val W = 10 + val S = 10 + val modifytimes = 1200 + val snaptimes = 600 + val ct = new TrieMap[Wrap, Int] + for (i <- 0 until sz) ct(new Wrap(i)) = i + + class Snapshooter extends Thread { + setName("Snapshooter") + override def run() { + for (k <- 0 until snaptimes) { + val snap = ct.snapshot() + for (i <- 0 until sz) snap.remove(new Wrap(i)) + for (i <- 0 until sz) assert(!snap.contains(new Wrap(i))) + } + } + } + + val mods = for (i <- 0 until W) yield new Modifier(ct, i, modifytimes, sz) + val shooters = for (i <- 0 until S) yield new Snapshooter + val threads = mods ++ shooters + threads.foreach(_.start()) + threads.foreach(_.join()) + } + + } + +} diff --git a/test/files/run/existentials3-old.check b/test/files/run/existentials3-old.check new file mode 100644 index 0000000000..e166e53ba8 --- /dev/null +++ b/test/files/run/existentials3-old.check @@ -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-old.scala b/test/files/run/existentials3-old.scala new file mode 100644 index 0000000000..944160ff12 --- /dev/null +++ b/test/files/run/existentials3-old.scala @@ -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/getClassTest-old.check b/test/files/run/getClassTest-old.check new file mode 100644 index 0000000000..94e86c3889 --- /dev/null +++ b/test/files/run/getClassTest-old.check @@ -0,0 +1,18 @@ +f1: java.lang.Class +f2: java.lang.Class +f3: java.lang.Class +f4: java.lang.Class +f5: java.lang.Class +f0: T +f1: class java.lang.Object +f2: class java.lang.Object +f3: class AnyRefs$A +f4: class AnyRefs$B +f5: class java.lang.Object +f6: class java.lang.Object +f7: class AnyRefs$A +f8: class AnyRefs$B +f1: java.lang.Class +f2: java.lang.Class +f3: java.lang.Class +f4: java.lang.Class diff --git a/test/files/run/getClassTest-old.scala b/test/files/run/getClassTest-old.scala new file mode 100644 index 0000000000..951cc8d931 --- /dev/null +++ b/test/files/run/getClassTest-old.scala @@ -0,0 +1,66 @@ +class AnyVals { + def f1 = (5: Any).getClass + def f2 = (5: AnyVal).getClass + def f3 = 5.getClass + def f4 = (5: java.lang.Integer).getClass + def f5 = (5.asInstanceOf[AnyRef]).getClass + + // scalap says: + // + // def f1 : java.lang.Class[?0] forSome {type ?0} = { /* compiled code */ } + // def f2 : java.lang.Class[?0] forSome {type ?0} = { /* compiled code */ } + // def f3 : java.lang.Class[scala.Int] = { /* compiled code */ } + // def f4 : java.lang.Class[?0] forSome {type ?0 <: java.lang.Integer} = { /* compiled code */ } + // def f5 : java.lang.Class[?0] forSome {type ?0 <: scala.AnyRef} = { /* compiled code */ } + // + // java generic signature says: + // + // f1: java.lang.Class + // f2: java.lang.Class + // f3: java.lang.Class + // f4: java.lang.Class + // f5: java.lang.Class +} + +class AnyRefs { + class A + class B extends A + + def f1 = (new B: Any).getClass().newInstance() + def f2 = (new B: AnyRef).getClass().newInstance() + def f3 = (new B: A).getClass().newInstance() + def f4 = (new B: B).getClass().newInstance() + + def f0[T >: B] = (new B: T).getClass().newInstance() + + def f5 = f0[Any] + def f6 = f0[AnyRef] + def f7 = f0[A] + def f8 = f0[B] +} + +class MoreAnyRefs { + trait A + trait B + + // don't leak anon/refinements + def f1 = (new A with B { }).getClass() + def f2 = (new B with A { }).getClass() + def f3 = (new { def bippy() = 5 }).getClass() + def f4 = (new A { def bippy() = 5 }).getClass() +} + +object Test { + def returnTypes[T: Manifest] = ( + manifest[T].erasure.getMethods.toList + filter (_.getName startsWith "f") + sortBy (_.getName) + map (m => m.getName + ": " + m.getGenericReturnType.toString) + ) + + def main(args: Array[String]): Unit = { + returnTypes[AnyVals] foreach println + returnTypes[AnyRefs] foreach println + returnTypes[MoreAnyRefs] foreach println + } +} diff --git a/test/files/run/manifests-old.scala b/test/files/run/manifests-old.scala new file mode 100644 index 0000000000..621689a254 --- /dev/null +++ b/test/files/run/manifests-old.scala @@ -0,0 +1,147 @@ +object Test +{ + object Variances extends Enumeration { + 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 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) + else expected match { + case CO => showsCovariance && !showsContravariance && !showsInvariance + case IN => showsInvariance && !showsCovariance && !showsContravariance + 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]) = (ev1 <:< ev2, ev2 <:< ev1) 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]) + ) foreach (assert(_, "assertAnyRef")) + + def assertAnyVal[T: Manifest] = List( + manifest[T] <:< manifest[Any], + !(manifest[T] <:< manifest[AnyRef]), + manifest[T] <:< manifest[AnyVal] + ) 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 && + showsCovariance[T, U, List] && + showsInvariance[T, U, Set], + "testVariancesVia" + ) + + def runAllTests = { + assertAnyVal[AnyVal] + assertAnyVal[Unit] + assertAnyVal[Int] + assertAnyVal[Double] + assertAnyVal[Boolean] + assertAnyVal[Char] + + assertAnyRef[AnyRef] + assertAnyRef[java.lang.Object] + assertAnyRef[java.lang.Integer] + assertAnyRef[java.lang.Double] + assertAnyRef[java.lang.Boolean] + assertAnyRef[java.lang.Character] + assertAnyRef[String] + assertAnyRef[scala.List[String]] + assertAnyRef[scala.List[_]] + + // variance doesn't work yet + // testVariancesVia[String, Any] + // testVariancesVia[String, AnyRef] + + 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] + assertSubType[Nothing, AnyRef] + assertSubType[Nothing, String] + assertSubType[Nothing, List[String]] + assertSubType[Nothing, Null] + assertSameType[Nothing, Nothing] + + // Null + assertSubType[Null, Any] + assertNoRelationship[Null, AnyVal] + assertSubType[Null, AnyRef] + assertSubType[Null, String] + assertSubType[Null, List[String]] + assertSameType[Null, Null] + assertSuperType[Null, Nothing] + + // Any + assertSameType[Any, Any] + assertSuperType[Any, AnyVal] + assertSuperType[Any, AnyRef] + assertSuperType[Any, String] + assertSuperType[Any, List[String]] + assertSuperType[Any, Null] + assertSuperType[Any, Nothing] + + // Misc unrelated types + assertNoRelationship[Unit, AnyRef] + assertNoRelationship[Unit, Int] + assertNoRelationship[Int, Long] + assertNoRelationship[Boolean, String] + assertNoRelationship[List[Boolean], List[String]] + assertNoRelationship[Set[Boolean], Set[String]] + } + + def main(args: Array[String]): Unit = runAllTests +} \ No newline at end of file diff --git a/test/files/run/patmat_unapp_abstype-old.check b/test/files/run/patmat_unapp_abstype-old.check new file mode 100644 index 0000000000..72239d16cd --- /dev/null +++ b/test/files/run/patmat_unapp_abstype-old.check @@ -0,0 +1,4 @@ +TypeRef +none of the above +Bar +Foo diff --git a/test/files/run/patmat_unapp_abstype-old.flags b/test/files/run/patmat_unapp_abstype-old.flags new file mode 100644 index 0000000000..ba80cad69b --- /dev/null +++ b/test/files/run/patmat_unapp_abstype-old.flags @@ -0,0 +1 @@ +-Xoldpatmat diff --git a/test/files/run/patmat_unapp_abstype-old.scala b/test/files/run/patmat_unapp_abstype-old.scala new file mode 100644 index 0000000000..45496f08a2 --- /dev/null +++ b/test/files/run/patmat_unapp_abstype-old.scala @@ -0,0 +1,83 @@ +// abstract types and extractors, oh my! +trait TypesAPI { + trait Type + + // an alternative fix (implemented in the virtual pattern matcher, is to replace the isInstanceOf by a manifest-based run-time test) + // that's what typeRefMani is for + type TypeRef <: Type //; implicit def typeRefMani: Manifest[TypeRef] + val TypeRef: TypeRefExtractor; trait TypeRefExtractor { + def apply(x: Int): TypeRef + def unapply(x: TypeRef): Option[(Int)] + } + + // just for illustration, should follow the same pattern as TypeRef + case class MethodType(n: Int) extends Type +} + +// user should not be exposed to the implementation +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") + } + } +} + +trait TypesImpl extends TypesAPI { + object TypeRef extends TypeRefExtractor // this will have a bridged unapply(x: Type) = unapply(x.asInstanceOf[TypeRef]) + case class TypeRef(n: Int) extends Type // this has a bridge from TypesAPI#Type to TypesImpl#TypeRef + // --> the cast in the bridge will fail because the pattern matcher can't type test against the abstract types in TypesUser + //lazy val typeRefMani = manifest[TypeRef] +} + +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() +} diff --git a/test/files/run/primitive-sigs-2-old.check b/test/files/run/primitive-sigs-2-old.check new file mode 100644 index 0000000000..9132b4d8ae --- /dev/null +++ b/test/files/run/primitive-sigs-2-old.check @@ -0,0 +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[]) diff --git a/test/files/run/primitive-sigs-2-old.scala b/test/files/run/primitive-sigs-2-old.scala new file mode 100644 index 0000000000..b7152f7e3d --- /dev/null +++ b/test/files/run/primitive-sigs-2-old.scala @@ -0,0 +1,39 @@ +import java.{ lang => jl } + +trait T[A] { + def f(): A +} +class C extends T[Char] { + def f(): Char = 'a' +} +class Arr { + def arr1(xs: Array[Int]): List[Int] = xs.toList + def arr2(xs: Array[jl.Character]): List[jl.Character] = xs.toList + def arr3(xss: Array[Array[Float]]): Array[Float] = xss map (_.sum) + // This gets a signature like + // public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.Manifest) + // + // instead of the more appealing version from the past + // public T[] Arr.arr4(T[][],scala.reflect.Manifest) + // + // because java inflict's its reference-only generic-arrays on us. + // + def arr4[T: Manifest](xss: Array[Array[T]]): Array[T] = xss map (_.head) +} + +object Test { + val c1: Class[_] = classOf[T[_]] + val c2: Class[_] = classOf[C] + val c3: Class[_] = classOf[Arr] + + val c1m = c1.getMethods.toList filter (_.getName == "f") map (_.getGenericReturnType.toString) + val c2m = c2.getMethods.toList filter (_.getName == "f") map (_.getGenericReturnType.toString) + val c3m = c3.getDeclaredMethods.toList map (_.toGenericString) + + def main(args: Array[String]): Unit = { + println(c2.getGenericInterfaces.map(_.toString).sorted mkString " ") + println(c1m ++ c2m sorted) + println(new C f) + c3m.sorted foreach println + } +} diff --git a/test/files/run/reflection-implClass-old.scala b/test/files/run/reflection-implClass-old.scala new file mode 100644 index 0000000000..6583624d8b --- /dev/null +++ b/test/files/run/reflection-implClass-old.scala @@ -0,0 +1,38 @@ +/** + * Tries to load a symbol for the `Foo$class` using Scala reflection. + * Since trait implementation classes do not get pickling information + * symbol for them should be created using fallback mechanism + * that exposes Java reflection information dressed up in + * a Scala symbol. + */ +object Test extends App with Outer { + import scala.reflect.mirror + + assert(mirror.classToSymbol(manifest[Foo].erasure).typeSignature.declaration(mirror.newTermName("bar")).typeSignature == + mirror.classToSymbol(manifest[Bar].erasure).typeSignature.declaration(mirror.newTermName("foo")).typeSignature) + + val s1 = implClass(manifest[Foo].erasure) + assert(s1 != mirror.NoSymbol) + assert(s1.typeSignature != mirror.NoType) + assert(s1.companionSymbol.typeSignature != mirror.NoType) + assert(s1.companionSymbol.typeSignature.declaration(mirror.newTermName("bar")) != mirror.NoSymbol) + val s2 = implClass(manifest[Bar].erasure) + assert(s2 != mirror.NoSymbol) + assert(s2.typeSignature != mirror.NoType) + assert(s2.companionSymbol.typeSignature != mirror.NoType) + assert(s2.companionSymbol.typeSignature.declaration(mirror.newTermName("foo")) != mirror.NoSymbol) + def implClass(clazz: Class[_]) = { + val implClass = Class.forName(clazz.getName + "$class") + mirror.classToSymbol(implClass) + } +} + +trait Foo { + def bar = 1 +} + +trait Outer { + trait Bar { + def foo = 1 + } +} diff --git a/test/files/run/reify_implicits-old.check b/test/files/run/reify_implicits-old.check new file mode 100644 index 0000000000..e3aeb20f6b --- /dev/null +++ b/test/files/run/reify_implicits-old.check @@ -0,0 +1 @@ +x = List(1, 2, 3, 4) diff --git a/test/files/run/reify_implicits-old.scala b/test/files/run/reify_implicits-old.scala new file mode 100644 index 0000000000..60971c3cfb --- /dev/null +++ b/test/files/run/reify_implicits-old.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + reify { + implicit def arrayWrapper[A : ClassManifest](x: Array[A]) = + new { + def sort(p: (A, A) => Boolean) = { + util.Sorting.stableSort(x, p); x + } + } + val x = Array(2, 3, 1, 4) + println("x = "+ x.sort((x: Int, y: Int) => x < y).toList) + }.eval +} diff --git a/test/files/run/t0421-old.check b/test/files/run/t0421-old.check new file mode 100644 index 0000000000..cdcf042f19 --- /dev/null +++ b/test/files/run/t0421-old.check @@ -0,0 +1,3 @@ +[Array(0, 1),Array(2, 3),Array(4, 5)] +[Array(31.0)] +[Array(24.0, 32.0)] diff --git a/test/files/run/t0421-old.scala b/test/files/run/t0421-old.scala new file mode 100644 index 0000000000..8d51013924 --- /dev/null +++ b/test/files/run/t0421-old.scala @@ -0,0 +1,30 @@ +// ticket #421 +object Test extends App { + + def transpose[A: ClassManifest](xss: Array[Array[A]]) = { + for (i <- Array.range(0, xss(0).length)) yield + for (xs <- xss) yield xs(i) + } + + def scalprod(xs: Array[Double], ys: Array[Double]) = { + var acc = 0.0 + for ((x, y) <- xs zip ys) acc = acc + x * y + acc + } + + def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { + val ysst = transpose(yss) + val ysst1: Array[Array[Double]] = yss.transpose + assert(ysst.deep == ysst1.deep) + for (xs <- xss) yield + for (yst <- ysst) yield + scalprod(xs, yst) + } + + val a1 = Array(Array(0, 2, 4), Array(1, 3, 5)) + println(transpose(a1).deep.mkString("[", ",", "]")) + + println(matmul(Array(Array(2, 3)), Array(Array(5), Array(7))).deep.mkString("[", ",", "]")) + + println(matmul(Array(Array(4)), Array(Array(6, 8))).deep.mkString("[", ",", "]")) +} diff --git a/test/files/run/t0677-old.scala b/test/files/run/t0677-old.scala new file mode 100644 index 0000000000..6c8a3a7e99 --- /dev/null +++ b/test/files/run/t0677-old.scala @@ -0,0 +1,8 @@ +object Test extends App { + class X[T: ClassManifest] { + val a = Array.ofDim[T](3, 4) + } + val x = new X[String] + x.a(1)(2) = "hello" + assert(x.a(1)(2) == "hello") +} diff --git a/test/files/run/t1195-old.check b/test/files/run/t1195-old.check new file mode 100644 index 0000000000..eb60eceb17 --- /dev/null +++ b/test/files/run/t1195-old.check @@ -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-old.scala b/test/files/run/t1195-old.scala new file mode 100644 index 0000000000..b46a3b70f5 --- /dev/null +++ b/test/files/run/t1195-old.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]) + + 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/t2236-old.scala b/test/files/run/t2236-old.scala new file mode 100644 index 0000000000..64ed18c805 --- /dev/null +++ b/test/files/run/t2236-old.scala @@ -0,0 +1,17 @@ +class T[A](implicit val m:Manifest[A]) +class Foo +class Bar extends T[Foo] +object Test extends App { + new Bar +} + +object EvidenceTest { + trait E[T] + trait A[T] { implicit val e: E[T] = null } + class B[T : E] extends A[T] { override val e = null } + + def f[T] { + implicit val e: E[T] = null + new B[T]{} + } +} diff --git a/test/files/run/t3758-old.scala b/test/files/run/t3758-old.scala new file mode 100644 index 0000000000..f00254afee --- /dev/null +++ b/test/files/run/t3758-old.scala @@ -0,0 +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]) + } +} \ No newline at end of file diff --git a/test/files/run/t4110-old.check b/test/files/run/t4110-old.check new file mode 100644 index 0000000000..8b005989de --- /dev/null +++ b/test/files/run/t4110-old.check @@ -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-old.scala b/test/files/run/t4110-old.scala new file mode 100644 index 0000000000..a42646ce52 --- /dev/null +++ b/test/files/run/t4110-old.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/scalacheck/array-old.scala b/test/files/scalacheck/array-old.scala new file mode 100644 index 0000000000..f262bc6320 --- /dev/null +++ b/test/files/scalacheck/array-old.scala @@ -0,0 +1,37 @@ +import org.scalacheck._ +import Prop._ +import Gen._ +import Arbitrary._ +import util._ +import Buildable._ +import scala.collection.mutable.ArraySeq + +object Test extends Properties("Array") { + /** At this moment the authentic scalacheck Array Builder/Arb bits are commented out. + */ + implicit def arbArray[T](implicit a: Arbitrary[T], m: Manifest[T]): Arbitrary[Array[T]] = + Arbitrary(containerOf[List,T](arbitrary[T]) map (_.toArray)) + + val arrGen: Gen[Array[_]] = oneOf( + arbitrary[Array[Int]], + arbitrary[Array[Array[Int]]], + arbitrary[Array[List[String]]], + arbitrary[Array[String]], + arbitrary[Array[Boolean]], + arbitrary[Array[AnyVal]] + ) + + // inspired by #1857 and #2352 + property("eq/ne") = forAll(arrGen, arrGen) { (c1, c2) => + (c1 eq c2) || (c1 ne c2) + } + + // inspired by #2299 + def smallInt = choose(1, 10) + property("ofDim") = forAll(smallInt, smallInt, smallInt) { (i1, i2, i3) => + val arr = Array.ofDim[String](i1, i2, i3) + val flattened = arr flatMap (x => x) flatMap (x => x) + flattened.length == i1 * i2 * i3 + } +} + diff --git a/test/files/specialized/spec-matrix-old.check b/test/files/specialized/spec-matrix-old.check new file mode 100644 index 0000000000..5ec3e84597 --- /dev/null +++ b/test/files/specialized/spec-matrix-old.check @@ -0,0 +1,2 @@ +251437.0 +Boxed doubles: 1 diff --git a/test/files/specialized/spec-matrix-old.scala b/test/files/specialized/spec-matrix-old.scala new file mode 100644 index 0000000000..98735c8c03 --- /dev/null +++ b/test/files/specialized/spec-matrix-old.scala @@ -0,0 +1,80 @@ +/** Test matrix multiplication with specialization. + */ + +class Matrix[@specialized A: ClassManifest](val rows: Int, val cols: Int) { + private val arr: Array[Array[A]] = Array.ofDim[A](rows, cols) + + def apply(i: Int, j: Int): A = { + if (i < 0 || i >= rows || j < 0 || j >= cols) + throw new NoSuchElementException("Indexes out of bounds: " + (i, j)) + + arr(i)(j) + } + + def update(i: Int, j: Int, e: A) { + arr(i)(j) = e + } + + def rowsIterator: Iterator[Array[A]] = new Iterator[Array[A]] { + var idx = 0; + def hasNext = idx < rows + def next = { + idx += 1 + arr(idx - 1) + } + } +} + +object Test { + def main(args: Array[String]) { + val m = randomMatrix(200, 100) + val n = randomMatrix(100, 200) + + val p = mult(m, n) + println(p(0, 0)) + println("Boxed doubles: " + runtime.BoxesRunTime.doubleBoxCount) +// println("Boxed integers: " + runtime.BoxesRunTime.integerBoxCount) + } + + def randomMatrix(n: Int, m: Int) = { + val r = new util.Random(10) + val x = new Matrix[Double](n, m) + for (i <- 0 until n; j <- 0 until m) + x(i, j) = (r.nextInt % 1000).toDouble + x + } + + def printMatrix[Double](m: Matrix[Double]) { + for (i <- 0 until m.rows) { + for (j <- 0 until m.cols) + print("%5.3f ".format(m(i, j))) + println + } + } + + def multManifest[@specialized(Int) T](m: Matrix[T], n: Matrix[T])(implicit cm: ClassManifest[T], num: Numeric[T]) { + val p = new Matrix[T](m.rows, n.cols) + import num._ + + for (i <- 0 until m.rows) + for (j <- 0 until n.cols) { + var sum = num.zero + for (k <- 0 until n.rows) + sum += m(i, k) * n(k, j) + p(i, j) = sum + } + } + + def mult(m: Matrix[Double], n: Matrix[Double]) = { + val p = new Matrix[Double](m.rows, n.cols) + + for (i <- 0 until m.rows) + for (j <- 0 until n.cols) { + var sum = 0.0 + for (k <- 0 until n.rows) + sum += m(i, k) * n(k, j) + p(i, j) = sum + } + p + } +} -- cgit v1.2.3 From d4b8d8deefcdd9144ef39d1456b03aa693f93ff7 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sun, 22 Apr 2012 22:02:34 +0200 Subject: interop between manifests and tags --- src/compiler/scala/reflect/internal/StdNames.scala | 3 ++ .../scala/tools/nsc/typechecker/Implicits.scala | 11 ++++++- src/library/scala/reflect/DummyMirror.scala | 9 ++++++ src/library/scala/reflect/TagInterop.scala | 34 ++++++++++++++++++++++ src/library/scala/reflect/api/TreeBuildUtil.scala | 18 ++++++++++++ .../scala/reflect/makro/internal/Utils.scala | 12 +++++++- src/library/scala/reflect/package.scala | 4 +++ ...op_classmanifests_arenot_concretetypetags.check | 4 +++ ...op_classmanifests_arenot_concretetypetags.scala | 9 ++++++ .../neg/interop_classtags_arenot_manifests.check | 7 +++++ .../neg/interop_classtags_arenot_manifests.scala | 17 +++++++++++ ...interop_erasuretags_arenot_classmanifests.check | 4 +++ ...interop_erasuretags_arenot_classmanifests.scala | 9 ++++++ .../neg/interop_erasuretags_arenot_manifests.check | 4 +++ .../neg/interop_erasuretags_arenot_manifests.scala | 9 ++++++ .../interop_typetags_arenot_classmanifests.check | 4 +++ .../interop_typetags_arenot_classmanifests.scala | 9 ++++++ .../neg/interop_typetags_arenot_manifests.check | 4 +++ .../neg/interop_typetags_arenot_manifests.scala | 9 ++++++ ...erop_classmanifests_arepartially_typetags.check | 6 ++++ ...erop_classmanifests_arepartially_typetags.scala | 10 +++++++ .../run/interop_classtags_are_classmanifests.check | 6 ++++ .../run/interop_classtags_are_classmanifests.scala | 17 +++++++++++ ...terop_concretetypetags_are_classmanifests.check | 3 ++ ...terop_concretetypetags_are_classmanifests.scala | 9 ++++++ .../interop_concretetypetags_are_manifests.check | 3 ++ .../interop_concretetypetags_are_manifests.scala | 9 ++++++ .../run/interop_manifests_are_classtags.check | 24 +++++++++++++++ .../run/interop_manifests_are_classtags.scala | 23 +++++++++++++++ .../interop_manifests_are_concretetypetags.check | 6 ++++ .../interop_manifests_are_concretetypetags.scala | 10 +++++++ .../files/run/interop_manifests_are_typetags.check | 6 ++++ .../files/run/interop_manifests_are_typetags.scala | 10 +++++++ 33 files changed, 320 insertions(+), 2 deletions(-) create mode 100644 src/library/scala/reflect/TagInterop.scala create mode 100644 test/files/neg/interop_classmanifests_arenot_concretetypetags.check create mode 100644 test/files/neg/interop_classmanifests_arenot_concretetypetags.scala create mode 100644 test/files/neg/interop_classtags_arenot_manifests.check create mode 100644 test/files/neg/interop_classtags_arenot_manifests.scala create mode 100644 test/files/neg/interop_erasuretags_arenot_classmanifests.check create mode 100644 test/files/neg/interop_erasuretags_arenot_classmanifests.scala create mode 100644 test/files/neg/interop_erasuretags_arenot_manifests.check create mode 100644 test/files/neg/interop_erasuretags_arenot_manifests.scala create mode 100644 test/files/neg/interop_typetags_arenot_classmanifests.check create mode 100644 test/files/neg/interop_typetags_arenot_classmanifests.scala create mode 100644 test/files/neg/interop_typetags_arenot_manifests.check create mode 100644 test/files/neg/interop_typetags_arenot_manifests.scala create mode 100644 test/files/run/interop_classmanifests_arepartially_typetags.check create mode 100644 test/files/run/interop_classmanifests_arepartially_typetags.scala create mode 100644 test/files/run/interop_classtags_are_classmanifests.check create mode 100644 test/files/run/interop_classtags_are_classmanifests.scala create mode 100644 test/files/run/interop_concretetypetags_are_classmanifests.check create mode 100644 test/files/run/interop_concretetypetags_are_classmanifests.scala create mode 100644 test/files/run/interop_concretetypetags_are_manifests.check create mode 100644 test/files/run/interop_concretetypetags_are_manifests.scala create mode 100644 test/files/run/interop_manifests_are_classtags.check create mode 100644 test/files/run/interop_manifests_are_classtags.scala create mode 100644 test/files/run/interop_manifests_are_concretetypetags.check create mode 100644 test/files/run/interop_manifests_are_concretetypetags.scala create mode 100644 test/files/run/interop_manifests_are_typetags.check create mode 100644 test/files/run/interop_manifests_are_typetags.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 4ce6afe1f3..a55efea2e6 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -564,6 +564,7 @@ trait StdNames { val argv : NameType = "argv" val arrayClass: NameType = "arrayClass" val arrayElementClass: NameType = "arrayElementClass" + val arrayTagToClassManifest: NameType = "arrayTagToClassManifest" val arrayValue: NameType = "arrayValue" val array_apply : NameType = "array_apply" val array_clone : NameType = "array_clone" @@ -581,6 +582,7 @@ trait StdNames { val checkInitialized: NameType = "checkInitialized" val classOf: NameType = "classOf" val clone_ : NameType = if (forMSIL) "MemberwiseClone" else "clone" // sn.OClone causes checkinit failure + val concreteTypeTagToManifest: NameType = "concreteTypeTagToManifest" val conforms: NameType = "conforms" val copy: NameType = "copy" val definitions: NameType = "definitions" @@ -629,6 +631,7 @@ trait StdNames { val macroContext : NameType = "c" val main: NameType = "main" val manifest: NameType = "manifest" + val manifestToConcreteTypeTag: NameType = "manifestToConcreteTypeTag" val map: NameType = "map" val materializeArrayTag: NameType = "materializeArrayTag" val materializeClassTag: NameType = "materializeClassTag" diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index fadb691cb6..1612253dd6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1265,7 +1265,16 @@ trait Implicits { } } - mot(tp, Nil, Nil) + val tagInScope = + if (full) context.withMacrosDisabled(resolveTypeTag(pos, ReflectMirrorPrefix.tpe, tp, true)) + else context.withMacrosDisabled(resolveArrayTag(pos, tp)) + if (tagInScope.isEmpty) mot(tp, Nil, Nil) + else { + val interop = + if (full) gen.mkMethodCall(ReflectPackage, nme.concreteTypeTagToManifest, List(tp), List(tagInScope)) + else gen.mkMethodCall(ReflectPackage, nme.arrayTagToClassManifest, List(tp), List(tagInScope)) + wrapResult(interop) + } } def wrapResult(tree: Tree): SearchResult = diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala index 276237fce4..f40531e856 100644 --- a/src/library/scala/reflect/DummyMirror.scala +++ b/src/library/scala/reflect/DummyMirror.scala @@ -500,6 +500,7 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { type TreeGenTree = global.Tree type TreeGenType = global.Type type TreeGenSymbol = global.Symbol + type TreeGenName = global.Name def mkAttributedQualifier(tpe: TreeGenType): TreeGenTree = notSupported() def mkAttributedQualifier(tpe: TreeGenType, termSym: TreeGenSymbol): TreeGenTree = notSupported() def mkAttributedRef(pre: TreeGenType, sym: TreeGenSymbol): TreeGenTree = notSupported() @@ -507,6 +508,14 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { def mkAttributedThis(sym: TreeGenSymbol): TreeGenTree = notSupported() def mkAttributedIdent(sym: TreeGenSymbol): TreeGenTree = notSupported() def mkAttributedSelect(qual: TreeGenTree, sym: TreeGenSymbol): TreeGenTree = notSupported() + def mkMethodCall(target: TreeGenTree,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported() + def mkMethodCall(receiver: TreeGenTree,method: TreeGenSymbol,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported() + def mkMethodCall(receiver: TreeGenSymbol,methodName: TreeGenName,args: List[TreeGenTree]): TreeGenTree = notSupported() + def mkMethodCall(target: TreeGenTree,args: List[TreeGenTree]): TreeGenTree = notSupported() + def mkMethodCall(method: TreeGenSymbol,args: List[TreeGenTree]): TreeGenTree = notSupported() + def mkMethodCall(method: TreeGenSymbol,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported() + def mkMethodCall(receiver: TreeGenSymbol,methodName: TreeGenName,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported() + def mkNullaryCall(method: TreeGenSymbol,targs: List[TreeGenType]): TreeGenTree = notSupported() } // Members declared in scala.reflect.api.TreePrinters diff --git a/src/library/scala/reflect/TagInterop.scala b/src/library/scala/reflect/TagInterop.scala new file mode 100644 index 0000000000..6c6bfcc2f2 --- /dev/null +++ b/src/library/scala/reflect/TagInterop.scala @@ -0,0 +1,34 @@ +package scala.reflect + +import scala.runtime.ScalaRunTime._ +import mirror._ +import definitions._ + +object TagInterop { + def arrayTagToClassManifest[T](tag: ArrayTag[T]): ClassManifest[T] = { + val erasure = arrayElementClass(tag) + if (erasure.isArray) { + val elementClass = arrayElementClass(erasure) + val elementManifest = arrayTagToClassManifest(ClassTag(elementClass)) + ClassManifest.arrayType(elementManifest).asInstanceOf[ClassManifest[T]] + } else { + ClassManifest.fromClass(erasure.asInstanceOf[Class[T]]) + } + } + + def concreteTypeTagToManifest[T](tag: ConcreteTypeTag[T]): Manifest[T] = { + // todo. reproduce manifest generation code here. toolboxes are too slow. + val implicitly = PredefModule.typeSignature.member(newTermName("implicitly")) + val taggedTpe = appliedType(staticClass("scala.reflect.Manifest").asTypeConstructor, List(tag.tpe)) + val materializer = TypeApply(Ident(implicitly), List(TypeTree(taggedTpe))) + try mkToolBox().runExpr(materializer).asInstanceOf[Manifest[T]] + catch { case ex: Throwable => Manifest.classType(tag.erasure).asInstanceOf[Manifest[T]] } + } + + def manifestToConcreteTypeTag[T](tag: Manifest[T]): ConcreteTypeTag[T] = { + val tpe = + if (tag.typeArguments.isEmpty) classToType(tag.erasure) + else appliedType(classToType(tag.erasure).typeConstructor, tag.typeArguments map (manifestToConcreteTypeTag(_)) map (_.tpe)) + ConcreteTypeTag(tpe, tag.erasure) + } +} \ 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 4f510337c2..87790b3812 100644 --- a/src/library/scala/reflect/api/TreeBuildUtil.scala +++ b/src/library/scala/reflect/api/TreeBuildUtil.scala @@ -138,4 +138,22 @@ trait AbsTreeGen { /** Builds a typed Select with an underlying symbol. */ def mkAttributedSelect(qual: Tree, sym: Symbol): Tree + + /** A creator for method calls, e.g. fn[T1, T2, ...](v1, v2, ...) + * There are a number of variations. + * + * @param receiver symbol of the method receiver + * @param methodName name of the method to call + * @param targs type arguments (if Nil, no TypeApply node will be generated) + * @param args value arguments + * @return the newly created trees. + */ + def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree + def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree + def mkMethodCall(method: Symbol, args: List[Tree]): Tree + def mkMethodCall(target: Tree, args: List[Tree]): Tree + def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree + def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree + def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree + def mkNullaryCall(method: Symbol, targs: List[Type]): Tree } diff --git a/src/library/scala/reflect/makro/internal/Utils.scala b/src/library/scala/reflect/makro/internal/Utils.scala index a8a2c98715..3af58e1c88 100644 --- a/src/library/scala/reflect/makro/internal/Utils.scala +++ b/src/library/scala/reflect/makro/internal/Utils.scala @@ -97,12 +97,22 @@ package internal { val ref = if (tagModule.owner.isPackageClass) Ident(tagModule) else Select(prefix, tagModule.name) Select(ref, coreTags(coreTpe)) case _ => - translatingReificationErrors(materializer) + val manifestInScope = nonSyntheticManifestInScope(tpe) + if (manifestInScope.isEmpty) translatingReificationErrors(materializer) + else gen.mkMethodCall(staticModule("scala.reflect.package"), newTermName("manifestToConcreteTypeTag"), List(tpe), List(manifestInScope)) } try c.typeCheck(result) catch { case terr @ c.TypeError(pos, msg) => failTag(terr) } } + private def nonSyntheticManifestInScope(tpe: Type) = { + val ManifestClass = staticClass("scala.reflect.Manifest") + val ManifestModule = staticModule("scala.reflect.Manifest") + val manifest = c.inferImplicitValue(appliedType(ManifestClass.asTypeConstructor, List(tpe))) + val notOk = manifest.isEmpty || (manifest exists (sub => sub.symbol != null && (sub.symbol == ManifestModule || sub.symbol.owner == ManifestModule))) + if (notOk) EmptyTree else manifest + } + def materializeExpr(prefix: Tree, expr: Tree): Tree = { val result = translatingReificationErrors(c.reifyTree(prefix, expr)) try c.typeCheck(result) diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 0e6350183f..38a144cd49 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -63,4 +63,8 @@ package object reflect { // ClassTag object is defined separately from the mirror lazy val TypeTag = scala.reflect.mirror.TypeTag lazy val ConcreteTypeTag = scala.reflect.mirror.ConcreteTypeTag + + def arrayTagToClassManifest[T](tag: ArrayTag[T]): ClassManifest[T] = TagInterop.arrayTagToClassManifest[T](tag) + def concreteTypeTagToManifest[T](tag: ConcreteTypeTag[T]): Manifest[T] = TagInterop.concreteTypeTagToManifest[T](tag) + def manifestToConcreteTypeTag[T](tag: Manifest[T]): ConcreteTypeTag[T] = TagInterop.manifestToConcreteTypeTag[T](tag) } diff --git a/test/files/neg/interop_classmanifests_arenot_concretetypetags.check b/test/files/neg/interop_classmanifests_arenot_concretetypetags.check new file mode 100644 index 0000000000..d6fa564df4 --- /dev/null +++ b/test/files/neg/interop_classmanifests_arenot_concretetypetags.check @@ -0,0 +1,4 @@ +interop_classmanifests_arenot_concretetypetags.scala:3: error: No ConcreteTypeTag available for T + println(concreteTypeTag[T]) + ^ +one error found diff --git a/test/files/neg/interop_classmanifests_arenot_concretetypetags.scala b/test/files/neg/interop_classmanifests_arenot_concretetypetags.scala new file mode 100644 index 0000000000..5b1ed55e47 --- /dev/null +++ b/test/files/neg/interop_classmanifests_arenot_concretetypetags.scala @@ -0,0 +1,9 @@ +object Test extends App { + def classManifestIsnotConcreteTypeTag[T: ClassManifest] = { + println(concreteTypeTag[T]) + } + + classManifestIsnotConcreteTypeTag[Int] + classManifestIsnotConcreteTypeTag[String] + classManifestIsnotConcreteTypeTag[Array[Int]] +} \ No newline at end of file diff --git a/test/files/neg/interop_classtags_arenot_manifests.check b/test/files/neg/interop_classtags_arenot_manifests.check new file mode 100644 index 0000000000..95f6a94d4b --- /dev/null +++ b/test/files/neg/interop_classtags_arenot_manifests.check @@ -0,0 +1,7 @@ +interop_classtags_arenot_manifests.scala:3: error: No Manifest available for T. + println(manifest[T]) + ^ +interop_classtags_arenot_manifests.scala:11: error: No Manifest available for T. + println(manifest[T]) + ^ +two errors found diff --git a/test/files/neg/interop_classtags_arenot_manifests.scala b/test/files/neg/interop_classtags_arenot_manifests.scala new file mode 100644 index 0000000000..7351f7e305 --- /dev/null +++ b/test/files/neg/interop_classtags_arenot_manifests.scala @@ -0,0 +1,17 @@ +object Test extends App { + def arrayTagIsnotManifest[T: ArrayTag] = { + println(manifest[T]) + } + + arrayTagIsnotManifest[Int] + arrayTagIsnotManifest[String] + arrayTagIsnotManifest[Array[Int]] + + def classTagIsnotManifest[T: ClassTag] = { + println(manifest[T]) + } + + classTagIsnotManifest[Int] + classTagIsnotManifest[String] + classTagIsnotManifest[Array[Int]] +} \ No newline at end of file diff --git a/test/files/neg/interop_erasuretags_arenot_classmanifests.check b/test/files/neg/interop_erasuretags_arenot_classmanifests.check new file mode 100644 index 0000000000..4bb81108d1 --- /dev/null +++ b/test/files/neg/interop_erasuretags_arenot_classmanifests.check @@ -0,0 +1,4 @@ +interop_erasuretags_arenot_classmanifests.scala:3: error: could not find implicit value for parameter m: ClassManifest[T] + println(classManifest[T]) + ^ +one error found diff --git a/test/files/neg/interop_erasuretags_arenot_classmanifests.scala b/test/files/neg/interop_erasuretags_arenot_classmanifests.scala new file mode 100644 index 0000000000..cf7d1ac257 --- /dev/null +++ b/test/files/neg/interop_erasuretags_arenot_classmanifests.scala @@ -0,0 +1,9 @@ +object Test extends App { + def erasureTagIsnotClassManifest[T: ErasureTag] = { + println(classManifest[T]) + } + + erasureTagIsnotClassManifest[Int] + erasureTagIsnotClassManifest[String] + erasureTagIsnotClassManifest[Array[Int]] +} \ No newline at end of file diff --git a/test/files/neg/interop_erasuretags_arenot_manifests.check b/test/files/neg/interop_erasuretags_arenot_manifests.check new file mode 100644 index 0000000000..da3c03d371 --- /dev/null +++ b/test/files/neg/interop_erasuretags_arenot_manifests.check @@ -0,0 +1,4 @@ +interop_erasuretags_arenot_manifests.scala:3: error: No Manifest available for T. + println(manifest[T]) + ^ +one error found diff --git a/test/files/neg/interop_erasuretags_arenot_manifests.scala b/test/files/neg/interop_erasuretags_arenot_manifests.scala new file mode 100644 index 0000000000..5c326549d8 --- /dev/null +++ b/test/files/neg/interop_erasuretags_arenot_manifests.scala @@ -0,0 +1,9 @@ +object Test extends App { + def erasureTagIsnotManifest[T: ErasureTag] = { + println(manifest[T]) + } + + erasureTagIsnotManifest[Int] + erasureTagIsnotManifest[String] + erasureTagIsnotManifest[Array[Int]] +} \ No newline at end of file diff --git a/test/files/neg/interop_typetags_arenot_classmanifests.check b/test/files/neg/interop_typetags_arenot_classmanifests.check new file mode 100644 index 0000000000..9ed4fd43d4 --- /dev/null +++ b/test/files/neg/interop_typetags_arenot_classmanifests.check @@ -0,0 +1,4 @@ +interop_typetags_arenot_classmanifests.scala:3: error: could not find implicit value for parameter m: ClassManifest[T] + println(classManifest[T]) + ^ +one error found diff --git a/test/files/neg/interop_typetags_arenot_classmanifests.scala b/test/files/neg/interop_typetags_arenot_classmanifests.scala new file mode 100644 index 0000000000..b1fbb7b5a6 --- /dev/null +++ b/test/files/neg/interop_typetags_arenot_classmanifests.scala @@ -0,0 +1,9 @@ +object Test extends App { + def typeTagIsnotClassManifest[T: TypeTag] = { + println(classManifest[T]) + } + + typeTagIsnotClassManifest[Int] + typeTagIsnotClassManifest[String] + typeTagIsnotClassManifest[Array[Int]] +} \ No newline at end of file diff --git a/test/files/neg/interop_typetags_arenot_manifests.check b/test/files/neg/interop_typetags_arenot_manifests.check new file mode 100644 index 0000000000..7761a747ff --- /dev/null +++ b/test/files/neg/interop_typetags_arenot_manifests.check @@ -0,0 +1,4 @@ +interop_typetags_arenot_manifests.scala:3: error: No Manifest available for T. + println(manifest[T]) + ^ +one error found diff --git a/test/files/neg/interop_typetags_arenot_manifests.scala b/test/files/neg/interop_typetags_arenot_manifests.scala new file mode 100644 index 0000000000..4e2a04489b --- /dev/null +++ b/test/files/neg/interop_typetags_arenot_manifests.scala @@ -0,0 +1,9 @@ +object Test extends App { + def typeTagIsnotManifest[T: TypeTag] = { + println(manifest[T]) + } + + typeTagIsnotManifest[Int] + typeTagIsnotManifest[String] + typeTagIsnotManifest[Array[Int]] +} \ No newline at end of file diff --git a/test/files/run/interop_classmanifests_arepartially_typetags.check b/test/files/run/interop_classmanifests_arepartially_typetags.check new file mode 100644 index 0000000000..3dfcdccbec --- /dev/null +++ b/test/files/run/interop_classmanifests_arepartially_typetags.check @@ -0,0 +1,6 @@ +T +int +T +class java.lang.String +T +class [I diff --git a/test/files/run/interop_classmanifests_arepartially_typetags.scala b/test/files/run/interop_classmanifests_arepartially_typetags.scala new file mode 100644 index 0000000000..9bc1f32e86 --- /dev/null +++ b/test/files/run/interop_classmanifests_arepartially_typetags.scala @@ -0,0 +1,10 @@ +object Test extends App { + def classManifestIspartiallyTypeTag[T: ClassManifest] = { + println(typeTag[T].tpe) + println(typeTag[T].erasure) + } + + classManifestIspartiallyTypeTag[Int] + classManifestIspartiallyTypeTag[String] + classManifestIspartiallyTypeTag[Array[Int]] +} \ No newline at end of file diff --git a/test/files/run/interop_classtags_are_classmanifests.check b/test/files/run/interop_classtags_are_classmanifests.check new file mode 100644 index 0000000000..02393dff23 --- /dev/null +++ b/test/files/run/interop_classtags_are_classmanifests.check @@ -0,0 +1,6 @@ +Int +java.lang.String +Array[Int] +Int +java.lang.String +Array[Int] diff --git a/test/files/run/interop_classtags_are_classmanifests.scala b/test/files/run/interop_classtags_are_classmanifests.scala new file mode 100644 index 0000000000..309c99a3f5 --- /dev/null +++ b/test/files/run/interop_classtags_are_classmanifests.scala @@ -0,0 +1,17 @@ +object Test extends App { + def arrayTagIsClassManifest[T: ArrayTag] = { + println(classManifest[T]) + } + + arrayTagIsClassManifest[Int] + arrayTagIsClassManifest[String] + arrayTagIsClassManifest[Array[Int]] + + def classTagIsClassManifest[T: ClassTag] = { + println(classManifest[T]) + } + + classTagIsClassManifest[Int] + classTagIsClassManifest[String] + classTagIsClassManifest[Array[Int]] +} \ No newline at end of file diff --git a/test/files/run/interop_concretetypetags_are_classmanifests.check b/test/files/run/interop_concretetypetags_are_classmanifests.check new file mode 100644 index 0000000000..c59e92d4eb --- /dev/null +++ b/test/files/run/interop_concretetypetags_are_classmanifests.check @@ -0,0 +1,3 @@ +Int +java.lang.String +Array[Int] diff --git a/test/files/run/interop_concretetypetags_are_classmanifests.scala b/test/files/run/interop_concretetypetags_are_classmanifests.scala new file mode 100644 index 0000000000..b578d7e626 --- /dev/null +++ b/test/files/run/interop_concretetypetags_are_classmanifests.scala @@ -0,0 +1,9 @@ +object Test extends App { + def concreteTypeTagIsClassManifest[T: ConcreteTypeTag] = { + println(classManifest[T]) + } + + concreteTypeTagIsClassManifest[Int] + concreteTypeTagIsClassManifest[String] + concreteTypeTagIsClassManifest[Array[Int]] +} \ No newline at end of file diff --git a/test/files/run/interop_concretetypetags_are_manifests.check b/test/files/run/interop_concretetypetags_are_manifests.check new file mode 100644 index 0000000000..c59e92d4eb --- /dev/null +++ b/test/files/run/interop_concretetypetags_are_manifests.check @@ -0,0 +1,3 @@ +Int +java.lang.String +Array[Int] diff --git a/test/files/run/interop_concretetypetags_are_manifests.scala b/test/files/run/interop_concretetypetags_are_manifests.scala new file mode 100644 index 0000000000..731410bc10 --- /dev/null +++ b/test/files/run/interop_concretetypetags_are_manifests.scala @@ -0,0 +1,9 @@ +object Test extends App { + def concreteTypeTagIsManifest[T: ConcreteTypeTag] = { + println(manifest[T]) + } + + concreteTypeTagIsManifest[Int] + concreteTypeTagIsManifest[String] + concreteTypeTagIsManifest[Array[Int]] +} \ No newline at end of file diff --git a/test/files/run/interop_manifests_are_classtags.check b/test/files/run/interop_manifests_are_classtags.check new file mode 100644 index 0000000000..07ff6b984a --- /dev/null +++ b/test/files/run/interop_manifests_are_classtags.check @@ -0,0 +1,24 @@ +Int +Int +List() +List(0, 0, 0, 0, 0) +java.lang.String +java.lang.String +List() +List(null, null, null, null, null) +Array[Int] +Array[Int] +List() +List(null, null, null, null, null) +Int +Int +List() +List(0, 0, 0, 0, 0) +java.lang.String +java.lang.String +List() +List(null, null, null, null, null) +Array[Int] +Array[Int] +List() +List(null, null, null, null, null) diff --git a/test/files/run/interop_manifests_are_classtags.scala b/test/files/run/interop_manifests_are_classtags.scala new file mode 100644 index 0000000000..582cea3467 --- /dev/null +++ b/test/files/run/interop_manifests_are_classtags.scala @@ -0,0 +1,23 @@ +object Test extends App { + def classManifestIsClassTag[T: ClassManifest] = { + println(arrayTag[T]) + println(erasureTag[T]) + println(Array[T]().toList) + println(new Array[T](5).toList) + } + + classManifestIsClassTag[Int] + classManifestIsClassTag[String] + classManifestIsClassTag[Array[Int]] + + def manifestIsClassTag[T: Manifest] = { + println(arrayTag[T]) + println(erasureTag[T]) + println(Array[T]().toList) + println(new Array[T](5).toList) + } + + manifestIsClassTag[Int] + manifestIsClassTag[String] + manifestIsClassTag[Array[Int]] +} \ No newline at end of file diff --git a/test/files/run/interop_manifests_are_concretetypetags.check b/test/files/run/interop_manifests_are_concretetypetags.check new file mode 100644 index 0000000000..edab85ecf1 --- /dev/null +++ b/test/files/run/interop_manifests_are_concretetypetags.check @@ -0,0 +1,6 @@ +Int +int +String +class java.lang.String +Array[Int] +class [I diff --git a/test/files/run/interop_manifests_are_concretetypetags.scala b/test/files/run/interop_manifests_are_concretetypetags.scala new file mode 100644 index 0000000000..0b82a56d0a --- /dev/null +++ b/test/files/run/interop_manifests_are_concretetypetags.scala @@ -0,0 +1,10 @@ +object Test extends App { + def manifestIsConcreteTypeTag[T: Manifest] = { + println(concreteTypeTag[T].tpe) + println(concreteTypeTag[T].erasure) + } + + manifestIsConcreteTypeTag[Int] + manifestIsConcreteTypeTag[String] + manifestIsConcreteTypeTag[Array[Int]] +} \ No newline at end of file diff --git a/test/files/run/interop_manifests_are_typetags.check b/test/files/run/interop_manifests_are_typetags.check new file mode 100644 index 0000000000..edab85ecf1 --- /dev/null +++ b/test/files/run/interop_manifests_are_typetags.check @@ -0,0 +1,6 @@ +Int +int +String +class java.lang.String +Array[Int] +class [I diff --git a/test/files/run/interop_manifests_are_typetags.scala b/test/files/run/interop_manifests_are_typetags.scala new file mode 100644 index 0000000000..03a7b7b6d5 --- /dev/null +++ b/test/files/run/interop_manifests_are_typetags.scala @@ -0,0 +1,10 @@ +object Test extends App { + def manifestIsTypeTag[T: Manifest] = { + println(typeTag[T].tpe) + println(typeTag[T].erasure) + } + + manifestIsTypeTag[Int] + manifestIsTypeTag[String] + manifestIsTypeTag[Array[Int]] +} \ No newline at end of file -- cgit v1.2.3 From f4d7febab57f7cc172abebfb3233f0ab771cd72a Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 23 Apr 2012 10:46:10 -0700 Subject: Removed FlatArray. We thought better of it. --- .../scala/collection/mutable/FlatArray.scala | 157 --------------------- test/files/run/Meter.check | 8 -- test/files/run/Meter.scala | 36 ++--- test/files/run/MeterCaseClass.check | 8 -- test/files/run/MeterCaseClass.scala | 36 ++--- 5 files changed, 36 insertions(+), 209 deletions(-) delete mode 100644 src/library/scala/collection/mutable/FlatArray.scala (limited to 'src') diff --git a/src/library/scala/collection/mutable/FlatArray.scala b/src/library/scala/collection/mutable/FlatArray.scala deleted file mode 100644 index 5b4b5e777f..0000000000 --- a/src/library/scala/collection/mutable/FlatArray.scala +++ /dev/null @@ -1,157 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.collection -package mutable - -import scala.reflect.ArrayTag -import generic.CanBuildFrom - -/** - * A class representing `Array[T]`. - * - * @tparam T type of the elements in this wrapped array. - * - * @author Martin Odersky, Stephane Micheloud - * @version 1.0 - * @since 2.8 - * @define Coll WrappedArray - * @define coll wrapped array - * @define orderDependent - * @define orderDependentFold - * @define mayNotTerminateInf - * @define willNotTerminateInf - */ -abstract sealed class FlatArray[T] -extends AbstractSeq[T] - with IndexedSeq[T] - with IndexedSeqOptimized[T, FlatArray[T]] -{ - - override protected[this] def thisCollection: FlatArray[T] = this - override protected[this] def toCollection(repr: FlatArray[T]): FlatArray[T] = repr - - /** The length of the array */ - def length: Int - - /** The element at given index */ - def apply(index: Int): T - - /** Update element at given index */ - def update(index: Int, elem: T): Unit - - override def stringPrefix = "FlatArray" - - override protected[this] def newBuilder: Builder[T, FlatArray[T]] = ??? // implemented in FlatArray.Impl - - /** Clones this object, including the underlying Array. */ - override def clone: FlatArray[T] = ??? // implemented in FlatArray.Impl -} - - -/** A companion object used to create instances of `WrappedArray`. - */ -object FlatArray { - - def ofDim[Boxed, Unboxed](size:Int) - (implicit boxings: BoxingConversions[Boxed, Unboxed], - tag: ArrayTag[Unboxed]): FlatArray[Boxed] = { - val elems = Array.ofDim[Unboxed](size) - new FlatArray.Impl(elems, boxings, tag) - } - - def empty[Boxed, Unboxed](implicit boxings: BoxingConversions[Boxed, Unboxed], - elemTag: ArrayTag[Unboxed]): FlatArray[Boxed] = apply() - - def apply[Boxed, Unboxed](elems: Boxed*) - (implicit boxings: BoxingConversions[Boxed, Unboxed], elemTag: ArrayTag[Unboxed]): FlatArray[Boxed] = { - val b = newBuilder[Boxed, Unboxed] - b.sizeHint(elems.length) - b ++= elems - b.result - } - - def newBuilder[Boxed, Unboxed] - (implicit boxings: BoxingConversions[Boxed, Unboxed], elemTag: ArrayTag[Unboxed]): Builder[Boxed, FlatArray[Boxed]] = - new Bldr[Boxed, Unboxed](boxings, elemTag) - - implicit def canBuildFrom[Boxed, Unboxed]( - implicit - boxings: BoxingConversions[Boxed, Unboxed], - elemTag: ArrayTag[Unboxed]): CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] = - new CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] { - def apply(from: FlatArray[_]): Builder[Boxed, FlatArray[Boxed]] = - newBuilder[Boxed, Unboxed] - def apply: Builder[Boxed, FlatArray[Boxed]] = - newBuilder[Boxed, Unboxed] - } - - private class Bldr[Boxed, Unboxed](boxings: BoxingConversions[Boxed, Unboxed], tag: ArrayTag[Unboxed]) extends Builder[Boxed, FlatArray[Boxed]] { - - private var elems: Array[Unboxed] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def resize(size: Int) { - val newelems = tag.newArray(size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - elems = newelems - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: Boxed): this.type = { - ensureSize(size + 1) - elems(size) = boxings.unbox(elem) - size += 1 - this - } - - def clear() { - size = 0 - } - - def result(): FlatArray[Boxed] = { - if (capacity == 0 || capacity != size) resize(size) - new FlatArray.Impl(elems, boxings, tag) - } - } - - private class Impl[Boxed, Unboxed]( - elems: Array[Unboxed], - boxings: BoxingConversions[Boxed, Unboxed], - elemTag: ArrayTag[Unboxed]) extends FlatArray[Boxed] { - - def length = elems.length - - def apply(idx: Int): Boxed = boxings.box(elems(idx)) - - def update(idx: Int, elem: Boxed) = elems(idx) = boxings.unbox(elem) - - /** Creates new builder for this collection ==> move to subclasses - */ - override protected[this] def newBuilder: Builder[Boxed, FlatArray[Boxed]] = - new Bldr[Boxed, Unboxed](boxings, elemTag) - - /** Clones this object, including the underlying Array. */ - override def clone: FlatArray[Boxed] = new Impl[Boxed, Unboxed](elems.clone(), boxings, elemTag) - } -} diff --git a/test/files/run/Meter.check b/test/files/run/Meter.check index 7562f9a1bf..b7e2eac125 100644 --- a/test/files/run/Meter.check +++ b/test/files/run/Meter.check @@ -11,11 +11,3 @@ Array(1.0m, 2.0m) 1.0m >>>1.0m<<< 1.0m >>>2.0m<<< 2.0m -testing wrapped arrays -FlatArray(1.0m, 2.0m) -1.0m ->>>1.0m<<< 1.0m ->>>2.0m<<< 2.0m -FlatArray(2.0m, 3.0m) -ArrayBuffer(1.0, 2.0) -FlatArray(0.3048ft, 0.6096ft) diff --git a/test/files/run/Meter.scala b/test/files/run/Meter.scala index 515e46de24..d94f338ca9 100644 --- a/test/files/run/Meter.scala +++ b/test/files/run/Meter.scala @@ -80,23 +80,23 @@ object Test extends App { println(m) foo(arr) } - - { println("testing wrapped arrays") - import collection.mutable.FlatArray - val arr = FlatArray(x, y + x) - println(arr) - def foo(x: FlatArray[Meter]) { - for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) } - } - val m = arr(0) - println(m) - foo(arr) - val ys: Seq[Meter] = arr map (_ + new Meter(1)) - println(ys) - val zs = arr map (_ / Meter(1)) - println(zs) - val fs = arr map (_.toFoot) - println(fs) - } + // + // { println("testing wrapped arrays") + // import collection.mutable.FlatArray + // val arr = FlatArray(x, y + x) + // println(arr) + // def foo(x: FlatArray[Meter]) { + // for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) } + // } + // val m = arr(0) + // println(m) + // foo(arr) + // val ys: Seq[Meter] = arr map (_ + new Meter(1)) + // println(ys) + // val zs = arr map (_ / Meter(1)) + // println(zs) + // val fs = arr map (_.toFoot) + // println(fs) + // } } diff --git a/test/files/run/MeterCaseClass.check b/test/files/run/MeterCaseClass.check index 08370d2097..2528753657 100644 --- a/test/files/run/MeterCaseClass.check +++ b/test/files/run/MeterCaseClass.check @@ -11,11 +11,3 @@ Array(Meter(1.0), Meter(2.0)) Meter(1.0) >>>Meter(1.0)<<< Meter(1.0) >>>Meter(2.0)<<< Meter(2.0) -testing wrapped arrays -FlatArray(Meter(1.0), Meter(2.0)) -Meter(1.0) ->>>Meter(1.0)<<< Meter(1.0) ->>>Meter(2.0)<<< Meter(2.0) -FlatArray(Meter(2.0), Meter(3.0)) -ArrayBuffer(1.0, 2.0) -FlatArray(0.3048ft, 0.6096ft) diff --git a/test/files/run/MeterCaseClass.scala b/test/files/run/MeterCaseClass.scala index 8459163f31..e5979cf761 100644 --- a/test/files/run/MeterCaseClass.scala +++ b/test/files/run/MeterCaseClass.scala @@ -77,23 +77,23 @@ object Test extends App { println(m) foo(arr) } - - { println("testing wrapped arrays") - import collection.mutable.FlatArray - val arr = FlatArray(x, y + x) - println(arr) - def foo(x: FlatArray[Meter]) { - for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) } - } - val m = arr(0) - println(m) - foo(arr) - val ys: Seq[Meter] = arr map (_ + new Meter(1)) - println(ys) - val zs = arr map (_ / Meter(1)) - println(zs) - val fs = arr map (_.toFoot) - println(fs) - } + // + // { println("testing wrapped arrays") + // import collection.mutable.FlatArray + // val arr = FlatArray(x, y + x) + // println(arr) + // def foo(x: FlatArray[Meter]) { + // for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) } + // } + // val m = arr(0) + // println(m) + // foo(arr) + // val ys: Seq[Meter] = arr map (_ + new Meter(1)) + // println(ys) + // val zs = arr map (_ / Meter(1)) + // println(zs) + // val fs = arr map (_.toFoot) + // println(fs) + // } } -- cgit v1.2.3 From 114be21b0d6ba4bbaaa067d856eabd7ef89d3d2e Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 23 Apr 2012 21:11:38 +0200 Subject: adds isStatic to Symbols API in macro context @paulp I think this is the place we should dump the contents of AbsSymbolInternal to --- src/compiler/scala/reflect/makro/runtime/Symbols.scala | 2 ++ src/library/scala/reflect/makro/Symbols.scala | 7 +++++++ 2 files changed, 9 insertions(+) (limited to 'src') diff --git a/src/compiler/scala/reflect/makro/runtime/Symbols.scala b/src/compiler/scala/reflect/makro/runtime/Symbols.scala index 552ad2a303..6341523486 100644 --- a/src/compiler/scala/reflect/makro/runtime/Symbols.scala +++ b/src/compiler/scala/reflect/makro/runtime/Symbols.scala @@ -5,4 +5,6 @@ trait Symbols { self: Context => def isLocatable(sym: Symbol) = sym.isLocatable + + def isStatic(sym: Symbol) = sym.isStatic } \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Symbols.scala b/src/library/scala/reflect/makro/Symbols.scala index 91a5f6d8a5..ca1c17534c 100644 --- a/src/library/scala/reflect/makro/Symbols.scala +++ b/src/library/scala/reflect/makro/Symbols.scala @@ -14,4 +14,11 @@ trait Symbols { * 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 + + /** 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(sym: Symbol): Boolean } \ No newline at end of file -- cgit v1.2.3 From 9759909f12818e75fda426a6d809db92c5dc9a9e Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 23 Apr 2012 11:17:41 -0700 Subject: Make scala.language vals lazy. Otherwise loading the class reflectively runs the initializer and throws an exception. --- src/library/scala/language.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/library/scala/language.scala b/src/library/scala/language.scala index 2837187d48..df2eb0b910 100644 --- a/src/library/scala/language.scala +++ b/src/library/scala/language.scala @@ -17,7 +17,7 @@ object language { * of programs. Furthermore, dynamic member selection often relies on reflection, * which is not available on all platforms. */ - implicit val dynamics: dynamics = ??? + implicit lazy val dynamics: dynamics = ??? /** Only where enabled, postfix operator notation `(expr op)` will be allowed. * @@ -26,7 +26,7 @@ object language { * _Why control it?_ Postfix operators interact poorly with semicolon inference. * Most programmers avoid them for this reason. */ - implicit val postfixOps: postfixOps = ??? + implicit lazy 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 @@ -42,7 +42,7 @@ object language { * 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 = ??? + implicit lazy 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`, @@ -53,7 +53,7 @@ object language { * 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 + * implicit values of other types are not affected, and neither are implicit * classes. * * _Why keep the feature?_ Implicit conversions are central to many aspects @@ -65,7 +65,7 @@ object language { * most situations using implicit parameters leads to a better design than * implicit conversions. */ - implicit val implicitConversions: implicitConversions = ??? + implicit lazy val implicitConversions: implicitConversions = ??? /** Only where this flag is enabled, higher-kinded types can be written. * @@ -86,7 +86,7 @@ object language { * 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 = ??? + implicit lazy 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 @@ -102,7 +102,7 @@ object language { * 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 = ??? + implicit lazy val existentials: existentials = ??? object experimental { @@ -119,6 +119,6 @@ object language { * _Why control it?_ For their very power, macros can lead to code that is hard * to debug and understand. */ - implicit val macros: macros = ??? + implicit lazy val macros: macros = ??? } } -- cgit v1.2.3 From 4a4d7e5defb6a436521e5b5c0e5a7fa0154745da Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Tue, 24 Apr 2012 07:27:22 +0900 Subject: $op_name, $op_names, $plus and $eq are not macro --- src/compiler/scala/reflect/internal/Names.scala | 4 ++-- src/library/scala/reflect/api/Names.scala | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala index dc89b14869..23eaa1088c 100644 --- a/src/compiler/scala/reflect/internal/Names.scala +++ b/src/compiler/scala/reflect/internal/Names.scala @@ -397,14 +397,14 @@ trait Names extends api.Names { // def decodedName: ThisNameType = newName(decoded) def encodedName: ThisNameType = encode - /** Replace operator symbols by corresponding $op_name. */ + /** Replace operator symbols by corresponding \$op_name. */ def encode: ThisNameType = { val str = toString val res = NameTransformer.encode(str) if (res == str) thisName else newName(res) } - /** Replace $op_name by corresponding operator symbol. */ + /** Replace \$op_name by corresponding operator symbol. */ def decode: String = { if (this containsChar '$') { val str = toString diff --git a/src/library/scala/reflect/api/Names.scala b/src/library/scala/reflect/api/Names.scala index d92d056751..96651ffa88 100755 --- a/src/library/scala/reflect/api/Names.scala +++ b/src/library/scala/reflect/api/Names.scala @@ -33,13 +33,13 @@ trait Names { /** Returns a type name that represents the same string as this name */ def toTypeName: TypeName - /** Replaces all occurrences of $op_names in this name by corresponding operator symbols. - * Example: `foo_$plus$eq` becomes `foo_+=` + /** Replaces all occurrences of \$op_names in this name by corresponding operator symbols. + * Example: `foo_\$plus\$eq` becomes `foo_+=` */ def decoded: String - /** Replaces all occurrences of operator symbols in this name by corresponding $op_names. - * Example: `foo_+=` becomes `foo_$plus$eq`. + /** Replaces all occurrences of operator symbols in this name by corresponding \$op_names. + * Example: `foo_+=` becomes `foo_\$plus\$eq`. */ def encoded: String -- cgit v1.2.3 From 20faec5815947ed7b41fdb16e05309e1ebf62efb Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Tue, 24 Apr 2012 07:36:27 +0900 Subject: "@returns" is not a Scaladoc tag --- src/library/scala/collection/SeqExtractors.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/library/scala/collection/SeqExtractors.scala b/src/library/scala/collection/SeqExtractors.scala index cbb09a0a90..de9ff93521 100644 --- a/src/library/scala/collection/SeqExtractors.scala +++ b/src/library/scala/collection/SeqExtractors.scala @@ -11,8 +11,7 @@ object +: { /** An extractor used to init/last deconstruct sequences. */ object :+ { /** Splits a sequence into init :+ tail. - * @returns Some(init, tail) if sequence is non-empty. - * None otherwise. + * @return Some(init, tail) if sequence is non-empty. None otherwise. */ def unapply[T,Coll <: SeqLike[T, Coll]]( t: Coll with SeqLike[T, Coll]): Option[(Coll, T)] = -- cgit v1.2.3 From ed3dafc62145c9236156e1b9b7fff02d0ecd2b6f Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Tue, 24 Apr 2012 07:37:05 +0900 Subject: Fix unmatched parenthesis --- src/library/scala/reflect/api/Types.scala | 1 + src/library/scala/util/matching/Regex.scala | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala index 4cb5609166..e06bb37cba 100755 --- a/src/library/scala/reflect/api/Types.scala +++ b/src/library/scala/reflect/api/Types.scala @@ -269,6 +269,7 @@ trait Types { self: Universe => * (T # x).type SingleType(T, x) * p.x.type SingleType(p.type, x) * x.type SingleType(NoPrefix, x) + * }}} */ type SingleType <: SingletonType diff --git a/src/library/scala/util/matching/Regex.scala b/src/library/scala/util/matching/Regex.scala index 3f21cc9724..a83619cf01 100644 --- a/src/library/scala/util/matching/Regex.scala +++ b/src/library/scala/util/matching/Regex.scala @@ -204,7 +204,7 @@ class Regex(regex: String, groupNames: String*) extends Serializable { /** Return all matches of this regexp in given character sequence as a - * [[scala.collection.Iterator]] of [[scala.util.matching.Regex.Match]. + * [[scala.collection.Iterator]] of [[scala.util.matching.Regex.Match]]. * * @param source The text to match against. * @return A [[scala.collection.Iterator]] of [[scala.util.matching.Regex.Match]] for all matches. -- cgit v1.2.3 From 40e9fe51a5dbfbd17baac3474afc803d689a1adc Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 23 Apr 2012 19:51:25 -0700 Subject: Express flags as bit shifts. For those of us robots who still have a little human blood. --- src/compiler/scala/reflect/internal/Flags.scala | 114 ++++++++++++------------ 1 file changed, 57 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala index ce459bdd06..c6901d1cf6 100644 --- a/src/compiler/scala/reflect/internal/Flags.scala +++ b/src/compiler/scala/reflect/internal/Flags.scala @@ -83,40 +83,40 @@ import scala.collection.{ mutable, immutable } /** Flags set on Modifiers instances in the parsing stage. */ class ModifierFlags { - final val IMPLICIT = 0x00000200 - final val FINAL = 0x00000020 // May not be overridden. Note that java final implies much more than scala final. - final val PRIVATE = 0x00000004 - final val PROTECTED = 0x00000001 - - final val SEALED = 0x00000400 - final val OVERRIDE = 0x00000002 - final val CASE = 0x00000800 - final val ABSTRACT = 0x00000008 // abstract class, or used in conjunction with abstract override. + final val IMPLICIT = 1 << 9 + final val FINAL = 1 << 5 // May not be overridden. Note that java final implies much more than scala final. + final val PRIVATE = 1 << 2 + final val PROTECTED = 1 << 0 + + final val SEALED = 1 << 10 + final val OVERRIDE = 1 << 1 + final val CASE = 1 << 11 + final val ABSTRACT = 1 << 3 // abstract class, or used in conjunction with abstract override. // Note difference to DEFERRED! - final val DEFERRED = 0x00000010 // was `abstract' for members | trait is virtual - final val INTERFACE = 0x00000080 // symbol is an interface (i.e. a trait which defines only abstract methods) - final val MUTABLE = 0x00001000 // symbol is a mutable variable. - final val PARAM = 0x00002000 // symbol is a (value or type) parameter to a method - final val MACRO = 0x00008000 // symbol is a macro definition - - final val COVARIANT = 0x00010000 // symbol is a covariant type variable - final val BYNAMEPARAM = 0x00010000 // parameter is by name - final val CONTRAVARIANT = 0x00020000 // symbol is a contravariant type variable - final val ABSOVERRIDE = 0x00040000 // combination of abstract & override - final val LOCAL = 0x00080000 // symbol is local to current class (i.e. private[this] or protected[this] + final val DEFERRED = 1 << 4 // was `abstract' for members | trait is virtual + final val INTERFACE = 1 << 7 // symbol is an interface (i.e. a trait which defines only abstract methods) + final val MUTABLE = 1 << 12 // symbol is a mutable variable. + final val PARAM = 1 << 13 // symbol is a (value or type) parameter to a method + final val MACRO = 1 << 15 // symbol is a macro definition + + final val COVARIANT = 1 << 16 // symbol is a covariant type variable + final val BYNAMEPARAM = 1 << 16 // parameter is by name + final val CONTRAVARIANT = 1 << 17 // symbol is a contravariant type variable + final val ABSOVERRIDE = 1 << 18 // combination of abstract & override + final val LOCAL = 1 << 19 // symbol is local to current class (i.e. private[this] or protected[this] // pre: PRIVATE or PROTECTED are also set - final val JAVA = 0x00100000 // symbol was defined by a Java class - final val STATIC = 0x00800000 // static field, method or class - final val CASEACCESSOR = 0x01000000 // symbol is a case parameter (or its accessor, or a GADT skolem) - final val TRAIT = 0x02000000 // symbol is a trait - final val DEFAULTPARAM = 0x02000000 // the parameter has a default value - final val PARAMACCESSOR = 0x20000000 // for field definitions generated for primary constructor + final val JAVA = 1 << 20 // symbol was defined by a Java class + final val STATIC = 1 << 23 // static field, method or class + final val CASEACCESSOR = 1 << 24 // symbol is a case parameter (or its accessor, or a GADT skolem) + final val TRAIT = 1 << 25 // symbol is a trait + final val DEFAULTPARAM = 1 << 25 // the parameter has a default value + final val PARAMACCESSOR = 1 << 29 // for field definitions generated for primary constructor // parameters (no matter if it's a 'val' parameter or not) // for parameters of a primary constructor ('val' or not) // for the accessor methods generated for 'val' or 'var' parameters - final val LAZY = 0x80000000L // symbol is a lazy val. can't have MUTABLE unless transformed by typer - final val PRESUPER = 0x2000000000L // value is evaluated before super call - final val DEFAULTINIT = 0x20000000000L// symbol is initialized to the default value: used by -Xcheckinit + final val LAZY = 1L << 31 // symbol is a lazy val. can't have MUTABLE unless transformed by typer + final val PRESUPER = 1L << 37 // value is evaluated before super call + final val DEFAULTINIT = 1L << 41 // symbol is initialized to the default value: used by -Xcheckinit // Overridden. def flagToString(flag: Long): String = "" @@ -129,43 +129,43 @@ object ModifierFlags extends ModifierFlags /** All flags and associated operatins */ class Flags extends ModifierFlags { - final val METHOD = 0x00000040 // a method - final val MODULE = 0x00000100 // symbol is module or class implementing a module - final val PACKAGE = 0x00004000 // symbol is a java package - - final val CAPTURED = 0x00010000 // variable is accessed from nested function. Set by LambdaLift. - final val LABEL = 0x00020000 // method symbol is a label. Set by TailCall - final val INCONSTRUCTOR = 0x00020000 // class symbol is defined in this/superclass constructor. - final val SYNTHETIC = 0x00200000 // symbol is compiler-generated - final val STABLE = 0x00400000 // functions that are assumed to be stable + final val METHOD = 1 << 6 // a method + final val MODULE = 1 << 8 // symbol is module or class implementing a module + final val PACKAGE = 1 << 14 // symbol is a java package + + final val CAPTURED = 1 << 16 // variable is accessed from nested function. Set by LambdaLift. + final val LABEL = 1 << 17 // method symbol is a label. Set by TailCall + final val INCONSTRUCTOR = 1 << 17 // class symbol is defined in this/superclass constructor. + final val SYNTHETIC = 1 << 21 // symbol is compiler-generated + final val STABLE = 1 << 22 // functions that are assumed to be stable // (typically, access methods for valdefs) // or classes that do not contain abstract types. - final val BRIDGE = 0x04000000 // function is a bridge method. Set by Erasure - final val ACCESSOR = 0x08000000 // a value or variable accessor (getter or setter) + final val BRIDGE = 1 << 26 // function is a bridge method. Set by Erasure + final val ACCESSOR = 1 << 27 // a value or variable accessor (getter or setter) - final val SUPERACCESSOR = 0x10000000 // a super accessor - final val MODULEVAR = 0x40000000 // for variables: is the variable caching a module value + final val SUPERACCESSOR = 1 << 28 // a super accessor + final val MODULEVAR = 1 << 30 // for variables: is the variable caching a module value - final val IS_ERROR = 0x100000000L // symbol is an error symbol - final val OVERLOADED = 0x200000000L // symbol is overloaded - final val LIFTED = 0x400000000L // class has been lifted out to package level + final val IS_ERROR = 1L << 32 // symbol is an error symbol + final val OVERLOADED = 1L << 33 // symbol is overloaded + final val LIFTED = 1L << 34 // class has been lifted out to package level // local value has been lifted out to class level // todo: make LIFTED = latePRIVATE? - final val MIXEDIN = 0x800000000L // term member has been mixed in - final val EXISTENTIAL = 0x800000000L // type is an existential parameter or skolem - final val EXPANDEDNAME = 0x1000000000L // name has been expanded with class suffix - final val IMPLCLASS = 0x2000000000L // symbol is an implementation class - final val TRANS_FLAG = 0x4000000000L // transient flag guaranteed to be reset after each phase. + final val MIXEDIN = 1L << 35 // term member has been mixed in + final val EXISTENTIAL = 1L << 35 // type is an existential parameter or skolem + final val EXPANDEDNAME = 1L << 36 // name has been expanded with class suffix + final val IMPLCLASS = 1L << 37 // symbol is an implementation class + final val TRANS_FLAG = 1L << 38 // transient flag guaranteed to be reset after each phase. - final val LOCKED = 0x8000000000L // temporary flag to catch cyclic dependencies - final val SPECIALIZED = 0x10000000000L// symbol is a generated specialized member - final val VBRIDGE = 0x40000000000L// symbol is a varargs bridge + final val LOCKED = 1L << 39 // temporary flag to catch cyclic dependencies + final val SPECIALIZED = 1L << 40 // symbol is a generated specialized member + final val VBRIDGE = 1L << 42 // symbol is a varargs bridge - final val VARARGS = 0x80000000000L// symbol is a Java-style varargs method - final val TRIEDCOOKING = 0x100000000000L // ``Cooking'' has been tried on this symbol - // A Java method's type is ``cooked'' by transforming raw types to existentials + final val VARARGS = 1L << 43 // symbol is a Java-style varargs method + final val TRIEDCOOKING = 1L << 44 // ``Cooking'' has been tried on this symbol + // A Java method's type is ``cooked'' by transforming raw types to existentials - final val SYNCHRONIZED = 0x200000000000L // symbol is a method which should be marked ACC_SYNCHRONIZED + final val SYNCHRONIZED = 1L << 45 // symbol is a method which should be marked ACC_SYNCHRONIZED // ------- shift definitions ------------------------------------------------------- final val InitialFlags = 0x0001FFFFFFFFFFFFL // flags that are enabled from phase 1. -- cgit v1.2.3 From d9740f82a3aea3b223233776cd7c9460a2e4dfc3 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 24 Apr 2012 06:08:12 -0700 Subject: Back from the dead, it's ScalaObject! Trying to compile sbt with 2.10.0 reminded me that ScalaObject wasn't only a marker interface, it was a public trait in the library and has to be removed properly. "The ol' boy had a bit of life in him yet, 'e did." --- src/library/scala/ScalaObject.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/library/scala/ScalaObject.scala (limited to 'src') diff --git a/src/library/scala/ScalaObject.scala b/src/library/scala/ScalaObject.scala new file mode 100644 index 0000000000..7cd64becbe --- /dev/null +++ b/src/library/scala/ScalaObject.scala @@ -0,0 +1,16 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +/** Until scala 2.10.0 this marker trait was added to + * scala-compiled classes. Now it only exists for backward + * compatibility. + */ +@deprecated("ScalaObject will be removed", "2.10.0") +trait ScalaObject -- cgit v1.2.3 From 2890714d7bcdd55b7a62091dcdf031cc3efe0822 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 24 Apr 2012 15:59:58 +0200 Subject: generate well-formed patterns in parser val pattern: Type = expr desugared to val x = expr match { case pattern: Type => (var_1, ..., var_N)} but `pattern: Type` is only a valid pattern if `pattern` is an Ident thus, we desugar to val x = (expr: Type) match { case pattern => (var_1, ..., var_N)} ... in this case (see def makePatDef) also, MaybeBoundType now fails on illegal patterns (to defend against similar regressions) --- .../scala/tools/nsc/ast/parser/TreeBuilder.scala | 22 ++++++++++++++++++++-- .../tools/nsc/typechecker/PatMatVirtualiser.scala | 9 +++++---- test/files/run/virtpatmat_valdef.check | 1 + test/files/run/virtpatmat_valdef.scala | 6 ++++++ 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 test/files/run/virtpatmat_valdef.check create mode 100644 test/files/run/virtpatmat_valdef.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 3a6e26d3b5..de7e6f9c7a 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -521,11 +521,29 @@ abstract class TreeBuilder { // val/var x_1 = t$._1 // ... // val/var x_N = t$._N - val pat1 = patvarTransformer.transform(pat) + + val rhsUnchecked = gen.mkUnchecked(rhs) + + // TODO: clean this up -- there is too much information packked into makePatDef's `pat` argument + // when it's a simple identifier (case Some((name, tpt)) -- above), + // pat should have the type ascription that was specified by the user + // however, in `case None` (here), we must be careful not to generate illegal pattern trees (such as `(a, b): Tuple2[Int, String]`) + // i.e., this must hold: pat1 match { case Typed(expr, tp) => assert(expr.isInstanceOf[Ident]) case _ => } + // if we encounter such an erroneous pattern, we strip off the type ascription from pat and propagate the type information to rhs + val (pat1, rhs1) = patvarTransformer.transform(pat) match { + // move the Typed ascription to the rhs + case Typed(expr, tpt) if !expr.isInstanceOf[Ident] => + val rhsTypedUnchecked = + if (tpt.isEmpty) rhsUnchecked + else Typed(rhsUnchecked, tpt) setPos (rhs.pos union tpt.pos) + (expr, rhsTypedUnchecked) + case ok => + (ok, rhsUnchecked) + } val vars = getVariables(pat1) val matchExpr = atPos((pat1.pos union rhs.pos).makeTransparent) { Match( - gen.mkUnchecked(rhs), + rhs1, List( atPos(pat1.pos) { CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true)) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 02e53cb624..3be8397a9c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -260,10 +260,11 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer => * @arg patBinder symbol used to refer to the result of the previous pattern's extractor (will later be replaced by the outer tree with the correct tree to refer to that patterns result) */ def unapply(tree: Tree): Option[(Symbol, Type)] = tree match { - case Bound(subpatBinder, typed@Typed(expr, tpt)) if typed.tpe ne null => Some((subpatBinder, typed.tpe)) - case Bind(_, typed@Typed(expr, tpt)) if typed.tpe ne null => Some((patBinder, typed.tpe)) - case Typed(expr, tpt) if tree.tpe ne null => Some((patBinder, tree.tpe)) - case _ => None + // the Ident subpattern can be ignored, subpatBinder or patBinder tell us all we need to know about it + case Bound(subpatBinder, typed@Typed(Ident(_), tpt)) if typed.tpe ne null => Some((subpatBinder, typed.tpe)) + case Bind(_, typed@Typed(Ident(_), tpt)) if typed.tpe ne null => Some((patBinder, typed.tpe)) + case Typed(Ident(_), tpt) if tree.tpe ne null => Some((patBinder, tree.tpe)) + case _ => None } } diff --git a/test/files/run/virtpatmat_valdef.check b/test/files/run/virtpatmat_valdef.check new file mode 100644 index 0000000000..1a45335bd2 --- /dev/null +++ b/test/files/run/virtpatmat_valdef.check @@ -0,0 +1 @@ +meh(true,null) diff --git a/test/files/run/virtpatmat_valdef.scala b/test/files/run/virtpatmat_valdef.scala new file mode 100644 index 0000000000..f1a9b46cdd --- /dev/null +++ b/test/files/run/virtpatmat_valdef.scala @@ -0,0 +1,6 @@ +object Test extends App { + // patterns in valdefs... + // TODO: irrefutability should indicate we don't actually need to test, just deconstruct + val (modified, result) : (Boolean, String) = (true, null) + println("meh"+ (modified, result)) +} \ No newline at end of file -- cgit v1.2.3 From a47acbc36d312cc12ab02f4564edff1deb93d941 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 24 Apr 2012 18:40:12 +0200 Subject: copy BackQuotedIdent trees (don't copy as Ident) typer synthesized the wrong isDefinedAt method in typedMatchAnon because a BackQuotedIdent was copied as an Ident, so that the equality check was performed in applyOrElse (since it operates on the original tree), but not in isDefinedAt (since it operates on the copy, which collapsed Ident and BackQuotedIdent) --- src/compiler/scala/reflect/internal/TreePrinters.scala | 3 +++ .../scala/tools/nsc/typechecker/PatMatVirtualiser.scala | 3 ++- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 ++ src/library/scala/reflect/api/Trees.scala | 5 ++++- test/files/run/virtpatmat_partial_backquoted.check | 1 + test/files/run/virtpatmat_partial_backquoted.scala | 12 ++++++++++++ 6 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 test/files/run/virtpatmat_partial_backquoted.check create mode 100644 test/files/run/virtpatmat_partial_backquoted.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala index 486a3d3567..3093bb049a 100644 --- a/src/compiler/scala/reflect/internal/TreePrinters.scala +++ b/src/compiler/scala/reflect/internal/TreePrinters.scala @@ -373,6 +373,9 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => case Select(qualifier, name) => print(backquotedPath(qualifier), ".", symName(tree, name)) + case bqid: BackQuotedIdent => + print("`%s`" format symName(tree, bqid.name)) + case Ident(name) => print(symName(tree, name)) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 3be8397a9c..96d92e0609 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -136,7 +136,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer => // (that would require more sophistication when generating trees, // and the only place that emits Matches after typers is for exception handling anyway) if(phase.id >= currentRun.uncurryPhase.id) debugwarn("running translateMatch at "+ phase +" on "+ scrut +" match "+ cases) - + // println("translating "+ cases.mkString("{", "\n", "}")) val scrutSym = freshSym(scrut.pos, pureType(scrutType)) setFlag SYNTH_CASE // pt = Any* occurs when compiling test/files/pos/annotDepMethType.scala with -Xexperimental combineCases(scrut, scrutSym, cases map translateCase(scrutSym, pt), pt, matchOwner, matchFailGenOverride) @@ -987,6 +987,7 @@ class Foo(x: Other) { x._1 } // no error in this order fixerUpper(owner, scrut.pos){ val ptDefined = if (isFullyDefined(pt)) pt else NoType def matchFailGen = (matchFailGenOverride orElse Some(CODE.MATCHERROR(_: Tree))) + // println("combining cases: "+ (casesNoSubstOnly.map(_.mkString(" >> ")).mkString("{", "\n", "}"))) emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride).getOrElse{ if (casesNoSubstOnly nonEmpty) { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index ba6a363095..1414424a0b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2288,6 +2288,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser // need to duplicate the cases before typing them to generate the apply method, or the symbols will be all messed up val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => TRUE_typed).duplicate) else Nil + // println("casesTrue "+ casesTrue) def parentsPartial(targs: List[Type]) = List(appliedType(AbstractPartialFunctionClass.typeConstructor, targs), SerializableClass.tpe) def applyMethod = { @@ -2373,6 +2374,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser } val members = if (isPartial) { + // TODO: don't check for MarkerCPSTypes -- check whether all targs are subtype of any (which they are not under CPS) if ((MarkerCPSTypes ne NoSymbol) && (targs exists (_ hasAnnotation MarkerCPSTypes))) List(applyMethod, isDefinedAtMethod) else List(applyOrElseMethodDef, isDefinedAtMethod) } else List(applyMethod) diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 6e2e8261e7..2f6dc820a5 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -1171,7 +1171,10 @@ trait Trees { self: Universe => def Select(tree: Tree, qualifier: Tree, selector: Name) = new Select(qualifier, selector).copyAttrs(tree) def Ident(tree: Tree, name: Name) = - new Ident(name).copyAttrs(tree) + (tree match { + case _ : BackQuotedIdent => new BackQuotedIdent(name) + case _ => new Ident(name) + }).copyAttrs(tree) def ReferenceToBoxed(tree: Tree, idt: Ident) = new ReferenceToBoxed(idt).copyAttrs(tree) def Literal(tree: Tree, value: Constant) = diff --git a/test/files/run/virtpatmat_partial_backquoted.check b/test/files/run/virtpatmat_partial_backquoted.check new file mode 100644 index 0000000000..8ab8f29677 --- /dev/null +++ b/test/files/run/virtpatmat_partial_backquoted.check @@ -0,0 +1 @@ +Set(You got me!) diff --git a/test/files/run/virtpatmat_partial_backquoted.scala b/test/files/run/virtpatmat_partial_backquoted.scala new file mode 100644 index 0000000000..6d92229d6b --- /dev/null +++ b/test/files/run/virtpatmat_partial_backquoted.scala @@ -0,0 +1,12 @@ +object Test extends App { + class Region { override def toString = "You got me!" } + class SymbolType + case class SymbolInfo(tp: SymbolType, regions: List[Region], x: Any) + + def findRegionsWithSymbolType(rawSymbolInfos: Seq[SymbolInfo], symbolType: SymbolType): Set[Region] = + rawSymbolInfos.collect { case SymbolInfo(`symbolType`, regions, _) => regions }.flatten.toSet + + val stp = new SymbolType + val stp2 = new SymbolType + println(findRegionsWithSymbolType(List(SymbolInfo(stp2, List(), null), SymbolInfo(stp, List(new Region), null)), stp)) +} \ No newline at end of file -- cgit v1.2.3 From 996f96fb3f84b87d8761cb360d441a57a3db60ee Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 24 Apr 2012 19:18:12 +0200 Subject: TODO: use tree attachments instead of subclasses --- src/library/scala/reflect/api/Trees.scala | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 2f6dc820a5..b70ca7e0fd 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -663,10 +663,17 @@ trait Trees { self: Universe => def Apply(sym: Symbol, args: Tree*): Tree + // TODO remove this class, add a tree attachment to Apply to track whether implicits were involved + // copying trees will all too easily forget to distinguish subclasses class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args) + // TODO remove this class, add a tree attachment to Apply to track whether implicits were involved + // copying trees will all too easily forget to distinguish subclasses class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args) + // TODO: use a factory method, not a class (???) + // as a case in point of the comment that should go here by similarity to ApplyToImplicitArgs, + // this tree is considered in importers, but not in treecopier class ApplyConstructor(tpt: Tree, args: List[Tree]) extends Apply(Select(New(tpt), nme.CONSTRUCTOR), args) { override def printingPrefix = "ApplyConstructor" } @@ -718,6 +725,8 @@ trait Trees { self: Universe => def Ident(sym: Symbol): Ident + // TODO remove this class, add a tree attachment to Ident to track whether it was backquoted + // copying trees will all too easily forget to distinguish subclasses class BackQuotedIdent(name: Name) extends Ident(name) /** Marks underlying reference to id as boxed. @@ -1157,9 +1166,10 @@ trait Trees { self: Universe => def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = new TypeApply(fun, args).copyAttrs(tree) def Apply(tree: Tree, fun: Tree, args: List[Tree]) = - (tree match { + (tree match { // TODO: use a tree attachment to track whether this is an apply to implicit args or a view case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args) case _: ApplyImplicitView => new ApplyImplicitView(fun, args) + // TODO: ApplyConstructor ??? case _ => new Apply(fun, args) }).copyAttrs(tree) def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) = @@ -1171,7 +1181,7 @@ trait Trees { self: Universe => def Select(tree: Tree, qualifier: Tree, selector: Name) = new Select(qualifier, selector).copyAttrs(tree) def Ident(tree: Tree, name: Name) = - (tree match { + (tree match { // TODO: use a tree attachment to track whether this identifier was backquoted case _ : BackQuotedIdent => new BackQuotedIdent(name) case _ => new Ident(name) }).copyAttrs(tree) -- cgit v1.2.3 From f32d301fb556e006ae40b27175c4a4ca0e548616 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Tue, 24 Apr 2012 23:36:52 +0300 Subject: fixes SI-5704 --- src/compiler/scala/reflect/runtime/ToolBoxes.scala | 2 +- test/files/run/t5704.check | 1 + test/files/run/t5704.flags | 1 + test/files/run/t5704.scala | 16 ++++++++++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 test/files/run/t5704.check create mode 100644 test/files/run/t5704.flags create mode 100644 test/files/run/t5704.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala index 21a90326cf..7b1fc9fc0d 100644 --- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala +++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala @@ -113,7 +113,7 @@ trait ToolBoxes extends { self: Universe => override def transform(tree: Tree): Tree = tree match { case Ident(name) if reversedFreeTermNames contains name => - Ident(reversedFreeTermNames(name)) + Ident(reversedFreeTermNames(name)) setType tree.tpe case _ => super.transform(tree) } diff --git a/test/files/run/t5704.check b/test/files/run/t5704.check new file mode 100644 index 0000000000..7b56bf2bfd --- /dev/null +++ b/test/files/run/t5704.check @@ -0,0 +1 @@ +String \ No newline at end of file diff --git a/test/files/run/t5704.flags b/test/files/run/t5704.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/t5704.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/t5704.scala b/test/files/run/t5704.scala new file mode 100644 index 0000000000..25a6575dc3 --- /dev/null +++ b/test/files/run/t5704.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + class MyQuerycollection{ + def findUserByName( name:String ) = { + val tree = reify{ "test" == name } + val toolbox = mkToolBox() + toolbox.typeCheck(tree) match{ + case Apply(Select(lhs,op),rhs::Nil) => + println(rhs.tpe) + } + } + } + val qc = new MyQuerycollection + qc.findUserByName("some value") +} -- cgit v1.2.3 From 211df62491ada71a4a574fd2314942ab3c4a4ba8 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 20 Apr 2012 08:00:07 +0100 Subject: Reordering genBlock match cases by frequency. --- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 104 ++++++++++++++------- 1 file changed, 68 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index f7898f2aa2..68996fbdfc 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1311,6 +1311,40 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } + // Collected frequency of opcdes to determine case ordering: + // + // 47514 CALL_METHOD + // 43434 LOAD_LOCAL + // 38572 THIS + // 31207 RETURN + // 5832 JUMP + // 5395 CONSTANT + // 5010 LOAD_FIELD + // 4731 STORE_LOCAL + // 4252 DUP + // 3612 NEW + // 3519 CZJUMP + // 2938 SCOPE_ENTER + // 2900 CALL_PRIMITIVE + // 2884 STORE_FIELD + // 2881 CHECK_CAST + // 2459 LOAD_MODULE + // 1783 SCOPE_EXIT + // 1315 CJUMP + // 1305 THROW + // 1030 DROP + // 485 BOX + // 468 UNBOX + // 464 MONITOR_EXIT + // 434 IS_INSTANCE + // 428 STORE_ARRAY_ITEM + // 329 LOAD_ARRAY_ITEM + // 280 CREATE_ARRAY + // 253 LOAD_EXCEPTION + // 232 MONITOR_ENTER + // 37 STORE_THIS + // 19 SWITCH + def genBlock(b: BasicBlock) { labels(b).anchorToNext() @@ -1324,11 +1358,43 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with val lastInstr = b.lastInstruction for (instr <- b) { + println(instr.getClass) instr match { - case THIS(clasz) => jcode.emitALOAD_0() + case call @ CALL_METHOD(method, style) => + /** Special handling to access native Array.clone() */ + if (method == definitions.Array_clone && style == Dynamic) { + val target = javaType(call.targetTypeKind).getSignature() + jcode.emitINVOKEVIRTUAL(target, "clone", arrayCloneType) + } + else genCallMethod(call) + + case LOAD_LOCAL(local) => jcode.emitLOAD(indexOf(local), javaType(local.kind)) + case THIS(clasz) => jcode.emitALOAD_0() + case RETURN(kind) => jcode emitRETURN javaType(kind) - case CONSTANT(const) => genConstant(jcode, const) + case CONSTANT(const) => genConstant(jcode, const) + case JUMP(whereto) => + if (nextBlock != whereto) + jcode.emitGOTO_maybe_W(labels(whereto), false) // default to short jumps + + case lf @ LOAD_FIELD(field, isStatic) => + var owner = javaName(lf.hostClass) + debuglog("LOAD_FIELD with owner: " + owner + " flags: " + Flags.flagsToString(field.owner.flags)) + val fieldJName = javaName(field) + val fieldJType = javaType(field) + if (isStatic) jcode.emitGETSTATIC(owner, fieldJName, fieldJType) + else jcode.emitGETFIELD( owner, fieldJName, fieldJType) + + case STORE_LOCAL(local) => + jcode.emitSTORE(indexOf(local), javaType(local.kind)) + + case DUP(kind) => + if(kind.isWideType) jcode.emitDUP2() + else jcode.emitDUP() + + case NEW(REFERENCE(cls)) => + jcode emitNEW javaName(cls) case LOAD_ARRAY_ITEM(kind) => if(kind.isRefOrArrayType) { jcode.emitAALOAD() } @@ -1345,17 +1411,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } - case LOAD_LOCAL(local) => jcode.emitLOAD(indexOf(local), javaType(local.kind)) - - case lf @ LOAD_FIELD(field, isStatic) => - var owner = javaName(lf.hostClass) - debuglog("LOAD_FIELD with owner: " + owner + - " flags: " + Flags.flagsToString(field.owner.flags)) - val fieldJName = javaName(field) - val fieldJType = javaType(field) - if (isStatic) jcode.emitGETSTATIC(owner, fieldJName, fieldJType) - else jcode.emitGETFIELD( owner, fieldJName, fieldJType) - case LOAD_MODULE(module) => // assert(module.isModule, "Expected module: " + module) debuglog("generating LOAD_MODULE for: " + module + " flags: " + Flags.flagsToString(module.flags)); @@ -1381,9 +1436,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } - case STORE_LOCAL(local) => - jcode.emitSTORE(indexOf(local), javaType(local.kind)) - case STORE_THIS(_) => // this only works for impl classes because the self parameter comes first // in the method signature. If that changes, this code has to be revisited. @@ -1398,13 +1450,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with case CALL_PRIMITIVE(primitive) => genPrimitive(primitive, instr.pos) - /** Special handling to access native Array.clone() */ - case call @ CALL_METHOD(definitions.Array_clone, Dynamic) => - val target: String = javaType(call.targetTypeKind).getSignature() - jcode.emitINVOKEVIRTUAL(target, "clone", arrayCloneType) - - case call @ CALL_METHOD(method, style) => genCallMethod(call) - case BOX(kind) => val Pair(mname, mtype) = jBoxTo(kind) jcode.emitINVOKESTATIC(BoxesRunTime, mname, mtype) @@ -1413,10 +1458,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with val Pair(mname, mtype) = jUnboxTo(kind) jcode.emitINVOKESTATIC(BoxesRunTime, mname, mtype) - case NEW(REFERENCE(cls)) => - val className = javaName(cls) - jcode emitNEW className - case CREATE_ARRAY(elem, 1) => if(elem.isRefOrArrayType) { jcode emitANEWARRAY javaType(elem).asInstanceOf[JReferenceType] } else { jcode emitNEWARRAY javaType(elem) } @@ -1462,10 +1503,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with MIN_SWITCH_DENSITY) () - case JUMP(whereto) => - if (nextBlock != whereto) - jcode.emitGOTO_maybe_W(labels(whereto), false) // default to short jumps - case CJUMP(success, failure, cond, kind) => if(kind.isIntSizedType) { // BOOL, BYTE, CHAR, SHORT, or INT if (nextBlock == success) { @@ -1552,7 +1589,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } - case RETURN(kind) => jcode emitRETURN javaType(kind) case THROW(_) => jcode.emitATHROW() @@ -1560,10 +1596,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with if(kind.isWideType) jcode.emitPOP2() else jcode.emitPOP() - case DUP(kind) => - if(kind.isWideType) jcode.emitDUP2() - else jcode.emitDUP() - case MONITOR_ENTER() => jcode.emitMONITORENTER() case MONITOR_EXIT() => jcode.emitMONITOREXIT() -- cgit v1.2.3 From 1d0372f84f9a7325a47beb55169cc454895ef74b Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 20 Apr 2012 01:00:24 +0100 Subject: Moved ancillary methods off specialized traits. Moved compose/andThen off Function1, curried/tupled off Function2. Pushed Tuple2 zipped into auxiliary class. Created implicits to plaster over the changes. This drops several hundred classfiles and takes (unoptimized) scala-library.jar from 7.8 Mb to 7.4 Mb. --- src/build/genprod.scala | 132 ++------------------- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 2 - src/library/scala/Function0.scala | 2 +- src/library/scala/Function1.scala | 16 --- src/library/scala/Function2.scala | 14 --- src/library/scala/PartialFunction.scala | 2 +- src/library/scala/Predef.scala | 8 +- src/library/scala/Tuple2.scala | 114 ------------------ src/library/scala/Tuple3.scala | 11 -- src/library/scala/runtime/RichFunction1.scala | 27 +++++ src/library/scala/runtime/RichFunction2.scala | 26 ++++ src/library/scala/runtime/Tuple2Zipped.scala | 109 +++++++++++++++++ test/files/neg/t5067.check | 8 +- test/files/neg/t5067.scala | 6 +- test/files/run/tuple-zipped.scala | 2 +- 15 files changed, 183 insertions(+), 296 deletions(-) create mode 100644 src/library/scala/runtime/RichFunction1.scala create mode 100644 src/library/scala/runtime/RichFunction2.scala create mode 100644 src/library/scala/runtime/Tuple2Zipped.scala (limited to 'src') diff --git a/src/build/genprod.scala b/src/build/genprod.scala index 1ea0bf7b73..8a5c44f1c1 100644 --- a/src/build/genprod.scala +++ b/src/build/genprod.scala @@ -123,23 +123,7 @@ object FunctionOne extends Function(1) { * assert(succ(0) == anonfun1(0)) * """) - override def moreMethods = """ - /** Composes two instances of Function1 in a new Function1, with this function applied last. - * - * @tparam A the type to which function `g` can be applied - * @param g a function A => T1 - * @return a new function `f` such that `f(x) == apply(g(x))` - */ - def compose[A](g: A => T1): A => R = { x => apply(g(x)) } - - /** Composes two instances of Function1 in a new Function1, with this function applied first. - * - * @tparam A the result type of function `g` - * @param g a function R => A - * @return a new function `f` such that `f(x) == g(apply(x))` - */ - def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } -""" + override def moreMethods = "" } object FunctionTwo extends Function(2) { @@ -155,6 +139,8 @@ object FunctionTwo extends Function(2) { * } * assert(max(0, 1) == anonfun2(0, 1)) * """) + + override def moreMethods = "" } object Function { @@ -255,11 +241,6 @@ class Function(val i: Int) extends Group("Function") with Arity { zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz */ object Tuple { - val zipImports = """ -import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } -import scala.collection.generic.{ CanBuildFrom => CBF } -""" - def make(i: Int) = apply(i)() def apply(i: Int) = i match { case 1 => TupleOne @@ -276,7 +257,6 @@ object TupleOne extends Tuple(1) object TupleTwo extends Tuple(2) { - override def imports = Tuple.zipImports override def covariantSpecs = "@specialized(Int, Long, Double, Char, Boolean, AnyRef) " override def moreMethods = """ /** Swaps the elements of this `Tuple`. @@ -284,112 +264,14 @@ object TupleTwo extends Tuple(2) * second element is the first element of this Tuple. */ def swap: Tuple2[T2,T1] = Tuple2(_2, _1) - - @deprecated("Use `zipped` instead.", "2.9.0") - def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], - w2: T2 => Iterable[El2], - cbf1: CBF[Repr1, (El1, El2), To]): To = { - zipped map ((x, y) => ((x, y))) - } - - /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. - * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] - * or [[scala.collection.IterableLike]]. - * {{{ - * scala> val tuple = (List(1,2,3),List('a','b','c')) - * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) - * - * scala> tuple.zipped map { (x,y) => x + ":" + y } - * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) - * }}} - * - * @see Zipped - * Note: will not terminate for infinite-sized collections. - */ - 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) - - 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) - b.sizeHint(coll1) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b += f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b ++= f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { - val b1 = cbf1(coll1.repr) - val b2 = cbf2(coll2.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - val el2 = elems2.next - if (f(el1, el2)) { - b1 += el1 - b2 += el2 - } - } - else return (b1.result, b2.result) - } - - (b1.result, b2.result) - } - - def exists(f: (El1, El2) => Boolean): Boolean = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - if (f(el1, elems2.next)) - return true - } - else return false - } - false - } - - def forall(f: (El1, El2) => Boolean): Boolean = - !exists((x, y) => !f(x, y)) - - def foreach[U](f: (El1, El2) => U): Unit = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - f(el1, elems2.next) - else - return - } - } - } """ } object TupleThree extends Tuple(3) { - override def imports = Tuple.zipImports + override def imports = """ +import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } +import scala.collection.generic.{ CanBuildFrom => CBF } + """ override def moreMethods = """ @deprecated("Use `zipped` instead.", "2.9.0") diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 68996fbdfc..ac5814f4f2 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1358,8 +1358,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with val lastInstr = b.lastInstruction for (instr <- b) { - println(instr.getClass) - instr match { case call @ CALL_METHOD(method, style) => /** Special handling to access native Array.clone() */ diff --git a/src/library/scala/Function0.scala b/src/library/scala/Function0.scala index dceed26439..cc17f8797a 100644 --- a/src/library/scala/Function0.scala +++ b/src/library/scala/Function0.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ // GENERATED CODE: DO NOT EDIT. -// genprod generated these sources at: Tue Feb 14 16:49:03 PST 2012 +// genprod generated these sources at: Tue Apr 24 16:32:13 PDT 2012 package scala diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala index 8995ef912b..a4391c1509 100644 --- a/src/library/scala/Function1.scala +++ b/src/library/scala/Function1.scala @@ -38,21 +38,5 @@ trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, s */ def apply(v1: T1): R - /** Composes two instances of Function1 in a new Function1, with this function applied last. - * - * @tparam A the type to which function `g` can be applied - * @param g a function A => T1 - * @return a new function `f` such that `f(x) == apply(g(x))` - */ - def compose[A](g: A => T1): A => R = { x => apply(g(x)) } - - /** Composes two instances of Function1 in a new Function1, with this function applied first. - * - * @tparam A the result type of function `g` - * @param g a function R => A - * @return a new function `f` such that `f(x) == g(apply(x))` - */ - def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } - override def toString() = "" } diff --git a/src/library/scala/Function2.scala b/src/library/scala/Function2.scala index cacb96ef5d..5ea2b411bb 100644 --- a/src/library/scala/Function2.scala +++ b/src/library/scala/Function2.scala @@ -37,20 +37,6 @@ trait Function2[@specialized(scala.Int, scala.Long, scala.Double) -T1, @speciali * @return the result of function application. */ def apply(v1: T1, v2: T2): R - /** Creates a curried version of this function. - * - * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)` - */ def curried: T1 => T2 => R = { - (x1: T1) => (x2: T2) => apply(x1, x2) - } - /** Creates a tupled version of this function: instead of 2 arguments, - * it accepts a single [[scala.Tuple2]] argument. - * - * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)` - */ - def tupled: Tuple2[T1, T2] => R = { - case Tuple2(x1, x2) => apply(x1, x2) - } override def toString() = "" } diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index 7154b8da34..fafaef9c2f 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -78,7 +78,7 @@ trait PartialFunction[-A, +B] extends (A => B) { self => * @return a partial function with the same domain as this partial function, which maps * arguments `x` to `k(this(x))`. */ - override def andThen[C](k: B => C) : PartialFunction[A, C] = new PartialFunction[A, C] { + def andThen[C](k: B => C) : PartialFunction[A, C] = new PartialFunction[A, C] { def isDefinedAt(x: A): Boolean = self isDefinedAt x def apply(x: A): C = k(self(x)) } diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index d2aa3a8b34..96b8b6d8d5 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -308,11 +308,11 @@ object Predef extends LowPriorityImplicits { // views -------------------------------------------------------------- implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc) + implicit def function1ToRichFunction1[T, R](f: T => R): runtime.RichFunction1[T, R] = new runtime.RichFunction1(f) + implicit def function2ToRichFunction2[T1, T2, R](f: (T1, T2) => R): runtime.RichFunction2[T1, T2, R] = + new runtime.RichFunction2(f) - implicit def zipped2ToTraversable[El1, El2](zz: Tuple2[_, _]#Zipped[_, El1, _, El2]): Traversable[(El1, El2)] = - new collection.AbstractTraversable[(El1, El2)] { - def foreach[U](f: ((El1, El2)) => U): Unit = zz foreach Function.untupled(f) - } + implicit def tuple2ToZipped[T1, T2](zz: (T1, T2)) = new runtime.Tuple2ZippedOps(zz) implicit def zipped3ToTraversable[El1, El2, El3](zz: Tuple3[_, _, _]#Zipped[_, El1, _, El2, _, El3]): Traversable[(El1, El2, El3)] = new collection.AbstractTraversable[(El1, El2, El3)] { diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 37ab564c3c..924b2b6fe3 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -9,9 +9,6 @@ package scala -import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } -import scala.collection.generic.{ CanBuildFrom => CBF } - /** A tuple of 2 elements; the canonical representation of a [[scala.Product2]]. * @@ -30,115 +27,4 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s */ def swap: Tuple2[T2,T1] = Tuple2(_2, _1) - @deprecated("Use `zipped` instead.", "2.9.0") - def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], - w2: T2 => Iterable[El2], - cbf1: CBF[Repr1, (El1, El2), To]): To = { - zipped map ((x, y) => ((x, y))) - } - - /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. - * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] - * or [[scala.collection.IterableLike]]. - * {{{ - * scala> val tuple = (List(1,2,3),List('a','b','c')) - * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) - * - * scala> tuple.zipped map { (x,y) => x + ":" + y } - * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) - * }}} - * - * @see Zipped - * Note: will not terminate for infinite-sized collections. - */ - 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) - b.sizeHint(coll1) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b += f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b ++= f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { - val b1 = cbf1(coll1.repr) - val b2 = cbf2(coll2.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - val el2 = elems2.next - if (f(el1, el2)) { - b1 += el1 - b2 += el2 - } - } - else return (b1.result, b2.result) - } - - (b1.result, b2.result) - } - - def exists(f: (El1, El2) => Boolean): Boolean = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - if (f(el1, elems2.next)) - return true - } - else return false - } - false - } - - def forall(f: (El1, El2) => Boolean): Boolean = - !exists((x, y) => !f(x, y)) - - def foreach[U](f: (El1, El2) => U): Unit = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - f(el1, elems2.next) - else - return - } - } - } - } diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index cd5ee23757..dfa0c962a2 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -53,17 +53,6 @@ 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/library/scala/runtime/RichFunction1.scala b/src/library/scala/runtime/RichFunction1.scala new file mode 100644 index 0000000000..26651b8d6a --- /dev/null +++ b/src/library/scala/runtime/RichFunction1.scala @@ -0,0 +1,27 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.runtime + +@inline final class RichFunction1[-T1, +R](f: T1 => R) { + /** Composes two instances of Function1 in a new Function1, with the function on the left applied last. + * + * @tparam A the type to which function `g` can be applied + * @param g a function A => T1 + * @return a new function `h` such that `h(x) == f(g(x))` + */ + def compose[A](g: A => T1): A => R = { x => f(g(x)) } + + /** Composes two instances of Function1 in a new Function1, with the function on the left applied first. + * + * @tparam A the result type of function `g` + * @param g a function R => A + * @return a new function `h` such that `h(x) == g(f(x))` + */ + def andThen[A](g: R => A): T1 => A = { x => g(f(x)) } +} diff --git a/src/library/scala/runtime/RichFunction2.scala b/src/library/scala/runtime/RichFunction2.scala new file mode 100644 index 0000000000..14e23be31b --- /dev/null +++ b/src/library/scala/runtime/RichFunction2.scala @@ -0,0 +1,26 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.runtime + +@inline final class RichFunction2[-T1, -T2, +R](f: (T1, T2) => R) { + /** Creates a curried version of this function. + * + * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)` + */ + def curried: T1 => T2 => R = (x1: T1) => (x2: T2) => f(x1, x2) + + /** Creates a tupled version of this function: instead of 2 arguments, + * it accepts a single [[scala.Tuple2]] argument. + * + * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)` + */ + def tupled: ((T1, T2)) => R = { + case Tuple2(x1, x2) => f(x1, x2) + } +} diff --git a/src/library/scala/runtime/Tuple2Zipped.scala b/src/library/scala/runtime/Tuple2Zipped.scala new file mode 100644 index 0000000000..2eb2a47e46 --- /dev/null +++ b/src/library/scala/runtime/Tuple2Zipped.scala @@ -0,0 +1,109 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.runtime + +import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } +import scala.collection.generic.{ CanBuildFrom => CBF } + + /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. + * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] + * or [[scala.collection.IterableLike]]. + * {{{ + * scala> val tuple = (List(1,2,3),List('a','b','c')) + * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) + * + * scala> tuple.zipped map { (x,y) => x + ":" + y } + * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) + * }}} + * + * @see Zipped + * Note: will not terminate for infinite-sized collections. + */ +@inline private[scala] final class Tuple2Zipped[+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) + b.sizeHint(coll1) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b += f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b ++= f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { + val b1 = cbf1(coll1.repr) + val b2 = cbf2(coll2.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + val el2 = elems2.next + if (f(el1, el2)) { + b1 += el1 + b2 += el2 + } + } + else return (b1.result, b2.result) + } + + (b1.result, b2.result) + } + + def exists(f: (El1, El2) => Boolean): Boolean = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + if (f(el1, elems2.next)) + return true + } + else return false + } + false + } + + def forall(f: (El1, El2) => Boolean): Boolean = + !exists((x, y) => !f(x, y)) + + def foreach[U](f: (El1, El2) => U): Unit = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + f(el1, elems2.next) + else + return + } + } +} + +@inline private[scala] final class Tuple2ZippedOps[T1, T2](zz: (T1, T2)) { + def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]) = + new Tuple2Zipped[Repr1, El1, Repr2, El2](w1(zz._1), w2(zz._2)) +} diff --git a/test/files/neg/t5067.check b/test/files/neg/t5067.check index 32491766d7..395eda7442 100644 --- a/test/files/neg/t5067.check +++ b/test/files/neg/t5067.check @@ -1,6 +1,6 @@ t5067.scala:3: error: type mismatch; - found : ((Int, Int)) => Int - required: (Int, Int) => Int - override def tupled: (Int, Int) => Int = super.tupled - ^ + found : ((Int, Int, Int)) => Int + required: (Int, Int, Int) => Int + override def tupled: (Int, Int, Int) => Int = super.tupled + ^ one error found diff --git a/test/files/neg/t5067.scala b/test/files/neg/t5067.scala index f8235c0e83..0a961d2f40 100644 --- a/test/files/neg/t5067.scala +++ b/test/files/neg/t5067.scala @@ -1,4 +1,4 @@ -class Foo extends Function2[Int, Int, Int] { - def apply(x: Int, y: Int) = x + y - override def tupled: (Int, Int) => Int = super.tupled +class Foo extends Function3[Int, Int, Int, Int] { + def apply(x: Int, y: Int, z: Int) = x + y + z + override def tupled: (Int, Int, Int) => Int = super.tupled } diff --git a/test/files/run/tuple-zipped.scala b/test/files/run/tuple-zipped.scala index a9851346bc..08dcc82de6 100644 --- a/test/files/run/tuple-zipped.scala +++ b/test/files/run/tuple-zipped.scala @@ -15,7 +15,7 @@ object Test { def main(args: Array[String]): Unit = { for (cc1 <- xss1 ; cc2 <- xss2) { - val sum1 = (cc1, cc2).zip map { case (x, y) => x + y } sum + val sum1 = (cc1 zip cc2) map { case (x, y) => x + y } sum val sum2 = (cc1, cc2).zipped map (_ + _) sum assert(sum1 == sum2) -- cgit v1.2.3 From 0a24981d0a71627e541d283b9f739e09a7eab550 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 25 Apr 2012 13:30:51 +0300 Subject: fixes SI-5706 --- src/compiler/scala/tools/nsc/typechecker/Macros.scala | 1 + test/files/pos/t5706.flags | 1 + test/files/pos/t5706.scala | 10 ++++++++++ 3 files changed, 12 insertions(+) create mode 100644 test/files/pos/t5706.flags create mode 100644 test/files/pos/t5706.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 5d4cd0be77..4e4c52e0f7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -388,6 +388,7 @@ trait Macros { self: Analyzer => 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) + atpe = atpe.dealias // SI-5706 // 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 diff --git a/test/files/pos/t5706.flags b/test/files/pos/t5706.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/pos/t5706.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/pos/t5706.scala b/test/files/pos/t5706.scala new file mode 100644 index 0000000000..847acb693f --- /dev/null +++ b/test/files/pos/t5706.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.Context + +class Logger { + def error(message: String) = macro Impls.error +} + +object Impls { + type LoggerContext = Context { type PrefixType = Logger } + def error(c: LoggerContext)(message: c.Expr[String]): c.Expr[Unit] = ??? +} -- cgit v1.2.3 From bf621aa912ec76ba5794280b88f62d0861aa530d Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 25 Apr 2012 15:49:27 +0300 Subject: fixes SI-5707 --- src/compiler/scala/reflect/internal/Definitions.scala | 4 ++-- src/compiler/scala/reflect/internal/TreeInfo.scala | 2 +- src/library/scala/reflect/makro/Reifiers.scala | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 6cb935edad..2b6607e23e 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -493,8 +493,8 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val NoManifest = getRequiredModule("scala.reflect.NoManifest") lazy val ExprClass = getMember(getRequiredClass("scala.reflect.api.Exprs"), tpnme.Expr) - def ExprTree = getMemberClass(ExprClass, nme.tree) - def ExprTpe = getMemberClass(ExprClass, nme.tpe) + 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) diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index 48dfe8bcfc..f4878139e9 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -602,7 +602,7 @@ abstract class TreeInfo { object ReifiedTree { 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 => + case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(Apply(_, List(tree)), List(Apply(_, tpe :: _)))) if mrDef.name == nme.MIRROR_SHORT => Some(reifee, symbolTable, tree, tpe) case _ => None diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala index ae6669946c..b1de8d9957 100644 --- a/src/library/scala/reflect/makro/Reifiers.scala +++ b/src/library/scala/reflect/makro/Reifiers.scala @@ -74,4 +74,4 @@ trait Reifiers { case class ReificationError(var pos: reflect.api.Position, val msg: String) extends Throwable(msg) -case class UnexpectedReificationError(val pos: reflect.api.Position, val msg: String, val cause: Throwable = null) extends Throwable(msg) \ No newline at end of file +case class UnexpectedReificationError(val pos: reflect.api.Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause) \ No newline at end of file -- cgit v1.2.3 From edc7071d3b284fcf82bd17c7a1cf83f23e32788f Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 25 Apr 2012 06:43:45 -0700 Subject: Fix reifier crashing repl. Very first time I tried "reify" in the repl and it crashed. I changed an assert to issue a proper error, as best I could figure out how. We probably need to do a lot more of this. --- .../tools/nsc/typechecker/ContextErrors.scala | 5 ++++ .../scala/tools/nsc/typechecker/Macros.scala | 34 ++++++++++++---------- test/files/run/reify-repl-fail-gracefully.check | 21 +++++++++++++ test/files/run/reify-repl-fail-gracefully.scala | 10 +++++++ 4 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 test/files/run/reify-repl-fail-gracefully.check create mode 100644 test/files/run/reify-repl-fail-gracefully.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index c13be0e39d..2d1369b11d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -343,6 +343,11 @@ trait ContextErrors { issueNormalTypeError(tree, "macros cannot be eta-expanded") setError(tree) } + + def MacroPartialApplicationError(tree: Tree) = { + issueNormalTypeError(tree, "macros cannot be partially applied") + setError(tree) + } //typedReturn def ReturnOutsideOfDefError(tree: Tree) = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 5d4cd0be77..4d35549773 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -855,7 +855,7 @@ trait Macros { self: Analyzer => val numParamLists = paramss_without_evidences.length val numArgLists = argss.length if (numParamLists != numArgLists) { - typer.context.error(expandee.pos, "macros cannot be partially applied") + typer.TyperErrorGen.MacroPartialApplicationError(expandee) return None } @@ -953,6 +953,11 @@ trait Macros { self: Analyzer => * the expandee with an error marker set if there has been an error */ def macroExpand(typer: Typer, expandee: Tree, mode: Int = EXPRmode, pt: Type = WildcardType): Tree = { + def fail(what: String, tree: Tree): Tree = { + val err = typer.context.errBuffer.head + this.fail(typer, tree, "failed to perform %s: %s at %s".format(what, err.errMsg, err.errPos)) + return expandee + } val start = startTimer(macroExpandNanos) incCounter(macroExpandCount) try { @@ -979,15 +984,9 @@ trait Macros { self: Analyzer => case _ => ; } - def fail(what: String): Tree = { - val err = typer.context.errBuffer.head - this.fail(typer, expanded, "failed to perform %s: %s at %s".format(what, err.errMsg, err.errPos)) - return expandee - } - if (macroDebug) println("typechecking1 against %s: %s".format(expectedTpe, expanded)) var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe)) - if (typer.context.hasErrors) fail("typecheck1") + if (typer.context.hasErrors) fail("typecheck1", expanded) if (macroDebug) { println("typechecked1:") println(typechecked) @@ -996,7 +995,7 @@ trait Macros { self: Analyzer => if (macroDebug) println("typechecking2 against %s: %s".format(pt, expanded)) typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt)) - if (typer.context.hasErrors) fail("typecheck2") + if (typer.context.hasErrors) fail("typecheck2", expanded) if (macroDebug) { println("typechecked2:") println(typechecked) @@ -1009,13 +1008,16 @@ trait Macros { self: Analyzer => } case Delay(expandee) => // need to save the context to preserve enclosures - val args = macroArgs(typer, expandee) - assert(args.isDefined, expandee) - val context = args.get.head.asInstanceOf[MacroContext] - var result = expandee withAttachment MacroAttachment(delayed = true, context = Some(context)) - // adapting here would be premature, we must wait until undetparams are inferred -// result = typer.adapt(result, mode, pt) - result + macroArgs(typer, expandee) match { + case Some((context: MacroContext) :: _) => + // adapting here would be premature, we must wait until undetparams are inferred + expandee withAttachment MacroAttachment(delayed = true, context = Some(context)) + case _ => + // !!! The correct place to issue an error needs to be clarified. + // I have the else condition here only as a fallback. + if (expandee.isErroneous) expandee + else fail("macros cannot be partially applied", expandee) + } case Fallback(fallback) => typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt)) case Other(result) => diff --git a/test/files/run/reify-repl-fail-gracefully.check b/test/files/run/reify-repl-fail-gracefully.check new file mode 100644 index 0000000000..680db12667 --- /dev/null +++ b/test/files/run/reify-repl-fail-gracefully.check @@ -0,0 +1,21 @@ +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.mirror._ +import scala.reflect.mirror._ + +scala> + +scala> reify +:12: error: macros cannot be partially applied + reify + ^ + +scala> + +scala> diff --git a/test/files/run/reify-repl-fail-gracefully.scala b/test/files/run/reify-repl-fail-gracefully.scala new file mode 100644 index 0000000000..d7a06e8da8 --- /dev/null +++ b/test/files/run/reify-repl-fail-gracefully.scala @@ -0,0 +1,10 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = """ + |import language.experimental.macros + |import scala.reflect.mirror._ + | + |reify + """.stripMargin +} -- cgit v1.2.3 From ef48117f4e408da8e62624e4f3efebf7233fb741 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Wed, 25 Apr 2012 16:19:50 +0200 Subject: don't translate matches in the IDE --- .../scala/tools/nsc/typechecker/PatMatVirtualiser.scala | 4 ++-- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 96d92e0609..56830339bc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -46,7 +46,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer => val outer = newTermName("") val runOrElse = newTermName("runOrElse") val zero = newTermName("zero") - val _match = newTermName("__match") // don't call it __match, since that will trigger virtual pattern matching... + val _match = newTermName("__match") // don't call the val __match, since that will trigger virtual pattern matching... def counted(str: String, i: Int) = newTermName(str+i) } @@ -1067,7 +1067,7 @@ class Foo(x: Other) { x._1 } // no error in this order // assert(owner ne null); assert(owner ne NoSymbol) def freshSym(pos: Position, tp: Type = NoType, prefix: String = "x") = - NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo /*repackExistential*/(tp) + NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo tp // codegen relevant to the structure of the translation (how extractors are combined) trait AbsCodegen { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1414424a0b..5c40576559 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -83,6 +83,9 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser private def isPastTyper = phase.id > currentRun.typerPhase.id + // don't translate matches in presentation compiler: it loses vital symbols that are needed to do hyperlinking + @inline private def doMatchTranslation = !forInteractive && opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id) + abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with Tagging with TyperContextErrors { import context0.unit import typeDebug.{ ptTree, ptBlock, ptLine } @@ -2436,7 +2439,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser fun.body match { // later phase indicates scaladoc is calling (where shit is messed up, I tell you) // -- so fall back to old patmat, which is more forgiving - case Match(sel, cases) if opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id) => + case Match(sel, cases) if doMatchTranslation => // 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) @@ -3830,7 +3833,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser } def typedTranslatedMatch(tree: Tree, selector: Tree, cases: List[CaseDef]): Tree = { - if (opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id)) { + if (doMatchTranslation) { if (selector ne EmptyTree) { val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = typedMatch(selector, cases, mode, pt) typed(translatedMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt) @@ -4734,9 +4737,8 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser catches1 = catches1 map (adaptCase(_, mode, owntype)) } - if((phase.id < currentRun.uncurryPhase.id) && opt.virtPatmat) { + if (doMatchTranslation) catches1 = (MatchTranslator(this)).translateTry(catches1, owntype, tree.pos) - } treeCopy.Try(tree, block1, catches1, finalizer1) setType owntype -- cgit v1.2.3 From daeee868956faaa92c4ea873e0c6b24b52202ee7 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Wed, 25 Apr 2012 16:29:53 +0200 Subject: fail gracefully on very messed up source files --- src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 56830339bc..e5dc8e9ca9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -1141,7 +1141,7 @@ class Foo(x: Other) { x._1 } // no error in this order val matchStrategy: Tree def inMatchMonad(tp: Type): Type = appliedType(oneSig, List(tp)).finalResultType - def pureType(tp: Type): Type = appliedType(oneSig, List(tp)).paramTypes.head + def pureType(tp: Type): Type = appliedType(oneSig, List(tp)).paramTypes.headOption getOrElse NoType // fail gracefully (otherwise we get crashes) protected def matchMonadSym = oneSig.finalResultType.typeSymbol import CODE._ -- cgit v1.2.3 From 07ed42f07380aec06e5d0f65d69ce6826df39e2a Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Wed, 25 Apr 2012 17:28:07 +0200 Subject: Added a Presentation Compiler test for hyperlinking. This test ensures hyperlinking works inside and around pattern matching. The new virtual pattern matcher synthesizes trees that are not properly nested, and whose positions make it impossible to retrieve the correct tree/symbol for a given position. Therefore, the current test is using the old pattern matcher. However, once the virtual pattern matcher is fixed, remove the corresponding line from patmat.flags to re-enable virtpatmat. --- .../nsc/interactive/tests/core/CoreTestDefs.scala | 3 +- test/files/presentation/patmat.check | 36 ++++++++++++++++++++++ test/files/presentation/patmat.flags | 3 ++ test/files/presentation/patmat/Runner.scala | 11 +++++++ .../presentation/patmat/src/PatMatTests.scala | 28 +++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 test/files/presentation/patmat.check create mode 100644 test/files/presentation/patmat.flags create mode 100644 test/files/presentation/patmat/Runner.scala create mode 100644 test/files/presentation/patmat/src/PatMatTests.scala (limited to 'src') 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 99541ff4b4..9646ee1cf0 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala @@ -90,8 +90,9 @@ private[tests] trait CoreTestDefs compiler.askLinkPos(tree.symbol, source, r) r.get match { case Left(pos) => + val resolvedPos = if (tree.symbol.pos.isDefined) tree.symbol.pos else pos withResponseDelimiter { - reporter.println("[response] found askHyperlinkPos for `" + tree.symbol.name + "` at " + format(pos) + " " + tree.symbol.sourceFile.name) + reporter.println("[response] found askHyperlinkPos for `" + tree.symbol.name + "` at " + format(resolvedPos) + " " + tree.symbol.sourceFile.name) } case Right(ex) => ex.printStackTrace() diff --git a/test/files/presentation/patmat.check b/test/files/presentation/patmat.check new file mode 100644 index 0000000000..29fd8b8e68 --- /dev/null +++ b/test/files/presentation/patmat.check @@ -0,0 +1,36 @@ +reload: PatMatTests.scala + +askHyperlinkPos for `CaseOne` at (12,18) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `CaseOne` at (5,12) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `first` at (14,21) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `first` at (12,29) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `tmp` at (15,19) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `tmp` at (13,13) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `CaseTwo` at (17,18) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `CaseTwo` at (6,12) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `mystring` at (18,24) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `mystring` at (17,25) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `x` at (25,13) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `x` at (23,10) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `y` at (25,21) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `y` at (23,13) PatMatTests.scala +================================================================================ diff --git a/test/files/presentation/patmat.flags b/test/files/presentation/patmat.flags new file mode 100644 index 0000000000..468b48c9e3 --- /dev/null +++ b/test/files/presentation/patmat.flags @@ -0,0 +1,3 @@ +# This test will fail in the new pattern matcher because +# it generates trees whose positions are not transparent +-Xoldpatmat diff --git a/test/files/presentation/patmat/Runner.scala b/test/files/presentation/patmat/Runner.scala new file mode 100644 index 0000000000..3d19f2d948 --- /dev/null +++ b/test/files/presentation/patmat/Runner.scala @@ -0,0 +1,11 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest { + override def runTests() { + // make sure typer is done.. the virtual pattern matcher might translate + // some trees and mess up positions. But we'll catch it red handed! + sourceFiles foreach (src => askLoadedTyped(src).get) + super.runTests() + } + +} \ No newline at end of file diff --git a/test/files/presentation/patmat/src/PatMatTests.scala b/test/files/presentation/patmat/src/PatMatTests.scala new file mode 100644 index 0000000000..bbd0f2e7ed --- /dev/null +++ b/test/files/presentation/patmat/src/PatMatTests.scala @@ -0,0 +1,28 @@ +package patmat + +abstract class BaseType + +case class CaseOne(x: Int, y: List[Int]) extends BaseType +case class CaseTwo(str: String) extends BaseType + +class PatMatTests { + + def foo(x: BaseType) { + x match { + case CaseOne/*#*/(10, first :: second :: Nil) => + val tmp = 23 + println(first/*#*/) + println(tmp/*#*/) + + case CaseTwo/*#*/(mystring) => + println(mystring/*#*/) + } + } + + def multipleAssign() { + val (x, y) = ("abc", "def") + + println(x/*#*/, y/*#*/) + } + +} \ No newline at end of file -- cgit v1.2.3 From c22ec635c75170d1ac1cb0074e532b4186eed845 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 24 Apr 2012 07:51:19 -0700 Subject: Some long overdue conveniences. Not just conveniences though. One of the clearest statements made by profiling is that collections methods of the form of the enclosed flatCollect are materially faster than the alternatives. --- .../scala/reflect/internal/Definitions.scala | 2 +- .../scala/reflect/internal/SymbolTable.scala | 13 +++++++++++ src/compiler/scala/reflect/internal/Types.scala | 7 +++--- .../scala/reflect/internal/util/Collections.scala | 25 ++++++++++++++++++++++ .../scala/tools/nsc/backend/icode/GenICode.scala | 2 +- .../scala/tools/nsc/interpreter/IMain.scala | 10 ++++----- .../scala/tools/nsc/interpreter/Power.scala | 3 +-- .../tools/nsc/transform/SpecializeTypes.scala | 2 +- .../scala/tools/nsc/typechecker/Implicits.scala | 2 +- .../scala/tools/nsc/typechecker/TreeCheckers.scala | 2 +- .../scala/tools/nsc/typechecker/Typers.scala | 14 ++++++------ 11 files changed, 58 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 2b6607e23e..d89e852124 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -103,7 +103,7 @@ trait Definitions extends reflect.api.StandardDefinitions { getMemberMethod(valueClassCompanion(className.toTermName).moduleClass, methodName) private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f) - private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = syms zip (syms map (x => f(x.name))) toMap + private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = mapFrom(syms)(x => f(x.name)) private def symbolsMapFilt[T](syms: List[Symbol], p: Name => Boolean, f: Name => T) = symbolsMap(syms filter (x => p(x.name)), f) private def boxedName(name: Name) = sn.Boxed(name.toTypeName) diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 7d9dd282cf..9158c2a4d4 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -76,6 +76,19 @@ abstract class SymbolTable extends api.Universe result } + // For too long have we suffered in order to sort NAMES. + // I'm pretty sure there's a reasonable default for that. + // Notice challenge created by Ordering's invariance. + implicit def lowPriorityNameOrdering[T <: Names#Name]: Ordering[T] = + SimpleNameOrdering.asInstanceOf[Ordering[T]] + + private object SimpleNameOrdering extends Ordering[Names#Name] { + def compare(n1: Names#Name, n2: Names#Name) = ( + if (n1 eq n2) 0 + else n1.toString compareTo n2.toString + ) + } + /** Dump each symbol to stdout after shutdown. */ final val traceSymbolActivity = sys.props contains "scalac.debug.syms" diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 815a5c0710..2fe7dfda17 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -1509,7 +1509,8 @@ trait Types extends api.Types { self: SymbolTable => case tv: TypeVar => tvs += tv case _ => } - val varToParamMap: Map[Type, Symbol] = tvs map (tv => tv -> tv.origin.typeSymbol.cloneSymbol) toMap + val varToParamMap: Map[Type, Symbol] = + mapFrom[TypeVar, Type, Symbol](tvs.toList)(_.origin.typeSymbol.cloneSymbol) val paramToVarMap = varToParamMap map (_.swap) val varToParam = new TypeMap { def apply(tp: Type) = varToParamMap get tp match { @@ -3473,7 +3474,7 @@ trait Types extends api.Types { self: SymbolTable => case TypeRef(pre, sym, _) if sameLength(sym.typeParams, args) => val eparams = typeParamsToExistentials(sym) val bounds = args map (TypeBounds upper _) - (eparams, bounds).zipped foreach (_ setInfo _) + foreach2(eparams, bounds)(_ setInfo _) newExistentialType(eparams, typeRef(pre, sym, eparams map (_.tpe))) case _ => @@ -3655,7 +3656,7 @@ trait Types extends api.Types { self: SymbolTable => else owner.newValueParameter(name.toTermName) paramStack = newParams :: paramStack try { - (newParams, ptypes).zipped foreach ((p, t) => p setInfo this(t)) + foreach2(newParams, ptypes)((p, t) => p setInfo this(t)) val restpe1 = this(restpe) if (isType) PolyType(newParams, restpe1) else MethodType(newParams, restpe1) diff --git a/src/compiler/scala/reflect/internal/util/Collections.scala b/src/compiler/scala/reflect/internal/util/Collections.scala index 9e4ae1ca00..2e119f8ccc 100644 --- a/src/compiler/scala/reflect/internal/util/Collections.scala +++ b/src/compiler/scala/reflect/internal/util/Collections.scala @@ -70,6 +70,27 @@ trait Collections { lb.toList } + final def flatCollect[A, B](elems: List[A])(pf: PartialFunction[A, Traversable[B]]): List[B] = { + val lb = new ListBuffer[B] + for (x <- elems ; if pf isDefinedAt x) + lb ++= pf(x) + + lb.toList + } + + final def distinctBy[A, B](xs: List[A])(f: A => B): List[A] = { + val buf = new ListBuffer[A] + val seen = mutable.Set[B]() + xs foreach { x => + val y = f(x) + if (!seen(y)) { + buf += x + seen += y + } + } + buf.toList + } + @tailrec final def flattensToEmpty(xss: Seq[Seq[_]]): Boolean = { xss.isEmpty || xss.head.isEmpty && flattensToEmpty(xss.tail) } @@ -89,6 +110,10 @@ trait Collections { xs find p getOrElse orElse } + final def mapFrom[A, A1 >: A, B](xs: List[A])(f: A => B): Map[A1, B] = { + Map[A1, B](xs map (x => (x, f(x))): _*) + } + final def mapWithIndex[A, B](xs: List[A])(f: (A, Int) => B): List[B] = { val lb = new ListBuffer[B] var index = 0 diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index ff58de5f12..5e5b09405c 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -2225,7 +2225,7 @@ abstract class GenICode extends SubComponent { * jumps to the given basic block. */ def patch(code: Code) { - val map = toPatch map (i => (i -> patch(i))) toMap; + val map = mapFrom(toPatch)(patch) code.blocks foreach (_ subst map) } diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 3d77344091..a9c2ce0d09 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -369,7 +369,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def flatName(id: String) = optFlatName(id) getOrElse id def optFlatName(id: String) = requestForIdent(id) map (_ fullFlatName id) - def allDefinedNames = definedNameMap.keys.toList sortBy (_.toString) + def allDefinedNames = definedNameMap.keys.toList.sorted def pathToType(id: String): String = pathToName(newTypeName(id)) def pathToTerm(id: String): String = pathToName(newTermName(id)) def pathToName(name: Name): String = { @@ -1007,9 +1007,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def lookupTypeOf(name: Name) = typeOf.getOrElse(name, typeOf(global.encode(name.toString))) def simpleNameOfType(name: TypeName) = (compilerTypeOf get name) map (_.typeSymbol.simpleName) - private def typeMap[T](f: Type => T): Map[Name, T] = { - termNames ++ typeNames map (x => x -> f(cleanMemberDecl(resultSymbol, x))) toMap - } + private def typeMap[T](f: Type => T) = + mapFrom[Name, Name, T](termNames ++ typeNames)(x => f(cleanMemberDecl(resultSymbol, x))) /** Types of variables defined by this request. */ lazy val compilerTypeOf = typeMap[Type](x => x) withDefaultValue NoType @@ -1024,8 +1023,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends typeNames.map(x => x -> compilerTypeOf(x).typeSymbol) ).toMap[Name, Symbol] withDefaultValue NoSymbol - lazy val typesOfDefinedTerms: Map[Name, Type] = - termNames map (x => x -> applyToResultMember(x, _.tpe)) toMap + lazy val typesOfDefinedTerms = mapFrom[Name, Name, Type](termNames)(x => applyToResultMember(x, _.tpe)) /** load and run the code using reflection */ def loadAndRun: (String, Boolean) = { diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index 01ace0e984..659caad1e1 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Power.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala @@ -231,7 +231,7 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV def shortClass = erasure.getName split "[$.]" last def baseClasses = tpe.baseClasses - def baseClassDecls = baseClasses map (x => (x, x.info.decls.toList.sortBy(_.name.toString))) toMap + def baseClassDecls = mapFrom(baseClasses)(_.info.decls.toList.sortBy(_.name)) def ancestors = baseClasses drop 1 def ancestorDeclares(name: String) = ancestors filter (_.info member newTermName(name) ne NoSymbol) def baseTypes = tpe.baseTypeSeq.toList @@ -362,7 +362,6 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV else if (s1 isLess s2) -1 else 1 } - implicit lazy val powerNameOrdering: Ordering[Name] = Ordering[String] on (_.toString) implicit lazy val powerSymbolOrdering: Ordering[Symbol] = Ordering[Name] on (_.name) implicit lazy val powerTypeOrdering: Ordering[Type] = Ordering[Symbol] on (_.typeSymbol) diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index ff671088ac..1fb7fac184 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -820,7 +820,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // concise printing of type env private def pp(env: TypeEnv): String = { - env.toList.sortBy(_._1.name.toString) map { + env.toList.sortBy(_._1.name) map { case (k, v) => val vsym = v.typeSymbol if (k == vsym) "" + k.name diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 1612253dd6..0d7ef71193 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -831,7 +831,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() = mapFrom(eligible)(typedImplicit(_, false)) /** Returns the SearchResult of the best match. */ diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index 4319dd10c7..a6a8d6009f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -57,7 +57,7 @@ abstract class TreeCheckers extends Analyzer { def prev = maps.init.last._2 def latest = maps.last._2 - def sortedNewSyms = newSyms.toList.distinct sortBy (_.name.toString) + def sortedNewSyms = newSyms.toList.distinct sortBy (_.name) def inPrev(sym: Symbol) = { (maps.size >= 2) && (prev contains sym) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1414424a0b..a956b9a177 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3289,14 +3289,12 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser case tp => tp } - (hidden map { s => - // Hanging onto lower bound in case anything interesting - // happens with it. - (s, s.existentialBound match { - case TypeBounds(lo, hi) => TypeBounds(lo, hiBound(s)) - case _ => hiBound(s) - }) - }).toMap + // Hanging onto lower bound in case anything interesting + // happens with it. + mapFrom(hidden)(s => s.existentialBound match { + case TypeBounds(lo, hi) => TypeBounds(lo, hiBound(s)) + case _ => hiBound(s) + }) } /** Given a set `rawSyms` of term- and type-symbols, and a type -- cgit v1.2.3 From 4c6f64b708dc10b010e4da3aa05205ca3b04bcf9 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 25 Apr 2012 07:42:04 -0700 Subject: Minor tweaks to reifier logic. Nothing too major, please see the comment. --- .../scala/reflect/reify/codegen/Types.scala | 2 +- .../scala/reflect/reify/phases/Reify.scala | 66 +++++++++++++--------- 2 files changed, 39 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala index 841ec61e60..8fa24c5b00 100644 --- a/src/compiler/scala/reflect/reify/codegen/Types.scala +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -84,7 +84,7 @@ trait Types { def spliceType(tpe: Type): Tree = { // [Eugene] it seems that depending on the context the very same symbol can be either a spliceable tparam or a quantified existential. very weird! - val quantified = currents collect { case ExistentialType(quantified, _) => quantified } flatMap identity + val quantified = currentQuantified if (tpe.isSpliceable && !(quantified contains tpe.typeSymbol)) { if (reifyDebug) println("splicing " + tpe) diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala index a1ff486ed7..e03ff5832c 100644 --- a/src/compiler/scala/reflect/reify/phases/Reify.scala +++ b/src/compiler/scala/reflect/reify/phases/Reify.scala @@ -19,37 +19,47 @@ trait Reify extends Symbols import definitions._ import treeInfo._ + // `reify` looked so nice, I wanted to push the last bit of orthogonal + // logic out of it so you can see the improvement. There is no cost to + // wrapper methods of this form because the inliner will eliminate them, + // but they are very good at separating concerns like pushing/popping + // a stack, and they are great for composition and reuse. + // + // Also, please avoid public vars whenever possible. + private object reifyStack { + var currents: List[Any] = reifee :: Nil + + @inline final def push[T](reifee: Any)(body: => T): T = { + currents ::= reifee + try body + finally currents = currents.tail + } + } + def currentQuantified = flatCollect(reifyStack.currents)({ case ExistentialType(quantified, _) => quantified }) + def current = reifyStack.currents.head + /** * Reifies any supported value. * For internal use only, use ``reified'' instead. */ - var currents: List[Any] = reifee :: Nil - def current = currents.head - def reify(reifee: Any): Tree = { - currents = reifee :: currents - try { - 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) - // disabled because this is a very special case that I plan to remove later - // why do I dislike annotations? see comments to `reifyAnnotationInfo` + def reify(reifee: Any): Tree = reifyStack.push(reifee)(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) + // 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) - 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)) - } - } finally { - currents = currents.tail - } - } + 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 -- cgit v1.2.3 From 79dfed0baabd14394ba078b62c7418ae0e738603 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 25 Apr 2012 19:37:26 +0300 Subject: removes Expr <-> Tree implicits --- src/library/scala/reflect/api/Exprs.scala | 34 +--------------------- src/library/scala/reflect/api/Trees.scala | 28 ------------------ src/library/scala/reflect/api/Universe.scala | 3 +- src/library/scala/reflect/makro/Context.scala | 4 +-- .../Impls_1.scala | 3 +- .../Impls_1.scala | 2 +- .../neg/macro-without-xmacros-a/Impls_1.scala | 6 ++-- .../neg/macro-without-xmacros-b/Impls_1.scala | 6 ++-- test/files/run/macro-abort-fresh/Test_2.scala | 2 +- test/files/run/macro-basic-mamd-mi/Impls_1.scala | 4 +-- .../run/macro-def-infer-return-type-b/Test_2.scala | 2 +- .../macro-expand-tparams-bounds-a/Impls_1.scala | 5 +--- .../macro-expand-tparams-bounds-b/Impls_1.scala | 5 +--- .../Impls_1.scala | 5 +--- .../macro-expand-tparams-prefix-c1/Impls_1.scala | 4 +-- .../Impls_Macros_1.scala | 4 +-- .../macro-expand-tparams-prefix-d1/Impls_1.scala | 4 +-- .../Macros_Test_2.scala | 2 +- .../Impls_Macros_1.scala | 2 +- .../Test_2.scala | 2 +- .../run/macro-invalidret-nontypeable/Test_2.scala | 2 +- .../run/macro-invalidusage-badret/Test_2.scala | 2 +- .../Test_2.scala | 2 +- .../run/macro-range/Expansion_Impossible_2.scala | 10 +++---- .../macro-reflective-ma-normal-mdmi/Test_2.scala | 2 +- .../macro-reify-eval-outside-reify/Test_2.scala | 2 +- test/files/run/macro-reify-freevars/Test_2.scala | 2 +- test/files/run/macro-reify-tagless-a/Test_2.scala | 2 +- .../macro-reify-value-outside-reify/Test_2.scala | 2 +- test/files/run/reify_newimpl_45.scala | 6 ++-- test/files/run/t5704.scala | 32 ++++++++++---------- .../run/toolbox_default_reporter_is_silent.scala | 2 +- test/files/run/toolbox_silent_reporter.scala | 2 +- 33 files changed, 62 insertions(+), 133 deletions(-) (limited to 'src') diff --git a/src/library/scala/reflect/api/Exprs.scala b/src/library/scala/reflect/api/Exprs.scala index ff89a1cd48..b8db64422e 100644 --- a/src/library/scala/reflect/api/Exprs.scala +++ b/src/library/scala/reflect/api/Exprs.scala @@ -16,36 +16,4 @@ trait Exprs { self: Universe => 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 - // [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 -} - +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index b70ca7e0fd..9f8906a8cd 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -278,34 +278,6 @@ 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. */ diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala index 2a7445c41c..9670780522 100755 --- a/src/library/scala/reflect/api/Universe.scala +++ b/src/library/scala/reflect/api/Universe.scala @@ -65,8 +65,7 @@ abstract class Universe extends Symbols 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._ import scala.reflect.makro.internal._ - cc.materializeExpr(cc.prefix, expr) + cc.Expr(cc.materializeExpr(cc.prefix.tree, expr.tree)) } } diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala index 668d239087..b8fb0dcce5 100644 --- a/src/library/scala/reflect/makro/Context.scala +++ b/src/library/scala/reflect/makro/Context.scala @@ -36,9 +36,9 @@ object Context { import cc.mirror._ import scala.reflect.makro.internal._ // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure? - val prefix: Tree = Select(cc.prefix, newTermName("mirror")) + val prefix: Tree = Select(cc.prefix.tree, newTermName("mirror")) val prefixTpe = cc.typeCheck(TypeApply(Select(prefix, newTermName("asInstanceOf")), List(SingletonTypeTree(prefix)))).tpe prefix setType prefixTpe - cc.materializeExpr(prefix, expr) + cc.Expr(cc.materializeExpr(prefix, expr.tree)) } } 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 index 7bc46ff876..db79ddbcd8 100644 --- a/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala @@ -2,10 +2,9 @@ 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(())) + c.literalUnit } } 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 index 7bc46ff876..43c5a2acd5 100644 --- a/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala @@ -6,6 +6,6 @@ object Impls { println(implicitly[c.TypeTag[T]]) println(implicitly[c.TypeTag[U]]) println(V) - Literal(Constant(())) + c.literalUnit } } diff --git a/test/files/neg/macro-without-xmacros-a/Impls_1.scala b/test/files/neg/macro-without-xmacros-a/Impls_1.scala index 01daf12b1a..e6cee46e85 100644 --- a/test/files/neg/macro-without-xmacros-a/Impls_1.scala +++ b/test/files/neg/macro-without-xmacros-a/Impls_1.scala @@ -3,16 +3,16 @@ 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)))) + Expr(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)))) + Expr(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)))) + Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3))))) } } diff --git a/test/files/neg/macro-without-xmacros-b/Impls_1.scala b/test/files/neg/macro-without-xmacros-b/Impls_1.scala index 01daf12b1a..e6cee46e85 100644 --- a/test/files/neg/macro-without-xmacros-b/Impls_1.scala +++ b/test/files/neg/macro-without-xmacros-b/Impls_1.scala @@ -3,16 +3,16 @@ 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)))) + Expr(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)))) + Expr(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)))) + Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3))))) } } diff --git a/test/files/run/macro-abort-fresh/Test_2.scala b/test/files/run/macro-abort-fresh/Test_2.scala index f389231ca6..ecf48b9752 100644 --- a/test/files/run/macro-abort-fresh/Test_2.scala +++ b/test/files/run/macro-abort-fresh/Test_2.scala @@ -1,6 +1,6 @@ object Test extends App { import scala.reflect.mirror._ val tree = Select(Ident("Macros"), newTermName("foo")) - try tree.eval + try Expr(tree).eval catch { case ex: Throwable => println(ex.getMessage) } } \ No newline at end of file diff --git a/test/files/run/macro-basic-mamd-mi/Impls_1.scala b/test/files/run/macro-basic-mamd-mi/Impls_1.scala index eadb63fa8e..82d2cce2f5 100644 --- a/test/files/run/macro-basic-mamd-mi/Impls_1.scala +++ b/test/files/run/macro-basic-mamd-mi/Impls_1.scala @@ -3,12 +3,12 @@ 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)))) + Expr(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)))) + Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2))))) } def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { 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 index 8ff4494750..f8f15b4224 100644 --- 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 @@ -1,6 +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 + try Expr(tree).eval catch { case ex: Throwable => println(ex.getMessage) } } \ 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 index 4cd98c5838..5019d5d4a7 100644 --- a/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala +++ b/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala @@ -1,8 +1,5 @@ import scala.reflect.makro.{Context => Ctx} object Impls { - def foo[U <: String](c: Ctx): c.Expr[Unit] = { - import c.mirror._ - Literal(Constant(())) - } + def foo[U <: String](c: Ctx): c.Expr[Unit] = c.literalUnit } 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 index 9103ddb08a..abd68696b6 100644 --- a/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala +++ b/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala @@ -3,8 +3,5 @@ import scala.reflect.makro.{Context => Ctx} class C object Impls { - def foo[U <: C](c: Ctx): c.Expr[Unit] = { - import c.mirror._ - Literal(Constant(())) - } + def foo[U <: C](c: Ctx): c.Expr[Unit] = c.literalUnit } 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 index 4cd98c5838..5019d5d4a7 100644 --- 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 @@ -1,8 +1,5 @@ import scala.reflect.makro.{Context => Ctx} object Impls { - def foo[U <: String](c: Ctx): c.Expr[Unit] = { - import c.mirror._ - Literal(Constant(())) - } + def foo[U <: String](c: Ctx): c.Expr[Unit] = c.literalUnit } 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 index bc880fdf77..4da5a9b823 100644 --- a/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala +++ b/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala @@ -3,10 +3,10 @@ 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( + Expr(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(()))) + Literal(Constant(())))) } } 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 index c83e401afb..4d137a4aef 100644 --- 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 @@ -3,11 +3,11 @@ 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( + Expr(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(()))) + Literal(Constant(())))) } } 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 index bc880fdf77..4da5a9b823 100644 --- a/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala +++ b/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala @@ -3,10 +3,10 @@ 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( + Expr(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(()))) + Literal(Constant(())))) } } 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 index 523c6b0645..01fc9d4462 100644 --- 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 @@ -5,6 +5,6 @@ object Macros { 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 + try Expr(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-def-rettype/Impls_Macros_1.scala b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala index 882867fcab..828ccf34e2 100644 --- 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 @@ -3,7 +3,7 @@ import scala.reflect.makro.{Context => Ctx} object Impls { def foo(c: Ctx): c.Expr[Int] = { import c.mirror._ - Literal(Constant("42")) + Expr(Literal(Constant("42"))) } } 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 index f389231ca6..ecf48b9752 100644 --- 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 @@ -1,6 +1,6 @@ object Test extends App { import scala.reflect.mirror._ val tree = Select(Ident("Macros"), newTermName("foo")) - try tree.eval + try Expr(tree).eval catch { case ex: Throwable => println(ex.getMessage) } } \ No newline at end of file diff --git a/test/files/run/macro-invalidret-nontypeable/Test_2.scala b/test/files/run/macro-invalidret-nontypeable/Test_2.scala index f389231ca6..ecf48b9752 100644 --- a/test/files/run/macro-invalidret-nontypeable/Test_2.scala +++ b/test/files/run/macro-invalidret-nontypeable/Test_2.scala @@ -1,6 +1,6 @@ object Test extends App { import scala.reflect.mirror._ val tree = Select(Ident("Macros"), newTermName("foo")) - try tree.eval + try Expr(tree).eval catch { case ex: Throwable => println(ex.getMessage) } } \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-badret/Test_2.scala b/test/files/run/macro-invalidusage-badret/Test_2.scala index e171c9d05a..aeb3c26eaa 100644 --- a/test/files/run/macro-invalidusage-badret/Test_2.scala +++ b/test/files/run/macro-invalidusage-badret/Test_2.scala @@ -1,6 +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 + try Expr(tree).eval catch { case ex: Throwable => println(ex.getMessage) } } \ 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 index 63371a4a82..293d906048 100644 --- a/test/files/run/macro-invalidusage-partialapplication/Test_2.scala +++ b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala @@ -1,6 +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 + try Expr(tree).eval catch { case ex: Throwable => println(ex.getMessage) } } diff --git a/test/files/run/macro-range/Expansion_Impossible_2.scala b/test/files/run/macro-range/Expansion_Impossible_2.scala index 7a093b74ee..051afff99c 100644 --- a/test/files/run/macro-range/Expansion_Impossible_2.scala +++ b/test/files/run/macro-range/Expansion_Impossible_2.scala @@ -14,7 +14,7 @@ object Impls { // 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 { + Expr(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") @@ -23,7 +23,7 @@ object Impls { val labelname = newTermName("$while") val cond = makeBinop(iref, "$less", href) val body = Block( - List(makeApply(f, List(iref))), + List(makeApply(f.tree, List(iref))), Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1))))) val generated = Block( @@ -37,10 +37,10 @@ object Impls { case _ => Apply( Select( - Typed(c.prefix, Ident(newTypeName("RangeDefault"))), + Typed(c.prefix.tree, Ident(newTypeName("RangeDefault"))), newTermName("foreach")), - List(f)) - } + List(f.tree)) + }) } } 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 index 3c594aed75..632708a125 100644 --- a/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala +++ b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala @@ -1,5 +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) + println(Expr(tree).eval) } 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 index 3c594aed75..632708a125 100644 --- a/test/files/run/macro-reify-eval-outside-reify/Test_2.scala +++ b/test/files/run/macro-reify-eval-outside-reify/Test_2.scala @@ -1,5 +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) + println(Expr(tree).eval) } diff --git a/test/files/run/macro-reify-freevars/Test_2.scala b/test/files/run/macro-reify-freevars/Test_2.scala index 55c677155a..e7077f9c7f 100644 --- a/test/files/run/macro-reify-freevars/Test_2.scala +++ b/test/files/run/macro-reify-freevars/Test_2.scala @@ -4,6 +4,6 @@ object Test extends App { 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 + try Expr(tree).eval catch { case ex: Throwable => println(ex.getMessage) } } \ 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 index d996da1570..94efbd0c37 100644 --- a/test/files/run/macro-reify-tagless-a/Test_2.scala +++ b/test/files/run/macro-reify-tagless-a/Test_2.scala @@ -7,6 +7,6 @@ object Test extends App { 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 + try Expr(tree).eval catch { case ex: Throwable => println(ex.getMessage) } } 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 index 8225eb0b39..128cad4510 100644 --- a/test/files/run/macro-reify-value-outside-reify/Test_2.scala +++ b/test/files/run/macro-reify-value-outside-reify/Test_2.scala @@ -1,6 +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) + try println(Expr(tree).eval) catch { case ex: Throwable => println(ex.getMessage) } } diff --git a/test/files/run/reify_newimpl_45.scala b/test/files/run/reify_newimpl_45.scala index 241b7d4bc3..b2b52eaf5b 100644 --- a/test/files/run/reify_newimpl_45.scala +++ b/test/files/run/reify_newimpl_45.scala @@ -3,9 +3,9 @@ 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)) + println(freeTypes(code.tree)) + val T = freeTypes(code.tree)(0) + mkToolBox().runExpr(code.tree, Map(T -> definitions.StringClass.asType)) } new C[String] diff --git a/test/files/run/t5704.scala b/test/files/run/t5704.scala index 25a6575dc3..8fd721d4e7 100644 --- a/test/files/run/t5704.scala +++ b/test/files/run/t5704.scala @@ -1,16 +1,16 @@ -import scala.reflect.mirror._ - -object Test extends App { - class MyQuerycollection{ - def findUserByName( name:String ) = { - val tree = reify{ "test" == name } - val toolbox = mkToolBox() - toolbox.typeCheck(tree) match{ - case Apply(Select(lhs,op),rhs::Nil) => - println(rhs.tpe) - } - } - } - val qc = new MyQuerycollection - qc.findUserByName("some value") -} +import scala.reflect.mirror._ + +object Test extends App { + class MyQuerycollection{ + def findUserByName( name:String ) = { + val tree = reify{ "test" == name }.tree + val toolbox = mkToolBox() + toolbox.typeCheck(tree) match{ + case Apply(Select(lhs,op),rhs::Nil) => + println(rhs.tpe) + } + } + } + val qc = new MyQuerycollection + qc.findUserByName("some value") +} diff --git a/test/files/run/toolbox_default_reporter_is_silent.scala b/test/files/run/toolbox_default_reporter_is_silent.scala index 78606e2abc..6908c001a3 100644 --- a/test/files/run/toolbox_default_reporter_is_silent.scala +++ b/test/files/run/toolbox_default_reporter_is_silent.scala @@ -9,5 +9,5 @@ object Test extends App { } Utils.foo - }) + }.tree) } diff --git a/test/files/run/toolbox_silent_reporter.scala b/test/files/run/toolbox_silent_reporter.scala index 5f264f7d74..6f5687ba4f 100644 --- a/test/files/run/toolbox_silent_reporter.scala +++ b/test/files/run/toolbox_silent_reporter.scala @@ -9,7 +9,7 @@ object Test extends App { } Utils.foo - }) + }.tree) println("============compiler messages============") toolbox.frontEnd.infos.foreach(println(_)) println("=========================================") -- cgit v1.2.3 From bd3eacbae21f39b1ac7fe8ade4ed71fa98e1a28d Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 25 Apr 2012 20:28:35 +0300 Subject: fixes SI-5693 --- .../scala/reflect/internal/StdAttachments.scala | 2 - .../scala/tools/nsc/typechecker/Analyzer.scala | 1 + .../scala/tools/nsc/typechecker/Macros.scala | 161 ++++++++++----------- .../tools/nsc/typechecker/StdAttachments.scala | 10 ++ 4 files changed, 85 insertions(+), 89 deletions(-) create mode 100644 src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/StdAttachments.scala b/src/compiler/scala/reflect/internal/StdAttachments.scala index 488195b7dd..ae2ad87deb 100644 --- a/src/compiler/scala/reflect/internal/StdAttachments.scala +++ b/src/compiler/scala/reflect/internal/StdAttachments.scala @@ -7,6 +7,4 @@ trait StdAttachments { self: SymbolTable => case class ReifyAttachment(original: Symbol) - - case class MacroAttachment(delayed: Boolean, context: Option[MacroContext]) } \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala index 18c7635b1e..a77df71312 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala @@ -24,6 +24,7 @@ trait Analyzer extends AnyRef with NamesDefaults with TypeDiagnostics with ContextErrors + with StdAttachments { val global : Global import global._ diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index ef9bae700e..6d4c543a5a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -294,8 +294,6 @@ trait Macros { self: Analyzer => } finally { openMacros = openMacros.tail } - case Delay(result) => - result case Fallback(fallback) => typer.typed1(fallback, EXPRmode, WildcardType) case Other(result) => @@ -828,7 +826,7 @@ trait Macros { self: Analyzer => case _ => } collectMacroArgs(expandee) - val context = expandee.attachmentOpt[MacroAttachment].flatMap(_.context).getOrElse(macroContext(typer, prefixTree, expandee)) + val context = expandee.attachmentOpt[MacroAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefixTree, expandee)) var argss: List[List[Any]] = List(context) :: exprArgs.toList macroTrace("argss: ")(argss) @@ -1007,18 +1005,6 @@ trait Macros { self: Analyzer => } finally { openMacros = openMacros.tail } - case Delay(expandee) => - // need to save the context to preserve enclosures - macroArgs(typer, expandee) match { - case Some((context: MacroContext) :: _) => - // adapting here would be premature, we must wait until undetparams are inferred - expandee withAttachment MacroAttachment(delayed = true, context = Some(context)) - case _ => - // !!! The correct place to issue an error needs to be clarified. - // I have the else condition here only as a fallback. - if (expandee.isErroneous) expandee - else fail("macros cannot be partially applied", expandee) - } case Fallback(fallback) => typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt)) case Other(result) => @@ -1032,8 +1018,8 @@ trait Macros { self: Analyzer => 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 Delay(expandee: Tree) extends MacroExpansionResult private case class Other(result: Tree) extends MacroExpansionResult + private def Delay(expanded: Tree) = Other(expanded) private def Skip(expanded: Tree) = Other(expanded) private def Cancel(expandee: Tree) = Other(expandee) private def Failure(expandee: Tree) = Other(expandee) @@ -1086,75 +1072,78 @@ trait Macros { self: Analyzer => if (!wasDelayed) { if (macroDebug || macroCopypaste) println("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) - if (nowDelayed) { - if (macroDebug || macroCopypaste) println("macro expansion is delayed: %s".format(expandee)) - delayed += expandee -> (typer.context, undetparams) - Delay(expandee) - } else { - 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 - expandee.detach(null) - 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 args = macroArgs(typer, expandee) + args match { + case Some(args) => + val (context: MacroContext) :: _ = args + if (nowDelayed) { + if (macroDebug || macroCopypaste) println("macro expansion is delayed: %s".format(expandee)) + delayed += expandee -> undetparams + // need to save typer context for `macroExpandAll` + // need to save macro context to preserve enclosures + expandee attach MacroAttachment(delayed = true, typerContext = typer.context, macroContext = Some(context)) + Delay(expandee) + } else { + val expanded: MacroExpansionResult = + try { + val prevNumErrors = reporter.ERROR.count + openMacros = context :: openMacros + 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 + } finally { + expandee.detach(classOf[MacroAttachment]) } - } 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 - } + } + case None => + fail(typer, expandee) // error has been reported by macroArgs } } else { if (nowDelayed) @@ -1164,8 +1153,6 @@ trait Macros { self: Analyzer => } } catch { case ex => handleMacroExpansionException(typer, expandee, ex) - } finally { - expandee.detach(classOf[MacroAttachment]) } private def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroExpansionResult = { @@ -1261,10 +1248,10 @@ trait Macros { self: Analyzer => * 2) undetparams (sym.isTypeParameter && !sym.isSkolem) */ var hasPendingMacroExpansions = false - private val delayed = perRunCaches.newWeakMap[Tree, (Context, collection.mutable.Set[Int])] + private val delayed = perRunCaches.newWeakMap[Tree, 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 { + delayed.get(expandee).getOrElse { val calculated = collection.mutable.Set[Symbol]() expandee foreach (sub => { def traverse(sym: Symbol) = if (sym != null && (undetparams contains sym.id)) calculated += sym @@ -1284,7 +1271,7 @@ trait Macros { self: Analyzer => if (macroDebug) (undetNoMore zip inferreds) foreach {case (sym, tpe) => println("undetParam inferred: %s as %s".format(sym, tpe))} if (!delayed.isEmpty) delayed.toList foreach { - case (expandee, (_, undetparams)) if !undetparams.isEmpty => + case (expandee, undetparams) if !undetparams.isEmpty => undetparams --= undetNoMore map (_.id) if (undetparams.isEmpty) { hasPendingMacroExpansions = true @@ -1304,7 +1291,7 @@ trait Macros { self: Analyzer => 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) + val context = wannabe.attachment[MacroAttachment].typerContext delayed -= wannabe context.implicitsEnabled = typer.context.implicitsEnabled context.enrichmentEnabled = typer.context.enrichmentEnabled diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala new file mode 100644 index 0000000000..329a247106 --- /dev/null +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -0,0 +1,10 @@ +package scala.tools.nsc +package typechecker + +import scala.reflect.makro.runtime.{Context => MacroContext} + +trait StdAttachments { + self: Analyzer => + + case class MacroAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext]) +} \ No newline at end of file -- cgit v1.2.3 From b242637ee1fc6db79992a67073219ec87150d06a Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 25 Apr 2012 21:13:29 +0300 Subject: diagnostics for SI-5692 --- src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala | 13 ++++++++++--- test/pending/run/t5692.flags | 1 + test/pending/run/t5692/Impls_Macros_1.scala | 9 +++++++++ test/pending/run/t5692/Test_2.scala | 4 ++++ 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 test/pending/run/t5692.flags create mode 100644 test/pending/run/t5692/Impls_Macros_1.scala create mode 100644 test/pending/run/t5692/Test_2.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 52648380ec..192cc94b90 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -62,9 +62,16 @@ abstract class Pickler extends SubComponent { // when we pickle it: so let's report an error instead. We know next // to nothing about what happened, but our supposition is a lot better // than "bad type: " in terms of explanatory power. - for (t <- unit.body ; if t.isErroneous) { - unit.error(t.pos, "erroneous or inaccessible type") - return + for (t <- unit.body) { + if (t.isErroneous) { + unit.error(t.pos, "erroneous or inaccessible type") + return + } + + if (!t.isDef && t.hasSymbol && t.symbol.isTermMacro) { + unit.error(t.pos, "macro has not been expanded") + return + } } pickle(unit.body) diff --git a/test/pending/run/t5692.flags b/test/pending/run/t5692.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/pending/run/t5692.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/pending/run/t5692/Impls_Macros_1.scala b/test/pending/run/t5692/Impls_Macros_1.scala new file mode 100644 index 0000000000..f9c1e5f12b --- /dev/null +++ b/test/pending/run/t5692/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.Context + +object Impls { + def impl[A](c: reflect.makro.Context) = c.reify(()) +} + +object Macros { + def decl[A] = macro Impls.impl[A] +} \ No newline at end of file diff --git a/test/pending/run/t5692/Test_2.scala b/test/pending/run/t5692/Test_2.scala new file mode 100644 index 0000000000..29251a5ef5 --- /dev/null +++ b/test/pending/run/t5692/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val x = Macros.decl + def y() { Macros.decl(); } +} \ No newline at end of file -- cgit v1.2.3 From 6ea732424238ce4a664aedd416655836ef16d1c4 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 25 Apr 2012 18:02:32 -0700 Subject: Reverts 211df62491 . A strange blip in the benchmarks makes me wish to see this on the sidelines. --- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 104 ++++++++------------- 1 file changed, 37 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index ac5814f4f2..f7898f2aa2 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1311,40 +1311,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } - // Collected frequency of opcdes to determine case ordering: - // - // 47514 CALL_METHOD - // 43434 LOAD_LOCAL - // 38572 THIS - // 31207 RETURN - // 5832 JUMP - // 5395 CONSTANT - // 5010 LOAD_FIELD - // 4731 STORE_LOCAL - // 4252 DUP - // 3612 NEW - // 3519 CZJUMP - // 2938 SCOPE_ENTER - // 2900 CALL_PRIMITIVE - // 2884 STORE_FIELD - // 2881 CHECK_CAST - // 2459 LOAD_MODULE - // 1783 SCOPE_EXIT - // 1315 CJUMP - // 1305 THROW - // 1030 DROP - // 485 BOX - // 468 UNBOX - // 464 MONITOR_EXIT - // 434 IS_INSTANCE - // 428 STORE_ARRAY_ITEM - // 329 LOAD_ARRAY_ITEM - // 280 CREATE_ARRAY - // 253 LOAD_EXCEPTION - // 232 MONITOR_ENTER - // 37 STORE_THIS - // 19 SWITCH - def genBlock(b: BasicBlock) { labels(b).anchorToNext() @@ -1358,41 +1324,11 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with val lastInstr = b.lastInstruction for (instr <- b) { - instr match { - case call @ CALL_METHOD(method, style) => - /** Special handling to access native Array.clone() */ - if (method == definitions.Array_clone && style == Dynamic) { - val target = javaType(call.targetTypeKind).getSignature() - jcode.emitINVOKEVIRTUAL(target, "clone", arrayCloneType) - } - else genCallMethod(call) - - case LOAD_LOCAL(local) => jcode.emitLOAD(indexOf(local), javaType(local.kind)) - case THIS(clasz) => jcode.emitALOAD_0() - case RETURN(kind) => jcode emitRETURN javaType(kind) - - case CONSTANT(const) => genConstant(jcode, const) - case JUMP(whereto) => - if (nextBlock != whereto) - jcode.emitGOTO_maybe_W(labels(whereto), false) // default to short jumps - case lf @ LOAD_FIELD(field, isStatic) => - var owner = javaName(lf.hostClass) - debuglog("LOAD_FIELD with owner: " + owner + " flags: " + Flags.flagsToString(field.owner.flags)) - val fieldJName = javaName(field) - val fieldJType = javaType(field) - if (isStatic) jcode.emitGETSTATIC(owner, fieldJName, fieldJType) - else jcode.emitGETFIELD( owner, fieldJName, fieldJType) - - case STORE_LOCAL(local) => - jcode.emitSTORE(indexOf(local), javaType(local.kind)) - - case DUP(kind) => - if(kind.isWideType) jcode.emitDUP2() - else jcode.emitDUP() + instr match { + case THIS(clasz) => jcode.emitALOAD_0() - case NEW(REFERENCE(cls)) => - jcode emitNEW javaName(cls) + case CONSTANT(const) => genConstant(jcode, const) case LOAD_ARRAY_ITEM(kind) => if(kind.isRefOrArrayType) { jcode.emitAALOAD() } @@ -1409,6 +1345,17 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } + case LOAD_LOCAL(local) => jcode.emitLOAD(indexOf(local), javaType(local.kind)) + + case lf @ LOAD_FIELD(field, isStatic) => + var owner = javaName(lf.hostClass) + debuglog("LOAD_FIELD with owner: " + owner + + " flags: " + Flags.flagsToString(field.owner.flags)) + val fieldJName = javaName(field) + val fieldJType = javaType(field) + if (isStatic) jcode.emitGETSTATIC(owner, fieldJName, fieldJType) + else jcode.emitGETFIELD( owner, fieldJName, fieldJType) + case LOAD_MODULE(module) => // assert(module.isModule, "Expected module: " + module) debuglog("generating LOAD_MODULE for: " + module + " flags: " + Flags.flagsToString(module.flags)); @@ -1434,6 +1381,9 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } + case STORE_LOCAL(local) => + jcode.emitSTORE(indexOf(local), javaType(local.kind)) + case STORE_THIS(_) => // this only works for impl classes because the self parameter comes first // in the method signature. If that changes, this code has to be revisited. @@ -1448,6 +1398,13 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with case CALL_PRIMITIVE(primitive) => genPrimitive(primitive, instr.pos) + /** Special handling to access native Array.clone() */ + case call @ CALL_METHOD(definitions.Array_clone, Dynamic) => + val target: String = javaType(call.targetTypeKind).getSignature() + jcode.emitINVOKEVIRTUAL(target, "clone", arrayCloneType) + + case call @ CALL_METHOD(method, style) => genCallMethod(call) + case BOX(kind) => val Pair(mname, mtype) = jBoxTo(kind) jcode.emitINVOKESTATIC(BoxesRunTime, mname, mtype) @@ -1456,6 +1413,10 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with val Pair(mname, mtype) = jUnboxTo(kind) jcode.emitINVOKESTATIC(BoxesRunTime, mname, mtype) + case NEW(REFERENCE(cls)) => + val className = javaName(cls) + jcode emitNEW className + case CREATE_ARRAY(elem, 1) => if(elem.isRefOrArrayType) { jcode emitANEWARRAY javaType(elem).asInstanceOf[JReferenceType] } else { jcode emitNEWARRAY javaType(elem) } @@ -1501,6 +1462,10 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with MIN_SWITCH_DENSITY) () + case JUMP(whereto) => + if (nextBlock != whereto) + jcode.emitGOTO_maybe_W(labels(whereto), false) // default to short jumps + case CJUMP(success, failure, cond, kind) => if(kind.isIntSizedType) { // BOOL, BYTE, CHAR, SHORT, or INT if (nextBlock == success) { @@ -1587,6 +1552,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } + case RETURN(kind) => jcode emitRETURN javaType(kind) case THROW(_) => jcode.emitATHROW() @@ -1594,6 +1560,10 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with if(kind.isWideType) jcode.emitPOP2() else jcode.emitPOP() + case DUP(kind) => + if(kind.isWideType) jcode.emitDUP2() + else jcode.emitDUP() + case MONITOR_ENTER() => jcode.emitMONITORENTER() case MONITOR_EXIT() => jcode.emitMONITOREXIT() -- cgit v1.2.3 From 1297d87d5e5bfa25022568b6e20fbd92f6d6c40a Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 25 Apr 2012 15:39:18 -0700 Subject: More style tips for team macros. --- .../scala/reflect/makro/runtime/Enclosures.scala | 39 ++++++++-------------- 1 file changed, 13 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala index 72e9e568c0..ab38fc024d 100644 --- a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala +++ b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala @@ -6,31 +6,18 @@ trait Enclosures { import mirror._ + private def site = callsiteTyper.context + private def enclTrees = site.enclosingContextChain map (_.tree) + private def enclPoses = enclosingMacros map (_.macroApplication.pos) filterNot (_ eq NoPosition) + // 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 // include self - - 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 + val macroApplication: Tree = expandee + val enclosingApplication: Tree = enclTrees collectFirst { case t: Apply => t } getOrElse EmptyTree + val enclosingClass: Tree = site.enclClass.tree + val enclosingImplicits: List[(Type, Tree)] = site.openImplicits + val enclosingMacros: List[Context] = this :: mirror.analyzer.openMacros // include self + val enclosingMethod: Tree = site.enclMethod.tree + val enclosingPosition: Position = if (enclPoses.isEmpty) NoPosition else enclPoses.head.pos + val enclosingUnit: CompilationUnit = currentRun.currentUnit +} -- cgit v1.2.3 From 8fc543b5dd7e6a8fa1827cc9e9d65e721cae140e Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 25 Apr 2012 18:33:05 -0700 Subject: Trying to set an example in the land of macros. Hopefully there are useful examples to be had in here. Please note that you should never be testing "x.size != 0", use isEmpty or nonEmpty. Even if these happen to be small collections, it's not a habit you want to form: size is O(n) on a number of collections. (Most pointedly, Lists.) --- src/compiler/scala/reflect/internal/Symbols.scala | 7 +- .../scala/tools/nsc/typechecker/Macros.scala | 199 +++++++++++---------- test/files/run/macro-reify-freevars.check | 6 +- test/files/run/macro-reify-tagless-a.check | 6 +- 4 files changed, 117 insertions(+), 101 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 380ceb4bc7..31f068494c 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -2971,12 +2971,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => ) } - class FreeTerm(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) { + trait FreeSymbol extends Symbol { + def origin: String + } + class FreeTerm(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) with FreeSymbol { def value = value0 override def isFreeTerm = true } - class FreeType(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) { + class FreeType(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol { def value = value0 override def isFreeType = true } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 6d4c543a5a..14f09d9dc9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -806,13 +806,12 @@ trait Macros { self: Analyzer => * @return list of runtime objects to pass to the implementation obtained by ``macroRuntime'' */ private def macroArgs(typer: Typer, expandee: Tree): Option[List[Any]] = { - val macroDef = expandee.symbol - val runtime = macroRuntime(macroDef) - if (runtime == None) return None - + val macroDef = expandee.symbol + val runtime = macroRuntime(macroDef) orElse { return None } var prefixTree: Tree = EmptyTree - var typeArgs = List[Tree]() - val exprArgs = new ListBuffer[List[Expr[_]]] + var typeArgs = List[Tree]() + val exprArgs = 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 @@ -843,8 +842,8 @@ trait Macros { self: Analyzer => // 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 + val isEmptyParamlistDef = paramss_without_evidences.nonEmpty && paramss_without_evidences.last.isEmpty + val isEmptyArglistInvocation = argss.nonEmpty && argss.last.isEmpty if (isEmptyParamlistDef && !isEmptyArglistInvocation) { if (macroDebug) println("isEmptyParamlistDef && !isEmptyArglistInvocation: appending a List() to argss") argss = argss :+ Nil @@ -894,13 +893,13 @@ trait Macros { self: Analyzer => if (macroDebug) println("resolved tparam %s as %s".format(tparam, tpe)) resolved(tparam) = tpe param.tpe.typeSymbol match { - case sym if sym == definitions.TypeTagClass => + case definitions.TypeTagClass => // do nothing - case sym if sym == definitions.ConcreteTypeTagClass => + case definitions.ConcreteTypeTagClass => if (!tpe.isConcrete) context.abort(context.enclosingPosition, "cannot create ConcreteTypeTag from a type %s having unresolved type parameters".format(tpe)) // otherwise do nothing case _ => - throw new Error("unsupported tpe: %s".format(tpe)) + throw new Error("unsupported tpe: " + tpe) } Some(tparam) }) @@ -928,6 +927,16 @@ trait Macros { self: Analyzer => * See more informations in comments to ``openMacros'' in ``scala.reflect.makro.Context''. */ var openMacros = List[MacroContext]() + private def openMacroPos = openMacros map (_.expandee.pos) find (_ ne NoPosition) getOrElse NoPosition + + // !!! YOu should use a method like this which manages the stack. + // That you presently need to spread this logic out is a major + // design flaw. + private def pushMacroContext[T](mc: MacroContext)(body: => T): T = { + openMacros ::= mc + try body + finally openMacros = openMacros.tail + } /** Performs macro expansion: * 1) Checks whether the expansion needs to be delayed (see ``mustDelayMacroExpansion'') @@ -1064,96 +1073,95 @@ trait Macros { self: Analyzer => /** Expands a macro when a runtime (i.e. the macro implementation) can be successfully loaded * Meant for internal use within the macro infrastructure, don't use it elsewhere. */ - private def macroExpandWithRuntime(typer: Typer, expandee: Tree, runtime: MacroRuntime): MacroExpansionResult = - try { - val wasDelayed = isDelayed(expandee) + private def macroExpandWithRuntime(typer: Typer, expandee: Tree, runtime: MacroRuntime): MacroExpansionResult = { + def issueFreeError(sym: FreeSymbol) = { + val template = ( + "Macro expansion contains free @kind@ variable %s. Have you forgotten to use %s? " + + "If you have troubles tracking free @kind@ variables, consider using -Xlog-free-@kind@s" + ) + val forgotten = ( + if (sym.isTerm) "eval when splicing this variable into a reifee" + else "c.TypeTag annotation for this type parameter" + ) + typer.context.error(expandee.pos, + template.replaceAllLiterally("@kind@", sym.name.nameKind).format( + sym.name + " " + sym.origin, forgotten) + ) + } + def macroExpandInternal = { + val wasDelayed = isDelayed(expandee) val undetparams = calculateUndetparams(expandee) - val nowDelayed = !typer.context.macrosEnabled || undetparams.size != 0 - - if (!wasDelayed) { - if (macroDebug || macroCopypaste) println("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) - val args = macroArgs(typer, expandee) - args match { - case Some(args) => - val (context: MacroContext) :: _ = args + val nowDelayed = !typer.context.macrosEnabled || undetparams.nonEmpty + + def failExpansion(msg: String = null) = fail(typer, expandee, msg) + def performExpansion(args: List[Any]): MacroExpansionResult = { + val numErrors = reporter.ERROR.count + def hasNewErrors = reporter.ERROR.count > numErrors + + val expanded = runtime(args) + + if (hasNewErrors) + failExpansion() // errors have been reported by the macro itself + else expanded match { + case expanded: Expr[_] => + if (macroDebug) println("original:") + macroDebugLog("" + expanded.tree + "\n" + showRaw(expanded.tree)) + + freeTerms(expanded.tree) foreach issueFreeError + freeTypes(expanded.tree) foreach issueFreeError + // inherit the position from the first position-ful expandee in macro callstack + // this is essential for sane error messages + // now macro expansion gets typechecked against the macro definition return type + // however, this happens in macroExpand, not here in macroExpand1 + if (hasNewErrors) failExpansion() + else Success(atPos(openMacroPos.focus)(expanded.tree)) + case _ => + failExpansion( + "macro must return a compiler-specific expr; returned value is " + ( + if (expanded.isInstanceOf[Expr[_]]) " Expr, but it doesn't belong to this compiler's universe" + else " of " + expanded.getClass + ) + ) + } + } + + if (wasDelayed) { + if (nowDelayed) Delay(expandee) + else Skip(macroExpandAll(typer, expandee)) + } + else { + macroDebugLog("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) + macroArgs(typer, expandee).fold(failExpansion(): MacroExpansionResult) { + case args @ ((context: MacroContext) :: _) => if (nowDelayed) { - if (macroDebug || macroCopypaste) println("macro expansion is delayed: %s".format(expandee)) + macroDebugLog("macro expansion is delayed: %s".format(expandee)) delayed += expandee -> undetparams // need to save typer context for `macroExpandAll` // need to save macro context to preserve enclosures expandee attach MacroAttachment(delayed = true, typerContext = typer.context, macroContext = Some(context)) Delay(expandee) - } else { - val expanded: MacroExpansionResult = - try { - val prevNumErrors = reporter.ERROR.count - openMacros = context :: openMacros - 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 - } finally { - expandee.detach(classOf[MacroAttachment]) - } - if (!expanded.isInstanceOf[Success]) openMacros = openMacros.tail - expanded } - case None => - fail(typer, expandee) // error has been reported by macroArgs + else { + // adding stuff to openMacros is easy, but removing it is a nightmare + // it needs to be sprinkled over several different code locations + openMacros ::= args.head.asInstanceOf[MacroContext] + var isSuccess = false + try performExpansion(args) match { + case x: Success => isSuccess = true ; x + case x => x + } + finally { + expandee.detach(classOf[MacroAttachment]) + if (!isSuccess) openMacros = openMacros.tail + } + } } - } else { - if (nowDelayed) - Delay(expandee) - else - Skip(macroExpandAll(typer, expandee)) } - } catch { - case ex => handleMacroExpansionException(typer, expandee, ex) } + + try macroExpandInternal + catch { case ex => handleMacroExpansionException(typer, expandee, ex) } + } private def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroExpansionResult = { val macroDef = expandee.symbol @@ -1198,21 +1206,26 @@ trait Macros { self: Analyzer => fail(typer, expandee) } } + + @inline final def macroDebugLog(msg: => String) { + if (macroDebug || macroCopypaste) println(msg) + } - private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = { + private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = { // [Eugene] any ideas about how to improve this one? val realex = ReflectionUtils.unwrapThrowable(ex) realex match { case realex: reflect.makro.runtime.AbortMacroException => - if (macroDebug || macroCopypaste) println("macro expansion has failed: %s".format(realex.msg)) + macroDebugLog("macro expansion has failed: %s".format(realex.msg)) fail(typer, expandee) // error has been reported by abort case err: TypeError => - if (macroDebug || macroCopypaste) println("macro expansion has failed: %s at %s".format(err.msg, err.pos)) + macroDebugLog("macro expansion has failed: %s at %s".format(err.msg, err.pos)) throw err // error should be propagated, don't report case _ => val message = { try { // [Eugene] is there a better way? + // [Paul] See Exceptional.scala and Origins.scala. val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == "macroExpand1") if (relevancyThreshold == -1) None else { diff --git a/test/files/run/macro-reify-freevars.check b/test/files/run/macro-reify-freevars.check index 02a6a7436b..068742f0b6 100644 --- a/test/files/run/macro-reify-freevars.check +++ b/test/files/run/macro-reify-freevars.check @@ -1,3 +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 +reflective compilation has failed: + +Macro expansion contains free term variable code defined by map in Macros_1.scala:8:9. Have you forgotten 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-tagless-a.check b/test/files/run/macro-reify-tagless-a.check index b58cff19bc..4ee11190d6 100644 --- a/test/files/run/macro-reify-tagless-a.check +++ b/test/files/run/macro-reify-tagless-a.check @@ -1,3 +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 +reflective compilation has failed: + +Macro expansion contains free type variable T defined by foo in Impls_Macros_1.scala:7:13. Have you forgotten to use c.TypeTag annotation for this type parameter? If you have troubles tracking free type variables, consider using -Xlog-free-types -- cgit v1.2.3 From 99388a81d42cde0cb0e8ecd57f290f6df25b9bdd Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 26 Apr 2012 10:03:56 +0300 Subject: cleaning up macros, one step at a time --- .../scala/reflect/makro/runtime/Context.scala | 3 +- .../scala/reflect/makro/runtime/Traces.scala | 8 + .../scala/reflect/makro/runtime/Typers.scala | 17 +- src/compiler/scala/reflect/makro/util/Traces.scala | 18 ++ src/compiler/scala/reflect/reify/Errors.scala | 3 +- .../scala/reflect/reify/codegen/Types.scala | 2 +- .../scala/reflect/reify/codegen/Util.scala | 2 - src/compiler/scala/reflect/reify/package.scala | 10 +- .../scala/tools/nsc/settings/ScalaSettings.scala | 6 +- .../scala/tools/nsc/typechecker/Macros.scala | 201 +++++++++------------ src/library/scala/reflect/makro/Typers.scala | 2 +- 11 files changed, 135 insertions(+), 137 deletions(-) create mode 100644 src/compiler/scala/reflect/makro/runtime/Traces.scala create mode 100644 src/compiler/scala/reflect/makro/util/Traces.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/makro/runtime/Context.scala b/src/compiler/scala/reflect/makro/runtime/Context.scala index 15a4118b85..ca02822788 100644 --- a/src/compiler/scala/reflect/makro/runtime/Context.scala +++ b/src/compiler/scala/reflect/makro/runtime/Context.scala @@ -14,7 +14,8 @@ abstract class Context extends scala.reflect.makro.Context with Settings with Symbols with Typers - with Util { + with Util + with Traces { val mirror: Global diff --git a/src/compiler/scala/reflect/makro/runtime/Traces.scala b/src/compiler/scala/reflect/makro/runtime/Traces.scala new file mode 100644 index 0000000000..6b61842316 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Traces.scala @@ -0,0 +1,8 @@ +package scala.reflect.makro +package runtime + +trait Traces extends util.Traces { + self: Context => + + def globalSettings = mirror.settings +} diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala index 98dbd65b72..c61e492250 100644 --- a/src/compiler/scala/reflect/makro/runtime/Typers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala @@ -9,8 +9,7 @@ trait Typers { def 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)) + macroLogVerbose("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)) @@ -21,25 +20,24 @@ trait Typers { // (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) + macroLogVerbose(result) result case error @ mirror.analyzer.SilentTypeError(_) => - trace(error.err.errMsg) + macroLogVerbose(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)) + macroLogVerbose("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) import mirror.analyzer.SearchResult val context = callsiteTyper.context val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) def wrapper (inference: => SearchResult) = wrapper1(inference) 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") + macroLogVerbose("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 => @@ -48,8 +46,7 @@ trait Typers { } 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)) + macroLogVerbose("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous)) import mirror.analyzer.SearchResult val context = callsiteTyper.context val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) @@ -58,7 +55,7 @@ trait Typers { val viewTpe = mirror.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to)) wrapper(mirror.analyzer.inferImplicit(tree, 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") + macroLogVerbose("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 => diff --git a/src/compiler/scala/reflect/makro/util/Traces.scala b/src/compiler/scala/reflect/makro/util/Traces.scala new file mode 100644 index 0000000000..2363cc4bac --- /dev/null +++ b/src/compiler/scala/reflect/makro/util/Traces.scala @@ -0,0 +1,18 @@ +package scala.reflect.makro +package util + +trait Traces { + def globalSettings: tools.nsc.Settings + + // [Eugene] lots of ways to log: + // 1) trace(...) + // 2) log(...) + // 3) if (foo) { doStuff(); includingSomeLogs(); } + // what is the conventional way of unifying this? + val macroDebugLite = globalSettings.YmacrodebugLite.value + val macroDebugVerbose = globalSettings.YmacrodebugVerbose.value + val macroTraceLite = scala.tools.nsc.util.trace when (macroDebugLite || macroDebugVerbose) + val macroTraceVerbose = scala.tools.nsc.util.trace when macroDebugVerbose + @inline final def macroLogLite(msg: => Any) { if (macroDebugLite || macroDebugVerbose) println(msg) } + @inline final def macroLogVerbose(msg: => Any) { if (macroDebugVerbose) println(msg) } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala index 1a881455f2..4466f281b8 100644 --- a/src/compiler/scala/reflect/reify/Errors.scala +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -10,8 +10,7 @@ trait Errors { import mirror._ import definitions._ - lazy val defaultErrorPosition: Position = - mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication.pos).getOrElse(NoPosition) + def defaultErrorPosition = analyzer.enclosingMacroPosition // 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 diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala index 8fa24c5b00..1f336f4b0f 100644 --- a/src/compiler/scala/reflect/reify/codegen/Types.scala +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -99,7 +99,7 @@ trait Types { // 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)) - typer.resolveTypeTag(positionBearer.pos, prefix.tpe, tpe, concrete) match { + typer.resolveTypeTag(defaultErrorPosition, prefix.tpe, tpe, concrete) match { case failure if failure.isEmpty => if (reifyDebug) println("implicit search was fruitless") EmptyTree diff --git a/src/compiler/scala/reflect/reify/codegen/Util.scala b/src/compiler/scala/reflect/reify/codegen/Util.scala index 8d7cf39ff7..bb369a1adb 100644 --- a/src/compiler/scala/reflect/reify/codegen/Util.scala +++ b/src/compiler/scala/reflect/reify/codegen/Util.scala @@ -14,8 +14,6 @@ trait Util { object reifiedNodePrinters extends { val global: mirror.type = mirror } with tools.nsc.ast.NodePrinters with NodePrinters val reifiedNodeToString = reifiedNodePrinters.reifiedNodeToString - val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] - def reifyList(xs: List[Any]): Tree = mkList(xs map reify) diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index fa11c6313d..3f9d6200cd 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -31,8 +31,12 @@ package object reify { def reifyErasure(global: Global)(typer0: global.analyzer.Typer, tpe: global.Type, concrete: Boolean = true): global.Tree = { import global._ import definitions._ - val positionBearer = analyzer.openMacros.find(_.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] - val inScope = typer0.context.withMacrosDisabled(typer0.resolveErasureTag(positionBearer.pos, tpe, concrete = concrete), typer0.resolveArrayTag(positionBearer.pos, tpe)) + import analyzer.enclosingMacroPosition + + def erasureTagInScope = typer0.context.withMacrosDisabled(typer0.resolveErasureTag(enclosingMacroPosition, tpe, concrete = concrete)) + def arrayTagInScope = typer0.context.withMacrosDisabled(typer0.resolveArrayTag(enclosingMacroPosition, tpe)) + val inScope = (erasureTagInScope, arrayTagInScope) + inScope match { case (success, _) if !success.isEmpty => Select(success, nme.erasure) @@ -44,7 +48,7 @@ package object reify { val componentErasure = reifyErasure(global)(typer0, componentTpe, concrete) gen.mkMethodCall(arrayClassMethod, List(componentErasure)) } else { - if (tpe.isSpliceable && concrete) throw new ReificationError(positionBearer.pos, "tpe %s is an unresolved spliceable type".format(tpe)) + if (tpe.isSpliceable && concrete) throw new ReificationError(enclosingMacroPosition, "tpe %s is an unresolved spliceable type".format(tpe)) var erasure = tpe.erasure if (tpe.typeSymbol.isDerivedValueClass && global.phase.id < global.currentRun.erasurePhase.id) erasure = tpe gen.mkNullaryCall(Predef_classOf, List(erasure)) diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 6a5c4c92bc..91e31cae97 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -138,7 +138,7 @@ trait ScalaSettings extends AbsScalaSettings 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 YinlinerWarnings= BooleanSetting ("-Yinline-warnings", "Emit inlining warnings. (Normally surpressed due to high volume)") + val YinlinerWarnings= BooleanSetting ("-Yinline-warnings", "Emit inlining warnings. (Normally surpressed due to high volume)") 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.") @@ -172,7 +172,6 @@ trait ScalaSettings extends AbsScalaSettings 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.") @@ -193,7 +192,8 @@ trait ScalaSettings extends AbsScalaSettings 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 YmacrodebugLite = BooleanSetting("-Ymacro-debug-lite", "Trace essential macro-related activities.") + val YmacrodebugVerbose = BooleanSetting("-Ymacro-debug-verbose", "Trace all 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.") diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 14f09d9dc9..1b8a43bf27 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -10,6 +10,7 @@ import scala.compat.Platform.EOL import scala.reflect.makro.runtime.{Context => MacroContext} import scala.reflect.runtime.Mirror import util.Statistics._ +import scala.reflect.makro.util._ /** * Code to deal with macros, namely with: @@ -36,13 +37,12 @@ import util.Statistics._ * (Expr(elems)) * (TypeTag(Int)) */ -trait Macros { self: Analyzer => +trait Macros extends Traces { + self: Analyzer => + import global._ import definitions._ - - val macroDebug = settings.Ymacrodebug.value - val macroCopypaste = settings.Ymacrocopypaste.value - val macroTrace = scala.tools.nsc.util.trace when macroDebug + def globalSettings = global.settings val globalMacroCache = collection.mutable.Map[Any, Any]() val perRunMacroCache = perRunCaches.newMap[Symbol, collection.mutable.Map[Any, Any]] @@ -136,11 +136,11 @@ trait Macros { self: Analyzer => } import SigGenerator._ - macroTrace("generating macroImplSigs for: ")(macroDef) - macroTrace("tparams are: ")(tparams) - macroTrace("vparamss are: ")(vparamss) - macroTrace("retTpe is: ")(retTpe) - macroTrace("macroImplSigs are: ")(paramsss, implRetTpe) + macroTraceVerbose("generating macroImplSigs for: ")(macroDef) + macroTraceVerbose("tparams are: ")(tparams) + macroTraceVerbose("vparamss are: ")(vparamss) + macroTraceVerbose("retTpe is: ")(retTpe) + macroTraceVerbose("macroImplSigs are: ")(paramsss, implRetTpe) } private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Option[Symbol]): List[List[Symbol]] = { @@ -183,7 +183,7 @@ 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)) + macroLogVerbose("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos)) if (!typer.checkFeature(ddef.pos, MacrosFeature, immediate = true)) { ddef.symbol setFlag IS_ERROR @@ -267,7 +267,7 @@ trait Macros { self: Analyzer => val rhs = ddef.rhs validatePreTyper(rhs) - if (hasErrors) macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + if (hasErrors) macroTraceVerbose("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 @@ -284,12 +284,7 @@ trait Macros { self: Analyzer => case Success(expanded) => try { val typechecked = typer.typed1(expanded, EXPRmode, WildcardType) - if (macroDebug) { - println("typechecked1:") - println(typechecked) - println(showRaw(typechecked)) - } - + macroLogVerbose("typechecked1:%n%s%n%s".format(typechecked, showRaw(typechecked))) typechecked } finally { openMacros = openMacros.tail @@ -312,7 +307,7 @@ trait Macros { self: Analyzer => 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) + if (typecheckedWithErrors) macroTraceVerbose("body of a macro def failed to typecheck: ")(ddef) val macroImpl = rhs1.symbol macroDef withAnnotation AnnotationInfo(MacroImplAnnotation.tpe, List(rhs1), Nil) @@ -330,7 +325,7 @@ trait Macros { self: Analyzer => validatePostTyper(rhs1) } if (hasErrors) - macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef) } if (!hasErrors) { @@ -352,7 +347,7 @@ trait Macros { self: Analyzer => compatibilityError("number of parameter sections differ") def checkSubType(slot: String, reqtpe: Type, acttpe: Type): Unit = { - val ok = if (macroDebug) { + val ok = if (macroDebugVerbose) { if (reqtpe eq acttpe) println(reqtpe + " <: " + acttpe + "?" + EOL + "true") withTypesExplained(reqtpe <:< acttpe) } else reqtpe <:< acttpe @@ -437,7 +432,7 @@ trait Macros { self: Analyzer => 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) + macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef) } if (!hasErrors) { @@ -458,9 +453,9 @@ trait Macros { self: Analyzer => "\n found : "+showMeth(actparamss, actres, false)+ "\n"+addendum) - macroTrace("considering " + reqparamsss.length + " possibilities of compatible macro impl signatures for macro def: ")(ddef.name) + macroTraceVerbose("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) => + if (macroDebugVerbose) (reqparamsss zip results) foreach { case (reqparamss, result) => println("%s %s".format(if (result.isEmpty) "[ OK ]" else "[FAILED]", reqparamss)) result foreach (errorMsg => println(" " + errorMsg)) } @@ -472,7 +467,7 @@ trait Macros { self: Analyzer => compatibilityError(mostRelevantMessage) } else { assert((results filter (_.isEmpty)).length == 1, results) - if (macroDebug) (reqparamsss zip results) filter (_._2.isEmpty) foreach { case (reqparamss, result) => + if (macroDebugVerbose) (reqparamsss zip results) filter (_._2.isEmpty) foreach { case (reqparamss, result) => println("typechecked macro impl as: " + reqparamss) } } @@ -596,11 +591,11 @@ trait Macros { self: Analyzer => val libraryClassLoader = { if (settings.XmacroPrimaryClasspath.value != "") { - if (macroDebug) println("primary macro mirror: initializing from -Xmacro-primary-classpath: %s".format(settings.XmacroPrimaryClasspath.value)) + macroLogVerbose("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)) + macroLogVerbose("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) @@ -626,7 +621,7 @@ trait Macros { self: Analyzer => 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)) + macroLogVerbose("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) } @@ -649,24 +644,24 @@ trait Macros { self: Analyzer => private def macroRuntime(macroDef: Symbol): Option[MacroRuntime] = macroRuntimesCache.getOrElseUpdate(macroDef, { val runtime = { - macroTrace("looking for macro implementation: ")(macroDef) - macroTrace("macroDef is annotated with: ")(macroDef.annotations) + macroTraceVerbose("looking for macro implementation: ")(macroDef) + macroTraceVerbose("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) + macroTraceVerbose("@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) + macroTraceVerbose("@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)) + macroLogVerbose("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) + macroTraceVerbose("macro implementation is erroneous (this means that either macro body or macro implementation signature failed to typecheck)")(macroDef) return None } @@ -680,14 +675,14 @@ trait Macros { self: Analyzer => // 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")) + macroTraceVerbose("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName) + macroTraceVerbose("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 _ => "" } - macroTrace("classpath is: ")(inferClasspath(macroMirror.classLoader)) + macroTraceVerbose("classpath is: ")(inferClasspath(macroMirror.classLoader)) // [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? @@ -711,7 +706,7 @@ trait Macros { self: Analyzer => val implClassName = classfile(macroImpl.owner) val implClassSymbol: macroMirror.Symbol = macroMirror.symbolForName(implClassName) - if (macroDebug) { + if (macroDebugVerbose) { println("implClassSymbol is: " + implClassSymbol.fullNameString) if (implClassSymbol != macroMirror.NoSymbol) { @@ -723,7 +718,7 @@ trait Macros { self: Analyzer => } val implObjSymbol = implClassSymbol.companionModule - macroTrace("implObjSymbol is: ")(implObjSymbol.fullNameString) + macroTraceVerbose("implObjSymbol is: ")(implObjSymbol.fullNameString) if (implObjSymbol == macroMirror.NoSymbol) None else { @@ -733,29 +728,27 @@ trait Macros { self: Analyzer => 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 + case ex: NoSuchFieldException => macroTraceVerbose("exception when loading implObj: ")(ex); null + case ex: NoClassDefFoundError => macroTraceVerbose("exception when loading implObj: ")(ex); null + case ex: ClassNotFoundException => macroTraceVerbose("exception when loading implObj: ")(ex); null } if (implObj == null) None else { val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString)) - if (macroDebug) { - println("implMethSymbol is: " + implMethSymbol.fullNameString) - println("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol)) - } + macroLogVerbose("implMethSymbol is: " + implMethSymbol.fullNameString) + macroLogVerbose("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol)) if (implMethSymbol == macroMirror.NoSymbol) None else { - if (macroDebug) println("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol)) + macroLogVerbose("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) + macroTraceVerbose("implementation class failed to load: ")(ex.toString) None } } @@ -767,7 +760,7 @@ trait Macros { self: Analyzer => 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)) + macroLogVerbose("trying to load macro implementation from the fallback mirror: %s".format(settings.XmacroFallbackClasspath.value)) val fallback = loadMacroImpl(fallbackMirror) fallback match { case Some((implObj, implMethSymbol)) => @@ -827,13 +820,13 @@ trait Macros { self: Analyzer => collectMacroArgs(expandee) val context = expandee.attachmentOpt[MacroAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefixTree, expandee)) var argss: List[List[Any]] = List(context) :: exprArgs.toList - macroTrace("argss: ")(argss) + macroTraceVerbose("argss: ")(argss) 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) + macroTraceVerbose("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 @@ -845,7 +838,7 @@ trait Macros { self: Analyzer => val isEmptyParamlistDef = paramss_without_evidences.nonEmpty && paramss_without_evidences.last.isEmpty val isEmptyArglistInvocation = argss.nonEmpty && argss.last.isEmpty if (isEmptyParamlistDef && !isEmptyArglistInvocation) { - if (macroDebug) println("isEmptyParamlistDef && !isEmptyArglistInvocation: appending a List() to argss") + macroLogVerbose("isEmptyParamlistDef && !isEmptyArglistInvocation: appending a List() to argss") argss = argss :+ Nil } @@ -890,7 +883,7 @@ trait Macros { self: Analyzer => macroDef.owner) } else implRefTarg.tpe - if (macroDebug) println("resolved tparam %s as %s".format(tparam, tpe)) + macroLogVerbose("resolved tparam %s as %s".format(tparam, tpe)) resolved(tparam) = tpe param.tpe.typeSymbol match { case definitions.TypeTagClass => @@ -919,7 +912,7 @@ trait Macros { self: Analyzer => else as } val rawArgs = rawArgss.flatten - macroTrace("rawArgs: ")(rawArgs) + macroTraceVerbose("rawArgs: ")(rawArgs) Some(rawArgs) } @@ -927,16 +920,7 @@ trait Macros { self: Analyzer => * See more informations in comments to ``openMacros'' in ``scala.reflect.makro.Context''. */ var openMacros = List[MacroContext]() - private def openMacroPos = openMacros map (_.expandee.pos) find (_ ne NoPosition) getOrElse NoPosition - - // !!! YOu should use a method like this which manages the stack. - // That you presently need to spread this logic out is a major - // design flaw. - private def pushMacroContext[T](mc: MacroContext)(body: => T): T = { - openMacros ::= mc - try body - finally openMacros = openMacros.tail - } + def enclosingMacroPosition = openMacros map (_.macroApplication.pos) find (_ ne NoPosition) getOrElse NoPosition /** Performs macro expansion: * 1) Checks whether the expansion needs to be delayed (see ``mustDelayMacroExpansion'') @@ -945,13 +929,13 @@ trait Macros { self: Analyzer => * 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 + * If -Ymacro-debug-lite is enabled, you will get basic notifications about macro expansion + * along with macro expansions logged in the form that can be copy/pasted verbatim into REPL. + * + * If -Ymacro-debug-verbose 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, @@ -963,7 +947,7 @@ trait Macros { self: Analyzer => def macroExpand(typer: Typer, expandee: Tree, mode: Int = EXPRmode, pt: Type = WildcardType): Tree = { def fail(what: String, tree: Tree): Tree = { val err = typer.context.errBuffer.head - this.fail(typer, tree, "failed to perform %s: %s at %s".format(what, err.errMsg, err.errPos)) + this.fail(typer, tree, "failed to %s: %s at %s".format(what, err.errMsg, err.errPos)) return expandee } val start = startTimer(macroExpandNanos) @@ -984,31 +968,23 @@ trait Macros { self: Analyzer => } if (isNullaryInvocation) expectedTpe match { case NullaryMethodType(restpe) => - macroTrace("nullary invocation of a nullary method. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) + macroTraceVerbose("nullary invocation of a nullary method. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) expectedTpe = restpe case MethodType(Nil, restpe) => - macroTrace("nullary invocation of a method with an empty parameter list. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) + macroTraceVerbose("nullary invocation of a method with an empty parameter list. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) expectedTpe = restpe case _ => ; } - if (macroDebug) println("typechecking1 against %s: %s".format(expectedTpe, expanded)) + macroLogVerbose("typechecking1 against %s: %s".format(expectedTpe, expanded)) var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe)) - if (typer.context.hasErrors) fail("typecheck1", expanded) - if (macroDebug) { - println("typechecked1:") - println(typechecked) - println(showRaw(typechecked)) - } + if (typer.context.hasErrors) fail("typecheck against macro def return type", expanded) + macroLogVerbose("typechecked1:%n%s%n%s".format(typechecked, showRaw(typechecked))) - if (macroDebug) println("typechecking2 against %s: %s".format(pt, expanded)) + macroLogVerbose("typechecking2 against %s: %s".format(pt, expanded)) typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt)) - if (typer.context.hasErrors) fail("typecheck2", expanded) - if (macroDebug) { - println("typechecked2:") - println(typechecked) - println(showRaw(typechecked)) - } + if (typer.context.hasErrors) fail("typecheck against expected type", expanded) + macroLogVerbose("typechecked2:%n%s%n%s".format(typechecked, showRaw(typechecked))) typechecked } finally { @@ -1033,11 +1009,9 @@ trait Macros { self: Analyzer => 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 != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg - if (macroDebug) 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) + def msgForLog = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg + macroLogVerbose("macro expansion has failed: %s".format(msgForLog)) + val pos = if (expandee.pos != NoPosition) expandee.pos else enclosingMacroPosition if (msg != null) typer.context.error(pos, msg) typer.infer.setError(expandee) Failure(expandee) @@ -1058,7 +1032,7 @@ trait Macros { self: Analyzer => // 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) + macroTraceVerbose("cancelled macro expansion because of %s: ".format(reason))(expandee) return Cancel(typer.infer.setError(expandee)) } @@ -1092,7 +1066,7 @@ trait Macros { self: Analyzer => val wasDelayed = isDelayed(expandee) val undetparams = calculateUndetparams(expandee) val nowDelayed = !typer.context.macrosEnabled || undetparams.nonEmpty - + def failExpansion(msg: String = null) = fail(typer, expandee, msg) def performExpansion(args: List[Any]): MacroExpansionResult = { val numErrors = reporter.ERROR.count @@ -1104,17 +1078,18 @@ trait Macros { self: Analyzer => failExpansion() // errors have been reported by the macro itself else expanded match { case expanded: Expr[_] => - if (macroDebug) println("original:") - macroDebugLog("" + expanded.tree + "\n" + showRaw(expanded.tree)) + macroLogVerbose("original:") + macroLogVerbose("" + expanded.tree + "\n" + showRaw(expanded.tree)) freeTerms(expanded.tree) foreach issueFreeError freeTypes(expanded.tree) foreach issueFreeError + if (hasNewErrors) failExpansion() + // inherit the position from the first position-ful expandee in macro callstack // this is essential for sane error messages // now macro expansion gets typechecked against the macro definition return type // however, this happens in macroExpand, not here in macroExpand1 - if (hasNewErrors) failExpansion() - else Success(atPos(openMacroPos.focus)(expanded.tree)) + else Success(atPos(enclosingMacroPosition.focus)(expanded.tree)) case _ => failExpansion( "macro must return a compiler-specific expr; returned value is " + ( @@ -1130,11 +1105,11 @@ trait Macros { self: Analyzer => else Skip(macroExpandAll(typer, expandee)) } else { - macroDebugLog("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) + macroLogVerbose("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) macroArgs(typer, expandee).fold(failExpansion(): MacroExpansionResult) { case args @ ((context: MacroContext) :: _) => if (nowDelayed) { - macroDebugLog("macro expansion is delayed: %s".format(expandee)) + macroLogVerbose("macro expansion is delayed: %s".format(expandee)) delayed += expandee -> undetparams // need to save typer context for `macroExpandAll` // need to save macro context to preserve enclosures @@ -1144,7 +1119,9 @@ trait Macros { self: Analyzer => else { // adding stuff to openMacros is easy, but removing it is a nightmare // it needs to be sprinkled over several different code locations - openMacros ::= args.head.asInstanceOf[MacroContext] + // why? https://github.com/scala/scala/commit/bd3eacbae21f39b1ac7fe8ade4ed71fa98e1a28d#L2R1137 + // todo. will be improved + openMacros ::= context var isSuccess = false try performExpansion(args) match { case x: Success => isSuccess = true ; x @@ -1158,7 +1135,7 @@ trait Macros { self: Analyzer => } } } - + try macroExpandInternal catch { case ex => handleMacroExpansionException(typer, expandee, ex) } } @@ -1179,7 +1156,7 @@ trait Macros { self: Analyzer => case first :: _ => Some(Select(qual, name) setPos tree.pos setSymbol first) case _ => - macroTrace("macro is not overridden: ")(tree) + macroTraceVerbose("macro is not overridden: ")(tree) notFound() } case Apply(fn, args) => @@ -1193,33 +1170,29 @@ trait Macros { self: Analyzer => case _ => None } case _ => - macroTrace("unexpected tree in fallback: ")(tree) + macroTraceVerbose("unexpected tree in fallback: ")(tree) notFound() } } fallBackToOverridden(expandee) match { case Some(tree1) => - macroTrace("falling back to: ")(tree1) + macroTraceVerbose("falling back to: ")(tree1) currentRun.macroExpansionFailed = true Fallback(tree1) case None => fail(typer, expandee) } } - - @inline final def macroDebugLog(msg: => String) { - if (macroDebug || macroCopypaste) println(msg) - } - private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = { + private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = { // [Eugene] any ideas about how to improve this one? val realex = ReflectionUtils.unwrapThrowable(ex) realex match { case realex: reflect.makro.runtime.AbortMacroException => - macroDebugLog("macro expansion has failed: %s".format(realex.msg)) + macroLogVerbose("macro expansion has failed: %s".format(realex.msg)) fail(typer, expandee) // error has been reported by abort case err: TypeError => - macroDebugLog("macro expansion has failed: %s at %s".format(err.msg, err.pos)) + macroLogVerbose("macro expansion has failed: %s at %s".format(err.msg, err.pos)) throw err // error should be propagated, don't report case _ => val message = { @@ -1271,24 +1244,24 @@ trait Macros { self: Analyzer => if (sub.symbol != null) traverse(sub.symbol) if (sub.tpe != null) sub.tpe foreach (sub => traverse(sub.typeSymbol)) }) - if (macroDebug) println("calculateUndetparams: %s".format(calculated)) + macroLogVerbose("calculateUndetparams: %s".format(calculated)) calculated map (_.id) } private val undetparams = perRunCaches.newSet[Int] def notifyUndetparamsAdded(newUndets: List[Symbol]): Unit = { undetparams ++= newUndets map (_.id) - if (macroDebug) newUndets foreach (sym => println("undetParam added: %s".format(sym))) + if (macroDebugVerbose) newUndets foreach (sym => println("undetParam added: %s".format(sym))) } def notifyUndetparamsInferred(undetNoMore: List[Symbol], inferreds: List[Type]): Unit = { undetparams --= undetNoMore map (_.id) - if (macroDebug) (undetNoMore zip inferreds) foreach {case (sym, tpe) => println("undetParam inferred: %s as %s".format(sym, tpe))} + if (macroDebugVerbose) (undetNoMore zip inferreds) foreach { case (sym, tpe) => println("undetParam inferred: %s as %s".format(sym, tpe))} 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) + macroTraceVerbose("macro expansion is pending: ")(expandee) } case _ => // do nothing diff --git a/src/library/scala/reflect/makro/Typers.scala b/src/library/scala/reflect/makro/Typers.scala index 1ced2daccd..c62c5f254c 100644 --- a/src/library/scala/reflect/makro/Typers.scala +++ b/src/library/scala/reflect/makro/Typers.scala @@ -29,7 +29,7 @@ trait Typers { * * 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. + * Such errors don't vanish and can be inspected by turning on -Ymacro-debug-verbose. * Unlike in ``inferImplicitValue'' and ``inferImplicitView'', ``silent'' is false by default. * * Typechecking can be steered with the following optional parameters: -- cgit v1.2.3 From efd1293df967a10211ca877130f97955be94dc30 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 26 Apr 2012 15:29:07 +0200 Subject: SI-5690: no-selector match in function yields function the implicit beta-reduction performed by typedFunction on a Function(.., Match(EmptyTree, ...)) must of course only be done when the selector actually is empty... (yes, typedMatchAnonFun needs to be cleaned up, I know) --- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 +- test/files/pos/virtpatmat_partialfun_nsdnho.scala | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 test/files/pos/virtpatmat_partialfun_nsdnho.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 934a7567d5..e4c3dcfa55 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2439,7 +2439,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser fun.body match { // later phase indicates scaladoc is calling (where shit is messed up, I tell you) // -- so fall back to old patmat, which is more forgiving - case Match(sel, cases) if doMatchTranslation => + case Match(sel, cases) if (sel ne EmptyTree) && doMatchTranslation => // 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) diff --git a/test/files/pos/virtpatmat_partialfun_nsdnho.scala b/test/files/pos/virtpatmat_partialfun_nsdnho.scala new file mode 100644 index 0000000000..f79e82813c --- /dev/null +++ b/test/files/pos/virtpatmat_partialfun_nsdnho.scala @@ -0,0 +1,18 @@ +class Test { + // m.$minus(1) + // at scala.Predef$.assert(Predef.scala:185) + // at scala.tools.nsc.Global.assert(Global.scala:187) + // at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:291) + val a: (Map[Int, Int] => (Any => Any)) = { m => { case _ => m - 1} } + + // patmat-crash.scala:9: error: erroneous or inaccessible type + val b: (Int => (Any => Any)) = { m => { case _ => m } } + + // no-symbol does not have an owner (this is a bug: scala version 2.10.0-20120420-170445-56c1f29250) + // at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:45) + // at scala.tools.nsc.Global.abort(Global.scala:202) + // at scala.reflect.internal.Symbols$NoSymbol.owner(Symbols.scala:3031) + // at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.hostForAccessorOf(SuperAccessors.scala:474) + // at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.needsProtectedAccessor(SuperAccessors.scala:457) + val c: (Int => (Any => Any)) = { m => { case _ => m.toInt } } +} \ No newline at end of file -- cgit v1.2.3 From 17165269e22f8e4b60483d1277eb841131c3686d Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 26 Apr 2012 17:08:05 +0200 Subject: clean up typedMatchAnonFun --- .../scala/tools/nsc/typechecker/Typers.scala | 90 ++++++++++++---------- 1 file changed, 51 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index e4c3dcfa55..6234c05258 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2249,43 +2249,35 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser } } - def typedMatchAnonFun(tree: Tree, cases: List[CaseDef], mode: Int, pt0: Type, selOverride: Option[(List[ValDef], Tree)] = None) = { - val pt = deskolemizeGADTSkolems(pt0) - val targs = pt.normalize.typeArgs - val arity = if (isFunctionType(pt)) targs.length - 1 else 1 // TODO pt should always be a (Partial)Function, right? - val ptRes = if (targs.isEmpty) WildcardType else targs.last // may not be fully defined + // synthesize and type check a (Partial)Function implementation based on a match specified by `cases` + // Match(EmptyTree, cases) ==> new Function { def apply(params) = `translateMatch('`(param1,...,paramN)` match { cases }')` } + // for fresh params, the selector of the match we'll translated simply gathers those in a tuple + class MatchFunTyper(tree: Tree, cases: List[CaseDef], mode: Int, pt0: Type) { + private val pt = deskolemizeGADTSkolems(pt0) + private val targs = pt.normalize.typeArgs + private val arity = if (isFunctionType(pt)) targs.length - 1 else 1 // TODO pt should always be a (Partial)Function, right? + private val ptRes = if (targs.isEmpty) WildcardType else targs.last // may not be fully defined - val isPartial = pt.typeSymbol == PartialFunctionClass - val anonClass = context.owner.newAnonymousFunctionClass(tree.pos) - val funThis = This(anonClass) - val serialVersionUIDAnnotation = AnnotationInfo(SerialVersionUIDAttr.tpe, List(Literal(Constant(0))), List()) + private val isPartial = pt.typeSymbol == PartialFunctionClass + private val anonClass = context.owner.newAnonymousFunctionClass(tree.pos) + private val funThis = This(anonClass) - anonClass addAnnotation serialVersionUIDAnnotation + anonClass addAnnotation AnnotationInfo(SerialVersionUIDAttr.tpe, List(Literal(Constant(0))), List()) def deriveFormals = - selOverride match { - case None if targs.isEmpty => Nil - case None => targs.init // is there anything we can do if targs.isEmpty?? - case Some((vparams, _)) => - vparams map {p => if(p.tpt.tpe == null) typedType(p.tpt).tpe else p.tpt.tpe} - } + if (targs.isEmpty) Nil + else targs.init - def mkParams(methodSym: Symbol, formals: List[Type] = deriveFormals) = { - selOverride match { - case None if targs.isEmpty => MissingParameterTypeAnonMatchError(tree, pt); (Nil, EmptyTree) - case None => - val ps = methodSym newSyntheticValueParams formals // is there anything we can do if targs.isEmpty?? - val ids = ps map (p => Ident(p.name)) - val sel = atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) } - (ps, sel) - case Some((vparams, sel)) => - val newParamSyms = (vparams, formals).zipped map {(p, tp) => - methodSym.newValueParameter(p.name, p.pos.focus, SYNTHETIC) setInfo tp - } + def mkParams(methodSym: Symbol, formals: List[Type] = deriveFormals) = + if (formals.isEmpty) { MissingParameterTypeAnonMatchError(tree, pt); Nil } + else methodSym newSyntheticValueParams formals - (newParamSyms, sel.duplicate) + def mkSel(params: List[Symbol]) = + if (params.isEmpty) EmptyTree + else { + val ids = params map (p => Ident(p.name)) + atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) } } - } import CODE._ @@ -2298,7 +2290,8 @@ trait Typers extends Modes with Adaptations with Taggings 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, if(isPartial) (FINAL | OVERRIDE) else FINAL) - val (paramSyms, selector) = mkParams(methodSym) + val paramSyms = mkParams(methodSym) + val selector = mkSel(paramSyms) if (selector eq EmptyTree) EmptyTree else { @@ -2329,9 +2322,10 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser val methodSym = anonClass.newMethod(nme.applyOrElse, tree.pos, FINAL | OVERRIDE) // create the parameter that corresponds to the function's parameter - val List(argTp) = deriveFormals - val A1 = methodSym newTypeParameter(newTypeName("A1")) setInfo TypeBounds.upper(argTp) - val (List(x), selector) = mkParams(methodSym, List(A1.tpe)) + val List(argTp) = deriveFormals + val A1 = methodSym newTypeParameter(newTypeName("A1")) setInfo TypeBounds.upper(argTp) + val paramSyms@List(x) = mkParams(methodSym, List(A1.tpe)) + val selector = mkSel(paramSyms) if (selector eq EmptyTree) EmptyTree else { @@ -2362,7 +2356,9 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser def isDefinedAtMethod = { val methodSym = anonClass.newMethod(nme.isDefinedAt, tree.pos, FINAL) - val (paramSyms, selector) = mkParams(methodSym) + val paramSyms = mkParams(methodSym) + val selector = mkSel(paramSyms) + 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) @@ -2382,8 +2378,23 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser else List(applyOrElseMethodDef, isDefinedAtMethod) } else List(applyMethod) - if (members.head eq EmptyTree) setError(tree) - else typed(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos)), New(anonClass.tpe)), mode, pt) + def translated = + if (members.head eq EmptyTree) setError(tree) + else typed(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos)), New(anonClass.tpe)), mode, pt) + } + + // Function(params, Match(sel, cases)) ==> new Function { def apply(params) = `translateMatch('sel match { cases }')` } + class MatchFunTyperBetaReduced(fun: Function, sel: Tree, cases: List[CaseDef], mode: Int, pt: Type) extends MatchFunTyper(fun, cases, mode, pt) { + override def deriveFormals = + fun.vparams map { p => if(p.tpt.tpe == null) typedType(p.tpt).tpe else p.tpt.tpe } + + // the only difference from the super class is that we must preserve the names of the parameters + override def mkParams(methodSym: Symbol, formals: List[Type] = deriveFormals) = + (fun.vparams, formals).zipped map { (p, tp) => + methodSym.newValueParameter(p.name, p.pos.focus, SYNTHETIC) setInfo tp + } + + override def mkSel(params: List[Symbol]) = sel.duplicate } /** @@ -2443,7 +2454,8 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser // 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))) + val outerTyper = newTyper(context.outer) + (new outerTyper.MatchFunTyperBetaReduced(fun, sel, cases, mode, pt)).translated case _ => val vparamSyms = fun.vparams map { vparam => enterSym(context, vparam) @@ -3835,7 +3847,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser if (selector ne EmptyTree) { val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = typedMatch(selector, cases, mode, pt) typed(translatedMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt) - } else typedMatchAnonFun(tree, cases, mode, pt) + } else (new MatchFunTyper(tree, cases, mode, pt)).translated } else if (selector == EmptyTree) { if (opt.virtPatmat) debugwarn("virtpatmat should not encounter empty-selector matches "+ tree) val arity = if (isFunctionType(pt)) pt.normalize.typeArgs.length - 1 else 1 -- cgit v1.2.3 From 2aa44c230c96b0ceb8e2b84c8095620a1be5a77f Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 26 Apr 2012 07:02:55 -0700 Subject: A brand new, fast classfile parser. Try it: ./tools/dump-class ./build/quick/classes The output is intended to be easy to filter on the command line. This is a starting point for lots of interesting bytecode analysis for which we have waited too long. Example. All generic signatures we produce. // almost 20K classfiles % find build/quick/classes -name '*.class' |wc -l 18519 // fully parsed in 6 seconds tools/dump-class build/quick/classes |grep "^ signature" | wc -l 50802 real 0m6.230s It's designed to be easy to make faster if you don't care about particular classfile bits; you can override those methods to jump forward in the input stream rather than building a structure. For just a little sampling, here are our most frequently repeated name/signature combinations. 194 signature ()V // this one is weird, wonder why there's a generic signature 115 signature $div$colon$bslash (TA1;Lscala/Function2;)TA1; 105 signature applyOrElse (TA1;Lscala/Function1;)TB1; 103 signature view ()Ljava/lang/Object; 101 signature toSet ()Lscala/collection/immutable/Set; And the top five name/descriptor combinations. 11170 descriptor ()V 10155 descriptor serialVersionUID J 7130 descriptor apply (Ljava/lang/Object;)Ljava/lang/Object; 3028 descriptor apply ()Ljava/lang/Object; 2426 descriptor ()V --- .../scala/reflect/internal/JvmClassInfo.scala | 440 +++++++++++++++++++++ .../scala/tools/cmd/program/DumpClass.scala | 40 ++ src/compiler/scala/tools/util/StringOps.scala | 10 + test/files/run/inner-parse.check | 86 ++++ test/files/run/inner-parse/J_1.java | 9 + test/files/run/inner-parse/S_2.scala | 9 + test/files/run/inner-parse/S_3.scala | 12 + tools/dump-class | 6 + 8 files changed, 612 insertions(+) create mode 100644 src/compiler/scala/reflect/internal/JvmClassInfo.scala create mode 100644 src/compiler/scala/tools/cmd/program/DumpClass.scala create mode 100644 test/files/run/inner-parse.check create mode 100644 test/files/run/inner-parse/J_1.java create mode 100644 test/files/run/inner-parse/S_2.scala create mode 100644 test/files/run/inner-parse/S_3.scala create mode 100755 tools/dump-class (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/JvmClassInfo.scala b/src/compiler/scala/reflect/internal/JvmClassInfo.scala new file mode 100644 index 0000000000..d47f51e512 --- /dev/null +++ b/src/compiler/scala/reflect/internal/JvmClassInfo.scala @@ -0,0 +1,440 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.reflect.internal + +import java.io.{ DataInput, InputStream, DataInputStream, ByteArrayInputStream, BufferedInputStream, FileInputStream } +import scala.tools.nsc.io.{ Directory } +import scala.reflect.NameTransformer.decode +import scala.tools.util.StringOps.trimTrailingSpace +import ConstantPool._ + +final case class JvmVersion(minorVersion: Int, majorVersion: Int) + +trait ClassfileModel { + type Result + type Entry + type InterfaceInfo + type MemberInfo + type AttributeInfo + type InnerClassInfo + + protected implicit def EntryArrayTag: ArrayTag[Entry] + protected implicit def InterfaceInfoArrayTag: ArrayTag[InterfaceInfo] + protected implicit def MemberInfoArrayTag: ArrayTag[MemberInfo] + protected implicit def AttributeInfoArrayTag: ArrayTag[AttributeInfo] + protected implicit def InnerClassInfoArrayTag: ArrayTag[InnerClassInfo] + + // These could be implemented to jump forward in the stream if the + // result is not wanted. + def readConstantPoolEntry(): Entry + def readInterface(): InterfaceInfo + def readMember(): MemberInfo + def readAttribute(): AttributeInfo + def readInnerClass(): InnerClassInfo + + def createInfo( + version: JvmVersion, + entries: Array[Entry], + flags: Int, + name: String, + superName: String, + interfaces: Array[InterfaceInfo], + fields: Array[MemberInfo], + methods: Array[MemberInfo], + attributes: Array[AttributeInfo] + ): Result +} + +abstract class StreamingClassfileModel extends ClassfileModel { + protected[this] val in: DataInput + private[this] var name: String = _ + private[this] var entries: Array[PoolEntry] = _ + + type Entry = PoolEntry + + // These translate null into "", it's less troublesome. + protected def nameAt(idx: Int) = entries(idx) match { + case x: Name_Info => stringAt(x.name_index).replace('/', '.') + case _ => "" + } + protected def stringAt(idx: Int) = entries(idx) match { + case x: Utf8_info => x.stringValue + case _ => "" + } + + protected def u4 = in.readInt + protected def u2 = in.readUnsignedShort.toChar + protected def u1 = in.readUnsignedByte + + // The constant_pool table is indexed from 1 to constant_pool_count−1. + protected def readConstantPool(): Array[Entry] = { + val count = u2 + val entries = new Array[Entry](count) + var i = 1 + while (i < count) { + val entry = readConstantPoolEntry() + entries(i) = entry + i += entry.width + } + entries + } + protected def readInterfaces() = { + val count = u2 + val interfaces = new Array[InterfaceInfo](count) + var i = 0 + while (i < count) { + interfaces(i) = readInterface() + i += 1 + } + interfaces + } + protected def readMembers() = { + val count = u2 + val arr = new Array[MemberInfo](count) + var i = 0 + while (i < count) { + arr(i) = readMember() + i += 1 + } + arr + } + protected def readAttributes(): Array[AttributeInfo] = { + val count = u2 + val arr = new Array[AttributeInfo](count) + var i = 0 + while (i < count) { + arr(i) = readAttribute() + i += 1 + } + arr + } + protected def readInnerClasses() = { + val count = u2 + val arr = new Array[InnerClassInfo](count) + var i = 0 + while (i < count) { + arr(i) = readInnerClass() + i += 1 + } + arr + } + protected def thisClass = name + + def parse() = { + assert(u4 == 0xCAFEBABE, "Bad magic number") + val version = JvmVersion(u2, u2) + this.entries = readConstantPool() + val flags = u2.toShort + this.name = nameAt(u2) + val superName = nameAt(u2) + val interfaces = readInterfaces() + val fields = readMembers() + val methods = readMembers() + val attributes = readAttributes() + + try createInfo(version, entries, flags, name, superName, interfaces, fields, methods, attributes) + finally entries = null + } +} + +abstract class ScalacClassfileModel extends StreamingClassfileModel { + type Result = JvmClassInfo + type InterfaceInfo = String + type MemberInfo = JvmMemberInfo + type AttributeInfo = JvmAttributeInfo + type InnerClassInfo = JvmInnerClassInfo + + protected implicit def EntryArrayTag = arrayTag[PoolEntry] + protected implicit def InterfaceInfoArrayTag = arrayTag[InterfaceInfo] + protected implicit def MemberInfoArrayTag = arrayTag[MemberInfo] + protected implicit def AttributeInfoArrayTag = arrayTag[AttributeInfo] + protected implicit def InnerClassInfoArrayTag = arrayTag[InnerClassInfo] + + def readConstantPoolEntry(): PoolEntry + def readInterface(): String + def readMember(): JvmMemberInfo + def readAttribute(): JvmAttributeInfo + def readInnerClass(): JvmInnerClassInfo + + def createInfo( + version: JvmVersion, + entries: Array[PoolEntry], + flags: Int, + name: String, + superName: String, + interfaces: Array[String], + fields: Array[JvmMemberInfo], + methods: Array[JvmMemberInfo], + attributes: Array[JvmAttributeInfo] + ): JvmClassInfo = new JvmClassInfo(name, superName, interfaces, fields, methods, attributes) +} + +class JvmClassInfoBuilder(protected[this] val in: DataInput) extends ScalacClassfileModel { + def readInterface(): InterfaceInfo = nameAt(u2) + def readMember(): JvmMemberInfo = new JvmMemberInfo(u2.toShort, stringAt(u2), stringAt(u2), readAttributes()) + def readInnerClass(): JvmInnerClassInfo = new JvmInnerClassInfo(thisClass, nameAt(u2), nameAt(u2), stringAt(u2), u2.toShort) + + def readConstantPoolEntry(): Entry = (u1: @annotation.switch) match { + case CONSTANT_Utf8 => new Utf8_info(in.readUTF) + case CONSTANT_Integer => new Integer_info(in.readInt) + case CONSTANT_Float => new Float_info(in.readFloat) + case CONSTANT_Long => new Long_info(in.readLong) + case CONSTANT_Double => new Double_info(in.readDouble) + case CONSTANT_Class => new Class_info(u2) + case CONSTANT_String => new String_info(u2) + case CONSTANT_Fieldref => new Fieldref_info(u2, u2) + case CONSTANT_Methodref => new Methodref_info(u2, u2) + case CONSTANT_InterfaceMethodref => new InterfaceMethodref_info(u2, u2) + case CONSTANT_NameAndType => new NameAndType_info(u2, u2) + } + + // field_info attributes: + // ConstantValue (§4.7.2), Synthetic (§4.7.8), Signature (§4.7.9), Deprecated (§4.7.15), + // RuntimeVisibleAnnotations (§4.7.16) and RuntimeInvisibleAnnotations (§4.7.17). + // + // method_info attributes: + // Code (§4.7.3), Exceptions (§4.7.5), Synthetic (§4.7.8), Signature (§4.7.9), Deprecated (§4.7.15), + // RuntimeVisibleAnnotations (§4.7.16), RuntimeInvisibleAnnotations (§4.7.17), RuntimeVisibleParameterAnnotations (§4.7.18), + // RuntimeInvisibleParameterAnnotations (§4.7.19) and AnnotationDefault (§4.7.20). + + def readAttribute(): AttributeInfo = stringAt(u2) match { + case "Signature" => u4 ; new SignatureAttr(stringAt(u2)) + case "InnerClasses" => u4 ; new InnerClassesAttr(readInnerClasses()) + case name => val bytes = new Array[Byte](u4) ; in.readFully(bytes) ; new GenericAttr(name, bytes) + } +} + +object Classify { + + /* + + + 4.2.2 Unqualified Names + +Names of methods, fields and local variables are stored as unqualified +names. Unqualified names must not contain the characters '.', ';', '[' +or '/'. Method names are further constrained so that, with the exception +of the special method names and (§3.9), they must not +contain the characters '<' or '>'. + + 4.3 Descriptors and Signatures + +A descriptor is a string representing the type of a field or method. +Descriptors are represented in the class file format using modified +UTF-8 strings (§4.4.7) and thus may be drawn, where not further +constrained, from the entire Unicode character set. A signature is a +string representing the generic type of a field or method, or generic +type information for a class declaration. +*/ + +} + +object ConstantPool { + type UShort = Char + + final val CONSTANT_Utf8 = 1 + final val CONSTANT_Integer = 3 + final val CONSTANT_Float = 4 + final val CONSTANT_Long = 5 + final val CONSTANT_Double = 6 + final val CONSTANT_Class = 7 + final val CONSTANT_String = 8 + final val CONSTANT_Fieldref = 9 + final val CONSTANT_Methodref = 10 + final val CONSTANT_InterfaceMethodref = 11 + final val CONSTANT_NameAndType = 12 + + abstract class Name_Info(tag: Byte) extends PoolEntry(tag) { + def name_index: UShort + } + abstract class Ref_Info(tag: Byte) extends PoolEntry(tag) { + def class_index: UShort + def name_and_type_index: UShort + } + class Class_info(val name_index: UShort) extends Name_Info(CONSTANT_Class) { } + class Double_info(val value: Double) extends PoolEntry(CONSTANT_Double) { + override def width = 2 + } + class Fieldref_info(val class_index: UShort, val name_and_type_index: UShort) extends Ref_Info(CONSTANT_Fieldref) + class Float_info(val value: Float) extends PoolEntry(CONSTANT_Float) + class Integer_info(val value: Int) extends PoolEntry(CONSTANT_Integer) + class InterfaceMethodref_info(val class_index: UShort, val name_and_type_index: UShort) extends Ref_Info(CONSTANT_InterfaceMethodref) + class Long_info(val value: Long) extends PoolEntry(CONSTANT_Long) { + override def width = 2 + } + class Methodref_info(val class_index: UShort, val name_and_type_index: UShort) extends Ref_Info(CONSTANT_Methodref) + class NameAndType_info(val name_index: UShort, val descriptor_index: UShort) extends Name_Info(CONSTANT_NameAndType) { + override def toString = "NameAndType #%s:#%s;".format(name_index, descriptor_index) + } + class String_info(val string_index: UShort) extends PoolEntry(CONSTANT_String) { } + class Utf8_info(override val stringValue: String) extends PoolEntry(CONSTANT_Utf8) { + override def toString = ("Asciz " + stringValue).trim + } + + abstract class PoolEntry(tag: Byte) { + def width = 1 + def stringValue: String = sys.error("Not a String-valued constant pool entry: " + this) + override def toString = ( + getClass.getName.split("[.$]").last + "/" + tag + ) + } + object NoEntry extends PoolEntry(-1) { } +} + +abstract class JvmInfo(attributes: Array[JvmAttributeInfo]) { + // def flags: Short + def name: String + + val signature = attributes collectFirst { case x: SignatureAttr => x.value } getOrElse "" + val innerClasses = attributes collectFirst { case x: InnerClassesAttr => x.value } getOrElse Array() +} + + +class JvmClassInfo( + val name: String, + val superName: String, + val interfaces: Array[String], + val fields: Array[JvmMemberInfo], + val methods: Array[JvmMemberInfo], + attributes: Array[JvmAttributeInfo] +) extends JvmInfo(attributes) { + + def members = fields ++ methods sortBy (_.decodedName) + def memberDescriptors = members map (_.toErasedString) + def memberSignatures = members filter (_.hasSignature) map (_.toGenericString) + def descriptorsString = if (memberDescriptors.nonEmpty) memberDescriptors.mkString("\n-- Member Descriptors --\n", "\n", "\n") else "" + def signaturesString = if (memberSignatures.nonEmpty) memberSignatures.mkString("\n-- Member Signatures --\n", "\n", "\n") else "" + def innersString = if (innerClasses.isEmpty) "" else innerClasses.mkString("\n-- Inner Classes --\n", "\n", "\n") + def membersString = descriptorsString + signaturesString + def extendsString = if (superName == "") "" else " extends " + superName + def implementsString = if (interfaces.isEmpty) "" else interfaces.mkString("Implements: ", ", ", "") + + private def group(label: String, xs: Traversable[(String, String)]) = + xs map { case (name, value) => line(label, name, value) } mkString "\n" + + private def line(label: String, name: String, data: String) = + trimTrailingSpace(" %-15s %30s %s".format(label, name, data)) + + override def toString = ( + List( + "class " + name + extendsString, + if (signature == "") "" else line("class sig", "", signature), + group("interface", interfaces map (x => (("", x)))), + (innerClasses map (ic => line(ic.kind, ic.innerName, ic.nestString))).sorted.mkString("\n"), + group("descriptor", members map (x => (x.name, x.descriptor))), + group("signature", members filter (_.hasSignature) map (x => (x.name, x.signature))) + ) map trimTrailingSpace filterNot (_ == "") mkString ("", "\n", "\n") + ) +} + +// method_info or field_info { +// u2 access_flags; +// u2 name_index; +// u2 descriptor_index; +// u2 attributes_count; +// attribute_info attributes[attributes_count]; +// } +class JvmMemberInfo( + val flags: Short, + val name: String, + val descriptor: String, + attributes: Array[JvmAttributeInfo] +) extends JvmInfo(attributes) { + def decodedName = decode(name) + def hasSignature = signature != "" + def toErasedString = "%-30s %s".format(decodedName, descriptor) + def toGenericString = "%-30s %s".format(decodedName, signature) + + override def toString = ( + if (hasSignature) toGenericString else toErasedString + ) +} + +abstract class JvmAttributeInfo { + def name: String + def value: Any +} +class GenericAttr(val name: String, val value: Array[Byte]) extends JvmAttributeInfo { + // attribute_info { + // u2 attribute_name_index; + // u4 attribute_length; + // u1 info[attribute_length]; + // } +} +class SignatureAttr(val value: String) extends JvmAttributeInfo { + def name = "Signature" +} +class InnerClassesAttr(val value: Array[JvmInnerClassInfo]) extends JvmAttributeInfo { + def name = "InnerClasses" +} + +// package foo { class Foo { class Bar } } +// +// javap would say +// Bar = class foo.Foo$Bar of class foo.Foo +// which is translated as +// innerClass = foo.Foo$Bar +// outerClass = foo.Foo +// innerName = Bar + +class JvmInnerClassInfo( + thisClass: String, // classfile which is being parsed + val innerClass: String, // the full name of the inner/nested class + val outerClass: String, // the full name of the outer class - must be a prefix of innerClass + val innerName: String, // the simple name of the inner class - should (?) be a suffix of innerClass + val flags: Short // flags +) { + val isEntryOfEnclosingClass = !isAnonymousClass && (innerClass == thisClass) + val isEntryOfNestedClass = !isAnonymousClass && (outerClass == thisClass) + + def isTopLevelClass = outerClass == "" + def isAnonymousClass = innerName == "" + def isMemberClass = !isTopLevelClass + + def kind = ( + if (isEntryOfEnclosingClass) "inner/enclosing" + else if (isEntryOfNestedClass) "inner/nested" + else if (isAnonymousClass) "inner/anon" + else "inner" + ) + def nestString = ( + if (isEntryOfEnclosingClass) "enclosing class: " + outerClass + else if (isEntryOfNestedClass) "member class: " + innerClass + else if (isAnonymousClass) "anonymous class: " + innerClass + else innerClass + " in " + outerClass + ) + override def toString = innerName + "=" + nestString +} + +object JvmClassInfo { + private def classFiles(path: String) = + Directory(path).deepFiles filter (_ hasExtension "class") + + def classInfoMap(path: String): Map[String, JvmClassInfo] = { + classFiles(path) map (f => (f.path, JvmClassInfo fromFile f.jfile)) toMap + } + def classInfoList(path: String): List[(String, JvmClassInfo)] = { + classInfoMap(path).toList sortBy (_._1) + } + + def fromFile(file: java.io.File) = + fromStream(new BufferedInputStream(new FileInputStream(file))) + + def fromBytes(bytes: Array[Byte]) = + fromStream(new ByteArrayInputStream(bytes)) + + def fromPath(path: String) = + fromStream(new BufferedInputStream(new FileInputStream(path))) + + def fromStream(in0: InputStream) = { + val in = new DataInputStream(in0) + try fromDataInput(in) finally in.close() + } + + def fromDataInput(in: DataInput): JvmClassInfo = { + new JvmClassInfoBuilder(in) parse + } +} diff --git a/src/compiler/scala/tools/cmd/program/DumpClass.scala b/src/compiler/scala/tools/cmd/program/DumpClass.scala new file mode 100644 index 0000000000..a583f1d3ea --- /dev/null +++ b/src/compiler/scala/tools/cmd/program/DumpClass.scala @@ -0,0 +1,40 @@ +/* NEST (New Scala Test) + * Copyright 2007-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd +package program + +import scala.reflect.internal.JvmClassInfo +import scala.tools.nsc.io.Directory + +object DumpClass { + private val usage = """ + |Usage: dump-class [options] ... + | + |Parses and dumps the bytecode of all classes found at the given paths. + |""".stripMargin + + private val unaryOps = List( + "signatures" -> "dump signatures" + ) + private val info = Simple.scalaProgramInfo("dump-class", usage) + private val spec = Simple(info, unaryOps, Nil, null) + + def deepInfos(dir: String) = { + val files = Directory(dir).deepFiles.toList filter (_ hasExtension "class") + files.sortBy(_.path) map (f => (f.path, JvmClassInfo fromPath f.path)) + } + + def main(args: Array[String]): Unit = { + val runner = spec instance args + import runner._ + + if (args.isEmpty) + println(usage) + else + (residualArgs flatMap deepInfos) sortBy (_._1) map (_._2) foreach println + } +} diff --git a/src/compiler/scala/tools/util/StringOps.scala b/src/compiler/scala/tools/util/StringOps.scala index 02eb364abe..725e0afb79 100644 --- a/src/compiler/scala/tools/util/StringOps.scala +++ b/src/compiler/scala/tools/util/StringOps.scala @@ -25,6 +25,16 @@ trait StringOps { val ys = oempty(xs: _*) if (ys.isEmpty) orElse else ys mkString sep } + def trimTrailingSpace(s: String) = { + if (s.length == 0 || !s.charAt(s.length - 1).isWhitespace) s + else { + var idx = s.length - 1 + while (idx >= 0 && s.charAt(idx).isWhitespace) + idx -= 1 + + s.substring(0, idx + 1) + } + } def decompose(str: String, sep: Char): List[String] = { def ws(start: Int): List[String] = diff --git a/test/files/run/inner-parse.check b/test/files/run/inner-parse.check new file mode 100644 index 0000000000..87ea9ddeb5 --- /dev/null +++ b/test/files/run/inner-parse.check @@ -0,0 +1,86 @@ +file Test$$anonfun$main$1.class +class Test$$anonfun$main$1 extends scala.runtime.AbstractFunction1$mcVL$sp + interface scala.Serializable + inner/anon anonymous class: Test$$anonfun$main$1 + descriptor ()V + descriptor apply (Lscala/Tuple2;)V + descriptor apply (Ljava/lang/Object;)Ljava/lang/Object; + descriptor cwd$1 Ljava/lang/String; + descriptor serialVersionUID J + descriptor (Ljava/lang/String;)V + signature apply (Lscala/Tuple2;)V + +file Test$.class +class Test$ extends java.lang.Object + inner/anon anonymous class: Test$$anonfun$main$1 + descriptor ()V + descriptor MODULE$ LTest$; + descriptor main ([Ljava/lang/String;)V + descriptor ()V + +file Test.class +class Test extends java.lang.Object + inner/anon anonymous class: Test$$anonfun$main$1 + descriptor main ([Ljava/lang/String;)V + +file j/J_1$B$C$D.class +class j.J_1$B$C$D extends java.lang.Object + inner B j.J_1$B in j.J_1 + inner C j.J_1$B$C in j.J_1$B + inner/enclosing D enclosing class: j.J_1$B$C + descriptor (Lj/J_1$B$C;)V + descriptor this$2 Lj/J_1$B$C; + +file j/J_1$B$C.class +class j.J_1$B$C extends java.lang.Object + inner B j.J_1$B in j.J_1 + inner/enclosing C enclosing class: j.J_1$B + inner/nested D member class: j.J_1$B$C$D + descriptor (Lj/J_1$B;)V + descriptor this$1 Lj/J_1$B; + +file j/J_1$B.class +class j.J_1$B extends java.lang.Object + inner/enclosing B enclosing class: j.J_1 + inner/nested C member class: j.J_1$B$C + descriptor (Lj/J_1;)V + descriptor this$0 Lj/J_1; + +file j/J_1.class +class j.J_1 extends java.lang.Object + interface java.util.RandomAccess + inner/nested B member class: j.J_1$B + descriptor ()V + +file s/J_1$B$C$D.class +class s.J_1$B$C$D extends java.lang.Object + inner B s.J_1$B in s.J_1 + inner C s.J_1$B$C in s.J_1$B + inner/enclosing D enclosing class: s.J_1$B$C + descriptor $outer Ls/J_1$B$C; + descriptor s$J_1$B$C$D$$$outer ()Ls/J_1$B$C; + descriptor (Ls/J_1$B$C;)V + +file s/J_1$B$C.class +class s.J_1$B$C extends java.lang.Object + inner B s.J_1$B in s.J_1 + inner/enclosing C enclosing class: s.J_1$B + inner/nested D member class: s.J_1$B$C$D + descriptor $outer Ls/J_1$B; + descriptor s$J_1$B$C$$$outer ()Ls/J_1$B; + descriptor (Ls/J_1$B;)V + +file s/J_1$B.class +class s.J_1$B extends java.lang.Object + inner/enclosing B enclosing class: s.J_1 + inner/nested C member class: s.J_1$B$C + descriptor $outer Ls/J_1; + descriptor s$J_1$B$$$outer ()Ls/J_1; + descriptor (Ls/J_1;)V + +file s/J_1.class +class s.J_1 extends java.lang.Object + interface java.util.RandomAccess + inner/nested B member class: s.J_1$B + descriptor ()V + diff --git a/test/files/run/inner-parse/J_1.java b/test/files/run/inner-parse/J_1.java new file mode 100644 index 0000000000..920ab951ab --- /dev/null +++ b/test/files/run/inner-parse/J_1.java @@ -0,0 +1,9 @@ +package j; + +public class J_1 implements java.util.RandomAccess { // "random" marker interface + class B { + class C { + class D { } + } + } +} diff --git a/test/files/run/inner-parse/S_2.scala b/test/files/run/inner-parse/S_2.scala new file mode 100644 index 0000000000..fd144a40b7 --- /dev/null +++ b/test/files/run/inner-parse/S_2.scala @@ -0,0 +1,9 @@ +package s; + +class J_1 extends java.util.RandomAccess { + class B { + class C { + class D { } + } + } +} diff --git a/test/files/run/inner-parse/S_3.scala b/test/files/run/inner-parse/S_3.scala new file mode 100644 index 0000000000..296a651460 --- /dev/null +++ b/test/files/run/inner-parse/S_3.scala @@ -0,0 +1,12 @@ +import scala.reflect.internal.JvmClassInfo + +object Test { + def main(args: Array[String]): Unit = { + val cwd = sys.props("partest.output") + + for ((f, info) <- JvmClassInfo.classInfoList(cwd)) { + println("file " + f.stripPrefix(cwd + "/")) + println(info) + } + } +} diff --git a/tools/dump-class b/tools/dump-class new file mode 100755 index 0000000000..0b4f2a73fa --- /dev/null +++ b/tools/dump-class @@ -0,0 +1,6 @@ +#!/bin/sh +# + +classpath=$($(dirname $BASH_SOURCE)/quickcp) + +java -cp "$classpath" scala.tools.nsc.MainGenericRunner -usejavacp scala.tools.cmd.program.DumpClass "$@" \ No newline at end of file -- cgit v1.2.3 From f7e1a4940386491b0691147b12b1b321c4cce2c5 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 23 Apr 2012 13:26:21 -0700 Subject: Better position printing in NodePrinters. Try this unreasonably long command line: scalac -Xprint-pos -Yshow-trees -Xprint:all -Yrangepos *.scala --- .../scala/tools/nsc/ast/NodePrinters.scala | 48 ++++++++++++++++------ 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala index 108c8fcbfa..5d849b9622 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -63,10 +63,14 @@ abstract class NodePrinters { } trait DefaultPrintAST extends PrintAST { + val printPos = settings.Xprintpos.value || settings.Yposdebug.value + + def showNameAndPos(tree: NameTree) = showPosition(tree) + showName(tree.name) def showDefTreeName(tree: DefTree) = showName(tree.name) + def showPosition(tree: Tree) = if (printPos) tree.pos.show else "" def showFlags(tree: MemberDef) = flagsToString(tree.symbol.flags | tree.mods.flags) - def showLiteral(lit: Literal) = lit.value.escapedStringValue - def showTypeTree(tt: TypeTree) = "" + emptyOrComment(showType(tt)) + def showLiteral(lit: Literal) = showPosition(lit) + lit.value.escapedStringValue + def showTypeTree(tt: TypeTree) = showPosition(tt) + "" + emptyOrComment(showType(tt)) def showName(name: Name) = name match { case nme.EMPTY | tpnme.EMPTY => "" case name => "\"" + name + "\"" @@ -97,17 +101,21 @@ abstract class NodePrinters { private var level = 0 def showName(name: Name): String + def showPosition(tree: Tree): String + def showNameAndPos(tree: NameTree): String def showDefTreeName(defTree: DefTree): String def showFlags(tree: MemberDef): String 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) - case Ident(name) => showName(name) - case _ => "" + tree + def showRefTreeName(tree: Tree): String = { + tree match { + case SelectFromTypeTree(qual, name) => showRefTreeName(qual) + "#" + showName(name) + case Select(qual, name) => showRefTreeName(qual) + "." + showName(name) + case id @ Ident(name) => showNameAndPos(id) + case _ => "" + tree + } } def showRefTree(tree: RefTree): String = { def prefix0 = showRefTreeName(tree.qualifier) @@ -116,7 +124,7 @@ abstract class NodePrinters { case Select(_, _) => prefix0 + "." case _ => "" }) - prefix + showName(tree.name) + emptyOrComment(showAttributes(tree)) + prefix + showNameAndPos(tree) + emptyOrComment(showAttributes(tree)) } def emptyOrComment(s: String) = if (s == "") "" else " // " + s @@ -191,8 +199,9 @@ abstract class NodePrinters { } } + def treePrefix(tree: Tree) = showPosition(tree) + tree.printingPrefix def printMultiline(tree: Tree)(body: => Unit) { - printMultiline(tree.printingPrefix, showAttributes(tree))(body) + printMultiline(treePrefix(tree), showAttributes(tree))(body) } def printMultiline(prefix: String, comment: String)(body: => Unit) { printLine(prefix + "(", comment) @@ -218,10 +227,12 @@ abstract class NodePrinters { } def printSingle(tree: Tree, name: Name) { - println(tree.printingPrefix + "(" + showName(name) + ")" + showAttributes(tree)) + println(treePrefix(tree) + "(" + showName(name) + ")" + showAttributes(tree)) } def traverse(tree: Tree) { + showPosition(tree) + tree match { case AppliedTypeTree(tpt, args) => applyCommon(tree, tpt, args) case ApplyDynamic(fun, args) => applyCommon(tree, fun, args) @@ -230,6 +241,19 @@ abstract class NodePrinters { case Throw(Ident(name)) => printSingle(tree, name) + case b @ Bind(name, body) => + printMultiline(tree) { + println(showDefTreeName(b)) + traverse(body) + } + + case ld @ LabelDef(name, params, rhs) => + printMultiline(tree) { + showNameAndPos(ld) + traverseList("()", "params")(params) + traverse(rhs) + } + case Function(vparams, body) => printMultiline(tree) { traverseList("()", "parameter")(vparams) @@ -309,7 +333,7 @@ abstract class NodePrinters { val ps0 = parents map { p => if (p.tpe eq null) p match { case x: RefTree => showRefTree(x) - case x => "" + x + case x => showPosition(x) + x } else showName(newTypeName(p.tpe.typeSymbol.fullName)) } @@ -353,7 +377,7 @@ abstract class NodePrinters { case _ => tree match { case t: RefTree => println(showRefTree(t)) - case t if t.productArity == 0 => println(tree.printingPrefix) + case t if t.productArity == 0 => println(treePrefix(t)) case t => printMultiline(tree)(tree.productIterator foreach traverseAny) } } -- cgit v1.2.3 From 9d925a30c73ee5856c83d3caab124f7dbeaa85a8 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sun, 22 Apr 2012 02:58:26 -0700 Subject: SI-5702 Pattern parser halts on star In patterns, the parser halts when it sees stars. This means it does not handle infix notation for a case class named "*". This patch uses lookahead to decide whether to parse '_' '*' as a sequence pattern or as the start of infix. (For both normal and error cases, the tokens are always consumed immediately.) Error messages are improved for _* (as a help to learners) and slightly improved recovery helps the parse continue. The entry point for XML patterns is now distinct; otherwise, the change is local to pattern3-simplepattern; the entry point for simplepattern() is unchanged because it is commented "hook for IDE." --- .../scala/tools/nsc/ast/parser/MarkupParsers.scala | 2 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 115 +++++++++++++++------ test/files/neg/t1878-typer.check | 4 + test/files/neg/t1878-typer.scala | 6 ++ test/files/neg/t1878.check | 24 +---- test/files/neg/t1878.scala | 2 + test/files/neg/t3189.check | 4 + test/files/neg/t3189.scala | 3 + test/files/neg/t5702-neg-bad-and-wild.check | 28 +++++ test/files/neg/t5702-neg-bad-and-wild.scala | 29 ++++++ test/files/neg/t5702-neg-bad-brace.check | 10 ++ test/files/neg/t5702-neg-bad-brace.scala | 17 +++ test/files/neg/t5702-neg-bad-xbrace.check | 7 ++ test/files/neg/t5702-neg-bad-xbrace.scala | 31 ++++++ test/files/neg/t5702-neg-ugly-xbrace.check | 19 ++++ test/files/neg/t5702-neg-ugly-xbrace.scala | 14 +++ test/files/pos/t5702-pos-infix-star.scala | 15 +++ test/pending/neg/t3189.check | 7 -- test/pending/neg/t3189.scala | 3 - 19 files changed, 279 insertions(+), 61 deletions(-) create mode 100644 test/files/neg/t1878-typer.check create mode 100644 test/files/neg/t1878-typer.scala create mode 100644 test/files/neg/t3189.check create mode 100644 test/files/neg/t3189.scala create mode 100644 test/files/neg/t5702-neg-bad-and-wild.check create mode 100644 test/files/neg/t5702-neg-bad-and-wild.scala create mode 100644 test/files/neg/t5702-neg-bad-brace.check create mode 100644 test/files/neg/t5702-neg-bad-brace.scala create mode 100644 test/files/neg/t5702-neg-bad-xbrace.check create mode 100644 test/files/neg/t5702-neg-bad-xbrace.scala create mode 100644 test/files/neg/t5702-neg-ugly-xbrace.check create mode 100644 test/files/neg/t5702-neg-ugly-xbrace.scala create mode 100644 test/files/pos/t5702-pos-infix-star.scala delete mode 100644 test/pending/neg/t3189.check delete mode 100644 test/pending/neg/t3189.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala index 93fa9a60f6..f702f44338 100755 --- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala @@ -397,7 +397,7 @@ trait MarkupParsers { /** xScalaPatterns ::= patterns */ - def xScalaPatterns: List[Tree] = escapeToScala(parser.seqPatterns(), "pattern") + def xScalaPatterns: List[Tree] = escapeToScala(parser.xmlSeqPatterns(), "pattern") def reportSyntaxError(pos: Int, str: String) = parser.syntaxError(pos, str) def reportSyntaxError(str: String) { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index bca1cc4596..337ca7671c 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1705,11 +1705,11 @@ self => * was threaded through methods as boolean seqOK. */ trait SeqContextSensitive extends PatternContextSensitive { - /** Returns Some(tree) if it finds a star and prematurely ends parsing. - * This is an artifact of old implementation which has proven difficult - * to cleanly extract. - */ - def interceptStarPattern(top: Tree): Option[Tree] + // is a sequence pattern _* allowed? + def isSequenceOK: Boolean + + // are we in an XML pattern? + def isXML: Boolean = false def functionArgType(): Tree = argType() def argType(): Tree = { @@ -1796,45 +1796,98 @@ self => /** {{{ * Pattern3 ::= SimplePattern * | SimplePattern {Id [nl] SimplePattern} - * SeqPattern3 ::= SeqSimplePattern [ `*' | `?' | `+' ] - * | SeqSimplePattern {Id [nl] SeqSimplePattern} * }}} */ def pattern3(): Tree = { + var top = simplePattern(badPattern3) + // after peekahead + def acceptWildStar() = atPos(top.pos.startOrPoint, in.prev.offset)(Star(stripParens(top))) + def peekahead() = { + in.prev copyFrom in + in.nextToken() + } + def pushback() = { + in.next copyFrom in + in copyFrom in.prev + } + // See SI-3189, SI-4832 for motivation. Cf SI-3480 for counter-motivation. + // TODO: dredge out the remnants of regexp patterns. + // /{/ peek for _*) or _*} (for xml escape) + if (isSequenceOK) { + top match { + case Ident(nme.WILDCARD) if (isRawStar) => + peekahead() + in.token match { + case RBRACE if (isXML) => return acceptWildStar() + case RPAREN if (!isXML) => return acceptWildStar() + case _ => pushback() + } + case _ => + } + } val base = opstack - var top = simplePattern() - interceptStarPattern(top) foreach { x => return x } - while (isIdent && in.name != raw.BAR) { - top = reduceStack( - false, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) + top = reduceStack(false, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) val op = in.name opstack = OpInfo(top, op, in.offset) :: opstack ident() - top = simplePattern() + top = simplePattern(badPattern3) } stripParens(reduceStack(false, base, top, 0, true)) } + def badPattern3(): Tree = { + def isComma = in.token == COMMA + def isAnyBrace = in.token == RPAREN || in.token == RBRACE + val badStart = "illegal start of simple pattern" + // better recovery if don't skip delims of patterns + var skip = !(isComma || isAnyBrace) + val msg = if (!opstack.isEmpty && opstack.head.operator == nme.STAR) { + opstack.head.operand match { + case Ident(nme.WILDCARD) => + if (isSequenceOK && isComma) + "bad use of _* (a sequence pattern must be the last pattern)" + else if (isSequenceOK && isAnyBrace) { + skip = true // do skip bad paren; scanner may skip bad brace already + "bad brace or paren after _*" + } else if (!isSequenceOK && isAnyBrace) + "bad use of _* (sequence pattern not allowed)" + else badStart + case _ => + if (isSequenceOK && isAnyBrace) + "use _* to match a sequence" + else if (isComma || isAnyBrace) + "trailing * is not a valid pattern" + else badStart + } + } else { + badStart + } + syntaxErrorOrIncomplete(msg, skip) + errorPatternTree + } /** {{{ * SimplePattern ::= varid * | `_' * | literal * | XmlPattern - * | StableId [TypeArgs] [`(' [SeqPatterns] `)'] + * | StableId /[TypeArgs]/ [`(' [Patterns] `)'] + * | StableId [`(' [Patterns] `)'] + * | StableId [`(' [Patterns] `,' [varid `@'] `_' `*' `)'] * | `(' [Patterns] `)' - * SimpleSeqPattern ::= varid - * | `_' - * | literal - * | XmlPattern - * | `<' xLiteralPattern - * | StableId [TypeArgs] [`(' [SeqPatterns] `)'] - * | `(' [SeqPatterns] `)' * }}} * * XXX: Hook for IDE */ def simplePattern(): Tree = { + // simple diagnostics for this entry point + def badStart(): Tree = { + syntaxErrorOrIncomplete("illegal start of simple pattern", true) + errorPatternTree + } + simplePattern(badStart) + } + def simplePattern(onError: () => Tree): Tree = { val start = in.offset in.token match { case IDENTIFIER | BACKQUOTED_IDENT | THIS => @@ -1867,8 +1920,7 @@ self => case XMLSTART => xmlLiteralPattern() case _ => - syntaxErrorOrIncomplete("illegal start of simple pattern", true) - errorPatternTree + onError() } } } @@ -1879,16 +1931,16 @@ self => } /** The implementation for parsing inside of patterns at points where sequences are allowed. */ object seqOK extends SeqContextSensitive { - // See ticket #3189 for the motivation for the null check. - // TODO: dredge out the remnants of regexp patterns. - // ... and now this is back the way it was because it caused #3480. - def interceptStarPattern(top: Tree): Option[Tree] = - if (isRawStar) Some(atPos(top.pos.startOrPoint, in.skipToken())(Star(stripParens(top)))) - else None + val isSequenceOK = true } /** The implementation for parsing inside of patterns at points where sequences are disallowed. */ object noSeq extends SeqContextSensitive { - def interceptStarPattern(top: Tree) = None + val isSequenceOK = false + } + /** For use from xml pattern, where sequence is allowed and encouraged. */ + object xmlSeqOK extends SeqContextSensitive { + val isSequenceOK = true + override val isXML = true } /** These are default entry points into the pattern context sensitive methods: * they are all initiated from non-pattern context. @@ -1902,7 +1954,8 @@ self => /** Default entry points into some pattern contexts. */ def pattern(): Tree = noSeq.pattern() def patterns(): List[Tree] = noSeq.patterns() - def seqPatterns(): List[Tree] = seqOK.patterns() // Also called from xml parser + def seqPatterns(): List[Tree] = seqOK.patterns() + def xmlSeqPatterns(): List[Tree] = xmlSeqOK.patterns() // Called from xml parser def argumentPatterns(): List[Tree] = inParens { if (in.token == RPAREN) Nil else seqPatterns() diff --git a/test/files/neg/t1878-typer.check b/test/files/neg/t1878-typer.check new file mode 100644 index 0000000000..e3a20d0be7 --- /dev/null +++ b/test/files/neg/t1878-typer.check @@ -0,0 +1,4 @@ +t1878-typer.scala:4: error: _* may only come last + case

{ _* }

=> + ^ +one error found diff --git a/test/files/neg/t1878-typer.scala b/test/files/neg/t1878-typer.scala new file mode 100644 index 0000000000..1eb0cb7dff --- /dev/null +++ b/test/files/neg/t1878-typer.scala @@ -0,0 +1,6 @@ +object Test extends App { + // illegal - bug #1764 + null match { + case

{ _* }

=> + } +} diff --git a/test/files/neg/t1878.check b/test/files/neg/t1878.check index b47367e12c..ac2071c3d8 100644 --- a/test/files/neg/t1878.check +++ b/test/files/neg/t1878.check @@ -1,21 +1,7 @@ -t1878.scala:3: error: _* may only come last +t1878.scala:3: error: bad use of _* (a sequence pattern must be the last pattern) val err1 = "" match { case Seq(f @ _*, ',') => f } - ^ -t1878.scala:3: error: scrutinee is incompatible with pattern type; - found : Seq[A] - required: String - val err1 = "" match { case Seq(f @ _*, ',') => f } - ^ -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 + ^ +t1878.scala:9: error: bad use of _* (a sequence pattern must be the last pattern) val List(List(_*, arg2), _) = List(List(1,2,3), List(4,5,6)) - ^ -t1878.scala:13: error: _* may only come last - case

{ _* }

=> - ^ -6 errors found + ^ +two errors found diff --git a/test/files/neg/t1878.scala b/test/files/neg/t1878.scala index 5278fbb7bd..99fee48a96 100644 --- a/test/files/neg/t1878.scala +++ b/test/files/neg/t1878.scala @@ -8,8 +8,10 @@ object Test extends App { // illegal val List(List(_*, arg2), _) = List(List(1,2,3), List(4,5,6)) + /* see t1878-typer.scala // illegal - bug #1764 null match { case

{ _* }

=> } + */ } diff --git a/test/files/neg/t3189.check b/test/files/neg/t3189.check new file mode 100644 index 0000000000..3913c526a2 --- /dev/null +++ b/test/files/neg/t3189.check @@ -0,0 +1,4 @@ +t3189.scala:2: error: use _* to match a sequence + val Array(a,b*) = ("": Any) + ^ +one error found diff --git a/test/files/neg/t3189.scala b/test/files/neg/t3189.scala new file mode 100644 index 0000000000..4ea4bb7581 --- /dev/null +++ b/test/files/neg/t3189.scala @@ -0,0 +1,3 @@ +object A { + val Array(a,b*) = ("": Any) +} \ No newline at end of file diff --git a/test/files/neg/t5702-neg-bad-and-wild.check b/test/files/neg/t5702-neg-bad-and-wild.check new file mode 100644 index 0000000000..eae81ad5f2 --- /dev/null +++ b/test/files/neg/t5702-neg-bad-and-wild.check @@ -0,0 +1,28 @@ +t5702-neg-bad-and-wild.scala:10: error: bad use of _* (a sequence pattern must be the last pattern) + case List(1, _*,) => // bad use of _* (a sequence pattern must be the last pattern) + ^ +t5702-neg-bad-and-wild.scala:10: error: illegal start of simple pattern + case List(1, _*,) => // bad use of _* (a sequence pattern must be the last pattern) + ^ +t5702-neg-bad-and-wild.scala:12: error: illegal start of simple pattern + case List(1, _*3,) => // illegal start of simple pattern + ^ +t5702-neg-bad-and-wild.scala:14: error: use _* to match a sequence + case List(1, x*) => // use _* to match a sequence + ^ +t5702-neg-bad-and-wild.scala:15: error: trailing * is not a valid pattern + case List(x*, 1) => // trailing * is not a valid pattern + ^ +t5702-neg-bad-and-wild.scala:16: error: trailing * is not a valid pattern + case (1, x*) => // trailing * is not a valid pattern + ^ +t5702-neg-bad-and-wild.scala:17: error: bad use of _* (sequence pattern not allowed) + case (1, x@_*) => // bad use of _* (sequence pattern not allowed) + ^ +t5702-neg-bad-and-wild.scala:23: error: bad use of _* (a sequence pattern must be the last pattern) + val K(ns @ _*, x) = k // bad use of _* (a sequence pattern must be the last pattern) + ^ +t5702-neg-bad-and-wild.scala:24: error: bad use of _* (sequence pattern not allowed) + val (b, _ * ) = Pair(5,6) // bad use of _* (sequence pattern not allowed) + ^ +9 errors found diff --git a/test/files/neg/t5702-neg-bad-and-wild.scala b/test/files/neg/t5702-neg-bad-and-wild.scala new file mode 100644 index 0000000000..3833a002b1 --- /dev/null +++ b/test/files/neg/t5702-neg-bad-and-wild.scala @@ -0,0 +1,29 @@ + +object Test { + case class K(i: Int) + + def main(args: Array[String]) { + val k = new K(9) + val is = List(1,2,3) + + is match { + case List(1, _*,) => // bad use of _* (a sequence pattern must be the last pattern) + // illegal start of simple pattern + case List(1, _*3,) => // illegal start of simple pattern + //case List(1, _*3:) => // poor recovery by parens + case List(1, x*) => // use _* to match a sequence + case List(x*, 1) => // trailing * is not a valid pattern + case (1, x*) => // trailing * is not a valid pattern + case (1, x@_*) => // bad use of _* (sequence pattern not allowed) + } + +// good syntax, bad semantics, detected by typer +//gowild.scala:14: error: star patterns must correspond with varargs parameters + val K(is @ _*) = k + val K(ns @ _*, x) = k // bad use of _* (a sequence pattern must be the last pattern) + val (b, _ * ) = Pair(5,6) // bad use of _* (sequence pattern not allowed) +// no longer complains +//bad-and-wild.scala:15: error: ')' expected but '}' found. + } +} + diff --git a/test/files/neg/t5702-neg-bad-brace.check b/test/files/neg/t5702-neg-bad-brace.check new file mode 100644 index 0000000000..503f7d95ed --- /dev/null +++ b/test/files/neg/t5702-neg-bad-brace.check @@ -0,0 +1,10 @@ +t5702-neg-bad-brace.scala:14: error: Unmatched closing brace '}' ignored here + case List(1, _*} => + ^ +t5702-neg-bad-brace.scala:14: error: illegal start of simple pattern + case List(1, _*} => + ^ +t5702-neg-bad-brace.scala:15: error: ')' expected but '}' found. + } + ^ +three errors found diff --git a/test/files/neg/t5702-neg-bad-brace.scala b/test/files/neg/t5702-neg-bad-brace.scala new file mode 100644 index 0000000000..16a341cf8c --- /dev/null +++ b/test/files/neg/t5702-neg-bad-brace.scala @@ -0,0 +1,17 @@ + +object Test { + + def main(args: Array[String]) { + val is = List(1,2,3) + + is match { +// the erroneous brace is ignored, so we can't halt on it. +// maybe brace healing can detect overlapping unmatched (...} +// In this case, the fix emits an extra error: +// t5702-neg-bad-brace.scala:10: error: Unmatched closing brace '}' ignored here +// t5702-neg-bad-brace.scala:10: error: illegal start of simple pattern (i.e., =>) +// t5702-neg-bad-brace.scala:11: error: ')' expected but '}' found. + case List(1, _*} => + } + } +} diff --git a/test/files/neg/t5702-neg-bad-xbrace.check b/test/files/neg/t5702-neg-bad-xbrace.check new file mode 100644 index 0000000000..d88638aee9 --- /dev/null +++ b/test/files/neg/t5702-neg-bad-xbrace.check @@ -0,0 +1,7 @@ +t5702-neg-bad-xbrace.scala:19: error: bad brace or paren after _* + case {_*)} => y + ^ +t5702-neg-bad-xbrace.scala:28: error: bad brace or paren after _* + val {a, z@_*)} = xml + ^ +two errors found diff --git a/test/files/neg/t5702-neg-bad-xbrace.scala b/test/files/neg/t5702-neg-bad-xbrace.scala new file mode 100644 index 0000000000..64bbdb18be --- /dev/null +++ b/test/files/neg/t5702-neg-bad-xbrace.scala @@ -0,0 +1,31 @@ + +object Test { + def main(args: Array[String]) { + /* PiS example, minus a brace + val yearMade = 1965 + val old = + { if (yearMade < 2000) yearMade} + else xml.NodeSeq.Empty } + println(old) + */ + + // bad brace or paren after _* + // actually, we know it's a bad paren... + // we skip it because not in a context looking for rparen + val xyear = 1965 + val ancient = + { + val when = xyear match { + case {_*)} => y + case _ => "2035" + } + {when} + } + println(ancient) + + val xml = appleboychild + // bad brace or paren after _* + val {a, z@_*)} = xml + println("A for "+ a +", ending with "+ z) + } +} diff --git a/test/files/neg/t5702-neg-ugly-xbrace.check b/test/files/neg/t5702-neg-ugly-xbrace.check new file mode 100644 index 0000000000..7d80bbf6be --- /dev/null +++ b/test/files/neg/t5702-neg-ugly-xbrace.check @@ -0,0 +1,19 @@ +t5702-neg-ugly-xbrace.scala:11: error: bad brace or paren after _* + val {a, z@_*) = xml + ^ +t5702-neg-ugly-xbrace.scala:12: error: Missing closing brace `}' assumed here + println("A for "+ a +", ending with "+ z) + ^ +t5702-neg-ugly-xbrace.scala:13: error: in XML literal: in XML content, please use '}}' to express '}' + } + ^ +t5702-neg-ugly-xbrace.scala:11: error: I encountered a '}' where I didn't expect one, maybe this tag isn't closed + val {a, z@_*) = xml + ^ +t5702-neg-ugly-xbrace.scala:14: error: illegal start of simple pattern +} +^ +t5702-neg-ugly-xbrace.scala:14: error: '}' expected but eof found. +} + ^ +6 errors found diff --git a/test/files/neg/t5702-neg-ugly-xbrace.scala b/test/files/neg/t5702-neg-ugly-xbrace.scala new file mode 100644 index 0000000000..0ff7bfa09d --- /dev/null +++ b/test/files/neg/t5702-neg-ugly-xbrace.scala @@ -0,0 +1,14 @@ + +object Test { + def main(args: Array[String]) { + + val xml = appleboychild + // This is the more likely typo, and the uglier parse. + // We could turn it into a } if } does not follow (to + // avoid handing }} back to xml) but that is quite ad hoc. + // Assuming } for ) after _* would not be not outlandish. + // bad brace or paren after _* + val {a, z@_*) = xml + println("A for "+ a +", ending with "+ z) + } +} diff --git a/test/files/pos/t5702-pos-infix-star.scala b/test/files/pos/t5702-pos-infix-star.scala new file mode 100644 index 0000000000..756bcdd8de --- /dev/null +++ b/test/files/pos/t5702-pos-infix-star.scala @@ -0,0 +1,15 @@ + +object Test { + case class *(a: Int, b: Int) + type Star = * + case class P(a: Int, b: Star) // alias still required + + def main(args: Array[String]) { + val v = new *(6,7) + val x * y = v + printf("%d,%d\n",x,y) + val p = P(5, v) + val P(a, b * c) = p + printf("%d,%d,%d\n",a,b,c) + } +} diff --git a/test/pending/neg/t3189.check b/test/pending/neg/t3189.check deleted file mode 100644 index 43dd0f29a0..0000000000 --- a/test/pending/neg/t3189.check +++ /dev/null @@ -1,7 +0,0 @@ -t3189.scala:2: error: illegal start of simple pattern - val Array(a,b*) = ("": Any) - ^ -t3189.scala:3: error: ')' expected but '}' found. -} -^ -two errors found diff --git a/test/pending/neg/t3189.scala b/test/pending/neg/t3189.scala deleted file mode 100644 index 4ea4bb7581..0000000000 --- a/test/pending/neg/t3189.scala +++ /dev/null @@ -1,3 +0,0 @@ -object A { - val Array(a,b*) = ("": Any) -} \ No newline at end of file -- cgit v1.2.3 From c577aaca7a7dab7b03fc3b69d766378486e10c00 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 27 Apr 2012 10:17:53 +0200 Subject: SI-3755: catch exception thrown by adaptToNewrun it would be nice to have a test for this, but you'd need to involve the repl, as I couldn't trigger it using multiple scalac runs --- src/compiler/scala/reflect/internal/Types.scala | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 2fe7dfda17..c049df47af 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -4832,9 +4832,14 @@ trait Types extends api.Types { self: SymbolTable => if (sym.isPackage) tp else { val pre1 = this(pre) - val sym1 = adaptToNewRun(pre1, sym) - if ((pre1 eq pre) && (sym1 eq sym)) tp - else singleType(pre1, sym1) + try { + val sym1 = adaptToNewRun(pre1, sym) + if ((pre1 eq pre) && (sym1 eq sym)) tp + else singleType(pre1, sym1) + } catch { + case _: MissingTypeControl => + tp + } } case TypeRef(pre, sym, args) => if (sym.isPackageClass) tp -- cgit v1.2.3 From 23b3e9dfd6c476b866148c18b1a4341741e1c011 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 27 Apr 2012 13:03:55 +0300 Subject: essential information about macro expansion --- src/compiler/scala/tools/nsc/typechecker/Macros.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 1b8a43bf27..353514c397 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -1010,7 +1010,7 @@ trait Macros extends Traces { private def Failure(expandee: Tree) = Other(expandee) private def fail(typer: Typer, expandee: Tree, msg: String = null) = { def msgForLog = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg - macroLogVerbose("macro expansion has failed: %s".format(msgForLog)) + macroLogLite("macro expansion has failed: %s".format(msgForLog)) val pos = if (expandee.pos != NoPosition) expandee.pos else enclosingMacroPosition if (msg != null) typer.context.error(pos, msg) typer.infer.setError(expandee) @@ -1079,7 +1079,7 @@ trait Macros extends Traces { else expanded match { case expanded: Expr[_] => macroLogVerbose("original:") - macroLogVerbose("" + expanded.tree + "\n" + showRaw(expanded.tree)) + macroLogLite("" + expanded.tree + "\n" + showRaw(expanded.tree)) freeTerms(expanded.tree) foreach issueFreeError freeTypes(expanded.tree) foreach issueFreeError @@ -1105,11 +1105,11 @@ trait Macros extends Traces { else Skip(macroExpandAll(typer, expandee)) } else { - macroLogVerbose("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) + macroLogLite("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) macroArgs(typer, expandee).fold(failExpansion(): MacroExpansionResult) { case args @ ((context: MacroContext) :: _) => if (nowDelayed) { - macroLogVerbose("macro expansion is delayed: %s".format(expandee)) + macroLogLite("macro expansion is delayed: %s".format(expandee)) delayed += expandee -> undetparams // need to save typer context for `macroExpandAll` // need to save macro context to preserve enclosures @@ -1176,7 +1176,7 @@ trait Macros extends Traces { } fallBackToOverridden(expandee) match { case Some(tree1) => - macroTraceVerbose("falling back to: ")(tree1) + macroTraceLite("falling back to: ")(tree1) currentRun.macroExpansionFailed = true Fallback(tree1) case None => @@ -1192,7 +1192,7 @@ trait Macros extends Traces { macroLogVerbose("macro expansion has failed: %s".format(realex.msg)) fail(typer, expandee) // error has been reported by abort case err: TypeError => - macroLogVerbose("macro expansion has failed: %s at %s".format(err.msg, err.pos)) + macroLogLite("macro expansion has failed: %s at %s".format(err.msg, err.pos)) throw err // error should be propagated, don't report case _ => val message = { -- cgit v1.2.3 From 543df62aed1fcdcf3902b9b54ec4495a882b0fcc Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 27 Apr 2012 13:27:49 +0300 Subject: fixes SI-5713 --- src/compiler/scala/tools/nsc/ToolBoxes.scala | 3 ++- test/files/run/t5713.check | 1 + test/files/run/t5713.flags | 1 + test/files/run/t5713/Impls_Macros_1.scala | 27 +++++++++++++++++++++++++++ test/files/run/t5713/Test_2.scala | 5 +++++ 5 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 test/files/run/t5713.check create mode 100644 test/files/run/t5713.flags create mode 100644 test/files/run/t5713/Impls_Macros_1.scala create mode 100644 test/files/run/t5713/Test_2.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ToolBoxes.scala b/src/compiler/scala/tools/nsc/ToolBoxes.scala index 5b2b5ff5e9..8bf977090b 100644 --- a/src/compiler/scala/tools/nsc/ToolBoxes.scala +++ b/src/compiler/scala/tools/nsc/ToolBoxes.scala @@ -39,7 +39,8 @@ trait ToolBoxes { self: Global => 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) + // upd. this has to be done by the user himself, otherwise we run into troubles. see SI-5713 +// tree = resetAllAttrs(tree0.duplicate) val imported = importer.importTree(tree) val toolBox = libraryClasspathMirror.mkToolBox(frontEnd.asInstanceOf[libraryClasspathMirror.FrontEnd], options) try toolBox.runExpr(imported) diff --git a/test/files/run/t5713.check b/test/files/run/t5713.check new file mode 100644 index 0000000000..d3e9348123 --- /dev/null +++ b/test/files/run/t5713.check @@ -0,0 +1 @@ +err diff --git a/test/files/run/t5713.flags b/test/files/run/t5713.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/t5713.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/t5713/Impls_Macros_1.scala b/test/files/run/t5713/Impls_Macros_1.scala new file mode 100644 index 0000000000..b499bc7e4e --- /dev/null +++ b/test/files/run/t5713/Impls_Macros_1.scala @@ -0,0 +1,27 @@ +package m + +import language.experimental.macros +import scala.reflect.makro.Context + +object Level extends Enumeration { + val Error = Value(5) +} + +object Logger { + def error(message: String): Unit = macro LoggerMacros.error +} + +private object LoggerMacros { + + type LoggerContext = Context { type PrefixType = Logger.type } + + def error(c: LoggerContext)(message: c.Expr[String]): c.Expr[Unit] = + log(c)(c.reify(Level.Error), message) + + private def log(c: LoggerContext)(level: c.Expr[Level.Value], message: c.Expr[String]): c.Expr[Unit] = + if (level.eval.id < 4) // TODO Remove hack! + c.reify(()) + else { + c.reify(println(message.eval)) + } +} \ No newline at end of file diff --git a/test/files/run/t5713/Test_2.scala b/test/files/run/t5713/Test_2.scala new file mode 100644 index 0000000000..24f9e79b11 --- /dev/null +++ b/test/files/run/t5713/Test_2.scala @@ -0,0 +1,5 @@ +import m._ + +object Test extends App { + Logger.error("err") +} \ No newline at end of file -- cgit v1.2.3 From 1c3f66b6f2d41c02cc2bc32cb696aafa56b71176 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 27 Apr 2012 07:24:46 -0700 Subject: Revert "Moved ancillary methods off specialized traits." This reverts commit 1d0372f84f9a7325a47beb55169cc454895ef74b. I forgot about polymorphic dispatch. Have to seek another way. --- src/build/genprod.scala | 132 +++++++++++++++++++-- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 1 - src/library/scala/Function0.scala | 2 +- src/library/scala/Function1.scala | 16 +++ src/library/scala/Function2.scala | 14 +++ src/library/scala/PartialFunction.scala | 2 +- src/library/scala/Predef.scala | 8 +- src/library/scala/Tuple2.scala | 114 ++++++++++++++++++ src/library/scala/Tuple3.scala | 11 ++ src/library/scala/runtime/RichFunction1.scala | 27 ----- src/library/scala/runtime/RichFunction2.scala | 26 ---- src/library/scala/runtime/Tuple2Zipped.scala | 109 ----------------- test/files/neg/t5067.check | 8 +- test/files/neg/t5067.scala | 6 +- test/files/run/tuple-zipped.scala | 2 +- 15 files changed, 294 insertions(+), 184 deletions(-) delete mode 100644 src/library/scala/runtime/RichFunction1.scala delete mode 100644 src/library/scala/runtime/RichFunction2.scala delete mode 100644 src/library/scala/runtime/Tuple2Zipped.scala (limited to 'src') diff --git a/src/build/genprod.scala b/src/build/genprod.scala index 8a5c44f1c1..1ea0bf7b73 100644 --- a/src/build/genprod.scala +++ b/src/build/genprod.scala @@ -123,7 +123,23 @@ object FunctionOne extends Function(1) { * assert(succ(0) == anonfun1(0)) * """) - override def moreMethods = "" + override def moreMethods = """ + /** Composes two instances of Function1 in a new Function1, with this function applied last. + * + * @tparam A the type to which function `g` can be applied + * @param g a function A => T1 + * @return a new function `f` such that `f(x) == apply(g(x))` + */ + def compose[A](g: A => T1): A => R = { x => apply(g(x)) } + + /** Composes two instances of Function1 in a new Function1, with this function applied first. + * + * @tparam A the result type of function `g` + * @param g a function R => A + * @return a new function `f` such that `f(x) == g(apply(x))` + */ + def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } +""" } object FunctionTwo extends Function(2) { @@ -139,8 +155,6 @@ object FunctionTwo extends Function(2) { * } * assert(max(0, 1) == anonfun2(0, 1)) * """) - - override def moreMethods = "" } object Function { @@ -241,6 +255,11 @@ class Function(val i: Int) extends Group("Function") with Arity { zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz */ object Tuple { + val zipImports = """ +import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } +import scala.collection.generic.{ CanBuildFrom => CBF } +""" + def make(i: Int) = apply(i)() def apply(i: Int) = i match { case 1 => TupleOne @@ -257,6 +276,7 @@ object TupleOne extends Tuple(1) object TupleTwo extends Tuple(2) { + override def imports = Tuple.zipImports override def covariantSpecs = "@specialized(Int, Long, Double, Char, Boolean, AnyRef) " override def moreMethods = """ /** Swaps the elements of this `Tuple`. @@ -264,14 +284,112 @@ object TupleTwo extends Tuple(2) * second element is the first element of this Tuple. */ def swap: Tuple2[T2,T1] = Tuple2(_2, _1) + + @deprecated("Use `zipped` instead.", "2.9.0") + def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], + w2: T2 => Iterable[El2], + cbf1: CBF[Repr1, (El1, El2), To]): To = { + zipped map ((x, y) => ((x, y))) + } + + /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. + * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] + * or [[scala.collection.IterableLike]]. + * {{{ + * scala> val tuple = (List(1,2,3),List('a','b','c')) + * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) + * + * scala> tuple.zipped map { (x,y) => x + ":" + y } + * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) + * }}} + * + * @see Zipped + * Note: will not terminate for infinite-sized collections. + */ + 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) + + 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) + b.sizeHint(coll1) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b += f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b ++= f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { + val b1 = cbf1(coll1.repr) + val b2 = cbf2(coll2.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + val el2 = elems2.next + if (f(el1, el2)) { + b1 += el1 + b2 += el2 + } + } + else return (b1.result, b2.result) + } + + (b1.result, b2.result) + } + + def exists(f: (El1, El2) => Boolean): Boolean = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + if (f(el1, elems2.next)) + return true + } + else return false + } + false + } + + def forall(f: (El1, El2) => Boolean): Boolean = + !exists((x, y) => !f(x, y)) + + def foreach[U](f: (El1, El2) => U): Unit = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + f(el1, elems2.next) + else + return + } + } + } """ } object TupleThree extends Tuple(3) { - override def imports = """ -import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } -import scala.collection.generic.{ CanBuildFrom => CBF } - """ + override def imports = Tuple.zipImports override def moreMethods = """ @deprecated("Use `zipped` instead.", "2.9.0") diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index f7898f2aa2..aace545ea5 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1324,7 +1324,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with val lastInstr = b.lastInstruction for (instr <- b) { - instr match { case THIS(clasz) => jcode.emitALOAD_0() diff --git a/src/library/scala/Function0.scala b/src/library/scala/Function0.scala index cc17f8797a..dceed26439 100644 --- a/src/library/scala/Function0.scala +++ b/src/library/scala/Function0.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ // GENERATED CODE: DO NOT EDIT. -// genprod generated these sources at: Tue Apr 24 16:32:13 PDT 2012 +// genprod generated these sources at: Tue Feb 14 16:49:03 PST 2012 package scala diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala index a4391c1509..8995ef912b 100644 --- a/src/library/scala/Function1.scala +++ b/src/library/scala/Function1.scala @@ -38,5 +38,21 @@ trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, s */ def apply(v1: T1): R + /** Composes two instances of Function1 in a new Function1, with this function applied last. + * + * @tparam A the type to which function `g` can be applied + * @param g a function A => T1 + * @return a new function `f` such that `f(x) == apply(g(x))` + */ + def compose[A](g: A => T1): A => R = { x => apply(g(x)) } + + /** Composes two instances of Function1 in a new Function1, with this function applied first. + * + * @tparam A the result type of function `g` + * @param g a function R => A + * @return a new function `f` such that `f(x) == g(apply(x))` + */ + def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } + override def toString() = "" } diff --git a/src/library/scala/Function2.scala b/src/library/scala/Function2.scala index 5ea2b411bb..cacb96ef5d 100644 --- a/src/library/scala/Function2.scala +++ b/src/library/scala/Function2.scala @@ -37,6 +37,20 @@ trait Function2[@specialized(scala.Int, scala.Long, scala.Double) -T1, @speciali * @return the result of function application. */ def apply(v1: T1, v2: T2): R + /** Creates a curried version of this function. + * + * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)` + */ def curried: T1 => T2 => R = { + (x1: T1) => (x2: T2) => apply(x1, x2) + } + /** Creates a tupled version of this function: instead of 2 arguments, + * it accepts a single [[scala.Tuple2]] argument. + * + * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)` + */ + def tupled: Tuple2[T1, T2] => R = { + case Tuple2(x1, x2) => apply(x1, x2) + } override def toString() = "" } diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index fafaef9c2f..7154b8da34 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -78,7 +78,7 @@ trait PartialFunction[-A, +B] extends (A => B) { self => * @return a partial function with the same domain as this partial function, which maps * arguments `x` to `k(this(x))`. */ - def andThen[C](k: B => C) : PartialFunction[A, C] = new PartialFunction[A, C] { + override def andThen[C](k: B => C) : PartialFunction[A, C] = new PartialFunction[A, C] { def isDefinedAt(x: A): Boolean = self isDefinedAt x def apply(x: A): C = k(self(x)) } diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 96b8b6d8d5..d2aa3a8b34 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -308,11 +308,11 @@ object Predef extends LowPriorityImplicits { // views -------------------------------------------------------------- implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc) - implicit def function1ToRichFunction1[T, R](f: T => R): runtime.RichFunction1[T, R] = new runtime.RichFunction1(f) - implicit def function2ToRichFunction2[T1, T2, R](f: (T1, T2) => R): runtime.RichFunction2[T1, T2, R] = - new runtime.RichFunction2(f) - implicit def tuple2ToZipped[T1, T2](zz: (T1, T2)) = new runtime.Tuple2ZippedOps(zz) + implicit def zipped2ToTraversable[El1, El2](zz: Tuple2[_, _]#Zipped[_, El1, _, El2]): Traversable[(El1, El2)] = + new collection.AbstractTraversable[(El1, El2)] { + def foreach[U](f: ((El1, El2)) => U): Unit = zz foreach Function.untupled(f) + } implicit def zipped3ToTraversable[El1, El2, El3](zz: Tuple3[_, _, _]#Zipped[_, El1, _, El2, _, El3]): Traversable[(El1, El2, El3)] = new collection.AbstractTraversable[(El1, El2, El3)] { diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 924b2b6fe3..37ab564c3c 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -9,6 +9,9 @@ package scala +import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } +import scala.collection.generic.{ CanBuildFrom => CBF } + /** A tuple of 2 elements; the canonical representation of a [[scala.Product2]]. * @@ -27,4 +30,115 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s */ def swap: Tuple2[T2,T1] = Tuple2(_2, _1) + @deprecated("Use `zipped` instead.", "2.9.0") + def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], + w2: T2 => Iterable[El2], + cbf1: CBF[Repr1, (El1, El2), To]): To = { + zipped map ((x, y) => ((x, y))) + } + + /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. + * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] + * or [[scala.collection.IterableLike]]. + * {{{ + * scala> val tuple = (List(1,2,3),List('a','b','c')) + * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) + * + * scala> tuple.zipped map { (x,y) => x + ":" + y } + * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) + * }}} + * + * @see Zipped + * Note: will not terminate for infinite-sized collections. + */ + 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) + b.sizeHint(coll1) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b += f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b ++= f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { + val b1 = cbf1(coll1.repr) + val b2 = cbf2(coll2.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + val el2 = elems2.next + if (f(el1, el2)) { + b1 += el1 + b2 += el2 + } + } + else return (b1.result, b2.result) + } + + (b1.result, b2.result) + } + + def exists(f: (El1, El2) => Boolean): Boolean = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + if (f(el1, elems2.next)) + return true + } + else return false + } + false + } + + def forall(f: (El1, El2) => Boolean): Boolean = + !exists((x, y) => !f(x, y)) + + def foreach[U](f: (El1, El2) => U): Unit = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + f(el1, elems2.next) + else + return + } + } + } + } diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index dfa0c962a2..cd5ee23757 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -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/library/scala/runtime/RichFunction1.scala b/src/library/scala/runtime/RichFunction1.scala deleted file mode 100644 index 26651b8d6a..0000000000 --- a/src/library/scala/runtime/RichFunction1.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.runtime - -@inline final class RichFunction1[-T1, +R](f: T1 => R) { - /** Composes two instances of Function1 in a new Function1, with the function on the left applied last. - * - * @tparam A the type to which function `g` can be applied - * @param g a function A => T1 - * @return a new function `h` such that `h(x) == f(g(x))` - */ - def compose[A](g: A => T1): A => R = { x => f(g(x)) } - - /** Composes two instances of Function1 in a new Function1, with the function on the left applied first. - * - * @tparam A the result type of function `g` - * @param g a function R => A - * @return a new function `h` such that `h(x) == g(f(x))` - */ - def andThen[A](g: R => A): T1 => A = { x => g(f(x)) } -} diff --git a/src/library/scala/runtime/RichFunction2.scala b/src/library/scala/runtime/RichFunction2.scala deleted file mode 100644 index 14e23be31b..0000000000 --- a/src/library/scala/runtime/RichFunction2.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.runtime - -@inline final class RichFunction2[-T1, -T2, +R](f: (T1, T2) => R) { - /** Creates a curried version of this function. - * - * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)` - */ - def curried: T1 => T2 => R = (x1: T1) => (x2: T2) => f(x1, x2) - - /** Creates a tupled version of this function: instead of 2 arguments, - * it accepts a single [[scala.Tuple2]] argument. - * - * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)` - */ - def tupled: ((T1, T2)) => R = { - case Tuple2(x1, x2) => f(x1, x2) - } -} diff --git a/src/library/scala/runtime/Tuple2Zipped.scala b/src/library/scala/runtime/Tuple2Zipped.scala deleted file mode 100644 index 2eb2a47e46..0000000000 --- a/src/library/scala/runtime/Tuple2Zipped.scala +++ /dev/null @@ -1,109 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.runtime - -import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } -import scala.collection.generic.{ CanBuildFrom => CBF } - - /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. - * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] - * or [[scala.collection.IterableLike]]. - * {{{ - * scala> val tuple = (List(1,2,3),List('a','b','c')) - * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) - * - * scala> tuple.zipped map { (x,y) => x + ":" + y } - * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) - * }}} - * - * @see Zipped - * Note: will not terminate for infinite-sized collections. - */ -@inline private[scala] final class Tuple2Zipped[+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) - b.sizeHint(coll1) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b += f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b ++= f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { - val b1 = cbf1(coll1.repr) - val b2 = cbf2(coll2.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - val el2 = elems2.next - if (f(el1, el2)) { - b1 += el1 - b2 += el2 - } - } - else return (b1.result, b2.result) - } - - (b1.result, b2.result) - } - - def exists(f: (El1, El2) => Boolean): Boolean = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - if (f(el1, elems2.next)) - return true - } - else return false - } - false - } - - def forall(f: (El1, El2) => Boolean): Boolean = - !exists((x, y) => !f(x, y)) - - def foreach[U](f: (El1, El2) => U): Unit = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - f(el1, elems2.next) - else - return - } - } -} - -@inline private[scala] final class Tuple2ZippedOps[T1, T2](zz: (T1, T2)) { - def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]) = - new Tuple2Zipped[Repr1, El1, Repr2, El2](w1(zz._1), w2(zz._2)) -} diff --git a/test/files/neg/t5067.check b/test/files/neg/t5067.check index 395eda7442..32491766d7 100644 --- a/test/files/neg/t5067.check +++ b/test/files/neg/t5067.check @@ -1,6 +1,6 @@ t5067.scala:3: error: type mismatch; - found : ((Int, Int, Int)) => Int - required: (Int, Int, Int) => Int - override def tupled: (Int, Int, Int) => Int = super.tupled - ^ + found : ((Int, Int)) => Int + required: (Int, Int) => Int + override def tupled: (Int, Int) => Int = super.tupled + ^ one error found diff --git a/test/files/neg/t5067.scala b/test/files/neg/t5067.scala index 0a961d2f40..f8235c0e83 100644 --- a/test/files/neg/t5067.scala +++ b/test/files/neg/t5067.scala @@ -1,4 +1,4 @@ -class Foo extends Function3[Int, Int, Int, Int] { - def apply(x: Int, y: Int, z: Int) = x + y + z - override def tupled: (Int, Int, Int) => Int = super.tupled +class Foo extends Function2[Int, Int, Int] { + def apply(x: Int, y: Int) = x + y + override def tupled: (Int, Int) => Int = super.tupled } diff --git a/test/files/run/tuple-zipped.scala b/test/files/run/tuple-zipped.scala index 08dcc82de6..a9851346bc 100644 --- a/test/files/run/tuple-zipped.scala +++ b/test/files/run/tuple-zipped.scala @@ -15,7 +15,7 @@ object Test { def main(args: Array[String]): Unit = { for (cc1 <- xss1 ; cc2 <- xss2) { - val sum1 = (cc1 zip cc2) map { case (x, y) => x + y } sum + val sum1 = (cc1, cc2).zip map { case (x, y) => x + y } sum val sum2 = (cc1, cc2).zipped map (_ + _) sum assert(sum1 == sum2) -- cgit v1.2.3 From d1460afa09989bcecb306b3cf78880cea39cbdc7 Mon Sep 17 00:00:00 2001 From: Simon Ochsenreither Date: Sat, 28 Apr 2012 16:22:47 +0200 Subject: Removes @bridge methods. --- src/library/scala/collection/GenSeqLike.scala | 7 ---- src/library/scala/collection/GenSetLike.scala | 15 -------- src/library/scala/collection/IterableLike.scala | 11 ------ src/library/scala/collection/MapLike.scala | 3 -- src/library/scala/collection/SeqLike.scala | 36 ----------------- src/library/scala/collection/SeqViewLike.scala | 4 -- src/library/scala/collection/SetLike.scala | 9 ----- src/library/scala/collection/Traversable.scala | 6 --- src/library/scala/collection/TraversableLike.scala | 4 -- .../scala/collection/generic/GenSeqFactory.scala | 7 +--- .../collection/generic/GenericSeqCompanion.scala | 10 +---- .../generic/GenericTraversableTemplate.scala | 5 --- .../scala/collection/generic/MapFactory.scala | 2 - .../scala/collection/generic/SetFactory.scala | 9 +---- .../scala/collection/generic/Subtractable.scala | 3 -- .../collection/generic/TraversableFactory.scala | 45 +--------------------- .../scala/collection/immutable/ListMap.scala | 3 -- .../scala/collection/immutable/ListSet.scala | 2 - .../scala/collection/immutable/MapLike.scala | 2 - src/library/scala/collection/immutable/Range.scala | 5 +-- .../scala/collection/immutable/SortedMap.scala | 2 - .../scala/collection/immutable/TreeMap.scala | 2 - .../scala/collection/mutable/BufferLike.scala | 5 --- src/library/scala/collection/mutable/MapLike.scala | 4 -- .../scala/collection/mutable/PriorityQueue.scala | 3 -- src/library/scala/collection/mutable/SetLike.scala | 4 -- src/library/scala/package.scala | 5 --- src/library/scala/runtime/RichInt.scala | 6 --- 28 files changed, 5 insertions(+), 214 deletions(-) (limited to 'src') diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala index 71316cefc9..646fe09855 100644 --- a/src/library/scala/collection/GenSeqLike.scala +++ b/src/library/scala/collection/GenSeqLike.scala @@ -228,9 +228,6 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal */ def startsWith[B](that: GenSeq[B]): Boolean = startsWith(that, 0) - @bridge - def startsWith[B](that: Seq[B]): Boolean = startsWith(that: GenSeq[B]) - /** Tests whether this $coll contains the given sequence at a given index. * * '''Note''': If the both the receiver object `this` and the argument @@ -413,10 +410,6 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal */ def union[B >: A, That](that: GenSeq[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = this ++ that - @bridge - def union[B >: A, That](that: Seq[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = - union(that: GenSeq[B])(bf) - /** Computes the multiset difference between this $coll and another sequence. * * @param that the sequence of elements to remove diff --git a/src/library/scala/collection/GenSetLike.scala b/src/library/scala/collection/GenSetLike.scala index f729f82bb4..a576014445 100644 --- a/src/library/scala/collection/GenSetLike.scala +++ b/src/library/scala/collection/GenSetLike.scala @@ -51,9 +51,6 @@ extends GenIterableLike[A, Repr] */ def intersect(that: GenSet[A]): Repr = this filter that - @bridge - def intersect(that: Set[A]): Repr = intersect(that: GenSet[A]) - /** Computes the intersection between this set and another set. * * '''Note:''' Same as `intersect`. @@ -63,9 +60,6 @@ extends GenIterableLike[A, Repr] */ def &(that: GenSet[A]): Repr = this intersect that - @bridge - def &(that: Set[A]): Repr = &(that: GenSet[A]) - /** Computes the union between of set and another set. * * @param that the set to form the union with. @@ -83,9 +77,6 @@ extends GenIterableLike[A, Repr] */ def | (that: GenSet[A]): Repr = this union that - @bridge - def | (that: Set[A]): Repr = | (that: GenSet[A]) - /** Computes the difference of this set and another set. * * @param that the set of elements to exclude. @@ -103,9 +94,6 @@ extends GenIterableLike[A, Repr] */ def &~(that: GenSet[A]): Repr = this diff that - @bridge - def &~(that: Set[A]): Repr = &~(that: GenSet[A]) - /** Tests whether this set is a subset of another set. * * @param that the set to test. @@ -114,9 +102,6 @@ extends GenIterableLike[A, Repr] */ def subsetOf(that: GenSet[A]): Boolean = this forall that - @bridge - def subsetOf(that: Set[A]): Boolean = subsetOf(that: GenSet[A]) - /** Compares this set with another object for equality. * * '''Note:''' This operation contains an unchecked cast: if `that` diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala index 3c4ad0612a..6a000abd54 100644 --- a/src/library/scala/collection/IterableLike.scala +++ b/src/library/scala/collection/IterableLike.scala @@ -239,10 +239,6 @@ self => b.result } - @bridge - def zip[A1 >: A, B, That](that: Iterable[B])(implicit bf: CanBuildFrom[Repr, (A1, B), That]): That = - zip(that: GenIterable[B])(bf) - def zipAll[B, A1 >: A, That](that: GenIterable[B], thisElem: A1, thatElem: B)(implicit bf: CanBuildFrom[Repr, (A1, B), That]): That = { val b = bf(repr) val these = this.iterator @@ -256,10 +252,6 @@ self => b.result } - @bridge - def zipAll[B, A1 >: A, That](that: Iterable[B], thisElem: A1, thatElem: B)(implicit bf: CanBuildFrom[Repr, (A1, B), That]): That = - zipAll(that: GenIterable[B], thisElem, thatElem)(bf) - def zipWithIndex[A1 >: A, That](implicit bf: CanBuildFrom[Repr, (A1, Int), That]): That = { val b = bf(repr) var i = 0 @@ -280,9 +272,6 @@ self => !these.hasNext && !those.hasNext } - @bridge - def sameElements[B >: A](that: Iterable[B]): Boolean = sameElements(that: GenIterable[B]) - override /*TraversableLike*/ def toStream: Stream[A] = iterator.toStream /** Method called from equality methods, so that user-defined subclasses can diff --git a/src/library/scala/collection/MapLike.scala b/src/library/scala/collection/MapLike.scala index 8f88e62791..034c1a0c0c 100644 --- a/src/library/scala/collection/MapLike.scala +++ b/src/library/scala/collection/MapLike.scala @@ -297,9 +297,6 @@ self => def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): Map[A, B1] = ((repr: Map[A, B1]) /: xs.seq) (_ + _) - @bridge - def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): Map[A, B1] = ++(xs: GenTraversableOnce[(A, B1)]) - /** Returns a new map with all key/value pairs for which the predicate * `p` returns `true`. * diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index ced99e897f..5e37566008 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -296,9 +296,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ !j.hasNext } - @bridge - def startsWith[B](that: Seq[B], offset: Int): Boolean = startsWith(that: GenSeq[B], offset) - def endsWith[B](that: GenSeq[B]): Boolean = { val i = this.iterator.drop(length - that.length) val j = that.iterator @@ -309,10 +306,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ !j.hasNext } - @bridge - def endsWith[B](that: Seq[B]): Boolean = endsWith(that: GenSeq[B]) - - /** Finds first index where this $coll contains a given sequence as a slice. * $mayNotTerminateInf * @param that the sequence to test @@ -321,9 +314,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ */ def indexOfSlice[B >: A](that: GenSeq[B]): Int = indexOfSlice(that, 0) - @bridge - def indexOfSlice[B >: A](that: Seq[B]): Int = indexOfSlice(that: GenSeq[B]) - /** Finds first index after or at a start index where this $coll contains a given sequence as a slice. * $mayNotTerminateInf * @param that the sequence to test @@ -354,9 +344,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ -1 } - @bridge - def indexOfSlice[B >: A](that: Seq[B], from: Int): Int = indexOfSlice(that: GenSeq[B], from) - /** Finds last index where this $coll contains a given sequence as a slice. * $willNotTerminateInf * @param that the sequence to test @@ -365,9 +352,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ */ def lastIndexOfSlice[B >: A](that: GenSeq[B]): Int = lastIndexOfSlice(that, length) - @bridge - def lastIndexOfSlice[B >: A](that: Seq[B]): Int = lastIndexOfSlice(that: GenSeq[B]) - /** Finds last index before or at a given end index where this $coll contains a given sequence as a slice. * @param that the sequence to test * @param end the end index @@ -385,9 +369,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ else SeqLike.kmpSearch(thisCollection, 0, clippedL+tl, that.seq, 0, tl, false) } - @bridge - def lastIndexOfSlice[B >: A](that: Seq[B], end: Int): Int = lastIndexOfSlice(that: GenSeq[B], end) - /** Tests whether this $coll contains a given sequence as a slice. * $mayNotTerminateInf * @param that the sequence to test @@ -396,9 +377,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ */ def containsSlice[B](that: GenSeq[B]): Boolean = indexOfSlice(that) != -1 - @bridge - def containsSlice[B](that: Seq[B]): Boolean = containsSlice(that: GenSeq[B]) - /** Tests whether this $coll contains a given value as an element. * $mayNotTerminateInf * @@ -463,9 +441,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ b.result } - @bridge - def diff[B >: A](that: Seq[B]): Repr = diff(that: GenSeq[B]) - /** Computes the multiset intersection between this $coll and another sequence. * * @param that the sequence of elements to intersect with. @@ -499,9 +474,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ b.result } - @bridge - def intersect[B >: A](that: Seq[B]): Repr = intersect(that: GenSeq[B]) - private def occCounts[B](sq: Seq[B]): mutable.Map[B, Int] = { val occ = new mutable.HashMap[B, Int] { override def default(k: B) = 0 } for (y <- sq.seq) occ(y) += 1 @@ -534,10 +506,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ b.result } - @bridge - def patch[B >: A, That](from: Int, patch: Seq[B], replaced: Int)(implicit bf: CanBuildFrom[Repr, B, That]): That = - this.patch(from, patch: GenSeq[B], replaced)(bf) - def updated[B >: A, That](index: Int, elem: B)(implicit bf: CanBuildFrom[Repr, B, That]): That = { val b = bf(repr) val (prefix, rest) = this.splitAt(index) @@ -583,10 +551,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ !i.hasNext && !j.hasNext } - @bridge - def corresponds[B](that: Seq[B])(p: (A,B) => Boolean): Boolean = - corresponds(that: GenSeq[B])(p) - /** Sorts this $coll according to a comparison function. * $willNotTerminateInf * diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala index a32cad08e5..9b697a164c 100644 --- a/src/library/scala/collection/SeqViewLike.scala +++ b/src/library/scala/collection/SeqViewLike.scala @@ -132,13 +132,9 @@ trait SeqViewLike[+A, override def diff[B >: A](that: GenSeq[B]): This = newForced(thisSeq diff that).asInstanceOf[This] - @bridge def diff[B >: A](that: Seq[B]): This = diff(that: GenSeq[B]) - override def intersect[B >: A](that: GenSeq[B]): This = newForced(thisSeq intersect that).asInstanceOf[This] - @bridge def intersect[B >: A](that: Seq[B]): This = intersect(that: GenSeq[B]) - override def sorted[B >: A](implicit ord: Ordering[B]): This = newForced(thisSeq sorted ord).asInstanceOf[This] diff --git a/src/library/scala/collection/SetLike.scala b/src/library/scala/collection/SetLike.scala index 7293f3775c..04ec4af830 100644 --- a/src/library/scala/collection/SetLike.scala +++ b/src/library/scala/collection/SetLike.scala @@ -127,9 +127,6 @@ self => */ def ++ (elems: GenTraversableOnce[A]): This = (repr /: elems.seq)(_ + _) - @bridge - def ++ (elems: TraversableOnce[A]): This = ++ (elems: GenTraversableOnce[A]) - /** Creates a new set with a given element removed from this set. * * @param elem the element to be removed @@ -152,9 +149,6 @@ self => */ def union(that: GenSet[A]): This = this ++ that - @bridge - def union(that: Set[A]): This = union(that: GenSet[A]) - /** Computes the difference of this set and another set. * * @param that the set of elements to exclude. @@ -163,9 +157,6 @@ self => */ def diff(that: GenSet[A]): This = this -- that - @bridge - def diff(that: Set[A]): This = diff(that: GenSet[A]) - /** An iterator over all subsets of this set of the given size. * If the requested size is impossible, an empty iterator is returned. * diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala index a65be3ffcc..e75000297f 100644 --- a/src/library/scala/collection/Traversable.scala +++ b/src/library/scala/collection/Traversable.scala @@ -28,12 +28,6 @@ trait Traversable[+A] extends TraversableLike[A, Traversable[A]] override def seq: Traversable[A] = this - @bridge - def flatten[B](implicit asTraversable: A => /*<: /*<:: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = - ++(that: GenTraversableOnce[B])(bf) - /** As with `++`, returns a new collection containing the elements from the left operand followed by the * elements from the right operand. * diff --git a/src/library/scala/collection/generic/GenSeqFactory.scala b/src/library/scala/collection/generic/GenSeqFactory.scala index 3bd63c08b8..3664fe1b4f 100644 --- a/src/library/scala/collection/generic/GenSeqFactory.scala +++ b/src/library/scala/collection/generic/GenSeqFactory.scala @@ -19,9 +19,4 @@ import language.higherKinds * @since 2.8 */ abstract class GenSeqFactory[CC[X] <: GenSeq[X] with GenericTraversableTemplate[X, CC]] -extends GenTraversableFactory[CC] { - - @bridge - def unapplySeq[A](x: GenSeq[A]): Some[GenSeq[A]] = Some(x) - -} +extends GenTraversableFactory[CC] diff --git a/src/library/scala/collection/generic/GenericSeqCompanion.scala b/src/library/scala/collection/generic/GenericSeqCompanion.scala index 4c0c34733c..79cc2f13d4 100644 --- a/src/library/scala/collection/generic/GenericSeqCompanion.scala +++ b/src/library/scala/collection/generic/GenericSeqCompanion.scala @@ -14,12 +14,4 @@ import annotation.bridge import language.higherKinds trait GenericSeqCompanion[CC[X] <: Traversable[X]] - extends GenericCompanion[CC] { - - @bridge - override def empty[A]: CC[A] = super.empty[A] - - @bridge - override def apply[A](elems: A*): CC[A] = super.apply(elems: _*) - -} + extends GenericCompanion[CC] \ No newline at end of file diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala index b26e07393c..69eab43150 100644 --- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala @@ -147,11 +147,6 @@ trait GenericTraversableTemplate[+A, +CC[X] <: GenTraversable[X]] extends HasNew b.result } - // cannot have a bridge, because it would have the same signature as the target method after erasure - // @bridge - // def flatten[B](implicit asTraversable: A => /*<: GenTraversableOnce[B]) - /** Transposes this $coll of traversable collections into * a $coll of ${coll}s. * diff --git a/src/library/scala/collection/generic/MapFactory.scala b/src/library/scala/collection/generic/MapFactory.scala index e502c4067e..5a6d825aa8 100644 --- a/src/library/scala/collection/generic/MapFactory.scala +++ b/src/library/scala/collection/generic/MapFactory.scala @@ -36,6 +36,4 @@ abstract class MapFactory[CC[A, B] <: Map[A, B] with MapLike[A, B, CC[A, B]]] ex def empty[A, B]: CC[A, B] - @bridge - override def apply[A, B](elems: (A, B)*): CC[A, B] = super.apply(elems: _*) } diff --git a/src/library/scala/collection/generic/SetFactory.scala b/src/library/scala/collection/generic/SetFactory.scala index fb99f83ebb..7443bfbf6a 100644 --- a/src/library/scala/collection/generic/SetFactory.scala +++ b/src/library/scala/collection/generic/SetFactory.scala @@ -16,11 +16,4 @@ import annotation.bridge import language.higherKinds abstract class SetFactory[CC[X] <: Set[X] with SetLike[X, CC[X]]] - extends GenSetFactory[CC] with GenericSeqCompanion[CC] { - - @bridge - override def empty[A]: CC[A] = super.empty[A] - - @bridge - override def apply[A](elems: A*): CC[A] = super.apply(elems: _*) -} + extends GenSetFactory[CC] with GenericSeqCompanion[CC] \ No newline at end of file diff --git a/src/library/scala/collection/generic/Subtractable.scala b/src/library/scala/collection/generic/Subtractable.scala index 1ca9d706f0..ef4f466119 100644 --- a/src/library/scala/collection/generic/Subtractable.scala +++ b/src/library/scala/collection/generic/Subtractable.scala @@ -58,7 +58,4 @@ trait Subtractable[A, +Repr <: Subtractable[A, Repr]] { self => * except one less occurrence of each of the elements of `elems`. */ def --(xs: GenTraversableOnce[A]): Repr = (repr /: xs.seq) (_ - _) - - @bridge - def --(xs: TraversableOnce[A]): Repr = --(xs: GenTraversableOnce[A]) } diff --git a/src/library/scala/collection/generic/TraversableFactory.scala b/src/library/scala/collection/generic/TraversableFactory.scala index 07da1bb5c2..e99c77c4f1 100644 --- a/src/library/scala/collection/generic/TraversableFactory.scala +++ b/src/library/scala/collection/generic/TraversableFactory.scala @@ -37,48 +37,5 @@ import language.higherKinds * @see GenericCanBuildFrom */ trait TraversableFactory[CC[X] <: Traversable[X] with GenericTraversableTemplate[X, CC]] - extends GenTraversableFactory[CC] with GenericSeqCompanion[CC] { - - @bridge - override def concat[A](xss: Traversable[A]*): CC[A] = super.concat(xss: _*) - - @bridge - override def fill[A](n: Int)(elem: => A): CC[A] = super.fill(n)(elem) - - @bridge - override def fill[A](n1: Int, n2: Int)(elem: => A): CC[CC[A]] = super.fill(n1, n2)(elem) - - @bridge - override def fill[A](n1: Int, n2: Int, n3: Int)(elem: => A): CC[CC[CC[A]]] = super.fill(n1, n2, n3)(elem) - - @bridge - override def fill[A](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => A): CC[CC[CC[CC[A]]]] = super.fill(n1, n2, n3, n4)(elem) - - @bridge - override def fill[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => A): CC[CC[CC[CC[CC[A]]]]] = super.fill(n1, n2, n3, n4, n5)(elem) - - @bridge - override def tabulate[A](n: Int)(f: Int => A): CC[A] = super.tabulate(n)(f) - - @bridge - override def tabulate[A](n1: Int, n2: Int)(f: (Int, Int) => A): CC[CC[A]] = super.tabulate(n1, n2)(f) - - @bridge - override def tabulate[A](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => A): CC[CC[CC[A]]] = super.tabulate(n1, n2, n3)(f) - - @bridge - override def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => A): CC[CC[CC[CC[A]]]] = super.tabulate(n1, n2, n3, n4)(f) - - @bridge - override def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => A): CC[CC[CC[CC[CC[A]]]]] = super.tabulate(n1, n2, n3, n4, n5)(f) - - @bridge - override def range[T: Integral](start: T, end: T): CC[T] = super.range(start, end) - - @bridge - override def range[T: Integral](start: T, end: T, step: T): CC[T] = super.range(start, end, step) - - @bridge - override def iterate[A](start: A, len: Int)(f: A => A): CC[A] = super.iterate(start, len)(f) -} + extends GenTraversableFactory[CC] with GenericSeqCompanion[CC] diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala index e008fb86e3..9289b35632 100644 --- a/src/library/scala/collection/immutable/ListMap.scala +++ b/src/library/scala/collection/immutable/ListMap.scala @@ -105,9 +105,6 @@ extends AbstractMap[A, B] override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): ListMap[A, B1] = ((repr: ListMap[A, B1]) /: xs.seq) (_ + _) - @bridge def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): ListMap[A, B1] = - ++(xs: GenTraversableOnce[(A, B1)]) - /** This creates a new mapping without the given `key`. * If the map does not contain a mapping for the given key, the * method returns the same map. diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala index b71071d3c0..0331e01f35 100644 --- a/src/library/scala/collection/immutable/ListSet.scala +++ b/src/library/scala/collection/immutable/ListSet.scala @@ -102,8 +102,6 @@ class ListSet[A] extends AbstractSet[A] if (xs.isEmpty) this else (new ListSet.ListSetBuilder(this) ++= xs.seq).result - @bridge def ++(xs: TraversableOnce[A]): ListSet[A] = ++(xs: GenTraversableOnce[A]): ListSet[A] - private[ListSet] def unchecked_+(e: A): ListSet[A] = new Node(e) private[ListSet] def unchecked_outer: ListSet[A] = throw new NoSuchElementException("Empty ListSet has no outer pointer") diff --git a/src/library/scala/collection/immutable/MapLike.scala b/src/library/scala/collection/immutable/MapLike.scala index 80da1ab010..090c7f3043 100644 --- a/src/library/scala/collection/immutable/MapLike.scala +++ b/src/library/scala/collection/immutable/MapLike.scala @@ -86,8 +86,6 @@ trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]] override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): immutable.Map[A, B1] = ((repr: immutable.Map[A, B1]) /: xs.seq) (_ + _) - @bridge def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): immutable.Map[A, B1] = ++(xs: GenTraversableOnce[(A, B1)]) - /** Filters this map by retaining only keys satisfying a predicate. * @param p the predicate used to test keys * @return an immutable map consisting only of those key value pairs of this map where the key satisfies diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index b72d83f896..3eb37e99fc 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -400,8 +400,5 @@ object Range { } @deprecated("use Range instead", "2.9.0") - trait ByOne extends Range { -// @bridge override def foreach[@specialized(Unit) U](f: Int => U) = -// super.foreach(f) - } + trait ByOne extends Range } diff --git a/src/library/scala/collection/immutable/SortedMap.scala b/src/library/scala/collection/immutable/SortedMap.scala index 902a0f8457..05248e5805 100644 --- a/src/library/scala/collection/immutable/SortedMap.scala +++ b/src/library/scala/collection/immutable/SortedMap.scala @@ -77,8 +77,6 @@ trait SortedMap[A, +B] extends Map[A, B] */ override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): SortedMap[A, B1] = ((repr: SortedMap[A, B1]) /: xs.seq) (_ + _) - - @bridge def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): SortedMap[A, B1] = ++(xs: GenTraversableOnce[(A, B1)]) } /** $factoryInfo diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala index dc4f79be35..5c85621b0f 100644 --- a/src/library/scala/collection/immutable/TreeMap.scala +++ b/src/library/scala/collection/immutable/TreeMap.scala @@ -162,8 +162,6 @@ class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Orderi override def ++[B1 >: B] (xs: GenTraversableOnce[(A, B1)]): TreeMap[A, B1] = ((repr: TreeMap[A, B1]) /: xs.seq) (_ + _) - @bridge def ++[B1 >: B] (xs: TraversableOnce[(A, B1)]): TreeMap[A, B1] = ++(xs: GenTraversableOnce[(A, B1)]) - /** A new TreeMap with the entry added is returned, * assuming that key is not in the TreeMap. * diff --git a/src/library/scala/collection/mutable/BufferLike.scala b/src/library/scala/collection/mutable/BufferLike.scala index 1dc2fc27d5..f82a596b32 100644 --- a/src/library/scala/collection/mutable/BufferLike.scala +++ b/src/library/scala/collection/mutable/BufferLike.scala @@ -223,9 +223,6 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]] @migration("`++` creates a new buffer. Use `++=` to add an element from this buffer and return that buffer itself.", "2.8.0") def ++(xs: GenTraversableOnce[A]): This = clone() ++= xs.seq - @bridge - def ++(xs: TraversableOnce[A]): This = ++(xs: GenTraversableOnce[A]) - /** Creates a new collection with all the elements of this collection except `elem`. * * @param elem the element to remove. @@ -255,6 +252,4 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]] */ @migration("`--` creates a new buffer. Use `--=` to remove an element from this buffer and return that buffer itself.", "2.8.0") override def --(xs: GenTraversableOnce[A]): This = clone() --= xs.seq - - @bridge def --(xs: TraversableOnce[A]): This = --(xs: GenTraversableOnce[A]) } diff --git a/src/library/scala/collection/mutable/MapLike.scala b/src/library/scala/collection/mutable/MapLike.scala index b08a4b7bc9..b8b1152099 100644 --- a/src/library/scala/collection/mutable/MapLike.scala +++ b/src/library/scala/collection/mutable/MapLike.scala @@ -119,8 +119,6 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]] override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): Map[A, B1] = clone().asInstanceOf[Map[A, B1]] ++= xs.seq - @bridge def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): Map[A, B1] = ++(xs: GenTraversableOnce[(A, B1)]) - /** Removes a key from this map, returning the value associated previously * with that key as an option. * @param key the key to be removed @@ -224,6 +222,4 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]] */ @migration("`--` creates a new map. Use `--=` to remove an element from this map and return that map itself.", "2.8.0") override def --(xs: GenTraversableOnce[A]): This = clone() --= xs.seq - - @bridge def --(xs: TraversableOnce[A]): This = --(xs: GenTraversableOnce[A]) } diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index 381cb09e18..324af77dd4 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -113,9 +113,6 @@ class PriorityQueue[A](implicit val ord: Ordering[A]) */ def ++(xs: GenTraversableOnce[A]): PriorityQueue[A] = { this.clone() ++= xs.seq } - @bridge - def ++(xs: TraversableOnce[A]): PriorityQueue[A] = ++ (xs: GenTraversableOnce[A]) - /** Adds all elements to the queue. * * @param elems the elements to add. diff --git a/src/library/scala/collection/mutable/SetLike.scala b/src/library/scala/collection/mutable/SetLike.scala index 5e201d9959..37313c8ca3 100644 --- a/src/library/scala/collection/mutable/SetLike.scala +++ b/src/library/scala/collection/mutable/SetLike.scala @@ -170,8 +170,6 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]] @migration("`++` creates a new set. Use `++=` to add elements to this set and return that set itself.", "2.8.0") override def ++(xs: GenTraversableOnce[A]): This = clone() ++= xs.seq - @bridge def ++(xs: TraversableOnce[A]): This = ++(xs: GenTraversableOnce[A]) - /** Creates a new set consisting of all the elements of this set except `elem`. * * @param elem the element to remove. @@ -203,8 +201,6 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]] @migration("`--` creates a new set. Use `--=` to remove elements from this set and return that set itself.", "2.8.0") override def --(xs: GenTraversableOnce[A]): This = clone() --= xs.seq - @bridge def --(xs: TraversableOnce[A]): This = --(xs: GenTraversableOnce[A]) - /** Send a message to this scriptable object. * * @param cmd the message to send. diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index 1ef1911fd3..e50f854bc5 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -84,11 +84,6 @@ package object scala { @deprecated("Use Thread.currentThread instead", "2.9.0") def currentThread = java.lang.Thread.currentThread() - // Moved back into Predef to avoid unnecessary indirection by - // way of the scala package object within the standard library, - // but bridged for compatibility. - @bridge def $scope = scala.xml.TopScope - // Numeric types which were moved into scala.math.* type BigDecimal = scala.math.BigDecimal diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala index cf5aab0be4..fcacb9c82a 100644 --- a/src/library/scala/runtime/RichInt.scala +++ b/src/library/scala/runtime/RichInt.scala @@ -37,9 +37,6 @@ final class RichInt(val self: Int) extends ScalaNumberProxy[Int] with RangedProx */ def until(end: Int, step: Int): Range = Range(self, end, step) -// @bridge -// def until(end: Int): Range with Range.ByOne = new Range(self, end, 1) with Range.ByOne - /** like `until`, but includes the last index */ /** * @param end The final bound of the range to make. @@ -56,9 +53,6 @@ final class RichInt(val self: Int) extends ScalaNumberProxy[Int] with RangedProx */ def to(end: Int, step: Int): Range.Inclusive = Range.inclusive(self, end, step) -// @bridge -// def to(end: Int): Range with Range.ByOne = new Range.Inclusive(self, end, 1) with Range.ByOne - /** * @return `'''this'''` if `'''this''' < that` or `that` otherwise */ -- cgit v1.2.3 From 14144be0bcd3f6823a9622c6f962aed295ef3392 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 28 Apr 2012 11:52:10 -0700 Subject: Removed a few more @deprecated members. The ones which remain I'm not removing on purpose, as I know from experience it's more trouble than it's yet worth. --- src/compiler/scala/reflect/internal/TreeGen.scala | 15 ++++++++------- src/compiler/scala/tools/nsc/javac/JavaParsers.scala | 13 +++++++------ src/library/scala/Predef.scala | 7 ------- src/library/scala/collection/immutable/Range.scala | 3 --- src/library/scala/package.scala | 13 ------------- src/library/scala/reflect/makro/internal/macroImpl.scala | 2 +- src/library/scala/runtime/package.scala | 12 +----------- test/files/neg/annot-nonconst.check | 4 ++-- test/files/neg/annot-nonconst.scala | 4 ++-- test/files/neg/reify_ann2b.check | 8 ++++---- test/files/neg/reify_ann2b.scala | 2 +- test/files/pos/annot-inner.scala | 2 +- test/files/pos/annotDepMethType.scala | 2 +- test/files/pos/annotations.scala | 10 +++++----- test/files/pos/attributes.scala | 14 +++++++------- test/files/pos/spec-annotations.scala | 2 +- test/files/pos/t1029/Test_1.scala | 2 +- test/files/pos/t1203.scala | 2 +- test/files/pos/t1942/A_1.scala | 2 +- test/files/pos/t2868/pick_1.scala | 2 +- test/files/pos/t3800.scala | 2 +- test/files/pos/t3951/Coll_1.scala | 2 +- test/files/run/bugs.scala | 3 +-- .../files/run/macro-declared-in-annotation/Macros_2.scala | 2 +- test/files/run/reify_ann1a.scala | 2 +- test/files/run/reify_ann1b.scala | 2 +- test/files/run/reify_ann2a.scala | 2 +- test/files/run/reify_classfileann_a.scala | 2 +- test/files/run/reify_classfileann_b.scala | 2 +- test/files/run/t1500.scala | 2 +- test/files/run/t1501.scala | 2 +- test/files/run/t5224.scala | 2 +- test/files/run/t5419.scala | 2 +- test/files/run/t5423.scala | 2 +- 34 files changed, 59 insertions(+), 91 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala index f30ec67c7e..f2f9842595 100644 --- a/src/compiler/scala/reflect/internal/TreeGen.scala +++ b/src/compiler/scala/reflect/internal/TreeGen.scala @@ -7,13 +7,14 @@ abstract class TreeGen extends api.AbsTreeGen { import global._ import definitions._ - def rootId(name: Name) = Select(Ident(nme.ROOTPKG), name) - def rootScalaDot(name: Name) = Select(rootId(nme.scala_) setSymbol ScalaPackage, name) - def scalaDot(name: Name) = Select(Ident(nme.scala_) setSymbol ScalaPackage, name) - def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) setSymbol AnyRefClass - def scalaUnitConstr = scalaDot(tpnme.Unit) setSymbol UnitClass - def productConstr = scalaDot(tpnme.Product) setSymbol ProductRootClass - def serializableConstr = scalaDot(tpnme.Serializable) setSymbol SerializableClass + def rootId(name: Name) = Select(Ident(nme.ROOTPKG), name) + def rootScalaDot(name: Name) = Select(rootId(nme.scala_) setSymbol ScalaPackage, name) + def scalaDot(name: Name) = Select(Ident(nme.scala_) setSymbol ScalaPackage, name) + def scalaAnnotationDot(name: Name) = Select(scalaDot(nme.annotation), name) + def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) setSymbol AnyRefClass + def scalaUnitConstr = scalaDot(tpnme.Unit) setSymbol UnitClass + def productConstr = scalaDot(tpnme.Product) setSymbol ProductRootClass + def serializableConstr = scalaDot(tpnme.Serializable) setSymbol SerializableClass def scalaFunctionConstr(argtpes: List[Tree], restpe: Tree, abstractFun: Boolean = false): Tree = { val cls = if (abstractFun) diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index ca3f3ff635..5c413243e8 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -789,23 +789,24 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { val idefs = members.toList ::: (sdefs flatMap forwarders) (sdefs, idefs) } - + def annotationParents = List( + gen.scalaAnnotationDot(tpnme.Annotation), + Select(javaLangDot(nme.annotation), tpnme.Annotation), + gen.scalaAnnotationDot(tpnme.ClassfileAnnotation) + ) def annotationDecl(mods: Modifiers): List[Tree] = { accept(AT) accept(INTERFACE) val pos = in.currentPos val name = identForType() - val parents = List(scalaDot(tpnme.Annotation), - Select(javaLangDot(nme.annotation), tpnme.Annotation), - scalaDot(tpnme.ClassfileAnnotation)) val (statics, body) = typeBody(AT, name) def getValueMethodType(tree: Tree) = tree match { case DefDef(_, nme.value, _, _, tpt, _) => Some(tpt.duplicate) case _ => None } - var templ = makeTemplate(parents, body) + var templ = makeTemplate(annotationParents, body) for (stat <- templ.body; tpt <- getValueMethodType(stat)) - templ = makeTemplate(parents, makeConstructor(List(tpt)) :: templ.body) + templ = makeTemplate(annotationParents, makeConstructor(List(tpt)) :: templ.body) addCompanionObject(statics, atPos(pos) { ClassDef(mods, name, List(), templ) }) diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index d2aa3a8b34..b84fcc4126 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -468,13 +468,6 @@ object Predef extends LowPriorityImplicits { implicit def tpEquals[A]: A =:= A = singleton_=:=.asInstanceOf[A =:= A] } - // less useful due to #2781 - @deprecated("Use From => To instead", "2.9.0") - 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} - } - /** A type for which there is always an implicit value. * @see fallbackCanBuildFrom in Array.scala */ diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 3eb37e99fc..07c8df57ba 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -398,7 +398,4 @@ object Range { def apply(start: Int, end: Int, step: Int) = NumericRange(start, end, step) def inclusive(start: Int, end: Int, step: Int) = NumericRange.inclusive(start, end, step) } - - @deprecated("use Range instead", "2.9.0") - trait ByOne extends Range } diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index e50f854bc5..064ccd7735 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -80,10 +80,6 @@ package object scala { type Range = scala.collection.immutable.Range val Range = scala.collection.immutable.Range - // Migrated from Predef - @deprecated("Use Thread.currentThread instead", "2.9.0") - def currentThread = java.lang.Thread.currentThread() - // Numeric types which were moved into scala.math.* type BigDecimal = scala.math.BigDecimal @@ -127,13 +123,4 @@ package object scala { type unchecked = annotation.unchecked.unchecked type volatile = annotation.volatile */ - - @deprecated("use scala.annotation.Annotation instead", "2.9.0") - type Annotation = scala.annotation.Annotation - @deprecated("use scala.annotation.ClassfileAnnotation instead", "2.9.0") - type ClassfileAnnotation = scala.annotation.ClassfileAnnotation - @deprecated("use scala.annotation.StaticAnnotation instead", "2.9.0") - type StaticAnnotation = scala.annotation.StaticAnnotation - @deprecated("use scala.annotation.TypeConstraint instead", "2.9.0") - type TypeConstraint = scala.annotation.TypeConstraint } diff --git a/src/library/scala/reflect/makro/internal/macroImpl.scala b/src/library/scala/reflect/makro/internal/macroImpl.scala index 86600ba0a1..9cf4d23072 100644 --- a/src/library/scala/reflect/makro/internal/macroImpl.scala +++ b/src/library/scala/reflect/makro/internal/macroImpl.scala @@ -2,4 +2,4 @@ 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 +class macroImpl(val referenceToMacroImpl: Any) extends annotation.StaticAnnotation diff --git a/src/library/scala/runtime/package.scala b/src/library/scala/runtime/package.scala index 9c87baf6a7..e4472b3ea1 100644 --- a/src/library/scala/runtime/package.scala +++ b/src/library/scala/runtime/package.scala @@ -1,13 +1,3 @@ package scala -package object runtime { - @deprecated("Use `scala.Unit` instead.", "2.9.0") val Unit = scala.Unit - @deprecated("Use `scala.Boolean` instead.", "2.9.0") val Boolean = scala.Boolean - @deprecated("Use `scala.Byte` instead.", "2.9.0") val Byte = scala.Byte - @deprecated("Use `scala.Short` instead.", "2.9.0") val Short = scala.Short - @deprecated("Use `scala.Char` instead.", "2.9.0") val Char = scala.Char - @deprecated("Use `scala.Int` instead.", "2.9.0") val Int = scala.Int - @deprecated("Use `scala.Long` instead.", "2.9.0") val Long = scala.Long - @deprecated("Use `scala.Float` instead.", "2.9.0") val Float = scala.Float - @deprecated("Use `scala.Double` instead.", "2.9.0") val Double = scala.Double -} +package object runtime { } diff --git a/test/files/neg/annot-nonconst.check b/test/files/neg/annot-nonconst.check index e4166e08b6..b43e58a0ca 100644 --- a/test/files/neg/annot-nonconst.check +++ b/test/files/neg/annot-nonconst.check @@ -1,12 +1,12 @@ annot-nonconst.scala:1: warning: Implementation restriction: subclassing Classfile does not make your annotation visible at runtime. If that is what you want, you must write the annotation class in Java. -class Length(value: Int) extends ClassfileAnnotation +class Length(value: Int) extends annotation.ClassfileAnnotation ^ annot-nonconst.scala:2: warning: Implementation restriction: subclassing Classfile does not make your annotation visible at runtime. If that is what you want, you must write the annotation class in Java. -class Ann2(value: String) extends ClassfileAnnotation +class Ann2(value: String) extends annotation.ClassfileAnnotation ^ annot-nonconst.scala:6: error: annotation argument needs to be a constant; found: n @Length(n) def foo = "foo" diff --git a/test/files/neg/annot-nonconst.scala b/test/files/neg/annot-nonconst.scala index 69bb60d34e..1b5856f8b2 100644 --- a/test/files/neg/annot-nonconst.scala +++ b/test/files/neg/annot-nonconst.scala @@ -1,5 +1,5 @@ -class Length(value: Int) extends ClassfileAnnotation -class Ann2(value: String) extends ClassfileAnnotation +class Length(value: Int) extends annotation.ClassfileAnnotation +class Ann2(value: String) extends annotation.ClassfileAnnotation object Test { def n = 15 diff --git a/test/files/neg/reify_ann2b.check b/test/files/neg/reify_ann2b.check index b9dd84c1ee..52bdbe5b7c 100644 --- a/test/files/neg/reify_ann2b.check +++ b/test/files/neg/reify_ann2b.check @@ -1,4 +1,4 @@ -reify_ann2b.scala:6: error: inner classes cannot be classfile annotations - class ann(bar: String) extends ClassfileAnnotation - ^ -one error found +reify_ann2b.scala:6: error: inner classes cannot be classfile annotations + class ann(bar: String) extends annotation.ClassfileAnnotation + ^ +one error found diff --git a/test/files/neg/reify_ann2b.scala b/test/files/neg/reify_ann2b.scala index 6b6da8f790..397d00210d 100644 --- a/test/files/neg/reify_ann2b.scala +++ b/test/files/neg/reify_ann2b.scala @@ -3,7 +3,7 @@ import scala.reflect.mirror._ object Test extends App { // test 1: reify val tree = reify{ - class ann(bar: String) extends ClassfileAnnotation + class ann(bar: String) extends annotation.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")) { @ann(bar="5a") @ann(bar="5b") def f(x: Int @ann(bar="6a") @ann(bar="6b")) = { diff --git a/test/files/pos/annot-inner.scala b/test/files/pos/annot-inner.scala index f2ecb5ddb3..9f155a5a83 100644 --- a/test/files/pos/annot-inner.scala +++ b/test/files/pos/annot-inner.scala @@ -1,5 +1,5 @@ object test { - class annot extends Annotation + class annot extends scala.annotation.Annotation def foo { @annot def bar(i: Int): Int = i diff --git a/test/files/pos/annotDepMethType.scala b/test/files/pos/annotDepMethType.scala index b5e7cb9e8b..079ca6224c 100644 --- a/test/files/pos/annotDepMethType.scala +++ b/test/files/pos/annotDepMethType.scala @@ -1,4 +1,4 @@ -case class pc(calls: Any*) extends TypeConstraint +case class pc(calls: Any*) extends annotation.TypeConstraint object Main { class C0 { def baz: String = "" } diff --git a/test/files/pos/annotations.scala b/test/files/pos/annotations.scala index 4e5fddda39..706a715bad 100644 --- a/test/files/pos/annotations.scala +++ b/test/files/pos/annotations.scala @@ -1,5 +1,5 @@ -class ann(i: Int) extends Annotation -class cfann(x: String) extends ClassfileAnnotation +class ann(i: Int) extends scala.annotation.Annotation +class cfann(x: String) extends annotation.ClassfileAnnotation // annotations on abstract types abstract class C1[@serializable @cloneable +T, U, V[_]] @@ -91,9 +91,9 @@ trait BeanF { } -class Ann3(arr: Array[String]) extends ClassfileAnnotation -class Ann4(i: Int) extends ClassfileAnnotation -class Ann5(value: Class[_]) extends ClassfileAnnotation +class Ann3(arr: Array[String]) extends annotation.ClassfileAnnotation +class Ann4(i: Int) extends annotation.ClassfileAnnotation +class Ann5(value: Class[_]) extends annotation.ClassfileAnnotation object Test3 { final val i = 1083 diff --git a/test/files/pos/attributes.scala b/test/files/pos/attributes.scala index f3bbb4c42e..ec735d0aae 100644 --- a/test/files/pos/attributes.scala +++ b/test/files/pos/attributes.scala @@ -52,15 +52,15 @@ object O6 { } object myAttrs { - class a1 extends scala.Annotation; - class a2(x: Int) extends scala.Annotation; - class a3(x: a1) extends scala.Annotation; + class a1 extends scala.annotation.Annotation; + class a2(x: Int) extends scala.annotation.Annotation; + class a3(x: a1) extends scala.annotation.Annotation; } -class a4(ns: Array[Int]) extends scala.Annotation; +class a4(ns: Array[Int]) extends scala.annotation.Annotation; object O7 { - class a1 extends scala.Annotation; - class a2(x: Int) extends scala.Annotation; - class a3(x: a1) extends scala.Annotation; + class a1 extends scala.annotation.Annotation; + class a2(x: Int) extends scala.annotation.Annotation; + class a3(x: a1) extends scala.annotation.Annotation; final val x = new a1; @a1 class C1; diff --git a/test/files/pos/spec-annotations.scala b/test/files/pos/spec-annotations.scala index 35cab6de09..48281e5df5 100644 --- a/test/files/pos/spec-annotations.scala +++ b/test/files/pos/spec-annotations.scala @@ -1,4 +1,4 @@ -class ann(i: Int) extends Annotation +class ann(i: Int) extends scala.annotation.Annotation // annotations on abstract types abstract class C1[@serializable @cloneable +T, U, V[_]] diff --git a/test/files/pos/t1029/Test_1.scala b/test/files/pos/t1029/Test_1.scala index e828087f2c..d268c71429 100644 --- a/test/files/pos/t1029/Test_1.scala +++ b/test/files/pos/t1029/Test_1.scala @@ -1,4 +1,4 @@ -class ann(a: Array[Int]) extends StaticAnnotation +class ann(a: Array[Int]) extends annotation.StaticAnnotation object Test1 { // bug #1029 diff --git a/test/files/pos/t1203.scala b/test/files/pos/t1203.scala index 4938621aa9..062ef93fc6 100644 --- a/test/files/pos/t1203.scala +++ b/test/files/pos/t1203.scala @@ -1,4 +1,4 @@ -case class ant(t: String) extends Annotation +case class ant(t: String) extends scala.annotation.Annotation object Test { def main(args: Array[String]): Unit = { val a: scala.xml.NodeSeq @ant("12") = Nil diff --git a/test/files/pos/t1942/A_1.scala b/test/files/pos/t1942/A_1.scala index 19a7575a0a..4915b54a64 100644 --- a/test/files/pos/t1942/A_1.scala +++ b/test/files/pos/t1942/A_1.scala @@ -3,7 +3,7 @@ class A { def foo(x: String) = 1 } -class ann(x: Int) extends StaticAnnotation +class ann(x: Int) extends annotation.StaticAnnotation class t { val a = new A diff --git a/test/files/pos/t2868/pick_1.scala b/test/files/pos/t2868/pick_1.scala index e91728ec2f..a211687432 100644 --- a/test/files/pos/t2868/pick_1.scala +++ b/test/files/pos/t2868/pick_1.scala @@ -1,4 +1,4 @@ -class ann(s: String) extends StaticAnnotation +class ann(s: String) extends annotation.StaticAnnotation class pick { final val s = "bang!" @ann("bang!") def foo = 1 diff --git a/test/files/pos/t3800.scala b/test/files/pos/t3800.scala index 796eb268c5..61dbeafff3 100644 --- a/test/files/pos/t3800.scala +++ b/test/files/pos/t3800.scala @@ -1,4 +1,4 @@ -class meh extends StaticAnnotation +class meh extends annotation.StaticAnnotation class ALike[C] abstract class AFactory[CC[x] <: ALike[CC[x]]] { diff --git a/test/files/pos/t3951/Coll_1.scala b/test/files/pos/t3951/Coll_1.scala index c2cc39a1a9..556c848688 100644 --- a/test/files/pos/t3951/Coll_1.scala +++ b/test/files/pos/t3951/Coll_1.scala @@ -15,7 +15,7 @@ sealed trait DynamicDocument extends Document { class Coll extends StaticDocument // similiar issue with annotations -class ann[T] extends StaticAnnotation +class ann[T] extends annotation.StaticAnnotation trait StatDoc extends Doc { @ann[StatFB] diff --git a/test/files/run/bugs.scala b/test/files/run/bugs.scala index d5905af76c..ca598603bb 100644 --- a/test/files/run/bugs.scala +++ b/test/files/run/bugs.scala @@ -445,8 +445,7 @@ object Test { test; } catch { case exception => - val curr: String = currentThread.toString(); - Console.print("Exception in thread \"" + curr + "\" " + exception); + Console.print("Exception in thread \"" + Thread.currentThread + "\" " + exception); Console.println; errors += 1 } diff --git a/test/files/run/macro-declared-in-annotation/Macros_2.scala b/test/files/run/macro-declared-in-annotation/Macros_2.scala index a565849aa9..40d71c62fb 100644 --- a/test/files/run/macro-declared-in-annotation/Macros_2.scala +++ b/test/files/run/macro-declared-in-annotation/Macros_2.scala @@ -1,4 +1,4 @@ -class foo(val bar: String) extends StaticAnnotation +class foo(val bar: String) extends annotation.StaticAnnotation object Api { // foo in ann must have a different name diff --git a/test/files/run/reify_ann1a.scala b/test/files/run/reify_ann1a.scala index 1f5d1daccd..6c062ca2c2 100644 --- a/test/files/run/reify_ann1a.scala +++ b/test/files/run/reify_ann1a.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class ann(bar: List[String]) extends StaticAnnotation +class ann(bar: List[String]) extends annotation.StaticAnnotation object Test extends App { // test 1: reify diff --git a/test/files/run/reify_ann1b.scala b/test/files/run/reify_ann1b.scala index 13d861a15c..4faddef72c 100644 --- a/test/files/run/reify_ann1b.scala +++ b/test/files/run/reify_ann1b.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class ann(bar: String) extends ClassfileAnnotation +class ann(bar: String) extends annotation.ClassfileAnnotation object Test extends App { // test 1: reify diff --git a/test/files/run/reify_ann2a.scala b/test/files/run/reify_ann2a.scala index 370abadba0..a1723c221d 100644 --- a/test/files/run/reify_ann2a.scala +++ b/test/files/run/reify_ann2a.scala @@ -3,7 +3,7 @@ import scala.reflect.mirror._ object Test extends App { // test 1: reify val tree = reify{ - class ann(bar: List[String]) extends StaticAnnotation + class ann(bar: List[String]) extends annotation.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"))) = { diff --git a/test/files/run/reify_classfileann_a.scala b/test/files/run/reify_classfileann_a.scala index c3e7d8d2e9..9aec69b4a3 100644 --- a/test/files/run/reify_classfileann_a.scala +++ b/test/files/run/reify_classfileann_a.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation +class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends annotation.ClassfileAnnotation object Test extends App { // test 1: reify diff --git a/test/files/run/reify_classfileann_b.scala b/test/files/run/reify_classfileann_b.scala index 4e50494af3..a37f20e72e 100644 --- a/test/files/run/reify_classfileann_b.scala +++ b/test/files/run/reify_classfileann_b.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation +class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends annotation.ClassfileAnnotation object Test extends App { // test 1: reify diff --git a/test/files/run/t1500.scala b/test/files/run/t1500.scala index c312a9a883..586a2666ad 100644 --- a/test/files/run/t1500.scala +++ b/test/files/run/t1500.scala @@ -8,7 +8,7 @@ object Test { val testCode = - class posingAs[A] extends TypeConstraint + class posingAs[A] extends annotation.TypeConstraint def resolve[A,B](x: A @posingAs[B]): B = x.asInstanceOf[B] diff --git a/test/files/run/t1501.scala b/test/files/run/t1501.scala index 05e4da8c7a..dee6e0c68e 100644 --- a/test/files/run/t1501.scala +++ b/test/files/run/t1501.scala @@ -8,7 +8,7 @@ object Test { val testCode = - class xyz[A] extends TypeConstraint + class xyz[A] extends annotation.TypeConstraint def loopWhile[T](cond: =>Boolean)(body: =>(Unit @xyz[T])): Unit @ xyz[T] = {{ if (cond) {{ diff --git a/test/files/run/t5224.scala b/test/files/run/t5224.scala index 93b244e03e..cf65f16457 100644 --- a/test/files/run/t5224.scala +++ b/test/files/run/t5224.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class Foo(bar: String) extends ClassfileAnnotation +class Foo(bar: String) extends annotation.ClassfileAnnotation object Test extends App { val tree = reify{@Foo(bar = "qwe") class C}.tree diff --git a/test/files/run/t5419.scala b/test/files/run/t5419.scala index d65d8f38c8..5f11f5056c 100644 --- a/test/files/run/t5419.scala +++ b/test/files/run/t5419.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class Foo extends StaticAnnotation +class Foo extends annotation.StaticAnnotation object Test extends App { val tree = reify{(5: @Foo).asInstanceOf[Int]}.tree diff --git a/test/files/run/t5423.scala b/test/files/run/t5423.scala index 645c8c7c1d..ed1faf0429 100644 --- a/test/files/run/t5423.scala +++ b/test/files/run/t5423.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -final class table extends StaticAnnotation +final class table extends annotation.StaticAnnotation @table class A object Test extends App { -- cgit v1.2.3 From 3404d5a9bf750e7022934d6b70035718544be900 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 28 Apr 2012 12:37:12 -0700 Subject: @unspecialized annotation. Suppresses specialization on a per-method basis. I would have preferred to call it @nospecialize, but seeing as the positive form of the annotation is @specialized, that would have sown unnecessary grammatical confusion. @nospecialized sounds a bit too caveman for my tastes. "Grog no specialized! Grog generic!" --- src/build/genprod.scala | 23 +++++++++++----------- .../scala/reflect/internal/Definitions.scala | 1 + .../tools/nsc/transform/SpecializeTypes.scala | 17 ++++++++++------ src/library/scala/Function0.scala | 6 +++--- src/library/scala/Function1.scala | 8 ++++---- src/library/scala/Function10.scala | 7 ++++--- src/library/scala/Function11.scala | 7 ++++--- src/library/scala/Function12.scala | 7 ++++--- src/library/scala/Function13.scala | 7 ++++--- src/library/scala/Function14.scala | 7 ++++--- src/library/scala/Function15.scala | 7 ++++--- src/library/scala/Function16.scala | 7 ++++--- src/library/scala/Function17.scala | 7 ++++--- src/library/scala/Function18.scala | 7 ++++--- src/library/scala/Function19.scala | 7 ++++--- src/library/scala/Function2.scala | 11 ++++++----- src/library/scala/Function20.scala | 7 ++++--- src/library/scala/Function21.scala | 7 ++++--- src/library/scala/Function22.scala | 7 ++++--- src/library/scala/Function3.scala | 7 ++++--- src/library/scala/Function4.scala | 7 ++++--- src/library/scala/Function5.scala | 7 ++++--- src/library/scala/Function6.scala | 7 ++++--- src/library/scala/Function7.scala | 7 ++++--- src/library/scala/Function8.scala | 7 ++++--- src/library/scala/Function9.scala | 7 ++++--- src/library/scala/Tuple2.scala | 13 ++---------- src/library/scala/Tuple3.scala | 13 +----------- src/library/scala/annotation/unspecialized.scala | 17 ++++++++++++++++ .../scala/runtime/AbstractPartialFunction.scala | 8 ++++---- 30 files changed, 141 insertions(+), 116 deletions(-) create mode 100644 src/library/scala/annotation/unspecialized.scala (limited to 'src') diff --git a/src/build/genprod.scala b/src/build/genprod.scala index 1ea0bf7b73..5a77c7a699 100644 --- a/src/build/genprod.scala +++ b/src/build/genprod.scala @@ -130,7 +130,7 @@ object FunctionOne extends Function(1) { * @param g a function A => T1 * @return a new function `f` such that `f(x) == apply(g(x))` */ - def compose[A](g: A => T1): A => R = { x => apply(g(x)) } + @annotation.unspecialized def compose[A](g: A => T1): A => R = { x => apply(g(x)) } /** Composes two instances of Function1 in a new Function1, with this function applied first. * @@ -138,7 +138,7 @@ object FunctionOne extends Function(1) { * @param g a function R => A * @return a new function `f` such that `f(x) == g(apply(x))` */ - def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } + @annotation.unspecialized def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } """ } @@ -169,19 +169,20 @@ object Function { class Function(val i: Int) extends Group("Function") with Arity { def descriptiveComment = "" - def functionNTemplate = """ + def functionNTemplate = +""" * In the following example, the definition of %s is a * shorthand for the anonymous class definition %s: * * {{{ - * object Main extends App { %s } + * object Main extends App {%s} * }}} * * Note that `Function1` does not define a total function, as might * be suggested by the existence of [[scala.PartialFunction]]. The only * distinction between `Function1` and `PartialFunction` is that the * latter can specify inputs which it will not handle. - """ +""" def toStr() = "\"" + ("" format i) + "\"" def apply() = { @@ -195,7 +196,7 @@ class Function(val i: Int) extends Group("Function") with Arity { * @return the result of function application. */ def apply({funArgs}): R - {moreMethods} +{moreMethods} override def toString() = {toStr} }} @@ -218,15 +219,15 @@ class Function(val i: Int) extends Group("Function") with Arity { // f(x1,x2,x3,x4,x5,x6) == (f.curried)(x1)(x2)(x3)(x4)(x5)(x6) def curryComment = { -"""/** Creates a curried version of this function. +""" /** Creates a curried version of this function. * * @return a function `f` such that `f%s == apply%s` */""".format(xdefs map ("(" + _ + ")") mkString, commaXs) } def tupleMethod = { - def comment = """ - /** Creates a tupled version of this function: instead of %d arguments, + def comment = +""" /** Creates a tupled version of this function: instead of %d arguments, * it accepts a single [[scala.Tuple%d]] argument. * * @return a function `f` such that `f(%s) == f(Tuple%d%s) == apply%s` @@ -234,14 +235,14 @@ class Function(val i: Int) extends Group("Function") with Arity { """.format(i, i, commaXs, i, commaXs, commaXs) def body = "case Tuple%d%s => apply%s".format(i, commaXs, commaXs) - comment + " def tupled: Tuple%d%s => R = {\n %s\n }".format(i, invariantArgs, body) + comment + "\n @annotation.unspecialized def tupled: Tuple%d%s => R = {\n %s\n }".format(i, invariantArgs, body) } def curryMethod = { val body = if (i < 5) shortCurry else longCurry curryComment + - " def curried: %s => R = {\n %s\n }\n".format( + "\n @annotation.unspecialized def curried: %s => R = {\n %s\n }\n".format( targs mkString " => ", body ) } diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index d89e852124..9e28319882 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -946,6 +946,7 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val ThrowsClass = getRequiredClass("scala.throws") lazy val TransientAttr = getRequiredClass("scala.transient") lazy val UncheckedClass = getRequiredClass("scala.unchecked") + lazy val UnspecializedClass = getRequiredClass("scala.annotation.unspecialized") lazy val VolatileAttr = getRequiredClass("scala.volatile") // Meta-annotations diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 1fb7fac184..f6296acdca 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -68,7 +68,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { import definitions.{ RootClass, BooleanClass, UnitClass, ArrayClass, ScalaValueClasses, isPrimitiveValueClass, isScalaValueType, - SpecializedClass, AnyRefClass, ObjectClass, AnyRefModule, + SpecializedClass, UnspecializedClass, AnyRefClass, ObjectClass, AnyRefModule, GroupOfSpecializable, uncheckedVarianceClass, ScalaInlineClass } @@ -374,12 +374,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * - members with specialized type parameters found in the given environment * - constructors of specialized classes * - normalized members whose type bounds appear in the environment + * But suppressed for: + * - any member with the @unspecialized annotation, or which has an + * enclosing member with the annotation. */ - private def needsSpecialization(env: TypeEnv, sym: Symbol): Boolean = { - specializedTypeVars(sym).intersect(env.keySet).diff(wasSpecializedForTypeVars(sym)).nonEmpty || - (sym.isClassConstructor && (sym.enclClass.typeParams exists (_.isSpecialized))) || - (isNormalizedMember(sym) && info(sym).typeBoundsIn(env)) - } + private def needsSpecialization(env: TypeEnv, sym: Symbol): Boolean = ( + !sym.ownerChain.exists(_ hasAnnotation UnspecializedClass) && ( + specializedTypeVars(sym).intersect(env.keySet).diff(wasSpecializedForTypeVars(sym)).nonEmpty + || sym.isClassConstructor && (sym.enclClass.typeParams exists (_.isSpecialized)) + || isNormalizedMember(sym) && info(sym).typeBoundsIn(env) + ) + ) def isNormalizedMember(m: Symbol) = m.isSpecialized && (info get m exists { case NormalizedMember(_) => true diff --git a/src/library/scala/Function0.scala b/src/library/scala/Function0.scala index dceed26439..e1e9ddb3fb 100644 --- a/src/library/scala/Function0.scala +++ b/src/library/scala/Function0.scala @@ -6,13 +6,13 @@ ** |/ ** \* */ // GENERATED CODE: DO NOT EDIT. -// genprod generated these sources at: Tue Feb 14 16:49:03 PST 2012 +// genprod generated these sources at: Sat Apr 28 12:59:55 PDT 2012 package scala /** A function of 0 parameters. - * + * * In the following example, the definition of javaVersion is a * shorthand for the anonymous class definition anonfun0: * @@ -24,7 +24,7 @@ package scala * def apply(): String = sys.props("java.version") * } * assert(javaVersion() == anonfun0()) - * } + * } * }}} * * Note that `Function1` does not define a total function, as might diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala index 8995ef912b..f9b37fc6bd 100644 --- a/src/library/scala/Function1.scala +++ b/src/library/scala/Function1.scala @@ -11,7 +11,7 @@ package scala /** A function of 1 parameter. - * + * * In the following example, the definition of succ is a * shorthand for the anonymous class definition anonfun1: * @@ -22,7 +22,7 @@ package scala * def apply(x: Int): Int = x + 1 * } * assert(succ(0) == anonfun1(0)) - * } + * } * }}} * * Note that `Function1` does not define a total function, as might @@ -44,7 +44,7 @@ trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, s * @param g a function A => T1 * @return a new function `f` such that `f(x) == apply(g(x))` */ - def compose[A](g: A => T1): A => R = { x => apply(g(x)) } + @annotation.unspecialized def compose[A](g: A => T1): A => R = { x => apply(g(x)) } /** Composes two instances of Function1 in a new Function1, with this function applied first. * @@ -52,7 +52,7 @@ trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, s * @param g a function R => A * @return a new function `f` such that `f(x) == g(apply(x))` */ - def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } + @annotation.unspecialized def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } override def toString() = "" } diff --git a/src/library/scala/Function10.scala b/src/library/scala/Function10.scala index 9e107fc53d..f7e5d414f2 100644 --- a/src/library/scala/Function10.scala +++ b/src/library/scala/Function10.scala @@ -21,16 +21,17 @@ trait Function10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)).curried } - /** Creates a tupled version of this function: instead of 10 arguments, * it accepts a single [[scala.Tuple10]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) == f(Tuple10(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)` */ - def tupled: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] => R = { + + @annotation.unspecialized def tupled: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] => R = { case Tuple10(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) } override def toString() = "" diff --git a/src/library/scala/Function11.scala b/src/library/scala/Function11.scala index 783a86ab5d..53742bf733 100644 --- a/src/library/scala/Function11.scala +++ b/src/library/scala/Function11.scala @@ -21,16 +21,17 @@ trait Function11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] ex /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)).curried } - /** Creates a tupled version of this function: instead of 11 arguments, * it accepts a single [[scala.Tuple11]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) == f(Tuple11(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)` */ - def tupled: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] => R = { + + @annotation.unspecialized def tupled: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] => R = { case Tuple11(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) } override def toString() = "" diff --git a/src/library/scala/Function12.scala b/src/library/scala/Function12.scala index 7f4dee6216..e349d9017d 100644 --- a/src/library/scala/Function12.scala +++ b/src/library/scala/Function12.scala @@ -21,16 +21,17 @@ trait Function12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)).curried } - /** Creates a tupled version of this function: instead of 12 arguments, * it accepts a single [[scala.Tuple12]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) == f(Tuple12(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)` */ - def tupled: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] => R = { + + @annotation.unspecialized def tupled: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] => R = { case Tuple12(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) } override def toString() = "" diff --git a/src/library/scala/Function13.scala b/src/library/scala/Function13.scala index 23853dde69..10ec64b87a 100644 --- a/src/library/scala/Function13.scala +++ b/src/library/scala/Function13.scala @@ -21,16 +21,17 @@ trait Function13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)).curried } - /** Creates a tupled version of this function: instead of 13 arguments, * it accepts a single [[scala.Tuple13]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) == f(Tuple13(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)` */ - def tupled: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] => R = { + + @annotation.unspecialized def tupled: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] => R = { case Tuple13(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) } override def toString() = "" diff --git a/src/library/scala/Function14.scala b/src/library/scala/Function14.scala index 372f1cfafb..82dd409223 100644 --- a/src/library/scala/Function14.scala +++ b/src/library/scala/Function14.scala @@ -21,16 +21,17 @@ trait Function14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)).curried } - /** Creates a tupled version of this function: instead of 14 arguments, * it accepts a single [[scala.Tuple14]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) == f(Tuple14(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)` */ - def tupled: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] => R = { + + @annotation.unspecialized def tupled: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] => R = { case Tuple14(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) } override def toString() = "" diff --git a/src/library/scala/Function15.scala b/src/library/scala/Function15.scala index 47c7309695..be5fbeeca1 100644 --- a/src/library/scala/Function15.scala +++ b/src/library/scala/Function15.scala @@ -21,16 +21,17 @@ trait Function15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)).curried } - /** Creates a tupled version of this function: instead of 15 arguments, * it accepts a single [[scala.Tuple15]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) == f(Tuple15(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)` */ - def tupled: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] => R = { + + @annotation.unspecialized def tupled: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] => R = { case Tuple15(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) } override def toString() = "" diff --git a/src/library/scala/Function16.scala b/src/library/scala/Function16.scala index 8eea42de5b..7a185b369c 100644 --- a/src/library/scala/Function16.scala +++ b/src/library/scala/Function16.scala @@ -21,16 +21,17 @@ trait Function16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)).curried } - /** Creates a tupled version of this function: instead of 16 arguments, * it accepts a single [[scala.Tuple16]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) == f(Tuple16(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)` */ - def tupled: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] => R = { + + @annotation.unspecialized def tupled: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] => R = { case Tuple16(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) } override def toString() = "" diff --git a/src/library/scala/Function17.scala b/src/library/scala/Function17.scala index 2d93af34f2..94e0000802 100644 --- a/src/library/scala/Function17.scala +++ b/src/library/scala/Function17.scala @@ -21,16 +21,17 @@ trait Function17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)).curried } - /** Creates a tupled version of this function: instead of 17 arguments, * it accepts a single [[scala.Tuple17]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) == f(Tuple17(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)` */ - def tupled: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] => R = { + + @annotation.unspecialized def tupled: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] => R = { case Tuple17(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) } override def toString() = "" diff --git a/src/library/scala/Function18.scala b/src/library/scala/Function18.scala index ffca98c443..a3ee6776ba 100644 --- a/src/library/scala/Function18.scala +++ b/src/library/scala/Function18.scala @@ -21,16 +21,17 @@ trait Function18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17)(x18) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)).curried } - /** Creates a tupled version of this function: instead of 18 arguments, * it accepts a single [[scala.Tuple18]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) == f(Tuple18(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)` */ - def tupled: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] => R = { + + @annotation.unspecialized def tupled: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] => R = { case Tuple18(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) } override def toString() = "" diff --git a/src/library/scala/Function19.scala b/src/library/scala/Function19.scala index f661ea7707..038dcbb778 100644 --- a/src/library/scala/Function19.scala +++ b/src/library/scala/Function19.scala @@ -21,16 +21,17 @@ trait Function19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17)(x18)(x19) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)).curried } - /** Creates a tupled version of this function: instead of 19 arguments, * it accepts a single [[scala.Tuple19]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) == f(Tuple19(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)` */ - def tupled: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] => R = { + + @annotation.unspecialized def tupled: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] => R = { case Tuple19(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) } override def toString() = "" diff --git a/src/library/scala/Function2.scala b/src/library/scala/Function2.scala index cacb96ef5d..0794a4048a 100644 --- a/src/library/scala/Function2.scala +++ b/src/library/scala/Function2.scala @@ -11,7 +11,7 @@ package scala /** A function of 2 parameters. - * + * * In the following example, the definition of max is a * shorthand for the anonymous class definition anonfun2: * @@ -23,7 +23,7 @@ package scala * def apply(x: Int, y: Int): Int = if (x < y) y else x * } * assert(max(0, 1) == anonfun2(0, 1)) - * } + * } * }}} * * Note that `Function1` does not define a total function, as might @@ -40,16 +40,17 @@ trait Function2[@specialized(scala.Int, scala.Long, scala.Double) -T1, @speciali /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)` - */ def curried: T1 => T2 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => R = { (x1: T1) => (x2: T2) => apply(x1, x2) } - /** Creates a tupled version of this function: instead of 2 arguments, * it accepts a single [[scala.Tuple2]] argument. * * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)` */ - def tupled: Tuple2[T1, T2] => R = { + + @annotation.unspecialized def tupled: Tuple2[T1, T2] => R = { case Tuple2(x1, x2) => apply(x1, x2) } override def toString() = "" diff --git a/src/library/scala/Function20.scala b/src/library/scala/Function20.scala index e4fb9f280c..727684d6d5 100644 --- a/src/library/scala/Function20.scala +++ b/src/library/scala/Function20.scala @@ -21,16 +21,17 @@ trait Function20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17)(x18)(x19)(x20) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)).curried } - /** Creates a tupled version of this function: instead of 20 arguments, * it accepts a single [[scala.Tuple20]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) == f(Tuple20(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)` */ - def tupled: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] => R = { + + @annotation.unspecialized def tupled: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] => R = { case Tuple20(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) } override def toString() = "" diff --git a/src/library/scala/Function21.scala b/src/library/scala/Function21.scala index 9823386856..2441278be8 100644 --- a/src/library/scala/Function21.scala +++ b/src/library/scala/Function21.scala @@ -21,16 +21,17 @@ trait Function21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17)(x18)(x19)(x20)(x21) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => T21 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => T21 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)).curried } - /** Creates a tupled version of this function: instead of 21 arguments, * it accepts a single [[scala.Tuple21]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) == f(Tuple21(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)` */ - def tupled: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] => R = { + + @annotation.unspecialized def tupled: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] => R = { case Tuple21(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) } override def toString() = "" diff --git a/src/library/scala/Function22.scala b/src/library/scala/Function22.scala index e708f7f49a..1f70b190a6 100644 --- a/src/library/scala/Function22.scala +++ b/src/library/scala/Function22.scala @@ -21,16 +21,17 @@ trait Function22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17)(x18)(x19)(x20)(x21)(x22) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => T21 => T22 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => T21 => T22 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)).curried } - /** Creates a tupled version of this function: instead of 22 arguments, * it accepts a single [[scala.Tuple22]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) == f(Tuple22(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)` */ - def tupled: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] => R = { + + @annotation.unspecialized def tupled: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] => R = { case Tuple22(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) } override def toString() = "" diff --git a/src/library/scala/Function3.scala b/src/library/scala/Function3.scala index 62a997c1b5..bbbde82056 100644 --- a/src/library/scala/Function3.scala +++ b/src/library/scala/Function3.scala @@ -21,16 +21,17 @@ trait Function3[-T1, -T2, -T3, +R] extends AnyRef { self => /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3) == apply(x1, x2, x3)` - */ def curried: T1 => T2 => T3 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => R = { (x1: T1) => (x2: T2) => (x3: T3) => apply(x1, x2, x3) } - /** Creates a tupled version of this function: instead of 3 arguments, * it accepts a single [[scala.Tuple3]] argument. * * @return a function `f` such that `f((x1, x2, x3)) == f(Tuple3(x1, x2, x3)) == apply(x1, x2, x3)` */ - def tupled: Tuple3[T1, T2, T3] => R = { + + @annotation.unspecialized def tupled: Tuple3[T1, T2, T3] => R = { case Tuple3(x1, x2, x3) => apply(x1, x2, x3) } override def toString() = "" diff --git a/src/library/scala/Function4.scala b/src/library/scala/Function4.scala index 86d2faeac8..f100860a97 100644 --- a/src/library/scala/Function4.scala +++ b/src/library/scala/Function4.scala @@ -21,16 +21,17 @@ trait Function4[-T1, -T2, -T3, -T4, +R] extends AnyRef { self => /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4) == apply(x1, x2, x3, x4)` - */ def curried: T1 => T2 => T3 => T4 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => R = { (x1: T1) => (x2: T2) => (x3: T3) => (x4: T4) => apply(x1, x2, x3, x4) } - /** Creates a tupled version of this function: instead of 4 arguments, * it accepts a single [[scala.Tuple4]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4)) == f(Tuple4(x1, x2, x3, x4)) == apply(x1, x2, x3, x4)` */ - def tupled: Tuple4[T1, T2, T3, T4] => R = { + + @annotation.unspecialized def tupled: Tuple4[T1, T2, T3, T4] => R = { case Tuple4(x1, x2, x3, x4) => apply(x1, x2, x3, x4) } override def toString() = "" diff --git a/src/library/scala/Function5.scala b/src/library/scala/Function5.scala index bd9af77f12..cba9b6ce52 100644 --- a/src/library/scala/Function5.scala +++ b/src/library/scala/Function5.scala @@ -21,16 +21,17 @@ trait Function5[-T1, -T2, -T3, -T4, -T5, +R] extends AnyRef { self => /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5) == apply(x1, x2, x3, x4, x5)` - */ def curried: T1 => T2 => T3 => T4 => T5 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5) => self.apply(x1, x2, x3, x4, x5)).curried } - /** Creates a tupled version of this function: instead of 5 arguments, * it accepts a single [[scala.Tuple5]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5)) == f(Tuple5(x1, x2, x3, x4, x5)) == apply(x1, x2, x3, x4, x5)` */ - def tupled: Tuple5[T1, T2, T3, T4, T5] => R = { + + @annotation.unspecialized def tupled: Tuple5[T1, T2, T3, T4, T5] => R = { case Tuple5(x1, x2, x3, x4, x5) => apply(x1, x2, x3, x4, x5) } override def toString() = "" diff --git a/src/library/scala/Function6.scala b/src/library/scala/Function6.scala index 4f601a468c..0b8addf7de 100644 --- a/src/library/scala/Function6.scala +++ b/src/library/scala/Function6.scala @@ -21,16 +21,17 @@ trait Function6[-T1, -T2, -T3, -T4, -T5, -T6, +R] extends AnyRef { self => /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6) == apply(x1, x2, x3, x4, x5, x6)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => self.apply(x1, x2, x3, x4, x5, x6)).curried } - /** Creates a tupled version of this function: instead of 6 arguments, * it accepts a single [[scala.Tuple6]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6)) == f(Tuple6(x1, x2, x3, x4, x5, x6)) == apply(x1, x2, x3, x4, x5, x6)` */ - def tupled: Tuple6[T1, T2, T3, T4, T5, T6] => R = { + + @annotation.unspecialized def tupled: Tuple6[T1, T2, T3, T4, T5, T6] => R = { case Tuple6(x1, x2, x3, x4, x5, x6) => apply(x1, x2, x3, x4, x5, x6) } override def toString() = "" diff --git a/src/library/scala/Function7.scala b/src/library/scala/Function7.scala index 6978b6545d..2098658fa9 100644 --- a/src/library/scala/Function7.scala +++ b/src/library/scala/Function7.scala @@ -21,16 +21,17 @@ trait Function7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends AnyRef { self => /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7) == apply(x1, x2, x3, x4, x5, x6, x7)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => self.apply(x1, x2, x3, x4, x5, x6, x7)).curried } - /** Creates a tupled version of this function: instead of 7 arguments, * it accepts a single [[scala.Tuple7]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7)) == f(Tuple7(x1, x2, x3, x4, x5, x6, x7)) == apply(x1, x2, x3, x4, x5, x6, x7)` */ - def tupled: Tuple7[T1, T2, T3, T4, T5, T6, T7] => R = { + + @annotation.unspecialized def tupled: Tuple7[T1, T2, T3, T4, T5, T6, T7] => R = { case Tuple7(x1, x2, x3, x4, x5, x6, x7) => apply(x1, x2, x3, x4, x5, x6, x7) } override def toString() = "" diff --git a/src/library/scala/Function8.scala b/src/library/scala/Function8.scala index 903551d939..08a480dce5 100644 --- a/src/library/scala/Function8.scala +++ b/src/library/scala/Function8.scala @@ -21,16 +21,17 @@ trait Function8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends AnyRef { sel /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8) == apply(x1, x2, x3, x4, x5, x6, x7, x8)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8)).curried } - /** Creates a tupled version of this function: instead of 8 arguments, * it accepts a single [[scala.Tuple8]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8)) == f(Tuple8(x1, x2, x3, x4, x5, x6, x7, x8)) == apply(x1, x2, x3, x4, x5, x6, x7, x8)` */ - def tupled: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] => R = { + + @annotation.unspecialized def tupled: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] => R = { case Tuple8(x1, x2, x3, x4, x5, x6, x7, x8) => apply(x1, x2, x3, x4, x5, x6, x7, x8) } override def toString() = "" diff --git a/src/library/scala/Function9.scala b/src/library/scala/Function9.scala index 0c273ba929..2e35f7949c 100644 --- a/src/library/scala/Function9.scala +++ b/src/library/scala/Function9.scala @@ -21,16 +21,17 @@ trait Function9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends AnyRef /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9)).curried } - /** Creates a tupled version of this function: instead of 9 arguments, * it accepts a single [[scala.Tuple9]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9)) == f(Tuple9(x1, x2, x3, x4, x5, x6, x7, x8, x9)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9)` */ - def tupled: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] => R = { + + @annotation.unspecialized def tupled: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] => R = { case Tuple9(x1, x2, x3, x4, x5, x6, x7, x8, x9) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9) } override def toString() = "" diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 37ab564c3c..58638f440f 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. @@ -31,6 +31,7 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s def swap: Tuple2[T2,T1] = Tuple2(_2, _1) @deprecated("Use `zipped` instead.", "2.9.0") + @annotation.unspecialized def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => Iterable[El2], cbf1: CBF[Repr1, (El1, El2), To]): To = { @@ -54,16 +55,6 @@ 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 cd5ee23757..0d5399308b 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,17 +53,6 @@ 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/library/scala/annotation/unspecialized.scala b/src/library/scala/annotation/unspecialized.scala new file mode 100644 index 0000000000..28d9aa169c --- /dev/null +++ b/src/library/scala/annotation/unspecialized.scala @@ -0,0 +1,17 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.annotation + +/** A method annotation which suppresses the creation of + * additional specialized forms based on enclosing specialized + * type parameters. + * + * @since 2.10 + */ +class unspecialized extends annotation.StaticAnnotation diff --git a/src/library/scala/runtime/AbstractPartialFunction.scala b/src/library/scala/runtime/AbstractPartialFunction.scala index 2e435d8a7e..f499350ce9 100644 --- a/src/library/scala/runtime/AbstractPartialFunction.scala +++ b/src/library/scala/runtime/AbstractPartialFunction.scala @@ -36,7 +36,7 @@ abstract class AbstractPartialFunction[@specialized(scala.Int, scala.Long, scala // let's not make it final so as not to confuse anyone /*final*/ def apply(x: T1): R = applyOrElse(x, PartialFunction.empty) - override final def andThen[C](k: R => C) : PartialFunction[T1, C] = + @annotation.unspecialized override final def andThen[C](k: R => C) : PartialFunction[T1, C] = new AbstractPartialFunction[T1, C] { def isDefinedAt(x: T1): Boolean = self.isDefinedAt(x) override def applyOrElse[A1 <: T1, C1 >: C](x: A1, default: A1 => C1): C1 = @@ -61,8 +61,8 @@ abstract class AbstractPartialFunction[@specialized(scala.Int, scala.Long, scala */ abstract class AbstractTotalFunction[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, scala.AnyRef) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double, scala.AnyRef) +R] extends Function1[T1, R] with PartialFunction[T1, R] { final def isDefinedAt(x: T1): Boolean = true - override final def applyOrElse[A1 <: T1, B1 >: R](x: A1, default: A1 => B1): B1 = apply(x) - override final def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = this + @annotation.unspecialized override final def applyOrElse[A1 <: T1, B1 >: R](x: A1, default: A1 => B1): B1 = apply(x) + @annotation.unspecialized override final def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = this //TODO: check generated code for PF literal here - override final def andThen[C](k: R => C): PartialFunction[T1, C] = { case x => k(apply(x)) } + @annotation.unspecialized override final def andThen[C](k: R => C): PartialFunction[T1, C] = { case x => k(apply(x)) } } -- cgit v1.2.3 From 774cd4f87b1ef1ba0b0850f1934fa1539b0e2bce Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 28 Apr 2012 14:13:42 -0700 Subject: Removed all the imports of the bridge annotation. Now that nothing uses it. --- src/library/scala/annotation/bridge.scala | 1 + src/library/scala/collection/GenSeqLike.scala | 1 - src/library/scala/collection/GenSetLike.scala | 1 - src/library/scala/collection/IterableLike.scala | 1 - src/library/scala/collection/SeqLike.scala | 1 - src/library/scala/collection/SeqViewLike.scala | 1 - src/library/scala/collection/Traversable.scala | 1 - src/library/scala/collection/generic/GenSeqFactory.scala | 1 - src/library/scala/collection/generic/GenericSeqCompanion.scala | 1 - src/library/scala/collection/generic/MapFactory.scala | 1 - src/library/scala/collection/generic/SetFactory.scala | 1 - src/library/scala/collection/generic/Subtractable.scala | 1 - src/library/scala/collection/generic/TraversableFactory.scala | 1 - src/library/scala/collection/immutable/MapLike.scala | 1 - src/library/scala/collection/immutable/Range.scala | 1 - src/library/scala/collection/immutable/SortedMap.scala | 1 - src/library/scala/collection/immutable/TreeMap.scala | 1 - src/library/scala/collection/mutable/PriorityQueue.scala | 1 - src/library/scala/package.scala | 1 - src/library/scala/runtime/RichInt.scala | 1 - 20 files changed, 1 insertion(+), 19 deletions(-) (limited to 'src') diff --git a/src/library/scala/annotation/bridge.scala b/src/library/scala/annotation/bridge.scala index 690370854e..a56129fb96 100644 --- a/src/library/scala/annotation/bridge.scala +++ b/src/library/scala/annotation/bridge.scala @@ -10,4 +10,5 @@ package scala.annotation /** If this annotation is present on a method, it will be treated as a bridge method. */ +@deprecated("Reconsider whether using this annotation will accomplish anything", "2.10.0") private[scala] class bridge extends annotation.StaticAnnotation diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala index 646fe09855..fd7892c9f9 100644 --- a/src/library/scala/collection/GenSeqLike.scala +++ b/src/library/scala/collection/GenSeqLike.scala @@ -9,7 +9,6 @@ package scala.collection import generic._ -import annotation.bridge /** A template trait for all sequences which may be traversed * in parallel. diff --git a/src/library/scala/collection/GenSetLike.scala b/src/library/scala/collection/GenSetLike.scala index a576014445..219374abc6 100644 --- a/src/library/scala/collection/GenSetLike.scala +++ b/src/library/scala/collection/GenSetLike.scala @@ -8,7 +8,6 @@ package scala.collection -import annotation.bridge /** A template trait for sets which may possibly * have their operations implemented in parallel. diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala index 6a000abd54..f4397f2167 100644 --- a/src/library/scala/collection/IterableLike.scala +++ b/src/library/scala/collection/IterableLike.scala @@ -12,7 +12,6 @@ package scala.collection import generic._ import immutable.{ List, Stream } import annotation.unchecked.uncheckedVariance -import annotation.bridge /** A template trait for iterable collections of type `Iterable[A]`. * $iterableInfo diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index 5e37566008..a9535adc23 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -12,7 +12,6 @@ import mutable.{ ListBuffer, ArraySeq } import immutable.{ List, Range } import generic._ import parallel.ParSeq -import annotation.bridge import scala.math.Ordering /** A template trait for sequences of type `Seq[A]` diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala index 9b697a164c..f64045c9f6 100644 --- a/src/library/scala/collection/SeqViewLike.scala +++ b/src/library/scala/collection/SeqViewLike.scala @@ -11,7 +11,6 @@ package scala.collection import generic._ import Seq.fill import TraversableView.NoBuilder -import annotation.bridge /** A template trait for non-strict views of sequences. * $seqViewInfo diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala index e75000297f..cd85ea4d2d 100644 --- a/src/library/scala/collection/Traversable.scala +++ b/src/library/scala/collection/Traversable.scala @@ -13,7 +13,6 @@ package scala.collection import generic._ import mutable.{Builder, Buffer, ArrayBuffer, ListBuffer} import scala.util.control.Breaks -import annotation.bridge /** A trait for traversable collections. * All operations are guaranteed to be performed in a single-threaded manner. diff --git a/src/library/scala/collection/generic/GenSeqFactory.scala b/src/library/scala/collection/generic/GenSeqFactory.scala index 3664fe1b4f..19eeba9b1d 100644 --- a/src/library/scala/collection/generic/GenSeqFactory.scala +++ b/src/library/scala/collection/generic/GenSeqFactory.scala @@ -11,7 +11,6 @@ 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/GenericSeqCompanion.scala b/src/library/scala/collection/generic/GenericSeqCompanion.scala index 79cc2f13d4..90063c1ca2 100644 --- a/src/library/scala/collection/generic/GenericSeqCompanion.scala +++ b/src/library/scala/collection/generic/GenericSeqCompanion.scala @@ -10,7 +10,6 @@ package scala.collection package generic -import annotation.bridge import language.higherKinds trait GenericSeqCompanion[CC[X] <: Traversable[X]] diff --git a/src/library/scala/collection/generic/MapFactory.scala b/src/library/scala/collection/generic/MapFactory.scala index 5a6d825aa8..ce44ae9bf4 100644 --- a/src/library/scala/collection/generic/MapFactory.scala +++ b/src/library/scala/collection/generic/MapFactory.scala @@ -11,7 +11,6 @@ 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/SetFactory.scala b/src/library/scala/collection/generic/SetFactory.scala index 7443bfbf6a..646e99dd1e 100644 --- a/src/library/scala/collection/generic/SetFactory.scala +++ b/src/library/scala/collection/generic/SetFactory.scala @@ -12,7 +12,6 @@ package scala.collection package generic import mutable.Builder -import annotation.bridge import language.higherKinds abstract class SetFactory[CC[X] <: Set[X] with SetLike[X, CC[X]]] diff --git a/src/library/scala/collection/generic/Subtractable.scala b/src/library/scala/collection/generic/Subtractable.scala index ef4f466119..cda71c0291 100644 --- a/src/library/scala/collection/generic/Subtractable.scala +++ b/src/library/scala/collection/generic/Subtractable.scala @@ -10,7 +10,6 @@ package scala.collection package generic -import annotation.bridge /** This trait represents collection-like objects that can be reduced * using a '+' operator. It defines variants of `-` and `--` diff --git a/src/library/scala/collection/generic/TraversableFactory.scala b/src/library/scala/collection/generic/TraversableFactory.scala index e99c77c4f1..254a6a224f 100644 --- a/src/library/scala/collection/generic/TraversableFactory.scala +++ b/src/library/scala/collection/generic/TraversableFactory.scala @@ -10,7 +10,6 @@ package scala.collection package generic -import annotation.bridge import language.higherKinds /** A template for companion objects of `Traversable` and subclasses thereof. diff --git a/src/library/scala/collection/immutable/MapLike.scala b/src/library/scala/collection/immutable/MapLike.scala index 090c7f3043..84c87b4eae 100644 --- a/src/library/scala/collection/immutable/MapLike.scala +++ b/src/library/scala/collection/immutable/MapLike.scala @@ -11,7 +11,6 @@ package immutable import generic._ import parallel.immutable.ParMap -import annotation.bridge /** * A generic template for immutable maps from keys of type `A` diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 07c8df57ba..5698d53b06 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -10,7 +10,6 @@ package scala.collection.immutable import scala.collection.parallel.immutable.ParRange -import annotation.bridge /** The `Range` class represents integer values in range * ''[start;end)'' with non-zero step value `step`. diff --git a/src/library/scala/collection/immutable/SortedMap.scala b/src/library/scala/collection/immutable/SortedMap.scala index 05248e5805..526f7a1ffe 100644 --- a/src/library/scala/collection/immutable/SortedMap.scala +++ b/src/library/scala/collection/immutable/SortedMap.scala @@ -14,7 +14,6 @@ package immutable import generic._ import mutable.Builder import annotation.unchecked.uncheckedVariance -import annotation.bridge /** A map whose keys are sorted. * diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala index 5c85621b0f..4c1a5f2e03 100644 --- a/src/library/scala/collection/immutable/TreeMap.scala +++ b/src/library/scala/collection/immutable/TreeMap.scala @@ -14,7 +14,6 @@ package immutable import generic._ import immutable.{RedBlackTree => RB} import mutable.Builder -import annotation.bridge /** $factoryInfo * @define Coll immutable.TreeMap diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index 324af77dd4..12dee45bae 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -12,7 +12,6 @@ package scala.collection package mutable import generic._ -import annotation.bridge /** This class implements priority queues using a heap. * To prioritize elements of type A there must be an implicit diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index 064ccd7735..e3890d7a9d 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -6,7 +6,6 @@ ** |/ ** \* */ -import annotation.bridge /** * Core Scala types. They are always available without an explicit import. diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala index fcacb9c82a..d03968212f 100644 --- a/src/library/scala/runtime/RichInt.scala +++ b/src/library/scala/runtime/RichInt.scala @@ -9,7 +9,6 @@ package scala.runtime import scala.collection.immutable.Range -import annotation.bridge // Note that this does not implement IntegralProxy[Int] so that it can return // the Int-specific Range class from until/to. -- cgit v1.2.3 From e6d5d22d280909dacf635a0a2398158a1b1a6ae1 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 28 Apr 2012 22:37:56 -0700 Subject: Eliminate useless type parameter. --- src/compiler/scala/reflect/internal/Symbols.scala | 2 +- src/library/scala/reflect/DummyMirror.scala | 2 +- src/library/scala/reflect/api/Symbols.scala | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 31f068494c..37caa06fe9 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -2053,7 +2053,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this - @inline final def orElse[T](alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt + @inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt // ------ toString ------------------------------------------------------------------- diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala index f5b757fdba..422598caef 100644 --- a/src/library/scala/reflect/DummyMirror.scala +++ b/src/library/scala/reflect/DummyMirror.scala @@ -443,7 +443,7 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { def name: Name = notSupported() def fullName: String = notSupported() def id: Int = notSupported() - def orElse[T](alt: => Symbol): Symbol = notSupported() + def orElse(alt: => Symbol): Symbol = notSupported() def filter(cond: Symbol => Boolean): Symbol = notSupported() def suchThat(cond: Symbol => Boolean): Symbol = notSupported() def privateWithin: Symbol = notSupported() diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index dbd264c0ab..32faee2512 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -146,7 +146,7 @@ trait Symbols { self: Universe => /** ... */ - def orElse[T](alt: => Symbol): Symbol + def orElse(alt: => Symbol): Symbol /** ... */ -- cgit v1.2.3 From 94c63f5da548996535cad43142758c9405118828 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 29 Apr 2012 17:16:48 -0700 Subject: Fighting bitrot with typing. if (false && settings.debug.value) { ... } Date: 7 years ago *** empty log message *** That's way past the sell-by date for 'if (false && condition)'. --- src/compiler/scala/reflect/internal/Symbols.scala | 11 ++- .../reflect/runtime/SynchronizedSymbols.scala | 2 +- .../scala/tools/nsc/typechecker/Contexts.scala | 11 +++ .../scala/tools/nsc/typechecker/Modes.scala | 2 +- .../scala/tools/nsc/typechecker/Namers.scala | 49 +++------- .../tools/nsc/typechecker/NamesDefaults.scala | 11 +-- .../tools/nsc/typechecker/PatMatVirtualiser.scala | 11 ++- .../scala/tools/nsc/typechecker/Typers.scala | 103 ++++++++------------- 8 files changed, 81 insertions(+), 119 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 37caa06fe9..c2ef633d58 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -1425,7 +1425,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Reset symbol to initial state */ - def reset(completer: Type) { + def reset(completer: Type): this.type = { resetFlags() infos = null _validTo = NoPeriod @@ -2054,6 +2054,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this @inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt + @inline final def andAlso(f: Symbol => Unit): Symbol = if (this eq NoSymbol) NoSymbol else { f(this) ; this } // ------ toString ------------------------------------------------------------------- @@ -2636,10 +2637,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => info.baseTypeIndex(that) >= 0 ) - override def reset(completer: Type) { + override def reset(completer: Type): this.type = { super.reset(completer) tpePeriod = NoPeriod tyconRunId = NoRunId + this } /*** example: @@ -2822,9 +2824,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => else super.sourceFile override def sourceFile_=(f: AbstractFileType) { source = f } - override def reset(completer: Type) { + override def reset(completer: Type): this.type = { super.reset(completer) thissym = this + this } /** the type this.type in this class */ @@ -3022,7 +3025,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def ownerChain: List[Symbol] = List() override def ownersIterator: Iterator[Symbol] = Iterator.empty override def alternatives: List[Symbol] = List() - override def reset(completer: Type) {} + override def reset(completer: Type): this.type = this override def info: Type = NoType override def existentialBound: Type = NoType override def rawInfo: Type = NoType diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala index 4048e94d0f..8378f1a892 100644 --- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala @@ -46,7 +46,7 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => override def typeParams: List[Symbol] = synchronized { super.typeParams } - override def reset(completer: Type) = synchronized { super.reset(completer) } + override def reset(completer: Type): this.type = synchronized { super.reset(completer) } override def infosString: String = synchronized { super.infosString } diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index e2d4efab83..4584ba032d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -405,6 +405,17 @@ trait Contexts { self: Analyzer => case _ => outer.isLocal() } + /** Fast path for some slow checks (ambiguous assignment in Refchecks, and + * existence of __match for MatchTranslation in virtpatmat.) This logic probably + * needs improvement. + */ + def isNameInScope(name: Name) = ( + enclosingContextChain exists (ctx => + (ctx.scope.lookupEntry(name) != null) + || (ctx.owner.rawInfo.member(name) != NoSymbol) + ) + ) + // nextOuter determines which context is searched next for implicits // (after `this`, which contributes `newImplicits` below.) In // most cases, it is simply the outer context: if we're owned by diff --git a/src/compiler/scala/tools/nsc/typechecker/Modes.scala b/src/compiler/scala/tools/nsc/typechecker/Modes.scala index 48068b58d4..3eff5ef024 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Modes.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Modes.scala @@ -105,7 +105,7 @@ trait Modes { final def inFunMode(mode: Int) = (mode & FUNmode) != 0 final def inPolyMode(mode: Int) = (mode & POLYmode) != 0 final def inPatternMode(mode: Int) = (mode & PATTERNmode) != 0 - + final def inExprModeOr(mode: Int, others: Int) = (mode & (EXPRmode | others)) != 0 final def inExprModeButNot(mode: Int, prohibited: Int) = (mode & (EXPRmode | prohibited)) == EXPRmode diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index ffd00751e0..45f7d7e618 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -139,16 +139,9 @@ trait Namers extends MethodSynthesis { || vd.symbol.isLazy ) - def setPrivateWithin[Sym <: Symbol](tree: Tree, sym: Sym, mods: Modifiers): Sym = + def setPrivateWithin[T <: Symbol](tree: Tree, sym: T, mods: Modifiers): T = if (sym.isPrivateLocal || !mods.hasAccessBoundary) sym - else sym setPrivateWithin ( - typer.qualifyingClass(tree, mods.privateWithin, true) match { - case None => - NoSymbol - case Some(sym) => - sym - } - ) + else sym setPrivateWithin typer.qualifyingClass(tree, mods.privateWithin, packageOK = true) def setPrivateWithin(tree: MemberDef, sym: Symbol): Symbol = setPrivateWithin(tree, sym, tree.mods) @@ -160,24 +153,14 @@ trait Namers extends MethodSynthesis { def moduleClassFlags(moduleFlags: Long) = (moduleFlags & ModuleToClassFlags) | inConstructorFlag - private def resetKeepingFlags(sym: Symbol, keeping: Long): Symbol = { - val keep = sym.flags & keeping - sym reset NoType - sym setFlag keep - } - def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = { debuglog("[overwrite] " + sym) - resetKeepingFlags(sym, LOCKED) - sym setFlag flags - sym setPos pos - - if (sym.isModule && sym.moduleClass != NoSymbol) - updatePosFlags(sym.moduleClass, pos, moduleClassFlags(flags)) + val newFlags = (sym.flags & LOCKED) | flags + sym reset NoType setFlag newFlags setPos pos + sym.moduleClass andAlso (updatePosFlags(_, pos, moduleClassFlags(flags))) if (sym.owner.isPackageClass) { - val companion = companionSymbolOf(sym, context) - if (companion != NoSymbol) { + companionSymbolOf(sym, context) andAlso { companion => val assignNoType = companion.rawInfo match { case _: SymLoader => true case tp => tp.isComplete && (runId(sym.validTo) != currentRunId) @@ -400,9 +383,7 @@ trait Namers extends MethodSynthesis { if (m.isModule && !m.isPackage && inCurrentScope(m) && (currentRun.canRedefine(m) || m.isSynthetic)) { updatePosFlags(m, tree.pos, moduleFlags) setPrivateWithin(tree, m) - if (m.moduleClass != NoSymbol) - setPrivateWithin(tree, m.moduleClass) - + m.moduleClass andAlso (setPrivateWithin(tree, _)) context.unit.synthetics -= m tree.symbol = m } @@ -475,8 +456,7 @@ trait Namers extends MethodSynthesis { val defSym = context.prefix.member(to) filter ( sym => sym.exists && context.isAccessible(sym, context.prefix, false)) - if (defSym != NoSymbol) - typer.permanentlyHiddenWarning(pos, to0, defSym) + defSym andAlso (typer.permanentlyHiddenWarning(pos, to0, _)) } } if (!tree.symbol.isSynthetic && expr.symbol != null && !expr.symbol.isInterpreterWrapper) { @@ -669,10 +649,9 @@ trait Namers extends MethodSynthesis { protected def enterExistingSym(sym: Symbol): Context = { if (forInteractive && sym != null && sym.owner.isTerm) { enterIfNotThere(sym) - if (sym.isLazy) { - val acc = sym.lazyAccessor - if (acc != NoSymbol) enterIfNotThere(acc) - } + if (sym.isLazy) + sym.lazyAccessor andAlso enterIfNotThere + defaultParametersOfMethod(sym) foreach { symRef => enterIfNotThere(symRef()) } } this.context @@ -1547,13 +1526,13 @@ trait Namers extends MethodSynthesis { * call this method? */ def companionSymbolOf(original: Symbol, ctx: Context): Symbol = { - try original.companionSymbol match { - case NoSymbol => + try { + original.companionSymbol orElse { ctx.lookup(original.name.companionName, original.owner).suchThat(sym => (original.isTerm || sym.hasModuleFlag) && (sym isCoDefinedWith original) ) - case sym => sym + } } catch { case e: InvalidCompanions => diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 3d9fc67389..898a9fee9f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -444,21 +444,12 @@ trait NamesDefaults { self: Analyzer => } } - /** Fast path for ambiguous assignment check. - */ - private def isNameInScope(context: Context, name: Name) = ( - context.enclosingContextChain exists (ctx => - (ctx.scope.lookupEntry(name) != null) - || (ctx.owner.rawInfo.member(name) != NoSymbol) - ) - ) - /** A full type check is very expensive; let's make sure there's a name * somewhere which could potentially be ambiguous before we go that route. */ private def isAmbiguousAssignment(typer: Typer, param: Symbol, arg: Tree) = { import typer.context - isNameInScope(context, param.name) && { + (context isNameInScope param.name) && { // for named arguments, check whether the assignment expression would // typecheck. if it does, report an ambiguous error. val paramtpe = param.tpe.cloneInfo(param) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index e5dc8e9ca9..e5b5746e8d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -55,10 +55,15 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer => def apply(typer: Typer): MatchTranslation with CodegenCore = { import typer._ // typing `_match` to decide which MatchTranslator to create adds 4% to quick.comp.timer - newTyper(context.makeImplicit(reportAmbiguousErrors = false)).silent(_.typed(Ident(vpmName._match), EXPRmode, WildcardType), reportAmbiguousErrors = false) match { - case SilentResultValue(ms) => new PureMatchTranslator(typer, ms) - case _ => new OptimizingMatchTranslator(typer) + val matchStrategy: Tree = ( + if (!context.isNameInScope(vpmName._match)) null // fast path, avoiding the next line if there's no __match to be seen + else newTyper(context.makeImplicit(reportAmbiguousErrors = false)).silent(_.typed(Ident(vpmName._match), EXPRmode, WildcardType), reportAmbiguousErrors = false) match { + case SilentResultValue(ms) => ms + case _ => null } + ) + if (matchStrategy eq null) new OptimizingMatchTranslator(typer) + else new PureMatchTranslator(typer, matchStrategy) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 6234c05258..89c30590c9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -458,13 +458,10 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser * of a this or super with prefix qual. * packageOk is equal false when qualifying class symbol */ - def qualifyingClass(tree: Tree, qual: Name, packageOK: Boolean = false): Option[Symbol] = + def qualifyingClass(tree: Tree, qual: Name, packageOK: Boolean) = context.enclClass.owner.ownerChain.find(o => qual.isEmpty || o.isClass && o.name == qual) match { - case Some(c) if packageOK || !c.isPackageClass => - Some(c) - case _ => - QualifyingClassError(tree, qual) - None + case Some(c) if packageOK || !c.isPackageClass => c + case _ => QualifyingClassError(tree, qual) ; NoSymbol } /** The typer for an expression, depending on where we are. If we are before a superclass @@ -4133,7 +4130,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser } def convertToAssignment(fun: Tree, qual: Tree, name: Name, args: List[Tree]): Tree = { - val prefix = name.subName(0, name.length - nme.EQL.length) + val prefix = name stripSuffix nme.EQL def mkAssign(vble: Tree): Tree = Assign( vble, @@ -4142,21 +4139,18 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser ) setPos tree.pos def mkUpdate(table: Tree, indices: List[Tree]) = { - gen.evalOnceAll(table :: indices, context.owner, context.unit) { ts => - val tab = ts.head - val is = ts.tail - Apply( - Select(tab(), nme.update) setPos table.pos, - ((is map (i => i())) ::: List( - Apply( - Select( - Apply( - Select(tab(), nme.apply) setPos table.pos, - is map (i => i())) setPos qual.pos, - prefix) setPos fun.pos, - args) setPos tree.pos) - ) - ) setPos tree.pos + gen.evalOnceAll(table :: indices, context.owner, context.unit) { + case tab :: is => + def mkCall(name: Name, extraArgs: Tree*) = ( + Apply( + Select(tab(), name) setPos table.pos, + is.map(i => i()) ++ extraArgs + ) setPos tree.pos + ) + mkCall( + nme.update, + Apply(Select(mkCall(nme.apply), prefix) setPos fun.pos, args) setPos tree.pos + ) } } @@ -4223,15 +4217,11 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype) } - def typedThis(qual: Name) = { - val qualifyingClassSym = if (tree.symbol != NoSymbol) Some(tree.symbol) else qualifyingClass(tree, qual) - qualifyingClassSym match { - case Some(clazz) => - tree setSymbol clazz setType clazz.thisType.underlying - if (isStableContext(tree, mode, pt)) tree setType clazz.thisType - tree - case None => tree - } + def typedThis(qual: Name) = tree.symbol orElse qualifyingClass(tree, qual, packageOK = false) match { + case NoSymbol => tree + case clazz => + tree setSymbol clazz setType clazz.thisType.underlying + if (isStableContext(tree, mode, pt)) tree setType clazz.thisType else tree } /** Attribute a selection where tree is qual.name. @@ -4242,34 +4232,19 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser * @return ... */ def typedSelect(qual: Tree, name: Name): Tree = { - val sym = - if (tree.symbol != NoSymbol) { - if (phase.erasedTypes && qual.isInstanceOf[Super]) - qual.tpe = tree.symbol.owner.tpe - if (false && settings.debug.value) { // todo: replace by settings.check.value? - val alts = qual.tpe.member(tree.symbol.name).alternatives - if (!(alts exists (alt => - alt == tree.symbol || alt.isTerm && (alt.tpe matches tree.symbol.tpe)))) - assert(false, "symbol "+tree.symbol+tree.symbol.locationString+" not in "+alts+" of "+qual.tpe+ - "\n members = "+qual.tpe.members+ - "\n type history = "+qual.tpe.termSymbol.infosString+ - "\n phase = "+phase) - } - tree.symbol - } else { - member(qual, name) + val sym = tree.symbol orElse member(qual, name) orElse { + // symbol not found? --> try to convert implicitly to a type that does have the required + // member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an + // xml member to StringContext, which in turn has an unapply[Seq] method) + if (name != nme.CONSTRUCTOR && inExprModeOr(mode, PATTERNmode)) { + val qual1 = adaptToMemberWithArgs(tree, qual, name, mode, true, true) + if (qual1 ne qual) + return typed(treeCopy.Select(tree, qual1, name), mode, pt) } - - // 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) - - if (qual1 ne qual) - return typed(treeCopy.Select(tree, qual1, name), mode, pt) + NoSymbol } + if (phase.erasedTypes && qual.isInstanceOf[Super] && tree.symbol != NoSymbol) + qual.tpe = tree.symbol.owner.tpe if (!reallyExists(sym)) { if (context.owner.enclosingTopLevelClass.isJavaDefined && name.isTypeName) { @@ -4284,14 +4259,12 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser case _ => } - if (settings.debug.value) { - log( - "qual = "+qual+":"+qual.tpe+ - "\nSymbol="+qual.tpe.termSymbol+"\nsymbol-info = "+qual.tpe.termSymbol.info+ - "\nscope-id = "+qual.tpe.termSymbol.info.decls.hashCode()+"\nmembers = "+qual.tpe.members+ - "\nname = "+name+"\nfound = "+sym+"\nowner = "+context.enclClass.owner - ) - } + debuglog( + "qual = "+qual+":"+qual.tpe+ + "\nSymbol="+qual.tpe.termSymbol+"\nsymbol-info = "+qual.tpe.termSymbol.info+ + "\nscope-id = "+qual.tpe.termSymbol.info.decls.hashCode()+"\nmembers = "+qual.tpe.members+ + "\nname = "+name+"\nfound = "+sym+"\nowner = "+context.enclClass.owner + ) def makeInteractiveErrorTree = { val tree1 = tree match { -- cgit v1.2.3 From 416abb70256267ccb80b7f5b6d205c9f384a14e0 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Mon, 30 Apr 2012 11:46:33 +0200 Subject: Fixed `Setting.enabling` to properly disable dependent settings when the original setting is set to `false`. This can be witnessed in the IDE, when explicitly setting the `-optimize` flag to false leads to setting all the dependent flags to true (`-Yinline`, `-Ydce`, `-Ycloselim`). --- src/compiler/scala/tools/nsc/settings/ScalaSettings.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 91e31cae97..0a9d25af7e 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -41,11 +41,11 @@ trait ScalaSettings extends AbsScalaSettings protected def optimiseSettings = List[BooleanSetting](inline, inlineHandlers, Xcloselim, Xdce) /** Internal use - syntax enhancements. */ - private class EnableSettings[T <: Setting](val s: T) { - def enabling(toEnable: List[BooleanSetting]): s.type = s withPostSetHook (_ => toEnable foreach (_.value = true)) + private class EnableSettings[T <: BooleanSetting](val s: T) { + def enabling(toEnable: List[BooleanSetting]): s.type = s withPostSetHook (_ => toEnable foreach (_.value = s.value)) def andThen(f: s.T => Unit): s.type = s withPostSetHook (setting => f(setting.value)) } - private implicit def installEnableSettings[T <: Setting](s: T) = new EnableSettings(s) + private implicit def installEnableSettings[T <: BooleanSetting](s: T) = new EnableSettings(s) /** Disable a setting */ def disable(s: Setting) = allSettings -= s -- cgit v1.2.3 From b72f52bbd59602ec9e09900381d5ff19752fa961 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Mon, 30 Apr 2012 11:53:41 +0200 Subject: Presentation Compiler tests for visibility of members. Removed some unneeded indirection in the testing framework. --- .../nsc/interactive/tests/core/CoreTestDefs.scala | 20 +- .../tests/core/PresentationCompilerTestDef.scala | 4 - test/files/presentation/callcc-interpreter.check | 120 +++++------ test/files/presentation/ide-bug-1000349.check | 68 +++--- test/files/presentation/ide-bug-1000475.check | 192 ++++++++--------- test/files/presentation/ide-bug-1000531.check | 238 ++++++++++----------- test/files/presentation/implicit-member.check | 70 +++--- test/files/presentation/ping-pong.check | 142 ++++++------ test/files/presentation/visibility.check | 221 +++++++++++++++++++ test/files/presentation/visibility/Test.scala | 5 + .../presentation/visibility/src/Completions.scala | 40 ++++ 11 files changed, 687 insertions(+), 433 deletions(-) create mode 100644 test/files/presentation/visibility.check create mode 100644 test/files/presentation/visibility/Test.scala create mode 100644 test/files/presentation/visibility/src/Completions.scala (limited to 'src') 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 9646ee1cf0..d6102734ab 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala @@ -17,15 +17,11 @@ private[tests] trait CoreTestDefs extends PresentationCompilerTestDef with AskCompletionAt { - object MemberPrinter { - def apply(member: compiler.Member): String = - "`" + (member.sym.toString() + member.tpe.toString()).trim() + "`" - } - - protected val marker = CompletionMarker + def memberPrinter(member: compiler.Member): String = + "[accessible: %5s] ".format(member.accessible) + "`" + (member.sym.toString() + member.tpe.toString()).trim() + "`" override def runTest() { - askAllSources(marker) { pos => + askAllSources(CompletionMarker) { pos => askCompletionAt(pos) } { (pos, members) => withResponseDelimiter { @@ -35,7 +31,7 @@ private[tests] trait CoreTestDefs reporter.println("retrieved %d members".format(members.size)) compiler ask { () => val filtered = members.filterNot(member => member.sym.name.toString == "getClass" || member.sym.isConstructor) - reporter.println(filtered.map(MemberPrinter(_)).sortBy(_.toString()).mkString("\n")) + reporter.println(filtered.map(memberPrinter).sortBy(_.toString()).mkString("\n")) } } } @@ -48,10 +44,8 @@ private[tests] trait CoreTestDefs extends PresentationCompilerTestDef with AskTypeAt { - protected val marker = TypeMarker - override def runTest() { - askAllSources(marker) { pos => + askAllSources(TypeMarker) { pos => askTypeAt(pos) } { (pos, tree) => withResponseDelimiter { @@ -69,10 +63,8 @@ private[tests] trait CoreTestDefs with AskTypeAt with AskCompletionAt { - protected val marker = HyperlinkMarker - override def runTest() { - askAllSources(marker) { pos => + askAllSources(HyperlinkMarker) { pos => askTypeAt(pos)(NullReporter) } { (pos, tree) => if(tree.symbol == compiler.NoSymbol) { diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala index 390363eca8..8b8be697cc 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala @@ -5,10 +5,6 @@ import scala.tools.nsc.util.Position trait PresentationCompilerTestDef { - def compiler: Global - - protected val marker: TestMarker - private[tests] def runTest(): Unit protected def withResponseDelimiter(block: => Unit)(implicit reporter: Reporter) { diff --git a/test/files/presentation/callcc-interpreter.check b/test/files/presentation/callcc-interpreter.check index c50e171b4e..68ac904b18 100644 --- a/test/files/presentation/callcc-interpreter.check +++ b/test/files/presentation/callcc-interpreter.check @@ -4,66 +4,66 @@ askTypeCompletion at CallccInterpreter.scala(51,38) ================================================================================ [response] aksTypeCompletion at (51,38) retrieved 64 members -`class AddcallccInterpreter.Add` -`class AppcallccInterpreter.App` -`class CcccallccInterpreter.Ccc` -`class ConcallccInterpreter.Con` -`class FuncallccInterpreter.Fun` -`class LamcallccInterpreter.Lam` -`class McallccInterpreter.M` -`class NumcallccInterpreter.Num` -`class VarcallccInterpreter.Var` -`method !=(x$1: Any)Boolean` -`method !=(x$1: AnyRef)Boolean` -`method ##()Int` -`method +(other: String)String` -`method ->[B](y: B)(callccInterpreter.type, B)` -`method ==(x$1: Any)Boolean` -`method ==(x$1: AnyRef)Boolean` -`method add(a: callccInterpreter.Value, b: callccInterpreter.Value)callccInterpreter.M[_ >: callccInterpreter.Num with callccInterpreter.Wrong.type <: Product with Serializable with callccInterpreter.Value]` -`method apply(a: callccInterpreter.Value, b: callccInterpreter.Value)callccInterpreter.M[callccInterpreter.Value]` -`method asInstanceOf[T0]=> T0` -`method callCC[A](h: (A => callccInterpreter.M[A]) => callccInterpreter.M[A])callccInterpreter.M[A]` -`method clone()Object` -`method ensuring(cond: Boolean)callccInterpreter.type` -`method ensuring(cond: Boolean, msg: => Any)callccInterpreter.type` -`method ensuring(cond: callccInterpreter.type => Boolean)callccInterpreter.type` -`method ensuring(cond: callccInterpreter.type => Boolean, msg: => Any)callccInterpreter.type` -`method eq(x$1: AnyRef)Boolean` -`method equals(x$1: Any)Boolean` -`method finalize()Unit` -`method formatted(fmtstr: String)String` -`method hashCode()Int` -`method id[A]=> A => A` -`method interp(t: callccInterpreter.Term, e: callccInterpreter.Environment)callccInterpreter.M[callccInterpreter.Value]` -`method isInstanceOf[T0]=> Boolean` -`method lookup(x: callccInterpreter.Name, e: callccInterpreter.Environment)callccInterpreter.M[callccInterpreter.Value]` -`method main(args: Array[String])Unit` -`method ne(x$1: AnyRef)Boolean` -`method notify()Unit` -`method notifyAll()Unit` -`method showM(m: callccInterpreter.M[callccInterpreter.Value])String` -`method synchronized[T0](x$1: T0)T0` -`method test(t: callccInterpreter.Term)String` -`method toString()String` -`method unitM[A](a: A)callccInterpreter.M[A]` -`method wait()Unit` -`method wait(x$1: Long)Unit` -`method wait(x$1: Long, x$2: Int)Unit` -`method x=> callccInterpreter.type` -`method →[B](y: B)(callccInterpreter.type, B)` -`object WrongcallccInterpreter.Wrong.type` -`trait TermcallccInterpreter.Term` -`trait ValuecallccInterpreter.Value` -`type AnswercallccInterpreter.Answer` -`type EnvironmentcallccInterpreter.Environment` -`type NamecallccInterpreter.Name` -`value __leftOfArrowcallccInterpreter.type` -`value __resultOfEnsuringcallccInterpreter.type` -`value selfAny` -`value term0callccInterpreter.App` -`value term1callccInterpreter.App` -`value term2callccInterpreter.Add` +[accessible: true] `class AddcallccInterpreter.Add` +[accessible: true] `class AppcallccInterpreter.App` +[accessible: true] `class CcccallccInterpreter.Ccc` +[accessible: true] `class ConcallccInterpreter.Con` +[accessible: true] `class FuncallccInterpreter.Fun` +[accessible: true] `class LamcallccInterpreter.Lam` +[accessible: true] `class McallccInterpreter.M` +[accessible: true] `class NumcallccInterpreter.Num` +[accessible: true] `class VarcallccInterpreter.Var` +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(callccInterpreter.type, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method add(a: callccInterpreter.Value, b: callccInterpreter.Value)callccInterpreter.M[_ >: callccInterpreter.Num with callccInterpreter.Wrong.type <: Product with Serializable with callccInterpreter.Value]` +[accessible: true] `method apply(a: callccInterpreter.Value, b: callccInterpreter.Value)callccInterpreter.M[callccInterpreter.Value]` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method callCC[A](h: (A => callccInterpreter.M[A]) => callccInterpreter.M[A])callccInterpreter.M[A]` +[accessible: true] `method clone()Object` +[accessible: true] `method ensuring(cond: Boolean)callccInterpreter.type` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)callccInterpreter.type` +[accessible: true] `method ensuring(cond: callccInterpreter.type => Boolean)callccInterpreter.type` +[accessible: true] `method ensuring(cond: callccInterpreter.type => Boolean, msg: => Any)callccInterpreter.type` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method finalize()Unit` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method id[A]=> A => A` +[accessible: true] `method interp(t: callccInterpreter.Term, e: callccInterpreter.Environment)callccInterpreter.M[callccInterpreter.Value]` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method lookup(x: callccInterpreter.Name, e: callccInterpreter.Environment)callccInterpreter.M[callccInterpreter.Value]` +[accessible: true] `method main(args: Array[String])Unit` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method showM(m: callccInterpreter.M[callccInterpreter.Value])String` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method test(t: callccInterpreter.Term)String` +[accessible: true] `method toString()String` +[accessible: true] `method unitM[A](a: A)callccInterpreter.M[A]` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> callccInterpreter.type` +[accessible: true] `method →[B](y: B)(callccInterpreter.type, B)` +[accessible: true] `object WrongcallccInterpreter.Wrong.type` +[accessible: true] `trait TermcallccInterpreter.Term` +[accessible: true] `trait ValuecallccInterpreter.Value` +[accessible: true] `type AnswercallccInterpreter.Answer` +[accessible: true] `type EnvironmentcallccInterpreter.Environment` +[accessible: true] `type NamecallccInterpreter.Name` +[accessible: true] `value term0callccInterpreter.App` +[accessible: true] `value term1callccInterpreter.App` +[accessible: true] `value term2callccInterpreter.Add` +[accessible: false] `value __leftOfArrowcallccInterpreter.type` +[accessible: false] `value __resultOfEnsuringcallccInterpreter.type` +[accessible: false] `value selfAny` ================================================================================ askType at CallccInterpreter.scala(14,21) diff --git a/test/files/presentation/ide-bug-1000349.check b/test/files/presentation/ide-bug-1000349.check index 9c070ef24e..d643f82a25 100644 --- a/test/files/presentation/ide-bug-1000349.check +++ b/test/files/presentation/ide-bug-1000349.check @@ -4,37 +4,37 @@ askTypeCompletion at CompletionOnEmptyArgMethod.scala(2,17) ================================================================================ [response] aksTypeCompletion at (2,17) retrieved 37 members -`method !=(x$1: Any)Boolean` -`method !=(x$1: AnyRef)Boolean` -`method ##()Int` -`method +(other: String)String` -`method ->[B](y: B)(Foo, B)` -`method ==(x$1: Any)Boolean` -`method ==(x$1: AnyRef)Boolean` -`method asInstanceOf[T0]=> T0` -`method clone()Object` -`method ensuring(cond: Boolean)Foo` -`method ensuring(cond: Boolean, msg: => Any)Foo` -`method ensuring(cond: Foo => Boolean)Foo` -`method ensuring(cond: Foo => Boolean, msg: => Any)Foo` -`method eq(x$1: AnyRef)Boolean` -`method equals(x$1: Any)Boolean` -`method finalize()Unit` -`method foo=> Foo` -`method formatted(fmtstr: String)String` -`method hashCode()Int` -`method isInstanceOf[T0]=> Boolean` -`method ne(x$1: AnyRef)Boolean` -`method notify()Unit` -`method notifyAll()Unit` -`method synchronized[T0](x$1: T0)T0` -`method toString()String` -`method wait()Unit` -`method wait(x$1: Long)Unit` -`method wait(x$1: Long, x$2: Int)Unit` -`method x=> Foo` -`method →[B](y: B)(Foo, B)` -`value __leftOfArrowFoo` -`value __resultOfEnsuringFoo` -`value selfAny` -================================================================================ \ No newline at end of file +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(Foo, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method clone()Object` +[accessible: true] `method ensuring(cond: Boolean)Foo` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)Foo` +[accessible: true] `method ensuring(cond: Foo => Boolean)Foo` +[accessible: true] `method ensuring(cond: Foo => Boolean, msg: => Any)Foo` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method finalize()Unit` +[accessible: true] `method foo=> Foo` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> Foo` +[accessible: true] `method →[B](y: B)(Foo, B)` +[accessible: false] `value __leftOfArrowFoo` +[accessible: false] `value __resultOfEnsuringFoo` +[accessible: false] `value selfAny` +================================================================================ diff --git a/test/files/presentation/ide-bug-1000475.check b/test/files/presentation/ide-bug-1000475.check index 1718119385..2410ebf71d 100644 --- a/test/files/presentation/ide-bug-1000475.check +++ b/test/files/presentation/ide-bug-1000475.check @@ -4,112 +4,112 @@ askTypeCompletion at Foo.scala(3,7) ================================================================================ [response] aksTypeCompletion at (3,7) retrieved 36 members -`method !=(x$1: Any)Boolean` -`method !=(x$1: AnyRef)Boolean` -`method ##()Int` -`method +(other: String)String` -`method ->[B](y: B)(Object, B)` -`method ==(x$1: Any)Boolean` -`method ==(x$1: AnyRef)Boolean` -`method asInstanceOf[T0]=> T0` -`method clone()Object` -`method ensuring(cond: Boolean)Object` -`method ensuring(cond: Boolean, msg: => Any)Object` -`method ensuring(cond: Object => Boolean)Object` -`method ensuring(cond: Object => Boolean, msg: => Any)Object` -`method eq(x$1: AnyRef)Boolean` -`method equals(x$1: Any)Boolean` -`method finalize()Unit` -`method formatted(fmtstr: String)String` -`method hashCode()Int` -`method isInstanceOf[T0]=> Boolean` -`method ne(x$1: AnyRef)Boolean` -`method notify()Unit` -`method notifyAll()Unit` -`method synchronized[T0](x$1: T0)T0` -`method toString()String` -`method wait()Unit` -`method wait(x$1: Long)Unit` -`method wait(x$1: Long, x$2: Int)Unit` -`method x=> Object` -`method →[B](y: B)(Object, B)` -`value __leftOfArrowObject` -`value __resultOfEnsuringObject` -`value selfAny` +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(Object, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method ensuring(cond: Boolean)Object` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)Object` +[accessible: true] `method ensuring(cond: Object => Boolean)Object` +[accessible: true] `method ensuring(cond: Object => Boolean, msg: => Any)Object` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> Object` +[accessible: true] `method →[B](y: B)(Object, B)` +[accessible: false] `method clone()Object` +[accessible: false] `method finalize()Unit` +[accessible: false] `value __leftOfArrowObject` +[accessible: false] `value __resultOfEnsuringObject` +[accessible: false] `value selfAny` ================================================================================ askTypeCompletion at Foo.scala(6,10) ================================================================================ [response] aksTypeCompletion at (6,10) retrieved 36 members -`method !=(x$1: Any)Boolean` -`method !=(x$1: AnyRef)Boolean` -`method ##()Int` -`method +(other: String)String` -`method ->[B](y: B)(Object, B)` -`method ==(x$1: Any)Boolean` -`method ==(x$1: AnyRef)Boolean` -`method asInstanceOf[T0]=> T0` -`method clone()Object` -`method ensuring(cond: Boolean)Object` -`method ensuring(cond: Boolean, msg: => Any)Object` -`method ensuring(cond: Object => Boolean)Object` -`method ensuring(cond: Object => Boolean, msg: => Any)Object` -`method eq(x$1: AnyRef)Boolean` -`method equals(x$1: Any)Boolean` -`method finalize()Unit` -`method formatted(fmtstr: String)String` -`method hashCode()Int` -`method isInstanceOf[T0]=> Boolean` -`method ne(x$1: AnyRef)Boolean` -`method notify()Unit` -`method notifyAll()Unit` -`method synchronized[T0](x$1: T0)T0` -`method toString()String` -`method wait()Unit` -`method wait(x$1: Long)Unit` -`method wait(x$1: Long, x$2: Int)Unit` -`method x=> Object` -`method →[B](y: B)(Object, B)` -`value __leftOfArrowObject` -`value __resultOfEnsuringObject` -`value selfAny` +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(Object, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method ensuring(cond: Boolean)Object` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)Object` +[accessible: true] `method ensuring(cond: Object => Boolean)Object` +[accessible: true] `method ensuring(cond: Object => Boolean, msg: => Any)Object` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> Object` +[accessible: true] `method →[B](y: B)(Object, B)` +[accessible: false] `method clone()Object` +[accessible: false] `method finalize()Unit` +[accessible: false] `value __leftOfArrowObject` +[accessible: false] `value __resultOfEnsuringObject` +[accessible: false] `value selfAny` ================================================================================ askTypeCompletion at Foo.scala(7,7) ================================================================================ [response] aksTypeCompletion at (7,7) retrieved 36 members -`method !=(x$1: Any)Boolean` -`method !=(x$1: AnyRef)Boolean` -`method ##()Int` -`method +(other: String)String` -`method ->[B](y: B)(Object, B)` -`method ==(x$1: Any)Boolean` -`method ==(x$1: AnyRef)Boolean` -`method asInstanceOf[T0]=> T0` -`method clone()Object` -`method ensuring(cond: Boolean)Object` -`method ensuring(cond: Boolean, msg: => Any)Object` -`method ensuring(cond: Object => Boolean)Object` -`method ensuring(cond: Object => Boolean, msg: => Any)Object` -`method eq(x$1: AnyRef)Boolean` -`method equals(x$1: Any)Boolean` -`method finalize()Unit` -`method formatted(fmtstr: String)String` -`method hashCode()Int` -`method isInstanceOf[T0]=> Boolean` -`method ne(x$1: AnyRef)Boolean` -`method notify()Unit` -`method notifyAll()Unit` -`method synchronized[T0](x$1: T0)T0` -`method toString()String` -`method wait()Unit` -`method wait(x$1: Long)Unit` -`method wait(x$1: Long, x$2: Int)Unit` -`method x=> Object` -`method →[B](y: B)(Object, B)` -`value __leftOfArrowObject` -`value __resultOfEnsuringObject` -`value selfAny` +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(Object, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method ensuring(cond: Boolean)Object` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)Object` +[accessible: true] `method ensuring(cond: Object => Boolean)Object` +[accessible: true] `method ensuring(cond: Object => Boolean, msg: => Any)Object` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> Object` +[accessible: true] `method →[B](y: B)(Object, B)` +[accessible: false] `method clone()Object` +[accessible: false] `method finalize()Unit` +[accessible: false] `value __leftOfArrowObject` +[accessible: false] `value __resultOfEnsuringObject` +[accessible: false] `value selfAny` ================================================================================ diff --git a/test/files/presentation/ide-bug-1000531.check b/test/files/presentation/ide-bug-1000531.check index 2b48a80d38..d9109bcc6a 100644 --- a/test/files/presentation/ide-bug-1000531.check +++ b/test/files/presentation/ide-bug-1000531.check @@ -4,123 +4,123 @@ askTypeCompletion at CrashOnLoad.scala(6,12) ================================================================================ [response] aksTypeCompletion at (6,12) retrieved 123 members -`class GroupedIteratorIterator[B]#GroupedIterator` -`method !=(x$1: Any)Boolean` -`method !=(x$1: AnyRef)Boolean` -`method ##()Int` -`method +(other: String)String` -`method ++[B >: B](that: => scala.collection.GenTraversableOnce[B])Iterator[B]` -`method ->[B](y: B)(java.util.Iterator[B], B)` -`method /:[B](z: B)(op: (B, B) => B)B` -`method /:\[A1 >: B](z: A1)(op: (A1, A1) => A1)A1` -`method :\[B](z: B)(op: (B, B) => B)B` -`method ==(x$1: Any)Boolean` -`method ==(x$1: AnyRef)Boolean` -`method addString(b: StringBuilder)StringBuilder` -`method addString(b: StringBuilder, sep: String)StringBuilder` -`method addString(b: StringBuilder, start: String, sep: String, end: String)StringBuilder` -`method aggregate[B](z: B)(seqop: (B, B) => B, combop: (B, B) => B)B` -`method asInstanceOf[T0]=> T0` -`method buffered=> scala.collection.BufferedIterator[B]` -`method clone()Object` -`method collectFirst[B](pf: PartialFunction[B,B])Option[B]` -`method collect[B](pf: PartialFunction[B,B])Iterator[B]` -`method contains(elem: Any)Boolean` -`method copyToArray[B >: B](xs: Array[B])Unit` -`method copyToArray[B >: B](xs: Array[B], start: Int)Unit` -`method copyToArray[B >: B](xs: Array[B], start: Int, len: Int)Unit` -`method copyToBuffer[B >: B](dest: scala.collection.mutable.Buffer[B])Unit` -`method count(p: B => Boolean)Int` -`method drop(n: Int)Iterator[B]` -`method dropWhile(p: B => Boolean)Iterator[B]` -`method duplicate=> (Iterator[B], Iterator[B])` -`method ensuring(cond: Boolean)java.util.Iterator[B]` -`method ensuring(cond: Boolean, msg: => Any)java.util.Iterator[B]` -`method ensuring(cond: java.util.Iterator[B] => Boolean)java.util.Iterator[B]` -`method ensuring(cond: java.util.Iterator[B] => Boolean, msg: => Any)java.util.Iterator[B]` -`method eq(x$1: AnyRef)Boolean` -`method equals(x$1: Any)Boolean` -`method exists(p: B => Boolean)Boolean` -`method filter(p: B => Boolean)Iterator[B]` -`method filterNot(p: B => Boolean)Iterator[B]` -`method finalize()Unit` -`method find(p: B => Boolean)Option[B]` -`method flatMap[B](f: B => scala.collection.GenTraversableOnce[B])Iterator[B]` -`method foldLeft[B](z: B)(op: (B, B) => B)B` -`method foldRight[B](z: B)(op: (B, B) => B)B` -`method fold[A1 >: B](z: A1)(op: (A1, A1) => A1)A1` -`method forall(p: B => Boolean)Boolean` -`method foreach[U](f: B => U)Unit` -`method formatted(fmtstr: String)String` -`method grouped[B >: B](size: Int)Iterator[B]#GroupedIterator[B]` -`method hasDefiniteSize=> Boolean` -`method hasNext()Boolean` -`method hashCode()Int` -`method indexOf[B >: B](elem: B)Int` -`method indexWhere(p: B => Boolean)Int` -`method isEmpty=> Boolean` -`method isInstanceOf[T0]=> Boolean` -`method isTraversableAgain=> Boolean` -`method length=> Int` -`method map[B](f: B => B)Iterator[B]` -`method maxBy[B](f: B => B)(implicit cmp: Ordering[B])B` -`method max[B >: B](implicit cmp: Ordering[B])B` -`method minBy[B](f: B => B)(implicit cmp: Ordering[B])B` -`method min[B >: B](implicit cmp: Ordering[B])B` -`method mkString(sep: String)String` -`method mkString(start: String, sep: String, end: String)String` -`method mkString=> String` -`method ne(x$1: AnyRef)Boolean` -`method next()B` -`method nonEmpty=> Boolean` -`method notify()Unit` -`method notifyAll()Unit` -`method padTo[A1 >: B](len: Int, elem: A1)Iterator[A1]` -`method partition(p: B => Boolean)(Iterator[B], Iterator[B])` -`method patch[B >: B](from: Int, patchElems: Iterator[B], replaced: Int)Iterator[B]` -`method product[B >: B](implicit num: Numeric[B])B` -`method reduceLeftOption[B >: B](op: (B, B) => B)Option[B]` -`method reduceLeft[B >: B](op: (B, B) => B)B` -`method reduceOption[A1 >: B](op: (A1, A1) => A1)Option[A1]` -`method reduceRightOption[B >: B](op: (B, B) => B)Option[B]` -`method reduceRight[B >: B](op: (B, B) => B)B` -`method reduce[A1 >: B](op: (A1, A1) => A1)A1` -`method remove()Unit` -`method reversed=> List[B]` -`method sameElements(that: Iterator[_])Boolean` -`method scanLeft[B](z: B)(op: (B, B) => B)Iterator[B]` -`method scanRight[B](z: B)(op: (B, B) => B)Iterator[B]` -`method seq=> Iterator[B]` -`method size=> Int` -`method slice(from: Int, until: Int)Iterator[B]` -`method sliding[B >: B](size: Int, step: Int)Iterator[B]#GroupedIterator[B]` -`method span(p: B => Boolean)(Iterator[B], Iterator[B])` -`method sum[B >: B](implicit num: Numeric[B])B` -`method synchronized[T0](x$1: T0)T0` -`method take(n: Int)Iterator[B]` -`method takeWhile(p: B => Boolean)Iterator[B]` -`method toArray[B >: B](implicit evidence$1: ArrayTag[B])Array[B]` -`method toBuffer[B >: B]=> scala.collection.mutable.Buffer[B]` -`method toIndexedSeq=> scala.collection.immutable.IndexedSeq[B]` -`method toIterable=> Iterable[B]` -`method toIterator=> Iterator[B]` -`method toList=> List[B]` -`method toMap[T, U](implicit ev: <:<[B,(T, U)])scala.collection.immutable.Map[T,U]` -`method toSeq=> Seq[B]` -`method toSet[B >: B]=> scala.collection.immutable.Set[B]` -`method toStream=> scala.collection.immutable.Stream[B]` -`method toString()String` -`method toTraversable=> Traversable[B]` -`method wait()Unit` -`method wait(x$1: Long)Unit` -`method wait(x$1: Long, x$2: Int)Unit` -`method withFilter(p: B => Boolean)Iterator[B]` -`method x=> java.util.Iterator[B]` -`method zipAll[B, A1 >: B, B1 >: B](that: Iterator[B], thisElem: A1, thatElem: B1)Iterator[(A1, B1)]` -`method zipWithIndex=> Iterator[(B, Int)]` -`method zip[B](that: Iterator[B])Iterator[(B, B)]` -`method →[B](y: B)(java.util.Iterator[B], B)` -`value __leftOfArrowjava.util.Iterator[B]` -`value __resultOfEnsuringjava.util.Iterator[B]` -`value selfAny` +[accessible: true] `class GroupedIteratorIterator[B]#GroupedIterator` +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ++[B >: B](that: => scala.collection.GenTraversableOnce[B])Iterator[B]` +[accessible: true] `method ->[B](y: B)(java.util.Iterator[B], B)` +[accessible: true] `method /:[B](z: B)(op: (B, B) => B)B` +[accessible: true] `method /:\[A1 >: B](z: A1)(op: (A1, A1) => A1)A1` +[accessible: true] `method :\[B](z: B)(op: (B, B) => B)B` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method addString(b: StringBuilder)StringBuilder` +[accessible: true] `method addString(b: StringBuilder, sep: String)StringBuilder` +[accessible: true] `method addString(b: StringBuilder, start: String, sep: String, end: String)StringBuilder` +[accessible: true] `method aggregate[B](z: B)(seqop: (B, B) => B, combop: (B, B) => B)B` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method buffered=> scala.collection.BufferedIterator[B]` +[accessible: true] `method collectFirst[B](pf: PartialFunction[B,B])Option[B]` +[accessible: true] `method collect[B](pf: PartialFunction[B,B])Iterator[B]` +[accessible: true] `method contains(elem: Any)Boolean` +[accessible: true] `method copyToArray[B >: B](xs: Array[B])Unit` +[accessible: true] `method copyToArray[B >: B](xs: Array[B], start: Int)Unit` +[accessible: true] `method copyToArray[B >: B](xs: Array[B], start: Int, len: Int)Unit` +[accessible: true] `method copyToBuffer[B >: B](dest: scala.collection.mutable.Buffer[B])Unit` +[accessible: true] `method count(p: B => Boolean)Int` +[accessible: true] `method drop(n: Int)Iterator[B]` +[accessible: true] `method dropWhile(p: B => Boolean)Iterator[B]` +[accessible: true] `method duplicate=> (Iterator[B], Iterator[B])` +[accessible: true] `method ensuring(cond: Boolean)java.util.Iterator[B]` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)java.util.Iterator[B]` +[accessible: true] `method ensuring(cond: java.util.Iterator[B] => Boolean)java.util.Iterator[B]` +[accessible: true] `method ensuring(cond: java.util.Iterator[B] => Boolean, msg: => Any)java.util.Iterator[B]` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method exists(p: B => Boolean)Boolean` +[accessible: true] `method filter(p: B => Boolean)Iterator[B]` +[accessible: true] `method filterNot(p: B => Boolean)Iterator[B]` +[accessible: true] `method find(p: B => Boolean)Option[B]` +[accessible: true] `method flatMap[B](f: B => scala.collection.GenTraversableOnce[B])Iterator[B]` +[accessible: true] `method foldLeft[B](z: B)(op: (B, B) => B)B` +[accessible: true] `method foldRight[B](z: B)(op: (B, B) => B)B` +[accessible: true] `method fold[A1 >: B](z: A1)(op: (A1, A1) => A1)A1` +[accessible: true] `method forall(p: B => Boolean)Boolean` +[accessible: true] `method foreach[U](f: B => U)Unit` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method grouped[B >: B](size: Int)Iterator[B]#GroupedIterator[B]` +[accessible: true] `method hasDefiniteSize=> Boolean` +[accessible: true] `method hasNext()Boolean` +[accessible: true] `method hashCode()Int` +[accessible: true] `method indexOf[B >: B](elem: B)Int` +[accessible: true] `method indexWhere(p: B => Boolean)Int` +[accessible: true] `method isEmpty=> Boolean` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method isTraversableAgain=> Boolean` +[accessible: true] `method length=> Int` +[accessible: true] `method map[B](f: B => B)Iterator[B]` +[accessible: true] `method maxBy[B](f: B => B)(implicit cmp: Ordering[B])B` +[accessible: true] `method max[B >: B](implicit cmp: Ordering[B])B` +[accessible: true] `method minBy[B](f: B => B)(implicit cmp: Ordering[B])B` +[accessible: true] `method min[B >: B](implicit cmp: Ordering[B])B` +[accessible: true] `method mkString(sep: String)String` +[accessible: true] `method mkString(start: String, sep: String, end: String)String` +[accessible: true] `method mkString=> String` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method next()B` +[accessible: true] `method nonEmpty=> Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method padTo[A1 >: B](len: Int, elem: A1)Iterator[A1]` +[accessible: true] `method partition(p: B => Boolean)(Iterator[B], Iterator[B])` +[accessible: true] `method patch[B >: B](from: Int, patchElems: Iterator[B], replaced: Int)Iterator[B]` +[accessible: true] `method product[B >: B](implicit num: Numeric[B])B` +[accessible: true] `method reduceLeftOption[B >: B](op: (B, B) => B)Option[B]` +[accessible: true] `method reduceLeft[B >: B](op: (B, B) => B)B` +[accessible: true] `method reduceOption[A1 >: B](op: (A1, A1) => A1)Option[A1]` +[accessible: true] `method reduceRightOption[B >: B](op: (B, B) => B)Option[B]` +[accessible: true] `method reduceRight[B >: B](op: (B, B) => B)B` +[accessible: true] `method reduce[A1 >: B](op: (A1, A1) => A1)A1` +[accessible: true] `method remove()Unit` +[accessible: true] `method sameElements(that: Iterator[_])Boolean` +[accessible: true] `method scanLeft[B](z: B)(op: (B, B) => B)Iterator[B]` +[accessible: true] `method scanRight[B](z: B)(op: (B, B) => B)Iterator[B]` +[accessible: true] `method seq=> Iterator[B]` +[accessible: true] `method size=> Int` +[accessible: true] `method slice(from: Int, until: Int)Iterator[B]` +[accessible: true] `method sliding[B >: B](size: Int, step: Int)Iterator[B]#GroupedIterator[B]` +[accessible: true] `method span(p: B => Boolean)(Iterator[B], Iterator[B])` +[accessible: true] `method sum[B >: B](implicit num: Numeric[B])B` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method take(n: Int)Iterator[B]` +[accessible: true] `method takeWhile(p: B => Boolean)Iterator[B]` +[accessible: true] `method toArray[B >: B](implicit evidence$1: ArrayTag[B])Array[B]` +[accessible: true] `method toBuffer[B >: B]=> scala.collection.mutable.Buffer[B]` +[accessible: true] `method toIndexedSeq=> scala.collection.immutable.IndexedSeq[B]` +[accessible: true] `method toIterable=> Iterable[B]` +[accessible: true] `method toIterator=> Iterator[B]` +[accessible: true] `method toList=> List[B]` +[accessible: true] `method toMap[T, U](implicit ev: <:<[B,(T, U)])scala.collection.immutable.Map[T,U]` +[accessible: true] `method toSeq=> Seq[B]` +[accessible: true] `method toSet[B >: B]=> scala.collection.immutable.Set[B]` +[accessible: true] `method toStream=> scala.collection.immutable.Stream[B]` +[accessible: true] `method toString()String` +[accessible: true] `method toTraversable=> Traversable[B]` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method withFilter(p: B => Boolean)Iterator[B]` +[accessible: true] `method x=> java.util.Iterator[B]` +[accessible: true] `method zipAll[B, A1 >: B, B1 >: B](that: Iterator[B], thisElem: A1, thatElem: B1)Iterator[(A1, B1)]` +[accessible: true] `method zipWithIndex=> Iterator[(B, Int)]` +[accessible: true] `method zip[B](that: Iterator[B])Iterator[(B, B)]` +[accessible: true] `method →[B](y: B)(java.util.Iterator[B], B)` +[accessible: false] `method clone()Object` +[accessible: false] `method finalize()Unit` +[accessible: false] `method reversed=> List[B]` +[accessible: false] `value __leftOfArrowjava.util.Iterator[B]` +[accessible: false] `value __resultOfEnsuringjava.util.Iterator[B]` +[accessible: false] `value selfAny` ================================================================================ diff --git a/test/files/presentation/implicit-member.check b/test/files/presentation/implicit-member.check index e8e656f12a..ce21293ae5 100644 --- a/test/files/presentation/implicit-member.check +++ b/test/files/presentation/implicit-member.check @@ -4,39 +4,39 @@ askTypeCompletion at ImplicitMember.scala(7,7) ================================================================================ [response] aksTypeCompletion at (7,7) retrieved 39 members -`class AppliedImplicitImplicit.AppliedImplicit` -`method !=(x$1: Any)Boolean` -`method !=(x$1: AnyRef)Boolean` -`method ##()Int` -`method +(other: String)String` -`method ->[B](y: B)(Implicit.type, B)` -`method ==(x$1: Any)Boolean` -`method ==(x$1: AnyRef)Boolean` -`method AppliedImplicit[A](x: A)Implicit.AppliedImplicit[A]` -`method asInstanceOf[T0]=> T0` -`method clone()Object` -`method ensuring(cond: Boolean)Implicit.type` -`method ensuring(cond: Boolean, msg: => Any)Implicit.type` -`method ensuring(cond: Implicit.type => Boolean)Implicit.type` -`method ensuring(cond: Implicit.type => Boolean, msg: => Any)Implicit.type` -`method eq(x$1: AnyRef)Boolean` -`method equals(x$1: Any)Boolean` -`method finalize()Unit` -`method formatted(fmtstr: String)String` -`method hashCode()Int` -`method isInstanceOf[T0]=> Boolean` -`method ne(x$1: AnyRef)Boolean` -`method notify()Unit` -`method notifyAll()Unit` -`method synchronized[T0](x$1: T0)T0` -`method toString()String` -`method wait()Unit` -`method wait(x$1: Long)Unit` -`method wait(x$1: Long, x$2: Int)Unit` -`method x=> Implicit.type` -`method →[B](y: B)(Implicit.type, B)` -`value __leftOfArrowImplicit.type` -`value __resultOfEnsuringImplicit.type` -`value selfAny` -`value xImplicit.type` +[accessible: true] `class AppliedImplicitImplicit.AppliedImplicit` +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(Implicit.type, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method AppliedImplicit[A](x: A)Implicit.AppliedImplicit[A]` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method clone()Object` +[accessible: true] `method ensuring(cond: Boolean)Implicit.type` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)Implicit.type` +[accessible: true] `method ensuring(cond: Implicit.type => Boolean)Implicit.type` +[accessible: true] `method ensuring(cond: Implicit.type => Boolean, msg: => Any)Implicit.type` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method finalize()Unit` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> Implicit.type` +[accessible: true] `method →[B](y: B)(Implicit.type, B)` +[accessible: false] `value __leftOfArrowImplicit.type` +[accessible: false] `value __resultOfEnsuringImplicit.type` +[accessible: false] `value selfAny` +[accessible: false] `value xImplicit.type` ================================================================================ diff --git a/test/files/presentation/ping-pong.check b/test/files/presentation/ping-pong.check index 38040bdacf..1f02274736 100644 --- a/test/files/presentation/ping-pong.check +++ b/test/files/presentation/ping-pong.check @@ -4,83 +4,83 @@ askTypeCompletion at PingPong.scala(10,23) ================================================================================ [response] aksTypeCompletion at (10,23) retrieved 40 members -`method !=(x$1: Any)Boolean` -`method !=(x$1: AnyRef)Boolean` -`method ##()Int` -`method +(other: String)String` -`method ->[B](y: B)(Pong, B)` -`method ==(x$1: Any)Boolean` -`method ==(x$1: AnyRef)Boolean` -`method asInstanceOf[T0]=> T0` -`method clone()Object` -`method ensuring(cond: Boolean)Pong` -`method ensuring(cond: Boolean, msg: => Any)Pong` -`method ensuring(cond: Pong => Boolean)Pong` -`method ensuring(cond: Pong => Boolean, msg: => Any)Pong` -`method eq(x$1: AnyRef)Boolean` -`method equals(x$1: Any)Boolean` -`method finalize()Unit` -`method formatted(fmtstr: String)String` -`method hashCode()Int` -`method isInstanceOf[T0]=> Boolean` -`method ne(x$1: AnyRef)Boolean` -`method notify()Unit` -`method notifyAll()Unit` -`method poke()Unit` -`method synchronized[T0](x$1: T0)T0` -`method toString()String` -`method wait()Unit` -`method wait(x$1: Long)Unit` -`method wait(x$1: Long, x$2: Int)Unit` -`method x=> Pong` -`method →[B](y: B)(Pong, B)` -`value __leftOfArrowPong` -`value __resultOfEnsuringPong` -`value nameString` -`value pingPing` -`value selfAny` +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(Pong, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method ensuring(cond: Boolean)Pong` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)Pong` +[accessible: true] `method ensuring(cond: Pong => Boolean)Pong` +[accessible: true] `method ensuring(cond: Pong => Boolean, msg: => Any)Pong` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method poke()Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> Pong` +[accessible: true] `method →[B](y: B)(Pong, B)` +[accessible: false] `method clone()Object` +[accessible: false] `method finalize()Unit` +[accessible: false] `value __leftOfArrowPong` +[accessible: false] `value __resultOfEnsuringPong` +[accessible: false] `value nameString` +[accessible: false] `value pingPing` +[accessible: false] `value selfAny` ================================================================================ askTypeCompletion at PingPong.scala(19,20) ================================================================================ [response] aksTypeCompletion at (19,20) retrieved 40 members -`method !=(x$1: Any)Boolean` -`method !=(x$1: AnyRef)Boolean` -`method ##()Int` -`method +(other: String)String` -`method ->[B](y: B)(Ping, B)` -`method ==(x$1: Any)Boolean` -`method ==(x$1: AnyRef)Boolean` -`method asInstanceOf[T0]=> T0` -`method clone()Object` -`method ensuring(cond: Boolean)Ping` -`method ensuring(cond: Boolean, msg: => Any)Ping` -`method ensuring(cond: Ping => Boolean)Ping` -`method ensuring(cond: Ping => Boolean, msg: => Any)Ping` -`method eq(x$1: AnyRef)Boolean` -`method equals(x$1: Any)Boolean` -`method finalize()Unit` -`method formatted(fmtstr: String)String` -`method hashCode()Int` -`method isInstanceOf[T0]=> Boolean` -`method loop=> Unit` -`method name=> String` -`method ne(x$1: AnyRef)Boolean` -`method notify()Unit` -`method notifyAll()Unit` -`method poke=> Unit` -`method synchronized[T0](x$1: T0)T0` -`method toString()String` -`method wait()Unit` -`method wait(x$1: Long)Unit` -`method wait(x$1: Long, x$2: Int)Unit` -`method x=> Ping` -`method →[B](y: B)(Ping, B)` -`value __leftOfArrowPing` -`value __resultOfEnsuringPing` -`value pongPong` -`value selfAny` +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(Ping, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method ensuring(cond: Boolean)Ping` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)Ping` +[accessible: true] `method ensuring(cond: Ping => Boolean)Ping` +[accessible: true] `method ensuring(cond: Ping => Boolean, msg: => Any)Ping` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method loop=> Unit` +[accessible: true] `method name=> String` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method poke=> Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> Ping` +[accessible: true] `method →[B](y: B)(Ping, B)` +[accessible: false] `method clone()Object` +[accessible: false] `method finalize()Unit` +[accessible: false] `value __leftOfArrowPing` +[accessible: false] `value __resultOfEnsuringPing` +[accessible: false] `value pongPong` +[accessible: false] `value selfAny` ================================================================================ askType at PingPong.scala(8,10) diff --git a/test/files/presentation/visibility.check b/test/files/presentation/visibility.check new file mode 100644 index 0000000000..290a5ac381 --- /dev/null +++ b/test/files/presentation/visibility.check @@ -0,0 +1,221 @@ +reload: Completions.scala + +askTypeCompletion at Completions.scala(14,12) +================================================================================ +[response] aksTypeCompletion at (14,12) +retrieved 42 members +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(accessibility.Foo, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method clone()Object` +[accessible: true] `method ensuring(cond: Boolean)accessibility.Foo` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)accessibility.Foo` +[accessible: true] `method ensuring(cond: accessibility.Foo => Boolean)accessibility.Foo` +[accessible: true] `method ensuring(cond: accessibility.Foo => Boolean, msg: => Any)accessibility.Foo` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method finalize()Unit` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method secretPrivate()Unit` +[accessible: true] `method secretProtected()Unit` +[accessible: true] `method secretProtectedInPackage()Unit` +[accessible: true] `method secretPublic()Unit` +[accessible: true] `method someTests(other: accessibility.Foo)Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> accessibility.Foo` +[accessible: true] `method →[B](y: B)(accessibility.Foo, B)` +[accessible: false] `method secretPrivateThis()Unit` +[accessible: false] `value __leftOfArrowaccessibility.Foo` +[accessible: false] `value __resultOfEnsuringaccessibility.Foo` +[accessible: false] `value selfAny` +================================================================================ + +askTypeCompletion at Completions.scala(16,11) +================================================================================ +[response] aksTypeCompletion at (16,11) +retrieved 42 members +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(accessibility.Foo, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method clone()Object` +[accessible: true] `method ensuring(cond: Boolean)accessibility.Foo` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)accessibility.Foo` +[accessible: true] `method ensuring(cond: accessibility.Foo => Boolean)accessibility.Foo` +[accessible: true] `method ensuring(cond: accessibility.Foo => Boolean, msg: => Any)accessibility.Foo` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method finalize()Unit` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method secretPrivate()Unit` +[accessible: true] `method secretPrivateThis()Unit` +[accessible: true] `method secretProtected()Unit` +[accessible: true] `method secretProtectedInPackage()Unit` +[accessible: true] `method secretPublic()Unit` +[accessible: true] `method someTests(other: accessibility.Foo)Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> accessibility.Foo` +[accessible: true] `method →[B](y: B)(accessibility.Foo, B)` +[accessible: false] `value __leftOfArrowaccessibility.Foo` +[accessible: false] `value __resultOfEnsuringaccessibility.Foo` +[accessible: false] `value selfAny` +================================================================================ + +askTypeCompletion at Completions.scala(22,11) +================================================================================ +[response] aksTypeCompletion at (22,11) +retrieved 42 members +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(accessibility.AccessibilityChecks, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method clone()Object` +[accessible: true] `method ensuring(cond: Boolean)accessibility.AccessibilityChecks` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)accessibility.AccessibilityChecks` +[accessible: true] `method ensuring(cond: accessibility.AccessibilityChecks => Boolean)accessibility.AccessibilityChecks` +[accessible: true] `method ensuring(cond: accessibility.AccessibilityChecks => Boolean, msg: => Any)accessibility.AccessibilityChecks` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method finalize()Unit` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method secretProtected()Unit` +[accessible: true] `method secretProtectedInPackage()Unit` +[accessible: true] `method secretPublic()Unit` +[accessible: true] `method someTests(other: accessibility.Foo)Unit` +[accessible: true] `method someTests=> Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> accessibility.AccessibilityChecks` +[accessible: true] `method →[B](y: B)(accessibility.AccessibilityChecks, B)` +[accessible: false] `method secretPrivate()Unit` +[accessible: false] `value __leftOfArrowaccessibility.AccessibilityChecks` +[accessible: false] `value __resultOfEnsuringaccessibility.AccessibilityChecks` +[accessible: false] `value selfAny` +================================================================================ + +askTypeCompletion at Completions.scala(28,10) +================================================================================ +[response] aksTypeCompletion at (28,10) +retrieved 42 members +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(accessibility.Foo, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method ensuring(cond: Boolean)accessibility.Foo` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)accessibility.Foo` +[accessible: true] `method ensuring(cond: accessibility.Foo => Boolean)accessibility.Foo` +[accessible: true] `method ensuring(cond: accessibility.Foo => Boolean, msg: => Any)accessibility.Foo` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method secretProtectedInPackage()Unit` +[accessible: true] `method secretPublic()Unit` +[accessible: true] `method someTests(other: accessibility.Foo)Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> accessibility.Foo` +[accessible: true] `method →[B](y: B)(accessibility.Foo, B)` +[accessible: false] `method clone()Object` +[accessible: false] `method finalize()Unit` +[accessible: false] `method secretPrivate()Unit` +[accessible: false] `method secretPrivateThis()Unit` +[accessible: false] `method secretProtected()Unit` +[accessible: false] `value __leftOfArrowaccessibility.Foo` +[accessible: false] `value __resultOfEnsuringaccessibility.Foo` +[accessible: false] `value selfAny` +================================================================================ + +askTypeCompletion at Completions.scala(37,8) +================================================================================ +[response] aksTypeCompletion at (37,8) +retrieved 42 members +[accessible: true] `method !=(x$1: Any)Boolean` +[accessible: true] `method !=(x$1: AnyRef)Boolean` +[accessible: true] `method ##()Int` +[accessible: true] `method +(other: String)String` +[accessible: true] `method ->[B](y: B)(accessibility.Foo, B)` +[accessible: true] `method ==(x$1: Any)Boolean` +[accessible: true] `method ==(x$1: AnyRef)Boolean` +[accessible: true] `method asInstanceOf[T0]=> T0` +[accessible: true] `method ensuring(cond: Boolean)accessibility.Foo` +[accessible: true] `method ensuring(cond: Boolean, msg: => Any)accessibility.Foo` +[accessible: true] `method ensuring(cond: accessibility.Foo => Boolean)accessibility.Foo` +[accessible: true] `method ensuring(cond: accessibility.Foo => Boolean, msg: => Any)accessibility.Foo` +[accessible: true] `method eq(x$1: AnyRef)Boolean` +[accessible: true] `method equals(x$1: Any)Boolean` +[accessible: true] `method formatted(fmtstr: String)String` +[accessible: true] `method hashCode()Int` +[accessible: true] `method isInstanceOf[T0]=> Boolean` +[accessible: true] `method ne(x$1: AnyRef)Boolean` +[accessible: true] `method notify()Unit` +[accessible: true] `method notifyAll()Unit` +[accessible: true] `method secretPublic()Unit` +[accessible: true] `method someTests(other: accessibility.Foo)Unit` +[accessible: true] `method synchronized[T0](x$1: T0)T0` +[accessible: true] `method toString()String` +[accessible: true] `method wait()Unit` +[accessible: true] `method wait(x$1: Long)Unit` +[accessible: true] `method wait(x$1: Long, x$2: Int)Unit` +[accessible: true] `method x=> accessibility.Foo` +[accessible: true] `method →[B](y: B)(accessibility.Foo, B)` +[accessible: false] `method clone()Object` +[accessible: false] `method finalize()Unit` +[accessible: false] `method secretPrivate()Unit` +[accessible: false] `method secretPrivateThis()Unit` +[accessible: false] `method secretProtected()Unit` +[accessible: false] `method secretProtectedInPackage()Unit` +[accessible: false] `value __leftOfArrowaccessibility.Foo` +[accessible: false] `value __resultOfEnsuringaccessibility.Foo` +[accessible: false] `value selfAny` +================================================================================ diff --git a/test/files/presentation/visibility/Test.scala b/test/files/presentation/visibility/Test.scala new file mode 100644 index 0000000000..96e758d974 --- /dev/null +++ b/test/files/presentation/visibility/Test.scala @@ -0,0 +1,5 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest { + +} \ No newline at end of file diff --git a/test/files/presentation/visibility/src/Completions.scala b/test/files/presentation/visibility/src/Completions.scala new file mode 100644 index 0000000000..098b98a0fd --- /dev/null +++ b/test/files/presentation/visibility/src/Completions.scala @@ -0,0 +1,40 @@ +package accessibility { + + class Foo { + private def secretPrivate(): Unit = () + private[this] def secretPrivateThis(): Unit = () + + protected def secretProtected(): Unit + + protected[accessibility] def secretProtectedInPackage(): Unit + + def secretPublic(): Unit + + def someTests(other: Foo) { + other./*!*/secretPrivate // should be all but scretThis + + this./*!*/secretProtected // should hit five completions + } + } + + class AccessibilityChecks extends Foo { + def someTests { + this./*!*/ // should not list secretPrivate* + } + } + + class UnrelatedClass { + def someTests(foo: Foo) { + foo./*!*/ // should list public and protected[accessiblity] + } + } + +} + +package other { + class SomeChecsk { + def foo(o: accessibility.Foo) { + o./*!*/ // should only match secretPublic + } + } +} \ No newline at end of file -- cgit v1.2.3 From cf18d879d3f43d5a0c15c5c0af72f88c25605a08 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 30 Apr 2012 07:44:42 -0700 Subject: Optimization of Predef implicits. All those wildcards in a default-scoped implicit are expensive, they each lead to a typevar on every search. Restructured the Tuple2/Tuple3 Zipped classes, they're better this way anyway. This also gets all that Tuple[23] code out of genprod. --- src/build/genprod.scala | 224 +----------------------- src/compiler/scala/tools/cmd/gen/AnyVals.scala | 45 +++-- src/library/scala/Function0.scala | 2 +- src/library/scala/Predef.scala | 84 ++++----- src/library/scala/Tuple2.scala | 105 ----------- src/library/scala/Tuple3.scala | 120 ------------- src/library/scala/runtime/SeqCharSequence.scala | 25 +++ src/library/scala/runtime/Tuple2Zipped.scala | 130 ++++++++++++++ src/library/scala/runtime/Tuple3Zipped.scala | 141 +++++++++++++++ test/files/neg/t900.check | 4 +- test/files/run/tuple-zipped.scala | 4 +- tools/codegen | 2 +- 12 files changed, 364 insertions(+), 522 deletions(-) create mode 100644 src/library/scala/runtime/SeqCharSequence.scala create mode 100644 src/library/scala/runtime/Tuple2Zipped.scala create mode 100644 src/library/scala/runtime/Tuple3Zipped.scala (limited to 'src') diff --git a/src/build/genprod.scala b/src/build/genprod.scala index 5a77c7a699..8c91128de0 100644 --- a/src/build/genprod.scala +++ b/src/build/genprod.scala @@ -256,10 +256,7 @@ class Function(val i: Int) extends Group("Function") with Arity { zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz */ object Tuple { - val zipImports = """ -import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } -import scala.collection.generic.{ CanBuildFrom => CBF } -""" + val zipImports = "" def make(i: Int) = apply(i)() def apply(i: Int) = i match { @@ -285,230 +282,11 @@ object TupleTwo extends Tuple(2) * second element is the first element of this Tuple. */ def swap: Tuple2[T2,T1] = Tuple2(_2, _1) - - @deprecated("Use `zipped` instead.", "2.9.0") - def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], - w2: T2 => Iterable[El2], - cbf1: CBF[Repr1, (El1, El2), To]): To = { - zipped map ((x, y) => ((x, y))) - } - - /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. - * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] - * or [[scala.collection.IterableLike]]. - * {{{ - * scala> val tuple = (List(1,2,3),List('a','b','c')) - * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) - * - * scala> tuple.zipped map { (x,y) => x + ":" + y } - * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) - * }}} - * - * @see Zipped - * Note: will not terminate for infinite-sized collections. - */ - 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) - - 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) - b.sizeHint(coll1) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b += f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b ++= f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { - val b1 = cbf1(coll1.repr) - val b2 = cbf2(coll2.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - val el2 = elems2.next - if (f(el1, el2)) { - b1 += el1 - b2 += el2 - } - } - else return (b1.result, b2.result) - } - - (b1.result, b2.result) - } - - def exists(f: (El1, El2) => Boolean): Boolean = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - if (f(el1, elems2.next)) - return true - } - else return false - } - false - } - - def forall(f: (El1, El2) => Boolean): Boolean = - !exists((x, y) => !f(x, y)) - - def foreach[U](f: (El1, El2) => U): Unit = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - f(el1, elems2.next) - else - return - } - } - } """ } object TupleThree extends Tuple(3) { override def imports = Tuple.zipImports - override def moreMethods = """ - - @deprecated("Use `zipped` instead.", "2.9.0") - def zip[Repr1, El1, El2, El3, To](implicit w1: T1 => TLike[El1, Repr1], - w2: T2 => Iterable[El2], - w3: T3 => Iterable[El3], - cbf1: CBF[Repr1, (El1, El2, El3), To]): To = { - zipped map ((x, y, z) => ((x, y, z))) - } - - /** Wraps a tuple in a `Zipped`, which supports 3-ary generalisations of `map`, `flatMap`, `filter`, etc. - * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] - * or [[scala.collection.IterableLike]]. - * {{{ - * scala> val tuple = (List(1,2,3),List('a','b','c'),List("x","y","z")) - * tuple: (List[Int], List[Char], List[java.lang.String]) = (List(1, 2, 3),List(a, b, c),List(x, y, z)) - * - * scala> tuple.zipped map { (x,y,z) => x + ":" + y + ":" + z} - * res8: List[java.lang.String] = List(1:a:x, 2:b:y, 3:c:z) - * }}} - * - * @see Zipped - * Note: will not terminate for infinite-sized collections. - */ - def zipped[Repr1, El1, Repr2, El2, Repr3, El3](implicit w1: T1 => TLike[El1, Repr1], - w2: T2 => ILike[El2, Repr2], - w3: T3 => ILike[El3, Repr3]): Zipped[Repr1, El1, Repr2, El2, Repr3, El3] - = new Zipped[Repr1, El1, Repr2, El2, Repr3, El3](_1, _2, _3) - - class Zipped[+Repr1, +El1, +Repr2, +El2, +Repr3, +El3](coll1: TLike[El1, Repr1], - coll2: ILike[El2, Repr2], - coll3: ILike[El3, Repr3]) { - def map[B, To](f: (El1, El2, El3) => B)(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - val elems2 = coll2.iterator - val elems3 = coll3.iterator - - for (el1 <- coll1) { - if (elems2.hasNext && elems3.hasNext) - b += f(el1, elems2.next, elems3.next) - else - return b.result - } - b.result - } - - def flatMap[B, To](f: (El1, El2, El3) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - val elems2 = coll2.iterator - val elems3 = coll3.iterator - - for (el1 <- coll1) { - if (elems2.hasNext && elems3.hasNext) - b ++= f(el1, elems2.next, elems3.next) - else - return b.result - } - b.result - } - - def filter[To1, To2, To3](f: (El1, El2, El3) => Boolean)( - implicit cbf1: CBF[Repr1, El1, To1], - cbf2: CBF[Repr2, El2, To2], - cbf3: CBF[Repr3, El3, To3]): (To1, To2, To3) = { - val b1 = cbf1(coll1.repr) - val b2 = cbf2(coll2.repr) - val b3 = cbf3(coll3.repr) - val elems2 = coll2.iterator - val elems3 = coll3.iterator - def result = (b1.result, b2.result, b3.result) - - for (el1 <- coll1) { - if (elems2.hasNext && elems3.hasNext) { - val el2 = elems2.next - val el3 = elems3.next - - if (f(el1, el2, el3)) { - b1 += el1 - b2 += el2 - b3 += el3 - } - } - else return result - } - - result - } - - def exists(f: (El1, El2, El3) => Boolean): Boolean = { - val elems2 = coll2.iterator - val elems3 = coll3.iterator - - for (el1 <- coll1) { - if (elems2.hasNext && elems3.hasNext) { - if (f(el1, elems2.next, elems3.next)) - return true - } - else return false - } - false - } - - def forall(f: (El1, El2, El3) => Boolean): Boolean = - !exists((x, y, z) => !f(x, y, z)) - - def foreach[U](f: (El1, El2, El3) => U): Unit = { - val elems2 = coll2.iterator - val elems3 = coll3.iterator - - for (el1 <- coll1) { - if (elems2.hasNext && elems3.hasNext) - f(el1, elems2.next, elems3.next) - else - return - } - } - } -""" } class Tuple(val i: Int) extends Group("Tuple") with Arity { diff --git a/src/compiler/scala/tools/cmd/gen/AnyVals.scala b/src/compiler/scala/tools/cmd/gen/AnyVals.scala index e8230b8ca4..83cd9c2578 100644 --- a/src/compiler/scala/tools/cmd/gen/AnyVals.scala +++ b/src/compiler/scala/tools/cmd/gen/AnyVals.scala @@ -15,18 +15,27 @@ trait AnyValReps { case class Op(val op : String, val doc : String) - private def companionCoercions(tos: String*) = { + private def companionCoercions(tos: AnyValRep*) = { tos.toList map (to => - """implicit def %s2%s(x: %s): %s = x.to%s""".format(javaEquiv, to, name, to.capitalize, to.capitalize) + """implicit def @javaequiv@2%s(x: @name@): %s = x.to%s""".format(to.javaEquiv, to.name, to.name) ) } - 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 coercionCommentExtra = "" + def coercionComment = """ + /** Language mandated coercions from @name@ to "wider" types.%s + */""".format(coercionCommentExtra) + + def implicitCoercions: List[String] = { + val coercions = this match { + case B => companionCoercions(S, I, L, F, D) + case S | C => companionCoercions(I, L, F, D) + case I => companionCoercions(L, F, D) + case L => companionCoercions(F, D) + case F => companionCoercions(D) + case _ => Nil + } + if (coercions.isEmpty) Nil + else coercionComment :: coercions } def isCardinal: Boolean = isIntegerType(this) @@ -174,7 +183,7 @@ trait AnyValReps { } def objectLines = { val comp = if (isCardinal) cardinalCompanion else floatingCompanion - ((comp + allCompanions).trim.lines map interpolate).toList ++ implicitCoercions + (comp + allCompanions + "\n" + nonUnitCompanions).trim.lines.toList ++ implicitCoercions map interpolate } /** Makes a set of binary operations based on the given set of ops, args, and resultFn. @@ -238,8 +247,9 @@ trait AnyValReps { def classDoc = interpolate(classDocTemplate) def objectDoc = "" def mkImports = "" - def mkClass = assemble("final class", "private", "AnyVal", classLines) + "\n" - def mkObject = assemble("object", "", "AnyValCompanion", objectLines) + "\n" + + def mkClass = assemble("final class " + name + " private extends AnyVal", classLines) + def mkObject = assemble("object " + name + " extends AnyValCompanion", objectLines) def make() = List[String]( headerTemplate, mkImports, @@ -249,11 +259,10 @@ trait AnyValReps { mkObject ) mkString "" - 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") + def assemble(decl: String, lines: List[String]): String = { + val body = if (lines.isEmpty) " { }\n\n" else lines map indent mkString (" {\n", "\n", "\n}\n") - decl + body + decl + body + "\n" } override def toString = name } @@ -310,6 +319,8 @@ def unbox(x: java.lang.Object): @name@ = @unboxImpl@ override def toString = "object scala.@name@" """ + def nonUnitCompanions = "" // todo + def cardinalCompanion = """ /** The smallest value representable as a @name@. */ @@ -446,7 +457,7 @@ def ^(x: Boolean): Boolean = sys.error("stub") override def getClass(): Class[Boolean] = sys.error("stub") """.trim.lines.toList - def objectLines = interpolate(allCompanions).lines.toList + def objectLines = interpolate(allCompanions + "\n" + nonUnitCompanions).lines.toList } object U extends AnyValRep("Unit", None, "void") { override def classDoc = """ diff --git a/src/library/scala/Function0.scala b/src/library/scala/Function0.scala index e1e9ddb3fb..3690a0e65b 100644 --- a/src/library/scala/Function0.scala +++ b/src/library/scala/Function0.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ // GENERATED CODE: DO NOT EDIT. -// genprod generated these sources at: Sat Apr 28 12:59:55 PDT 2012 +// genprod generated these sources at: Mon Apr 30 07:46:11 PDT 2012 package scala diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index b84fcc4126..9eb1e6a11b 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -307,42 +307,36 @@ object Predef extends LowPriorityImplicits { // views -------------------------------------------------------------- - implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc) - - implicit def zipped2ToTraversable[El1, El2](zz: Tuple2[_, _]#Zipped[_, El1, _, El2]): Traversable[(El1, El2)] = - new collection.AbstractTraversable[(El1, El2)] { - def foreach[U](f: ((El1, El2)) => U): Unit = zz foreach Function.untupled(f) - } - - implicit def zipped3ToTraversable[El1, El2, El3](zz: Tuple3[_, _, _]#Zipped[_, El1, _, El2, _, El3]): Traversable[(El1, El2, El3)] = - new collection.AbstractTraversable[(El1, El2, El3)] { - def foreach[U](f: ((El1, El2, El3)) => U): Unit = zz foreach Function.untupled(f) - } - - implicit def genericArrayOps[T](xs: Array[T]): ArrayOps[T] = xs match { - case x: Array[AnyRef] => refArrayOps[AnyRef](x).asInstanceOf[ArrayOps[T]] - case x: Array[Int] => intArrayOps(x).asInstanceOf[ArrayOps[T]] - case x: Array[Double] => doubleArrayOps(x).asInstanceOf[ArrayOps[T]] - case x: Array[Long] => longArrayOps(x).asInstanceOf[ArrayOps[T]] - case x: Array[Float] => floatArrayOps(x).asInstanceOf[ArrayOps[T]] - case x: Array[Char] => charArrayOps(x).asInstanceOf[ArrayOps[T]] - case x: Array[Byte] => byteArrayOps(x).asInstanceOf[ArrayOps[T]] - case x: Array[Short] => shortArrayOps(x).asInstanceOf[ArrayOps[T]] - case x: Array[Boolean] => booleanArrayOps(x).asInstanceOf[ArrayOps[T]] - case x: Array[Unit] => unitArrayOps(x).asInstanceOf[ArrayOps[T]] + implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc) + implicit def tuple2ToZippedOps[T1, T2](x: (T1, T2)) = new runtime.Tuple2Zipped.Ops(x) + implicit def tuple3ToZippedOps[T1, T2, T3](x: (T1, T2, T3)) = new runtime.Tuple3Zipped.Ops(x) + implicit def seqToCharSequence(xs: collection.IndexedSeq[Char]): CharSequence = new runtime.SeqCharSequence(xs) + implicit def arrayToCharSequence(xs: Array[Char]): CharSequence = new runtime.ArrayCharSequence(xs) + + implicit def genericArrayOps[T](xs: Array[T]): ArrayOps[T] = (xs match { + case x: Array[AnyRef] => refArrayOps[AnyRef](x) + case x: Array[Boolean] => booleanArrayOps(x) + case x: Array[Byte] => byteArrayOps(x) + case x: Array[Char] => charArrayOps(x) + case x: Array[Double] => doubleArrayOps(x) + case x: Array[Float] => floatArrayOps(x) + case x: Array[Int] => intArrayOps(x) + case x: Array[Long] => longArrayOps(x) + case x: Array[Short] => shortArrayOps(x) + case x: Array[Unit] => unitArrayOps(x) case null => null - } + }).asInstanceOf[ArrayOps[T]] - implicit def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps.ofRef[T](xs) - implicit def intArrayOps(xs: Array[Int]): ArrayOps[Int] = new ArrayOps.ofInt(xs) - implicit def doubleArrayOps(xs: Array[Double]): ArrayOps[Double] = new ArrayOps.ofDouble(xs) - implicit def longArrayOps(xs: Array[Long]): ArrayOps[Long] = new ArrayOps.ofLong(xs) - implicit def floatArrayOps(xs: Array[Float]): ArrayOps[Float] = new ArrayOps.ofFloat(xs) - implicit def charArrayOps(xs: Array[Char]): ArrayOps[Char] = new ArrayOps.ofChar(xs) - implicit def byteArrayOps(xs: Array[Byte]): ArrayOps[Byte] = new ArrayOps.ofByte(xs) - implicit def shortArrayOps(xs: Array[Short]): ArrayOps[Short] = new ArrayOps.ofShort(xs) implicit def booleanArrayOps(xs: Array[Boolean]): ArrayOps[Boolean] = new ArrayOps.ofBoolean(xs) - implicit def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps.ofUnit(xs) + implicit def byteArrayOps(xs: Array[Byte]): ArrayOps[Byte] = new ArrayOps.ofByte(xs) + implicit def charArrayOps(xs: Array[Char]): ArrayOps[Char] = new ArrayOps.ofChar(xs) + implicit def doubleArrayOps(xs: Array[Double]): ArrayOps[Double] = new ArrayOps.ofDouble(xs) + implicit def floatArrayOps(xs: Array[Float]): ArrayOps[Float] = new ArrayOps.ofFloat(xs) + implicit def intArrayOps(xs: Array[Int]): ArrayOps[Int] = new ArrayOps.ofInt(xs) + implicit def longArrayOps(xs: Array[Long]): ArrayOps[Long] = new ArrayOps.ofLong(xs) + implicit def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps.ofRef[T](xs) + implicit def shortArrayOps(xs: Array[Short]): ArrayOps[Short] = new ArrayOps.ofShort(xs) + implicit def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps.ofUnit(xs) // Primitive Widenings -------------------------------------------------------------- @@ -406,29 +400,17 @@ object Predef extends LowPriorityImplicits { // Strings and CharSequences -------------------------------------------------------------- - implicit def any2stringadd(x: Any) = new runtime.StringAdd(x) @inline implicit def any2stringfmt(x: Any) = new runtime.StringFormat(x) @inline implicit def augmentString(x: String): StringOps = new StringOps(x) + implicit def any2stringadd(x: Any) = new runtime.StringAdd(x) implicit def unaugmentString(x: StringOps): String = x.repr - implicit def stringCanBuildFrom: CanBuildFrom[String, Char, String] = - new CanBuildFrom[String, Char, String] { - def apply(from: String) = apply() - def apply() = mutable.StringBuilder.newBuilder - } - - implicit def seqToCharSequence(xs: collection.IndexedSeq[Char]): CharSequence = new CharSequence { - def length: Int = xs.length - def charAt(index: Int): Char = xs(index) - def subSequence(start: Int, end: Int): CharSequence = seqToCharSequence(xs.slice(start, end)) - override def toString: String = xs.mkString("") - } + @deprecated("Use StringCanBuildFrom", "2.10.0") + def stringCanBuildFrom: CanBuildFrom[String, Char, String] = StringCanBuildFrom - implicit def arrayToCharSequence(xs: Array[Char]): CharSequence = new CharSequence { - def length: Int = xs.length - def charAt(index: Int): Char = xs(index) - def subSequence(start: Int, end: Int): CharSequence = arrayToCharSequence(xs.slice(start, end)) - override def toString: String = xs.mkString("") + implicit val StringCanBuildFrom: CanBuildFrom[String, Char, String] = new CanBuildFrom[String, Char, String] { + def apply(from: String) = apply() + def apply() = mutable.StringBuilder.newBuilder } // Type Constraints -------------------------------------------------------------- diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 58638f440f..5e77127080 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -9,9 +9,6 @@ package scala -import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } -import scala.collection.generic.{ CanBuildFrom => CBF } - /** A tuple of 2 elements; the canonical representation of a [[scala.Product2]]. * @@ -30,106 +27,4 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s */ def swap: Tuple2[T2,T1] = Tuple2(_2, _1) - @deprecated("Use `zipped` instead.", "2.9.0") - @annotation.unspecialized - def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], - w2: T2 => Iterable[El2], - cbf1: CBF[Repr1, (El1, El2), To]): To = { - zipped map ((x, y) => ((x, y))) - } - - /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. - * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] - * or [[scala.collection.IterableLike]]. - * {{{ - * scala> val tuple = (List(1,2,3),List('a','b','c')) - * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) - * - * scala> tuple.zipped map { (x,y) => x + ":" + y } - * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) - * }}} - * - * @see Zipped - * Note: will not terminate for infinite-sized collections. - */ - 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) - - 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) - b.sizeHint(coll1) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b += f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b ++= f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { - val b1 = cbf1(coll1.repr) - val b2 = cbf2(coll2.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - val el2 = elems2.next - if (f(el1, el2)) { - b1 += el1 - b2 += el2 - } - } - else return (b1.result, b2.result) - } - - (b1.result, b2.result) - } - - def exists(f: (El1, El2) => Boolean): Boolean = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - if (f(el1, elems2.next)) - return true - } - else return false - } - false - } - - def forall(f: (El1, El2) => Boolean): Boolean = - !exists((x, y) => !f(x, y)) - - def foreach[U](f: (El1, El2) => U): Unit = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - f(el1, elems2.next) - else - return - } - } - } - } diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index 0d5399308b..5ed13602e3 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -9,9 +9,6 @@ package scala -import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } -import scala.collection.generic.{ CanBuildFrom => CBF } - /** A tuple of 3 elements; the canonical representation of a [[scala.Product3]]. * @@ -25,121 +22,4 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: 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], - w2: T2 => Iterable[El2], - w3: T3 => Iterable[El3], - cbf1: CBF[Repr1, (El1, El2, El3), To]): To = { - zipped map ((x, y, z) => ((x, y, z))) - } - - /** Wraps a tuple in a `Zipped`, which supports 3-ary generalisations of `map`, `flatMap`, `filter`, etc. - * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] - * or [[scala.collection.IterableLike]]. - * {{{ - * scala> val tuple = (List(1,2,3),List('a','b','c'),List("x","y","z")) - * tuple: (List[Int], List[Char], List[java.lang.String]) = (List(1, 2, 3),List(a, b, c),List(x, y, z)) - * - * scala> tuple.zipped map { (x,y,z) => x + ":" + y + ":" + z} - * res8: List[java.lang.String] = List(1:a:x, 2:b:y, 3:c:z) - * }}} - * - * @see Zipped - * Note: will not terminate for infinite-sized collections. - */ - def zipped[Repr1, El1, Repr2, El2, Repr3, El3](implicit w1: T1 => TLike[El1, Repr1], - w2: T2 => ILike[El2, Repr2], - w3: T3 => ILike[El3, Repr3]): Zipped[Repr1, El1, Repr2, El2, Repr3, El3] - = new Zipped[Repr1, El1, Repr2, El2, Repr3, El3](_1, _2, _3) - - class Zipped[+Repr1, +El1, +Repr2, +El2, +Repr3, +El3](coll1: TLike[El1, Repr1], - coll2: ILike[El2, Repr2], - coll3: ILike[El3, Repr3]) { - def map[B, To](f: (El1, El2, El3) => B)(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - val elems2 = coll2.iterator - val elems3 = coll3.iterator - - for (el1 <- coll1) { - if (elems2.hasNext && elems3.hasNext) - b += f(el1, elems2.next, elems3.next) - else - return b.result - } - b.result - } - - def flatMap[B, To](f: (El1, El2, El3) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - val elems2 = coll2.iterator - val elems3 = coll3.iterator - - for (el1 <- coll1) { - if (elems2.hasNext && elems3.hasNext) - b ++= f(el1, elems2.next, elems3.next) - else - return b.result - } - b.result - } - - def filter[To1, To2, To3](f: (El1, El2, El3) => Boolean)( - implicit cbf1: CBF[Repr1, El1, To1], - cbf2: CBF[Repr2, El2, To2], - cbf3: CBF[Repr3, El3, To3]): (To1, To2, To3) = { - val b1 = cbf1(coll1.repr) - val b2 = cbf2(coll2.repr) - val b3 = cbf3(coll3.repr) - val elems2 = coll2.iterator - val elems3 = coll3.iterator - def result = (b1.result, b2.result, b3.result) - - for (el1 <- coll1) { - if (elems2.hasNext && elems3.hasNext) { - val el2 = elems2.next - val el3 = elems3.next - - if (f(el1, el2, el3)) { - b1 += el1 - b2 += el2 - b3 += el3 - } - } - else return result - } - - result - } - - def exists(f: (El1, El2, El3) => Boolean): Boolean = { - val elems2 = coll2.iterator - val elems3 = coll3.iterator - - for (el1 <- coll1) { - if (elems2.hasNext && elems3.hasNext) { - if (f(el1, elems2.next, elems3.next)) - return true - } - else return false - } - false - } - - def forall(f: (El1, El2, El3) => Boolean): Boolean = - !exists((x, y, z) => !f(x, y, z)) - - def foreach[U](f: (El1, El2, El3) => U): Unit = { - val elems2 = coll2.iterator - val elems3 = coll3.iterator - - for (el1 <- coll1) { - if (elems2.hasNext && elems3.hasNext) - f(el1, elems2.next, elems3.next) - else - return - } - } - } - } diff --git a/src/library/scala/runtime/SeqCharSequence.scala b/src/library/scala/runtime/SeqCharSequence.scala new file mode 100644 index 0000000000..7f7bca789f --- /dev/null +++ b/src/library/scala/runtime/SeqCharSequence.scala @@ -0,0 +1,25 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.runtime + +import java.util.Arrays.copyOfRange + +final class SeqCharSequence(val xs: collection.IndexedSeq[Char]) extends CharSequence { + def length: Int = xs.length + def charAt(index: Int): Char = xs(index) + def subSequence(start: Int, end: Int): CharSequence = new SeqCharSequence(xs.slice(start, end)) + override def toString = xs.mkString("") +} + +final class ArrayCharSequence(val xs: Array[Char]) extends CharSequence { + def length: Int = xs.length + def charAt(index: Int): Char = xs(index) + def subSequence(start: Int, end: Int): CharSequence = new ArrayCharSequence(copyOfRange(xs, math.max(0, start), math.min(xs.length, end))) + override def toString = xs.mkString("") +} diff --git a/src/library/scala/runtime/Tuple2Zipped.scala b/src/library/scala/runtime/Tuple2Zipped.scala new file mode 100644 index 0000000000..5ad364c8a5 --- /dev/null +++ b/src/library/scala/runtime/Tuple2Zipped.scala @@ -0,0 +1,130 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.runtime + +import scala.collection.{ TraversableLike, IterableLike } +import scala.collection.generic.{ CanBuildFrom => CBF } + +/** This interface is intended as a minimal interface, not complicated + * by the requirement to resolve type constructors, for implicit search (which only + * needs to find an implicit conversion to Traversable for our purposes.) + */ +trait ZippedTraversable2[+El1, +El2] { + def foreach[U](f: (El1, El2) => U): Unit +} +object ZippedTraversable2 { + implicit def zippedTraversable2ToTraversable[El1, El2](zz: ZippedTraversable2[El1, El2]): Traversable[(El1, El2)] = { + new collection.AbstractTraversable[(El1, El2)] { + def foreach[U](f: ((El1, El2)) => U): Unit = zz foreach Function.untupled(f) + } + } +} + +class Tuple2Zipped[El1, Repr1, El2, Repr2]( + coll1: TraversableLike[El1, Repr1], + coll2: IterableLike[El2, Repr2] +) extends ZippedTraversable2[El1, El2] { + def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + b.sizeHint(coll1) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b += f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b ++= f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { + val b1 = cbf1(coll1.repr) + val b2 = cbf2(coll2.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + val el2 = elems2.next + if (f(el1, el2)) { + b1 += el1 + b2 += el2 + } + } + else return (b1.result, b2.result) + } + + (b1.result, b2.result) + } + + def exists(f: (El1, El2) => Boolean): Boolean = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + if (f(el1, elems2.next)) + return true + } + else return false + } + false + } + + def forall(f: (El1, El2) => Boolean): Boolean = + !exists((x, y) => !f(x, y)) + + def foreach[U](f: (El1, El2) => U): Unit = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + f(el1, elems2.next) + else + return + } + } +} + +object Tuple2Zipped { + class Ops[T1, T2](x: (T1, T2)) { + def invert[El1, CC1[X] <: TraversableOnce[X], El2, CC2[X] <: TraversableOnce[X], That] + (implicit w1: T1 <:< CC1[El1], + w2: T2 <:< CC2[El2], + bf: collection.generic.CanBuildFrom[CC1[_], (El1, El2), That] + ): That = { + val buf = bf(x._1) + val it1 = x._1.toIterator + val it2 = x._2.toIterator + while (it1.hasNext && it2.hasNext) + buf += ((it1.next, it2.next)) + + buf.result + } + + def zipped[El1, Repr1, El2, Repr2] + (implicit w1: T1 => TraversableLike[El1, Repr1], + w2: T2 => IterableLike[El2, Repr2] + ): Tuple2Zipped[El1, Repr1, El2, Repr2] = new Tuple2Zipped(x._1, x._2) + } +} diff --git a/src/library/scala/runtime/Tuple3Zipped.scala b/src/library/scala/runtime/Tuple3Zipped.scala new file mode 100644 index 0000000000..4e9c542c58 --- /dev/null +++ b/src/library/scala/runtime/Tuple3Zipped.scala @@ -0,0 +1,141 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.runtime + +import scala.collection.{ TraversableLike, IterableLike } +import scala.collection.generic.{ CanBuildFrom => CBF } + +/** See comment on ZippedTraversable2. */ +trait ZippedTraversable3[+El1, +El2, +El3] { + def foreach[U](f: (El1, El2, El3) => U): Unit +} +object ZippedTraversable3 { + implicit def zippedTraversable3ToTraversable[El1, El2, El3](zz: ZippedTraversable3[El1, El2, El3]): Traversable[(El1, El2, El3)] = { + new collection.AbstractTraversable[(El1, El2, El3)] { + def foreach[U](f: ((El1, El2, El3)) => U): Unit = zz foreach Function.untupled(f) + } + } +} + +class Tuple3Zipped[El1, Repr1, El2, Repr2, El3, Repr3]( + coll1: TraversableLike[El1, Repr1], + coll2: IterableLike[El2, Repr2], + coll3: IterableLike[El3, Repr3] +) extends ZippedTraversable3[El1, El2, El3] { + def map[B, To](f: (El1, El2, El3) => B)(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for (el1 <- coll1) { + if (elems2.hasNext && elems3.hasNext) + b += f(el1, elems2.next, elems3.next) + else + return b.result + } + b.result + } + + def flatMap[B, To](f: (El1, El2, El3) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for (el1 <- coll1) { + if (elems2.hasNext && elems3.hasNext) + b ++= f(el1, elems2.next, elems3.next) + else + return b.result + } + b.result + } + + def filter[To1, To2, To3](f: (El1, El2, El3) => Boolean)( + implicit cbf1: CBF[Repr1, El1, To1], + cbf2: CBF[Repr2, El2, To2], + cbf3: CBF[Repr3, El3, To3]): (To1, To2, To3) = { + val b1 = cbf1(coll1.repr) + val b2 = cbf2(coll2.repr) + val b3 = cbf3(coll3.repr) + val elems2 = coll2.iterator + val elems3 = coll3.iterator + def result = (b1.result, b2.result, b3.result) + + for (el1 <- coll1) { + if (elems2.hasNext && elems3.hasNext) { + val el2 = elems2.next + val el3 = elems3.next + + if (f(el1, el2, el3)) { + b1 += el1 + b2 += el2 + b3 += el3 + } + } + else return result + } + + result + } + + def exists(f: (El1, El2, El3) => Boolean): Boolean = { + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for (el1 <- coll1) { + if (elems2.hasNext && elems3.hasNext) { + if (f(el1, elems2.next, elems3.next)) + return true + } + else return false + } + false + } + + def forall(f: (El1, El2, El3) => Boolean): Boolean = + !exists((x, y, z) => !f(x, y, z)) + + def foreach[U](f: (El1, El2, El3) => U): Unit = { + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for (el1 <- coll1) { + if (elems2.hasNext && elems3.hasNext) + f(el1, elems2.next, elems3.next) + else + return + } + } +} + +object Tuple3Zipped { + class Ops[T1, T2, T3](x: (T1, T2, T3)) { + def invert[El1, CC1[X] <: TraversableOnce[X], El2, CC2[X] <: TraversableOnce[X], El3, CC3[X] <: TraversableOnce[X], That] + (implicit w1: T1 <:< CC1[El1], + w2: T2 <:< CC2[El2], + w3: T3 <:< CC3[El3], + bf: collection.generic.CanBuildFrom[CC1[_], (El1, El2, El3), That] + ): That = { + val buf = bf(x._1) + val it1 = x._1.toIterator + val it2 = x._2.toIterator + val it3 = x._3.toIterator + while (it1.hasNext && it2.hasNext && it3.hasNext) + buf += ((it1.next, it2.next, it3.next)) + + buf.result + } + + def zipped[El1, Repr1, El2, Repr2, El3, Repr3] + (implicit w1: T1 => TraversableLike[El1, Repr1], + w2: T2 => IterableLike[El2, Repr2], + w3: T3 => IterableLike[El3, Repr3] + ): Tuple3Zipped[El1, Repr1, El2, Repr2, El3, Repr3] = new Tuple3Zipped(x._1, x._2, x._3) + } +} diff --git a/test/files/neg/t900.check b/test/files/neg/t900.check index 047094ad6e..4611ceba8c 100644 --- a/test/files/neg/t900.check +++ b/test/files/neg/t900.check @@ -2,8 +2,8 @@ t900.scala:4: error: type mismatch; found : Foo.this.x.type (with underlying type Foo.this.bar) required: AnyRef Note that implicit conversions are not applicable because they are ambiguous: - both method any2stringadd in object Predef of type (x: Any)scala.runtime.StringAdd - and method any2stringfmt in object Predef of type (x: Any)scala.runtime.StringFormat + both method any2stringfmt in object Predef of type (x: Any)scala.runtime.StringFormat + and method any2stringadd in object Predef of type (x: Any)scala.runtime.StringAdd are possible conversion functions from Foo.this.x.type to AnyRef def break(): x.type ^ diff --git a/test/files/run/tuple-zipped.scala b/test/files/run/tuple-zipped.scala index a9851346bc..b197183844 100644 --- a/test/files/run/tuple-zipped.scala +++ b/test/files/run/tuple-zipped.scala @@ -15,14 +15,14 @@ object Test { def main(args: Array[String]): Unit = { for (cc1 <- xss1 ; cc2 <- xss2) { - val sum1 = (cc1, cc2).zip map { case (x, y) => x + y } sum + val sum1 = (cc1, cc2).zipped map { case (x, y) => x + y } sum val sum2 = (cc1, cc2).zipped map (_ + _) sum assert(sum1 == sum2) } for (cc1 <- xss1 ; cc2 <- xss2 ; cc3 <- xss3) { - val sum1 = (cc1, cc2, cc3).zip map { case (x, y, z) => x + y + z } sum + val sum1 = (cc1, cc2, cc3).zipped map { case (x, y, z) => x + y + z } sum val sum2 = (cc1, cc2, cc3).zipped map (_ + _ + _) sum assert(sum1 == sum2) diff --git a/tools/codegen b/tools/codegen index 734235aef8..35c93fba16 100755 --- a/tools/codegen +++ b/tools/codegen @@ -3,6 +3,6 @@ THISDIR=`dirname $0` SCALALIB=$THISDIR/../src/library/scala -BINDIR=$THISDIR/../build/pack/bin +BINDIR=$THISDIR/../build/quick/bin $BINDIR/scala scala.tools.cmd.gen.Codegen "$@" -- cgit v1.2.3 From 1d7430c7d574f02ea88ed8e1b5394e8986be5618 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 30 Apr 2012 09:22:12 -0700 Subject: De-duplication in Contexts. Friends don't let friends cut and paste. --- .../scala/tools/nsc/typechecker/Contexts.scala | 26 ++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 4584ba032d..0924789948 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -354,32 +354,30 @@ trait Contexts { self: Analyzer => private def unitError(pos: Position, msg: String) = unit.error(pos, if (checking) "\n**** ERROR DURING INTERNAL CHECKING ****\n" + msg else msg) - - def issue(err: AbsTypeError) { + + @inline private def issueCommon(err: AbsTypeError)(pf: PartialFunction[AbsTypeError, Unit]) { debugwarn("issue error: " + err.errMsg) if (settings.Yissuedebug.value) (new Exception).printStackTrace() - if (reportErrors) unitError(err.errPos, addDiagString(err.errMsg)) + if (pf isDefinedAt err) pf(err) else if (bufferErrors) { buffer += err } else throw new TypeError(err.errPos, err.errMsg) } + def issue(err: AbsTypeError) { + issueCommon(err) { case _ if reportErrors => + unitError(err.errPos, addDiagString(err.errMsg)) + } + } + 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) { + issueCommon(err) { case _ if ambiguousErrors => if (!pre.isErroneous && !sym1.isErroneous && !sym2.isErroneous) unitError(err.errPos, err.errMsg) - } else if (bufferErrors) { buffer += err } - else throw new TypeError(err.errPos, err.errMsg) + } } 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 } - else throw new TypeError(err.errPos, err.errMsg) + issueCommon(err) { case _ if ambiguousErrors => unitError(err.errPos, addDiagString(err.errMsg)) } } // TODO remove -- cgit v1.2.3