Skip to content

Use some enums in compiler #6733

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

Merged
merged 3 commits into from
Jul 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 19 additions & 23 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,22 @@ object desugar {
/** If a Select node carries this attachment, suppress the check
* that its type refers to an acessible symbol.
*/
val SuppressAccessCheck: Property.Key[Unit] = new Property.Key
val SuppressAccessCheck: Property.Key[Unit] = Property.Key()

/** An attachment for companion modules of classes that have a `derives` clause.
* The position value indicates the start position of the template of the
* deriving class.
*/
val DerivingCompanion: Property.Key[SourcePosition] = new Property.Key
val DerivingCompanion: Property.Key[SourcePosition] = Property.Key()

/** An attachment for match expressions generated from a PatDef or GenFrom.
* Value of key == one of IrrefutablePatDef, IrrefutableGenFrom
*/
val CheckIrrefutable: Property.Key[MatchCheck] = new Property.StickyKey

/** What static check should be applied to a Match (none, irrefutable, exhaustive) */
class MatchCheck(val n: Int) extends AnyVal
object MatchCheck {
val None = new MatchCheck(0)
val Exhaustive = new MatchCheck(1)
val IrrefutablePatDef = new MatchCheck(2)
val IrrefutableGenFrom = new MatchCheck(3)
val CheckIrrefutable: Property.Key[MatchCheck] = Property.StickyKey()

/** What static check should be applied to a Match? */
enum MatchCheck {
case None, Exhaustive, IrrefutablePatDef, IrrefutableGenFrom
}

/** Info of a variable in a pattern: The named tree and its type */
Expand Down Expand Up @@ -136,17 +132,17 @@ object desugar {
def derivedTypeParam(tdef: TypeDef, suffix: String = "")(implicit ctx: Context): TypeDef =
cpy.TypeDef(tdef)(
name = tdef.name ++ suffix,
rhs = new DerivedFromParamTree(suffix).withSpan(tdef.rhs.span).watching(tdef)
rhs = DerivedFromParamTree(suffix).withSpan(tdef.rhs.span).watching(tdef)
)

/** A derived type definition watching `sym` */
def derivedTypeParam(sym: TypeSymbol)(implicit ctx: Context): TypeDef =
TypeDef(sym.name, new DerivedFromParamTree("").watching(sym)).withFlags(TypeParam)
TypeDef(sym.name, DerivedFromParamTree("").watching(sym)).withFlags(TypeParam)

/** A value definition copied from `vdef` with a tpt typetree derived from it */
def derivedTermParam(vdef: ValDef)(implicit ctx: Context): ValDef =
cpy.ValDef(vdef)(
tpt = new DerivedFromParamTree("").withSpan(vdef.tpt.span).watching(vdef))
tpt = DerivedFromParamTree("").withSpan(vdef.tpt.span).watching(vdef))

// ----- Desugar methods -------------------------------------------------

Expand All @@ -165,7 +161,7 @@ object desugar {
// val getter = ValDef(mods, name, tpt, rhs) withPos vdef.pos?
// right now vdef maps via expandedTree to a thicket which concerns itself.
// I don't see a problem with that but if there is one we can avoid it by making a copy here.
val setterParam = makeSyntheticParameter(tpt = (new SetterParamTree).watching(vdef))
val setterParam = makeSyntheticParameter(tpt = SetterParamTree().watching(vdef))
// The rhs gets filled in later, when field is generated and getter has parameters (see Memoize miniphase)
val setterRhs = if (vdef.rhs.isEmpty) EmptyTree else unitLiteral
val setter = cpy.DefDef(vdef)(
Expand Down Expand Up @@ -217,7 +213,7 @@ object desugar {
val meth @ DefDef(_, tparams, vparamss, tpt, rhs) = transformQuotedPatternName(meth0)
val methName = normalizeName(meth, tpt).asTermName
val mods = meth.mods
val epbuf = new ListBuffer[ValDef]
val epbuf = ListBuffer[ValDef]()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ListBuffer[ValDef] is unambiguous. Meaning there is no question whether it is a reference to an object or a constructor call here because of the type parameters. Can we drop () here in future?

def desugarContextBounds(rhs: Tree): Tree = rhs match {
case ContextBounds(tbounds, cxbounds) =>
epbuf ++= makeImplicitParameters(cxbounds, Implicit, forPrimaryConstructor = isPrimaryConstructor)
Expand Down Expand Up @@ -443,7 +439,7 @@ object desugar {
val (enumCases, enumStats) = stats.partition(DesugarEnums.isEnumCase)
if (enumCases.isEmpty)
ctx.error("Enumerations must constain at least one case", namePos)
val enumCompanionRef = new TermRefTree()
val enumCompanionRef = TermRefTree()
val enumImport = Import(importDelegate = false, enumCompanionRef, enumCases.flatMap(caseIds))
(enumImport :: enumStats, enumCases, enumCompanionRef)
}
Expand All @@ -456,7 +452,7 @@ object desugar {
val derivedVparamss = constrVparamss.nestedMap(derivedTermParam(_))
val arity = constrVparamss.head.length

val classTycon: Tree = new TypeRefTree // watching is set at end of method
val classTycon: Tree = TypeRefTree() // watching is set at end of method

def appliedTypeTree(tycon: Tree, args: List[Tree]) =
(if (args.isEmpty) tycon else AppliedTypeTree(tycon, args))
Expand Down Expand Up @@ -895,8 +891,8 @@ object desugar {
}
else x
}
private val typeNameExtractor = new NameExtractor(followArgs = true)
private val argNameExtractor = new NameExtractor(followArgs = false)
private val typeNameExtractor = NameExtractor(followArgs = true)
private val argNameExtractor = NameExtractor(followArgs = false)

private def inventTypeName(tree: Tree)(implicit ctx: Context): String = typeNameExtractor("", tree)

Expand Down Expand Up @@ -1207,7 +1203,7 @@ object desugar {
def makeContextualFunction(formals: List[Type], body: Tree, isErased: Boolean)(implicit ctx: Context): Tree = {
val mods = if (isErased) Given | Erased else Given
val params = makeImplicitParameters(formals.map(TypeTree), mods)
new FunctionWithMods(params, body, Modifiers(mods))
FunctionWithMods(params, body, Modifiers(mods))
}

/** Add annotation to tree:
Expand Down Expand Up @@ -1419,7 +1415,7 @@ object desugar {
val pdefs = (valeqs, defpats, rhss).zipped.map(makePatDef(_, Modifiers(), _, _))
val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom(defpat0, gen.expr, gen.checkMode) :: Nil, Block(pdefs, makeTuple(id0 :: ids)))
val allpats = gen.pat :: pats
val vfrom1 = new GenFrom(makeTuple(allpats), rhs1, GenCheckMode.Ignore)
val vfrom1 = GenFrom(makeTuple(allpats), rhs1, GenCheckMode.Ignore)
makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
case (gen: GenFrom) :: test :: rest =>
val filtered = Apply(rhsSelect(gen, nme.withFilter), makeLambda(gen, test))
Expand Down Expand Up @@ -1594,7 +1590,7 @@ object desugar {
* without duplicates
*/
private def getVariables(tree: Tree)(implicit ctx: Context): List[VarInfo] = {
val buf = new ListBuffer[VarInfo]
val buf = ListBuffer[VarInfo]()
def seenName(name: Name) = buf exists (_._1.name == name)
def add(named: NameTree, t: Tree): Unit =
if (!seenName(named.name) && named.name.isTermName) buf += ((named, t))
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ object DesugarEnums {
}

/** Attachment containing the number of enum cases and the smallest kind that was seen so far. */
val EnumCaseCount: Property.Key[(Int, DesugarEnums.CaseKind.Value)] = new Property.Key
val EnumCaseCount: Property.Key[(Int, DesugarEnums.CaseKind.Value)] = Property.Key()

/** The enumeration class that belongs to an enum case. This works no matter
* whether the case is still in the enum class or it has been transferred to the
Expand Down
15 changes: 7 additions & 8 deletions compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ object Trees {
*/
final def tpe: T @uncheckedVariance = {
if (myTpe == null)
throw new UnAssignedTypeException(this)
throw UnAssignedTypeException(this)
myTpe
}

Expand Down Expand Up @@ -857,19 +857,19 @@ object Trees {

class EmptyTree[T >: Untyped] extends Thicket(Nil)(NoSource) {
// assert(uniqueId != 1492)
override def withSpan(span: Span) = throw new AssertionError("Cannot change span of EmptyTree")
override def withSpan(span: Span) = throw AssertionError("Cannot change span of EmptyTree")
}

class EmptyValDef[T >: Untyped] extends ValDef[T](
nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T])(NoSource) with WithoutTypeOrPos[T] {
myTpe = NoType.asInstanceOf[T]
setMods(untpd.Modifiers(PrivateLocal))
override def isEmpty: Boolean = true
override def withSpan(span: Span) = throw new AssertionError("Cannot change span of EmptyValDef")
override def withSpan(span: Span) = throw AssertionError("Cannot change span of EmptyValDef")
}

@sharable val theEmptyTree: EmptyTree[Type] = new EmptyTree[Type]
@sharable val theEmptyValDef: EmptyValDef[Type] = new EmptyValDef[Type]
@sharable val theEmptyTree = new EmptyTree[Type]()
@sharable val theEmptyValDef = new EmptyValDef[Type]()

def genericEmptyValDef[T >: Untyped]: ValDef[T] = theEmptyValDef.asInstanceOf[ValDef[T]]
def genericEmptyTree[T >: Untyped]: Thicket[T] = theEmptyTree.asInstanceOf[Thicket[T]]
Expand Down Expand Up @@ -992,11 +992,10 @@ object Trees {

@sharable val EmptyTree: Thicket = genericEmptyTree
@sharable val EmptyValDef: ValDef = genericEmptyValDef
@sharable val ContextualEmptyTree: Thicket = new EmptyTree // an empty tree marking a contextual closure
@sharable val ContextualEmptyTree: Thicket = EmptyTree() // an empty tree marking a contextual closure

// ----- Auxiliary creation methods ------------------

def Thicket(trees: List[Tree])(implicit src: SourceFile): Thicket = new Thicket(trees)
def Thicket(): Thicket = EmptyTree
def Thicket(x1: Tree, x2: Tree)(implicit src: SourceFile): Thicket = Thicket(x1 :: x2 :: Nil)
def Thicket(x1: Tree, x2: Tree, x3: Tree)(implicit src: SourceFile): Thicket = Thicket(x1 :: x2 :: x3 :: Nil)
Expand Down Expand Up @@ -1036,7 +1035,7 @@ object Trees {
def Select(tree: Tree)(qualifier: Tree, name: Name)(implicit ctx: Context): Select = tree match {
case tree: SelectWithSig =>
if ((qualifier eq tree.qualifier) && (name == tree.name)) tree
else finalize(tree, new SelectWithSig(qualifier, name, tree.sig)(sourceFile(tree)))
else finalize(tree, SelectWithSig(qualifier, name, tree.sig)(sourceFile(tree)))
case tree: Select if (qualifier eq tree.qualifier) && (name == tree.name) => tree
case _ => finalize(tree, untpd.Select(qualifier, name)(sourceFile(tree)))
}
Expand Down
32 changes: 16 additions & 16 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
ta.assignType(untpd.SeqLiteral(elems, elemtpt), elems, elemtpt)

def JavaSeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit ctx: Context): JavaSeqLiteral =
ta.assignType(new untpd.JavaSeqLiteral(elems, elemtpt), elems, elemtpt).asInstanceOf[JavaSeqLiteral]
ta.assignType(untpd.JavaSeqLiteral(elems, elemtpt), elems, elemtpt).asInstanceOf[JavaSeqLiteral]

def Inlined(call: Tree, bindings: List[MemberDef], expansion: Tree)(implicit ctx: Context): Inlined =
ta.assignType(untpd.Inlined(call, bindings, expansion), bindings, expansion)
Expand Down Expand Up @@ -231,7 +231,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def valueParamss(tp: Type): (List[List[TermSymbol]], Type) = tp match {
case tp: MethodType =>
val isParamDependent = tp.isParamDependent
val previousParamRefs = if (isParamDependent) new mutable.ListBuffer[TermRef]() else null
val previousParamRefs = if (isParamDependent) mutable.ListBuffer[TermRef]() else null

def valueParam(name: TermName, origInfo: Type): TermSymbol = {
val maybeImplicit =
Expand Down Expand Up @@ -294,7 +294,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
val newTypeParams =
for (tparam <- cls.typeParams if !(bodyTypeParams contains tparam))
yield TypeDef(tparam)
val findLocalDummy = new FindLocalDummyAccumulator(cls)
val findLocalDummy = FindLocalDummyAccumulator(cls)
val localDummy = ((NoSymbol: Symbol) /: body)(findLocalDummy.apply)
.orElse(ctx.newLocalDummy(cls))
val impl = untpd.Template(constr, parents, Nil, selfType, newTypeParams ++ body)
Expand Down Expand Up @@ -391,7 +391,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
private def followOuterLinks(t: Tree)(implicit ctx: Context) = t match {
case t: This if ctx.erasedTypes && !(t.symbol == ctx.owner.enclosingClass || t.symbol.isStaticOwner) =>
// after erasure outer paths should be respected
new ExplicitOuter.OuterOps(ctx).path(toCls = t.tpe.widen.classSymbol)
ExplicitOuter.OuterOps(ctx).path(toCls = t.tpe.widen.classSymbol)
case t =>
t
}
Expand Down Expand Up @@ -538,9 +538,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}

override val cpy: TypedTreeCopier = // Type ascription needed to pick up any new members in TreeCopier (currently there are none)
new TypedTreeCopier
TypedTreeCopier()

val cpyBetweenPhases: TimeTravellingTreeCopier = new TimeTravellingTreeCopier
val cpyBetweenPhases: TimeTravellingTreeCopier = TimeTravellingTreeCopier()

class TypedTreeCopier extends TreeCopier {
def postProcess(tree: Tree, copied: untpd.Tree): copied.ThisTree[Type] =
Expand Down Expand Up @@ -746,16 +746,16 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}

def shallowFold[T](z: T)(op: (T, tpd.Tree) => T)(implicit ctx: Context): T =
new ShallowFolder(op).apply(z, tree)
ShallowFolder(op).apply(z, tree)

def deepFold[T](z: T)(op: (T, tpd.Tree) => T)(implicit ctx: Context): T =
new DeepFolder(op).apply(z, tree)
DeepFolder(op).apply(z, tree)

def find[T](pred: (tpd.Tree) => Boolean)(implicit ctx: Context): Option[tpd.Tree] =
shallowFold[Option[tpd.Tree]](None)((accum, tree) => if (pred(tree)) Some(tree) else accum)

def subst(from: List[Symbol], to: List[Symbol])(implicit ctx: Context): ThisTree =
new TreeTypeMap(substFrom = from, substTo = to).apply(tree)
TreeTypeMap(substFrom = from, substTo = to).apply(tree)

/** Change owner from `from` to `to`. If `from` is a weak owner, also change its
* owner to `to`, and continue until a non-weak owner is reached.
Expand All @@ -766,7 +766,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
loop(from.owner, from :: froms, to :: tos)
else {
//println(i"change owner ${from :: froms}%, % ==> $tos of $tree")
new TreeTypeMap(oldOwners = from :: froms, newOwners = tos).apply(tree)
TreeTypeMap(oldOwners = from :: froms, newOwners = tos).apply(tree)
}
}
if (from == to) tree else loop(from, Nil, to :: Nil)
Expand All @@ -788,7 +788,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}
val owners = ownerAcc(immutable.Set.empty[Symbol], tree).toList
val newOwners = List.fill(owners.size)(newOwner)
new TreeTypeMap(oldOwners = owners, newOwners = newOwners).apply(tree)
TreeTypeMap(oldOwners = owners, newOwners = newOwners).apply(tree)
}

/** After phase `trans`, set the owner of every definition in this tree that was formerly
Expand Down Expand Up @@ -1008,7 +1008,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}

/** Replace Ident nodes references to the underlying tree that defined them */
def underlying(implicit ctx: Context): Tree = new MapToUnderlying().transform(tree)
def underlying(implicit ctx: Context): Tree = MapToUnderlying().transform(tree)

// --- Higher order traversal methods -------------------------------

Expand All @@ -1030,7 +1030,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {

/** All subtrees of this tree that satisfy predicate `p`. */
def filterSubTrees(f: Tree => Boolean)(implicit ctx: Context): List[Tree] = {
val buf = new mutable.ListBuffer[Tree]
val buf = mutable.ListBuffer[Tree]()
foreachSubTree { tree => if (f(tree)) buf += tree }
buf.toList
}
Expand Down Expand Up @@ -1137,7 +1137,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def applyOverloaded(receiver: Tree, method: TermName, args: List[Tree], targs: List[Type],
expectedType: Type, isContextual: Boolean = false)(implicit ctx: Context): Tree = {
val typer = ctx.typer
val proto = new FunProtoTyped(args, expectedType)(typer, isContextual)
val proto = FunProtoTyped(args, expectedType)(typer, isContextual)
val denot = receiver.tpe.member(method)
assert(denot.exists, i"no member $receiver . $method, members = ${receiver.tpe.decls}")
val selected =
Expand All @@ -1162,7 +1162,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
val fun = receiver.select(selected).appliedToTypes(targs)

val apply = untpd.Apply(fun, args)
new typer.ApplyToTyped(apply, fun, selected, args, expectedType).result.asInstanceOf[Tree] // needed to handle varargs
typer.ApplyToTyped(apply, fun, selected, args, expectedType).result.asInstanceOf[Tree] // needed to handle varargs
}

@tailrec
Expand Down Expand Up @@ -1221,7 +1221,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}

/** A key to be used in a context property that tracks enclosing inlined calls */
private val InlinedCalls = new Property.Key[List[Tree]]
private val InlinedCalls = Property.Key[List[Tree]]()

/** Record an enclosing inlined call.
* EmptyTree calls (for parameters) cancel the next-enclosing call in the list instead of being added to it.
Expand Down
21 changes: 10 additions & 11 deletions compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,11 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
class XMLBlock(stats: List[Tree], expr: Tree)(implicit @constructorOnly src: SourceFile) extends Block(stats, expr)

/** An enum to control checking or filtering of patterns in GenFrom trees */
class GenCheckMode(val x: Int) extends AnyVal
object GenCheckMode {
val Ignore = new GenCheckMode(0) // neither filter nor check since filtering was done before
val Check = new GenCheckMode(1) // check that pattern is irrefutable
val FilterNow = new GenCheckMode(2) // filter out non-matching elements since we are not in -strict
val FilterAlways = new GenCheckMode(3) // filter out non-matching elements since pattern is prefixed by `case`
enum GenCheckMode {
case Ignore // neither filter nor check since filtering was done before
case Check // check that pattern is irrefutable
case FilterNow //filter out non-matching elements since we are not in -strict
case FilterAlways // filter out non-matching elements since pattern is prefixed by `case`
}

// ----- Modifiers -----------------------------------------------------
Expand Down Expand Up @@ -247,7 +246,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def isEnumClass: Boolean = isEnum && !is(Case)
}

@sharable val EmptyModifiers: Modifiers = new Modifiers()
@sharable val EmptyModifiers: Modifiers = Modifiers()

// ----- TypeTrees that refer to other tree's symbols -------------------

Expand Down Expand Up @@ -285,16 +284,16 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
* from the symbol in this type. These type trees have marker trees
* TypeRefOfSym or InfoOfSym as their originals.
*/
val References: Property.Key[List[DerivedTypeTree]] = new Property.Key
val References: Property.Key[List[DerivedTypeTree]] = Property.Key()

/** Property key for TypeTrees marked with TypeRefOfSym or InfoOfSym
* which contains the symbol of the original tree from which this
* TypeTree is derived.
*/
val OriginalSymbol: Property.Key[Symbol] = new Property.Key
val OriginalSymbol: Property.Key[Symbol] = Property.Key()

/** Property key for contextual Apply trees of the form `fn given arg` */
val ApplyGiven: Property.StickyKey[Unit] = new Property.StickyKey
val ApplyGiven: Property.StickyKey[Unit] = Property.StickyKey()

// ------ Creation methods for untyped only -----------------

Expand Down Expand Up @@ -461,7 +460,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {

// --------- Copier/Transformer/Accumulator classes for untyped trees -----

override val cpy: UntypedTreeCopier = new UntypedTreeCopier
override val cpy: UntypedTreeCopier = UntypedTreeCopier()

class UntypedTreeCopier extends TreeCopier {

Expand Down
Loading