Skip to content

Commit 1e4b2a1

Browse files
committed
Change syntax from augment/extends to extend/implements
Also, drop labels.
1 parent 1c55e04 commit 1e4b2a1

File tree

18 files changed

+406
-398
lines changed

18 files changed

+406
-398
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ package ast
44

55
import core._
66
import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
7+
import util.Chars.isIdentifierPart
78
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
89
import Decorators._, transform.SymUtils._
9-
import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName, AugmentName}
10+
import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName}
1011
import language.higherKinds
1112
import typer.FrontEnd
1213
import collection.mutable.ListBuffer
@@ -771,59 +772,63 @@ object desugar {
771772
(elimTypeDefs.transform(tree), bindingsBuf.toList)
772773
}
773774

774-
/** augment [<id> @] <type-pattern> <params> extends <parents> { <body>} }
775+
private val collectNames = new untpd.UntypedTreeAccumulator[ListBuffer[String]] {
776+
override def apply(buf: ListBuffer[String], tree: Tree)(implicit ctx: Context): ListBuffer[String] = tree match {
777+
case Ident(name) =>
778+
buf += name.toString
779+
case Select(qual, name) =>
780+
apply(buf, qual) += name.toString
781+
case TypeDef(name, rhs) =>
782+
apply(buf += "type" += name.toString, rhs)
783+
case Apply(fn, _) =>
784+
apply(buf, fn)
785+
case _ =>
786+
foldOver(buf, tree)
787+
}
788+
}
789+
790+
private def extensionName(ext: Extension)(implicit ctx: Context): TypeName = {
791+
var buf = collectNames(new ListBuffer[String] += "extend", ext.extended)
792+
if (ext.impl.parents.nonEmpty)
793+
buf = collectNames(buf += "implements", ext.impl.parents)
794+
val ids = buf.toList.map(_.filter(isIdentifierPart)).filter(!_.isEmpty)
795+
ids.mkString("_").toTypeName
796+
}
797+
798+
/** extend <type-pattern> <params> implements <parents> { <body>} }
775799
* ->
776-
* implicit class <deconame> <type-params> ($this: <decorated>) <combined-params>
800+
* implicit class <extension-name> <type-params> ($this: <extended>) <combined-params>
777801
* extends <parents> { <body1> }
778802
*
779803
* where
780804
*
781-
* <deco-name> = <id>, if there is a `<id> @` binding
782-
* = unqiue, expanded name relative to top-level class of <deco-core>, otherwise
783-
* <deco-core> = "_augment_<from>_to_<to>" if <to> is nonempty
784-
* = "_augment_<from>" otherwise
785-
* <from> = underlying type name of <decorated>, or ""
786-
* <to> = underlying type name of first extended parent, or ""
787-
*
805+
* <extension-name> = concatenation of all alphanumeric characters between and including `extend` and `{`,
806+
* mapping every sequence of other characters to a single `_`.
807+
*
788808
* (<decorated>, <type-params0>) = decomposeTypePattern(<type-pattern>)
789809
* (<type-params>, <evidence-params>) = desugarTypeBindings(<type-params0>)
790810
* <combined-params> = <params> concatenated with <evidence-params> in one clause
791811
* <body1> = <body> with each occurrence of unqualified `this` substituted by `$this`.
792812
*
793813
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
794814
*
795-
* augment [<id> @] <type-pattern> <params> { <body> }
815+
* extend <type-pattern> <params> { <body> }
796816
* ->
797-
* implicit class <deconame> <type-params> ($this: <decorated>)
817+
* implicit class <extension-name> <type-params> ($this: <extended>)
798818
* extends AnyVal { <body2> }
799819
*
800820
* where
801821
*
802822
* <body2> = <body1> where each method definition gets <combined-params> as last parameter section.
803-
* <deco-name>, <type-params> are as above.
823+
* <extenion-name>, <type-params> are as above.
804824
*/
805-
def augmentation(tree: Augment)(implicit ctx: Context): Tree = {
806-
val Augment(id, augmented, impl) = tree
807-
val isSimpleExtension =
808-
impl.parents.isEmpty &&
809-
impl.self.isEmpty &&
810-
impl.body.forall(_.isInstanceOf[DefDef])
811-
val (decorated, bindings) = decomposeTypePattern(augmented)
825+
def extension(tree: Extension)(implicit ctx: Context): Tree = {
826+
val Extension(extended, impl) = tree
827+
val isSimpleExtension = impl.parents.isEmpty
828+
val (decorated, bindings) = decomposeTypePattern(extended)
812829
val (typeParams, evidenceParams) =
813830
desugarTypeBindings(bindings, forPrimaryConstructor = !isSimpleExtension)
814-
val decoName = id match {
815-
case Ident(name) =>
816-
name.asTypeName
817-
case EmptyTree =>
818-
def clsName(tree: Tree): String = leadingName("", tree)
819-
val fromName = clsName(augmented)
820-
val toName = impl.parents match {
821-
case parent :: _ if !clsName(parent).isEmpty => "_to_" + clsName(parent)
822-
case _ => ""
823-
}
824-
val core = s"${str.AUGMENT}$fromName$toName".toTermName
825-
AugmentName.fresh(core.expandedName(ctx.owner.topLevelClass)).toTypeName
826-
}
831+
val extName = extensionName(tree)
827832

828833
val firstParam = ValDef(nme.SELF, decorated, EmptyTree).withFlags(Private | Local | ParamAccessor)
829834
var constr1 =
@@ -841,16 +846,18 @@ object desugar {
841846
vdef.withMods(vdef.mods &~ PrivateLocalParamAccessor | Param)
842847
val originalParams = impl.constr.vparamss.headOption.getOrElse(Nil).map(resetFlags)
843848
addEvidenceParams(addEvidenceParams(ddef, originalParams), evidenceParams)
849+
case other =>
850+
other
844851
}
845852
}
846853
else
847854
constr1 = addEvidenceParams(constr1, evidenceParams)
848855

849856
val icls =
850-
TypeDef(decoName,
857+
TypeDef(extName,
851858
cpy.Template(impl)(constr = constr1, parents = parents1, body = body1))
852859
.withFlags(Implicit)
853-
desugr.println(i"desugar $augmented --> $icls")
860+
desugr.println(i"desugar $extended --> $icls")
854861
classDef(icls)
855862
}
856863

@@ -883,7 +890,7 @@ object desugar {
883890
else defDef(tree)
884891
case tree: ModuleDef => moduleDef(tree)
885892
case tree: PatDef => patDef(tree)
886-
case tree: Augment => augmentation(tree)
893+
case tree: Extension => extension(tree)
887894
}
888895

889896
/** { stats; <empty > }

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
4040
def withName(name: Name)(implicit ctx: Context) = cpy.ModuleDef(this)(name.toTermName, impl)
4141
}
4242

43-
/** augment id @ augmented impl */
44-
case class Augment(id: Tree, augmented: Tree, impl: Template) extends DefTree
43+
/** extend extended impl */
44+
case class Extension(extended: Tree, impl: Template) extends DefTree
4545

4646
case class ParsedTry(expr: Tree, handler: Tree, finalizer: Tree) extends TermTree
4747

@@ -414,9 +414,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
414414
case tree: ModuleDef if (name eq tree.name) && (impl eq tree.impl) => tree
415415
case _ => finalize(tree, untpd.ModuleDef(name, impl))
416416
}
417-
def Augment(tree: Tree)(id: Tree, augmented: Tree, impl: Template) = tree match {
418-
case tree: Augment if (id eq tree.id) && (augmented eq tree.augmented) && (impl eq tree.impl) => tree
419-
case _ => finalize(tree, untpd.Augment(id, augmented, impl))
417+
def Extension(tree: Tree)(extended: Tree, impl: Template) = tree match {
418+
case tree: Extension if (extended eq tree.extended) && (impl eq tree.impl) => tree
419+
case _ => finalize(tree, untpd.Extension(extended, impl))
420420
}
421421
def ParsedTry(tree: Tree)(expr: Tree, handler: Tree, finalizer: Tree) = tree match {
422422
case tree: ParsedTry

compiler/src/dotty/tools/dotc/core/NameKinds.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,6 @@ object NameKinds {
291291
val SkolemName = new UniqueNameKind("?")
292292
val LiftedTreeName = new UniqueNameKind("liftedTree")
293293
val SuperArgName = new UniqueNameKind("$superArg$")
294-
val AugmentName = new UniqueNameKind("_")
295294

296295
/** A kind of unique extension methods; Unlike other unique names, these can be
297296
* unmangled.

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ object StdNames {
2828
final val LOCALDUMMY_PREFIX = "<local " // owner of local blocks
2929
final val ANON_CLASS = "$anon"
3030
final val ANON_FUN = "$anonfun"
31-
final val AUGMENT = "_augment_"
3231

3332
final val REPL_SESSION_LINE = "rs$line$"
3433
final val REPL_ASSIGN_SUFFIX = "$assign"

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,7 +1865,7 @@ object Parsers {
18651865
* ImplicitParamClause ::= [nl] ‘(’ ImplicitMods ClsParams ‘)’)
18661866
* ImplicitMods ::= `implicit` [`unused`] | `unused` `implicit`
18671867
*/
1868-
def paramClauses(owner: Name, ofCaseClass: Boolean = false, ofAugmentation: Boolean = false): List[List[ValDef]] = {
1868+
def paramClauses(owner: Name, ofCaseClass: Boolean = false, ofExtension: Boolean = false): List[List[ValDef]] = {
18691869
var imods: Modifiers = EmptyModifiers
18701870
var implicitOffset = -1 // use once
18711871
var firstClauseOfCaseClass = ofCaseClass
@@ -1911,7 +1911,7 @@ object Parsers {
19111911
}
19121912
}
19131913
def paramClause(): List[ValDef] = inParens {
1914-
if (!ofAugmentation && in.token == RPAREN) Nil
1914+
if (!ofExtension && in.token == RPAREN) Nil
19151915
else {
19161916
def funArgMods(): Unit = {
19171917
if (in.token == IMPLICIT) {
@@ -1924,8 +1924,8 @@ object Parsers {
19241924
}
19251925
}
19261926
funArgMods()
1927-
if (ofAugmentation && !imods.is(Implicit))
1928-
syntaxError(i"parameters of augment clause must be implicit")
1927+
if (ofExtension && !imods.is(Implicit))
1928+
syntaxError(i"parameters of extension must be implicit")
19291929
commaSeparated(() => param())
19301930
}
19311931
}
@@ -1935,7 +1935,7 @@ object Parsers {
19351935
imods = EmptyModifiers
19361936
paramClause() :: {
19371937
firstClauseOfCaseClass = false
1938-
if (imods.is(Implicit) || ofAugmentation) Nil else clauses()
1938+
if (imods.is(Implicit) || ofExtension) Nil else clauses()
19391939
}
19401940
} else Nil
19411941
}
@@ -2303,32 +2303,33 @@ object Parsers {
23032303
Template(constr, parents, EmptyValDef, Nil)
23042304
}
23052305

2306-
/** Augmentation ::= ‘augment’ [id @] BindingTypePattern
2307-
* [[nl] ImplicitParamClause] Additions
2306+
/** Extension ::= ‘extend’ BindingTypePattern
2307+
* [[nl] ImplicitParamClause] ExtensionClause
23082308
* BindingTypePattern ::= AnnotType
2309-
* Additions ::= ‘extends’ Template
2310-
* | [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’
2309+
* ExtensionClause ::= ‘implements’ Template
2310+
* | [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’
23112311
*/
2312-
def augmentation(): Augment = atPos(in.skipToken(), nameStart) {
2313-
var id: Tree = EmptyTree
2314-
if (isIdent && lookaheadIn(AT)) {
2315-
id = typeIdent()
2316-
in.nextToken()
2317-
}
2318-
val augmented = withinTypePattern(binding = true)(annotType())
2319-
val vparamss = paramClauses(tpnme.EMPTY, ofAugmentation = true).take(1)
2312+
def extension(): Extension = atPos(in.skipToken(), nameStart) {
2313+
val extended = withinTypePattern(binding = true)(annotType())
2314+
val vparamss = paramClauses(tpnme.EMPTY, ofExtension = true).take(1)
23202315
val constr = makeConstructor(Nil, vparamss)
2321-
val isSimpleExtension = in.token != EXTENDS
2322-
val templ = templateClauseOpt(constr, bodyRequired = true)
2323-
if (isSimpleExtension) {
2324-
def checkDef(tree: Tree) = tree match {
2325-
case _: DefDef | EmptyValDef => // ok
2326-
case _ => syntaxError("`def` expected", tree.pos.startPos)
2316+
val templ =
2317+
if (in.token == IMPLEMENTS) {
2318+
in.nextToken()
2319+
template(constr, bodyRequired = true)._1
23272320
}
2328-
checkDef(templ.self)
2329-
templ.body.foreach(checkDef)
2330-
}
2331-
Augment(id, augmented, templ)
2321+
else {
2322+
if (in.token == EXTENDS) syntaxError("`implements` or `{` expected")
2323+
val templ = templateClauseOpt(constr, bodyRequired = true)
2324+
def checkDef(tree: Tree) = tree match {
2325+
case _: DefDef | EmptyValDef => // ok
2326+
case _ => syntaxError("`def` expected", tree.pos.startPos)
2327+
}
2328+
checkDef(templ.self)
2329+
templ.body.foreach(checkDef)
2330+
templ
2331+
}
2332+
Extension(extended, templ)
23322333
}
23332334

23342335
/* -------- TEMPLATES ------------------------------------------- */
@@ -2364,7 +2365,10 @@ object Parsers {
23642365
* TemplateClauseOpt = [TemplateClause]
23652366
*/
23662367
def templateClauseOpt(constr: DefDef, isEnum: Boolean = false, bodyRequired: Boolean = false): Template =
2367-
if (in.token == EXTENDS) { in.nextToken(); template(constr, isEnum, bodyRequired)._1 }
2368+
if (in.token == EXTENDS) {
2369+
in.nextToken()
2370+
template(constr, isEnum, bodyRequired)._1
2371+
}
23682372
else {
23692373
newLineOptWhenFollowedBy(LBRACE)
23702374
if (in.token == LBRACE || bodyRequired) template(constr, isEnum, bodyRequired)._1
@@ -2443,7 +2447,7 @@ object Parsers {
24432447
* TemplateStat ::= Import
24442448
* | Annotations Modifiers Def
24452449
* | Annotations Modifiers Dcl
2446-
* | Augmentation
2450+
* | Extension
24472451
* | Expr1
24482452
* |
24492453
* EnumStat ::= TemplateStat
@@ -2474,8 +2478,8 @@ object Parsers {
24742478
setLastStatOffset()
24752479
if (in.token == IMPORT)
24762480
stats ++= importClause()
2477-
else if (in.token == AUGMENT)
2478-
stats += augmentation()
2481+
else if (in.token == EXTEND)
2482+
stats += extension()
24792483
else if (isExprIntro)
24802484
stats += expr1()
24812485
else if (isDefIntro(modifierTokensOrCase))
@@ -2520,7 +2524,7 @@ object Parsers {
25202524
* BlockStat ::= Import
25212525
* | Annotations [implicit] [lazy] Def
25222526
* | Annotations LocalModifiers TmplDef
2523-
* | Augmentation
2527+
* | Extension
25242528
* | Expr1
25252529
* |
25262530
*/
@@ -2531,8 +2535,8 @@ object Parsers {
25312535
setLastStatOffset()
25322536
if (in.token == IMPORT)
25332537
stats ++= importClause()
2534-
else if (in.token == AUGMENT)
2535-
stats += augmentation()
2538+
else if (in.token == EXTEND)
2539+
stats += extension()
25362540
else if (isExprIntro)
25372541
stats += expr(Location.InBlock)
25382542
else if (isDefIntro(localModifierTokens))

compiler/src/dotty/tools/dotc/parsing/Tokens.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ object Tokens extends TokensCommon {
179179
final val ENUM = 63; enter(ENUM, "enum")
180180
final val ERASED = 64; enter(ERASED, "erased")
181181
final val OPAQUE = 65; enter(OPAQUE, "opaque")
182-
final val AUGMENT = 66; enter(AUGMENT, "augment")
182+
final val EXTEND = 66; enter(EXTEND, "extend")
183+
final val IMPLEMENTS = 67; enter(IMPLEMENTS, "implements")
183184

184185
/** special symbols */
185186
final val NEWLINE = 78; enter(NEWLINE, "end of statement", "new line")
@@ -200,7 +201,7 @@ object Tokens extends TokensCommon {
200201
/** XML mode */
201202
final val XMLSTART = 96; enter(XMLSTART, "$XMLSTART$<") // TODO: deprecate
202203

203-
final val alphaKeywords = tokenRange(IF, AUGMENT)
204+
final val alphaKeywords = tokenRange(IF, IMPLEMENTS)
204205
final val symbolicKeywords = tokenRange(USCORE, VIEWBOUND)
205206
final val symbolicTokens = tokenRange(COMMA, VIEWBOUND)
206207
final val keywords = alphaKeywords | symbolicKeywords
@@ -240,7 +241,7 @@ object Tokens extends TokensCommon {
240241

241242
/** Is token only legal as start of statement (eof also included)? */
242243
final val mustStartStatTokens = defIntroTokens | modifierTokens | BitSet(
243-
IMPORT, PACKAGE, AUGMENT)
244+
IMPORT, PACKAGE, EXTEND)
244245

245246
final val canStartStatTokens = canStartExpressionTokens | mustStartStatTokens | BitSet(
246247
AT, CASE)

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Flags._
88
import Names._
99
import Symbols._
1010
import NameOps._
11-
import NameKinds.{AugmentName, ExpandedName}
11+
import NameKinds.ExpandedName
1212
import Constants._
1313
import TypeErasure.ErasedValueType
1414
import Contexts.Context
@@ -722,12 +722,6 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
722722
case info: ImportType => return s"import $info.expr.show"
723723
case _ =>
724724
}
725-
sym.name.toTermName match {
726-
case AugmentName(ExpandedName(_, core), n) =>
727-
assert(core.startsWith(str.AUGMENT))
728-
return Str(s"augmentation ${core.drop(str.AUGMENT.length)}") ~ (Str(s"/$n") provided n > 1)
729-
case _ =>
730-
}
731725

732726
if (sym.is(ModuleClass))
733727
kindString(sym) ~~ (nameString(sym.name.stripModuleClassSuffix) + idString(sym))

0 commit comments

Comments
 (0)