diff --git a/compiler/src/dotty/tools/dotc/ast/MainProxies.scala b/compiler/src/dotty/tools/dotc/ast/MainProxies.scala index 5e969c0c38c9..1133d015f69f 100644 --- a/compiler/src/dotty/tools/dotc/ast/MainProxies.scala +++ b/compiler/src/dotty/tools/dotc/ast/MainProxies.scala @@ -242,8 +242,10 @@ object MainProxies { val param = paramName.toString val paramType0 = if formal.isRepeatedParam then formal.argTypes.head.dealias else formal.dealias val paramType = paramType0.dealias - - val paramTypeStr = formal.dealias.typeSymbol.owner.showFullName + "." + paramType.show + val paramTypeOwner = paramType.typeSymbol.owner + val paramTypeStr = + if paramTypeOwner == defn.EmptyPackageClass then paramType.show + else paramTypeOwner.showFullName + "." + paramType.show val hasDefault = defaultValueSymbols.contains(idx) val isRepeated = formal.isRepeatedParam val paramDoc = documentation.argDocs.getOrElse(param, "") diff --git a/tests/run/main-calculator-example.check b/tests/run/main-calculator-example.check new file mode 100644 index 000000000000..07946c911e9f --- /dev/null +++ b/tests/run/main-calculator-example.check @@ -0,0 +1,8 @@ +Expression: Plus(Number(1),Number(2)) +Calculated: 3 +executing sum2 with inputs: 2 3 +Expression: Plus(Number(2),Number(3)) +Calculated: 5 +executing sumAll with inputs: 1 2 3 +Expression: Plus(Plus(Number(1),Number(2)),Number(3)) +Calculated: 6 diff --git a/tests/run/main-calculator-example.scala b/tests/run/main-calculator-example.scala new file mode 100644 index 000000000000..813f63c956a8 --- /dev/null +++ b/tests/run/main-calculator-example.scala @@ -0,0 +1,64 @@ +sealed trait Expression: + def eval(): Int +case class Number(n: Int) extends Expression: + def eval(): Int = n +case class Plus(e1: Expression, e2: Expression) extends Expression: + def eval(): Int = e1.eval() + e2.eval() + +//// + +@main def sum(n1: Int, n2: Int) = + val x1 = Number(n1) + val x2 = Number(n2) + val expr = Plus(x1, x2) + println(s"Expression: $expr") + val result = expr.eval() + println(s"Calculated: $result") + +//// + +import scala.annotation.{ MainAnnotation, experimental } +import scala.annotation.MainAnnotation.{ Info, Parameter } +import scala.util.CommandLineParser.FromString + +@experimental class showAndEval extends MainAnnotation[FromString, Expression]: + def command(info: Info, args: Seq[String]): Option[Seq[String]] = + assert(info.parameters.forall(param => param.typeName == "Number"), "Only Number parameters allowed") + println(s"executing ${info.name} with inputs: ${args.mkString(" ")}") + Some(args) + + def argGetter[T](param: Parameter, arg: String, defaultArgument: Option[() => T])(using parser: FromString[T]): () => T = + () => parser.fromString(arg) + + def varargGetter[T](param: Parameter, args: Seq[String])(using parser: FromString[T]): () => Seq[T] = + () => args.map(arg => parser.fromString(arg)) + + def run(program: () => Expression): Unit = + val expr = program() + println(s"Expression: $expr") + val result = expr.eval() + println(s"Calculated: $result") +end showAndEval + +given FromString[Number] = (x: String) => Number(x.toInt) + +//// + +@showAndEval def sum2(x1: Number, x2: Number): Expression = + sumAll(x1, x2) + +@showAndEval def sumAll(xs: Number*): Expression = + if xs.isEmpty then Number(0) + else xs.tail.fold[Expression](xs.head)(Plus) + +//// + +@main def Test: Unit = + def callMain(name: String, args: String*): Unit = + val clazz = Class.forName(name) + val method = clazz.getMethod("main", classOf[Array[String]]) + method.invoke(null, args.toArray) + callMain("sum", "1", "2") + callMain("sum2", "2", "3") + callMain("sumAll", "1", "2", "3") +end Test