mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:59:47 +00:00
[macros] Add DiagnosticException
that macro implementations can throw to report a diagnostic.
R=jakemac@google.com Change-Id: I7546aa84f3e0b8423465dcb49d90a89df9231b84 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/350302 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Auto-Submit: Morgan :) <davidmorgan@google.com> Reviewed-by: Jake Macdonald <jakemac@google.com> Commit-Queue: Morgan :) <davidmorgan@google.com>
This commit is contained in:
parent
f4b1d59461
commit
f367d1e107
|
@ -4,6 +4,14 @@
|
|||
|
||||
part of '../api.dart';
|
||||
|
||||
/// Exception for use in macro implementations.
|
||||
///
|
||||
/// Throw to stop the current macro execution and report a [Diagnostic].
|
||||
class DiagnosticException implements Exception {
|
||||
final Diagnostic diagnostic;
|
||||
DiagnosticException(this.diagnostic);
|
||||
}
|
||||
|
||||
/// Base class for exceptions thrown by the host implementation during macro
|
||||
/// execution.
|
||||
///
|
||||
|
|
|
@ -59,8 +59,10 @@ Future<MacroExecutionResult> executeTypesMacro(
|
|||
'macro: $macro\ntarget: $target');
|
||||
}
|
||||
} catch (e, s) {
|
||||
// Preserve `MacroException`s thrown by SDK tools.
|
||||
if (e is MacroExceptionImpl) {
|
||||
if (e is DiagnosticException) {
|
||||
builder.report(e.diagnostic);
|
||||
} else if (e is MacroExceptionImpl) {
|
||||
// Preserve `MacroException`s thrown by SDK tools.
|
||||
builder.failWithException(e);
|
||||
} else {
|
||||
// Convert exceptions thrown by macro implementations into diagnostics.
|
||||
|
@ -137,8 +139,10 @@ Future<MacroExecutionResult> executeDeclarationsMacro(Macro macro,
|
|||
'macro: $macro\ntarget: $target');
|
||||
}
|
||||
} catch (e, s) {
|
||||
// Preserve `MacroException`s thrown by SDK tools.
|
||||
if (e is MacroExceptionImpl) {
|
||||
if (e is DiagnosticException) {
|
||||
builder.report(e.diagnostic);
|
||||
} else if (e is MacroExceptionImpl) {
|
||||
// Preserve `MacroException`s thrown by SDK tools.
|
||||
builder.failWithException(e);
|
||||
} else {
|
||||
// Convert exceptions thrown by macro implementations into diagnostics.
|
||||
|
@ -212,8 +216,10 @@ Future<MacroExecutionResult> executeDefinitionMacro(Macro macro, Object target,
|
|||
'macro: $macro\ntarget: $target');
|
||||
}
|
||||
} catch (e, s) {
|
||||
// Preserve `MacroException`s thrown by SDK tools.
|
||||
if (e is MacroExceptionImpl) {
|
||||
if (e is DiagnosticException) {
|
||||
builder.report(e.diagnostic);
|
||||
} else if (e is MacroExceptionImpl) {
|
||||
// Preserve `MacroException`s thrown by SDK tools.
|
||||
builder.failWithException(e);
|
||||
} else {
|
||||
// Convert exceptions thrown by macro implementations into diagnostics.
|
||||
|
|
14
tests/language/macros/error/diagnostic_exception_test.dart
Normal file
14
tests/language/macros/error/diagnostic_exception_test.dart
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
// SharedOptions=--enable-experiment=macros
|
||||
|
||||
import 'impl/throw_diagnostic_exception_macro.dart';
|
||||
|
||||
@ThrowDiagnosticException(atTypeDeclaration: 'B', withMessage: 'failed here')
|
||||
class A {}
|
||||
|
||||
class B {}
|
||||
// ^
|
||||
// [analyzer] COMPILE_TIME_ERROR.MACRO_ERROR
|
||||
// [cfe] failed here
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
// ignore_for_file: deprecated_member_use
|
||||
import 'package:_fe_analyzer_shared/src/macros/api.dart';
|
||||
|
||||
macro class ThrowDiagnosticException implements ClassDeclarationsMacro {
|
||||
final String atTypeDeclaration;
|
||||
final String withMessage;
|
||||
|
||||
const ThrowDiagnosticException({
|
||||
required this.atTypeDeclaration, required this.withMessage});
|
||||
|
||||
Future<void> buildDeclarationsForClass(
|
||||
ClassDeclaration clazz, MemberDeclarationBuilder builder) async {
|
||||
final identifier = await builder.resolveIdentifier(clazz.library.uri, atTypeDeclaration);
|
||||
final declaration = await builder.typeDeclarationOf(identifier);
|
||||
throw DiagnosticException(Diagnostic(DiagnosticMessage(
|
||||
withMessage, target: declaration.asDiagnosticTarget), Severity.error));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue