-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Labels
cfe-feature-macrosImplement macros features in the CFEImplement macros features in the CFElegacy-area-front-endLegacy: Use area-dart-model instead.Legacy: Use area-dart-model instead.pkg-macrosThe experimental package:_macros libraryThe experimental package:_macros librarytype-bugIncorrect behavior (everything from a crash to more subtle misbehavior)Incorrect behavior (everything from a crash to more subtle misbehavior)
Description
For the macro
final variantRegex = RegExp(r'^(\w+)\((.*?)\)$');
macro class Enum
implements ClassTypesMacro, ClassDeclarationsMacro
{
final String? variant1, variant2;
const Enum([this.variant1, this.variant2]);
List<String> get variants => [
if(variant1 != null) variant1!,
if(variant2 != null) variant2!
];
@override
FutureOr<void> buildTypesForClass(ClassDeclaration clazz, ClassTypeBuilder builder) {
final className = clazz.identifier.name;
for(final variant in variants) {
final match = variantRegex.firstMatch(variant);
if (match == null) {
throw Exception("Variant `$variant` is not valid");
}
final newTypeName = match.group(1)!;
final fieldTypes = match.group(2)!.split(',').map((s) => s.trim()).toList();
int count = 1;
final fields = StringBuffer();
final constructors = StringBuffer();
for(final fieldType in fieldTypes) {
fields.write("\t$fieldType v$count;\n");
constructors.write("this.v$count,");
}
builder.declareType(newTypeName, DeclarationCode.fromString('''
final class $className\$$newTypeName implements $className {
$fields
$className\$$newTypeName._($constructors);
}'''));
}
}
@override
Future<void> buildDeclarationsForClass(
ClassDeclaration clazz, MemberDeclarationBuilder builder) async {
final className = clazz.identifier.name;
for(final variant in variants) {
final match = variantRegex.firstMatch(variant);
if (match == null) {
throw Exception("Variant `$variant` is not valid");
}
final newTypeName = match.group(1)!;
final fieldTypes = match.group(2)!.split(',').map((s) => s.trim()).toList();
int count = 1;
final constructor = StringBuffer();
for(final fieldType in fieldTypes) {
constructor.write("$fieldType v$count,");
}
builder.declareInType(DeclarationCode.fromString("factory $className.$newTypeName($constructor) = $className\$$newTypeName._;"));
}
}
}Used like
@Enum("Variant(int)")
sealed class W {
}
void main() {
final w = W.Variant(1);
}Passes the analyzer and the generated augmentations are correct, but Gives the following error during compilation
Crash when compiling:
org-dartlang-augmentation:/workspaces/algebraic_types/bin/algebraic_types.dart-1: Internal problem: Expected 'null', but got 'ReturnStatement'.
#0 internalProblem (package:front_end/src/base/problems.dart:50:5)
#1 unexpected (package:front_end/src/base/problems.dart:79:10)
#2 RedirectingFactoryBuilder.setRedirectingFactoryBody (package:front_end/src/source/source_factory_builder.dart:452:7)
#3 ClassDeclarationMixin.resolveConstructors (package:front_end/src/source/class_declaration.dart:211:25)
#4 SourceLibraryBuilder.resolveConstructors (package:front_end/src/source/source_library_builder.dart:855:24)
#5 SourceLibraryBuilder.resolveConstructors (package:front_end/src/source/source_library_builder.dart:848:38)
#6 SourceLoader.resolveConstructors (package:front_end/src/source/source_loader.dart:1869:24)
#7 KernelTarget.buildOutlines.<anonymous closure> (package:front_end/src/kernel/kernel_target.dart:617:14)
<asynchronous suspension>
#8 withCrashReporting (package:front_end/src/base/crash.dart:136:12)
<asynchronous suspension>
#9 KernelTarget.buildOutlines (package:front_end/src/kernel/kernel_target.dart:486:12)
<asynchronous suspension>
#10 _buildInternal (package:front_end/src/kernel_generator_impl.dart:180:7)
<asynchronous suspension>
#11 withCrashReporting (package:front_end/src/base/crash.dart:136:12)
<asynchronous suspension>
#12 generateKernel.<anonymous closure> (package:front_end/src/kernel_generator_impl.dart:55:12)
<asynchronous suspension>
#13 CompilerContext.clear (package:front_end/src/base/compiler_context.dart:77:3)
<asynchronous suspension>
#14 generateKernel (package:front_end/src/kernel_generator_impl.dart:53:10)
<asynchronous suspension>
#15 kernelForModule (package:front_end/src/api_prototype/kernel_generator.dart:106:11)
<asynchronous suspension>
#16 SingleShotCompilerWrapper.compileInternal (file:///tmp/tmpy_tauav4/dart-3.7.0-232.0.dev/dart/pkg/vm/bin/kernel_service.dart:405:11)
<asynchronous suspension>
#17 Compiler.compile.<anonymous closure> (file:///tmp/tmpy_tauav4/dart-3.7.0-232.0.dev/dart/pkg/vm/bin/kernel_service.dart:216:45)
<asynchronous suspension>
#18 _processLoadRequest (file:///tmp/tmpy_tauav4/dart-3.7.0-232.0.dev/dart/pkg/vm/bin/kernel_service.dart:887:37)
<asynchronous suspension>Dart Info
#### General info
- Dart 3.7.0-232.0.dev (dev) (None) on "linux_x64"
- on linux / Linux 6.6.63 #1-NixOS SMP PREEMPT_DYNAMIC Fri Nov 22 14:38:37 UTC 2024
- locale is en_US.UTF-8
#### Project info
- sdk constraint: '3.7.0-232.0.dev'
- dependencies: json
- dev_dependencies: lints, testMetadata
Metadata
Assignees
Labels
cfe-feature-macrosImplement macros features in the CFEImplement macros features in the CFElegacy-area-front-endLegacy: Use area-dart-model instead.Legacy: Use area-dart-model instead.pkg-macrosThe experimental package:_macros libraryThe experimental package:_macros librarytype-bugIncorrect behavior (everything from a crash to more subtle misbehavior)Incorrect behavior (everything from a crash to more subtle misbehavior)