-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Change/higher kinded #137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change/higher kinded #137
Changes from 19 commits
51563ae
96196c9
4e287d5
c4f9683
a77a4f6
c2bcf2e
c1b884b
8db6b3e
9a6a4e8
cfd13f7
099e5a6
388d9a8
7f72143
f9625f9
7623856
91e44df
ad0600f
7cf6202
b3364db
c172148
f823e42
f600df4
e710af6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -87,13 +87,14 @@ object NameOps { | |
name.last == '=' && name.head != '=' && isOperatorPart(name.head) | ||
} | ||
|
||
/** Is this the name of a higher-kinded type parameter? */ | ||
def isHkParamName: Boolean = name(0) == '_' && name.startsWith(HK_PARAM_PREFIX) | ||
/** Is this the name of a higher-kinded type parameter of a Lambda? */ | ||
def isLambdaArgName = | ||
name(0) == tpnme.LAMBDA_ARG_PREFIXhead && name.startsWith(tpnme.LAMBDA_ARG_PREFIX) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can names be empty? (I guess not, but you never know :-)) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be cool to have the constant folder fold indexing of constant strings, so you could write There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, except that LAMBDA_ARG_PREFIX is a name, not a string. |
||
|
||
/** The index of the higher-kinded type parameter with this name. | ||
* Pre: isHkParamName. | ||
* Pre: isLambdaArgName. | ||
*/ | ||
def hkParamIndex: Int = name.drop(name.lastIndexOf('$') + 1).toString.toInt | ||
def lambdaArgIndex: Int = name.drop(name.lastIndexOf('$') + 1).toString.toInt | ||
|
||
/** If the name ends with $nn where nn are | ||
* all digits, strip the $ and the digits. | ||
|
@@ -177,19 +178,6 @@ object NameOps { | |
} | ||
} | ||
|
||
/** The variances of the higherKinded parameters of the trait named | ||
* by this name. | ||
* @pre The name is a higher-kinded trait name, i.e. it starts with HK_TRAIT_PREFIX | ||
*/ | ||
def hkVariances: List[Int] = { | ||
def varianceOfSuffix(suffix: Char): Int = { | ||
val idx = tpnme.varianceSuffixes.indexOf(suffix) | ||
assert(idx >= 0) | ||
idx - 1 | ||
} | ||
name.drop(tpnme.HK_TRAIT_PREFIX.length).toList.map(varianceOfSuffix) | ||
} | ||
|
||
/** The name of the generic runtime operation corresponding to an array operation */ | ||
def genericArrayOp: TermName = name match { | ||
case nme.apply => nme.array_apply | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -166,6 +166,8 @@ object StdNames { | |
final val WILDCARD_STAR: N = "_*" | ||
final val REIFY_TREECREATOR_PREFIX: N = "$treecreator" | ||
final val REIFY_TYPECREATOR_PREFIX: N = "$typecreator" | ||
final val LAMBDA_ARG_PREFIX: N = "$hkArg$" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On a semi-related note, could we switch to ☃ as our magic char, and reserve $ for class nesting and other java-mimicry? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be good to do this yes. We have a to-do list item to rehaul the whole name mangling scheme. |
||
final val LAMBDA_ARG_PREFIXhead: Char = LAMBDA_ARG_PREFIX.head | ||
|
||
final val Any: N = "Any" | ||
final val AnyVal: N = "AnyVal" | ||
|
@@ -249,8 +251,6 @@ object StdNames { | |
val SKOLEM: N = "<skolem>" | ||
val SPECIALIZED_INSTANCE: N = "specInstance$" | ||
val THIS: N = "_$this" | ||
val HK_PARAM_PREFIX: N = "_$hk$" | ||
val HK_TRAIT_PREFIX: N = "$HigherKinded$" | ||
|
||
final val Nil: N = "Nil" | ||
final val Predef: N = "Predef" | ||
|
@@ -286,6 +286,7 @@ object StdNames { | |
val Flag : N = "Flag" | ||
val Ident: N = "Ident" | ||
val Import: N = "Import" | ||
val LambdaPrefix: N = "Lambda$" | ||
val Literal: N = "Literal" | ||
val LiteralAnnotArg: N = "LiteralAnnotArg" | ||
val Modifiers: N = "Modifiers" | ||
|
@@ -645,8 +646,8 @@ object StdNames { | |
def syntheticTypeParamNames(num: Int): List[TypeName] = | ||
(0 until num).map(syntheticTypeParamName)(breakOut) | ||
|
||
def higherKindedTraitName(vcs: List[Int]): TypeName = HK_TRAIT_PREFIX ++ vcs.map(varianceSuffix).mkString | ||
def higherKindedParamName(n: Int) = HK_PARAM_PREFIX ++ n.toString | ||
def lambdaTraitName(vcs: List[Int]): TypeName = LambdaPrefix ++ vcs.map(varianceSuffix).mkString | ||
def lambdaArgName(n: Int) = LAMBDA_ARG_PREFIX ++ n.toString | ||
|
||
final val Conforms = encode("<:<") | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -321,9 +321,17 @@ object SymDenotations { | |
final def isAnonymousClass(implicit ctx: Context): Boolean = | ||
initial.asSymDenotation.name startsWith tpnme.ANON_CLASS | ||
|
||
/** Is this symbol a class representing a refinement? These classes | ||
* are used only temporarily in Typer and Unpickler as an intermediate | ||
* step for creating Refinement types. | ||
*/ | ||
final def isRefinementClass(implicit ctx: Context): Boolean = | ||
name.decode == tpnme.REFINE_CLASS | ||
|
||
/** is this symbol a trait representing a type lambda? */ | ||
final def isLambdaTrait(implicit ctx: Context): Boolean = | ||
isClass && name.startsWith(tpnme.LambdaPrefix) | ||
|
||
/** Is this symbol a package object or its module class? */ | ||
def isPackageObject(implicit ctx: Context): Boolean = { | ||
val poName = if (isType) nme.PACKAGE_CLS else nme.PACKAGE | ||
|
@@ -699,7 +707,7 @@ object SymDenotations { | |
|
||
/** All symbols overriden by this denotation. */ | ||
final def allOverriddenSymbols(implicit ctx: Context): Iterator[Symbol] = | ||
if (exists) | ||
if (exists && owner.isClass) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't understand: we are looking for the symbols which this symbol overrides. Finality of the overriding symbol does not change anything. |
||
owner.info.baseClasses.tail.iterator map overriddenSymbol filter (_.exists) | ||
else | ||
Iterator.empty | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the parentTraitRefs from the implementation should be described in this comment, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right. I'll add an explanation.