Skip to content

Commit 019c7aa

Browse files
author
Adriaan Moors
committed
Merge pull request scala#607 from paulp/may22-checkin
tests and misc improvements
2 parents c28a858 + f026bbb commit 019c7aa

26 files changed

+378
-113
lines changed

src/compiler/scala/reflect/internal/InfoTransformers.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ trait InfoTransformers {
2020
def transform(sym: Symbol, tpe: Type): Type
2121

2222
def insert(that: InfoTransformer) {
23-
assert(this.pid != that.pid)
23+
assert(this.pid != that.pid, this.pid)
24+
2425
if (that.pid < this.pid) {
2526
prev insert that
2627
} else if (next.pid <= that.pid && next.pid != NoPhase.id) {
2728
next insert that
2829
} else {
30+
log("Inserting info transformer %s following %s".format(phaseOf(that.pid), phaseOf(this.pid)))
2931
that.next = next
3032
that.prev = this
3133
next.prev = that

src/compiler/scala/reflect/internal/Phase.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ package scala.reflect
77
package internal
88

99
abstract class Phase(val prev: Phase) {
10+
if ((prev ne null) && (prev ne NoPhase))
11+
prev.nx = this
1012

1113
type Id = Int
12-
1314
val id: Id = if (prev eq null) 0 else prev.id + 1
1415

1516
/** New flags visible after this phase has completed */
@@ -18,12 +19,13 @@ abstract class Phase(val prev: Phase) {
1819
/** New flags visible once this phase has started */
1920
def newFlags: Long = 0l
2021

21-
private var fmask: Long =
22-
if (prev eq null) Flags.InitialFlags else prev.flagMask | prev.nextFlags | newFlags
22+
val fmask = (
23+
if (prev eq null) Flags.InitialFlags
24+
else prev.flagMask | prev.nextFlags | newFlags
25+
)
2326
def flagMask: Long = fmask
2427

2528
private var nx: Phase = this
26-
if ((prev ne null) && (prev ne NoPhase)) prev.nx = this
2729

2830
def next: Phase = nx
2931
def hasNext = next != this

src/compiler/scala/reflect/internal/util/Origins.scala

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ import Origins._
1515
* You could do this:
1616
*
1717
* {{{
18-
* private lazy val origins = Origins[SymbolTable]("phase_=")
18+
* private lazy val origins = Origins("arbitraryTag")
1919
* // Commented out original enclosed for contrast
2020
* // final def phase_=(p: Phase): Unit = {
2121
* final def phase_=(p: Phase): Unit = origins {
2222
* }}}
2323
*
2424
* And that's it. When the JVM exits it would issue a report something like this:
2525
{{{
26-
>> Origins scala.tools.nsc.symtab.SymbolTable.phase_= logged 145585 calls from 51 distinguished sources.
26+
>> Origins tag 'arbitraryTag' logged 145585 calls from 51 distinguished sources.
2727
2828
71114 scala.tools.nsc.symtab.Symbols$Symbol.unsafeTypeParams(Symbols.scala:862)
2929
16584 scala.tools.nsc.symtab.Symbols$Symbol.rawInfo(Symbols.scala:757)
@@ -37,37 +37,29 @@ import Origins._
3737
*/
3838
abstract class Origins {
3939
type Rep
40+
type StackSlice = Array[StackTraceElement]
41+
42+
def tag: String
43+
def isCutoff(el: StackTraceElement): Boolean
4044
def newRep(xs: StackSlice): Rep
4145
def repString(rep: Rep): String
42-
def originClass: String
43-
44-
private var _tag: String = null
45-
def tag: String = _tag
46-
def setTag(tag: String): this.type = {
47-
_tag = tag
48-
this
49-
}
5046

5147
private val origins = new mutable.HashMap[Rep, Int] withDefaultValue 0
5248
private def add(xs: Rep) = origins(xs) += 1
5349
private def total = origins.values.foldLeft(0L)(_ + _)
5450

55-
// We find the right line by dropping any from around here and any
56-
// from the method's origin class.
57-
private def dropStackElement(cn: String) =
58-
(cn startsWith OriginsName) || (cn startsWith originClass)
59-
6051
// Create a stack and whittle it down to the interesting part.
61-
private def readStack(): Array[StackTraceElement] =
62-
(new Throwable).getStackTrace dropWhile (el => dropStackElement(el.getClassName))
52+
def readStack(): Array[StackTraceElement] = (
53+
Thread.currentThread.getStackTrace dropWhile (x => !isCutoff(x)) dropWhile isCutoff drop 1
54+
)
6355

6456
def apply[T](body: => T): T = {
6557
add(newRep(readStack()))
6658
body
6759
}
6860
def clear() = origins.clear()
6961
def show() = {
70-
println("\n>> Origins %s.%s logged %s calls from %s distinguished sources.\n".format(originClass, tag, total, origins.keys.size))
62+
println("\n>> Origins tag '%s' logged %s calls from %s distinguished sources.\n".format(tag, total, origins.keys.size))
7163
origins.toList sortBy (-_._2) foreach {
7264
case (k, v) => println("%7s %s".format(v, repString(k)))
7365
}
@@ -79,29 +71,49 @@ abstract class Origins {
7971
}
8072

8173
object Origins {
82-
private type StackSlice = Array[StackTraceElement]
83-
private val OriginsName = classOf[Origins].getName
84-
private val counters = new mutable.HashSet[Origins]
74+
private val counters = mutable.HashMap[String, Origins]()
75+
private val thisClass = this.getClass.getName
8576

86-
{
87-
// Console.println("\nOrigins loaded: registering shutdown hook to display results.")
88-
sys.addShutdownHook(counters foreach (_.purge()))
77+
locally {
78+
sys.addShutdownHook(counters.values foreach (_.purge()))
8979
}
9080

91-
def apply[T: ClassTag](tag: String): Origins = apply(tag, classTag[T].erasure)
92-
def apply(tag: String, clazz: Class[_]): Origins = apply(tag, new OneLine(clazz))
93-
def apply(tag: String, orElse: => Origins): Origins = {
94-
counters find (_.tag == tag) getOrElse {
95-
val res = orElse setTag tag
96-
counters += res
97-
res
98-
}
81+
case class OriginId(className: String, methodName: String) {
82+
def matches(el: StackTraceElement) = (
83+
(methodName == el.getMethodName) && (className startsWith el.getClassName)
84+
)
9985
}
10086

101-
class OneLine(clazz: Class[_]) extends Origins {
102-
type Rep = StackTraceElement
103-
val originClass = clazz.getName stripSuffix MODULE_SUFFIX_STRING
104-
def newRep(xs: StackSlice): Rep = xs(0)
105-
def repString(rep: Rep) = " " + rep
87+
def lookup(tag: String, orElse: String => Origins): Origins =
88+
counters.getOrElseUpdate(tag, orElse(tag))
89+
def register(x: Origins): Origins = {
90+
counters(x.tag) = x
91+
x
92+
}
93+
94+
private def preCutoff(el: StackTraceElement) = (
95+
(el.getClassName == thisClass)
96+
|| (el.getClassName startsWith "java.lang.")
97+
)
98+
private def findCutoff() = {
99+
val cutoff = Thread.currentThread.getStackTrace dropWhile preCutoff head;
100+
OriginId(cutoff.getClassName, cutoff.getMethodName)
101+
}
102+
103+
def apply(tag: String): Origins = counters.getOrElseUpdate(tag, new OneLine(tag, findCutoff()))
104+
def apply(tag: String, frames: Int): Origins = counters.getOrElseUpdate(tag, new MultiLine(tag, findCutoff(), frames))
105+
106+
class OneLine(val tag: String, id: OriginId) extends Origins {
107+
type Rep = StackTraceElement
108+
def isCutoff(el: StackTraceElement) = id matches el
109+
def newRep(xs: StackSlice): Rep = if ((xs eq null) || (xs.length == 0)) null else xs(0)
110+
def repString(rep: Rep) = " " + rep
111+
}
112+
class MultiLine(val tag: String, id: OriginId, numLines: Int) extends Origins {
113+
type Rep = List[StackTraceElement]
114+
def isCutoff(el: StackTraceElement) = id matches el
115+
def newRep(xs: StackSlice): Rep = (xs take numLines).toList
116+
def repString(rep: Rep) = rep.map("\n " + _).mkString
117+
override def readStack() = super.readStack() drop 1
106118
}
107119
}

src/compiler/scala/tools/nsc/ast/TreeGen.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
208208
else AppliedTypeTree(Ident(clazz), targs map TypeTree)
209209
))
210210
}
211+
def mkSuperSelect = Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
211212

212213
def wildcardStar(tree: Tree) =
213214
atPos(tree.pos) { Typed(tree, Ident(tpnme.WILDCARD_STAR)) }

src/compiler/scala/tools/nsc/ast/Trees.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
115115
// convert (implicit ... ) to ()(implicit ... ) if its the only parameter section
116116
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
117117
vparamss1 = List() :: vparamss1;
118-
val superRef: Tree = atPos(superPos) {
119-
Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
120-
}
118+
val superRef: Tree = atPos(superPos)(gen.mkSuperSelect)
121119
val superCall = (superRef /: argss) (Apply)
122120
List(
123121
atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (

src/compiler/scala/tools/nsc/ast/parser/Parsers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ self =>
385385
Nil,
386386
List(Nil),
387387
TypeTree(),
388-
Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), Nil)), Literal(Constant(())))
388+
Block(List(Apply(gen.mkSuperSelect, Nil)), Literal(Constant(())))
389389
)
390390

391391
// def main

src/compiler/scala/tools/nsc/transform/AddInterfaces.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
308308
// body until now, because the typer knows that Any has no
309309
// constructor and won't accept a call to super.init.
310310
assert((clazz isSubClass AnyValClass) || clazz.info.parents.isEmpty, clazz)
311-
val superCall = Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), Nil)
312-
Block(List(superCall), expr)
311+
Block(List(Apply(gen.mkSuperSelect, Nil)), expr)
313312

314313
case Block(stats, expr) =>
315314
// needs `hasSymbol` check because `supercall` could be a block (named / default args)

src/compiler/scala/tools/nsc/transform/InfoTransform.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ trait InfoTransform extends Transform {
3737
val changesBaseClasses = InfoTransform.this.changesBaseClasses
3838
def transform(sym: Symbol, tpe: Type): Type = transformInfo(sym, tpe)
3939
}
40-
infoTransformers.insert(infoTransformer)
40+
infoTransformers insert infoTransformer
4141
}
4242
}
4343
}

src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,26 +1388,23 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
13881388
tree
13891389

13901390
case Select(qual, name) =>
1391-
debuglog("[%s] looking at Select: %s sym: %s: %s [tree.tpe: %s]".format(
1392-
tree.pos.safeLine, tree, symbol, symbol.info, tree.tpe))
1391+
debuglog("specializing Select %s [tree.tpe: %s]".format(symbol.defString, tree.tpe))
13931392

13941393
//log("!!! select " + tree + " -> " + symbol.info + " specTypeVars: " + specializedTypeVars(symbol.info))
13951394
if (specializedTypeVars(symbol.info).nonEmpty && name != nme.CONSTRUCTOR) {
13961395
// log("!!! unifying " + (symbol, symbol.tpe) + " and " + (tree, tree.tpe))
13971396
val env = unify(symbol.tpe, tree.tpe, emptyEnv, false)
13981397
// log("!!! found env: " + env + "; overloads: " + overloads(symbol))
1399-
debuglog("checking for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe + " env: " + env)
14001398
if (!env.isEmpty) {
1399+
// debuglog("checking for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe + " env: " + env)
14011400
val specMember = overload(symbol, env)
1402-
//log("!!! found member: " + specMember)
14031401
if (specMember.isDefined) {
1404-
// log("** routing " + tree + " to " + specMember.get.sym.fullName)
14051402
localTyper.typedOperator(atPos(tree.pos)(Select(transform(qual), specMember.get.sym.name)))
1406-
} else {
1403+
}
1404+
else {
14071405
val qual1 = transform(qual)
14081406
val specMember = qual1.tpe.member(specializedName(symbol, env)).suchThat(_.tpe matches subst(env, symbol.tpe))
14091407
if (specMember ne NoSymbol) {
1410-
// log("** using spec member " + specMember + ": " + specMember.tpe)
14111408
val tree1 = atPos(tree.pos)(Select(qual1, specMember))
14121409
if (specMember.isMethod)
14131410
localTyper.typedOperator(tree1)
@@ -1450,10 +1447,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
14501447
// log("--> method: " + ddef + " in " + ddef.symbol.owner + ", " + info(symbol))
14511448
if (symbol.isConstructor) {
14521449

1453-
val t = atOwner(symbol) {
1454-
val superRef: Tree = Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
1455-
forwardCtorCall(tree.pos, superRef, vparamss, symbol.owner)
1456-
}
1450+
val t = atOwner(symbol)(forwardCtorCall(tree.pos, gen.mkSuperSelect, vparamss, symbol.owner))
1451+
14571452
if (symbol.isPrimaryConstructor)
14581453
localTyper.typedPos(symbol.pos)(deriveDefDef(tree)(_ => Block(List(t), Literal(Constant()))))
14591454
else // duplicate the original constructor

src/compiler/scala/tools/nsc/typechecker/Namers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ trait Namers extends MethodSynthesis {
636636
classAndNamerOfModule(m) = (tree, null)
637637
}
638638
val owner = tree.symbol.owner
639-
if (settings.lint.value && owner.isPackageObjectClass) {
639+
if (settings.lint.value && owner.isPackageObjectClass && !mods.isImplicit) {
640640
context.unit.warning(tree.pos,
641641
"it is not recommended to define classes/objects inside of package objects.\n" +
642642
"If possible, define " + tree.symbol + " in " + owner.skipPackageObject + " instead."

0 commit comments

Comments
 (0)