Skip to content

Commit feaa0ae

Browse files
authored
Merge pull request #2042 from dotty-staging/matsuri
Last changes before presentation at Matsuri
2 parents 83a4f95 + 07cdb3d commit feaa0ae

File tree

13 files changed

+98
-35
lines changed

13 files changed

+98
-35
lines changed

compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import parsing.Tokens._
66
import scala.annotation.switch
77
import scala.collection.mutable.StringBuilder
88
import core.Contexts.Context
9+
import util.Chars.{ LF, FF, CR, SU }
910
import Highlighting.{Highlight, HighlightBuffer}
1011

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

3233
private val keywords: Seq[String] = for {
@@ -152,7 +153,11 @@ object SyntaxHighlighting {
152153
var open = 1
153154
while (open > 0 && remaining.nonEmpty) {
154155
curr = takeChar()
155-
newBuf += curr
156+
if (curr == '@') {
157+
appendWhile('@', !typeEnders.contains(_), annotation)
158+
newBuf append CommentColor
159+
}
160+
else newBuf += curr
156161

157162
if (curr == '*' && remaining.nonEmpty) {
158163
curr = takeChar()
@@ -163,6 +168,11 @@ object SyntaxHighlighting {
163168
newBuf += curr
164169
if (curr == '*') open += 1
165170
}
171+
172+
(curr: @switch) match {
173+
case LF | FF | CR | SU => newBuf append CommentColor
174+
case _ => ()
175+
}
166176
}
167177
prev = curr
168178
newBuf append NoColor
@@ -236,6 +246,11 @@ object SyntaxHighlighting {
236246
newBuf += curr
237247
closing = 0
238248
}
249+
250+
(curr: @switch) match {
251+
case LF | FF | CR | SU => newBuf append LiteralColor
252+
case _ => ()
253+
}
239254
}
240255
newBuf append NoColor
241256
prev = curr

compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ package reporting
55
import core.Contexts.Context
66
import core.Decorators._
77
import printing.Highlighting.{Blue, Red}
8+
import printing.SyntaxHighlighting
89
import diagnostic.{ErrorMessageID, Message, MessageContainer, NoExplanation}
910
import diagnostic.messages._
1011
import util.SourcePosition
12+
import util.Chars.{ LF, CR, FF, SU }
13+
import scala.annotation.switch
1114

1215
import scala.collection.mutable
1316

@@ -38,20 +41,37 @@ trait MessageRendering {
3841
*/
3942
def sourceLines(pos: SourcePosition)(implicit ctx: Context): (List[String], List[String], Int) = {
4043
var maxLen = Int.MinValue
41-
def render(xs: List[Int]) =
42-
xs.map(pos.source.offsetToLine(_))
43-
.map { lineNbr =>
44-
val prefix = s"${lineNbr + 1} |"
45-
maxLen = math.max(maxLen, prefix.length)
46-
(prefix, pos.lineContent(lineNbr).stripLineEnd)
47-
}
48-
.map { case (prefix, line) =>
49-
val lnum = Red(" " * math.max(0, maxLen - prefix.length) + prefix)
50-
hl"$lnum$line"
51-
}
44+
def render(offsetAndLine: (Int, String)): String = {
45+
val (offset, line) = offsetAndLine
46+
val lineNbr = pos.source.offsetToLine(offset)
47+
val prefix = s"${lineNbr + 1} |"
48+
maxLen = math.max(maxLen, prefix.length)
49+
val lnum = Red(" " * math.max(0, maxLen - prefix.length) + prefix).show
50+
lnum + line.stripLineEnd
51+
}
52+
53+
def linesFrom(arr: Array[Char]): List[String] = {
54+
def pred(c: Char) = (c: @switch) match {
55+
case LF | CR | FF | SU => true
56+
case _ => false
57+
}
58+
val (line, rest0) = arr.span(!pred(_))
59+
val (_, rest) = rest0.span(pred)
60+
new String(line) :: { if (rest.isEmpty) Nil else linesFrom(rest) }
61+
}
5262

63+
val syntax =
64+
if (ctx.settings.color.value != "never")
65+
SyntaxHighlighting(pos.linesSlice).toArray
66+
else pos.linesSlice
67+
val lines = linesFrom(syntax)
5368
val (before, after) = pos.beforeAndAfterPoint
54-
(render(before), render(after), maxLen)
69+
70+
(
71+
before.zip(lines).map(render),
72+
after.zip(lines.drop(before.length)).map(render),
73+
maxLen
74+
)
5575
}
5676

5777
/** The column markers aligned under the error */

compiler/src/dotty/tools/dotc/util/SourcePosition.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ extends interfaces.SourcePosition {
1212
def lineContent: String = source.lineContent(point)
1313

1414
def point: Int = pos.point
15+
1516
/** The line of the position, starting at 0 */
1617
def line: Int = source.offsetToLine(point)
1718

19+
/** Extracts the lines from the underlying source file as `Array[Char]`*/
20+
def linesSlice: Array[Char] =
21+
source.content.slice(source.startOfLine(start), source.nextLine(end))
22+
1823
/** The lines of the position */
1924
def lines: List[Int] =
2025
List.range(source.offsetToLine(start), source.offsetToLine(end + 1)) match {
@@ -25,9 +30,6 @@ extends interfaces.SourcePosition {
2530
def lineOffsets: List[Int] =
2631
lines.map(source.lineToOffset(_))
2732

28-
def lineContent(lineNumber: Int): String =
29-
source.lineContent(source.lineToOffset(lineNumber))
30-
3133
def beforeAndAfterPoint: (List[Int], List[Int]) =
3234
lineOffsets.partition(_ <= point)
3335

doc-tool/resources/_layouts/api-page.html

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,25 @@ <h1 class="section {% if entity.hasVisibleMembers == false %}empty{% endif %}">
134134
{% endfor %}
135135
{% endif %}
136136

137-
{% if member.kind == "type" and member.alias != null %}
137+
{% if member.kind == "type" %}
138+
{% for tparam in member.typeParams %}
139+
{% if forloop.first %}
140+
<span class="no-left">[</span>
141+
{% endif %}
142+
{% if forloop.last %}
143+
<span class="no-left">{{ tparam }}</span>
144+
<span class="no-left">]</span>
145+
{% else %}
146+
<span class="no-left">{{ tparam }}, </span>
147+
{% endif %}
148+
{% endfor %}
149+
{% if member.alias != null %}
138150
<span class="type-alias">
139151
<span class="equals"> = </span>
140152
{% renderRef member.alias %}
141153
</span>
142154
{% endif %}
155+
{% endif %}
143156

144157
{% if member.returnValue %}
145158
<span class="no-left">: {% renderRef member.returnValue %}</span>

doc-tool/resources/css/dottydoc.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,9 @@ pre > code.hljs {
328328
padding: 10px;
329329
background: transparent;
330330
}
331+
332+
blockquote {
333+
padding: 0 1em;
334+
color: #777;
335+
border-left: 0.25em solid #ddd;
336+
}

doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import dotc.CompilationUnit
88
import dotc.config.Printers.dottydoc
99
import dotc.core.Contexts.Context
1010
import dotc.core.Comments.ContextDocstrings
11-
import dotc.core.Types.NoType
11+
import dotc.core.Types.{PolyType, NoType}
1212
import dotc.core.Phases.Phase
1313
import dotc.core.Symbols.{ Symbol, NoSymbol }
1414

@@ -92,8 +92,16 @@ class DocASTPhase extends Phase {
9292
val sym = t.symbol
9393
if (sym.is(Flags.Synthetic | Flags.Param))
9494
NonEntity
95-
else
96-
TypeAliasImpl(sym, annotations(sym), flags(t), t.name.show.split("\\$\\$").last, path(sym), alias(t.rhs.tpe))
95+
else {
96+
val tparams = t.rhs.tpe match {
97+
case tp: PolyType => tp.paramRefs.zip(tp.variances).map { case (tp, variance) =>
98+
val varianceSym = if (variance == 1) "+" else if (variance == -1) "-" else ""
99+
varianceSym + tp.paramName.show
100+
}
101+
case _ => Nil
102+
}
103+
TypeAliasImpl(sym, annotations(sym), flags(t), t.name.show.split("\\$\\$").last, path(sym), alias(t.rhs.tpe), tparams)
104+
}
97105

98106
/** trait */
99107
case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) =>

doc-tool/src/dotty/tools/dottydoc/core/transform.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ object transform {
9292
t.name,
9393
t.path,
9494
t.alias,
95+
t.typeParams,
9596
t.comment,
9697
t.parent
9798
)

doc-tool/src/dotty/tools/dottydoc/model/JavaConverters.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ object JavaConverters {
189189
"name" -> ent.name,
190190
"path" -> ent.path.asJava,
191191
"alias" -> ent.alias.map(_.asJava).asJava,
192+
"typeParams" -> ent.typeParams.asJava,
192193
"comment" -> ent.comment.map(_.asJava).asJava,
193194
"hasShortenedDocstring" -> ent.hasShortenedDocstring,
194195
"isPrivate" -> ent.isPrivate,

doc-tool/src/dotty/tools/dottydoc/model/comment/CommentParser.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import dotty.tools.dottydoc.util.syntax._
66
import dotty.tools.dotc.util.Positions._
77
import dotty.tools.dotc.core.Symbols._
88
import dotty.tools.dotc.core.Contexts.Context
9+
import dotty.tools.dotc.core.Decorators._
910
import scala.collection.mutable
1011
import dotty.tools.dotc.config.Printers.dottydoc
1112
import scala.util.matching.Regex
@@ -196,7 +197,7 @@ trait CommentParser extends util.MemberLookup {
196197
)
197198

198199
for ((key, _) <- bodyTags) ctx.docbase.warn(
199-
s"Tag '@${key.name}' is not recognised",
200+
hl"Tag '${"@" + key.name}' is not recognised",
200201
// FIXME: here the position is stretched out over the entire comment,
201202
// with the point being at the very end. This ensures that the entire
202203
// comment will be visible in error reporting. A more fine-grained

doc-tool/src/dotty/tools/dottydoc/model/entities.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ trait Package extends Entity with Members with SuperTypes {
108108
val kind = "package"
109109
}
110110

111-
trait TypeAlias extends Entity with Modifiers {
111+
trait TypeAlias extends Entity with Modifiers with TypeParams {
112112
val kind = "type"
113113
def alias: Option[Reference]
114114
def isAbstract: Boolean = !alias.isDefined

doc-tool/src/dotty/tools/dottydoc/model/factories.scala

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ package model
44
import comment._
55
import references._
66
import dotty.tools.dotc
7-
import dotc.core.Types._
7+
import dotc.core.Types
8+
import Types._
89
import dotc.core.TypeApplications._
910
import dotc.core.Contexts.Context
1011
import dotc.core.Symbols.{ Symbol, ClassSymbol }
@@ -105,17 +106,8 @@ object factories {
105106
case ci: ClassInfo =>
106107
typeRef(ci.cls.name.show, query = ci.typeSymbol.showFullName)
107108

108-
case tl: PolyType => {
109-
// FIXME: should be handled correctly
110-
// example, in `Option`:
111-
//
112-
// ```scala
113-
// def companion: GenericCompanion[collection.Iterable]
114-
// ```
115-
//
116-
// Becomes: def companion: [+X0] -> collection.Iterable[X0]
117-
typeRef(tl.show + " (not handled)")
118-
}
109+
case tl: PolyType =>
110+
expandTpe(tl.resType)
119111

120112
case OrType(left, right) =>
121113
OrTypeReference(expandTpe(left), expandTpe(right))
@@ -148,6 +140,8 @@ object factories {
148140
prefix + tp.name.show.split("\\$").last
149141
}
150142
.toList
143+
case tp: Types.TypeAlias =>
144+
typeParams(tp.alias.typeSymbol)
151145
case _ =>
152146
Nil
153147
}

doc-tool/src/dotty/tools/dottydoc/model/internal.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ object internal {
3131
name: String,
3232
path: List[String],
3333
alias: Option[Reference],
34+
typeParams: List[String] = Nil,
3435
var comment: Option[Comment] = None,
3536
var parent: Entity = NonEntity
3637
) extends TypeAlias

doc-tool/src/dotty/tools/dottydoc/staticsite/tags.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ object tags {
180180
override def render(ctx: TemplateContext, nodes: LNode*): AnyRef =
181181
(nodes(0).render(ctx), nodes(1).render(ctx)) match {
182182
case (t: Title, parent: String) => renderTitle(t, parent)
183+
case (t: Title, _) => renderTitle(t, "./") // file is in top dir
183184
case _ => null
184185
}
185186
}

0 commit comments

Comments
 (0)