diff options
author | Paul Phillips <paulp@improving.org> | 2013-01-14 23:31:30 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-01-14 23:33:01 -0800 |
commit | aedec19808a7a3d383f839d2ee2c2ec4265fb9c6 (patch) | |
tree | 28ecd4e196b1af08232b8e2f327e11aea3dca468 /src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala | |
parent | 2d4ed8e795b814f3d71bc6bb4949e4c2a5510da8 (diff) | |
download | scala-aedec19808a7a3d383f839d2ee2c2ec4265fb9c6.tar.gz scala-aedec19808a7a3d383f839d2ee2c2ec4265fb9c6.tar.bz2 scala-aedec19808a7a3d383f839d2ee2c2ec4265fb9c6.zip |
Granted scaladoc its own Global.
An incremental step on the road to disentangling
scaladoc from the compiler sources. This pushes the
elements in typer outward so scaladoc can subclass
Global like everyone else.
Diffstat (limited to 'src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala | 105 |
1 files changed, 105 insertions, 0 deletions
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 +} |