Report MACRO_EXECUTION_EXCEPTION.

Change-Id: Ia4c9b897467ce276c2030cbf242146aa95410189
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241988
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2022-04-22 01:10:28 +00:00 committed by Commit Bot
parent 633803df35
commit 73935c1d83
9 changed files with 163 additions and 25 deletions

View file

@ -608,6 +608,8 @@ CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED:
status: needsEvaluation
CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE:
status: needsEvaluation
CompileTimeErrorCode.MACRO_EXECUTION_EXCEPTION:
status: needsEvaluation
CompileTimeErrorCode.MAIN_FIRST_POSITIONAL_PARAMETER_TYPE:
status: needsEvaluation
CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS:

View file

@ -285,6 +285,7 @@ const List<ErrorCode> errorCodeValues = [
CompileTimeErrorCode.LATE_FINAL_FIELD_WITH_CONST_CONSTRUCTOR,
CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED,
CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
CompileTimeErrorCode.MACRO_EXECUTION_EXCEPTION,
CompileTimeErrorCode.MAIN_FIRST_POSITIONAL_PARAMETER_TYPE,
CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS,
CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS,

View file

@ -9017,6 +9017,18 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
hasPublishedDocs: true,
);
/**
* Parameters:
* 0: the message of the exception
* 1: the stack trace
*/
static const CompileTimeErrorCode MACRO_EXECUTION_EXCEPTION =
CompileTimeErrorCode(
'MACRO_EXECUTION_EXCEPTION',
"Exception during macro execution: {0}\n{1}",
correctionMessage: "Re-install the Dart or Flutter SDK.",
);
/**
* No parameters.
*/

View file

@ -46,6 +46,7 @@ import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error_detection_helpers.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
import 'package:analyzer/src/generated/this_access_tracker.dart';
import 'package:analyzer/src/summary2/macro_application_error.dart';
import 'package:analyzer/src/utilities/extensions/string.dart';
import 'package:collection/collection.dart';
@ -445,6 +446,10 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
_checkForBadFunctionUse(node);
_checkForWrongTypeParameterVarianceInSuperinterfaces();
_checkForMainFunction(node.name);
_reportMacroApplicationErrors(
annotations: node.metadata,
macroErrors: element.macroApplicationErrors,
);
GetterSetterTypesVerifier(
typeSystem: typeSystem,
@ -5173,6 +5178,30 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
return null;
}
void _reportMacroApplicationErrors({
required List<Annotation> annotations,
required List<MacroApplicationError> macroErrors,
}) {
for (final macroError in macroErrors) {
if (macroError.annotationIndex < annotations.length) {
final applicationNode = annotations[macroError.annotationIndex];
if (macroError is UnknownMacroApplicationError) {
errorReporter.reportErrorForNode(
CompileTimeErrorCode.MACRO_EXECUTION_EXCEPTION,
applicationNode,
[
macroError.message,
macroError.stackTrace,
],
);
} else {
// TODO(scheglov) Other implementations.
throw UnimplementedError('(${macroError.runtimeType}) $macroError');
}
}
}
}
void _withEnclosingExecutable(
ExecutableElement element,
void Function() operation,

View file

@ -6,6 +6,7 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart' as macro;
import 'package:_fe_analyzer_shared/src/macros/executor.dart' as macro;
import 'package:_fe_analyzer_shared/src/macros/executor/introspection_impls.dart'
as macro;
import 'package:_fe_analyzer_shared/src/macros/executor/protocol.dart' as macro;
import 'package:_fe_analyzer_shared/src/macros/executor/remote_instance.dart'
as macro;
import 'package:analyzer/dart/ast/ast.dart';
@ -69,12 +70,20 @@ class LibraryMacroApplier {
}
} on MacroApplicationError catch (e) {
classElement.macroApplicationErrors.add(e);
} on macro.RemoteException catch (e) {
classElement.macroApplicationErrors.add(
UnknownMacroApplicationError(
annotationIndex: i,
message: e.error,
stackTrace: e.stackTrace ?? '<null>',
),
);
} catch (e, stackTrace) {
classElement.macroApplicationErrors.add(
UnknownMacroApplicationError(
annotationIndex: i,
stackTrace: stackTrace.toString(),
message: e.toString(),
stackTrace: stackTrace.toString(),
),
);
}

View file

@ -7917,6 +7917,13 @@ CompileTimeErrorCode:
```dart
List<num> x = [1, 2.5, 3];
```
MACRO_EXECUTION_EXCEPTION:
problemMessage: "Exception during macro execution: {0}\n{1}"
correctionMessage: Re-install the Dart or Flutter SDK.
comment: |-
Parameters:
0: the message of the exception
1: the stack trace
MAIN_FIRST_POSITIONAL_PARAMETER_TYPE:
problemMessage: "The type of the first positional parameter of the 'main' function must be a supertype of 'List<String>'."
correctionMessage: Try changing the type of the parameter.

View file

@ -8,8 +8,6 @@ import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/summary2/kernel_compilation_service.dart';
import 'package:analyzer/src/summary2/macro.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@ -24,11 +22,6 @@ main() {
@reflectiveTest
class AnalysisDriverCachingTest extends PubPackageResolutionTest {
@override
MacroKernelBuilder? get macroKernelBuilder {
return FrontEndServerMacroKernelBuilder();
}
String get testFilePathPlatform => convertPath(testFilePath);
List<Set<String>> get _linkedCycles {
@ -46,14 +39,6 @@ class AnalysisDriverCachingTest extends PubPackageResolutionTest {
);
}
@override
Future<void> tearDown() async {
await super.tearDown();
KernelCompilationService.disposeDelayed(
const Duration(milliseconds: 100),
);
}
test_analysisOptions_strictCasts() async {
useEmptyByteStore();

View file

@ -2,7 +2,7 @@
// 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.
import 'package:analyzer/src/summary2/kernel_compilation_service.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../summary/macros_environment.dart';
@ -33,14 +33,6 @@ class MacroResolutionTest extends PubPackageResolutionTest {
);
}
@override
Future<void> tearDown() async {
await super.tearDown();
KernelCompilationService.disposeDelayed(
const Duration(milliseconds: 100),
);
}
test_0() async {
newFile('$testPackageLibPath/a.dart', r'''
import 'dart:async';
@ -68,4 +60,46 @@ class A {}
void f(A_Macro a) {}
''');
}
test_macroExecutionException_compileTimeError() async {
newFile('$testPackageLibPath/a.dart', r'''
import 'package:_fe_analyzer_shared/src/macros/api.dart';
macro class MyMacro implements ClassTypesMacro {
const MyMacro();
buildTypesForClass(clazz, builder) {
unresolved;
}
}
''');
await assertErrorsInCode('''
import 'a.dart';
@MyMacro()
class A {}
''', [error(CompileTimeErrorCode.MACRO_EXECUTION_EXCEPTION, 18, 10)]);
}
test_macroExecutionException_throwsException() async {
newFile('$testPackageLibPath/a.dart', r'''
import 'package:_fe_analyzer_shared/src/macros/api.dart';
macro class MyMacro implements ClassTypesMacro {
const MyMacro();
buildTypesForClass(clazz, builder) {
throw 42;
}
}
''');
await assertErrorsInCode('''
import 'a.dart';
@MyMacro()
class A {}
''', [error(CompileTimeErrorCode.MACRO_EXECUTION_EXCEPTION, 18, 10)]);
}
}

View file

@ -5,6 +5,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/summary2/macro_application_error.dart';
import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@ -468,6 +469,64 @@ class A
''');
}
test_macroApplicationErrors_compileTimeError() async {
newFile('$testPackageLibPath/a.dart', r'''
import 'package:_fe_analyzer_shared/src/macros/api.dart';
macro class MyMacro implements ClassTypesMacro {
buildTypesForClass(clazz, builder) {
unresolved;
}
}
''');
final library = await buildLibrary(r'''
import 'a.dart';
@MyMacro()
class A {}
''', preBuildSequence: [
{'package:test/a.dart'}
]);
final A = library.getType('A') as ClassElementImpl;
final error = A.macroApplicationErrors.single;
error as UnknownMacroApplicationError;
expect(error.annotationIndex, 0);
expect(error.message, contains('unresolved'));
expect(error.stackTrace, contains('executeTypesMacro'));
}
test_macroApplicationErrors_throwsException() async {
newFile('$testPackageLibPath/a.dart', r'''
import 'package:_fe_analyzer_shared/src/macros/api.dart';
macro class MyMacro implements ClassTypesMacro {
buildTypesForClass(clazz, builder) {
throw 'foo bar';
}
}
''');
final library = await buildLibrary(r'''
import 'a.dart';
@MyMacro()
class A {}
''', preBuildSequence: [
{'package:test/a.dart'}
]);
final A = library.getType('A') as ClassElementImpl;
final error = A.macroApplicationErrors.single;
error as UnknownMacroApplicationError;
expect(error.annotationIndex, 0);
expect(error.message, 'foo bar');
expect(error.stackTrace, contains('MyMacro.buildTypesForClass'));
}
test_macroFlag_class() async {
var library = await buildLibrary(r'''
macro class A {}