aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala7
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala7
-rw-r--r--compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala19
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala44
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java1
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Checking.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/util/SourcePosition.scala8
-rw-r--r--compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala14
10 files changed, 98 insertions, 29 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index 847177e2f..79e97becb 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -906,13 +906,6 @@ class Definitions {
/** The type of the boxed class corresponding to primitive value type `tp`. */
def boxedType(tp: Type)(implicit ctx: Context): TypeRef = boxedTypes(scalaClassName(tp))
- def wrapArrayMethodName(elemtp: Type): TermName = {
- val cls = elemtp.classSymbol
- if (cls.isPrimitiveValueClass) nme.wrapXArray(cls.name)
- else if (cls.derivesFrom(ObjectClass) && !cls.isPhantomClass) nme.wrapRefArray
- else nme.genericWrapArray
- }
-
type PrimitiveClassEnc = Int
val ByteEnc = 2
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index c14108d2e..b27bff37a 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -1607,6 +1607,7 @@ object Parsers {
* LocalModifier ::= abstract | final | sealed | implicit | lazy
*/
def modifiers(allowed: BitSet = modifierTokens, start: Modifiers = Modifiers()): Modifiers = {
+ @tailrec
def loop(mods: Modifiers): Modifiers = {
if (allowed contains in.token) {
val isAccessMod = accessModifierTokens contains in.token
@@ -2057,7 +2058,7 @@ object Parsers {
val name = ident().toTypeName
val constr = atPos(in.lastOffset) {
val tparams = typeParamClauseOpt(ParamOwner.Class)
- val cmods = constrModsOpt()
+ val cmods = constrModsOpt(name)
val vparamss = paramClauses(name, mods is Case)
makeConstructor(tparams, vparamss).withMods(cmods)
@@ -2070,11 +2071,11 @@ object Parsers {
/** ConstrMods ::= AccessModifier
* | Annotation {Annotation} (AccessModifier | `this')
*/
- def constrModsOpt(): Modifiers = {
+ def constrModsOpt(owner: Name): Modifiers = {
val mods = modifiers(accessModifierTokens, annotsAsMods())
if (mods.hasAnnotations && !mods.hasFlags)
if (in.token == THIS) in.nextToken()
- else syntaxError("`private', `protected', or `this' expected")
+ else syntaxError(AnnotatedPrimaryConstructorRequiresModifierOrThis(owner), mods.annotations.last.pos)
mods
}
diff --git a/compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala b/compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala
index 86f34e64d..e20f846ac 100644
--- a/compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala
+++ b/compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala
@@ -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 */
@@ -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 {
@@ -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()
@@ -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
@@ -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
diff --git a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala
index 190445d60..17eb8d39b 100644
--- a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala
@@ -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
@@ -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 */
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java
index 2bf15cb7c..bbd93eb30 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java
@@ -51,6 +51,7 @@ public enum ErrorMessageID {
ExpectedTokenButFoundID,
MixedLeftAndRightAssociativeOpsID,
CantInstantiateAbstractClassOrTraitID,
+ AnnotatedPrimaryConstructorRequiresModifierOrThisID,
;
public int errorNumber() {
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 34190c114..e367e9ab2 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -1146,4 +1146,18 @@ object messages {
|""".stripMargin
}
+ case class AnnotatedPrimaryConstructorRequiresModifierOrThis(cls: Name)(implicit ctx: Context)
+ extends Message(AnnotatedPrimaryConstructorRequiresModifierOrThisID) {
+ val kind = "Syntax"
+ val msg = hl"""${"private"}, ${"protected"}, or ${"this"} expected for annotated primary constructor"""
+ val explanation =
+ hl"""|When using annotations with a primary constructor of a class,
+ |the annotation must be followed by an access modifier
+ |(${"private"} or ${"protected"}) or ${"this"}.
+ |
+ |For example:
+ | ${"class Sample @deprecated this(param: Parameter) { ..."}
+ | ^^^^
+ |""".stripMargin
+ }
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index 870198027..222717e7e 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -450,7 +450,16 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
def typedArg(arg: Arg, formal: Type): Arg = arg
def addArg(arg: TypedArg, formal: Type) =
- ok = ok & isCompatible(argType(arg, formal), formal)
+ ok = ok & {
+ argType(arg, formal) match {
+ case ref: TermRef if ref.denot.isOverloaded =>
+ // in this case we could not resolve overloading because no alternative
+ // matches expected type
+ false
+ case argtpe =>
+ isCompatible(argtpe, formal)
+ }
+ }
def makeVarArg(n: Int, elemFormal: Type) = {}
def fail(msg: => Message, arg: Arg) =
ok = false
diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala
index 48f9243f7..1ca7eb107 100644
--- a/compiler/src/dotty/tools/dotc/typer/Checking.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala
@@ -327,7 +327,7 @@ object Checking {
if (!sym.is(Deferred))
fail(i"`@native' members may not have implementation")
}
- else if (sym.is(Deferred, butNot = Param) && !sym.isSelfSym) {
+ else if (sym.is(Deferred, butNot = Param) && !sym.isType && !sym.isSelfSym) {
if (!sym.owner.isClass || sym.owner.is(Module) || sym.owner.isAnonymousClass)
fail(i"only classes can have declared but undefined members$varNote")
checkWithDeferred(Private)
diff --git a/compiler/src/dotty/tools/dotc/util/SourcePosition.scala b/compiler/src/dotty/tools/dotc/util/SourcePosition.scala
index aad4995d8..be5c46995 100644
--- a/compiler/src/dotty/tools/dotc/util/SourcePosition.scala
+++ b/compiler/src/dotty/tools/dotc/util/SourcePosition.scala
@@ -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 {
@@ -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)
diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala
index 971a40a1b..d6e687a1e 100644
--- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala
+++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala
@@ -198,4 +198,18 @@ class ErrorMessagesTests extends ErrorMessagesTest {
assertTrue("expected trait", isTrait)
}
+ @Test def constructorModifier =
+ checkMessagesAfter("frontend") {
+ """
+ |class AnotherClass @deprecated ()
+ """.stripMargin
+ }
+ .expect { (ictx, messages) =>
+ implicit val ctx: Context = ictx
+ val defn = ictx.definitions
+
+ assertMessageCount(1, messages)
+ val AnnotatedPrimaryConstructorRequiresModifierOrThis(cls) :: Nil = messages
+ assertEquals("AnotherClass", cls.show)
+ }
}