Skip to content

Last changes before presentation at Matsuri #2042

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 4 commits into from
Mar 1, 2017
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
19 changes: 17 additions & 2 deletions compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import parsing.Tokens._
import scala.annotation.switch
import scala.collection.mutable.StringBuilder
import core.Contexts.Context
import util.Chars.{ LF, FF, CR, SU }
import Highlighting.{Highlight, HighlightBuffer}

/** This object provides functions for syntax highlighting in the REPL */
Expand All @@ -26,7 +27,7 @@ object SyntaxHighlighting {
private def valDef(str: String) = ValDefColor + str + NoColor
private def operator(str: String) = TypeColor + str + NoColor
private def annotation(str: String) =
if (str.trim == "@") str else AnnotationColor + str + NoColor
if (str.trim == "@") str else { AnnotationColor + str + NoColor }
private val tripleQs = Console.RED_B + "???" + NoColor

private val keywords: Seq[String] = for {
Expand Down Expand Up @@ -152,7 +153,11 @@ object SyntaxHighlighting {
var open = 1
while (open > 0 && remaining.nonEmpty) {
curr = takeChar()
newBuf += curr
if (curr == '@') {
appendWhile('@', !typeEnders.contains(_), annotation)
newBuf append CommentColor
}
else newBuf += curr

if (curr == '*' && remaining.nonEmpty) {
curr = takeChar()
Expand All @@ -163,6 +168,11 @@ object SyntaxHighlighting {
newBuf += curr
if (curr == '*') open += 1
}

(curr: @switch) match {
case LF | FF | CR | SU => newBuf append CommentColor
case _ => ()
}
}
prev = curr
newBuf append NoColor
Expand Down Expand Up @@ -236,6 +246,11 @@ object SyntaxHighlighting {
newBuf += curr
closing = 0
}

(curr: @switch) match {
case LF | FF | CR | SU => newBuf append LiteralColor
case _ => ()
}
}
newBuf append NoColor
prev = curr
Expand Down
44 changes: 32 additions & 12 deletions compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ package reporting
import core.Contexts.Context
import core.Decorators._
import printing.Highlighting.{Blue, Red}
import printing.SyntaxHighlighting
import diagnostic.{ErrorMessageID, Message, MessageContainer, NoExplanation}
import diagnostic.messages._
import util.SourcePosition
import util.Chars.{ LF, CR, FF, SU }
import scala.annotation.switch

import scala.collection.mutable

Expand Down Expand Up @@ -38,20 +41,37 @@ trait MessageRendering {
*/
def sourceLines(pos: SourcePosition)(implicit ctx: Context): (List[String], List[String], Int) = {
var maxLen = Int.MinValue
def render(xs: List[Int]) =
xs.map(pos.source.offsetToLine(_))
.map { lineNbr =>
val prefix = s"${lineNbr + 1} |"
maxLen = math.max(maxLen, prefix.length)
(prefix, pos.lineContent(lineNbr).stripLineEnd)
}
.map { case (prefix, line) =>
val lnum = Red(" " * math.max(0, maxLen - prefix.length) + prefix)
hl"$lnum$line"
}
def render(offsetAndLine: (Int, String)): String = {
val (offset, line) = offsetAndLine
val lineNbr = pos.source.offsetToLine(offset)
val prefix = s"${lineNbr + 1} |"
maxLen = math.max(maxLen, prefix.length)
val lnum = Red(" " * math.max(0, maxLen - prefix.length) + prefix).show
lnum + line.stripLineEnd
}

def linesFrom(arr: Array[Char]): List[String] = {
def pred(c: Char) = (c: @switch) match {
case LF | CR | FF | SU => true
case _ => false
}
val (line, rest0) = arr.span(!pred(_))
val (_, rest) = rest0.span(pred)
new String(line) :: { if (rest.isEmpty) Nil else linesFrom(rest) }
}

val syntax =
if (ctx.settings.color.value != "never")
SyntaxHighlighting(pos.linesSlice).toArray
else pos.linesSlice
val lines = linesFrom(syntax)
val (before, after) = pos.beforeAndAfterPoint
(render(before), render(after), maxLen)

(
before.zip(lines).map(render),
after.zip(lines.drop(before.length)).map(render),
maxLen
)
}

/** The column markers aligned under the error */
Expand Down
8 changes: 5 additions & 3 deletions compiler/src/dotty/tools/dotc/util/SourcePosition.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ extends interfaces.SourcePosition {
def lineContent: String = source.lineContent(point)

def point: Int = pos.point

/** The line of the position, starting at 0 */
def line: Int = source.offsetToLine(point)

/** Extracts the lines from the underlying source file as `Array[Char]`*/
def linesSlice: Array[Char] =
source.content.slice(source.startOfLine(start), source.nextLine(end))

/** The lines of the position */
def lines: List[Int] =
List.range(source.offsetToLine(start), source.offsetToLine(end + 1)) match {
Expand All @@ -25,9 +30,6 @@ extends interfaces.SourcePosition {
def lineOffsets: List[Int] =
lines.map(source.lineToOffset(_))

def lineContent(lineNumber: Int): String =
source.lineContent(source.lineToOffset(lineNumber))

def beforeAndAfterPoint: (List[Int], List[Int]) =
lineOffsets.partition(_ <= point)

Expand Down
15 changes: 14 additions & 1 deletion doc-tool/resources/_layouts/api-page.html
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,25 @@ <h1 class="section {% if entity.hasVisibleMembers == false %}empty{% endif %}">
{% endfor %}
{% endif %}

{% if member.kind == "type" and member.alias != null %}
{% if member.kind == "type" %}
{% for tparam in member.typeParams %}
{% if forloop.first %}
<span class="no-left">[</span>
{% endif %}
{% if forloop.last %}
<span class="no-left">{{ tparam }}</span>
<span class="no-left">]</span>
{% else %}
<span class="no-left">{{ tparam }}, </span>
{% endif %}
{% endfor %}
{% if member.alias != null %}
<span class="type-alias">
<span class="equals"> = </span>
{% renderRef member.alias %}
</span>
{% endif %}
{% endif %}

{% if member.returnValue %}
<span class="no-left">: {% renderRef member.returnValue %}</span>
Expand Down
6 changes: 6 additions & 0 deletions doc-tool/resources/css/dottydoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,9 @@ pre > code.hljs {
padding: 10px;
background: transparent;
}

blockquote {
padding: 0 1em;
color: #777;
border-left: 0.25em solid #ddd;
}
14 changes: 11 additions & 3 deletions doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import dotc.CompilationUnit
import dotc.config.Printers.dottydoc
import dotc.core.Contexts.Context
import dotc.core.Comments.ContextDocstrings
import dotc.core.Types.NoType
import dotc.core.Types.{PolyType, NoType}
import dotc.core.Phases.Phase
import dotc.core.Symbols.{ Symbol, NoSymbol }

Expand Down Expand Up @@ -92,8 +92,16 @@ class DocASTPhase extends Phase {
val sym = t.symbol
if (sym.is(Flags.Synthetic | Flags.Param))
NonEntity
else
TypeAliasImpl(sym, annotations(sym), flags(t), t.name.show.split("\\$\\$").last, path(sym), alias(t.rhs.tpe))
else {
val tparams = t.rhs.tpe match {
case tp: PolyType => tp.paramRefs.zip(tp.variances).map { case (tp, variance) =>
val varianceSym = if (variance == 1) "+" else if (variance == -1) "-" else ""
varianceSym + tp.paramName.show
}
case _ => Nil
}
TypeAliasImpl(sym, annotations(sym), flags(t), t.name.show.split("\\$\\$").last, path(sym), alias(t.rhs.tpe), tparams)
}

/** trait */
case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) =>
Expand Down
1 change: 1 addition & 0 deletions doc-tool/src/dotty/tools/dottydoc/core/transform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ object transform {
t.name,
t.path,
t.alias,
t.typeParams,
t.comment,
t.parent
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ object JavaConverters {
"name" -> ent.name,
"path" -> ent.path.asJava,
"alias" -> ent.alias.map(_.asJava).asJava,
"typeParams" -> ent.typeParams.asJava,
"comment" -> ent.comment.map(_.asJava).asJava,
"hasShortenedDocstring" -> ent.hasShortenedDocstring,
"isPrivate" -> ent.isPrivate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dotty.tools.dottydoc.util.syntax._
import dotty.tools.dotc.util.Positions._
import dotty.tools.dotc.core.Symbols._
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Decorators._
import scala.collection.mutable
import dotty.tools.dotc.config.Printers.dottydoc
import scala.util.matching.Regex
Expand Down Expand Up @@ -196,7 +197,7 @@ trait CommentParser extends util.MemberLookup {
)

for ((key, _) <- bodyTags) ctx.docbase.warn(
s"Tag '@${key.name}' is not recognised",
hl"Tag '${"@" + key.name}' is not recognised",
// FIXME: here the position is stretched out over the entire comment,
// with the point being at the very end. This ensures that the entire
// comment will be visible in error reporting. A more fine-grained
Expand Down
2 changes: 1 addition & 1 deletion doc-tool/src/dotty/tools/dottydoc/model/entities.scala
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ trait Package extends Entity with Members with SuperTypes {
val kind = "package"
}

trait TypeAlias extends Entity with Modifiers {
trait TypeAlias extends Entity with Modifiers with TypeParams {
val kind = "type"
def alias: Option[Reference]
def isAbstract: Boolean = !alias.isDefined
Expand Down
18 changes: 6 additions & 12 deletions doc-tool/src/dotty/tools/dottydoc/model/factories.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ package model
import comment._
import references._
import dotty.tools.dotc
import dotc.core.Types._
import dotc.core.Types
import Types._
import dotc.core.TypeApplications._
import dotc.core.Contexts.Context
import dotc.core.Symbols.{ Symbol, ClassSymbol }
Expand Down Expand Up @@ -105,17 +106,8 @@ object factories {
case ci: ClassInfo =>
typeRef(ci.cls.name.show, query = ci.typeSymbol.showFullName)

case tl: PolyType => {
// FIXME: should be handled correctly
// example, in `Option`:
//
// ```scala
// def companion: GenericCompanion[collection.Iterable]
// ```
//
// Becomes: def companion: [+X0] -> collection.Iterable[X0]
typeRef(tl.show + " (not handled)")
}
case tl: PolyType =>
expandTpe(tl.resType)

case OrType(left, right) =>
OrTypeReference(expandTpe(left), expandTpe(right))
Expand Down Expand Up @@ -148,6 +140,8 @@ object factories {
prefix + tp.name.show.split("\\$").last
}
.toList
case tp: Types.TypeAlias =>
typeParams(tp.alias.typeSymbol)
case _ =>
Nil
}
Expand Down
1 change: 1 addition & 0 deletions doc-tool/src/dotty/tools/dottydoc/model/internal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ object internal {
name: String,
path: List[String],
alias: Option[Reference],
typeParams: List[String] = Nil,
var comment: Option[Comment] = None,
var parent: Entity = NonEntity
) extends TypeAlias
Expand Down
1 change: 1 addition & 0 deletions doc-tool/src/dotty/tools/dottydoc/staticsite/tags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ object tags {
override def render(ctx: TemplateContext, nodes: LNode*): AnyRef =
(nodes(0).render(ctx), nodes(1).render(ctx)) match {
case (t: Title, parent: String) => renderTitle(t, parent)
case (t: Title, _) => renderTitle(t, "./") // file is in top dir
case _ => null
}
}
Expand Down