diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/doc/DocFactory.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala | 105 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 65 |
3 files changed, 111 insertions, 69 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala index 77e53bd90b..a99b17dce4 100644 --- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala @@ -31,15 +31,7 @@ import scala.reflect.internal.util.BatchSourceFile * @author Gilles Dubochet */ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor => /** The unique compiler instance used by this processor and constructed from its `settings`. */ - object compiler extends Global(settings, reporter) with interactive.RangePositions { - override protected def computeInternalPhases() { - phasesSet += syntaxAnalyzer - phasesSet += analyzer.namerFactory - phasesSet += analyzer.packageObjects - phasesSet += analyzer.typerFactory - } - override def forScaladoc = true - } + object compiler extends ScaladocGlobal(settings, reporter) /** Creates a scaladoc site for all symbols defined in this call's `source`, * as well as those defined in `sources` of previous calls to the same processor. diff --git a/src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala b/src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala new file mode 100644 index 0000000000..5e68152936 --- /dev/null +++ b/src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala @@ -0,0 +1,105 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package doc + +import scala.util.control.ControlThrowable +import reporters.Reporter +import typechecker.Analyzer +import scala.reflect.internal.util.BatchSourceFile + +trait ScaladocAnalyzer extends Analyzer { + val global : ScaladocGlobal + import global._ + + override def newTyper(context: Context): ScaladocTyper = new ScaladocTyper(context) + + class ScaladocTyper(context0: Context) extends Typer(context0) { + private def unit = context.unit + + override def typedDocDef(docDef: DocDef, mode: Mode, pt: Type): Tree = { + val sym = docDef.symbol + + if ((sym ne null) && (sym ne NoSymbol)) { + val comment = docDef.comment + docComments(sym) = comment + comment.defineVariables(sym) + val typer1 = newTyper(context.makeNewScope(docDef, context.owner)) + for (useCase <- comment.useCases) { + typer1.silent(_ => typer1 defineUseCases useCase) match { + case SilentTypeError(err) => + unit.warning(useCase.pos, err.errMsg) + case _ => + } + for (useCaseSym <- useCase.defined) { + if (sym.name != useCaseSym.name) + unit.warning(useCase.pos, "@usecase " + useCaseSym.name.decode + " does not match commented symbol: " + sym.name.decode) + } + } + } + + super.typedDocDef(docDef, mode, pt) + } + + def defineUseCases(useCase: UseCase): List[Symbol] = { + def stringParser(str: String): syntaxAnalyzer.Parser = { + val file = new BatchSourceFile(context.unit.source.file, str) { + override def positionInUltimateSource(pos: Position) = { + pos.withSource(context.unit.source, useCase.pos.start) + } + } + val unit = new CompilationUnit(file) + new syntaxAnalyzer.UnitParser(unit) + } + + val trees = stringParser(useCase.body+";").nonLocalDefOrDcl + val enclClass = context.enclClass.owner + + def defineAlias(name: Name) = ( + if (context.scope.lookup(name) == NoSymbol) { + lookupVariable(name.toString.substring(1), enclClass) foreach { repl => + silent(_.typedTypeConstructor(stringParser(repl).typ())) map { tpt => + val alias = enclClass.newAliasType(name.toTypeName, useCase.pos) + val tparams = cloneSymbolsAtOwner(tpt.tpe.typeSymbol.typeParams, alias) + val newInfo = genPolyType(tparams, appliedType(tpt.tpe, tparams map (_.tpe))) + alias setInfo newInfo + context.scope.enter(alias) + } + } + } + ) + + for (tree <- trees; t <- tree) + t match { + case Ident(name) if name startsWith '$' => defineAlias(name) + case _ => + } + + useCase.aliases = context.scope.toList + namer.enterSyms(trees) + typedStats(trees, NoSymbol) + useCase.defined = context.scope.toList filterNot (useCase.aliases contains _) + + if (settings.debug.value) + useCase.defined foreach (sym => println("defined use cases: %s:%s".format(sym, sym.tpe))) + + useCase.defined + } + } +} + +class ScaladocGlobal(settings: doc.Settings, reporter: Reporter) extends Global(settings, reporter) with interactive.RangePositions { + override protected def computeInternalPhases() { + phasesSet += syntaxAnalyzer + phasesSet += analyzer.namerFactory + phasesSet += analyzer.packageObjects + phasesSet += analyzer.typerFactory + } + override def forScaladoc = true + override lazy val analyzer = new { + val global: ScaladocGlobal.this.type = ScaladocGlobal.this + } with ScaladocAnalyzer +} diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 20907979e9..61ef13cfa9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -80,6 +80,7 @@ trait Typers extends Adaptations with Tags { case class SilentResultValue[+T](value: T) extends SilentResult[T] { } def newTyper(context: Context): Typer = new NormalTyper(context) + private class NormalTyper(context : Context) extends Typer(context) // A transient flag to mark members of anonymous classes @@ -105,6 +106,9 @@ trait Typers extends Adaptations with Tags { import typeDebug.{ ptTree, ptBlock, ptLine } import TyperErrorGen._ + def typedDocDef(docDef: DocDef, mode: Mode, pt: Type): Tree = + typed(docDef.definition, mode, pt) + val infer = new Inferencer(context0) { override def isCoercible(tp: Type, pt: Type): Boolean = undoLog undo { // #3281 tp.isError || pt.isError || @@ -2135,43 +2139,6 @@ trait Typers extends Adaptations with Tags { failStruct(ddef.tpt.pos, "a user-defined value class", where = "Result type") } - def typedUseCase(useCase: UseCase) { - def stringParser(str: String): syntaxAnalyzer.Parser = { - val file = new BatchSourceFile(context.unit.source.file, str) { - override def positionInUltimateSource(pos: Position) = { - pos.withSource(context.unit.source, useCase.pos.start) - } - } - val unit = new CompilationUnit(file) - new syntaxAnalyzer.UnitParser(unit) - } - val trees = stringParser(useCase.body+";").nonLocalDefOrDcl - val enclClass = context.enclClass.owner - def defineAlias(name: Name) = - if (context.scope.lookup(name) == NoSymbol) { - lookupVariable(name.toString.substring(1), enclClass) foreach { repl => - silent(_.typedTypeConstructor(stringParser(repl).typ())) map { tpt => - val alias = enclClass.newAliasType(name.toTypeName, useCase.pos) - val tparams = cloneSymbolsAtOwner(tpt.tpe.typeSymbol.typeParams, alias) - val newInfo = genPolyType(tparams, appliedType(tpt.tpe, tparams map (_.tpe))) - alias setInfo newInfo - context.scope.enter(alias) - } - } - } - for (tree <- trees; t <- tree) - t match { - case Ident(name) if name startsWith '$' => defineAlias(name) - case _ => - } - useCase.aliases = context.scope.toList - namer.enterSyms(trees) - typedStats(trees, NoSymbol) - useCase.defined = context.scope.toList filterNot (useCase.aliases contains _) - if (settings.debug.value) - useCase.defined foreach (sym => println("defined use cases: %s:%s".format(sym, sym.tpe))) - } - def typedDefDef(ddef: DefDef): DefDef = { val meth = ddef.symbol.initialize @@ -4875,28 +4842,6 @@ trait Typers extends Adaptations with Tags { .typedStats(pdef.stats, NoSymbol) treeCopy.PackageDef(tree, pid1, stats1) setType NoType } - - def typedDocDef(docdef: DocDef) = { - if (forScaladoc && (sym ne null) && (sym ne NoSymbol)) { - val comment = docdef.comment - docComments(sym) = comment - comment.defineVariables(sym) - val typer1 = newTyper(context.makeNewScope(tree, context.owner)) - for (useCase <- comment.useCases) { - typer1.silent(_.typedUseCase(useCase)) match { - case SilentTypeError(err) => - unit.warning(useCase.pos, err.errMsg) - case _ => - } - for (useCaseSym <- useCase.defined) { - if (sym.name != useCaseSym.name) - unit.warning(useCase.pos, "@usecase " + useCaseSym.name.decode + " does not match commented symbol: " + sym.name.decode) - } - } - } - typed(docdef.definition, mode, pt) - } - def defDefTyper(ddef: DefDef) = { val flag = ddef.mods.hasDefaultFlag && sym.owner.isModuleClass && nme.defaultGetterToMethod(sym.name) == nme.CONSTRUCTOR @@ -5154,7 +5099,7 @@ trait Typers extends Adaptations with Tags { case tree: TypeDef => typedTypeDef(tree) case tree: LabelDef => labelTyper(tree).typedLabelDef(tree) case tree: PackageDef => typedPackageDef(tree) - case tree: DocDef => typedDocDef(tree) + case tree: DocDef => typedDocDef(tree, mode, pt) case tree: Annotated => typedAnnotated(tree) case tree: SingletonTypeTree => typedSingletonTypeTree(tree) case tree: SelectFromTypeTree => typedSelectFromTypeTree(tree) |