aboutsummaryrefslogtreecommitdiff
path: root/compiler/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src')
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala12
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Tokens.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala56
-rw-r--r--compiler/src/dotty/tools/dotc/typer/RefChecks.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala5
10 files changed, 81 insertions, 20 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index e3102fda2..deb239143 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -559,7 +559,7 @@ object desugar {
* ValDef or DefDef.
*/
def makePatDef(original: Tree, mods: Modifiers, pat: Tree, rhs: Tree)(implicit ctx: Context): Tree = pat match {
- case VarPattern(named, tpt) =>
+ case IdPattern(named, tpt) =>
derivedValDef(original, named, tpt, rhs, mods)
case _ =>
val rhsUnchecked = makeAnnotated("scala.unchecked", rhs)
@@ -816,7 +816,7 @@ object desugar {
* Otherwise this gives { case pat => body }
*/
def makeLambda(pat: Tree, body: Tree): Tree = pat match {
- case VarPattern(named, tpt) =>
+ case IdPattern(named, tpt) =>
Function(derivedValDef(pat, named, tpt, EmptyTree, Modifiers(Param)) :: Nil, body)
case _ =>
makeCaseLambda(CaseDef(pat, EmptyTree, body) :: Nil, unchecked = false)
@@ -898,7 +898,9 @@ object desugar {
}
def isIrrefutableGenFrom(gen: GenFrom): Boolean =
- gen.isInstanceOf[IrrefutableGenFrom] || isIrrefutable(gen.pat, gen.expr)
+ gen.isInstanceOf[IrrefutableGenFrom] ||
+ IdPattern.unapply(gen.pat).isDefined ||
+ isIrrefutable(gen.pat, gen.expr)
/** rhs.name with a pattern filter on rhs unless `pat` is irrefutable when
* matched against `rhs`.
@@ -1062,9 +1064,9 @@ object desugar {
TypeDef(tpnme.REFINE_CLASS, impl).withFlags(Trait)
}
- /** If tree is a variable pattern, return its name and type, otherwise return None.
+ /** If tree is of the form `id` or `id: T`, return its name and type, otherwise return None.
*/
- private object VarPattern {
+ private object IdPattern {
def unapply(tree: Tree)(implicit ctx: Context): Option[VarInfo] = tree match {
case id: Ident => Some(id, TypeTree())
case Typed(id: Ident, tpt) => Some((id, tpt))
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index 69ab6c21a..9e9e39a84 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -527,6 +527,8 @@ class Definitions {
lazy val EqType = ctx.requiredClassRef("scala.Eq")
def EqClass(implicit ctx: Context) = EqType.symbol.asClass
+ lazy val XMLTopScopeModuleRef = ctx.requiredModuleRef("scala.xml.TopScope")
+
// Annotation base classes
lazy val AnnotationType = ctx.requiredClassRef("scala.annotation.Annotation")
def AnnotationClass(implicit ctx: Context) = AnnotationType.symbol.asClass
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index 4a9c50dad..c424c6182 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -533,6 +533,7 @@ object StdNames {
val nullRuntimeClass: N = "scala.runtime.Null$"
val synthSwitch: N = "$synthSwitch"
+ val _scope: N = "$scope"
// unencoded operators
object raw {
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index 9f4cdbd35..45ae842b6 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -110,7 +110,8 @@ object Parsers {
*/
def syntaxError(msg: => Message, offset: Int = in.offset): Unit =
if (offset > lastErrorOffset) {
- syntaxError(msg, Position(offset))
+ val length = if (in.name != null) in.name.show.length else 0
+ syntaxError(msg, Position(offset, offset + length))
lastErrorOffset = in.offset
}
@@ -249,11 +250,6 @@ object Parsers {
lastErrorOffset = in.offset
} // DEBUG
- private def expectedMsg(token: Int): String =
- expectedMessage(showToken(token))
- private def expectedMessage(what: String): String =
- s"$what expected but ${showToken(in.token)} found"
-
/** Consume one token of the specified type, or
* signal an error if it is not there.
*
@@ -262,7 +258,7 @@ object Parsers {
def accept(token: Int): Int = {
val offset = in.offset
if (in.token != token) {
- syntaxErrorOrIncomplete(expectedMsg(token))
+ syntaxErrorOrIncomplete(ExpectedTokenButFound(token, in.token, in.name))
}
if (in.token == token) in.nextToken()
offset
@@ -474,7 +470,7 @@ object Parsers {
in.nextToken()
name
} else {
- syntaxErrorOrIncomplete(expectedMsg(IDENTIFIER))
+ syntaxErrorOrIncomplete(ExpectedTokenButFound(IDENTIFIER, in.token, in.name))
nme.ERROR
}
@@ -1055,7 +1051,7 @@ object Parsers {
case Block(Nil, EmptyTree) =>
assert(handlerStart != -1)
syntaxError(
- new EmptyCatchBlock(body),
+ EmptyCatchBlock(body),
Position(handlerStart, endOffset(handler))
)
case _ =>
diff --git a/compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala b/compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
index 20b655a19..09d1b20b1 100644
--- a/compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
@@ -55,7 +55,6 @@ class SymbolicXMLBuilder(parser: Parser, preserveWS: Boolean)(implicit ctx: Cont
val _buf: TermName = "$buf"
val _md: TermName = "$md"
val _plus: TermName = "$amp$plus"
- val _scope: TermName = "$scope"
val _tmpscope: TermName = "$tmpscope"
val _xml: TermName = "xml"
}
diff --git a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
index 280832ef3..8d42e525a 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
@@ -17,7 +17,7 @@ abstract class TokensCommon {
def showToken(token: Int) = {
val str = tokenString(token)
- if (keywords contains token) s"'$str'" else str
+ if (isKeyword(token)) s"'$str'" else str
}
val tokenString, debugString = new Array[String](maxToken + 1)
@@ -114,6 +114,8 @@ abstract class TokensCommon {
val keywords: TokenSet
+ def isKeyword(token: Token): Boolean = keywords contains token
+
/** parentheses */
final val LPAREN = 90; enter(LPAREN, "'('")
final val RPAREN = 91; enter(RPAREN, "')'")
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala
index 2497fb216..ab1222dab 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala
@@ -119,6 +119,8 @@ class ExtendMessage(_msg: () => Message)(f: String => String) { self =>
class NoExplanation(val msg: String) extends Message(NoExplanation.ID) {
val explanation = ""
val kind = ""
+
+ override def toString(): String = s"NoExplanation($msg)"
}
/** The extractor for `NoExplanation` can be used to check whether any error
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index c25c49597..94611e10d 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -4,10 +4,17 @@ package reporting
package diagnostic
import dotc.core._
-import Contexts.Context, Decorators._, Symbols._, Names._, NameOps._, Types._
+import Contexts.Context
+import Decorators._
+import Symbols._
+import Names._
+import NameOps._
+import Types._
import util.SourcePosition
import config.Settings.Setting
-import interfaces.Diagnostic.{ERROR, WARNING, INFO}
+import interfaces.Diagnostic.{ERROR, INFO, WARNING}
+import dotc.parsing.Scanners.Token
+import dotc.parsing.Tokens
import printing.Highlighting._
import printing.Formatting
@@ -1034,4 +1041,49 @@ object messages {
|"""
}
+ case class ForwardReferenceExtendsOverDefinition(value: Symbol, definition: Symbol)(implicit ctx: Context)
+ extends Message(39) {
+ val kind = "Reference"
+ val msg = hl"`${definition.name}` is a forward reference extending over the definition of `${value.name}`"
+
+ val explanation =
+ hl"""|`${definition.name}` is used before you define it, and the definition of `${value.name}`
+ |appears between that use and the definition of `${definition.name}`.
+ |
+ |Forward references are allowed only, if there are no value definitions between
+ |the reference and the referred method definition.
+ |
+ |Define `${definition.name}` before it is used,
+ |or move the definition of `${value.name}` so it does not appear between
+ |the declartion of `${definition.name}` and its use,
+ |or define `${value.name}` as lazy.
+ |""".stripMargin
+ }
+
+ case class ExpectedTokenButFound(expected: Token, found: Token, foundName: TermName)(implicit ctx: Context)
+ extends Message(40) {
+ val kind = "Syntax"
+
+ private val expectedText =
+ if (Tokens.isIdentifier(expected)) "an identifier"
+ else Tokens.showToken(expected)
+
+ private val foundText =
+ if (foundName != null) hl"`${foundName.show}`"
+ else Tokens.showToken(found)
+
+ val msg = hl"""${expectedText} expected, but ${foundText} found"""
+
+ private val ifKeyword =
+ if (Tokens.isIdentifier(expected) && Tokens.isKeyword(found))
+ s"""
+ |If you necessarily want to use $foundText as identifier, you may put it in backticks.""".stripMargin
+ else
+ ""
+
+ val explanation =
+ s"""|The text ${foundText} may not occur at that position, the compiler expected ${expectedText}.$ifKeyword
+ |""".stripMargin
+ }
+
}
diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
index ada53047a..eab91701b 100644
--- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -767,6 +767,7 @@ import RefChecks._
class RefChecks extends MiniPhase { thisTransformer =>
import tpd._
+ import reporting.diagnostic.messages.ForwardReferenceExtendsOverDefinition
override def phaseName: String = "refchecks"
@@ -789,8 +790,7 @@ class RefChecks extends MiniPhase { thisTransformer =>
if (sym.exists && sym.owner.isTerm && !sym.is(Lazy))
currentLevel.levelAndIndex.get(sym) match {
case Some((level, symIdx)) if symIdx < level.maxIndex =>
- ctx.debuglog("refsym = " + level.refSym)
- ctx.error(s"forward reference extends over definition of $sym", level.refPos)
+ ctx.error(ForwardReferenceExtendsOverDefinition(sym, level.refSym), level.refPos)
case _ =>
}
tree
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index e04667223..2b57cf778 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -351,6 +351,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val ownType =
if (rawType.exists)
ensureAccessible(rawType, superAccess = false, tree.pos)
+ else if (name == nme._scope) {
+ // gross hack to support current xml literals.
+ // awaiting a better implicits based solution for library-supported xml
+ return ref(defn.XMLTopScopeModuleRef)
+ }
else
errorType(new MissingIdent(tree, kind, name.show), tree.pos)