-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
2,760 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package dotty.tools.dotc.core | ||
|
||
object periods { | ||
|
||
class A[T] { def m: T } | ||
class B { def m: Integer };import org.scalaide.worksheet.runtime.library.WorksheetSupport._; def main(args: Array[String])=$execute{;$skip(131); | ||
|
||
val x: A[String] & B;System.out.println("""x: => <error> = """ + $show(x));$skip(72); val res$0 = | ||
|
||
x.m: AndRef(MemberRef(A.m, String), Symbol(B.m)): String & Integer;System.out.println("""res0: <error> = """ + $show(res$0));$skip(73); val res$1 = | ||
|
||
if (x.isInstanceOf[A]) x.asInstanceOf[A].m else x.asInstanceOf[B].m;System.out.println("""res1: <error> = """ + $show(res$1))} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package dotty.tools.dotc.core | ||
|
||
import Periods._ | ||
|
||
object test {;import org.scalaide.worksheet.runtime.library.WorksheetSupport._; def main(args: Array[String])=$execute{;$skip(78); | ||
val rid = 223;System.out.println("""rid : Int = """ + $show(rid ));$skip(27); | ||
val p = periodOf(rid, 2);System.out.println("""p : dotty.tools.dotc.core.Periods.Period = """ + $show(p ));$skip(34); | ||
val ivl = intervalOf(rid, 2, 4);System.out.println("""ivl : dotty.tools.dotc.core.Periods.Interval = """ + $show(ivl ));$skip(25); val res$0 = | ||
containsPeriod(ivl, p);System.out.println("""res0: Boolean = """ + $show(res$0));$skip(40); val res$1 = | ||
containsPeriod(ivl, periodOf(rid, 1));System.out.println("""res1: Boolean = """ + $show(res$1));$skip(40); val res$2 = | ||
containsPeriod(ivl, periodOf(rid, 5));System.out.println("""res2: Boolean = """ + $show(res$2));$skip(39); val res$3 = | ||
containsPeriod(ivl, periodOf(rid, 4));System.out.println("""res3: Boolean = """ + $show(res$3));$skip(41); val res$4 = | ||
containsPeriod(ivl, periodOf(rid+1, 2));System.out.println("""res4: Boolean = """ + $show(res$4));$skip(41); val res$5 = | ||
containsPeriod(ivl, periodOf(rid-1, 2));System.out.println("""res5: Boolean = """ + $show(res$5));$skip(15); val res$6 = | ||
phaseIdOf(p);System.out.println("""res6: dotty.tools.dotc.core.Periods.PhaseId = """ + $show(res$6));$skip(17); val res$7 = | ||
phaseIdOf(ivl);System.out.println("""res7: dotty.tools.dotc.core.Periods.PhaseId = """ + $show(res$7));$skip(13); val res$8 = | ||
runIdOf(p);System.out.println("""res8: dotty.tools.dotc.core.Periods.RunId = """ + $show(res$8));$skip(43); val res$9 = | ||
containsPeriod(intervalOf(rid, 2, 2), p);System.out.println("""res9: Boolean = """ + $show(res$9))} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package dotty.tools.dotc.core | ||
|
||
object Annotations { | ||
|
||
abstract class AnnotationInfo | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package dotty.tools.dotc | ||
package core | ||
|
||
import Types._ | ||
|
||
object Constants { | ||
|
||
case class Constant(value: Any) { | ||
def tpe: Type = ??? | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package dotty.tools.dotc | ||
package core | ||
|
||
import Decorators._ | ||
import Periods._ | ||
import Names._ | ||
import Phases._ | ||
import Types._ | ||
|
||
object Contexts { | ||
|
||
val NoContext: Context = null | ||
|
||
abstract class Context extends Periods { | ||
val underlying: Context | ||
val root: RootContext | ||
val period: Period | ||
def names: NameTable | ||
def phase: Phase = ??? | ||
|
||
} | ||
|
||
abstract class SubContext(val underlying: Context) extends Context { | ||
val root: RootContext = underlying.root | ||
val period: Period = underlying.period | ||
def names: NameTable = root.names | ||
} | ||
|
||
class RootContext extends Context | ||
with Symbols | ||
with Denotations | ||
with DenotationTransformers | ||
with Types { | ||
|
||
val underlying: Context = throw new UnsupportedOperationException("RootContext.underlying") | ||
|
||
val root: RootContext = this | ||
val period = periodOf(NoRunId, NoPhaseId) | ||
val names: NameTable = new NameTable | ||
val variance = 1 | ||
|
||
var lastPhaseId: Int = NoPhaseId | ||
|
||
} | ||
|
||
private final val initialUniquesCapacity = 4096 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package dotty.tools.dotc | ||
package core | ||
|
||
import Contexts._, Names._ | ||
|
||
object Decorators { | ||
|
||
implicit class toTypeNameDecorator(val s: String) extends AnyVal { | ||
def toTypeName(implicit context: Context): TypeName = | ||
context.names.newTypeName(s) | ||
} | ||
|
||
implicit class toTermNameDecorator(val s: String) extends AnyVal { | ||
def toTermName(implicit context: Context): TermName = | ||
context.names.newTermName(s) | ||
} | ||
|
||
final val MaxRecursions = 1000 | ||
|
||
implicit class ListDecorator[T](val xs: List[T]) extends AnyVal { | ||
def filterConserve(p: T => Boolean): List[T] = { | ||
def loop(xs: List[T], nrec: Int): List[T] = xs match { | ||
case Nil => xs | ||
case x :: xs1 => | ||
if (nrec < MaxRecursions) { | ||
val ys1 = loop(xs1, nrec + 1) | ||
if (p(x)) | ||
if (ys1 eq xs1) xs else x :: ys1 | ||
else | ||
ys1 | ||
} else xs filter p | ||
} | ||
loop(xs, 0) | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,241 @@ | ||
package dotty.tools.dotc | ||
package core | ||
|
||
import Periods._, Contexts._, Symbols._, RefSets._, Names._ | ||
import Types._, Flags._, Decorators._ | ||
import Scopes.Scope | ||
import collection.immutable.BitSet | ||
import collection.mutable | ||
import util.LRU8Cache | ||
|
||
trait Denotations { self: Context => | ||
|
||
/** A set for hash consing superclass bitsets */ | ||
private val uniqueBits = new util.HashSet[BitSet]("superbits", 1024) | ||
|
||
} | ||
|
||
object Denotations { | ||
|
||
abstract class Denotation { | ||
|
||
/** The validity interval of this symbol */ | ||
var valid: Interval = Nowhere | ||
|
||
/** The next instance of this symbol in the same run */ | ||
private[core] var nextInRun: Denotation = this | ||
|
||
/** | ||
* The version of this symbol that was valid in the first phase | ||
* of this run | ||
*/ | ||
def initial: Denotation = { | ||
var sym = nextInRun | ||
while (sym.valid > this.valid) sym = sym.nextInRun | ||
sym | ||
} | ||
|
||
def owner: Symbol = ??? | ||
|
||
def name: Name = ??? | ||
|
||
def flags: Long = ??? | ||
|
||
def setFlag(flag: Long): Unit = ??? | ||
|
||
def tpe: Type = ??? | ||
|
||
def info: Type = ??? | ||
|
||
/* Validity and instance handling: | ||
* | ||
* Symbols have an interval of validity, defined | ||
* by their `valid` fields. | ||
* | ||
* There may be several symbols with different validity | ||
* representing the same underlying symbol at different phases. | ||
* These are called a "flock". Flock members are generated by | ||
* @see SymRef.trackSym. Flock members are connected in a ring | ||
* with their `nextInFlock` fields. | ||
* | ||
* There are the following invariants converning flock members | ||
* | ||
* 1) validity intervals must be non-overlapping | ||
* 2) the union of all validity intervals must be a contiguous | ||
* interval starting in FirstPhaseId. | ||
*/ | ||
|
||
/** is this symbol a type? */ | ||
def isType: Boolean = false | ||
|
||
/** is this symbol a class? */ | ||
def isClass: Boolean = false | ||
|
||
/** is this symbol a method? */ | ||
def isMethod: Boolean = false | ||
|
||
/** is this symbol the result of an erroneous definition? */ | ||
def isError: Boolean = false | ||
|
||
def asClass: ClassDenotation = ??? | ||
|
||
def withType(tp: Type): Denotation = ??? | ||
} | ||
|
||
object NameFilter { | ||
final val WordSizeLog = 6 | ||
final val DefinedNamesWords = 16 | ||
final val DefinedNamesSize = DefinedNamesWords << WordSizeLog | ||
final val DefinedNamesMask = DefinedNamesSize - 1 | ||
|
||
type FingerPrint = Array[Long] | ||
|
||
def includeName(bits: FingerPrint, name: Name): Unit = { | ||
val hash = name.start & DefinedNamesMask | ||
bits(hash >> 6) |= (1 << hash) | ||
} | ||
|
||
def includeFingerPrint(bits1: FingerPrint, bits2: FingerPrint): Unit = | ||
for (i <- 0 until DefinedNamesWords) bits1(i) |= bits2(i) | ||
|
||
def containsName(bits: FingerPrint, name: Name): Boolean = { | ||
val hash = name.start & DefinedNamesMask | ||
(bits(hash >> 6) & (1 << hash)) != 0 | ||
} | ||
|
||
def newNameFilter: FingerPrint = new Array[Long](DefinedNamesWords) | ||
} | ||
|
||
class ClassDenotation(parents: List[Type], decls: Scope) extends Denotation { | ||
|
||
import NameFilter._ | ||
|
||
lazy val baseClasses: List[ClassSymbol] = ??? | ||
|
||
private var memberCacheVar: LRU8Cache[Name, RefSet] = null | ||
|
||
private def memberCache: LRU8Cache[Name, RefSet] = { | ||
if (memberCacheVar == null) memberCacheVar = new LRU8Cache | ||
memberCacheVar | ||
} | ||
|
||
def thisType: Type = ??? | ||
|
||
private var superClassBitsCache: BitSet = null | ||
|
||
private def computeSuperClassBits(implicit ctx: Context): BitSet = { | ||
val b = BitSet.newBuilder | ||
for (bc <- baseClasses) b += bc.superId | ||
val bits = ctx.root.uniqueBits.findEntryOrUpdate(b.result()) | ||
superClassBitsCache = bits | ||
bits | ||
} | ||
|
||
def superClassBits(implicit ctx: Context): BitSet = { | ||
val bits = superClassBitsCache | ||
if (bits != null) bits else computeSuperClassBits | ||
} | ||
|
||
/** Is this class a subclass of `clazz`? */ | ||
final def isSubClass(clazz: ClassSymbol)(implicit ctx: Context): Boolean = { | ||
superClassBits contains clazz.superId | ||
} | ||
|
||
private var definedFingerPrintCache: FingerPrint = null | ||
|
||
private def computeDefinedFingerPrint(implicit ctx: Context): FingerPrint = { | ||
var bits = newNameFilter | ||
var e = decls.lastEntry | ||
while (e != null) { | ||
includeName(bits, name) | ||
e = e.prev | ||
} | ||
var ps = parents | ||
while (ps.nonEmpty) { | ||
val parent = ps.head.typeSymbol.asClass.deref | ||
includeFingerPrint(bits, parent.definedFingerPrint) | ||
parent setFlag Frozen | ||
ps = ps.tail | ||
} | ||
definedFingerPrintCache = bits | ||
bits | ||
} | ||
|
||
/** Enter a symbol in current scope. | ||
* Note: We require that this does not happen after the first time | ||
* someone does a findMember on a subclass. | ||
*/ | ||
def enter(sym: Symbol)(implicit ctx: Context) = { | ||
require((flags & Frozen) == 0) | ||
decls enter sym | ||
if (definedFingerPrintCache != null) | ||
includeName(definedFingerPrintCache, sym.name) | ||
if (memberCacheVar != null) | ||
memberCache invalidate sym.name | ||
} | ||
|
||
/** Delete symbol from current scope. | ||
* Note: We require that this does not happen after the first time | ||
* someone does a findMember on a subclass. | ||
*/ | ||
def delete(sym: Symbol)(implicit ctx: Context) = { | ||
require((flags & Frozen) == 0) | ||
decls unlink sym | ||
if (definedFingerPrintCache != null) | ||
computeDefinedFingerPrint | ||
if (memberCacheVar != null) | ||
memberCache invalidate sym.name | ||
} | ||
|
||
def definedFingerPrint(implicit ctx: Context): FingerPrint = { | ||
val fp = definedFingerPrintCache | ||
if (fp != null) fp else computeDefinedFingerPrint | ||
} | ||
|
||
final def declsNamed(name: Name)(implicit ctx: Context): RefSet = { | ||
var syms: RefSet = NoType | ||
var e = decls lookupEntry name | ||
while (e != null) { | ||
syms = syms union e.sym.refType | ||
e = decls lookupNextEntry e | ||
} | ||
syms | ||
} | ||
|
||
final def memberRefsNamed(name: Name)(implicit ctx: Context): RefSet = { | ||
var refs: RefSet = memberCache lookup name | ||
if (refs == null) { | ||
if (containsName(definedFingerPrint, name)) { | ||
val ownRefs = declsNamed(name) | ||
refs = ownRefs | ||
var ps = parents | ||
val ownType = thisType | ||
while (ps.nonEmpty) { | ||
val parentSym = ps.head.typeSymbol.asClass | ||
val parent = parentSym.deref | ||
refs = refs union | ||
parent.memberRefsNamed(name) | ||
.filterExcluded(Flags.Private) | ||
.seenFrom(thisType, parentSym) | ||
.filterDisjoint(ownRefs) | ||
ps = ps.tail | ||
} | ||
} else { | ||
refs = NoType | ||
} | ||
memberCache enter (name, refs) | ||
} | ||
refs | ||
} | ||
} | ||
|
||
object NoDenotation extends Denotation { | ||
override def owner: Symbol = throw new AssertionError("NoDenotation.owner") | ||
override def name: Name = BootNameTable.newTermName("<none>") | ||
override def flags: Long = 0 | ||
override def tpe: Type = NoType | ||
override def info: Type = NoType | ||
} | ||
|
||
|
||
} |
Oops, something went wrong.