Skip to content

Commit 8042644

Browse files
committed
Allow named tuple syntax for case class constructors.
This is a tweak to the named tuple spec. If the expected type is a case class expand to a call of its apply method.
1 parent 4b8a832 commit 8042644

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1717,7 +1717,20 @@ object desugar {
17171717
cpy.Tuple(tree)(elemValues)
17181718
val names = elems.collect:
17191719
case NamedArg(name, arg) => name
1720-
if names.isEmpty || ctx.mode.is(Mode.Pattern) then
1720+
val targetClassType = pt.underlyingClassRef(refinementOK = true)
1721+
val targetClass = targetClassType.typeSymbol
1722+
val isCaseClassConstr =
1723+
ctx.mode.isExpr
1724+
&& targetClass.is(Case)
1725+
&& !defn.isTupleClass(targetClass)
1726+
&& targetClass != defn.TupleXXLClass
1727+
&& names.hasSameLengthAs(elems) // true iff all arguments are named
1728+
if isCaseClassConstr then
1729+
import tpd.TreeOps
1730+
val companion = targetClass.companionModule.termRef
1731+
.withPrefix(targetClassType.asInstanceOf[TypeRef].prefix).asInstanceOf[TermRef]
1732+
Apply(TypedSplice(tpd.ref(companion).select(nme.apply)), elems).withSpan(tree.span)
1733+
else if names.isEmpty || ctx.mode.is(Mode.Pattern) then
17211734
tup
17221735
else
17231736
def namesTuple = withModeBits(ctx.mode &~ Mode.Pattern | Mode.Type):

tests/run/json.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
BuildDescription(true,true,.,typescript,true,null,List(null, null),List(Plugin(typescript-transform-paths,false), Plugin(typescript-transform-paths,true)),List(someValue, some-value, a value),node,CommonJS,ES2020,)
2+
BuildDescription(true,true,.,typescript,false,null,List(null, null),List(Plugin(typescript-transform-paths,false), Plugin(typescript-transform-paths,true)),List(),node,,ES2020,)
3+
BuildDescription(false,true,.,,false,.,List(null, null),List(),List(),,,,)

tests/run/json.scala

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import language.`3.7`
2+
import language.experimental.namedTuples
3+
import language.experimental.collectionLiterals
4+
5+
case class BuildDescription(
6+
declarationMap: Boolean = false,
7+
esModuleInterop: Boolean = true,
8+
baseUrl: String = ".",
9+
rootDir: String = "",
10+
declaration: Boolean = false,
11+
outDir: String = ".",
12+
deps: Seq[Dep] = [junitInterface, commonsIo],
13+
plugins: Seq[Plugin] = [],
14+
aliases: Seq[String] = [],
15+
moduleResolution: String = "",
16+
module: String = "",
17+
target: String = "",
18+
other: String = ""
19+
)
20+
21+
case class Plugin(
22+
transform: String,
23+
afterDeclarations: Boolean = false
24+
)
25+
26+
val b1: BuildDescription = (
27+
declarationMap = true,
28+
esModuleInterop = true,
29+
baseUrl = ".",
30+
rootDir = "typescript",
31+
declaration = true,
32+
outDir = pubBundledOut,
33+
deps = [junitInterface, commonsIo],
34+
plugins = [
35+
( transform = "typescript-transform-paths" ),
36+
( transform = "typescript-transform-paths",
37+
afterDeclarations = true
38+
)
39+
],
40+
aliases = ["someValue", "some-value", "a value"],
41+
moduleResolution = "node",
42+
module = "CommonJS",
43+
target = "ES2020"
44+
)
45+
46+
val b2: BuildDescription = (
47+
declarationMap = true,
48+
baseUrl = ".",
49+
rootDir = "typescript",
50+
outDir = pubBundledOut,
51+
plugins = [
52+
( transform = "typescript-transform-paths" ),
53+
( transform = "typescript-transform-paths",
54+
afterDeclarations = true
55+
)
56+
],
57+
moduleResolution = "node",
58+
target = "ES2020"
59+
)
60+
61+
val b3: BuildDescription = ()
62+
63+
@main def Test =
64+
println(b1)
65+
println(b2)
66+
println(b3)
67+
68+
class Dep
69+
val junitInterface = Dep()
70+
val commonsIo = Dep()
71+
72+
val pubBundledOut = ""

0 commit comments

Comments
 (0)