1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
/* NSC -- new Scala compiler
* Copyright 2005-2011 LAMP/EPFL
* @author Paul Phillips
*/
package scala.reflect
package internal
import scala.collection.{ mutable, immutable }
import scala.collection.mutable.ListBuffer
import util.Statistics._
import Flags._
import api.Modifier
import scala.tools.util.StringOps.{ ojoin }
trait SymbolFlags {
self: SymbolTable =>
import definitions._
/** Not mixed in under normal conditions; a powerful debugging aid.
*/
trait FlagVerifier extends Symbol {
private def assert0(cond: Boolean, message: => Any) {
if (!cond) {
Console.err.println("[flag verification failure]\n%s\n%s\n".format(atPhaseStackMessage, message))
(new Throwable).getStackTrace.take(13).drop(3).foreach(println)
println("")
}
}
protected def verifyChange(isAdd: Boolean, mask: Long, before: Long) {
val after = if (isAdd) before | mask else before & ~mask
val added = after & ~before
val removed = before & ~after
val ignored = mask & ~added & ~removed
val error = (
(added & OverloadedFlagsMask) != 0 || (removed & OverloadedFlagsMask) != 0
// || (ignored != 0)
)
val addString = if (added == 0) "" else "+(" + flagsToString(added) + ")"
val removeString = if (removed == 0) "" else "-(" + flagsToString(removed) + ")"
val changeString = if (added == 0 && removed == 0) "no change" else addString + " " + removeString
if (error) {
val templ = (
"""| symbol: %s %s in %s
| call: %s(%s)
| flags: %s
| result: %s""".stripMargin
)
assert0(false, templ.format(
shortSymbolClass,
name.decode,
owner,
if (isAdd) "+" else "-",
flagsToString(mask),
flagsToString(before),
changeString
))
}
}
protected def verifyFlags(what: String) {
assert0(this hasAllFlags alwaysHasFlags, symbolCreationString + "\n always=%s, what=%s\n".format(flagsToString(alwaysHasFlags), what))
if (this hasFlag neverHasFlags) {
val hasRaw = (rawflags & neverHasFlags) != 0
assert0(!hasRaw, symbolCreationString + "\n never=%s, what=%s".format(flagsToString(neverHasFlags), what))
}
}
abstract override def initFlags(mask: Long): this.type = {
super.initFlags(mask)
verifyFlags("initFlags(" + flagsToString(mask) + ")")
this
}
abstract override def setFlag(mask: Long): this.type = {
verifyChange(true, mask, rawflags)
super.setFlag(mask)
verifyFlags("setFlag(" + flagsToString(mask) + ")")
this
}
abstract override def resetFlag(mask: Long): this.type = {
verifyChange(false, mask, rawflags)
super.resetFlag(mask)
verifyFlags("resetFlag(" + flagsToString(mask) + ")")
this
}
abstract override def flags_=(fs: Long) {
if ((fs & ~rawflags) != 0)
verifyChange(true, fs & ~rawflags, rawflags)
if ((rawflags & ~fs) != 0)
verifyChange(false, rawflags & ~fs, rawflags)
super.flags_=(fs)
verifyFlags("flags_=(" + flagsToString(fs) + ")")
}
}
/** A distinguishing flag is one which the mixing class must always
* have, and which no other symbol class is allowed to have.
*/
trait DistinguishingFlag extends SymbolFlagLogic {
this: Symbol =>
def distinguishingFlag: Long
override protected def alwaysHasFlags = super.alwaysHasFlags | distinguishingFlag
override protected def neverHasFlags = super.neverHasFlags & ~distinguishingFlag
}
trait SymbolFlagLogic {
this: Symbol =>
// Forced for performance reasons to define all the flag manipulation
// methods alongside the field being manipulated.
def getFlag(mask: Long): Long
def hasFlag(mask: Long): Boolean
def hasAllFlags(mask: Long): Boolean
def setFlag(mask: Long): this.type
def resetFlag(mask: Long): this.type
def initFlags(mask: Long): this.type
def resetFlags(): Unit
protected def resolveOverloadedFlag(flag: Long): String
protected def calculateFlagString(basis: Long): String
protected def alwaysHasFlags: Long = 0L
protected def neverHasFlags: Long = METHOD | MODULE
def rawFlagString(mask: Long): String = calculateFlagString(rawflags & mask)
def rawFlagString: String = rawFlagString(flagMask)
def debugFlagString: String = flagString(AllFlags)
/** String representation of symbol's variance */
def varianceString: String =
if (variance == 1) "+"
else if (variance == -1) "-"
else ""
override def flagMask =
if (settings.debug.value && !isAbstractType) AllFlags
else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE
else ExplicitFlags
// make the error message more googlable
def flagsExplanationString =
if (isGADTSkolem) " (this is a GADT skolem)"
else ""
/** If the given flag is set on this symbol, also set the corresponding
* notFLAG. For instance if flag is PRIVATE, the notPRIVATE flag will
* be set if PRIVATE is currently set.
*/
final def setNotFlag(flag: Int) = if (hasFlag(flag)) setFlag((flag: @annotation.switch) match {
case PRIVATE => notPRIVATE
case PROTECTED => notPROTECTED
case OVERRIDE => notOVERRIDE
case _ => abort("setNotFlag on invalid flag: " + flag)
})
protected def shortSymbolClass = getClass.getName.split('.').last.stripPrefix("Symbols$")
def symbolCreationString: String = (
"%s%25s | %-40s | %s".format(
if (settings.uniqid.value) "%06d | ".format(id) else "",
shortSymbolClass,
name.decode + " in " + owner,
rawFlagString
)
)
}
}
|