Macro. Record InvalidMacroTargetDiagnostic, if the target is not suitable for the macro.
Change-Id: Ic9e69e0297b76d06a2012e609750b1e0b7438093
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/350687
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index e2cd45b..cd1d589 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -95,7 +95,7 @@
// TODO(scheglov): Clean up the list of implicitly analyzed files.
class AnalysisDriver {
/// The version of data format, should be incremented on every format change.
- static const int DATA_VERSION = 339;
+ static const int DATA_VERSION = 340;
/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 8de08c4..9d3af70 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -6191,6 +6191,9 @@
// TODO(scheglov): Handle this case.
throw UnimplementedError();
}
+ case InvalidMacroTargetDiagnostic():
+ // TODO(scheglov): Handle this case.
+ throw UnimplementedError();
}
}
}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
index 9e2adc8..d446350 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -25,8 +25,9 @@
enum MacroDiagnosticKind {
argument,
- introspectionCycle,
exception,
+ introspectionCycle,
+ invalidTarget,
macro,
}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index 97c443e..605f742 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -2338,6 +2338,12 @@
argumentIndex: readUInt30(),
message: _reader.readStringUtf8(),
);
+ case MacroDiagnosticKind.exception:
+ return ExceptionMacroDiagnostic(
+ annotationIndex: readUInt30(),
+ message: _reader.readStringUtf8(),
+ stackTrace: _reader.readStringUtf8(),
+ );
case MacroDiagnosticKind.introspectionCycle:
return DeclarationsIntrospectionCycleDiagnostic(
annotationIndex: readUInt30(),
@@ -2350,11 +2356,9 @@
);
}),
);
- case MacroDiagnosticKind.exception:
- return ExceptionMacroDiagnostic(
- annotationIndex: readUInt30(),
- message: _reader.readStringUtf8(),
- stackTrace: _reader.readStringUtf8(),
+ case MacroDiagnosticKind.invalidTarget:
+ return InvalidMacroTargetDiagnostic(
+ supportedKinds: _reader.readStringUtf8List(),
);
case MacroDiagnosticKind.macro:
return MacroDiagnostic(
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 22f2d63..1ccf831 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -960,6 +960,9 @@
writeUInt30(diagnostic.annotationIndex);
writeStringUtf8(diagnostic.message);
writeStringUtf8(diagnostic.stackTrace);
+ case InvalidMacroTargetDiagnostic():
+ writeEnum(MacroDiagnosticKind.invalidTarget);
+ writeStringUtf8Iterable(diagnostic.supportedKinds);
case MacroDiagnostic():
writeEnum(MacroDiagnosticKind.macro);
writeEnum(diagnostic.severity);
diff --git a/pkg/analyzer/lib/src/summary2/macro_application.dart b/pkg/analyzer/lib/src/summary2/macro_application.dart
index 25191af..f6e067a 100644
--- a/pkg/analyzer/lib/src/summary2/macro_application.dart
+++ b/pkg/analyzer/lib/src/summary2/macro_application.dart
@@ -483,6 +483,18 @@
return instance.shouldExecute(targetDeclarationKind, phase);
}).toSet();
+ if (!instance.supportsDeclarationKind(targetDeclarationKind)) {
+ macroTarget.element.addMacroDiagnostic(
+ InvalidMacroTargetDiagnostic(
+ supportedKinds: macro.DeclarationKind.values
+ .where(instance.supportsDeclarationKind)
+ .map((e) => e.name)
+ .toList(),
+ ),
+ );
+ return;
+ }
+
final application = _MacroApplication(
target: macroTarget,
annotationIndex: annotationIndex,
diff --git a/pkg/analyzer/lib/src/summary2/macro_application_error.dart b/pkg/analyzer/lib/src/summary2/macro_application_error.dart
index b37821e..33bd6f3 100644
--- a/pkg/analyzer/lib/src/summary2/macro_application_error.dart
+++ b/pkg/analyzer/lib/src/summary2/macro_application_error.dart
@@ -86,6 +86,14 @@
});
}
+final class InvalidMacroTargetDiagnostic extends AnalyzerMacroDiagnostic {
+ final List<String> supportedKinds;
+
+ InvalidMacroTargetDiagnostic({
+ required this.supportedKinds,
+ });
+}
+
/// Diagnostic from the macro framework.
final class MacroDiagnostic extends AnalyzerMacroDiagnostic {
final macro.Severity severity;
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index bacdc98..d02ce82 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -901,6 +901,17 @@
'stackTrace:\n${diagnostic.stackTrace}',
);
});
+ case InvalidMacroTargetDiagnostic():
+ _sink.writelnWithIndent('InvalidMacroTargetDiagnostic');
+ _sink.withIndent(() {
+ _sink.writeElements(
+ 'supportedKinds',
+ diagnostic.supportedKinds,
+ (kindName) {
+ _sink.writelnWithIndent(kindName);
+ },
+ );
+ });
case MacroDiagnostic():
_sink.writelnWithIndent('MacroDiagnostic');
_sink.withIndent(() {
diff --git a/pkg/analyzer/test/src/summary/macro/diagnostic.dart b/pkg/analyzer/test/src/summary/macro/diagnostic.dart
index f5880ed..8cd13d9 100644
--- a/pkg/analyzer/test/src/summary/macro/diagnostic.dart
+++ b/pkg/analyzer/test/src/summary/macro/diagnostic.dart
@@ -348,6 +348,17 @@
}
}
+/*macro*/ class TargetClassOrMixinMacro
+ implements ClassTypesMacro, MixinTypesMacro {
+ const TargetClassOrMixinMacro();
+
+ @override
+ buildTypesForClass(declaration, builder) {}
+
+ @override
+ buildTypesForMixin(declaration, builder) {}
+}
+
/*macro*/ class ThrowExceptionDeclarationsPhase
implements
ClassDeclarationsMacro,
diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart
index 0f04b14..a954c57 100644
--- a/pkg/analyzer/test/src/summary/macro_test.dart
+++ b/pkg/analyzer/test/src/summary/macro_test.dart
@@ -3534,6 +3534,38 @@
''');
}
+ test_macroDiagnostics_invalidTarget_wantsClassOrMixin_hasFunction() async {
+ newFile(
+ '$testPackageLibPath/diagnostic.dart',
+ _getMacroCode('diagnostic.dart'),
+ );
+
+ final library = await buildLibrary(r'''
+import 'diagnostic.dart';
+
+@TargetClassOrMixinMacro()
+void f() {}
+''');
+
+ configuration
+ ..withConstructors = false
+ ..withMetadata = false;
+ checkElementText(library, r'''
+library
+ imports
+ package:test/diagnostic.dart
+ definingUnit
+ functions
+ f @59
+ returnType: void
+ macroDiagnostics
+ InvalidMacroTargetDiagnostic
+ supportedKinds
+ classType
+ mixinType
+''');
+ }
+
test_macroDiagnostics_report_atDeclaration_class() async {
newFile(
'$testPackageLibPath/diagnostic.dart',