diff options
author | Martin Odersky <odersky@gmail.com> | 2015-10-21 17:49:27 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-10-22 12:21:26 +0200 |
commit | f1b3859911ee04a90a0b169c5eefa2c64ce5d265 (patch) | |
tree | 0d8d90bc89d62a83c7bd1395ecac1e43f922bd09 /src/dotty/tools/dotc/typer/Namer.scala | |
parent | 54f5899b0888983495f5ff70f561d9634350f3f2 (diff) | |
download | dotty-f1b3859911ee04a90a0b169c5eefa2c64ce5d265.tar.gz dotty-f1b3859911ee04a90a0b169c5eefa2c64ce5d265.tar.bz2 dotty-f1b3859911ee04a90a0b169c5eefa2c64ce5d265.zip |
Add well-formedness checking for created symbols
Enforces various restrictions of definitions.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Namer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index d97bbff91..52989c1a5 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -234,6 +234,18 @@ class Namer { typer: Typer => sym } + def checkFlags(flags: FlagSet) = + if (flags.isEmpty) flags + else { + val (ok, adapted, kind) = tree match { + case tree: TypeDef => (flags.isTypeFlags, flags.toTypeFlags, "type") + case _ => (flags.isTermFlags, flags.toTermFlags, "value") + } + if (!ok) + ctx.error(i"modifier(s) `$flags' incompatible with $kind definition", tree.pos) + adapted + } + /** Add moduleClass/sourceModule to completer if it is for a module val or class */ def adjustIfModule(completer: LazyType, tree: MemberDef) = if (tree.mods is Module) ctx.adjustModuleCompleter(completer, tree.name.encode) @@ -261,14 +273,16 @@ class Namer { typer: Typer => tree match { case tree: TypeDef if tree.isClassDef => val name = checkNoConflict(tree.name.encode).asTypeName + val flags = checkFlags(tree.mods.flags &~ Implicit) val cls = record(ctx.newClassSymbol( - ctx.owner, name, tree.mods.flags | inSuperCall, + ctx.owner, name, flags | inSuperCall, cls => adjustIfModule(new ClassCompleter(cls, tree)(ctx), tree), privateWithinClass(tree.mods), tree.pos, ctx.source.file)) cls.completer.asInstanceOf[ClassCompleter].init() cls case tree: MemberDef => val name = checkNoConflict(tree.name.encode) + val flags = checkFlags(tree.mods.flags) val isDeferred = lacksDefinition(tree) val deferred = if (isDeferred) Deferred else EmptyFlags val method = if (tree.isInstanceOf[DefDef]) Method else EmptyFlags @@ -291,7 +305,7 @@ class Namer { typer: Typer => val cctx = if (tree.name == nme.CONSTRUCTOR && !(tree.mods is JavaDefined)) ctx.outer else ctx record(ctx.newSymbol( - ctx.owner, name, tree.mods.flags | deferred | method | higherKinded | inSuperCall1, + ctx.owner, name, flags | deferred | method | higherKinded | inSuperCall1, adjustIfModule(new Completer(tree)(cctx), tree), privateWithinClass(tree.mods), tree.pos)) case tree: Import => @@ -517,6 +531,7 @@ class Namer { typer: Typer => def completeInCreationContext(denot: SymDenotation): Unit = { denot.info = typeSig(denot.symbol) addAnnotations(denot) + Checking.checkWellFormed(denot.symbol) } } @@ -585,6 +600,7 @@ class Namer { typer: Typer => index(rest)(inClassContext(selfInfo)) denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo) addAnnotations(denot) + Checking.checkWellFormed(cls) if (isDerivedValueClass(cls)) cls.setFlag(Final) cls.setApplicableFlags( (NoInitsInterface /: impl.body)((fs, stat) => fs & defKind(stat))) |