Skip to content

Commit

Permalink
Add newMain prototype
Browse files Browse the repository at this point in the history
Based on prototype in scala#13727

Co-authored-by: Timothée Loyck Andres <timothee.andres@epfl.ch>
  • Loading branch information
nicolasstucki and timotheeandres committed May 19, 2022
1 parent 8bae490 commit 891a1c6
Show file tree
Hide file tree
Showing 77 changed files with 1,900 additions and 23 deletions.
22 changes: 8 additions & 14 deletions compiler/src/dotty/tools/dotc/ast/MainProxies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ import NameKinds.DefaultGetterName
import Annotations.Annotation

object MainProxies {

/** Generate proxy classes for @main functions and @myMain functions where myMain <:< MainAnnotation */
def proxies(stats: List[tpd.Tree])(using Context): List[untpd.Tree] = {
mainAnnotationProxies(stats) ++ mainProxies(stats)
}

/** Generate proxy classes for @main functions.
* A function like
*
Expand All @@ -35,7 +29,7 @@ object MainProxies {
* catch case err: ParseError => showError(err)
* }
*/
private def mainProxies(stats: List[tpd.Tree])(using Context): List[untpd.Tree] = {
def mainProxiesOld(stats: List[tpd.Tree])(using Context): List[untpd.Tree] = {
import tpd._
def mainMethods(stats: List[Tree]): List[Symbol] = stats.flatMap {
case stat: DefDef if stat.symbol.hasAnnotation(defn.MainAnnot) =>
Expand All @@ -45,11 +39,11 @@ object MainProxies {
case _ =>
Nil
}
mainMethods(stats).flatMap(mainProxy)
mainMethods(stats).flatMap(mainProxyOld)
}

import untpd._
private def mainProxy(mainFun: Symbol)(using Context): List[TypeDef] = {
def mainProxyOld(mainFun: Symbol)(using Context): List[TypeDef] = {
val mainAnnotSpan = mainFun.getAnnotation(defn.MainAnnot).get.tree.span
def pos = mainFun.sourcePos
val argsRef = Ident(nme.args)
Expand Down Expand Up @@ -171,7 +165,7 @@ object MainProxies {
* }
* }
*/
private def mainAnnotationProxies(stats: List[tpd.Tree])(using Context): List[untpd.Tree] = {
def mainProxies(stats: List[tpd.Tree])(using Context): List[untpd.Tree] = {
import tpd._

/**
Expand All @@ -194,12 +188,12 @@ object MainProxies {
def mainMethods(scope: Tree, stats: List[Tree]): List[(Symbol, ParameterAnnotationss, DefaultValueSymbols, Option[Comment])] = stats.flatMap {
case stat: DefDef =>
val sym = stat.symbol
sym.annotations.filter(_.matches(defn.MainAnnotationClass)) match {
sym.annotations.filter(_.matches(defn.MainAnnot)) match {
case Nil =>
Nil
case _ :: Nil =>
val paramAnnotations = stat.paramss.flatMap(_.map(
valdef => valdef.symbol.annotations.filter(_.matches(defn.MainAnnotationParameterAnnotation))
valdef => valdef.symbol.annotations.filter(_.matches(defn.MainAnnotParameterAnnotation))
))
(sym, paramAnnotations.toVector, defaultValueSymbols(scope, sym), stat.rawComment) :: Nil
case mainAnnot :: others =>
Expand All @@ -213,7 +207,7 @@ object MainProxies {
}

// Assuming that the top-level object was already generated, all main methods will have a scope
mainMethods(EmptyTree, stats).flatMap(mainAnnotationProxy)
mainMethods(EmptyTree, stats).flatMap(mainProxy)
}

private def mainAnnotationProxy(mainFun: Symbol, paramAnnotations: ParameterAnnotationss, defaultValueSymbols: DefaultValueSymbols, docComment: Option[Comment])(using Context): Option[TypeDef] = {
Expand Down Expand Up @@ -367,7 +361,7 @@ object MainProxies {
case tree => super.transform(tree)
}
val annots = mainFun.annotations
.filterNot(_.matches(defn.MainAnnotationClass))
.filterNot(_.matches(defn.MainAnnot))
.map(annot => insertTypeSplices.transform(annot.tree))
val mainMeth = DefDef(nme.main, (mainArg :: Nil) :: Nil, TypeTree(defn.UnitType), body)
.withFlags(JavaStatic)
Expand Down
1 change: 0 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,6 @@ class Definitions {
@tu lazy val InlineParamAnnot: ClassSymbol = requiredClass("scala.annotation.internal.InlineParam")
@tu lazy val ErasedParamAnnot: ClassSymbol = requiredClass("scala.annotation.internal.ErasedParam")
@tu lazy val InvariantBetweenAnnot: ClassSymbol = requiredClass("scala.annotation.internal.InvariantBetween")
@tu lazy val MainAnnot: ClassSymbol = requiredClass("scala.main")
@tu lazy val MigrationAnnot: ClassSymbol = requiredClass("scala.annotation.migration")
@tu lazy val NowarnAnnot: ClassSymbol = requiredClass("scala.annotation.nowarn")
@tu lazy val TransparentTraitAnnot: ClassSymbol = requiredClass("scala.annotation.transparentTrait")
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1382,10 +1382,9 @@ trait Checking {
/** check that annotation `annot` is applicable to symbol `sym` */
def checkAnnotApplicable(annot: Tree, sym: Symbol)(using Context): Boolean =
!ctx.reporter.reportsErrorsFor {
val annotCls = Annotations.annotClass(annot)
val concreteAnnot = Annotations.ConcreteAnnotation(annot)
val pos = annot.srcPos
if (annotCls == defn.MainAnnot || concreteAnnot.matches(defn.MainAnnotationClass)) {
if (concreteAnnot.matches(defn.MainAnnot)) {
if (!sym.isRealMethod)
report.error(em"main annotation cannot be applied to $sym", pos)
if (!sym.owner.is(Module) || !sym.owner.isStatic)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2626,7 +2626,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
pkg.moduleClass.info.decls.lookup(topLevelClassName).ensureCompleted()
var stats1 = typedStats(tree.stats, pkg.moduleClass)._1
if (!ctx.isAfterTyper)
stats1 = stats1 ++ typedBlockStats(MainProxies.proxies(stats1))._1
stats1 = stats1 ++ typedBlockStats(MainProxies.mainProxies(stats1))._1
cpy.PackageDef(tree)(pid1, stats1).withType(pkg.termRef)
}
case _ =>
Expand Down
Loading

0 comments on commit 891a1c6

Please sign in to comment.