Skip to content

Commit

Permalink
wip: bring paradise down to earth
Browse files Browse the repository at this point in the history
enable using -Ymacro-annot

TODO: fix commented out, failing tests,
which were also failing before integration into the compiler
  - src/test/scala/run/Multiple.scala
  - src/test/scala/run/Parameters.scala
  - src/test/scala/run/Recursive.scala

the tests are included as a new project (macroAnnot)

could we use quick as the compiler to compile these?
manually bootstrapping, it works
  • Loading branch information
adriaanm committed May 6, 2018
1 parent ac5c8fa commit ead62d5
Show file tree
Hide file tree
Showing 82 changed files with 3,579 additions and 12 deletions.
21 changes: 21 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,26 @@ lazy val junit = project.in(file("test") / "junit")
unmanagedSourceDirectories in Test := List(baseDirectory.value)
)

lazy val macroAnnot = project.in(file("test") / "macro-annot")
.dependsOn(library, reflect, compiler, repl, replFrontend, scaladoc)
.settings(disableDocs)
.settings(disablePublishing)
.settings(instanceSettings)
.settings(
fork in Test := true,
javaOptions in Test += "-Xss1M",
libraryDependencies ++= Seq(junitDep, junitInterfaceDep),
testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-v",
s"-Dsbt.paths.tests.classpath=${(fullClasspath in Test).value.files.map(_.getAbsolutePath).mkString(java.io.File.pathSeparatorChar.toString)}"),

baseDirectory in Compile := (baseDirectory in ThisBuild).value,
baseDirectory in Test := (baseDirectory in ThisBuild).value,

scalacOptions += "-Ymacro-annotations",
scalacOptions += "-Ywarn-unused-import",
scalacOptions += "-Xfatal-warnings"
)

lazy val scalacheck = project.in(file("test") / "scalacheck")
.dependsOn(library, reflect, compiler, scaladoc)
.settings(clearSourceAndResourceDirectories)
Expand Down Expand Up @@ -804,6 +824,7 @@ lazy val root: Project = (project in file("."))
val results = ScriptCommands.sequence[(Result[Unit], String)](List(
(Keys.test in Test in junit).result map (_ -> "junit/test"),
(Keys.test in Test in scalacheck).result map (_ -> "scalacheck/test"),
// (Keys.test in Test in macroAnnot).result map (_ -> "macroAnnot/test"),
(testOnly in IntegrationTest in testP).toTask(" -- run").result map (_ -> "partest run"),
(testOnly in IntegrationTest in testP).toTask(" -- pos neg jvm").result map (_ -> "partest pos neg jvm"),
(testOnly in IntegrationTest in testP).toTask(" -- res scalap specialized").result map (_ -> "partest res scalap specialized"),
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/scala/tools/nsc/Global.scala
Original file line number Diff line number Diff line change
Expand Up @@ -445,9 +445,9 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
// I only changed analyzer.
//
// factory for phases: namer, packageobjects, typer
lazy val analyzer = new {
val global: Global.this.type = Global.this
} with Analyzer
lazy val analyzer =
if (settings.YmacroAnnotations) new { val global: Global.this.type = Global.this } with Analyzer with MacroAnnotationNamers
else new { val global: Global.this.type = Global.this } with Analyzer

// phaseName = "patmat"
object patmat extends {
Expand Down
4 changes: 3 additions & 1 deletion src/compiler/scala/tools/nsc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
package scala.tools.nsc
package ast

import scala.reflect.internal.MacroAnnotionTreeInfo

/** This class ...
*
* @author Martin Odersky
* @version 1.0
*/
abstract class TreeInfo extends scala.reflect.internal.TreeInfo {
abstract class TreeInfo extends scala.reflect.internal.TreeInfo with MacroAnnotionTreeInfo {
val global: Global
import global._
import definitions._
Expand Down
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ trait ScalaSettings extends AbsScalaSettings
val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.")
val Ymacroexpand = ChoiceSetting ("-Ymacro-expand", "policy", "Control expansion of macros, useful for scaladoc and presentation compiler.", List(MacroExpand.Normal, MacroExpand.None, MacroExpand.Discard), MacroExpand.Normal)
val Ymacronoexpand = BooleanSetting ("-Ymacro-no-expand", "Don't expand macros. Might be useful for scaladoc and presentation compiler, but will crash anything which uses macros and gets past typer.") withDeprecationMessage(s"Use ${Ymacroexpand.name}:${MacroExpand.None}") withPostSetHook(_ => Ymacroexpand.value = MacroExpand.None)
val YmacroAnnotations = BooleanSetting ("-Ymacro-annotations", "Enable support for macro annotations, formerly in macro paradise.")
val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup")
val Yreplclassbased = BooleanSetting ("-Yrepl-class-based", "Use classes to wrap REPL snippets instead of objects")
val Yreploutdir = StringSetting ("-Yrepl-outdir", "path", "Write repl-generated classfiles to given output directory (use \"\" to generate a temporary dir)" , "")
Expand Down
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ trait Analyzer extends AnyRef
with TypeDiagnostics
with ContextErrors
with StdAttachments
with MacroAnnotationAttachments
with AnalyzerPlugins
{
val global : Global
Expand Down
62 changes: 62 additions & 0 deletions src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,68 @@ trait ContextErrors {

def MacroImplementationNotFoundError(expandee: Tree) =
macroExpansionError(expandee, macroImplementationNotFoundMessage(expandee.symbol.name))

def MacroAnnotationShapeError(clazz: Symbol) = {
val sym = clazz.info.member(nme.macroTransform)
var actualSignature = sym.toString
if (sym.isOverloaded) actualSignature += "(...) = ..."
else if (sym.isMethod) {
if (sym.typeParams.nonEmpty) {
def showTparam(tparam: Symbol) =
tparam.typeSignature match {
case tpe @ TypeBounds(_, _) => s"${tparam.name}$tpe"
case _ => tparam.name
}
def showTparams(tparams: List[Symbol]) = "[" + (tparams map showTparam mkString ", ") + "]"
actualSignature += showTparams(sym.typeParams)
}
if (sym.paramss.nonEmpty) {
def showParam(param: Symbol) = s"${param.name}: ${param.typeSignature}"
def showParams(params: List[Symbol]) = {
val s_mods = if (params.nonEmpty && params(0).hasFlag(scala.reflect.internal.Flags.IMPLICIT)) "implicit " else ""
val s_params = params map showParam mkString ", "
"(" + s_mods + s_params + ")"
}
def showParamss(paramss: List[List[Symbol]]) = paramss map showParams mkString ""
actualSignature += showParamss(sym.paramss)
}
if (sym.isTermMacro) actualSignature = actualSignature.replace("macro method", "def") + " = macro ..."
else actualSignature = actualSignature.replace("method", "def") + " = ..."
}
issueSymbolTypeError(clazz, s"""
|macro annotation has wrong shape:
| required: def macroTransform(annottees: Any*) = macro ...
| found : $actualSignature
""".trim.stripMargin)
}

def MacroAnnotationMustBeStaticError(clazz: Symbol) =
issueSymbolTypeError(clazz, s"macro annotation must extend scala.annotation.StaticAnnotation")

def MacroAnnotationCannotBeInheritedError(clazz: Symbol) =
issueSymbolTypeError(clazz, s"macro annotation cannot be @Inherited")

def MacroAnnotationCannotBeMemberError(clazz: Symbol) =
issueSymbolTypeError(clazz, s"macro annotation cannot be a member of another class")

def MacroAnnotationNotExpandedMessage = {
"macro annotation could not be expanded " +
"(the most common reason for that is that you need to enable the macro paradise plugin; " +
"another possibility is that you try to use macro annotation in the same compilation run that defines it)"
}

def MacroAnnotationOnlyDefinitionError(ann: Tree) =
issueNormalTypeError(ann, "macro annotations can only be put on definitions")

def MacroAnnotationTopLevelClassWithCompanionBadExpansion(ann: Tree) =
issueNormalTypeError(ann, "top-level class with companion can only expand into a block consisting in eponymous companions")

def MacroAnnotationTopLevelClassWithoutCompanionBadExpansion(ann: Tree) =
issueNormalTypeError(ann, "top-level class without companion can only expand either into an eponymous class or into a block consisting in eponymous companions")

def MacroAnnotationTopLevelModuleBadExpansion(ann: Tree) =
issueNormalTypeError(ann, "top-level object can only expand into an eponymous object")

}

/** This file will be the death of me. */
Expand Down
Loading

0 comments on commit ead62d5

Please sign in to comment.