-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Topic/language features #75
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
Changes from all commits
fecf74b
db9ac0a
0a71bf3
f5f9e23
0376acf
4be3a24
cde1cd5
b22287a
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 |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package dotty | ||
|
||
object language { | ||
|
||
class Feature | ||
|
||
/** Allow higher-kinded type syntax (not yet checked) */ | ||
val higherKinds = new Feature | ||
|
||
/** Keep union types */ | ||
val keepUnions = new Feature | ||
|
||
/** No auto tupling */ | ||
val noAutoTupling = new Feature | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import Contexts._, Types._, Symbols._, Names._, Flags._, Scopes._ | |
import SymDenotations._ | ||
import config.Printers._ | ||
import Decorators._ | ||
import StdNames._ | ||
import util.SimpleMap | ||
|
||
trait TypeOps { this: Context => | ||
|
@@ -76,6 +77,37 @@ trait TypeOps { this: Context => | |
def apply(tp: Type) = simplify(tp, this) | ||
} | ||
|
||
/** Approximate union type by intersection of its dominators. | ||
* See Type#approximateUnion for an explanation. | ||
*/ | ||
def approximateUnion(tp: Type): Type = { | ||
/** a faster version of cs1 intersect cs2 */ | ||
def intersect(cs1: List[ClassSymbol], cs2: List[ClassSymbol]): List[ClassSymbol] = { | ||
val cs2AsSet = new util.HashSet[ClassSymbol](100) | ||
cs2.foreach(cs2AsSet.addEntry) | ||
cs1.filter(cs2AsSet.contains) | ||
} | ||
/** The minimal set of classes in `cs` which derive all other classes in `cs` */ | ||
def dominators(cs: List[ClassSymbol], accu: List[ClassSymbol]): List[ClassSymbol] = (cs: @unchecked) match { | ||
case c :: rest => | ||
val accu1 = if (accu exists (_ derivesFrom c)) accu else c :: accu | ||
if (cs == c.baseClasses) accu1 else dominators(rest, accu1) | ||
} | ||
if (ctx.featureEnabled(defn.LanguageModuleClass, nme.keepUnions)) tp | ||
else tp match { | ||
case tp: OrType => | ||
val commonBaseClasses = tp.mapReduceOr(_.baseClasses)(intersect) | ||
val doms = dominators(commonBaseClasses, Nil) | ||
doms.map(tp.baseTypeWithArgs).reduceLeft(AndType.apply) | ||
case tp @ AndType(tp1, tp2) => | ||
tp derived_& (approximateUnion(tp1), approximateUnion(tp2)) | ||
case tp: RefinedType => | ||
tp.derivedRefinedType(approximateUnion(tp.parent), tp.refinedName, tp.refinedInfo) | ||
case _ => | ||
tp | ||
} | ||
} | ||
|
||
/** A type is volatile if its DNF contains an alternative of the form | ||
* {P1, ..., Pn}, {N1, ..., Nk}, where the Pi are parent typerefs and the | ||
* Nj are refinement names, and one the 4 following conditions is met: | ||
|
@@ -266,6 +298,44 @@ trait TypeOps { this: Context => | |
} | ||
parentRefs | ||
} | ||
|
||
/** Is `feature` enabled in class `owner`? | ||
* This is the case if one of the following two alternatives holds: | ||
* | ||
* 1. The feature is imported by a named import | ||
* | ||
* import owner.feature | ||
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. It will be good to have a test for this 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. Tests are included in the following commits. 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. It seems for me that only disabling language feature by command line argument is tested by tests that are currently in this pull request. https://github.com/lampepfl/dotty/pull/75/files#diff-28f8d722cae3da74d903fc63040c9d36R60 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. True. We should have other tests as well. But I am (again) running out of time. Can you put back the missing comment and add a test for the import feature? Thanks! |
||
* | ||
* (the feature may be bunched with others, or renamed, but wildcard imports | ||
* don't count). | ||
* | ||
* 2. The feature is enabled by a compiler option | ||
* | ||
* - language:<prefix>feature | ||
* | ||
* where <prefix> is the full name of the owner followed by a "." minus | ||
* the prefix "dotty.language.". | ||
*/ | ||
def featureEnabled(owner: ClassSymbol, feature: TermName): Boolean = { | ||
def toPrefix(sym: Symbol): String = | ||
if (sym eq defn.LanguageModuleClass) "" else toPrefix(sym.owner) + sym.name + "." | ||
def featureName = toPrefix(owner) + feature | ||
def hasImport(implicit ctx: Context): Boolean = ( | ||
ctx.importInfo != null | ||
&& ( (ctx.importInfo.site.widen.typeSymbol eq owner) | ||
&& ctx.importInfo.originals.contains(feature) | ||
|| | ||
{ var c = ctx.outer | ||
while (c.importInfo eq ctx.importInfo) c = c.outer | ||
hasImport(c) | ||
})) | ||
def hasOption = ctx.base.settings.language.value exists (s => s == featureName || s == "_") | ||
hasImport || hasOption | ||
} | ||
|
||
/** Is auto-tupling enabled? */ | ||
def canAutoTuple = | ||
!featureEnabled(defn.LanguageModuleClass, nme.noAutoTupling) | ||
} | ||
|
||
object TypeOps { | ||
|
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.
Why was documentation removed?
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.
Which documentation?
I something was removed it was probably not intentional, but because I went through a nightmare of rebasings and merges.
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.
this one
https://github.com/lampepfl/dotty/pull/75/files#diff-4c668835f1c9ce9b7ff638cf82a22d7eL938