@@ -66,7 +66,9 @@ object Inliner {
6666 * and body that replace it.
6767 */
6868 def inlineCall (tree : Tree )(implicit ctx : Context ): Tree = {
69- if (tree.symbol == defn.CompiletimeTesting_typeChecks ) return Intrinsics .typeChecks(tree)
69+ if tree.symbol.owner.companionModule == defn.CompiletimeTestingPackageObject
70+ if (tree.symbol == defn.CompiletimeTesting_typeChecks ) return Intrinsics .typeChecks(tree)
71+ if (tree.symbol == defn.CompiletimeTesting_typeCheckErrors ) return Intrinsics .typeCheckErrors(tree)
7072
7173 /** Set the position of all trees logically contained in the expansion of
7274 * inlined call `call` to the position of `call`. This transform is necessary
@@ -193,10 +195,12 @@ object Inliner {
193195 }
194196
195197 object Intrinsics {
198+ import dotty .tools .dotc .reporting .diagnostic .messages .Error
199+ private enum ErrorKind
200+ case Parser , Typer
196201
197- /** Expand call to scala.compiletime.testing.typeChecks */
198- def typeChecks (tree : Tree )(implicit ctx : Context ): Tree = {
199- assert(tree.symbol == defn.CompiletimeTesting_typeChecks )
202+ private def compileForErrors (tree : Tree , stopAfterParser : Boolean )(given ctx : Context ): List [(ErrorKind , Error )] =
203+ assert(tree.symbol == defn.CompiletimeTesting_typeChecks || tree.symbol == defn.CompiletimeTesting_typeCheckErrors )
200204 def stripTyped (t : Tree ): Tree = t match {
201205 case Typed (t2, _) => stripTyped(t2)
202206 case _ => t
@@ -205,20 +209,49 @@ object Inliner {
205209 val Apply (_, codeArg :: Nil ) = tree
206210 ConstFold (stripTyped(codeArg.underlyingArgument)).tpe.widenTermRefExpr match {
207211 case ConstantType (Constant (code : String )) =>
208- val ctx2 = ctx.fresh.setNewTyperState().setTyper(new Typer )
209- val tree2 = new Parser (SourceFile .virtual(" tasty-reflect" , code))(ctx2).block()
210- val res =
211- if (ctx2.reporter.hasErrors) false
212- else {
213- ctx2.typer.typed(tree2)(ctx2)
214- ! ctx2.reporter.hasErrors
215- }
216- Literal (Constant (res))
212+ val source2 = SourceFile .virtual(" tasty-reflect" , code)
213+ val ctx2 = ctx.fresh.setNewTyperState().setTyper(new Typer ).setSource(source2)
214+ val tree2 = new Parser (source2)(ctx2).block()
215+ val res = collection.mutable.ListBuffer .empty[(ErrorKind , Error )]
216+
217+ val parseErrors = ctx2.reporter.allErrors.toList
218+ res ++= parseErrors.map(e => ErrorKind .Parser -> e)
219+ if ! stopAfterParser || res.isEmpty
220+ ctx2.typer.typed(tree2)(ctx2)
221+ val typerErrors = ctx2.reporter.allErrors.filterNot(parseErrors.contains)
222+ res ++= typerErrors.map(e => ErrorKind .Typer -> e)
223+ res.toList
217224 case t =>
218225 assert(ctx.reporter.hasErrors) // at least: argument to inline parameter must be a known value
219- EmptyTree
226+ Nil
220227 }
221- }
228+
229+ private def packError (kind : ErrorKind , error : Error )(given Context ): Tree =
230+ def lit (x : Any ) = Literal (Constant (x))
231+ val constructor : Tree = ref(defn.CompiletimeTesting_Error_apply )
232+ val parserErrorKind : Tree = ref(defn.CompiletimeTesting_ErrorKind_Parser )
233+ val typerErrorKind : Tree = ref(defn.CompiletimeTesting_ErrorKind_Typer )
234+
235+ constructor.appliedTo(
236+ lit(error.message),
237+ lit(error.pos.lineContent.reverse.dropWhile(" \n " .contains).reverse),
238+ lit(error.pos.column),
239+ if kind == ErrorKind .Parser then parserErrorKind else typerErrorKind)
240+
241+ private def packErrors (errors : List [(ErrorKind , Error )])(given Context ): Tree =
242+ val individualErrors : List [Tree ] = errors.map(packError)
243+ val errorTpt = ref(defn.CompiletimeTesting_ErrorClass )
244+ mkList(individualErrors, errorTpt)
245+
246+ /** Expand call to scala.compiletime.testing.typeChecks */
247+ def typeChecks (tree : Tree )(given Context ): Tree =
248+ val errors = compileForErrors(tree, true )
249+ Literal (Constant (errors.isEmpty))
250+
251+ /** Expand call to scala.compiletime.testing.typeCheckErrors */
252+ def typeCheckErrors (tree : Tree )(given Context ): Tree =
253+ val errors = compileForErrors(tree, false )
254+ packErrors(errors)
222255 }
223256}
224257
0 commit comments