aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/parsing/Parsers.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/parsing/Parsers.scala')
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala98
1 files changed, 52 insertions, 46 deletions
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index 97213a685..153b58283 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -63,7 +63,7 @@ object Parsers {
atPos(Position(start, end, point))(t)
def atPos[T <: Positioned](start: Offset, point: Offset)(t: T): T =
- atPos(start, point, in.lastOffset max start)(t)
+ if (in.lastOffset > start) atPos(start, point, in.lastOffset)(t) else t
def atPos[T <: Positioned](start: Offset)(t: T): T =
atPos(start, start)(t)
@@ -71,7 +71,8 @@ object Parsers {
def atPos[T <: Positioned](pos: Position)(t: T): T =
if (t.pos.isSourceDerived) t else t.withPos(pos)
- def tokenRange = Position(in.offset, in.lastCharOffset, in.offset)
+ def nameStart: Offset =
+ if (in.token == BACKQUOTED_IDENT) in.offset + 1 else in.offset
def sourcePos(off: Int = in.offset): SourcePosition =
source atPos Position(off)
@@ -313,8 +314,6 @@ object Parsers {
tree
}
- def emptyConstructor() = atPos(in.offset) { ast.untpd.emptyConstructor }
-
/* --------------- PLACEHOLDERS ------------------------------------------- */
/** The implicit parameters introduced by `_` in the current expression.
@@ -694,9 +693,10 @@ object Parsers {
}
}
else if (in.token == LBRACKET) {
+ val start = in.offset
val tparams = typeParamClause(ParamOwner.TypeParam)
if (isIdent && in.name.toString == "->")
- atPos(in.skipToken())(TypeLambdaTree(tparams, typ()))
+ atPos(start, in.skipToken())(TypeLambdaTree(tparams, typ()))
else { syntaxErrorOrIncomplete(expectedMessage("`->'")); typ() }
}
else infixType()
@@ -762,7 +762,7 @@ object Parsers {
else if (isSimpleLiteral) { SingletonTypeTree(literal()) }
else if (in.token == USCORE) {
val start = in.skipToken()
- typeBounds().withPos(Position(start, in.offset, start))
+ typeBounds().withPos(Position(start, in.lastOffset, start))
}
else path(thisOK = false, handleSingletonType) match {
case r @ SingletonTypeTree(_) => r
@@ -866,7 +866,8 @@ object Parsers {
def typeParamBounds(pname: TypeName): Tree = {
val t = typeBounds()
val cbs = contextBounds(pname)
- if (cbs.isEmpty) t else atPos(t.pos.start) { ContextBounds(t, cbs) }
+ if (cbs.isEmpty) t
+ else atPos((t.pos union cbs.head.pos).start) { ContextBounds(t, cbs) }
}
def contextBounds(pname: TypeName): List[Tree] = in.token match {
@@ -1075,7 +1076,8 @@ object Parsers {
val tpt = typeDependingOn(location)
if (isWildcard(t) && location != Location.InPattern) {
val vd :: rest = placeholderParams
- placeholderParams = cpy.ValDef(vd)(tpt = tpt) :: rest
+ placeholderParams =
+ cpy.ValDef(vd)(tpt = tpt).withPos(vd.pos union tpt.pos) :: rest
}
Typed(t, tpt)
}
@@ -1154,12 +1156,12 @@ object Parsers {
case NEW =>
canApply = false
val start = in.skipToken()
- val (impl, missingBody) = template(emptyConstructor())
+ val (impl, missingBody) = template(emptyConstructor)
impl.parents match {
case parent :: Nil if missingBody =>
if (parent.isType) ensureApplied(wrapNew(parent)) else parent
case _ =>
- New(impl)
+ New(impl.withPos(Position(start, in.lastOffset)))
}
case _ =>
if (isLiteral) literal()
@@ -1362,15 +1364,15 @@ object Parsers {
*/
val pattern2 = () => infixPattern() match {
case p @ Ident(name) if isVarPattern(p) && in.token == AT =>
- val pos = in.skipToken()
+ val offset = in.skipToken()
// compatibility for Scala2 `x @ _*` syntax
infixPattern() match {
case pt @ Ident(tpnme.WILDCARD_STAR) =>
migrationWarningOrError("The syntax `x @ _*' is no longer supported; use `x : _*' instead", p.pos.start)
- atPos(p.pos.start, pos) { Typed(p, pt) }
+ atPos(p.pos.start, offset) { Typed(p, pt) }
case p =>
- atPos(p.pos.start, pos) { Bind(name, p) }
+ atPos(p.pos.start, offset) { Bind(name, p) }
}
case p @ Ident(tpnme.WILDCARD_STAR) =>
// compatibility for Scala2 `_*` syntax
@@ -1590,12 +1592,12 @@ object Parsers {
def typeParamClause(ownerKind: ParamOwner.Value): List[TypeDef] = inBrackets {
def typeParam(): TypeDef = {
val isConcreteOwner = ownerKind == ParamOwner.Class || ownerKind == ParamOwner.Def
- val modStart = in.offset
+ val start = in.offset
var mods = annotsAsMods()
if (ownerKind == ParamOwner.Class) {
mods = modifiers(start = mods)
mods =
- atPos(modStart, in.offset) {
+ atPos(start, in.offset) {
if (in.token == TYPE) {
in.nextToken()
mods | Param | ParamAccessor
@@ -1605,13 +1607,13 @@ object Parsers {
}
}
}
- else mods = atPos(modStart) (mods | Param)
+ else mods = atPos(start) (mods | Param)
if (ownerKind != ParamOwner.Def) {
if (isIdent(nme.raw.PLUS)) mods |= Covariant
else if (isIdent(nme.raw.MINUS)) mods |= Contravariant
if (mods is VarianceFlags) in.nextToken()
}
- atPos(tokenRange) {
+ atPos(start, nameStart) {
val name =
if (isConcreteOwner || in.token != USCORE) ident().toTypeName
else {
@@ -1645,12 +1647,12 @@ object Parsers {
var firstClauseOfCaseClass = ofCaseClass
var implicitOffset = -1 // use once
def param(): ValDef = {
- val modStart = in.offset
+ val start = in.offset
var mods = annotsAsMods()
if (owner.isTypeName) {
mods = modifiers(start = mods) | ParamAccessor
mods =
- atPos(modStart, in.offset) {
+ atPos(start, in.offset) {
if (in.token == VAL) {
in.nextToken()
mods
@@ -1663,8 +1665,8 @@ object Parsers {
}
}
}
- else mods = atPos(modStart) { mods | Param }
- atPos(tokenRange) {
+ else mods = atPos(start) { mods | Param }
+ atPos(start, nameStart) {
val name = ident()
val tpt =
if (ctx.settings.YmethodInfer.value && owner.isTermName && in.token != COLON) {
@@ -1683,7 +1685,7 @@ object Parsers {
if (in.token == EQUALS) { in.nextToken(); expr() }
else EmptyTree
if (implicitOffset >= 0) {
- mods = mods.withPos(mods.pos.withStart(implicitOffset))
+ mods = mods.withPos(mods.pos.union(Position(implicitOffset, implicitOffset)))
implicitOffset = -1
}
ValDef(name, tpt, default).withMods(addFlag(mods, implicitFlag))
@@ -1779,7 +1781,11 @@ object Parsers {
else from
}
- def posMods(start: Int, mods: Modifiers) = atPos(start, in.skipToken())(mods)
+ def posMods(start: Int, mods: Modifiers) = {
+ val mods1 = atPos(start)(mods)
+ in.nextToken()
+ mods1
+ }
/** Def ::= val PatDef
* | var VarDef
@@ -1793,13 +1799,13 @@ object Parsers {
*/
def defOrDcl(start: Int, mods: Modifiers): Tree = in.token match {
case VAL =>
- patDefOrDcl(posMods(start, mods), in.getDocComment(start))
+ patDefOrDcl(start, posMods(start, mods), in.getDocComment(start))
case VAR =>
- patDefOrDcl(posMods(start, addFlag(mods, Mutable)), in.getDocComment(start))
+ patDefOrDcl(start, posMods(start, addFlag(mods, Mutable)), in.getDocComment(start))
case DEF =>
- defDefOrDcl(posMods(start, mods), in.getDocComment(start))
+ defDefOrDcl(start, posMods(start, mods), in.getDocComment(start))
case TYPE =>
- typeDefOrDcl(posMods(start, mods), in.getDocComment(start))
+ typeDefOrDcl(start, posMods(start, mods), in.getDocComment(start))
case _ =>
tmplDef(start, mods)
}
@@ -1809,7 +1815,7 @@ object Parsers {
* ValDcl ::= Id {`,' Id} `:' Type
* VarDcl ::= Id {`,' Id} `:' Type
*/
- def patDefOrDcl(mods: Modifiers, docstring: Option[Comment] = None): Tree = {
+ def patDefOrDcl(start: Offset, mods: Modifiers, docstring: Option[Comment] = None): Tree = atPos(start, nameStart) {
val lhs = commaSeparated(pattern2)
val tpt = typedOpt()
val rhs =
@@ -1824,7 +1830,7 @@ object Parsers {
} else EmptyTree
lhs match {
case (id @ Ident(name: TermName)) :: Nil => {
- cpy.ValDef(id)(name, tpt, rhs).withMods(mods).setComment(docstring)
+ ValDef(name, tpt, rhs).withMods(mods).setComment(docstring)
} case _ =>
PatDef(mods, lhs, tpt, rhs)
}
@@ -1835,7 +1841,7 @@ object Parsers {
* DefDcl ::= DefSig `:' Type
* DefSig ::= id [DefTypeParamClause] ParamClauses
*/
- def defDefOrDcl(mods: Modifiers, docstring: Option[Comment] = None): Tree = atPos(tokenRange) {
+ def defDefOrDcl(start: Offset, mods: Modifiers, docstring: Option[Comment] = None): Tree = atPos(start, nameStart) {
def scala2ProcedureSyntax(resultTypeStr: String) = {
val toInsert =
if (in.token == LBRACE) s"$resultTypeStr ="
@@ -1910,9 +1916,9 @@ object Parsers {
/** TypeDef ::= type Id [TypeParamClause] `=' Type
* TypeDcl ::= type Id [TypeParamClause] TypeBounds
*/
- def typeDefOrDcl(mods: Modifiers, docstring: Option[Comment] = None): Tree = {
+ def typeDefOrDcl(start: Offset, mods: Modifiers, docstring: Option[Comment] = None): Tree = {
newLinesOpt()
- atPos(tokenRange) {
+ atPos(start, nameStart) {
val name = ident().toTypeName
val tparams = typeParamClauseOpt(ParamOwner.Type)
in.token match {
@@ -1935,15 +1941,15 @@ object Parsers {
val docstring = in.getDocComment(start)
in.token match {
case TRAIT =>
- classDef(posMods(start, addFlag(mods, Trait)), docstring)
+ classDef(start, posMods(start, addFlag(mods, Trait)), docstring)
case CLASS =>
- classDef(posMods(start, mods), docstring)
+ classDef(start, posMods(start, mods), docstring)
case CASECLASS =>
- classDef(posMods(start, mods | Case), docstring)
+ classDef(start, posMods(start, mods | Case), docstring)
case OBJECT =>
- objectDef(posMods(start, mods | Module), docstring)
+ objectDef(start, posMods(start, mods | Module), docstring)
case CASEOBJECT =>
- objectDef(posMods(start, mods | Case | Module), docstring)
+ objectDef(start, posMods(start, mods | Case | Module), docstring)
case _ =>
syntaxErrorOrIncomplete("expected start of definition")
EmptyTree
@@ -1953,9 +1959,9 @@ object Parsers {
/** ClassDef ::= Id [ClsTypeParamClause]
* [ConstrMods] ClsParamClauses TemplateOpt
*/
- def classDef(mods: Modifiers, docstring: Option[Comment]): TypeDef = atPos(tokenRange) {
+ def classDef(start: Offset, mods: Modifiers, docstring: Option[Comment]): TypeDef = atPos(start, nameStart) {
val name = ident().toTypeName
- val constr = atPos(in.offset) {
+ val constr = atPos(in.lastOffset) {
val tparams = typeParamClauseOpt(ParamOwner.Class)
val cmods = constrModsOpt()
val vparamss = paramClauses(name, mods is Case)
@@ -1980,9 +1986,9 @@ object Parsers {
/** ObjectDef ::= Id TemplateOpt
*/
- def objectDef(mods: Modifiers, docstring: Option[Comment] = None): ModuleDef = {
+ def objectDef(start: Offset, mods: Modifiers, docstring: Option[Comment] = None): ModuleDef = atPos(start, nameStart) {
val name = ident()
- val template = templateOpt(emptyConstructor())
+ val template = templateOpt(emptyConstructor)
ModuleDef(name, template).withMods(mods).setComment(docstring)
}
@@ -2021,12 +2027,12 @@ object Parsers {
else {
newLineOptWhenFollowedBy(LBRACE)
if (in.token == LBRACE) template(constr)._1
- else Template(constr, Nil, EmptyValDef, Nil).withPos(constr.pos.toSynthetic)
+ else Template(constr, Nil, EmptyValDef, Nil)
}
/** TemplateBody ::= [nl] `{' TemplateStatSeq `}'
*/
- def templateBodyOpt(constr: DefDef, parents: List[Tree]) = atPos(constr.pos.start) {
+ def templateBodyOpt(constr: DefDef, parents: List[Tree]) = {
val (self, stats) =
if (in.token == LBRACE) templateBody() else (EmptyValDef, Nil)
Template(constr, parents, self, stats)
@@ -2037,7 +2043,7 @@ object Parsers {
if (in.token == WITH) {
syntaxError("early definitions are not supported; use trait parameters instead")
in.nextToken()
- template(emptyConstructor())
+ template(emptyConstructor)
}
r
}
@@ -2072,7 +2078,7 @@ object Parsers {
if (in.token == PACKAGE) {
val start = in.skipToken()
if (in.token == OBJECT)
- stats += objectDef(atPos(start, in.skipToken()) { Modifiers(Package) })
+ stats += objectDef(start, atPos(start, in.skipToken()) { Modifiers(Package) })
else stats += packaging(start)
}
else if (in.token == IMPORT)
@@ -2206,7 +2212,7 @@ object Parsers {
in.nextToken()
if (in.token == OBJECT) {
val docstring = in.getDocComment(start)
- ts += objectDef(atPos(start, in.skipToken()) { Modifiers(Package) }, docstring)
+ ts += objectDef(start, atPos(start, in.skipToken()) { Modifiers(Package) }, docstring)
if (in.token != EOF) {
acceptStatSep()
ts ++= topStatSeq()