mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
[cfe] Report errors on macro declaration/annotation in the same library cycle
Change-Id: Ia8b7b572f8947e7b82f3468331cd33e430ef8376 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/356060 Reviewed-by: Jens Johansen <jensj@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
170e014e67
commit
9293d2fc33
22 changed files with 486 additions and 30 deletions
|
@ -11451,6 +11451,41 @@ Message _withArgumentsMacroClassNotDeclaredMacro(String name) {
|
|||
);
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(String name)>
|
||||
templateMacroDefinitionApplicationSameLibraryCycle =
|
||||
const Template<Message Function(String name)>(
|
||||
"MacroDefinitionApplicationSameLibraryCycle",
|
||||
problemMessageTemplate:
|
||||
r"""The macro '#name' can't be applied in the same library cycle where it is defined.""",
|
||||
correctionMessageTemplate:
|
||||
r"""Try moving it to a different library that does not import the one where it is applied.""",
|
||||
withArguments: _withArgumentsMacroDefinitionApplicationSameLibraryCycle,
|
||||
);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String name)>
|
||||
codeMacroDefinitionApplicationSameLibraryCycle =
|
||||
const Code<Message Function(String name)>(
|
||||
"MacroDefinitionApplicationSameLibraryCycle",
|
||||
);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsMacroDefinitionApplicationSameLibraryCycle(String name) {
|
||||
if (name.isEmpty) throw 'No name provided';
|
||||
name = demangleMixinApplicationName(name);
|
||||
return new Message(
|
||||
codeMacroDefinitionApplicationSameLibraryCycle,
|
||||
problemMessage:
|
||||
"""The macro '${name}' can't be applied in the same library cycle where it is defined.""",
|
||||
correctionMessage:
|
||||
"""Try moving it to a different library that does not import the one where it is applied.""",
|
||||
arguments: {
|
||||
'name': name,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Null> codeMainNotFunctionDeclaration =
|
||||
messageMainNotFunctionDeclaration;
|
||||
|
|
|
@ -25,7 +25,8 @@ List<MacroApplication>? prebuildAnnotations(
|
|||
{required SourceLibraryBuilder enclosingLibrary,
|
||||
required List<MetadataBuilder>? metadataBuilders,
|
||||
required Uri fileUri,
|
||||
required Scope scope}) {
|
||||
required Scope scope,
|
||||
required Set<ClassBuilder> currentMacroDeclarations}) {
|
||||
if (metadataBuilders == null) return null;
|
||||
List<MacroApplication>? result;
|
||||
for (MetadataBuilder metadataBuilder in metadataBuilders) {
|
||||
|
@ -38,7 +39,20 @@ List<MacroApplication>? prebuildAnnotations(
|
|||
MacroApplication? application = listener.popMacroApplication();
|
||||
if (application != null) {
|
||||
result ??= [];
|
||||
result.add(application);
|
||||
if (currentMacroDeclarations.contains(application.classBuilder)) {
|
||||
ClassBuilder classBuilder = application.classBuilder;
|
||||
UriOffset uriOffset = application.uriOffset;
|
||||
enclosingLibrary.addProblem(
|
||||
templateMacroDefinitionApplicationSameLibraryCycle
|
||||
.withArguments(classBuilder.name),
|
||||
uriOffset.fileOffset,
|
||||
noLength,
|
||||
uriOffset.uri);
|
||||
result.add(
|
||||
new MacroApplication.invalid(classBuilder, uriOffset: uriOffset));
|
||||
} else {
|
||||
result.add(application);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result != null && result.length > 1) {
|
||||
|
@ -217,7 +231,7 @@ class _MacroListener implements Listener {
|
|||
}
|
||||
} else {
|
||||
if (_macroClassBuilder != null && _unhandledReason != null) {
|
||||
_erroneousMacroApplication = new MacroApplication.error(
|
||||
_erroneousMacroApplication = new MacroApplication.unhandled(
|
||||
_unhandledReason!, _macroClassBuilder!,
|
||||
uriOffset: new UriOffset(uri, beginToken.next!.charOffset));
|
||||
}
|
||||
|
|
|
@ -53,18 +53,36 @@ class MacroApplication {
|
|||
final ClassBuilder classBuilder;
|
||||
final String constructorName;
|
||||
final macro.Arguments arguments;
|
||||
final String? errorReason;
|
||||
final bool isErroneous;
|
||||
final String? unhandledReason;
|
||||
|
||||
/// Creates a [MacroApplication] for a macro annotation that should be
|
||||
/// applied.
|
||||
MacroApplication(this.classBuilder, this.constructorName, this.arguments,
|
||||
{required this.uriOffset})
|
||||
: errorReason = null;
|
||||
: isErroneous = false,
|
||||
unhandledReason = null;
|
||||
|
||||
MacroApplication.error(String this.errorReason, this.classBuilder,
|
||||
/// Creates an erroneous [MacroApplication] for a macro annotation using
|
||||
/// syntax that is not unhandled.
|
||||
// TODO(johnniwinther): Separate this into unhandled (but valid) and
|
||||
// unsupported (thus invalid) annotations.
|
||||
MacroApplication.unhandled(String this.unhandledReason, this.classBuilder,
|
||||
{required this.uriOffset})
|
||||
: constructorName = '',
|
||||
: isErroneous = true,
|
||||
constructorName = '',
|
||||
arguments = new macro.Arguments(const [], const {});
|
||||
|
||||
bool get isErroneous => errorReason != null;
|
||||
/// Creates an erroneous [MacroApplication] for an invalid macro application
|
||||
/// for which an error has been reported, which should _not_ be applied. For
|
||||
/// instance a macro annotation of a macro declared in the same library cycle.
|
||||
MacroApplication.invalid(this.classBuilder, {required this.uriOffset})
|
||||
: constructorName = '',
|
||||
isErroneous = true,
|
||||
unhandledReason = null,
|
||||
arguments = new macro.Arguments(const [], const {});
|
||||
|
||||
bool get isUnhandled => unhandledReason != null;
|
||||
|
||||
late macro.MacroInstanceIdentifier instanceIdentifier;
|
||||
late Set<macro.Phase> phasesToExecute;
|
||||
|
@ -245,10 +263,10 @@ void checkMacroApplications(
|
|||
MacroApplication? macroApplication =
|
||||
applications?.remove(annotation.fileOffset);
|
||||
if (macroApplication != null) {
|
||||
if (macroApplication.isErroneous) {
|
||||
if (macroApplication.isUnhandled) {
|
||||
libraryBuilder.addProblem(
|
||||
templateUnhandledMacroApplication
|
||||
.withArguments(macroApplication.errorReason!),
|
||||
.withArguments(macroApplication.unhandledReason!),
|
||||
annotation.fileOffset,
|
||||
noLength,
|
||||
fileUri);
|
||||
|
@ -350,14 +368,17 @@ class MacroApplications {
|
|||
bool get hasLoadableMacroIds => _pendingLibraryData.isNotEmpty;
|
||||
|
||||
void computeLibrariesMacroApplicationData(
|
||||
Iterable<SourceLibraryBuilder> libraryBuilders) {
|
||||
Iterable<SourceLibraryBuilder> libraryBuilders,
|
||||
Set<ClassBuilder> currentMacroDeclarations) {
|
||||
for (SourceLibraryBuilder libraryBuilder in libraryBuilders) {
|
||||
_computeSourceLibraryMacroApplicationData(libraryBuilder);
|
||||
_computeSourceLibraryMacroApplicationData(
|
||||
libraryBuilder, currentMacroDeclarations);
|
||||
}
|
||||
}
|
||||
|
||||
void _computeSourceLibraryMacroApplicationData(
|
||||
SourceLibraryBuilder libraryBuilder) {
|
||||
SourceLibraryBuilder libraryBuilder,
|
||||
Set<ClassBuilder> currentMacroDeclarations) {
|
||||
// TODO(johnniwinther): Handle augmentation libraries.
|
||||
LibraryMacroApplicationData libraryMacroApplicationData =
|
||||
new LibraryMacroApplicationData();
|
||||
|
@ -366,7 +387,8 @@ class MacroApplications {
|
|||
enclosingLibrary: libraryBuilder,
|
||||
scope: libraryBuilder.scope,
|
||||
fileUri: libraryBuilder.fileUri,
|
||||
metadataBuilders: libraryBuilder.metadata);
|
||||
metadataBuilders: libraryBuilder.metadata,
|
||||
currentMacroDeclarations: currentMacroDeclarations);
|
||||
if (libraryMacroApplications != null) {
|
||||
libraryMacroApplicationData.libraryApplications =
|
||||
new LibraryApplicationData(
|
||||
|
@ -384,7 +406,8 @@ class MacroApplications {
|
|||
enclosingLibrary: libraryBuilder,
|
||||
scope: classBuilder.scope,
|
||||
fileUri: classBuilder.fileUri,
|
||||
metadataBuilders: classBuilder.metadata);
|
||||
metadataBuilders: classBuilder.metadata,
|
||||
currentMacroDeclarations: currentMacroDeclarations);
|
||||
if (classMacroApplications != null) {
|
||||
classMacroApplicationData.classApplications =
|
||||
new ClassApplicationData(_macroIntrospection, libraryBuilder,
|
||||
|
@ -398,7 +421,8 @@ class MacroApplications {
|
|||
enclosingLibrary: libraryBuilder,
|
||||
scope: classBuilder.scope,
|
||||
fileUri: memberBuilder.fileUri,
|
||||
metadataBuilders: memberBuilder.metadata);
|
||||
metadataBuilders: memberBuilder.metadata,
|
||||
currentMacroDeclarations: currentMacroDeclarations);
|
||||
if (macroApplications != null) {
|
||||
classMacroApplicationData.memberApplications[memberBuilder] =
|
||||
new MemberApplicationData(_macroIntrospection, libraryBuilder,
|
||||
|
@ -409,7 +433,8 @@ class MacroApplications {
|
|||
enclosingLibrary: libraryBuilder,
|
||||
scope: classBuilder.scope,
|
||||
fileUri: memberBuilder.fileUri,
|
||||
metadataBuilders: memberBuilder.metadata);
|
||||
metadataBuilders: memberBuilder.metadata,
|
||||
currentMacroDeclarations: currentMacroDeclarations);
|
||||
if (macroApplications != null) {
|
||||
classMacroApplicationData.memberApplications[memberBuilder] =
|
||||
new MemberApplicationData(_macroIntrospection, libraryBuilder,
|
||||
|
@ -429,7 +454,8 @@ class MacroApplications {
|
|||
enclosingLibrary: libraryBuilder,
|
||||
scope: classBuilder.scope,
|
||||
fileUri: memberBuilder.fileUri,
|
||||
metadataBuilders: memberBuilder.metadata);
|
||||
metadataBuilders: memberBuilder.metadata,
|
||||
currentMacroDeclarations: currentMacroDeclarations);
|
||||
if (macroApplications != null) {
|
||||
classMacroApplicationData.memberApplications[memberBuilder] =
|
||||
new MemberApplicationData(_macroIntrospection, libraryBuilder,
|
||||
|
@ -440,7 +466,8 @@ class MacroApplications {
|
|||
enclosingLibrary: libraryBuilder,
|
||||
scope: classBuilder.scope,
|
||||
fileUri: memberBuilder.fileUri,
|
||||
metadataBuilders: memberBuilder.metadata);
|
||||
metadataBuilders: memberBuilder.metadata,
|
||||
currentMacroDeclarations: currentMacroDeclarations);
|
||||
if (macroApplications != null) {
|
||||
classMacroApplicationData.memberApplications[memberBuilder] =
|
||||
new MemberApplicationData(_macroIntrospection, libraryBuilder,
|
||||
|
@ -462,7 +489,8 @@ class MacroApplications {
|
|||
enclosingLibrary: libraryBuilder,
|
||||
scope: libraryBuilder.scope,
|
||||
fileUri: builder.fileUri,
|
||||
metadataBuilders: builder.metadata);
|
||||
metadataBuilders: builder.metadata,
|
||||
currentMacroDeclarations: currentMacroDeclarations);
|
||||
if (macroApplications != null) {
|
||||
libraryMacroApplicationData.memberApplications[builder] =
|
||||
new MemberApplicationData(_macroIntrospection, libraryBuilder,
|
||||
|
@ -473,7 +501,8 @@ class MacroApplications {
|
|||
enclosingLibrary: libraryBuilder,
|
||||
scope: libraryBuilder.scope,
|
||||
fileUri: builder.fileUri,
|
||||
metadataBuilders: builder.metadata);
|
||||
metadataBuilders: builder.metadata,
|
||||
currentMacroDeclarations: currentMacroDeclarations);
|
||||
if (macroApplications != null) {
|
||||
libraryMacroApplicationData.memberApplications[builder] =
|
||||
new MemberApplicationData(_macroIntrospection, libraryBuilder,
|
||||
|
|
|
@ -217,6 +217,9 @@ class SourceLoader extends Loader {
|
|||
|
||||
ClassBuilder? _macroClassBuilder;
|
||||
|
||||
/// The macro declarations that are currently being compiled.
|
||||
Set<ClassBuilder> _macroDeclarations = {};
|
||||
|
||||
SourceLoader(this.fileSystem, this.includeComments, this.target)
|
||||
: dataForTesting =
|
||||
retainDataForTesting ? new SourceLoaderDataForTesting() : null;
|
||||
|
@ -1544,10 +1547,12 @@ severity: $severity
|
|||
ClassBuilder builder = iterator.current;
|
||||
if (builder.isMacro) {
|
||||
Uri libraryUri = builder.libraryBuilder.importUri;
|
||||
if (!target.context.options.runningPrecompilations
|
||||
.contains(libraryUri) &&
|
||||
!target.context.options.macroExecutor
|
||||
.libraryIsRegistered(libraryUri)) {
|
||||
if (target.context.options.runningPrecompilations
|
||||
.contains(libraryUri)) {
|
||||
// We are explicitly compiling this macro.
|
||||
_macroDeclarations.add(builder);
|
||||
} else if (!target.context.options.macroExecutor
|
||||
.libraryIsRegistered(libraryUri)) {
|
||||
(macroLibraries[libraryUri] ??= []).add(builder);
|
||||
if (retainDataForTesting) {
|
||||
(dataForTesting!.macroDeclarationData
|
||||
|
@ -1681,11 +1686,22 @@ severity: $severity
|
|||
// We have found the first needed layer of precompilation. There might
|
||||
// be more layers but we'll compute these at the next attempt at
|
||||
// compilation, when this layer has been precompiled.
|
||||
// TODO(johnniwinther): Use this to trigger a precompile step.
|
||||
return new NeededPrecompilations(neededPrecompilations);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (compilationSteps.isNotEmpty) {
|
||||
for (List<Uri> compilationStep in compilationSteps) {
|
||||
for (Uri uri in compilationStep) {
|
||||
List<ClassBuilder>? macroClasses = macroLibraries[uri];
|
||||
if (macroClasses != null) {
|
||||
// These macros are to be compiled during this (last) compilation
|
||||
// step.
|
||||
_macroDeclarations.addAll(macroClasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1700,8 +1716,8 @@ severity: $severity
|
|||
this,
|
||||
target.context.options.macroExecutor,
|
||||
dataForTesting?.macroApplicationData);
|
||||
macroApplications
|
||||
.computeLibrariesMacroApplicationData(sourceLibraryBuilders);
|
||||
macroApplications.computeLibrariesMacroApplicationData(
|
||||
sourceLibraryBuilders, _macroDeclarations);
|
||||
if (macroApplications.hasLoadableMacroIds) {
|
||||
target.benchmarker?.beginSubdivide(
|
||||
BenchmarkSubdivides.computeMacroApplications_macroExecutorProvider);
|
||||
|
@ -1715,8 +1731,8 @@ severity: $severity
|
|||
Future<void> computeAdditionalMacroApplications(
|
||||
MacroApplications macroApplications,
|
||||
Iterable<SourceLibraryBuilder> sourceLibraryBuilders) async {
|
||||
macroApplications
|
||||
.computeLibrariesMacroApplicationData(sourceLibraryBuilders);
|
||||
macroApplications.computeLibrariesMacroApplicationData(
|
||||
sourceLibraryBuilders, _macroDeclarations);
|
||||
if (macroApplications.hasLoadableMacroIds) {
|
||||
target.benchmarker?.beginSubdivide(
|
||||
BenchmarkSubdivides.computeMacroApplications_macroExecutorProvider);
|
||||
|
|
|
@ -711,6 +711,8 @@ ListLiteralTooManyTypeArguments/example: Fail
|
|||
LoadLibraryTakesNoArguments/example: Fail
|
||||
MacroClassNotDeclaredMacro/analyzerCode: Fail
|
||||
MacroClassNotDeclaredMacro/example: Fail
|
||||
MacroDefinitionApplicationSameLibraryCycle/analyzerCode: Fail
|
||||
MacroDefinitionApplicationSameLibraryCycle/example: Fail
|
||||
MainNotFunctionDeclaration/analyzerCode: Fail
|
||||
MainNotFunctionDeclarationExported/analyzerCode: Fail
|
||||
MainNotFunctionDeclarationExported/part_wrapped_script: Fail
|
||||
|
|
|
@ -7581,3 +7581,7 @@ InvalidMacroApplicationTarget:
|
|||
|
||||
NoMacroApplicationTarget:
|
||||
problemMessage: "The macro can not be applied to this declaration."
|
||||
|
||||
MacroDefinitionApplicationSameLibraryCycle:
|
||||
problemMessage: "The macro '#name' can't be applied in the same library cycle where it is defined."
|
||||
correctionMessage: Try moving it to a different library that does not import the one where it is applied.
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// org-dartlang-test:///a/b/c/main.dart:8:2: Error: The macro 'Macro' can't be applied in the same library cycle where it is defined.
|
||||
// Try moving it to a different library that does not import the one where it is applied.
|
||||
// @Macro() // Error
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "main_lib.dart" as mai;
|
||||
|
||||
import "dart:async";
|
||||
import "org-dartlang-test:///a/b/c/main_lib.dart";
|
||||
|
||||
@#C1
|
||||
static method method() → dynamic {}
|
||||
|
||||
library;
|
||||
import self as mai;
|
||||
import "dart:core" as core;
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart" as api;
|
||||
|
||||
import "dart:async";
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart";
|
||||
import "org-dartlang-test:///a/b/c/main.dart";
|
||||
|
||||
macro class Macro extends core::Object implements api::FunctionDeclarationsMacro /*hasConstConstructor*/ {
|
||||
const constructor •() → mai::Macro
|
||||
: super core::Object::•()
|
||||
;
|
||||
method buildDeclarationsForFunction(api::FunctionDeclaration function, api::DeclarationBuilder builder) → FutureOr<void> {}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = mai::Macro {}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:async';
|
||||
import 'main_lib.dart';
|
||||
|
||||
@Macro() // Error
|
||||
method() {}
|
|
@ -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.
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:_fe_analyzer_shared/src/macros/api.dart';
|
||||
import 'main.dart';
|
||||
|
||||
macro class Macro implements FunctionDeclarationsMacro {
|
||||
const Macro();
|
||||
|
||||
FutureOr<void> buildDeclarationsForFunction(
|
||||
FunctionDeclaration function, DeclarationBuilder builder) {}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// org-dartlang-test:///a/b/c/main.dart:9:2: Error: The macro 'Macro1' can't be applied in the same library cycle where it is defined.
|
||||
// Try moving it to a different library that does not import the one where it is applied.
|
||||
// @Macro1() // Error
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "main_lib1.dart" as mai;
|
||||
import "main_lib2.dart" as mai2;
|
||||
|
||||
import "dart:async";
|
||||
import "org-dartlang-test:///a/b/c/main_lib1.dart";
|
||||
import "org-dartlang-test:///a/b/c/main_lib2.dart";
|
||||
|
||||
@#C1
|
||||
@#C2
|
||||
static method method() → dynamic {}
|
||||
|
||||
library;
|
||||
import self as mai;
|
||||
import "dart:core" as core;
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart" as api;
|
||||
|
||||
import "dart:async";
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart";
|
||||
import "org-dartlang-test:///a/b/c/main.dart";
|
||||
|
||||
macro class Macro1 extends core::Object implements api::FunctionDeclarationsMacro /*hasConstConstructor*/ {
|
||||
const constructor •() → mai::Macro1
|
||||
: super core::Object::•()
|
||||
;
|
||||
method buildDeclarationsForFunction(api::FunctionDeclaration function, api::DeclarationBuilder builder) → FutureOr<void> {}
|
||||
}
|
||||
|
||||
library;
|
||||
import self as mai2;
|
||||
import "dart:core" as core;
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart" as api;
|
||||
|
||||
import "dart:async";
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart";
|
||||
|
||||
macro class Macro2 extends core::Object implements api::FunctionDeclarationsMacro /*hasConstConstructor*/ {
|
||||
const constructor •() → mai2::Macro2
|
||||
: super core::Object::•()
|
||||
;
|
||||
method buildDeclarationsForFunction(api::FunctionDeclaration function, api::DeclarationBuilder builder) → FutureOr<void> {}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = mai::Macro1 {}
|
||||
#C2 = mai2::Macro2 {}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// 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.
|
||||
|
||||
/*library:
|
||||
Declarations Order:
|
||||
method:Macro2.new()*/
|
||||
|
||||
import 'dart:async';
|
||||
import 'main_lib1.dart';
|
||||
import 'main_lib2.dart';
|
||||
|
||||
@Macro1() // Error
|
||||
@Macro2() // Ok
|
||||
method() {}
|
|
@ -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.
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:_fe_analyzer_shared/src/macros/api.dart';
|
||||
import 'main.dart';
|
||||
|
||||
macro class Macro1 implements FunctionDeclarationsMacro {
|
||||
const Macro1();
|
||||
|
||||
FutureOr<void> buildDeclarationsForFunction(
|
||||
FunctionDeclaration function, DeclarationBuilder builder) {}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:_fe_analyzer_shared/src/macros/api.dart';
|
||||
|
||||
macro class Macro2 implements FunctionDeclarationsMacro {
|
||||
const Macro2();
|
||||
|
||||
FutureOr<void> buildDeclarationsForFunction(
|
||||
FunctionDeclaration function, DeclarationBuilder builder) {}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// org-dartlang-test:///a/b/c/main.dart:8:2: Error: The macro 'Macro1' can't be applied in the same library cycle where it is defined.
|
||||
// Try moving it to a different library that does not import the one where it is applied.
|
||||
// @Macro1() // Error
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "main_lib1.dart" as mai;
|
||||
|
||||
import "dart:async";
|
||||
import "org-dartlang-test:///a/b/c/main_lib1.dart";
|
||||
|
||||
@#C1
|
||||
static method method() → dynamic {}
|
||||
|
||||
library;
|
||||
import self as mai;
|
||||
import "dart:core" as core;
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart" as api;
|
||||
import "main_lib2.dart" as mai2;
|
||||
|
||||
import "dart:async";
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart";
|
||||
import "org-dartlang-test:///a/b/c/main.dart";
|
||||
import "org-dartlang-test:///a/b/c/main_lib2.dart";
|
||||
|
||||
macro class Macro1 extends core::Object implements api::FunctionDeclarationsMacro /*hasConstConstructor*/ {
|
||||
const constructor •() → mai::Macro1
|
||||
: super core::Object::•()
|
||||
;
|
||||
@#C2
|
||||
method buildDeclarationsForFunction(api::FunctionDeclaration function, api::DeclarationBuilder builder) → FutureOr<void> {}
|
||||
}
|
||||
|
||||
library;
|
||||
import self as mai2;
|
||||
import "dart:core" as core;
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart" as api;
|
||||
|
||||
import "dart:async";
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart";
|
||||
|
||||
macro class Macro2 extends core::Object implements api::FunctionDeclarationsMacro /*hasConstConstructor*/ {
|
||||
const constructor •() → mai2::Macro2
|
||||
: super core::Object::•()
|
||||
;
|
||||
method buildDeclarationsForFunction(api::FunctionDeclaration function, api::DeclarationBuilder builder) → FutureOr<void> {}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = mai::Macro1 {}
|
||||
#C2 = mai2::Macro2 {}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// 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.
|
||||
|
||||
/*library:
|
||||
Declarations Order:
|
||||
Macro1.buildDeclarationsForFunction:Macro2.new()*/
|
||||
|
||||
import 'dart:async';
|
||||
import 'main_lib1.dart';
|
||||
|
||||
@Macro1() // Error
|
||||
method() {}
|
|
@ -0,0 +1,16 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:_fe_analyzer_shared/src/macros/api.dart';
|
||||
import 'main.dart';
|
||||
import 'main_lib2.dart';
|
||||
|
||||
macro class Macro1 implements FunctionDeclarationsMacro {
|
||||
const Macro1();
|
||||
|
||||
@Macro2() // Ok
|
||||
FutureOr<void> buildDeclarationsForFunction(
|
||||
FunctionDeclaration function, DeclarationBuilder builder) {}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:_fe_analyzer_shared/src/macros/api.dart';
|
||||
|
||||
macro class Macro2 implements FunctionDeclarationsMacro {
|
||||
const Macro2();
|
||||
|
||||
FutureOr<void> buildDeclarationsForFunction(
|
||||
FunctionDeclaration function, DeclarationBuilder builder) {}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
library;
|
||||
import self as self;
|
||||
|
||||
import "dart:async";
|
||||
import "org-dartlang-test:///a/b/c/main_lib.dart";
|
||||
|
||||
static method method() → dynamic {}
|
||||
|
||||
library;
|
||||
import self as self2;
|
||||
import "dart:core" as core;
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart" as api;
|
||||
|
||||
import "dart:async";
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart";
|
||||
|
||||
macro class Macro extends core::Object implements api::FunctionDeclarationsMacro /*hasConstConstructor*/ {
|
||||
const constructor •() → self2::Macro
|
||||
: super core::Object::•()
|
||||
;
|
||||
method buildDeclarationsForFunction(api::FunctionDeclaration function, api::DeclarationBuilder builder) → FutureOr<void> {}
|
||||
}
|
||||
@#C1
|
||||
static method method() → dynamic {}
|
||||
|
||||
constants {
|
||||
#C1 = self2::Macro {}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// 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.
|
||||
|
||||
/*library:
|
||||
Declarations Order:
|
||||
method:Macro.new()*/
|
||||
|
||||
import 'dart:async';
|
||||
import 'main_lib.dart';
|
||||
|
||||
method() {}
|
|
@ -0,0 +1,16 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:_fe_analyzer_shared/src/macros/api.dart';
|
||||
|
||||
macro class Macro implements FunctionDeclarationsMacro {
|
||||
const Macro();
|
||||
|
||||
FutureOr<void> buildDeclarationsForFunction(
|
||||
FunctionDeclaration function, DeclarationBuilder builder) {}
|
||||
}
|
||||
|
||||
@Macro() // Error
|
||||
method() {}
|
16
pkg/front_end/test/macros/application/data/tests/cyclic.dart
Normal file
16
pkg/front_end/test/macros/application/data/tests/cyclic.dart
Normal file
|
@ -0,0 +1,16 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:_fe_analyzer_shared/src/macros/api.dart';
|
||||
|
||||
macro class Macro implements FunctionDeclarationsMacro {
|
||||
const Macro();
|
||||
|
||||
FutureOr<void> buildDeclarationsForFunction(
|
||||
FunctionDeclaration function, DeclarationBuilder builder) {}
|
||||
}
|
||||
|
||||
@Macro() // Error
|
||||
method() {}
|
|
@ -0,0 +1,28 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// org-dartlang-test:///a/b/c/main.dart:15:2: Error: The macro 'Macro' can't be applied in the same library cycle where it is defined.
|
||||
// Try moving it to a different library that does not import the one where it is applied.
|
||||
// @Macro() // Error
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart" as api;
|
||||
|
||||
import "dart:async";
|
||||
import "package:_fe_analyzer_shared/src/macros/api.dart";
|
||||
|
||||
macro class Macro extends core::Object implements api::FunctionDeclarationsMacro /*hasConstConstructor*/ {
|
||||
const constructor •() → self::Macro
|
||||
: super core::Object::•()
|
||||
;
|
||||
method buildDeclarationsForFunction(api::FunctionDeclaration function, api::DeclarationBuilder builder) → FutureOr<void> {}
|
||||
}
|
||||
@#C1
|
||||
static method method() → dynamic {}
|
||||
|
||||
constants {
|
||||
#C1 = self::Macro {}
|
||||
}
|
Loading…
Reference in a new issue