Skip to content

Commit 7bc5f89

Browse files
committed
Refactor constructor call
1 parent 49d551a commit 7bc5f89

File tree

1 file changed

+44
-22
lines changed

1 file changed

+44
-22
lines changed

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -432,19 +432,10 @@ object Semantic {
432432
val cls = target.owner.enclosingClass.asClass
433433
val ddef = target.defTree.asInstanceOf[DefDef]
434434
val env2 = Env(ddef, args.map(_.value).widenArgs)
435-
if target.isPrimaryConstructor then
436-
given Env = env2
437-
val tpl = cls.defTree.asInstanceOf[TypeDef].rhs.asInstanceOf[Template]
438-
val res = withTrace(trace.add(cls.defTree)) { eval(tpl, ref, cls, cacheResult = true) }
439-
Result(ref, res.errors)
440-
else if target.isConstructor then
441-
given Env = env2
442-
eval(ddef.rhs, ref, cls, cacheResult = true)
443-
else
444-
// normal method call
445-
withEnv(if isLocal then env else Env.empty) {
446-
eval(ddef.rhs, ref, cls, cacheResult = true) ++ checkArgs
447-
}
435+
// normal method call
436+
withEnv(if isLocal then env else Env.empty) {
437+
eval(ddef.rhs, ref, cls, cacheResult = true) ++ checkArgs
438+
}
448439
else if ref.canIgnoreMethodCall(target) then
449440
Result(Hot, Nil)
450441
else
@@ -475,6 +466,37 @@ object Semantic {
475466
}
476467
}
477468

469+
def callConstructor(ctor: Symbol, args: List[ArgInfo], source: Tree): Contextual[Result] = log("call " + ctor.show + ", args = " + args, printer, res => res.asInstanceOf[Result].show) {
470+
value match {
471+
case Hot | Cold | _: RefSet | _: Fun =>
472+
report.error("unexpected constructor call, meth = " + ctor + ", value = " + value, source)
473+
Result(Hot, Nil)
474+
475+
case ref: Ref =>
476+
val trace1 = trace.add(source)
477+
if ctor.hasSource then
478+
given Trace = trace1
479+
val cls = ctor.owner.enclosingClass.asClass
480+
val ddef = ctor.defTree.asInstanceOf[DefDef]
481+
val env2 = Env(ddef, args.map(_.value).widenArgs)
482+
if ctor.isPrimaryConstructor then
483+
given Env = env2
484+
val tpl = cls.defTree.asInstanceOf[TypeDef].rhs.asInstanceOf[Template]
485+
val res = withTrace(trace.add(cls.defTree)) { eval(tpl, ref, cls, cacheResult = true) }
486+
Result(ref, res.errors)
487+
else
488+
given Env = env2
489+
eval(ddef.rhs, ref, cls, cacheResult = true)
490+
else if ref.canIgnoreMethodCall(ctor) then
491+
Result(Hot, Nil)
492+
else
493+
// no source code available
494+
val error = CallUnknown(ctor, source, trace.toVector)
495+
Result(Hot, error :: Nil)
496+
}
497+
498+
}
499+
478500
/** Handle a new expression `new p.C` where `p` is abstracted by `value` */
479501
def instantiate(klass: ClassSymbol, ctor: Symbol, args: List[ArgInfo], source: Tree): Contextual[Result] = log("instantiating " + klass.show + ", value = " + value + ", args = " + args, printer, res => res.asInstanceOf[Result].show) {
480502
val trace1 = trace.add(source)
@@ -493,10 +515,10 @@ object Semantic {
493515
Result(Hot, Errors.empty)
494516
else
495517
val outer = Hot
496-
val value = Warm(klass, outer, ctor, args2)
497-
val task = ThisRef(klass, outer, ctor, args2)
498-
this.addTask(task)
499-
Result(value, Errors.empty)
518+
val warm = Warm(klass, outer, ctor, args2)
519+
val argInfos2 = args.zip(args2).map { (argInfo, v) => argInfo.copy(value = v) }
520+
val res = warm.callConstructor(ctor, argInfos2, source)
521+
Result(warm, res.errors)
500522

501523
case Cold =>
502524
val error = CallCold(ctor, source, trace1.toVector)
@@ -510,10 +532,10 @@ object Semantic {
510532
case _ => ref
511533

512534
val argsWidened = args.map(_.value).widenArgs
513-
val value = Warm(klass, outer, ctor, argsWidened)
514-
val task = ThisRef(klass, outer, ctor, argsWidened)
515-
this.addTask(task)
516-
Result(value, Errors.empty)
535+
val argInfos2 = args.zip(argsWidened).map { (argInfo, v) => argInfo.copy(value = v) }
536+
val warm = Warm(klass, outer, ctor, argsWidened)
537+
val res = warm.callConstructor(ctor, argInfos2, source)
538+
Result(warm, res.errors)
517539

518540
case Fun(body, thisV, klass, env) =>
519541
report.error("unexpected tree in instantiating a function, fun = " + body.show, source)
@@ -1132,7 +1154,7 @@ object Semantic {
11321154
if cls.hasSource then
11331155
tasks.append { () =>
11341156
printer.println("init super class " + cls.show)
1135-
val res2 = thisV.call(ctor, args, superType = NoType, source)
1157+
val res2 = thisV.callConstructor(ctor, args, source)
11361158
errorBuffer ++= res2.errors
11371159
()
11381160
}

0 commit comments

Comments
 (0)