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
|
/* 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 SymbolCreations {
self: SymbolTable =>
import definitions._
/** Symbol creation interface, possibly better moved somewhere else.
* It'd be nice if we had virtual classes, but since we
* don't: these methods insulate the direct instantiation of the symbols
* (which may be overridden, e.g. in SynchronizedSymbols) from the
* enforcement of preconditions and choice of symbol constructor based
* on flags, which are (or should be) final so they can be reasoned about
* without lots of surprises.
*/
trait SymbolCreatorInterface {
// Fallbacks; more precise creators should normally be called.
protected def createTypeSymbol(name: TypeName, pos: Position, newFlags: Long): TypeSymbol
protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol
// I believe all but rogue TypeSymbols are one of: ClassSymbol, AbstractTypeSymbol, AliasTypeSymbol, or TypeSkolem.
protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol
protected def createAliasTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AliasTypeSymbol
protected def createTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position, newFlags: Long): TypeSkolem
protected def createClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol
// More specific ClassSymbols.
// TODO - AnonymousClassSymbol.
// TODO maybe - PackageObjects, but that one cost me a lot of time when I tried it before
// because it broke reification some way I couldn't see.
protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol
protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol
protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol
// Distinguished term categories include methods, modules, packages, package objects,
// value parameters, and values (including vals, vars, and lazy vals.)
protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol
protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol
protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol
// TODO
// protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol
// protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol
}
trait SymbolCreator extends SymbolCreatorInterface {
self: Symbol =>
/*** Predictable symbol creation.
*
* newTermSymbol, newClassSymbol, and newNonClassSymbol all create symbols based
* only on the flags (for reconstruction after reification.) It would be nice to
* combine the last two into newTypeSymbol, but this requires some flag which allows us
* to distinguish classes and type aliases, which as yet does not exist.
*
* The fundamental flags used to determine which Symbol subclass to instantiate are:
* METHOD, PACKAGE, MODULE, PARAM, DEFERRED.
*/
final def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = {
if ((newFlags & METHOD) != 0)
createMethodSymbol(name, pos, newFlags)
else if ((newFlags & PACKAGE) != 0)
createPackageSymbol(name, pos, newFlags | PackageFlags)
else if ((newFlags & MODULE) != 0)
createModuleSymbol(name, pos, newFlags)
else if ((newFlags & PARAM) != 0)
createValueParameterSymbol(name, pos, newFlags)
else
createValueMemberSymbol(name, pos, newFlags)
}
final def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = {
if (name == tpnme.REFINE_CLASS_NAME)
createRefinementClassSymbol(pos, newFlags)
else if ((newFlags & PACKAGE) != 0)
createPackageClassSymbol(name, pos, newFlags | PackageFlags)
else if ((newFlags & MODULE) != 0)
createModuleClassSymbol(name, pos, newFlags)
else
createClassSymbol(name, pos, newFlags)
}
final def newNonClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = {
if ((newFlags & DEFERRED) != 0)
createAbstractTypeSymbol(name, pos, newFlags)
else
createAliasTypeSymbol(name, pos, newFlags)
}
def newTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol =
newNonClassSymbol(name, pos, newFlags)
}
}
|