diff options
author | Martin Odersky <odersky@gmail.com> | 2014-09-04 08:35:42 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-09-04 08:41:01 +0200 |
commit | 225102627d37f16134bc682eb5b01270684a02e4 (patch) | |
tree | 6a57d22adc7c8231b7fbfcc22832ab68a698cb95 | |
parent | 2558c49984611935fff91b0b062f6af5a61e71ce (diff) | |
download | dotty-225102627d37f16134bc682eb5b01270684a02e4.tar.gz dotty-225102627d37f16134bc682eb5b01270684a02e4.tar.bz2 dotty-225102627d37f16134bc682eb5b01270684a02e4.zip |
Add inSuperCall mode and flag.
Needed to keep a record of definitions in supercall arguments. These
may not see the enclosing class.
-rw-r--r-- | src/dotty/tools/dotc/ast/tpd.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Flags.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/printing/RefinedPrinter.scala | 13 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeTransform.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Mode.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 6 |
9 files changed, 33 insertions, 22 deletions
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala index 58d356d15..175a6b37e 100644 --- a/src/dotty/tools/dotc/ast/tpd.scala +++ b/src/dotty/tools/dotc/ast/tpd.scala @@ -267,7 +267,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { } try test catch { // See remark in SymDenotations#accessWithin - case ex: NotDefinedHere => test(ctx.withMode(Mode.FutureDefsOK)) + case ex: NotDefinedHere => test(ctx.addMode(Mode.FutureDefsOK)) } } diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index b221d4083..6b9b1dec7 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -267,6 +267,7 @@ object Contexts { * - as owner: The primary constructor of the class * - as outer context: The context enclosing the class context * - as scope: The parameter accessors in the class context + * - with additional mode: InSuperCall * * The reasons for this peculiar choice of attributes are as follows: * @@ -303,7 +304,7 @@ object Contexts { /** The super= or this-call context with given owner and locals. */ private def superOrThisCallContext(owner: Symbol, locals: Scope): FreshContext = { assert(isClassDefContext) - outer.fresh.setOwner(owner).setScope(locals) + outer.fresh.setOwner(owner).setScope(locals).setMode(ctx.mode | Mode.InSuperCall) } /** The current source file; will be derived from current diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index d28a879d1..f89a5ce46 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -238,9 +238,6 @@ object Flags { /** A mutable var */ final val Mutable = termFlag(12, "mutable") - /** Class symbol is defined in this/superclass constructor. */ - final val InConstructor = typeFlag(12, "<inconstructor>") - /** Symbol is local to current class (i.e. private[this] or protected[this] * pre: Private or Protected are also set */ @@ -359,6 +356,9 @@ object Flags { // Flags following this one are not pickled + /** Symbol is defined in a super call */ + final val InSuperCall = commonFlag(46, "<in supercall>") + /** Symbol with private access is accessed outside its private scope */ final val NotJavaPrivate = commonFlag(47, "<not-java-private>") @@ -432,8 +432,8 @@ object Flags { /** Flags guaranteed to be set upon symbol creation */ final val FromStartFlags = - AccessFlags | Module | Package | Deferred | MethodOrHKCommon | Param | ParamAccessor | Scala2ExistentialCommon | Touched | - Static | CovariantOrOuter | ContravariantOrLabel | ExpandedName | AccessorOrSealed | + AccessFlags | Module | Package | Deferred | MethodOrHKCommon | Param | ParamAccessor | Scala2ExistentialCommon | + InSuperCall | Touched | Static | CovariantOrOuter | ContravariantOrLabel | ExpandedName | AccessorOrSealed | CaseAccessorOrTypeArgument | Frozen | Erroneous | ImplicitCommon | Permanent | SelfNameOrImplClass assert(FromStartFlags.isTermFlags && FromStartFlags.isTypeFlags) @@ -476,7 +476,7 @@ object Flags { /** Flags that can apply to a module class */ final val RetainedModuleClassFlags: FlagSet = RetainedModuleValAndClassFlags | - InConstructor | ImplClass + InSuperCall | ImplClass /** Packages and package classes always have these flags set */ final val PackageCreationFlags = diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala index eba27dfef..d66d93a16 100644 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -125,7 +125,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { case JavaArrayType(elemtp) => return toText(elemtp) ~ "[]" case tp: SelectionProto => - return toText(RefinedType(WildcardType, tp.name, tp.memberProto)) + return "?{ " ~ toText(tp.name) ~ ": " ~ toText(tp.memberProto) ~ " }" case tp: ViewProto => return toText(tp.argType) ~ " ?=>? " ~ toText(tp.resultType) case FunProto(args, resultType, _) => @@ -180,11 +180,15 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { def annotText(tree: untpd.Tree): Text = "@" ~ constrText(tree) // DD + def useSymbol = ctx.isAfterTyper(ctx.phase) && tree.symbol != null && tree.symbol.exists + def modText(mods: untpd.Modifiers, kw: String): Text = { // DD val suppressKw = if (ownerIsClass) mods is ParamAndLocal else mods is Param val flagMask = if (suppressKw) PrintableFlags &~ Private else PrintableFlags - val modsText: Text = (mods.flags & flagMask).toString - Text(mods.annotations.map(annotText), " ") ~~ modsText ~~ (kw provided !suppressKw) + val flagsText: Text = + if (useSymbol) toTextFlags(tree.symbol) + else (mods.flags & flagMask).toString + Text(mods.annotations.map(annotText), " ") ~~ flagsText ~~ (kw provided !suppressKw) } def argText(arg: Tree[T]): Text = arg match { @@ -198,8 +202,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { } def dclTextOr(treeText: => Text) = - if (ctx.isAfterTyper(ctx.phase) && tree.symbol != null && tree.symbol.exists) - annotsText(tree.symbol) ~~ dclText(tree.symbol) + if (useSymbol) annotsText(tree.symbol) ~~ dclText(tree.symbol) else treeText def idText(tree: untpd.Tree): Text = { diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala index 98447cc40..6f5956775 100644 --- a/src/dotty/tools/dotc/transform/TreeTransform.scala +++ b/src/dotty/tools/dotc/transform/TreeTransform.scala @@ -1081,7 +1081,7 @@ object TreeTransforms { implicit val mutatedInfo: TransformerInfo = mutateTransformers(info, prepForCaseDef, info.nx.nxPrepCaseDef, tree, cur) if (mutatedInfo eq null) tree else { - val pat = transform(tree.pat, mutatedInfo, cur)(ctx.withMode(Mode.Pattern)) + val pat = transform(tree.pat, mutatedInfo, cur)(ctx.addMode(Mode.Pattern)) val guard = transform(tree.guard, mutatedInfo, cur) val body = transform(tree.body, mutatedInfo, cur) goCaseDef(cpy.CaseDef(tree)(pat, guard, body), mutatedInfo.nx.nxTransCaseDef(cur)) diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index ab6514507..f3e9fda74 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -154,7 +154,7 @@ object Checking { * by a `LazyRef`, or `ErrorType` if a cycle was detected and reported. */ def checkNonCyclic(sym: Symbol, info: Type, reportErrors: Boolean)(implicit ctx: Context): Type = { - val checker = new CheckNonCyclicMap(sym, reportErrors)(ctx.withMode(Mode.CheckCyclic)) + val checker = new CheckNonCyclicMap(sym, reportErrors)(ctx.addMode(Mode.CheckCyclic)) try checker.checkInfo(info) catch { case ex: CyclicReference => diff --git a/src/dotty/tools/dotc/typer/Mode.scala b/src/dotty/tools/dotc/typer/Mode.scala index eb911987b..f855ef1c2 100644 --- a/src/dotty/tools/dotc/typer/Mode.scala +++ b/src/dotty/tools/dotc/typer/Mode.scala @@ -34,6 +34,8 @@ object Mode { val TypevarsMissContext = newMode(4, "TypevarsMissContext") val CheckCyclic = newMode(5, "CheckCyclic") + val InSuperCall = newMode(6, "InSuperCall") + /** This mode bit is set if we want to allow accessing a symbol's denotation * at a period before that symbol is first valid. An example where this is * the case is if we want to examine the environment where an access is made. @@ -44,7 +46,7 @@ object Mode { * before the symbol is defined will return the symbol's denotation at the * first phase where it is valid, instead of throwing a NotDefinedHere error. */ - val FutureDefsOK = newMode(6, "FutureDefsOK") + val FutureDefsOK = newMode(7, "FutureDefsOK") val PatternOrType = Pattern | Type }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 782faf0d4..5ceab475e 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -200,7 +200,7 @@ class Namer { typer: Typer => } else completer - typr.println(i"creating symbol for $tree") + typr.println(i"creating symbol for $tree in ${ctx.mode}") def checkNoConflict(name: Name): Unit = { def preExisting = ctx.effectiveScope.lookup(name) @@ -213,12 +213,13 @@ class Namer { typer: Typer => } } + val inSuperCall = if (ctx.mode is Mode.InSuperCall) InSuperCall else EmptyFlags tree match { case tree: TypeDef if tree.isClassDef => val name = tree.name.encode.asTypeName checkNoConflict(name) val cls = record(ctx.newClassSymbol( - ctx.owner, name, tree.mods.flags, + ctx.owner, name, tree.mods.flags | inSuperCall, cls => adjustIfModule(new ClassCompleter(cls, tree)(ctx), tree), privateWithinClass(tree.mods), tree.pos, ctx.source.file)) cls.completer.asInstanceOf[ClassCompleter].init() @@ -229,6 +230,8 @@ class Namer { typer: Typer => val isDeferred = lacksDefinition(tree) val deferred = if (isDeferred) Deferred else EmptyFlags val method = if (tree.isInstanceOf[DefDef]) Method else EmptyFlags + val inSuperCall1 = if (tree.mods is ParamOrAccessor) EmptyFlags else inSuperCall + // suppress inSuperCall for constructor parameters val higherKinded = tree match { case tree: TypeDef if tree.tparams.nonEmpty && isDeferred => HigherKinded case _ => EmptyFlags @@ -243,7 +246,7 @@ class Namer { typer: Typer => val cctx = if (tree.name == nme.CONSTRUCTOR) ctx.outer else ctx record(ctx.newSymbol( - ctx.owner, name, tree.mods.flags | deferred | method | higherKinded, + ctx.owner, name, tree.mods.flags | deferred | method | higherKinded | inSuperCall1, adjustIfModule(new Completer(tree)(cctx), tree), privateWithinClass(tree.mods), tree.pos)) case tree: Import => @@ -428,7 +431,7 @@ class Namer { typer: Typer => class ClassCompleter(cls: ClassSymbol, original: TypeDef)(ictx: Context) extends Completer(original)(ictx) { withDecls(newScope) - protected implicit val ctx: Context = localContext(cls) + protected implicit val ctx: Context = localContext(cls).setMode(ictx.mode &~ Mode.InSuperCall) val TypeDef(_, name, impl @ Template(constr, parents, self, body)) = original diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index f58ccbdbc..9c5fb09b0 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -951,8 +951,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val typer1 = localTyper(sym) typer1.typedDefDef(tree, sym)(localContext(tree, sym).setTyper(typer1)) case tree: untpd.TypeDef => - if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext(tree, sym)) - else typedTypeDef(tree, sym)(localContext(tree, sym).setNewScope) + if (tree.isClassDef) + typedClassDef(tree, sym.asClass)(localContext(tree, sym).setMode(ctx.mode &~ Mode.InSuperCall)) + else + typedTypeDef(tree, sym)(localContext(tree, sym).setNewScope) case _ => typedUnadapted(desugar(tree), pt) } } |