|
Scala example source code file (Errors.scala)
The Errors.scala Scala example source codepackage 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 treeInfo._ import typer.TyperErrorGen._ import typer.infer.InferErrorGen._ import runDefinitions._ def globalSettings = global.settings private def implRefError(message: String) = { val Applied(culprit, _, _) = macroDdef.rhs abort(culprit.pos, message) } private def bundleRefError(message: String) = { val Applied(core, _, _) = macroDdef.rhs val culprit = core match { case Select(Applied(core, _, _), _) => core case _ => core } abort(culprit.pos, message) } def MacroImplAmbiguousError() = implRefError( "macro implementation reference is ambiguous: makes sense both as\n"+ "a macro bundle method reference and a vanilla object method reference") def MacroBundleNonStaticError() = bundleRefError("macro bundles must be static") def MacroBundleWrongShapeError() = bundleRefError("macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter") trait Error { self: MacroImplRefCompiler => // sanity check errors 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 MacroImplWrongNumberOfTypeArgumentsError() = { val diagnostic = if (macroImpl.typeParams.length > targs.length) "has too few type arguments" else "has too many arguments" implRefError(s"macro implementation reference $diagnostic for " + treeSymTypeMsg(macroImplRef)) } private def macroImplementationWording = if (isImplBundle) "bundle implementation" else "macro implementation" def MacroImplNotPublicError() = implRefError(s"${macroImplementationWording} must be public") def MacroImplOverloadedError() = implRefError(s"${macroImplementationWording} cannot be overloaded") def MacroImplNonTagImplicitParameters(params: List[Symbol]) = implRefError(s"${macroImplementationWording}s cannot have implicit parameters other than WeakTypeTag evidences") // 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 = { val coreAliases = List("WeakTypeTag", "Expr", "Tree") coreAliases.foldLeft(s)((res, x) => res.replace("c.universe." + x, "c." + x)) } private def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean, untype: Boolean) = { def preprocess(tpe: Type) = if (untype) untypeMetalevel(tpe) else tpe var pssPart = (pss map (ps => ps map (p => p.defStringSeenAs(preprocess(p.info))) mkString ("(", ", ", ")"))).mkString if (abbreviate) pssPart = abbreviateCoreAliases(pssPart) var retPart = preprocess(restpe).toString if (abbreviate || macroDdef.tpt.tpe == null) retPart = abbreviateCoreAliases(retPart) pssPart + ": " + 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 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()) if rtpe.prefix =:= atpe.prefix => success() case (SubtreeType(), ExprClassOf(_)) if rtpe.prefix =:= atpe.prefix => success() case _ => rtpe <:< atpe } } val ok = if (verbose) withTypesExplained(check(rtpe, atpe)) else check(rtpe, atpe) if (!ok) { if (!verbose) explainTypes(rtpe, atpe) val msg = { val ss = Seq(rtpe, atpe) map (this abbreviateCoreAliases _.toString) s"type mismatch for $slot: ${ss(0)} does not conform to ${ss(1)}" } compatibilityError(msg) } } private def compatibilityError(message: String) = implRefError( s"${macroImplementationWording} has incompatible shape:"+ "\n required: " + showMeth(rparamss, rret, abbreviate = true, untype = false) + "\n or : " + showMeth(rparamss, rret, abbreviate = true, untype = true) + "\n found : " + showMeth(aparamss, aret, abbreviate = false, untype = false) + "\n" + message) 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], e: NoInstance) = { val badps = atparams map (_.defString) mkString ", " compatibilityError(f"type parameters $badps cannot be instantiated%n${e.getMessage}") } } } Other Scala source code examplesHere is a short list of links related to this Scala Errors.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.