1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
package scala.reflect.macros
package compiler
import scala.compat.Platform.EOL
import scala.reflect.macros.util.Traces
trait Errors extends Traces {
self: DefaultMacroCompiler =>
import global._
import analyzer._
import definitions._
import typer.TyperErrorGen._
import typer.infer.InferErrorGen._
def globalSettings = global.settings
// sanity check errors
private def implRefError(message: String) = abort(macroDdef.pos, message)
def MacroImplReferenceWrongShapeError() = implRefError(
"macro implementation reference has wrong shape. required:\n"+
"macro [<static object>].<method name>[[<type args>]] or\n" +
"macro [<macro bundle>].<method name>[[<type args>]]")
def MacroImplNotPublicError() = implRefError("macro implementation must be public")
def MacroImplOverloadedError() = implRefError("macro implementation cannot be overloaded")
def MacroImplWrongNumberOfTypeArgumentsError() = implRefError(TypedApplyWrongNumberOfTpeParametersErrorMessage(macroImplRef))
// compatibility errors
// helpers
private def lengthMsg(flavor: String, violation: String, extra: Symbol) = {
val noun = if (flavor == "value") "parameter" else "type parameter"
val message = noun + " lists have different length, " + violation + " extra " + noun
val suffix = if (extra ne NoSymbol) " " + extra.defString else ""
message + suffix
}
private def abbreviateCoreAliases(s: String): String = List("WeakTypeTag", "Expr").foldLeft(s)((res, x) => res.replace("c.universe." + x, "c." + x))
private def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = {
var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString
if (abbreviate) argsPart = abbreviateCoreAliases(argsPart)
var retPart = restpe.toString
if (abbreviate || macroDdef.tpt.tpe == null) retPart = abbreviateCoreAliases(retPart)
argsPart + ": " + retPart
}
// not exactly an error generator, but very related
// and I dearly wanted to push it away from Macros.scala
private def checkConforms(slot: String, rtpe: Type, atpe: Type) = {
val verbose = macroDebugVerbose || settings.explaintypes.value
def check(rtpe: Type, atpe: Type): Boolean = {
def success() = { if (verbose) println(rtpe + " <: " + atpe + "?" + EOL + "true"); true }
(rtpe, atpe) match {
case _ if rtpe eq atpe => success()
case (TypeRef(_, RepeatedParamClass, rtpe :: Nil), TypeRef(_, RepeatedParamClass, atpe :: Nil)) => check(rtpe, atpe)
case (ExprClassOf(_), TreeType()) => success()
case (TreeType(), ExprClassOf(_)) => success()
case _ => rtpe <:< atpe
}
}
val ok =
if (verbose) withTypesExplained(check(rtpe, atpe))
else check(rtpe, atpe)
if (!ok) {
if (!macroDebugVerbose)
explainTypes(rtpe, atpe)
compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, abbreviateCoreAliases(rtpe.toString), abbreviateCoreAliases(atpe.toString)))
}
}
private def compatibilityError(message: String) =
implRefError(
"macro implementation has wrong shape:"+
"\n required: " + showMeth(rparamss, rret, abbreviate = true) +
"\n found : " + showMeth(aparamss, aret, abbreviate = false) +
"\n" + message)
def MacroImplNonTagImplicitParameters(params: List[Symbol]) = compatibilityError("macro implementations cannot have implicit parameters other than WeakTypeTag evidences")
def MacroImplParamssMismatchError() = compatibilityError("number of parameter sections differ")
def MacroImplExtraParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(lengthMsg("value", "found", aparams(rparams.length)))
def MacroImplMissingParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(abbreviateCoreAliases(lengthMsg("value", "required", rparams(aparams.length))))
def checkMacroImplParamTypeMismatch(atpe: Type, rparam: Symbol) = checkConforms("parameter " + rparam.name, rparam.tpe, atpe)
def checkMacroImplResultTypeMismatch(atpe: Type, rret: Type) = checkConforms("return type", atpe, rret)
def MacroImplParamNameMismatchError(aparam: Symbol, rparam: Symbol) = compatibilityError("parameter names differ: " + rparam.name + " != " + aparam.name)
def MacroImplVarargMismatchError(aparam: Symbol, rparam: Symbol) = {
def fail(paramName: Name) = compatibilityError("types incompatible for parameter " + paramName + ": corresponding is not a vararg parameter")
if (isRepeated(rparam) && !isRepeated(aparam)) fail(rparam.name)
if (!isRepeated(rparam) && isRepeated(aparam)) fail(aparam.name)
}
def MacroImplTargMismatchError(atargs: List[Type], atparams: List[Symbol]) =
compatibilityError(NotWithinBoundsErrorMessage("", atargs, atparams, macroDebugVerbose || settings.explaintypes.value))
def MacroImplTparamInstantiationError(atparams: List[Symbol], ex: NoInstance) =
compatibilityError(
"type parameters "+(atparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+
ex.getMessage)
}
|