Version 2.17.0-43.0.dev
Merge commit '5183ba3ca4fe3787cae3c0a6cc7f8748ff01bcf5' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0776b8b..aa16e28 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,19 @@
- `IdbFactory.supportsDatabaseNames` has been deprecated. It will always return
`false`.
+### Tools
+
+#### Dart command line
+
+- **Breaking Change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
+ The standalone `dart2js` tool has been
+ marked deprecated as previously announced.
+ Its replacement is the `dart compile js` command.
+ Should you find any issues, or missing features, in the replacement
+ command, kindly file [an issue][].
+
+[an issue]: https://github.com/dart-lang/sdk/issues/new
+
## 2.16.0
### Core libraries
diff --git a/benchmarks/FfiMemory/dart/FfiMemory.dart b/benchmarks/FfiMemory/dart/FfiMemory.dart
index 6178f24..881eff2 100644
--- a/benchmarks/FfiMemory/dart/FfiMemory.dart
+++ b/benchmarks/FfiMemory/dart/FfiMemory.dart
@@ -15,6 +15,36 @@
import 'package:ffi/ffi.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
+/// Represents a native unsigned pointer-sized integer in C.
+///
+/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint64(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint64(),
+ Abi.fuchsiaArm64: Uint64(),
+ Abi.fuchsiaX64: Uint64(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint64(),
+ Abi.iosX64: Uint64(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint64(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint64(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint64(),
+ Abi.macosArm64: Uint64(),
+ Abi.macosX64: Uint64(),
+ Abi.windowsArm64: Uint64(),
+ Abi.windowsIA32: Uint32(),
+ Abi.windowsX64: Uint64(),
+})
+class UintPtr extends AbiSpecificInteger {
+ const UintPtr();
+}
+
//
// Pointer store.
//
diff --git a/benchmarks/FfiMemory/dart2/FfiMemory.dart b/benchmarks/FfiMemory/dart2/FfiMemory.dart
index b3a6cf9..86f7e1f 100644
--- a/benchmarks/FfiMemory/dart2/FfiMemory.dart
+++ b/benchmarks/FfiMemory/dart2/FfiMemory.dart
@@ -17,6 +17,36 @@
import 'package:ffi/ffi.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
+/// Represents a native unsigned pointer-sized integer in C.
+///
+/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint64(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint64(),
+ Abi.fuchsiaArm64: Uint64(),
+ Abi.fuchsiaX64: Uint64(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint64(),
+ Abi.iosX64: Uint64(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint64(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint64(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint64(),
+ Abi.macosArm64: Uint64(),
+ Abi.macosX64: Uint64(),
+ Abi.windowsArm64: Uint64(),
+ Abi.windowsIA32: Uint32(),
+ Abi.windowsX64: Uint64(),
+})
+class UintPtr extends AbiSpecificInteger {
+ const UintPtr();
+}
+
//
// Pointer store.
//
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
index 2bfd7e8..868e62f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
@@ -87,11 +87,6 @@
void declareInClass(DeclarationCode declaration);
}
-/// The api used by [Macro]s to reflect on the currently available
-/// members, superclass, and mixins for a given [ClassDeclaration]
-abstract class ClassDeclarationBuilder
- implements ClassMemberDeclarationBuilder, ClassIntrospector {}
-
/// The interface used by [Macro]s to resolve any [NamedStaticType] to its
/// declaration.
///
@@ -117,23 +112,25 @@
/// Retrieve a [VariableDefinitionBuilder] for a field by [name].
///
/// Throws an [ArgumentError] if there is no field by that name.
- VariableDefinitionBuilder buildField(String name);
+ Future<VariableDefinitionBuilder> buildField(String name);
/// Retrieve a [FunctionDefinitionBuilder] for a method by [name].
///
/// Throws an [ArgumentError] if there is no method by that name.
- FunctionDefinitionBuilder buildMethod(String name);
+ Future<FunctionDefinitionBuilder> buildMethod(String name);
/// Retrieve a [ConstructorDefinitionBuilder] for a constructor by [name].
///
/// Throws an [ArgumentError] if there is no constructor by that name.
- ConstructorDefinitionBuilder buildConstructor(String name);
+ Future<ConstructorDefinitionBuilder> buildConstructor(String name);
}
/// The apis used by [Macro]s to define the body of a constructor
/// or wrap the body of an existing constructor with additional statements.
abstract class ConstructorDefinitionBuilder implements DefinitionBuilder {
- /// Augments an existing constructor body with [body].
+ /// Augments an existing constructor body with [body] and [initializers].
+ ///
+ /// The [initializers] should not contain trailing or preceding commas.
///
/// TODO: Link the library augmentations proposal to describe the semantics.
void augment({FunctionBodyCode? body, List<Code>? initializers});
@@ -151,6 +148,9 @@
abstract class VariableDefinitionBuilder implements DefinitionBuilder {
/// Augments the field.
///
+ /// For [getter] and [setter] the full function declaration should be
+ /// provided, minus the `augment` keyword (which will be implicitly added).
+ ///
/// TODO: Link the library augmentations proposal to describe the semantics.
void augment({
DeclarationCode? getter,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
index 10ccafa..fae7630 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
@@ -69,6 +69,9 @@
///
/// See subtypes [ClassDeclaration] and [TypeAliasDeclaration].
abstract class TypeDeclaration implements Declaration {
+ // TODO: Change this to a [StaticType]? https://github.com/dart-lang/language/issues/2072
+ TypeAnnotation get type;
+
/// The type parameters defined for this type declaration.
Iterable<TypeParameterDeclaration> get typeParameters;
@@ -144,7 +147,7 @@
/// Method introspection information.
abstract class MethodDeclaration implements FunctionDeclaration {
/// The class that defines this method.
- TypeAnnotation get definingClass;
+ NamedTypeAnnotation get definingClass;
}
/// Constructor introspection information.
@@ -155,23 +158,27 @@
/// Variable introspection information.
abstract class VariableDeclaration implements Declaration {
- /// Whether this function has an `abstract` modifier.
- bool get isAbstract;
-
- /// Whether this function has an `external` modifier.
+ /// Whether this field has an `external` modifier.
bool get isExternal;
+ /// Whether this field has a `final` modifier.
+ bool get isFinal;
+
+ /// Whether this field has a `late` modifier.
+ bool get isLate;
+
/// The type of this field.
TypeAnnotation get type;
- /// A [Code] object representing the initializer for this field, if present.
- Code? get initializer;
+ /// A [ExpressionCode] object representing the initializer for this field, if
+ /// present.
+ ExpressionCode? get initializer;
}
/// Field introspection information ..
abstract class FieldDeclaration implements VariableDeclaration {
/// The class that defines this method.
- TypeAnnotation get definingClass;
+ NamedTypeAnnotation get definingClass;
}
/// Parameter introspection information.
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart
index 7685589a..5ab073a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart
@@ -50,7 +50,7 @@
/// The interface for [Macro]s that can be applied to any top level variable
/// or instance field, and wants to augment the variable definition.
abstract class VariableDefinitionMacro implements Macro {
- FutureOr<void> buildDefinitionForFunction(
+ FutureOr<void> buildDefinitionForVariable(
VariableDeclaration variable, VariableDefinitionBuilder builder);
}
@@ -65,7 +65,7 @@
/// contribute new non-type declarations to the program.
abstract class ClassDeclarationsMacro implements Macro {
FutureOr<void> buildDeclarationsForClass(
- ClassDeclaration clazz, ClassDeclarationBuilder builder);
+ ClassDeclaration clazz, ClassMemberDeclarationBuilder builder);
}
/// The interface for [Macro]s that can be applied to any class, and wants to
@@ -85,13 +85,13 @@
/// The interface for [Macro]s that can be applied to any field, and wants to
/// contribute new type declarations to the program.
abstract class FieldDeclarationsMacro implements Macro {
- FutureOr<void> buildTypesForField(
+ FutureOr<void> buildDeclarationsForField(
FieldDeclaration field, ClassMemberDeclarationBuilder builder);
}
/// The interface for [Macro]s that can be applied to any field, and wants to
/// augment the field definition.
-abstract class FieldDefinitionsMacro implements Macro {
+abstract class FieldDefinitionMacro implements Macro {
FutureOr<void> buildDefinitionForField(
FieldDeclaration field, VariableDefinitionBuilder builder);
}
@@ -105,7 +105,7 @@
/// The interface for [Macro]s that can be applied to any method, and wants to
/// contribute new non-type declarations to the program.
-abstract class MethodDeclarationDeclarationsMacro implements Macro {
+abstract class MethodDeclarationsMacro implements Macro {
FutureOr<void> buildDeclarationsForMethod(
MethodDeclaration method, ClassMemberDeclarationBuilder builder);
}
@@ -121,19 +121,20 @@
/// to contribute new type declarations to the program.
abstract class ConstructorTypesMacro implements Macro {
FutureOr<void> buildTypesForConstructor(
- ConstructorDeclaration method, TypeBuilder builder);
+ ConstructorDeclaration constructor, TypeBuilder builder);
}
/// The interface for [Macro]s that can be applied to any constructors, and
/// wants to contribute new non-type declarations to the program.
-abstract class ConstructorDeclarationDeclarationsMacro implements Macro {
+abstract class ConstructorDeclarationsMacro implements Macro {
FutureOr<void> buildDeclarationsForConstructor(
- ConstructorDeclaration method, ClassMemberDeclarationBuilder builder);
+ ConstructorDeclaration constructor,
+ ClassMemberDeclarationBuilder builder);
}
/// The interface for [Macro]s that can be applied to any constructor, and wants
/// to augment the function definition.
abstract class ConstructorDefinitionMacro implements Macro {
FutureOr<void> buildDefinitionForConstructor(
- ConstructorDeclaration method, ConstructorDefinitionBuilder builder);
+ ConstructorDeclaration constructor, ConstructorDefinitionBuilder builder);
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
index 4d2f6a1..1c50b6a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
@@ -37,6 +37,7 @@
import 'dart:async';
import 'dart:isolate';
+import 'package:_fe_analyzer_shared/src/macros/executor_shared/execute_macro.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/response_impls.dart';
@@ -70,6 +71,10 @@
var request = new InstantiateMacroRequest.deserialize(deserializer, zoneId);
(await _instantiateMacro(request)).serialize(serializer);
break;
+ case MessageType.executeDeclarationsPhaseRequest:
+ var request = new ExecuteDeclarationsPhaseRequest.deserialize(deserializer, zoneId);
+ (await _executeDeclarationsPhase(request, sendRequest)).serialize(serializer);
+ break;
case MessageType.executeDefinitionsPhaseRequest:
var request = new ExecuteDefinitionsPhaseRequest.deserialize(deserializer, zoneId);
(await _executeDefinitionsPhase(request, sendRequest)).serialize(serializer);
@@ -130,6 +135,41 @@
}
}
+Future<SerializableResponse> _executeDeclarationsPhase(
+ ExecuteDeclarationsPhaseRequest request,
+ Future<Response> Function(Request request) sendRequest) async {
+ try {
+ Macro? instance = _macroInstances[request.macro];
+ if (instance == null) {
+ throw new StateError('Unrecognized macro instance \${request.macro}\\n'
+ 'Known instances: \$_macroInstances)');
+ }
+ var classIntrospector = ClientClassIntrospector(
+ sendRequest,
+ remoteInstance: request.classIntrospector,
+ serializationZoneId: request.serializationZoneId);
+ var typeResolver = ClientTypeResolver(
+ sendRequest,
+ remoteInstance: request.typeResolver,
+ serializationZoneId: request.serializationZoneId);
+
+ var result = await executeDeclarationsMacro(
+ instance, request.declaration, classIntrospector, typeResolver);
+ return new SerializableResponse(
+ responseType: MessageType.macroExecutionResult,
+ response: result,
+ requestId: request.id,
+ serializationZoneId: request.serializationZoneId);
+ } catch (e, s) {
+ return new SerializableResponse(
+ responseType: MessageType.error,
+ error: e.toString(),
+ stackTrace: s.toString(),
+ requestId: request.id,
+ serializationZoneId: request.serializationZoneId);
+ }
+}
+
Future<SerializableResponse> _executeDefinitionsPhase(
ExecuteDefinitionsPhaseRequest request,
Future<Response> Function(Request request) sendRequest) async {
@@ -152,54 +192,14 @@
remoteInstance: request.classIntrospector,
serializationZoneId: request.serializationZoneId);
- Declaration declaration = request.declaration;
- if (instance is FunctionDefinitionMacro &&
- declaration is FunctionDeclarationImpl) {
- FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
- declaration,
- typeResolver,
- typeDeclarationResolver,
- classIntrospector);
- await instance.buildDefinitionForFunction(declaration, builder);
- return new SerializableResponse(
- responseType: MessageType.macroExecutionResult,
- response: builder.result,
- requestId: request.id,
- serializationZoneId: request.serializationZoneId);
- } else if (instance is MethodDefinitionMacro
- && declaration is MethodDeclarationImpl) {
- FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
- declaration,
- typeResolver,
- typeDeclarationResolver,
- classIntrospector);
- await instance.buildDefinitionForMethod(declaration, builder);
- var result = builder.result;
- // Wrap augmentations up as a part of the class
- if (result.augmentations.isNotEmpty) {
- result = MacroExecutionResultImpl(
- augmentations: [
- DeclarationCode.fromParts([
- 'augment class ',
- declaration.definingClass,
- ' {\\n',
- ...result.augmentations,
- '\\n}',
- ]),
- ],
- imports: result.imports,
- );
- }
- return new SerializableResponse(
- responseType: MessageType.macroExecutionResult,
- response: result,
- requestId: request.id,
- serializationZoneId: request.serializationZoneId);
- } else {
- throw new UnsupportedError(
- 'Unsupported macro type, only Method and Function Definition '
- 'Macros are supported currently');
- }
+ var result = await executeDefinitionMacro(
+ instance, request.declaration, classIntrospector, typeResolver,
+ typeDeclarationResolver);
+ return new SerializableResponse(
+ responseType: MessageType.macroExecutionResult,
+ response: result,
+ requestId: request.id,
+ serializationZoneId: request.serializationZoneId);
} catch (e, s) {
return new SerializableResponse(
responseType: MessageType.error,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/builder_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/builder_impls.dart
new file mode 100644
index 0000000..59a6376
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/builder_impls.dart
@@ -0,0 +1,398 @@
+// Copyright (c) 2021, 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 '../executor.dart';
+import '../api.dart';
+import 'response_impls.dart';
+
+class TypeBuilderBase {
+ /// The final result, will be built up over `augment` calls.
+ final List<DeclarationCode> _augmentations;
+
+ /// Creates and returns a [MacroExecutionResult] out of the [_augmentations]
+ /// created by this builder.
+ MacroExecutionResult get result => new MacroExecutionResultImpl(
+ augmentations: _augmentations,
+ // TODO: Implement `imports`, or possibly drop it?
+ imports: [],
+ );
+
+ TypeBuilderBase({List<DeclarationCode>? parentAugmentations})
+ : _augmentations = parentAugmentations ?? [];
+}
+
+/// Base class for all [DeclarationBuilder]s.
+class DeclarationBuilderBase extends TypeBuilderBase
+ implements ClassIntrospector, TypeResolver {
+ final ClassIntrospector classIntrospector;
+ final TypeResolver typeResolver;
+
+ DeclarationBuilderBase(this.classIntrospector, this.typeResolver,
+ {List<DeclarationCode>? parentAugmentations})
+ : super(parentAugmentations: parentAugmentations);
+
+ @override
+ Future<List<ConstructorDeclaration>> constructorsOf(ClassDeclaration clazz) =>
+ classIntrospector.constructorsOf(clazz);
+
+ @override
+ Future<List<FieldDeclaration>> fieldsOf(ClassDeclaration clazz) =>
+ classIntrospector.fieldsOf(clazz);
+
+ @override
+ Future<List<ClassDeclaration>> interfacesOf(ClassDeclaration clazz) =>
+ classIntrospector.interfacesOf(clazz);
+
+ @override
+ Future<List<MethodDeclaration>> methodsOf(ClassDeclaration clazz) =>
+ classIntrospector.methodsOf(clazz);
+
+ @override
+ Future<List<ClassDeclaration>> mixinsOf(ClassDeclaration clazz) =>
+ classIntrospector.mixinsOf(clazz);
+
+ @override
+ Future<ClassDeclaration?> superclassOf(ClassDeclaration clazz) =>
+ classIntrospector.superclassOf(clazz);
+
+ @override
+ Future<StaticType> resolve(TypeAnnotation typeAnnotation) =>
+ typeResolver.resolve(typeAnnotation);
+}
+
+class DeclarationBuilderImpl extends DeclarationBuilderBase
+ implements DeclarationBuilder {
+ DeclarationBuilderImpl(
+ ClassIntrospector classIntrospector, TypeResolver typeResolver,
+ {List<DeclarationCode>? parentAugmentations})
+ : super(classIntrospector, typeResolver,
+ parentAugmentations: parentAugmentations);
+
+ @override
+ void declareInLibrary(DeclarationCode declaration) {
+ _augmentations.add(declaration);
+ }
+}
+
+class ClassMemberDeclarationBuilderImpl extends DeclarationBuilderImpl
+ implements ClassMemberDeclarationBuilder {
+ final TypeAnnotation definingClass;
+
+ ClassMemberDeclarationBuilderImpl(this.definingClass,
+ ClassIntrospector classIntrospector, TypeResolver typeResolver,
+ {List<DeclarationCode>? parentAugmentations})
+ : super(classIntrospector, typeResolver,
+ parentAugmentations: parentAugmentations);
+
+ @override
+ void declareInClass(DeclarationCode declaration) {
+ _augmentations.add(_buildClassAugmentation(definingClass, [declaration]));
+ }
+}
+
+/// Base class for all [DefinitionBuilder]s.
+class DefinitionBuilderBase extends DeclarationBuilderBase
+ implements TypeDeclarationResolver {
+ final TypeDeclarationResolver typeDeclarationResolver;
+
+ DefinitionBuilderBase(ClassIntrospector classIntrospector,
+ TypeResolver typeResolver, this.typeDeclarationResolver,
+ {List<DeclarationCode>? parentAugmentations})
+ : super(classIntrospector, typeResolver,
+ parentAugmentations: parentAugmentations);
+
+ @override
+ Future<TypeDeclaration> declarationOf(NamedStaticType annotation) =>
+ typeDeclarationResolver.declarationOf(annotation);
+}
+
+class ClassDefinitionBuilderImpl extends DefinitionBuilderBase
+ implements ClassDefinitionBuilder {
+ /// The declaration this is a builder for.
+ final ClassDeclaration declaration;
+
+ ClassDefinitionBuilderImpl(
+ this.declaration,
+ ClassIntrospector classIntrospector,
+ TypeResolver typeResolver,
+ TypeDeclarationResolver typeDeclarationResolver,
+ {List<DeclarationCode>? parentAugmentations})
+ : super(classIntrospector, typeResolver, typeDeclarationResolver,
+ parentAugmentations: parentAugmentations);
+
+ @override
+ Future<ConstructorDefinitionBuilder> buildConstructor(String name) async {
+ ConstructorDeclaration constructor =
+ (await classIntrospector.constructorsOf(declaration))
+ .firstWhere((constructor) => constructor.name == name);
+ return new ConstructorDefinitionBuilderImpl(
+ constructor, classIntrospector, typeResolver, typeDeclarationResolver,
+ parentAugmentations: _augmentations);
+ }
+
+ @override
+ Future<VariableDefinitionBuilder> buildField(String name) async {
+ FieldDeclaration field = (await classIntrospector.fieldsOf(declaration))
+ .firstWhere((field) => field.name == name);
+ return new FieldDefinitionBuilderImpl(
+ field, classIntrospector, typeResolver, typeDeclarationResolver,
+ parentAugmentations: _augmentations);
+ }
+
+ @override
+ Future<FunctionDefinitionBuilder> buildMethod(String name) async {
+ MethodDeclaration method = (await classIntrospector.methodsOf(declaration))
+ .firstWhere((method) => method.name == name);
+ return new MethodDefinitionBuilderImpl(
+ method, classIntrospector, typeResolver, typeDeclarationResolver,
+ parentAugmentations: _augmentations);
+ }
+}
+
+/// Implementation of [FunctionDefinitionBuilder].
+class FunctionDefinitionBuilderImpl extends DefinitionBuilderBase
+ implements FunctionDefinitionBuilder {
+ final FunctionDeclaration declaration;
+
+ FunctionDefinitionBuilderImpl(
+ this.declaration,
+ ClassIntrospector classIntrospector,
+ TypeResolver typeResolver,
+ TypeDeclarationResolver typeDeclarationResolver,
+ {List<DeclarationCode>? parentAugmentations})
+ : super(classIntrospector, typeResolver, typeDeclarationResolver,
+ parentAugmentations: parentAugmentations);
+
+ @override
+ void augment(FunctionBodyCode body) {
+ _augmentations.add(_buildFunctionAugmentation(body, declaration));
+ }
+}
+
+/// Implementation of [MethodDefinitionBuilderImpl].
+class MethodDefinitionBuilderImpl extends FunctionDefinitionBuilderImpl {
+ @override
+ final MethodDeclaration declaration;
+
+ MethodDefinitionBuilderImpl(
+ this.declaration,
+ ClassIntrospector classIntrospector,
+ TypeResolver typeResolver,
+ TypeDeclarationResolver typeDeclarationResolver,
+ {List<DeclarationCode>? parentAugmentations})
+ : super(declaration, classIntrospector, typeResolver,
+ typeDeclarationResolver,
+ parentAugmentations: parentAugmentations);
+
+ @override
+ void augment(FunctionBodyCode body) {
+ _augmentations.add(_buildClassAugmentation(
+ declaration.definingClass,
+ [_buildFunctionAugmentation(body, declaration)],
+ ));
+ }
+}
+
+class ConstructorDefinitionBuilderImpl extends DefinitionBuilderBase
+ implements ConstructorDefinitionBuilder {
+ final ConstructorDeclaration declaration;
+
+ ConstructorDefinitionBuilderImpl(
+ this.declaration,
+ ClassIntrospector classIntrospector,
+ TypeResolver typeResolver,
+ TypeDeclarationResolver typeDeclarationResolver,
+ {List<DeclarationCode>? parentAugmentations})
+ : super(classIntrospector, typeResolver, typeDeclarationResolver,
+ parentAugmentations: parentAugmentations);
+
+ @override
+ void augment({FunctionBodyCode? body, List<Code>? initializers}) {
+ body ??= new FunctionBodyCode.fromString('''{
+ augment super();
+ }''');
+ _augmentations.add(_buildClassAugmentation(declaration.definingClass, [
+ _buildFunctionAugmentation(body, declaration, initializers: initializers)
+ ]));
+ }
+}
+
+class VariableDefinitionBuilderImpl extends DefinitionBuilderBase
+ implements VariableDefinitionBuilder {
+ final VariableDeclaration declaration;
+
+ VariableDefinitionBuilderImpl(
+ this.declaration,
+ ClassIntrospector classIntrospector,
+ TypeResolver typeResolver,
+ TypeDeclarationResolver typeDeclarationResolver,
+ {List<DeclarationCode>? parentAugmentations})
+ : super(classIntrospector, typeResolver, typeDeclarationResolver,
+ parentAugmentations: parentAugmentations);
+
+ @override
+ void augment(
+ {DeclarationCode? getter,
+ DeclarationCode? setter,
+ ExpressionCode? initializer}) {
+ _augmentations.addAll(_buildVariableAugmentations(declaration,
+ getter: getter, setter: setter, initializer: initializer));
+ }
+}
+
+class FieldDefinitionBuilderImpl extends DefinitionBuilderBase
+ implements VariableDefinitionBuilder {
+ final FieldDeclaration declaration;
+
+ FieldDefinitionBuilderImpl(
+ this.declaration,
+ ClassIntrospector classIntrospector,
+ TypeResolver typeResolver,
+ TypeDeclarationResolver typeDeclarationResolver,
+ {List<DeclarationCode>? parentAugmentations})
+ : super(classIntrospector, typeResolver, typeDeclarationResolver,
+ parentAugmentations: parentAugmentations);
+
+ @override
+ void augment(
+ {DeclarationCode? getter,
+ DeclarationCode? setter,
+ ExpressionCode? initializer}) {
+ _augmentations.add(_buildClassAugmentation(
+ declaration.definingClass,
+ _buildVariableAugmentations(declaration,
+ getter: getter, setter: setter, initializer: initializer)));
+ }
+}
+
+/// Creates an augmentation of [clazz] with member [augmentations].
+DeclarationCode _buildClassAugmentation(
+ TypeAnnotation clazz, List<DeclarationCode> augmentations) =>
+ new DeclarationCode.fromParts([
+ 'augment class ',
+ clazz,
+ ' {\n',
+ ...augmentations.joinAsCode('\n'),
+ '\n}',
+ ]);
+
+/// Builds all the possible augmentations for a variable.
+List<DeclarationCode> _buildVariableAugmentations(
+ VariableDeclaration declaration,
+ {DeclarationCode? getter,
+ DeclarationCode? setter,
+ ExpressionCode? initializer}) {
+ List<DeclarationCode> augmentations = [];
+ if (getter != null) {
+ augmentations.add(new DeclarationCode.fromParts([
+ 'augment ',
+ getter,
+ ]));
+ }
+ if (setter != null) {
+ augmentations.add(new DeclarationCode.fromParts([
+ 'augment ',
+ setter,
+ ]));
+ }
+ if (initializer != null) {
+ augmentations.add(new DeclarationCode.fromParts([
+ 'augment ',
+ if (declaration.isFinal) 'final ',
+ declaration.type,
+ ' ',
+ declaration.name,
+ ' = ',
+ initializer,
+ ';',
+ ]));
+ }
+
+ return augmentations;
+}
+
+/// Builds the code to augment a function, method, or constructor with a new
+/// body.
+///
+/// The [initializers] parameter can only be used if [declaration] is a
+/// constructor.
+DeclarationCode _buildFunctionAugmentation(
+ FunctionBodyCode body, FunctionDeclaration declaration,
+ {List<Code>? initializers}) {
+ assert(initializers == null || declaration is ConstructorDeclaration);
+
+ return new DeclarationCode.fromParts([
+ 'augment ',
+ if (declaration is ConstructorDeclaration) ...[
+ declaration.definingClass.name,
+ if (declaration.name.isNotEmpty) '.',
+ ] else ...[
+ declaration.returnType.code,
+ ' ',
+ ],
+ declaration.name,
+ if (declaration.typeParameters.isNotEmpty) ...[
+ '<',
+ for (TypeParameterDeclaration typeParam
+ in declaration.typeParameters) ...[
+ typeParam.name,
+ if (typeParam.bounds != null) ...['extends ', typeParam.bounds!.code],
+ if (typeParam != declaration.typeParameters.last) ', ',
+ ],
+ '>',
+ ],
+ '(',
+ for (ParameterDeclaration positionalRequired
+ in declaration.positionalParameters.where((p) => p.isRequired)) ...[
+ new ParameterCode.fromParts([
+ positionalRequired.type.code,
+ ' ',
+ positionalRequired.name,
+ ]),
+ ', '
+ ],
+ if (declaration.positionalParameters.any((p) => !p.isRequired)) ...[
+ '[',
+ for (ParameterDeclaration positionalOptional
+ in declaration.positionalParameters.where((p) => !p.isRequired)) ...[
+ new ParameterCode.fromParts([
+ positionalOptional.type.code,
+ ' ',
+ positionalOptional.name,
+ ]),
+ ', ',
+ ],
+ ']',
+ ],
+ if (declaration.namedParameters.isNotEmpty) ...[
+ '{',
+ for (ParameterDeclaration named in declaration.namedParameters) ...[
+ new ParameterCode.fromParts([
+ if (named.isRequired) 'required ',
+ named.type.code,
+ ' ',
+ named.name,
+ if (named.defaultValue != null) ...[
+ ' = ',
+ named.defaultValue!,
+ ],
+ ]),
+ ', ',
+ ],
+ '}',
+ ],
+ ') ',
+ if (initializers != null && initializers.isNotEmpty) ...[
+ ' : ',
+ initializers.first,
+ for (Code initializer in initializers.skip(1)) ...[
+ ',\n',
+ initializer,
+ ],
+ ],
+ body,
+ ]);
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/execute_macro.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/execute_macro.dart
new file mode 100644
index 0000000..f94470d
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/execute_macro.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2022, 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 'package:_fe_analyzer_shared/src/macros/executor.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor_shared/builder_impls.dart';
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+/// Runs [macro] in the declaration phase and returns a [MacroExecutionResult].
+Future<MacroExecutionResult> executeDeclarationsMacro(
+ Macro macro,
+ Declaration declaration,
+ ClassIntrospector classIntrospector,
+ TypeResolver typeResolver) async {
+ if (declaration is FunctionDeclaration) {
+ if (macro is ConstructorDeclarationsMacro &&
+ declaration is ConstructorDeclaration) {
+ ClassMemberDeclarationBuilderImpl builder =
+ new ClassMemberDeclarationBuilderImpl(
+ declaration.definingClass, classIntrospector, typeResolver);
+ await macro.buildDeclarationsForConstructor(declaration, builder);
+ return builder.result;
+ } else if (macro is MethodDeclarationsMacro &&
+ declaration is MethodDeclaration) {
+ ClassMemberDeclarationBuilderImpl builder =
+ new ClassMemberDeclarationBuilderImpl(
+ declaration.definingClass, classIntrospector, typeResolver);
+ await macro.buildDeclarationsForMethod(declaration, builder);
+ return builder.result;
+ } else if (macro is FunctionDeclarationsMacro) {
+ DeclarationBuilderImpl builder =
+ new DeclarationBuilderImpl(classIntrospector, typeResolver);
+ await macro.buildDeclarationsForFunction(declaration, builder);
+ return builder.result;
+ }
+ } else if (declaration is VariableDeclaration) {
+ if (macro is FieldDeclarationsMacro && declaration is FieldDeclaration) {
+ ClassMemberDeclarationBuilderImpl builder =
+ new ClassMemberDeclarationBuilderImpl(
+ declaration.definingClass, classIntrospector, typeResolver);
+ await macro.buildDeclarationsForField(declaration, builder);
+ return builder.result;
+ } else if (macro is VariableDeclarationsMacro) {
+ DeclarationBuilderImpl builder =
+ new DeclarationBuilderImpl(classIntrospector, typeResolver);
+ await macro.buildDeclarationsForVariable(declaration, builder);
+ return builder.result;
+ }
+ } else if (macro is ClassDeclarationsMacro &&
+ declaration is ClassDeclaration) {
+ ClassMemberDeclarationBuilderImpl builder =
+ new ClassMemberDeclarationBuilderImpl(
+ declaration.type, classIntrospector, typeResolver);
+ await macro.buildDeclarationsForClass(declaration, builder);
+ return builder.result;
+ }
+ throw new UnsupportedError('Unsupported macro type or invalid declaration:\n'
+ 'macro: $macro\ndeclaration: $declaration');
+}
+
+/// Runs [macro] in the definition phase and returns a [MacroExecutionResult].
+Future<MacroExecutionResult> executeDefinitionMacro(
+ Macro macro,
+ Declaration declaration,
+ ClassIntrospector classIntrospector,
+ TypeResolver typeResolver,
+ TypeDeclarationResolver typeDeclarationResolver) async {
+ if (declaration is FunctionDeclaration) {
+ if (macro is ConstructorDefinitionMacro &&
+ declaration is ConstructorDeclaration) {
+ ConstructorDefinitionBuilderImpl builder =
+ new ConstructorDefinitionBuilderImpl(declaration, classIntrospector,
+ typeResolver, typeDeclarationResolver);
+ await macro.buildDefinitionForConstructor(declaration, builder);
+ return builder.result;
+ } else if (macro is MethodDefinitionMacro &&
+ declaration is MethodDeclaration) {
+ MethodDefinitionBuilderImpl builder = new MethodDefinitionBuilderImpl(
+ declaration,
+ classIntrospector,
+ typeResolver,
+ typeDeclarationResolver);
+ await macro.buildDefinitionForMethod(declaration, builder);
+ return builder.result;
+ } else if (macro is FunctionDefinitionMacro) {
+ FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
+ declaration,
+ classIntrospector,
+ typeResolver,
+ typeDeclarationResolver);
+ await macro.buildDefinitionForFunction(declaration, builder);
+ return builder.result;
+ }
+ } else if (declaration is VariableDeclaration) {
+ if (macro is FieldDefinitionMacro && declaration is FieldDeclaration) {
+ FieldDefinitionBuilderImpl builder = new FieldDefinitionBuilderImpl(
+ declaration,
+ classIntrospector,
+ typeResolver,
+ typeDeclarationResolver);
+ await macro.buildDefinitionForField(declaration, builder);
+ return builder.result;
+ } else if (macro is VariableDefinitionMacro) {
+ VariableDefinitionBuilderImpl builder = new VariableDefinitionBuilderImpl(
+ declaration,
+ classIntrospector,
+ typeResolver,
+ typeDeclarationResolver);
+ await macro.buildDefinitionForVariable(declaration, builder);
+ return builder.result;
+ }
+ } else if (macro is ClassDefinitionMacro && declaration is ClassDeclaration) {
+ ClassDefinitionBuilderImpl builder = new ClassDefinitionBuilderImpl(
+ declaration, classIntrospector, typeResolver, typeDeclarationResolver);
+ await macro.buildDefinitionForClass(declaration, builder);
+ return builder.result;
+ }
+ throw new UnsupportedError('Unsupported macro type or invalid declaration:\n'
+ 'macro: $macro\ndeclaration: $declaration');
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart
index a3f6fb4..9bdd740 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart
@@ -334,7 +334,7 @@
class MethodDeclarationImpl extends FunctionDeclarationImpl
implements MethodDeclaration {
@override
- final TypeAnnotationImpl definingClass;
+ final NamedTypeAnnotationImpl definingClass;
@override
RemoteInstanceKind get kind => RemoteInstanceKind.methodDeclaration;
@@ -401,7 +401,7 @@
required TypeAnnotationImpl returnType,
required List<TypeParameterDeclarationImpl> typeParameters,
// Method fields
- required TypeAnnotationImpl definingClass,
+ required NamedTypeAnnotationImpl definingClass,
// Constructor fields
required this.isFactory,
}) : super(
@@ -433,15 +433,18 @@
class VariableDeclarationImpl extends DeclarationImpl
implements VariableDeclaration {
@override
- final Code? initializer;
-
- @override
- final bool isAbstract;
+ final ExpressionCode? initializer;
@override
final bool isExternal;
@override
+ final bool isFinal;
+
+ @override
+ final bool isLate;
+
+ @override
final TypeAnnotationImpl type;
@override
@@ -451,8 +454,9 @@
required int id,
required String name,
required this.initializer,
- required this.isAbstract,
required this.isExternal,
+ required this.isFinal,
+ required this.isLate,
required this.type,
}) : super(id: id, name: name);
@@ -466,8 +470,9 @@
initializer.serializeNullable(serializer);
serializer
- ..addBool(isAbstract)
- ..addBool(isExternal);
+ ..addBool(isExternal)
+ ..addBool(isFinal)
+ ..addBool(isLate);
type.serialize(serializer);
}
}
@@ -475,16 +480,17 @@
class FieldDeclarationImpl extends VariableDeclarationImpl
implements FieldDeclaration {
@override
- final TypeAnnotationImpl definingClass;
+ final NamedTypeAnnotationImpl definingClass;
FieldDeclarationImpl({
// Declaration fields
required int id,
required String name,
// Variable fields
- required Code? initializer,
- required bool isAbstract,
+ required ExpressionCode? initializer,
required bool isExternal,
+ required bool isFinal,
+ required bool isLate,
required TypeAnnotationImpl type,
// Field fields
required this.definingClass,
@@ -492,8 +498,9 @@
id: id,
name: name,
initializer: initializer,
- isAbstract: isAbstract,
isExternal: isExternal,
+ isFinal: isFinal,
+ isLate: isLate,
type: type);
@override
@@ -513,11 +520,15 @@
abstract class TypeDeclarationImpl extends DeclarationImpl
implements TypeDeclaration {
@override
+ final TypeAnnotationImpl type;
+
+ @override
final List<TypeParameterDeclarationImpl> typeParameters;
TypeDeclarationImpl({
required int id,
required String name,
+ required this.type,
required this.typeParameters,
}) : super(id: id, name: name);
@@ -535,6 +546,7 @@
return;
}
+ type.serialize(serializer);
serializer..startList();
for (TypeParameterDeclarationImpl param in typeParameters) {
param.serialize(serializer);
@@ -568,6 +580,7 @@
required int id,
required String name,
// TypeDeclaration fields
+ required TypeAnnotationImpl type,
required List<TypeParameterDeclarationImpl> typeParameters,
// ClassDeclaration fields
required this.interfaces,
@@ -575,7 +588,7 @@
required this.isExternal,
required this.mixins,
required this.superclass,
- }) : super(id: id, name: name, typeParameters: typeParameters);
+ }) : super(id: id, name: name, type: type, typeParameters: typeParameters);
@override
void serialize(Serializer serializer) {
@@ -604,21 +617,22 @@
class TypeAliasDeclarationImpl extends TypeDeclarationImpl
implements TypeAliasDeclaration {
- @override
- RemoteInstanceKind get kind => RemoteInstanceKind.typeAliasDeclaration;
+ /// The type being aliased.
+ final TypeAnnotationImpl aliasedType;
@override
- final TypeAnnotationImpl type;
+ RemoteInstanceKind get kind => RemoteInstanceKind.typeAliasDeclaration;
TypeAliasDeclarationImpl({
// Declaration fields
required int id,
required String name,
// TypeDeclaration fields
+ required TypeAnnotationImpl type,
required List<TypeParameterDeclarationImpl> typeParameters,
// TypeAlias fields
- required this.type,
- }) : super(id: id, name: name, typeParameters: typeParameters);
+ required this.aliasedType,
+ }) : super(id: id, name: name, type: type, typeParameters: typeParameters);
@override
void serialize(Serializer serializer) {
@@ -628,6 +642,6 @@
return;
}
- type.serialize(serializer);
+ aliasedType.serialize(serializer);
}
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
index f16daf9..3eae69c 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
@@ -239,6 +239,41 @@
/// A request to execute a macro on a particular declaration in the definition
/// phase.
+class ExecuteDeclarationsPhaseRequest extends Request {
+ final MacroInstanceIdentifier macro;
+ final DeclarationImpl declaration;
+
+ final RemoteInstanceImpl typeResolver;
+ final RemoteInstanceImpl classIntrospector;
+
+ ExecuteDeclarationsPhaseRequest(
+ this.macro, this.declaration, this.typeResolver, this.classIntrospector,
+ {required int serializationZoneId})
+ : super(serializationZoneId: serializationZoneId);
+
+ /// When deserializing we have already consumed the message type, so we don't
+ /// consume it again.
+ ExecuteDeclarationsPhaseRequest.deserialize(
+ Deserializer deserializer, int serializationZoneId)
+ : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
+ declaration = RemoteInstance.deserialize(deserializer),
+ typeResolver = RemoteInstance.deserialize(deserializer),
+ classIntrospector = RemoteInstance.deserialize(deserializer),
+ super.deserialize(deserializer, serializationZoneId);
+
+ void serialize(Serializer serializer) {
+ serializer.addNum(MessageType.executeDeclarationsPhaseRequest.index);
+ macro.serialize(serializer);
+ declaration.serialize(serializer);
+ typeResolver.serialize(serializer);
+ classIntrospector.serialize(serializer);
+
+ super.serialize(serializer);
+ }
+}
+
+/// A request to execute a macro on a particular declaration in the definition
+/// phase.
class ExecuteDefinitionsPhaseRequest extends Request {
final MacroInstanceIdentifier macro;
final DeclarationImpl declaration;
@@ -627,6 +662,7 @@
mixinsOfRequest,
superclassOfRequest,
error,
+ executeDeclarationsPhaseRequest,
executeDefinitionsPhaseRequest,
instantiateMacroRequest,
isExactlyTypeRequest,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
index 77556ad..f829357 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
@@ -2,13 +2,8 @@
// 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/executor_shared/remote_instance.dart';
-
import '../executor.dart';
import '../api.dart';
-import 'introspection_impls.dart';
import 'serialization.dart';
import 'serialization_extensions.dart';
@@ -55,10 +50,9 @@
final List<DeclarationCode> imports;
MacroExecutionResultImpl({
- List<DeclarationCode>? augmentations,
- List<DeclarationCode>? imports,
- }) : augmentations = augmentations ?? [],
- imports = imports ?? [];
+ required this.augmentations,
+ required this.imports,
+ });
factory MacroExecutionResultImpl.deserialize(Deserializer deserializer) {
deserializer.moveNext();
@@ -97,128 +91,3 @@
serializer.endList();
}
}
-
-/// Implementation of [FunctionDefinitionBuilder].
-class FunctionDefinitionBuilderImpl implements FunctionDefinitionBuilder {
- final TypeResolver typeResolver;
- final TypeDeclarationResolver typeDeclarationResolver;
- final ClassIntrospector classIntrospector;
-
- /// The declaration this is a builder for.
- final FunctionDeclarationImpl declaration;
-
- /// The final result, will be built up over `augment` calls.
- final MacroExecutionResultImpl result;
-
- FunctionDefinitionBuilderImpl(this.declaration, this.typeResolver,
- this.typeDeclarationResolver, this.classIntrospector)
- : result = new MacroExecutionResultImpl();
-
- FunctionDefinitionBuilderImpl.deserialize(Deserializer deserializer,
- this.typeResolver, this.typeDeclarationResolver, this.classIntrospector)
- : declaration = RemoteInstance.deserialize(deserializer),
- result = new MacroExecutionResultImpl.deserialize(deserializer);
-
- void serialize(Serializer serializer) {
- // Note that the `typeResolver`, `typeDeclarationResolver`, and
- // `classIntrospector` are not serialized. These have custom implementations
- // on the client/server side.
- declaration.serialize(serializer);
- result.serialize(serializer);
- }
-
- @override
- void augment(FunctionBodyCode body) {
- result.augmentations.add(new DeclarationCode.fromParts([
- 'augment ',
- declaration.returnType.code,
- ' ',
- declaration.name,
- if (declaration.typeParameters.isNotEmpty) ...[
- '<',
- for (TypeParameterDeclaration typeParam
- in declaration.typeParameters) ...[
- typeParam.name,
- if (typeParam.bounds != null) ...['extends ', typeParam.bounds!.code],
- if (typeParam != declaration.typeParameters.last) ', ',
- ],
- '>',
- ],
- '(',
- for (ParameterDeclaration positionalRequired
- in declaration.positionalParameters.where((p) => p.isRequired)) ...[
- new ParameterCode.fromParts([
- positionalRequired.type.code,
- ' ',
- positionalRequired.name,
- ]),
- ', '
- ],
- if (declaration.positionalParameters.any((p) => !p.isRequired)) ...[
- '[',
- for (ParameterDeclaration positionalOptional in declaration
- .positionalParameters
- .where((p) => !p.isRequired)) ...[
- new ParameterCode.fromParts([
- positionalOptional.type.code,
- ' ',
- positionalOptional.name,
- ]),
- ', ',
- ],
- ']',
- ],
- if (declaration.namedParameters.isNotEmpty) ...[
- '{',
- for (ParameterDeclaration named in declaration.namedParameters) ...[
- new ParameterCode.fromParts([
- if (named.isRequired) 'required ',
- named.type.code,
- ' ',
- named.name,
- if (named.defaultValue != null) ...[
- ' = ',
- named.defaultValue!,
- ],
- ]),
- ', ',
- ],
- '}',
- ],
- ') ',
- body,
- ]));
- }
-
- @override
- Future<List<ConstructorDeclaration>> constructorsOf(ClassDeclaration clazz) =>
- classIntrospector.constructorsOf(clazz);
-
- @override
- Future<List<FieldDeclaration>> fieldsOf(ClassDeclaration clazz) =>
- classIntrospector.fieldsOf(clazz);
-
- @override
- Future<List<ClassDeclaration>> interfacesOf(ClassDeclaration clazz) =>
- classIntrospector.interfacesOf(clazz);
-
- @override
- Future<List<MethodDeclaration>> methodsOf(ClassDeclaration clazz) =>
- classIntrospector.methodsOf(clazz);
-
- @override
- Future<List<ClassDeclaration>> mixinsOf(ClassDeclaration clazz) =>
- classIntrospector.mixinsOf(clazz);
-
- @override
- Future<TypeDeclaration> declarationOf(NamedStaticType annotation) =>
- typeDeclarationResolver.declarationOf(annotation);
-
- @override
- Future<ClassDeclaration?> superclassOf(ClassDeclaration clazz) =>
- classIntrospector.superclassOf(clazz);
-
- @override
- Future<StaticType> resolve(TypeAnnotation typeAnnotation) =>
- typeResolver.resolve(typeAnnotation);
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
index b7df0be..33464d7 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
@@ -152,8 +152,9 @@
id: id,
name: expectString(),
initializer: (this..moveNext()).expectNullableCode(),
- isAbstract: (this..moveNext()).expectBool(),
isExternal: (this..moveNext()).expectBool(),
+ isFinal: (this..moveNext()).expectBool(),
+ isLate: (this..moveNext()).expectBool(),
type: RemoteInstance.deserialize(this),
);
@@ -161,8 +162,9 @@
id: id,
name: expectString(),
initializer: (this..moveNext()).expectNullableCode(),
- isAbstract: (this..moveNext()).expectBool(),
isExternal: (this..moveNext()).expectBool(),
+ isFinal: (this..moveNext()).expectBool(),
+ isLate: (this..moveNext()).expectBool(),
type: RemoteInstance.deserialize(this),
definingClass: RemoteInstance.deserialize(this),
);
@@ -170,6 +172,7 @@
ClassDeclaration _expectClassDeclaration(int id) => new ClassDeclarationImpl(
id: id,
name: expectString(),
+ type: RemoteInstance.deserialize(this),
typeParameters: (this..moveNext())._expectRemoteInstanceList(),
interfaces: (this..moveNext())._expectRemoteInstanceList(),
isAbstract: (this..moveNext()).expectBool(),
@@ -183,8 +186,9 @@
new TypeAliasDeclarationImpl(
id: id,
name: expectString(),
- typeParameters: (this..moveNext())._expectRemoteInstanceList(),
type: RemoteInstance.deserialize(this),
+ typeParameters: (this..moveNext())._expectRemoteInstanceList(),
+ aliasedType: RemoteInstance.deserialize(this),
);
T expectCode<T extends Code>() {
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
index 91b1125..e1e12fe 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
@@ -6,6 +6,7 @@
import 'dart:isolate';
import 'dart:mirrors';
+import '../executor_shared/builder_impls.dart';
import '../executor_shared/introspection_impls.dart';
import '../executor_shared/response_impls.dart';
import '../executor_shared/protocol.dart';
@@ -97,9 +98,9 @@
declaration is FunctionDeclarationImpl) {
FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
declaration,
+ request.classIntrospector.instance as ClassIntrospector,
request.typeResolver.instance as TypeResolver,
- request.typeDeclarationResolver.instance as TypeDeclarationResolver,
- request.classIntrospector.instance as ClassIntrospector);
+ request.typeDeclarationResolver.instance as TypeDeclarationResolver);
await instance.buildDefinitionForFunction(declaration, builder);
return new Response(
response: builder.result,
@@ -109,9 +110,9 @@
declaration is MethodDeclarationImpl) {
FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
declaration,
+ request.classIntrospector.instance as ClassIntrospector,
request.typeResolver.instance as TypeResolver,
- request.typeDeclarationResolver.instance as TypeDeclarationResolver,
- request.classIntrospector.instance as ClassIntrospector);
+ request.typeDeclarationResolver.instance as TypeDeclarationResolver);
await instance.buildDefinitionForMethod(declaration, builder);
return new SerializableResponse(
responseType: MessageType.macroExecutionResult,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
index 57f0ec8..9194c7f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
@@ -377,13 +377,22 @@
@override
Future<MacroExecutionResult> executeDeclarationsPhase(
- MacroInstanceIdentifier macro,
- DeclarationImpl declaration,
- TypeResolver typeResolver,
- ClassIntrospector classIntrospector) {
- // TODO: implement executeDeclarationsPhase
- throw new UnimplementedError();
- }
+ MacroInstanceIdentifier macro,
+ DeclarationImpl declaration,
+ TypeResolver typeResolver,
+ ClassIntrospector classIntrospector) =>
+ _sendRequest((zoneId) => new ExecuteDeclarationsPhaseRequest(
+ macro,
+ declaration,
+ new RemoteInstanceImpl(
+ instance: typeResolver,
+ id: RemoteInstance.uniqueId,
+ kind: RemoteInstanceKind.typeResolver),
+ new RemoteInstanceImpl(
+ instance: classIntrospector,
+ id: RemoteInstance.uniqueId,
+ kind: RemoteInstanceKind.classIntrospector),
+ serializationZoneId: zoneId));
@override
Future<MacroExecutionResult> executeDefinitionsPhase(
diff --git a/pkg/_fe_analyzer_shared/test/macros/executor_shared/serialization_test.dart b/pkg/_fe_analyzer_shared/test/macros/executor_shared/serialization_test.dart
index 6a3807b..b9efa16 100644
--- a/pkg/_fe_analyzer_shared/test/macros/executor_shared/serialization_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/executor_shared/serialization_test.dart
@@ -207,9 +207,10 @@
var bar = VariableDeclarationImpl(
id: RemoteInstance.uniqueId,
name: 'bar',
- isAbstract: false,
isExternal: true,
- initializer: Code.fromString('Bar()'),
+ isFinal: false,
+ isLate: true,
+ initializer: ExpressionCode.fromString('Bar()'),
type: barType,
);
expectSerializationEquality(bar);
@@ -219,8 +220,9 @@
var bar = FieldDeclarationImpl(
id: RemoteInstance.uniqueId,
name: 'bar',
- isAbstract: false,
isExternal: false,
+ isFinal: true,
+ isLate: false,
initializer: null,
type: barType,
definingClass: fooType,
@@ -250,6 +252,7 @@
isExternal: false,
mixins: [serializableType],
superclass: objectType,
+ type: fooType,
typeParameters: [zapTypeParam],
);
expectSerializationEquality(fooClass);
@@ -262,9 +265,14 @@
type: NamedTypeAnnotationImpl(
id: RemoteInstance.uniqueId,
isNullable: false,
+ name: 'FooOfBar',
+ typeArguments: []),
+ typeParameters: [zapTypeParam],
+ aliasedType: NamedTypeAnnotationImpl(
+ id: RemoteInstance.uniqueId,
+ isNullable: false,
name: 'Foo',
typeArguments: [barType]),
- typeParameters: [zapTypeParam],
);
expectSerializationEquality(typeAlias);
});
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
index 7c242a4..81aa97f 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
@@ -18,31 +18,23 @@
void main() {
late MacroExecutor executor;
- late Directory tmpDir;
+ late File kernelOutputFile;
+ final macroName = 'SimpleMacro';
+ late MacroInstanceIdentifier instanceId;
+ late Uri macroUri;
late File simpleMacroFile;
+ late Directory tmpDir;
- setUpAll(() {
+ setUpAll(() async {
// We support running from either the root of the SDK or the package root.
simpleMacroFile = File(
'pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart');
if (!simpleMacroFile.existsSync()) {
simpleMacroFile = File('test/macros/isolated_executor/simple_macro.dart');
}
- });
-
- setUp(() async {
executor = await isolatedExecutor.start();
tmpDir = Directory.systemTemp.createTempSync('isolated_executor_test');
- });
-
- tearDown(() {
- if (tmpDir.existsSync()) tmpDir.deleteSync(recursive: true);
- executor.close();
- });
-
- test('can load and run macros', () async {
- var macroUri = simpleMacroFile.absolute.uri;
- var macroName = 'SimpleMacro';
+ macroUri = simpleMacroFile.absolute.uri;
var bootstrapContent = bootstrapMacroIsolate({
macroUri.toString(): {
@@ -51,22 +43,22 @@
});
var bootstrapFile = File(tmpDir.uri.resolve('main.dart').toFilePath())
..writeAsStringSync(bootstrapContent);
- var kernelOutputFile =
- File(tmpDir.uri.resolve('main.dart.dill').toFilePath());
- var result = await Process.run(Platform.resolvedExecutable, [
+ kernelOutputFile = File(tmpDir.uri.resolve('main.dart.dill').toFilePath());
+ var buildSnapshotResult = await Process.run(Platform.resolvedExecutable, [
'--snapshot=${kernelOutputFile.uri.toFilePath()}',
'--snapshot-kind=kernel',
'--packages=${(await Isolate.packageConfig)!}',
bootstrapFile.uri.toFilePath(),
]);
- expect(result.exitCode, 0,
- reason: 'stdout: ${result.stdout}\nstderr: ${result.stderr}');
+ expect(buildSnapshotResult.exitCode, 0,
+ reason: 'stdout: ${buildSnapshotResult.stdout}\n'
+ 'stderr: ${buildSnapshotResult.stderr}');
var clazzId = await executor.loadMacro(macroUri, macroName,
precompiledKernelUri: kernelOutputFile.uri);
expect(clazzId, isNotNull, reason: 'Can load a macro.');
- var instanceId =
+ instanceId =
await executor.instantiateMacro(clazzId, '', Arguments([], {}));
expect(instanceId, isNotNull,
reason: 'Can create an instance with no arguments.');
@@ -80,7 +72,14 @@
clazzId, 'named', Arguments([], {'x': 1, 'y': 2}));
expect(instanceId, isNotNull,
reason: 'Can create an instance with named arguments.');
+ });
+ tearDownAll(() {
+ if (tmpDir.existsSync()) tmpDir.deleteSync(recursive: true);
+ executor.close();
+ });
+
+ group('run macros', () {
var stringType = NamedTypeAnnotationImpl(
id: RemoteInstance.uniqueId,
name: 'String',
@@ -111,6 +110,7 @@
var myClass = ClassDeclarationImpl(
id: RemoteInstance.uniqueId,
name: myClassType.name,
+ type: myClassType,
typeParameters: [],
interfaces: [myInterfaceType],
isAbstract: false,
@@ -134,13 +134,15 @@
id: RemoteInstance.uniqueId,
name: 'myField',
initializer: null,
- isAbstract: false,
isExternal: false,
+ isFinal: false,
+ isLate: false,
type: stringType,
definingClass: myClassType);
var myInterface = ClassDeclarationImpl(
id: RemoteInstance.uniqueId,
name: myInterfaceType.name,
+ type: myInterfaceType,
typeParameters: [],
interfaces: [],
isAbstract: false,
@@ -162,6 +164,7 @@
var myMixin = ClassDeclarationImpl(
id: RemoteInstance.uniqueId,
name: myMixinType.name,
+ type: myMixinType,
typeParameters: [],
interfaces: [],
isAbstract: false,
@@ -171,6 +174,7 @@
var mySuperclass = ClassDeclarationImpl(
id: RemoteInstance.uniqueId,
name: mySuperclassType.name,
+ type: mySuperclassType,
typeParameters: [],
interfaces: [],
isAbstract: false,
@@ -181,61 +185,189 @@
var myClassStaticType = TestNamedStaticType(
'package:my_package/my_package.dart', myClassType.name, []);
- var definitionResult = await executor.executeDefinitionsPhase(
- instanceId,
- MethodDeclarationImpl(
- id: RemoteInstance.uniqueId,
- definingClass: myClassType,
- isAbstract: false,
- isExternal: false,
- isGetter: false,
- isSetter: false,
- name: 'foo',
- namedParameters: [],
- positionalParameters: [],
- returnType: stringType,
- typeParameters: [],
- ),
- TestTypeResolver({
- stringType: TestNamedStaticType('dart:core', stringType.name, []),
- myClassType: myClassStaticType,
- }),
- TestClassIntrospector(
- constructors: {
- myClass: [myConstructor],
- },
- fields: {
- myClass: [myField],
- },
- interfaces: {
- myClass: [myInterface],
- },
- methods: {
- myClass: [myMethod],
- },
- mixins: {
- myClass: [myMixin],
- },
- superclass: {
- myClass: mySuperclass,
- },
- ),
- TestTypeDeclarationResolver({myClassStaticType: myClass}));
- expect(definitionResult.augmentations, hasLength(1));
- expect(definitionResult.augmentations.first.debugString().toString(),
- equalsIgnoringWhitespace('''
- augment class MyClass {
- augment String foo() {
- print('x: 1, y: 2');
- print('parentClass: MyClass');
- print('superClass: MySuperclass');
- print('interface: MyInterface');
- print('mixin: MyMixin');
- print('field: myField');
- print('method: myMethod');
- print('constructor: myConstructor');
- return augment super();
- }
- }'''));
+ var testTypeResolver = TestTypeResolver({
+ stringType: TestNamedStaticType('dart:core', stringType.name, []),
+ myClassType: myClassStaticType,
+ });
+ var testClassIntrospector = TestClassIntrospector(
+ constructors: {
+ myClass: [myConstructor],
+ },
+ fields: {
+ myClass: [myField],
+ },
+ interfaces: {
+ myClass: [myInterface],
+ },
+ methods: {
+ myClass: [myMethod],
+ },
+ mixins: {
+ myClass: [myMixin],
+ },
+ superclass: {
+ myClass: mySuperclass,
+ },
+ );
+ var testTypeDeclarationResolver =
+ TestTypeDeclarationResolver({myClassStaticType: myClass});
+
+ group('in the declaration phase', () {
+ test('on methods', () async {
+ var result = await executor.executeDeclarationsPhase(
+ instanceId, myMethod, testTypeResolver, testClassIntrospector);
+ expect(
+ result.augmentations.single.debugString().toString(),
+ equalsIgnoringWhitespace(
+ 'String delegateMemberMyMethod() => myMethod();'));
+ });
+
+ test('on constructors', () async {
+ var result = await executor.executeDeclarationsPhase(
+ instanceId, myConstructor, testTypeResolver, testClassIntrospector);
+ expect(result.augmentations.single.debugString().toString(),
+ equalsIgnoringWhitespace('''
+ augment class MyClass {
+ factory MyClass.myConstructorDelegate() => MyClass.myConstructor();
+ }'''));
+ });
+
+ test('on fields', () async {
+ var result = await executor.executeDeclarationsPhase(
+ instanceId, myField, testTypeResolver, testClassIntrospector);
+ expect(result.augmentations.single.debugString().toString(),
+ equalsIgnoringWhitespace('''
+ augment class MyClass {
+ String get delegateMyField => myField;
+ }'''));
+ });
+
+ test('on classes', () async {
+ var result = await executor.executeDeclarationsPhase(
+ instanceId, myClass, testTypeResolver, testClassIntrospector);
+ expect(result.augmentations.single.debugString().toString(),
+ equalsIgnoringWhitespace('''
+ augment class MyClass {
+ static const List<String> fieldNames = ['myField',];
+ }'''));
+ });
+ });
+
+ group('in the definition phase', () {
+ test('on methods', () async {
+ var definitionResult = await executor.executeDefinitionsPhase(
+ instanceId,
+ myMethod,
+ testTypeResolver,
+ testClassIntrospector,
+ testTypeDeclarationResolver);
+ expect(definitionResult.augmentations, hasLength(2));
+ var augmentationStrings = definitionResult.augmentations
+ .map((a) => a.debugString().toString())
+ .toList();
+ expect(augmentationStrings, unorderedEquals(methodDefinitionMatchers));
+ });
+
+ test('on constructors', () async {
+ var definitionResult = await executor.executeDefinitionsPhase(
+ instanceId,
+ myConstructor,
+ testTypeResolver,
+ testClassIntrospector,
+ testTypeDeclarationResolver);
+ expect(definitionResult.augmentations, hasLength(1));
+ expect(definitionResult.augmentations.first.debugString().toString(),
+ constructorDefinitionMatcher);
+ });
+
+ test('on fields', () async {
+ var definitionResult = await executor.executeDefinitionsPhase(
+ instanceId,
+ myField,
+ testTypeResolver,
+ testClassIntrospector,
+ testTypeDeclarationResolver);
+ expect(definitionResult.augmentations, hasLength(1));
+ expect(definitionResult.augmentations.first.debugString().toString(),
+ fieldDefinitionMatcher);
+ });
+
+ test('on classes', () async {
+ var definitionResult = await executor.executeDefinitionsPhase(
+ instanceId,
+ myClass,
+ testTypeResolver,
+ testClassIntrospector,
+ testTypeDeclarationResolver);
+ var augmentationStrings = definitionResult.augmentations
+ .map((a) => a.debugString().toString())
+ .toList();
+ expect(
+ augmentationStrings,
+ unorderedEquals([
+ ...methodDefinitionMatchers,
+ constructorDefinitionMatcher,
+ fieldDefinitionMatcher
+ ]));
+ });
+ });
});
}
+
+final constructorDefinitionMatcher = equalsIgnoringWhitespace('''
+augment class MyClass {
+ augment MyClass.myConstructor() {
+ print('definingClass: MyClass');
+ print('isFactory: false');
+ print('isAbstract: false');
+ print('isExternal: false');
+ print('isGetter: false');
+ print('isSetter: false');
+ print('returnType: MyClass');
+ return augment super();
+ }
+}''');
+
+final fieldDefinitionMatcher = equalsIgnoringWhitespace('''
+augment class MyClass {
+ augment String get myField {
+ print('parentClass: MyClass');
+ print('isExternal: false');
+ print('isFinal: false');
+ print('isLate: false');
+ return augment super;
+ }
+ augment set (String value) {
+ augment super(value);
+ }
+}''');
+
+final methodDefinitionMatchers = [
+ equalsIgnoringWhitespace('''
+ augment class MyClass {
+ augment String myMethod() {
+ print('definingClass: MyClass');
+ print('isAbstract: false');
+ print('isExternal: false');
+ print('isGetter: false');
+ print('isSetter: false');
+ print('returnType: String');
+ return augment super();
+ }
+ }
+ '''),
+ equalsIgnoringWhitespace('''
+ augment class MyClass {
+ augment String myMethod() {
+ print('x: 1, y: 2');
+ print('parentClass: MyClass');
+ print('superClass: MySuperclass');
+ print('interface: MyInterface');
+ print('mixin: MyMixin');
+ print('field: myField');
+ print('method: myMethod');
+ print('constructor: myConstructor');
+ return augment super();
+ }
+ }'''),
+];
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
index 84ddb7a..b5681aa 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
@@ -6,9 +6,26 @@
import 'package:_fe_analyzer_shared/src/macros/api.dart';
-/// A very simple macro that annotates functions (or getters) with no arguments
-/// and adds a print statement to the top of them.
-class SimpleMacro implements MethodDefinitionMacro {
+/// A very simple macro that augments any declaration it is given, usually
+/// adding print statements and inlining values from the declaration object
+/// for comparision with expected values in tests.
+///
+/// When applied to [MethodDeclaration]s there is some extra work that happens
+/// to validate the introspection APIs work as expected.
+class SimpleMacro
+ implements
+ ClassDeclarationsMacro,
+ ClassDefinitionMacro,
+ ConstructorDeclarationsMacro,
+ ConstructorDefinitionMacro,
+ FieldDeclarationsMacro,
+ FieldDefinitionMacro,
+ FunctionDeclarationsMacro,
+ FunctionDefinitionMacro,
+ MethodDeclarationsMacro,
+ MethodDefinitionMacro,
+ VariableDeclarationsMacro,
+ VariableDefinitionMacro {
final int? x;
final int? y;
@@ -17,14 +34,132 @@
SimpleMacro.named({this.x, this.y});
@override
- FutureOr<void> buildDefinitionForMethod(
- MethodDeclaration method, FunctionDefinitionBuilder builder) async {
- if (method.namedParameters
- .followedBy(method.positionalParameters)
- .isNotEmpty) {
- throw ArgumentError(
- 'This macro can only be run on functions with no arguments!');
+ FutureOr<void> buildDeclarationsForClass(
+ ClassDeclaration clazz, ClassMemberDeclarationBuilder builder) async {
+ var fields = await builder.fieldsOf(clazz);
+ builder.declareInClass(DeclarationCode.fromParts([
+ 'static const List<String> fieldNames = [',
+ for (var field in fields) "'${field.name}',",
+ '];',
+ ]));
+ }
+
+ @override
+ FutureOr<void> buildDeclarationsForConstructor(
+ ConstructorDeclaration constructor,
+ ClassMemberDeclarationBuilder builder) {
+ if (constructor.positionalParameters.isNotEmpty ||
+ constructor.namedParameters.isNotEmpty) {
+ throw new UnsupportedError(
+ 'Can only run on constructors with no parameters!');
}
+ builder.declareInClass(
+ DeclarationCode.fromString('factory ${constructor.definingClass.name}'
+ '.${constructor.name}Delegate() => '
+ '${constructor.definingClass.name}.${constructor.name}();'));
+ }
+
+ @override
+ FutureOr<void> buildDeclarationsForFunction(
+ FunctionDeclaration function, DeclarationBuilder builder) {
+ if (function.positionalParameters.isNotEmpty ||
+ function.namedParameters.isNotEmpty) {
+ throw new UnsupportedError(
+ 'Can only run on functions with no parameters!');
+ }
+ builder.declareInLibrary(DeclarationCode.fromParts([
+ function.returnType,
+ ' delegate${function.name.capitalize()}() => ${function.name}();',
+ ]));
+ }
+
+ @override
+ FutureOr<void> buildDeclarationsForMethod(
+ MethodDeclaration method, ClassMemberDeclarationBuilder builder) {
+ if (method.positionalParameters.isNotEmpty ||
+ method.namedParameters.isNotEmpty) {
+ throw new UnsupportedError('Can only run on method with no parameters!');
+ }
+ builder.declareInLibrary(DeclarationCode.fromParts([
+ method.returnType,
+ ' delegateMember${method.name.capitalize()}() => ${method.name}();',
+ ]));
+ }
+
+ @override
+ FutureOr<void> buildDeclarationsForVariable(
+ VariableDeclaration variable, DeclarationBuilder builder) {
+ builder.declareInLibrary(DeclarationCode.fromParts([
+ variable.type,
+ ' get delegate${variable.name.capitalize()} => ${variable.name};',
+ ]));
+ }
+
+ @override
+ FutureOr<void> buildDeclarationsForField(
+ FieldDeclaration field, ClassMemberDeclarationBuilder builder) {
+ builder.declareInClass(DeclarationCode.fromParts([
+ field.type,
+ ' get delegate${field.name.capitalize()} => ${field.name};',
+ ]));
+ }
+
+ @override
+ Future<void> buildDefinitionForClass(
+ ClassDeclaration clazz, ClassDefinitionBuilder builder) async {
+ // Apply ourself to all our members
+ var fields = (await builder.fieldsOf(clazz));
+ for (var field in fields) {
+ await buildDefinitionForField(
+ field, await builder.buildField(field.name));
+ }
+ var methods = (await builder.methodsOf(clazz));
+ for (var method in methods) {
+ await buildDefinitionForMethod(
+ method, await builder.buildMethod(method.name));
+ }
+ var constructors = (await builder.constructorsOf(clazz));
+ for (var constructor in constructors) {
+ await buildDefinitionForConstructor(
+ constructor, await builder.buildConstructor(constructor.name));
+ }
+ }
+
+ @override
+ Future<void> buildDefinitionForConstructor(ConstructorDeclaration constructor,
+ ConstructorDefinitionBuilder builder) async {
+ var clazz = await builder.declarationOf(
+ await builder.resolve(constructor.definingClass) as NamedStaticType)
+ as ClassDeclaration;
+ var fields = (await builder.fieldsOf(clazz));
+
+ builder.augment(
+ body: _buildFunctionAugmentation(constructor),
+ initializers: [
+ for (var field in fields)
+ // TODO: Compare against actual `int` type.
+ if (field.isFinal &&
+ (field.type as NamedTypeAnnotation).name == 'int')
+ Code.fromString('${field.name} = ${x!}'),
+ ],
+ );
+ }
+
+ @override
+ Future<void> buildDefinitionForField(
+ FieldDeclaration field, VariableDefinitionBuilder builder) async =>
+ buildDefinitionForVariable(field, builder);
+
+ @override
+ Future<void> buildDefinitionForFunction(
+ FunctionDeclaration function, FunctionDefinitionBuilder builder) async {
+ builder.augment(_buildFunctionAugmentation(function));
+ }
+
+ @override
+ Future<void> buildDefinitionForMethod(
+ MethodDeclaration method, FunctionDefinitionBuilder builder) async {
+ await buildDefinitionForFunction(method, builder);
// Test the type resolver and static type interfaces
var staticReturnType = await builder.resolve(method.returnType);
@@ -48,6 +183,9 @@
// Test the type declaration resolver
var parentClass =
await builder.declarationOf(classType) as ClassDeclaration;
+ // Should be able to find ourself in the methods of the parent class.
+ (await builder.methodsOf(parentClass))
+ .singleWhere((m) => m.name == method.name);
// Test the class introspector
var superClass = (await builder.superclassOf(parentClass))!;
@@ -74,4 +212,71 @@
}''',
]));
}
+
+ @override
+ Future<void> buildDefinitionForVariable(
+ VariableDeclaration variable, VariableDefinitionBuilder builder) async {
+ var definingClass =
+ variable is FieldDeclaration ? variable.definingClass.name : '';
+ builder.augment(
+ getter: DeclarationCode.fromParts([
+ variable.type,
+ ' get ',
+ variable.name,
+ ''' {
+ print('parentClass: $definingClass');
+ print('isExternal: ${variable.isExternal}');
+ print('isFinal: ${variable.isFinal}');
+ print('isLate: ${variable.isLate}');
+ return augment super;
+ }''',
+ ]),
+ setter: DeclarationCode.fromParts(
+ ['set (', variable.type, ' value) { augment super(value); }']),
+ initializer: variable.initializer,
+ );
+ }
+}
+
+FunctionBodyCode _buildFunctionAugmentation(FunctionDeclaration function) =>
+ FunctionBodyCode.fromParts([
+ '{\n',
+ if (function is MethodDeclaration)
+ "print('definingClass: ${function.definingClass.name}');\n",
+ if (function is ConstructorDeclaration)
+ "print('isFactory: ${function.isFactory}');\n",
+ '''
+ print('isAbstract: ${function.isAbstract}');
+ print('isExternal: ${function.isExternal}');
+ print('isGetter: ${function.isGetter}');
+ print('isSetter: ${function.isSetter}');
+ print('returnType: ''',
+ function.returnType,
+ "');\n",
+ for (var param in function.positionalParameters) ...[
+ "print('positionalParam: ",
+ param.type,
+ ' ${param.name}',
+ if (param.defaultValue != null) ...[' = ', param.defaultValue!],
+ "');\n",
+ ],
+ for (var param in function.namedParameters) ...[
+ "print('namedParam: ",
+ param.type,
+ ' ${param.name}',
+ if (param.defaultValue != null) ...[' = ', param.defaultValue!],
+ "');\n",
+ ],
+ for (var param in function.typeParameters) ...[
+ "print('typeParam: ${param.name} ",
+ if (param.bounds != null) param.bounds!,
+ "');\n",
+ ],
+ '''
+ return augment super();
+ }''',
+ ]);
+
+extension _ on String {
+ String capitalize() => '${this[0].toUpperCase()}${this.substring(1)}';
}
diff --git a/pkg/analysis_server/test/client/completion_driver_test.dart b/pkg/analysis_server/test/client/completion_driver_test.dart
index 732e5bb..a12950d 100644
--- a/pkg/analysis_server/test/client/completion_driver_test.dart
+++ b/pkg/analysis_server/test/client/completion_driver_test.dart
@@ -15,8 +15,10 @@
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(BasicCompletionTest);
- defineReflectiveTests(CompletionWithSuggestionsTest);
+ defineReflectiveTests(BasicCompletionTest1);
+ defineReflectiveTests(BasicCompletionTest2);
+ defineReflectiveTests(CompletionWithSuggestionsTest1);
+ defineReflectiveTests(CompletionWithSuggestionsTest2);
});
}
@@ -29,6 +31,8 @@
String get projectPath => '/$projectName';
+ TestingCompletionProtocol get protocol;
+
AnalysisServerOptions get serverOptions => AnalysisServerOptions();
bool get supportsAvailableSuggestions;
@@ -108,7 +112,14 @@
await driver.waitForSetWithUri('dart:async');
}
- suggestions = await driver.getSuggestions();
+ switch (protocol) {
+ case TestingCompletionProtocol.version1:
+ suggestions = await driver.getSuggestions();
+ break;
+ case TestingCompletionProtocol.version2:
+ suggestions = await driver.getSuggestions2();
+ break;
+ }
return suggestions;
}
@@ -199,7 +210,20 @@
}
@reflectiveTest
-class BasicCompletionTest extends AbstractCompletionDriverTest {
+class BasicCompletionTest1 extends AbstractCompletionDriverTest
+ with BasicCompletionTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class BasicCompletionTest2 extends AbstractCompletionDriverTest
+ with BasicCompletionTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin BasicCompletionTestCases on AbstractCompletionDriverTest {
@override
bool get supportsAvailableSuggestions => false;
@@ -233,7 +257,40 @@
}
@reflectiveTest
-class CompletionWithSuggestionsTest extends AbstractCompletionDriverTest {
+class CompletionWithSuggestionsTest1 extends AbstractCompletionDriverTest
+ with CompletionWithSuggestionsTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+
+ @failingTest
+ @override
+ Future<void> test_project_lib_multipleExports() async {
+ return super.test_project_lib_multipleExports();
+ }
+}
+
+@reflectiveTest
+class CompletionWithSuggestionsTest2 extends AbstractCompletionDriverTest
+ with CompletionWithSuggestionsTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+
+ @FailingTest(reason: 'Not implemented yet')
+ @override
+ Future<void> test_project_lib_fields_static() {
+ // TODO: implement test_project_lib_fields_static
+ return super.test_project_lib_fields_static();
+ }
+
+ @FailingTest(reason: 'Not implemented yet')
+ @override
+ Future<void> test_project_lib_getters_static() {
+ // TODO: implement test_project_lib_getters_static
+ return super.test_project_lib_getters_static();
+ }
+}
+
+mixin CompletionWithSuggestionsTestCases on AbstractCompletionDriverTest {
@override
bool get supportsAvailableSuggestions => true;
@@ -507,7 +564,6 @@
assertNoSuggestion(completion: 'A.foo');
}
- @failingTest
Future<void> test_project_lib_multipleExports() async {
await addProjectFile('lib/a.dart', r'''
class A {}
@@ -732,3 +788,5 @@
// (No typedefs, enums, extensions defined in the Mock SDK.)
}
}
+
+enum TestingCompletionProtocol { version1, version2 }
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
index 13a02b0..8577738 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
@@ -5,16 +5,50 @@
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../../client/completion_driver_test.dart';
import 'completion_relevance.dart';
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(BoolAssignmentTest);
+ // defineReflectiveTests(BoolAssignmentTest1);
+ defineReflectiveTests(BoolAssignmentTest2);
});
}
@reflectiveTest
-class BoolAssignmentTest extends CompletionRelevanceTest {
+class BoolAssignmentTest1 extends CompletionRelevanceTest
+ with BoolAssignmentTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class BoolAssignmentTest2 extends CompletionRelevanceTest
+ with BoolAssignmentTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+
+ @FailingTest(reason: r'''
+The actual relevances are:
+[completion: bool.fromEnvironment][relevance: 591]
+[completion: bool.hasEnvironment][relevance: 591]
+[completion: b][relevance: 587]
+[completion: bool][relevance: 578]
+[completion: true][relevance: 574]
+[completion: false][relevance: 572]
+[completion: identical][relevance: 563]
+ for (var e in result) {
+ print('[completion: ${e.completion}][relevance: ${e.relevance}]');
+ }
+''')
+ @override
+ Future<void> test_boolLiterals_imported() {
+ // TODO: implement test_boolLiterals_imported
+ return super.test_boolLiterals_imported();
+ }
+}
+
+mixin BoolAssignmentTestCases on CompletionRelevanceTest {
Future<void> test_boolLiterals_imported() async {
await addTestFile('''
foo() {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart b/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
index 81532df..f353b8d 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
@@ -7,7 +7,7 @@
import '../../../../client/completion_driver_test.dart';
-class CompletionRelevanceTest extends AbstractCompletionDriverTest {
+abstract class CompletionRelevanceTest extends AbstractCompletionDriverTest {
@override
bool get supportsAvailableSuggestions => true;
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart
index 44d0f92..40826b7 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart
@@ -5,16 +5,31 @@
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../../client/completion_driver_test.dart';
import 'completion_relevance.dart';
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(DeprecatedMemberTest);
+ defineReflectiveTests(DeprecatedMemberTest1);
+ defineReflectiveTests(DeprecatedMemberTest2);
});
}
@reflectiveTest
-class DeprecatedMemberTest extends CompletionRelevanceTest {
+class DeprecatedMemberTest1 extends CompletionRelevanceTest
+ with DeprecatedMemberTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class DeprecatedMemberTest2 extends CompletionRelevanceTest
+ with DeprecatedMemberTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin DeprecatedMemberTestCases on CompletionRelevanceTest {
Future<void> test_deprecated() async {
await addTestFile('''
class A {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
index de08d73..b6ad9fc 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
@@ -4,16 +4,31 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../../client/completion_driver_test.dart';
import 'completion_relevance.dart';
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(InstanceMemberTest);
+ defineReflectiveTests(InstanceMemberTest1);
+ defineReflectiveTests(InstanceMemberTest2);
});
}
@reflectiveTest
-class InstanceMemberTest extends CompletionRelevanceTest {
+class InstanceMemberTest1 extends CompletionRelevanceTest
+ with InstanceMemberTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class InstanceMemberTest2 extends CompletionRelevanceTest
+ with InstanceMemberTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin InstanceMemberTestCases on CompletionRelevanceTest {
@override
bool get supportsAvailableSuggestions => true;
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart
index 388a377..0a02b82 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart
@@ -5,16 +5,31 @@
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../../client/completion_driver_test.dart';
import 'completion_relevance.dart';
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(IsNoSuchMethodTest);
+ defineReflectiveTests(IsNoSuchMethodTest1);
+ defineReflectiveTests(IsNoSuchMethodTest2);
});
}
@reflectiveTest
-class IsNoSuchMethodTest extends CompletionRelevanceTest {
+class IsNoSuchMethodTest1 extends CompletionRelevanceTest
+ with IsNoSuchMethodTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class IsNoSuchMethodTest2 extends CompletionRelevanceTest
+ with IsNoSuchMethodTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin IsNoSuchMethodTestCases on CompletionRelevanceTest {
Future<void> test_notSuper() async {
await addTestFile('''
void foo(Object o) {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
index 8fe61ae..c5a3d1a 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
@@ -5,16 +5,31 @@
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../../client/completion_driver_test.dart';
import 'completion_relevance.dart';
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(LocalVariableTest);
+ defineReflectiveTests(LocalVariableTest1);
+ defineReflectiveTests(LocalVariableTest2);
});
}
@reflectiveTest
-class LocalVariableTest extends CompletionRelevanceTest {
+class LocalVariableTest1 extends CompletionRelevanceTest
+ with LocalVariableTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class LocalVariableTest2 extends CompletionRelevanceTest
+ with LocalVariableTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin LocalVariableTestCases on CompletionRelevanceTest {
Future<void> test_localVariables() async {
await addTestFile('''
int f() {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart
index a8a5607..018a020 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart
@@ -4,18 +4,32 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../../client/completion_driver_test.dart';
import '../../../../src/utilities/mock_packages.dart';
import 'completion_relevance.dart';
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(NamedArgumentTest);
- defineReflectiveTests(NamedArgumentWithNullSafetyTest);
+ defineReflectiveTests(NamedArgumentTest1);
+ defineReflectiveTests(NamedArgumentTest2);
});
}
@reflectiveTest
-class NamedArgumentTest extends CompletionRelevanceTest {
+class NamedArgumentTest1 extends CompletionRelevanceTest
+ with NamedArgumentTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class NamedArgumentTest2 extends CompletionRelevanceTest
+ with NamedArgumentTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin NamedArgumentTestCases on CompletionRelevanceTest {
@override
Future<void> setUp() async {
await super.setUp();
@@ -28,11 +42,9 @@
''');
}
- Future<void> test_requiredAnnotation() async {
+ Future<void> test_required() async {
await addTestFile('''
-import 'package:meta/meta.dart';
-
-void f({int a, @required int b}) {}
+void f({int a = 0, required int b}) {}
void g() => f(^);
''');
@@ -41,13 +53,12 @@
suggestionWith(completion: 'a: '),
]);
}
-}
-@reflectiveTest
-class NamedArgumentWithNullSafetyTest extends NamedArgumentTest {
- Future<void> test_required() async {
+ Future<void> test_requiredAnnotation() async {
await addTestFile('''
-void f({int a = 0, required int b}) {}
+import 'package:meta/meta.dart';
+
+void f({int a, @required int b}) {}
void g() => f(^);
''');
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart
index 084c91c..c582a1c 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart
@@ -5,16 +5,31 @@
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../../client/completion_driver_test.dart';
import 'completion_relevance.dart';
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(NonTypeMemberTest);
+ defineReflectiveTests(NonTypeMemberTest1);
+ defineReflectiveTests(NonTypeMemberTest2);
});
}
@reflectiveTest
-class NonTypeMemberTest extends CompletionRelevanceTest {
+class NonTypeMemberTest1 extends CompletionRelevanceTest
+ with NonTypeMemberTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class NonTypeMemberTest2 extends CompletionRelevanceTest
+ with NonTypeMemberTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin NonTypeMemberTestCases on CompletionRelevanceTest {
Future<void> test_contextType_constructorInvocation_before_type() async {
await addTestFile('''
class StrWrap {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart
index 314b1e0..a9e1de8 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart
@@ -4,16 +4,31 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../../client/completion_driver_test.dart';
import 'completion_relevance.dart';
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(StaticMemberTest);
+ defineReflectiveTests(StaticMemberTest1);
+ defineReflectiveTests(StaticMemberTest2);
});
}
@reflectiveTest
-class StaticMemberTest extends CompletionRelevanceTest {
+class StaticMemberTest1 extends CompletionRelevanceTest
+ with StaticMemberTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class StaticMemberTest2 extends CompletionRelevanceTest
+ with StaticMemberTestCases {
+ @override
+ TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin StaticMemberTestCases on CompletionRelevanceTest {
Future<void> test_contextType() async {
await addTestFile(r'''
class A {}
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 18fa4cb..55ad35e 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -142,6 +142,10 @@
static const String cfeInvocationModes = '--cfe-invocation-modes';
+ /// Flag to indicate how the compiler is invoked. Used to ensure
+ /// dart2js is only invoked from supported tools and through the Dart CLI.
+ static const String invoker = '--invoker';
+
/// Flag to stop after splitting the program.
static const String stopAfterProgramSplit = '--stop-after-program-split';
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index d8ec77f..1913f4e 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -139,6 +139,7 @@
ReadStrategy readStrategy = ReadStrategy.fromDart;
WriteStrategy writeStrategy = WriteStrategy.toJs;
FeatureOptions features = FeatureOptions();
+ String invoker;
void passThrough(String argument) => options.add(argument);
void ignoreOption(String argument) {}
@@ -480,6 +481,10 @@
passThrough(argument);
}
+ void setInvoker(String argument) {
+ invoker = extractParameter(argument);
+ }
+
void handleThrowOnError(String argument) {
throwOnError = true;
String parameter = extractParameter(argument, isOptionalArgument: true);
@@ -645,6 +650,7 @@
OptionHandler(Flags.testMode, passThrough),
OptionHandler('${Flags.dumpSsa}=.+', passThrough),
OptionHandler('${Flags.cfeInvocationModes}=.+', passThrough),
+ OptionHandler('${Flags.invoker}=.+', setInvoker),
OptionHandler('${Flags.verbosity}=.+', passThrough),
// Experimental features.
@@ -694,6 +700,13 @@
parseCommandLine(handlers, argv);
+ if (invoker == null) {
+ warning("The 'dart2js' entrypoint script is deprecated, "
+ "please use 'dart compile js' instead.");
+ } else if (verbose != null) {
+ print("Compiler invoked from: '$invoker'");
+ }
+
// TODO(johnniwinther): Measure time for reading files.
SourceFileProvider inputProvider;
if (bazelPaths != null) {
@@ -1128,7 +1141,7 @@
// before and after running the compiler. Another two lines may be
// used to print an error message.
print('''
-Usage: dart2js [options] dartfile
+Usage: dart compile js [options] dartfile
Compiles Dart to JavaScript.
@@ -1140,7 +1153,7 @@
void verboseHelp() {
print(r'''
-Usage: dart2js [options] dartfile
+Usage: dart compile js [options] dartfile
Compiles Dart to JavaScript.
@@ -1352,6 +1365,15 @@
fail(message);
}
+void warning(String message) {
+ if (diagnosticHandler != null) {
+ diagnosticHandler.report(
+ null, null, -1, -1, message, api.Diagnostic.WARNING);
+ } else {
+ print('Warning: $message');
+ }
+}
+
Future<void> main(List<String> arguments) async {
// Expand `@path/to/file`
// When running from bazel, argument of the form `@path/to/file` might be
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 4198a79..bd48713 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -90,6 +90,7 @@
[
'--libraries-spec=$librariesPath',
'--cfe-invocation-modes=compile',
+ '--invoker=dart_cli',
...argResults.arguments,
],
packageConfigOverride: null);
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
index d92782a..8c513a4 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
@@ -40,7 +40,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect
index d92782a..8c513a4 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect
@@ -40,7 +40,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
index 0765c4c..ae497d5a 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
@@ -74,7 +74,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect
index 7e198e7..6c37a20d 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect
@@ -51,7 +51,6 @@
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
- ffi::Char,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
@@ -64,7 +63,6 @@
ffi::FloatArray,
ffi::FloatPointer,
ffi::Handle,
- ffi::Int,
ffi::Int16,
ffi::Int16Array,
ffi::Int16Pointer,
@@ -78,8 +76,6 @@
ffi::Int8Array,
ffi::Int8Pointer,
ffi::IntPtr,
- ffi::Long,
- ffi::LongLong,
ffi::NativeApi,
ffi::NativeFunction,
ffi::NativeFunctionPointer,
@@ -90,9 +86,6 @@
ffi::Pointer,
ffi::PointerArray,
ffi::PointerPointer,
- ffi::Short,
- ffi::SignedChar,
- ffi::Size,
ffi::Struct,
ffi::StructArray,
ffi::StructPointer,
@@ -108,18 +101,11 @@
ffi::Uint8,
ffi::Uint8Array,
ffi::Uint8Pointer,
- ffi::UintPtr,
ffi::Union,
ffi::UnionArray,
ffi::UnionPointer,
- ffi::UnsignedChar,
- ffi::UnsignedInt,
- ffi::UnsignedLong,
- ffi::UnsignedLongLong,
- ffi::UnsignedShort,
ffi::Unsized,
- ffi::Void,
- ffi::WChar)
+ ffi::Void)
export "org-dartlang-test:///lib3.dart";
@@ -141,7 +127,6 @@
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
- ffi::Char,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
@@ -154,7 +139,6 @@
ffi::FloatArray,
ffi::FloatPointer,
ffi::Handle,
- ffi::Int,
ffi::Int16,
ffi::Int16Array,
ffi::Int16Pointer,
@@ -168,8 +152,6 @@
ffi::Int8Array,
ffi::Int8Pointer,
ffi::IntPtr,
- ffi::Long,
- ffi::LongLong,
ffi::NativeApi,
ffi::NativeFunction,
ffi::NativeFunctionPointer,
@@ -180,9 +162,6 @@
ffi::Pointer,
ffi::PointerArray,
ffi::PointerPointer,
- ffi::Short,
- ffi::SignedChar,
- ffi::Size,
ffi::Struct,
ffi::StructArray,
ffi::StructPointer,
@@ -198,18 +177,11 @@
ffi::Uint8,
ffi::Uint8Array,
ffi::Uint8Pointer,
- ffi::UintPtr,
ffi::Union,
ffi::UnionArray,
ffi::UnionPointer,
- ffi::UnsignedChar,
- ffi::UnsignedInt,
- ffi::UnsignedLong,
- ffi::UnsignedLongLong,
- ffi::UnsignedShort,
ffi::Unsized,
- ffi::Void,
- ffi::WChar)
+ ffi::Void)
export "dart:ffi";
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect
index 934102e..e7c047a 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect
@@ -51,7 +51,6 @@
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
- ffi::Char,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
@@ -64,7 +63,6 @@
ffi::FloatArray,
ffi::FloatPointer,
ffi::Handle,
- ffi::Int,
ffi::Int16,
ffi::Int16Array,
ffi::Int16Pointer,
@@ -78,8 +76,6 @@
ffi::Int8Array,
ffi::Int8Pointer,
ffi::IntPtr,
- ffi::Long,
- ffi::LongLong,
ffi::NativeApi,
ffi::NativeFunction,
ffi::NativeFunctionPointer,
@@ -90,9 +86,6 @@
ffi::Pointer,
ffi::PointerArray,
ffi::PointerPointer,
- ffi::Short,
- ffi::SignedChar,
- ffi::Size,
ffi::Struct,
ffi::StructArray,
ffi::StructPointer,
@@ -108,18 +101,11 @@
ffi::Uint8,
ffi::Uint8Array,
ffi::Uint8Pointer,
- ffi::UintPtr,
ffi::Union,
ffi::UnionArray,
ffi::UnionPointer,
- ffi::UnsignedChar,
- ffi::UnsignedInt,
- ffi::UnsignedLong,
- ffi::UnsignedLongLong,
- ffi::UnsignedShort,
ffi::Unsized,
- ffi::Void,
- ffi::WChar)
+ ffi::Void)
export "org-dartlang-test:///lib3.dart";
@@ -141,7 +127,6 @@
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
- ffi::Char,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
@@ -154,7 +139,6 @@
ffi::FloatArray,
ffi::FloatPointer,
ffi::Handle,
- ffi::Int,
ffi::Int16,
ffi::Int16Array,
ffi::Int16Pointer,
@@ -168,8 +152,6 @@
ffi::Int8Array,
ffi::Int8Pointer,
ffi::IntPtr,
- ffi::Long,
- ffi::LongLong,
ffi::NativeApi,
ffi::NativeFunction,
ffi::NativeFunctionPointer,
@@ -180,9 +162,6 @@
ffi::Pointer,
ffi::PointerArray,
ffi::PointerPointer,
- ffi::Short,
- ffi::SignedChar,
- ffi::Size,
ffi::Struct,
ffi::StructArray,
ffi::StructPointer,
@@ -198,18 +177,11 @@
ffi::Uint8,
ffi::Uint8Array,
ffi::Uint8Pointer,
- ffi::UintPtr,
ffi::Union,
ffi::UnionArray,
ffi::UnionPointer,
- ffi::UnsignedChar,
- ffi::UnsignedInt,
- ffi::UnsignedLong,
- ffi::UnsignedLongLong,
- ffi::UnsignedShort,
ffi::Unsized,
- ffi::Void,
- ffi::WChar)
+ ffi::Void)
export "dart:ffi";
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
index b190b3a..35dda10 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
@@ -34,7 +34,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
index fccf634..02dfd2a 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
@@ -65,7 +65,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
index b190b3a..35dda10 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
@@ -34,7 +34,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect
index b190b3a..35dda10 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect
@@ -34,7 +34,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
index fccf634..02dfd2a 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
@@ -65,7 +65,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
index 4d771b3..0db513d 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
@@ -25,5 +25,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
index f3903c0..525cfd9 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
@@ -52,5 +52,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
index e179ab5..e6c0f95 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
@@ -25,5 +25,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect
index e179ab5..e6c0f95 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect
@@ -25,5 +25,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
index 24cfa96..b38ad34 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
@@ -52,5 +52,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
index dd7fa30..0e058b1 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
@@ -33,5 +33,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
index a16945b..ecf21c0 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
@@ -84,5 +84,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
index be09548..5e4b756 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
@@ -33,5 +33,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect
index be09548..5e4b756 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect
@@ -33,5 +33,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
index a83a86b..a9ba39c 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
@@ -84,5 +84,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/test_runner/lib/src/command.dart b/pkg/test_runner/lib/src/command.dart
index da28355..c14af03 100644
--- a/pkg/test_runner/lib/src/command.dart
+++ b/pkg/test_runner/lib/src/command.dart
@@ -124,7 +124,9 @@
(io.Platform.operatingSystem == 'windows')
? env.write('set $key=${escapeCommandLineArgument(value)} & ')
: env.write('$key=${escapeCommandLineArgument(value)} '));
- var command = ([executable]..addAll(batchArguments)..addAll(arguments))
+ var command = ([executable]
+ ..addAll(nonBatchArguments)
+ ..addAll(arguments))
.map(escapeCommandLineArgument)
.join(' ');
if (workingDirectory != null) {
@@ -135,10 +137,13 @@
bool get outputIsUpToDate => false;
- /// Arguments that are passed to the process when starting batch mode.
- ///
- /// In non-batch mode, they should be passed before [arguments].
+ /// Additional arguments to prepend before [arguments] when running the
+ /// process in batch mode.
List<String> get batchArguments => const [];
+
+ /// Additional arguments to prepend before [arguments] when running the
+ /// process in non-batch mode.
+ List<String> get nonBatchArguments => const [];
}
class CompilationCommand extends ProcessCommand {
@@ -243,6 +248,61 @@
deepJsonCompare(_bootstrapDependencies, other._bootstrapDependencies);
}
+class Dart2jsCompilationCommand extends CompilationCommand {
+ final bool useSdk;
+
+ Dart2jsCompilationCommand(
+ String outputFile,
+ List<Uri> bootstrapDependencies,
+ String executable,
+ List<String> arguments,
+ Map<String, String> environmentOverrides,
+ {this.useSdk,
+ bool alwaysCompile,
+ String workingDirectory,
+ int index = 0})
+ : super("dart2js", outputFile, bootstrapDependencies, executable,
+ arguments, environmentOverrides,
+ alwaysCompile: alwaysCompile || true,
+ workingDirectory: workingDirectory,
+ index: index);
+
+ @override
+ CommandOutput createOutput(int exitCode, bool timedOut, List<int> stdout,
+ List<int> stderr, Duration time, bool compilationSkipped,
+ [int pid = 0]) {
+ return Dart2jsCompilerCommandOutput(
+ this, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
+ }
+
+ @override
+ List<String> get batchArguments {
+ return <String>[
+ if (useSdk) ...['compile', 'js'],
+ ...super.batchArguments,
+ ];
+ }
+
+ @override
+ List<String> get nonBatchArguments {
+ return <String>[
+ if (useSdk) ...['compile', 'js'],
+ ...super.nonBatchArguments,
+ ];
+ }
+
+ @override
+ void _buildHashCode(HashCodeBuilder builder) {
+ super._buildHashCode(builder);
+ builder.addJson(useSdk);
+ }
+
+ @override
+ bool _equal(Dart2jsCompilationCommand other) {
+ return super._equal(other) && useSdk == other.useSdk;
+ }
+}
+
class FastaCompilationCommand extends CompilationCommand {
final Uri _compilerLocation;
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 16ac923..1ef049d 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -378,37 +378,34 @@
}
}
-/// Common configuration for dart2js-based tools, such as dart2js.
-class Dart2xCompilerConfiguration extends CompilerConfiguration {
+/// Configuration for dart2js.
+class Dart2jsCompilerConfiguration extends CompilerConfiguration {
static final Map<String, List<Uri>> _bootstrapDependenciesCache = {};
- final String moniker;
-
- Dart2xCompilerConfiguration(this.moniker, TestConfiguration configuration)
+ Dart2jsCompilerConfiguration(TestConfiguration configuration)
: super._subclass(configuration);
String computeCompilerPath() {
- var prefix = 'sdk/bin';
- var suffix = shellScriptExtension;
-
- if (_isHostChecked) {
- if (_useSdk) {
- // Note: when [_useSdk] is true, dart2js is run from a snapshot that was
- // built without checked mode. The VM cannot make such snapshot run in
- // checked mode later. These two flags could be used together if we also
- // build an sdk with checked snapshots.
- throw "--host-checked and --use-sdk cannot be used together";
- }
- // The script dart2js_developer is not included in the
- // shipped SDK, that is the script is not installed in
- // "$buildDir/dart-sdk/bin/"
- return '$prefix/dart2js_developer$suffix';
+ if (_isHostChecked && _useSdk) {
+ // When [_useSdk] is true, dart2js is compiled into a snapshot that was
+ // built without checked mode. The VM cannot make such snapshot run in
+ // checked mode later. These two flags could be used together if we also
+ // build an sdk with checked snapshots.
+ throw "--host-checked and --use-sdk cannot be used together";
}
if (_useSdk) {
- prefix = '${_configuration.buildDirectory}/dart-sdk/bin';
+ var dartSdk = '${_configuration.buildDirectory}/dart-sdk';
+ // When using the shipped sdk, we invoke dart2js via the dart CLI using
+ // `dart compile js`. The additional `compile js` arguments are added
+ // within [Dart2jsCompilationCommand]. This is because the arguments are
+ // added differently depending on whether the command is executed in batch
+ // mode or not.
+ return '$dartSdk/bin/dart$executableExtension';
+ } else {
+ var scriptName = _isHostChecked ? 'dart2js_developer' : 'dart2js';
+ return 'sdk/bin/$scriptName$shellScriptExtension';
}
- return '$prefix/dart2js$suffix';
}
Command computeCompilationCommand(String outputFileName,
@@ -416,9 +413,9 @@
arguments = arguments.toList();
arguments.add('--out=$outputFileName');
- return CompilationCommand(moniker, outputFileName, bootstrapDependencies(),
+ return Dart2jsCompilationCommand(outputFileName, bootstrapDependencies(),
computeCompilerPath(), arguments, environmentOverrides,
- alwaysCompile: !_useSdk);
+ useSdk: _useSdk, alwaysCompile: !_useSdk);
}
List<Uri> bootstrapDependencies() {
@@ -431,12 +428,6 @@
.resolve('dart-sdk/bin/snapshots/dart2js.dart.snapshot')
]);
}
-}
-
-/// Configuration for dart2js.
-class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration {
- Dart2jsCompilerConfiguration(TestConfiguration configuration)
- : super('dart2js', configuration);
List<String> computeCompilerArguments(
TestFile testFile, List<String> vmOptions, List<String> args) {
diff --git a/pkg/test_runner/lib/src/test_case.dart b/pkg/test_runner/lib/src/test_case.dart
index 2597e45..72ed102 100644
--- a/pkg/test_runner/lib/src/test_case.dart
+++ b/pkg/test_runner/lib/src/test_case.dart
@@ -260,7 +260,7 @@
_commandComplete(0);
} else {
var processEnvironment = _createProcessEnvironment();
- var args = command.arguments;
+ var args = [...command.nonBatchArguments, ...command.arguments];
var processFuture = io.Process.start(command.executable, args,
environment: processEnvironment,
workingDirectory: command.workingDirectory);
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index 1545f8e..dd5e41f 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -1138,36 +1138,27 @@
typedef intptr_t ssize_t;
#endif
-#define DEFINE_SIZE_OF_AND_SIGN_OF(type_modifier, type, type2) \
- DART_EXPORT uint64_t FfiSizeOf_##type_modifier##_##type##_##type2() { \
- return sizeof(type_modifier type type2); \
- } \
- \
- DART_EXPORT uint64_t FfiSignOf_##type_modifier##_##type##_##type2() { \
- return std::numeric_limits<type_modifier type type2>::is_signed; \
+#define DEFINE_SIZE_OF(type_modifier, type) \
+ DART_EXPORT uint64_t FfiSizeOf_##type_modifier##_##type() { \
+ return sizeof(type_modifier type); \
}
-#define TYPES(F) \
- F(, char, ) /* NOLINT */ \
- F(signed, char, ) /* NOLINT */ \
- F(unsigned, char, ) /* NOLINT */ \
- F(, short, ) /* NOLINT */ \
- F(unsigned, short, ) /* NOLINT */ \
- F(, int, ) /* NOLINT */ \
- F(unsigned, int, ) /* NOLINT */ \
- F(, long, ) /* NOLINT */ \
- F(unsigned, long, ) /* NOLINT */ \
- F(, long, long) /* NOLINT */ \
- F(unsigned, long, long) /* NOLINT */ \
- F(, intptr_t, ) /* NOLINT */ \
- F(, uintptr_t, ) /* NOLINT */ \
- F(, size_t, ) /* NOLINT */ \
- F(, wchar_t, ) /* NOLINT */
+#define SIZES(F) \
+ F(, intptr_t) \
+ F(, uintptr_t) \
+ F(, int) \
+ F(unsigned, int) \
+ F(, long) /* NOLINT */ \
+ F(unsigned, long) /* NOLINT */ \
+ F(, wchar_t) \
+ F(, size_t) \
+ F(, ssize_t) \
+ F(, off_t)
-TYPES(DEFINE_SIZE_OF_AND_SIGN_OF)
+SIZES(DEFINE_SIZE_OF)
-#undef DEFINE_SIZE_OF_AND_SIGN_OF
-#undef TYPES
+#undef DEFINE_SIZE_OF
+#undef SIZES
DART_EXPORT int64_t WCharMinValue() {
return WCHAR_MIN;
diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js
index cfc91b1..750f20d 100755
--- a/sdk/bin/dart2js
+++ b/sdk/bin/dart2js
@@ -25,6 +25,7 @@
unset EXTRA_OPTIONS
declare -a EXTRA_OPTIONS
+EXTRA_OPTIONS+=('--invoker=development_script')
if test -t 1; then
# Stdout is a terminal.
if test 8 -le `tput colors`; then
diff --git a/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
index ca47a83..92e23c1 100644
--- a/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
@@ -55,6 +55,11 @@
@pragma("vm:entry-point")
class Uint64 extends _NativeInteger {}
+// TODO(http://dartbug.com/47938): Implement as AbiSpecificInteger.
+@patch
+@pragma("vm:entry-point")
+class IntPtr extends _NativeInteger {}
+
@patch
@pragma("vm:entry-point")
class Float extends _NativeDouble {}
diff --git a/sdk/lib/ffi/abi_specific.dart b/sdk/lib/ffi/abi_specific.dart
index a41308c..d84f74e 100644
--- a/sdk/lib/ffi/abi_specific.dart
+++ b/sdk/lib/ffi/abi_specific.dart
@@ -13,12 +13,10 @@
/// For example:
///
/// ```
-/// /// The C `uintptr_t` type.
+/// /// Represents a `uintptr_t` in C.
/// ///
-/// /// The [UintPtr] type is a native type, and should not be constructed in
-/// /// Dart code.
-/// /// It occurs only in native type signatures and as annotation on [Struct]
-/// /// and [Union] fields.
+/// /// [UintPtr] is not constructible in the Dart code and serves purely as
+/// /// marker in type signatures.
/// @AbiSpecificIntegerMapping({
/// Abi.androidArm: Uint32(),
/// Abi.androidArm64: Uint64(),
diff --git a/sdk/lib/ffi/c_type.dart b/sdk/lib/ffi/c_type.dart
deleted file mode 100644
index 9370fdc..0000000
--- a/sdk/lib/ffi/c_type.dart
+++ /dev/null
@@ -1,541 +0,0 @@
-// Copyright (c) 2022, 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.
-
-/// This library defines [NativeType]s for common C types.
-///
-/// Many C types only define a minimal size in the C standard, but they are
-/// consistent per [Abi]. Therefore we use [AbiSpecificInteger]s to define
-/// these C types in this library.
-part of dart.ffi;
-
-/// The C `char` type.
-///
-/// Typically a signed or unsigned 8-bit integer.
-/// For a guaranteed 8-bit integer, use [Int8] with the C `int8_t` type
-/// or [Uint8] with the C `uint8_t` type.
-/// For a specifically `signed` or `unsigned` `char`, use [SignedChar] or
-/// [UnsignedChar].
-///
-/// The [Char] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint8(),
- Abi.androidArm64: Uint8(),
- Abi.androidIA32: Uint8(),
- Abi.androidX64: Uint8(),
- Abi.fuchsiaArm64: Int8(),
- Abi.fuchsiaX64: Int8(),
- Abi.iosArm: Uint8(),
- Abi.iosArm64: Int8(),
- Abi.iosX64: Int8(),
- Abi.linuxArm: Uint8(),
- Abi.linuxArm64: Int8(),
- Abi.linuxIA32: Int8(),
- Abi.linuxX64: Int8(),
- Abi.linuxRiscv32: Int8(),
- Abi.linuxRiscv64: Int8(),
- Abi.macosArm64: Int8(),
- Abi.macosX64: Int8(),
- Abi.windowsArm64: Int8(),
- Abi.windowsIA32: Int8(),
- Abi.windowsX64: Int8(),
-})
-class Char extends AbiSpecificInteger {
- const Char();
-}
-
-/// The C `signed char` type.
-///
-/// Typically a signed 8-bit integer.
-/// For a guaranteed 8-bit integer, use [Int8] with the C `int8_t` type.
-/// For an `unsigned char`, use [UnsignedChar].
-///
-/// The [SignedChar] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Int8(),
- Abi.androidArm64: Int8(),
- Abi.androidIA32: Int8(),
- Abi.androidX64: Int8(),
- Abi.fuchsiaArm64: Int8(),
- Abi.fuchsiaX64: Int8(),
- Abi.iosArm: Int8(),
- Abi.iosArm64: Int8(),
- Abi.iosX64: Int8(),
- Abi.linuxArm: Int8(),
- Abi.linuxArm64: Int8(),
- Abi.linuxIA32: Int8(),
- Abi.linuxX64: Int8(),
- Abi.linuxRiscv32: Int8(),
- Abi.linuxRiscv64: Int8(),
- Abi.macosArm64: Int8(),
- Abi.macosX64: Int8(),
- Abi.windowsArm64: Int8(),
- Abi.windowsIA32: Int8(),
- Abi.windowsX64: Int8(),
-})
-class SignedChar extends AbiSpecificInteger {
- const SignedChar();
-}
-
-/// The C `unsigned char` type.
-///
-/// Typically an unsigned 8-bit integer.
-/// For a guaranteed 8-bit integer, use [Uint8] with the C `uint8_t` type.
-/// For a `signed char`, use [Char].
-///
-/// The [UnsignedChar] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint8(),
- Abi.androidArm64: Uint8(),
- Abi.androidIA32: Uint8(),
- Abi.androidX64: Uint8(),
- Abi.fuchsiaArm64: Uint8(),
- Abi.fuchsiaX64: Uint8(),
- Abi.iosArm: Uint8(),
- Abi.iosArm64: Uint8(),
- Abi.iosX64: Uint8(),
- Abi.linuxArm: Uint8(),
- Abi.linuxArm64: Uint8(),
- Abi.linuxIA32: Uint8(),
- Abi.linuxX64: Uint8(),
- Abi.linuxRiscv32: Uint8(),
- Abi.linuxRiscv64: Uint8(),
- Abi.macosArm64: Uint8(),
- Abi.macosX64: Uint8(),
- Abi.windowsArm64: Uint8(),
- Abi.windowsIA32: Uint8(),
- Abi.windowsX64: Uint8(),
-})
-class UnsignedChar extends AbiSpecificInteger {
- const UnsignedChar();
-}
-
-/// The C `short` type.
-///
-/// Typically a signed 16-bit integer.
-/// For a guaranteed 16-bit integer, use [Int16] with the C `int16_t` type.
-/// For an `unsigned short`, use [UnsignedShort].
-///
-/// The [Short] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Int16(),
- Abi.androidArm64: Int16(),
- Abi.androidIA32: Int16(),
- Abi.androidX64: Int16(),
- Abi.fuchsiaArm64: Int16(),
- Abi.fuchsiaX64: Int16(),
- Abi.iosArm: Int16(),
- Abi.iosArm64: Int16(),
- Abi.iosX64: Int16(),
- Abi.linuxArm: Int16(),
- Abi.linuxArm64: Int16(),
- Abi.linuxIA32: Int16(),
- Abi.linuxX64: Int16(),
- Abi.linuxRiscv32: Int16(),
- Abi.linuxRiscv64: Int16(),
- Abi.macosArm64: Int16(),
- Abi.macosX64: Int16(),
- Abi.windowsArm64: Int16(),
- Abi.windowsIA32: Int16(),
- Abi.windowsX64: Int16(),
-})
-class Short extends AbiSpecificInteger {
- const Short();
-}
-
-/// The C `unsigned short` type.
-///
-/// Typically an unsigned 16-bit integer.
-/// For a guaranteed 16-bit integer, use [Uint16] with the C `uint16_t` type.
-/// For a signed `short`, use [Short].
-///
-/// The [UnsignedShort] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint16(),
- Abi.androidArm64: Uint16(),
- Abi.androidIA32: Uint16(),
- Abi.androidX64: Uint16(),
- Abi.fuchsiaArm64: Uint16(),
- Abi.fuchsiaX64: Uint16(),
- Abi.iosArm: Uint16(),
- Abi.iosArm64: Uint16(),
- Abi.iosX64: Uint16(),
- Abi.linuxArm: Uint16(),
- Abi.linuxArm64: Uint16(),
- Abi.linuxIA32: Uint16(),
- Abi.linuxX64: Uint16(),
- Abi.linuxRiscv32: Uint16(),
- Abi.linuxRiscv64: Uint16(),
- Abi.macosArm64: Uint16(),
- Abi.macosX64: Uint16(),
- Abi.windowsArm64: Uint16(),
- Abi.windowsIA32: Uint16(),
- Abi.windowsX64: Uint16(),
-})
-class UnsignedShort extends AbiSpecificInteger {
- const UnsignedShort();
-}
-
-/// The C `int` type.
-///
-/// Typically a signed 32-bit integer.
-/// For a guaranteed 32-bit integer, use [Int32] with the C `int32_t` type.
-/// For an `unsigned int`, use [UnsignedInt].
-///
-/// The [Int] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Int32(),
- Abi.androidArm64: Int32(),
- Abi.androidIA32: Int32(),
- Abi.androidX64: Int32(),
- Abi.fuchsiaArm64: Int32(),
- Abi.fuchsiaX64: Int32(),
- Abi.iosArm: Int32(),
- Abi.iosArm64: Int32(),
- Abi.iosX64: Int32(),
- Abi.linuxArm: Int32(),
- Abi.linuxArm64: Int32(),
- Abi.linuxIA32: Int32(),
- Abi.linuxX64: Int32(),
- Abi.linuxRiscv32: Int32(),
- Abi.linuxRiscv64: Int32(),
- Abi.macosArm64: Int32(),
- Abi.macosX64: Int32(),
- Abi.windowsArm64: Int32(),
- Abi.windowsIA32: Int32(),
- Abi.windowsX64: Int32(),
-})
-class Int extends AbiSpecificInteger {
- const Int();
-}
-
-/// The C `unsigned int` type.
-///
-/// Typically an unsigned 32-bit integer.
-/// For a guaranteed 32-bit integer, use [Uint32] with the C `uint32_t` type.
-/// For a signed `int`, use [Int].
-///
-/// The [UnsignedInt] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint32(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint32(),
- Abi.fuchsiaArm64: Uint32(),
- Abi.fuchsiaX64: Uint32(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint32(),
- Abi.iosX64: Uint32(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint32(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint32(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint32(),
- Abi.macosArm64: Uint32(),
- Abi.macosX64: Uint32(),
- Abi.windowsArm64: Uint32(),
- Abi.windowsIA32: Uint32(),
- Abi.windowsX64: Uint32(),
-})
-class UnsignedInt extends AbiSpecificInteger {
- const UnsignedInt();
-}
-
-/// The C `long int`, aka. `long`, type.
-///
-/// Typically a signed 32- or 64-bit integer.
-/// For a guaranteed 32-bit integer, use [Int32] with the C `int32_t` type.
-/// For a guaranteed 64-bit integer, use [Int64] with the C `int64_t` type.
-/// For an `unsigned long`, use [UnsignedLong].
-///
-/// The [Long] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Int32(),
- Abi.androidArm64: Int64(),
- Abi.androidIA32: Int32(),
- Abi.androidX64: Int64(),
- Abi.fuchsiaArm64: Int64(),
- Abi.fuchsiaX64: Int64(),
- Abi.iosArm: Int32(),
- Abi.iosArm64: Int64(),
- Abi.iosX64: Int64(),
- Abi.linuxArm: Int32(),
- Abi.linuxArm64: Int64(),
- Abi.linuxIA32: Int32(),
- Abi.linuxX64: Int64(),
- Abi.linuxRiscv32: Int32(),
- Abi.linuxRiscv64: Int64(),
- Abi.macosArm64: Int64(),
- Abi.macosX64: Int64(),
- Abi.windowsArm64: Int32(),
- Abi.windowsIA32: Int32(),
- Abi.windowsX64: Int32(),
-})
-class Long extends AbiSpecificInteger {
- const Long();
-}
-
-/// The C `unsigned long int`, aka. `unsigned long`, type.
-///
-/// Typically an unsigned 32- or 64-bit integer.
-/// For a guaranteed 32-bit integer, use [Uint32] with the C `uint32_t` type.
-/// For a guaranteed 64-bit integer, use [Uint64] with the C `uint64_t` type.
-/// For a signed `long`, use [Long].
-///
-/// The [UnsignedLong] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint64(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint64(),
- Abi.fuchsiaArm64: Uint64(),
- Abi.fuchsiaX64: Uint64(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint64(),
- Abi.iosX64: Uint64(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint64(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint64(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint64(),
- Abi.macosArm64: Uint64(),
- Abi.macosX64: Uint64(),
- Abi.windowsArm64: Uint32(),
- Abi.windowsIA32: Uint32(),
- Abi.windowsX64: Uint32(),
-})
-class UnsignedLong extends AbiSpecificInteger {
- const UnsignedLong();
-}
-
-/// The C `long long` type.
-///
-/// Typically a signed 64-bit integer.
-/// For a guaranteed 64-bit integer, use [Int64] with the C `int64_t` type.
-/// For an `unsigned long long`, use [UnsignedLongLong].
-///
-/// The [LongLong] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Int64(),
- Abi.androidArm64: Int64(),
- Abi.androidIA32: Int64(),
- Abi.androidX64: Int64(),
- Abi.fuchsiaArm64: Int64(),
- Abi.fuchsiaX64: Int64(),
- Abi.iosArm: Int64(),
- Abi.iosArm64: Int64(),
- Abi.iosX64: Int64(),
- Abi.linuxArm: Int64(),
- Abi.linuxArm64: Int64(),
- Abi.linuxIA32: Int64(),
- Abi.linuxX64: Int64(),
- Abi.linuxRiscv32: Int64(),
- Abi.linuxRiscv64: Int64(),
- Abi.macosArm64: Int64(),
- Abi.macosX64: Int64(),
- Abi.windowsArm64: Int64(),
- Abi.windowsIA32: Int64(),
- Abi.windowsX64: Int64(),
-})
-class LongLong extends AbiSpecificInteger {
- const LongLong();
-}
-
-/// The C `unsigned long long` type.
-///
-/// Typically an unsigned 64-bit integer.
-/// For a guaranteed 64-bit integer, use [Uint64] with the C `uint64_t` type.
-/// For a signed `long long`, use [LongLong].
-///
-/// The [UnsignedLongLong] type is a native type, and should not be constructed
-/// in Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint64(),
- Abi.androidArm64: Uint64(),
- Abi.androidIA32: Uint64(),
- Abi.androidX64: Uint64(),
- Abi.fuchsiaArm64: Uint64(),
- Abi.fuchsiaX64: Uint64(),
- Abi.iosArm: Uint64(),
- Abi.iosArm64: Uint64(),
- Abi.iosX64: Uint64(),
- Abi.linuxArm: Uint64(),
- Abi.linuxArm64: Uint64(),
- Abi.linuxIA32: Uint64(),
- Abi.linuxX64: Uint64(),
- Abi.linuxRiscv32: Uint64(),
- Abi.linuxRiscv64: Uint64(),
- Abi.macosArm64: Uint64(),
- Abi.macosX64: Uint64(),
- Abi.windowsArm64: Uint64(),
- Abi.windowsIA32: Uint64(),
- Abi.windowsX64: Uint64(),
-})
-class UnsignedLongLong extends AbiSpecificInteger {
- const UnsignedLongLong();
-}
-
-/// The C `intptr_t` type.
-///
-/// The [IntPtr] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Int32(),
- Abi.androidArm64: Int64(),
- Abi.androidIA32: Int32(),
- Abi.androidX64: Int64(),
- Abi.fuchsiaArm64: Int64(),
- Abi.fuchsiaX64: Int64(),
- Abi.iosArm: Int32(),
- Abi.iosArm64: Int64(),
- Abi.iosX64: Int64(),
- Abi.linuxArm: Int32(),
- Abi.linuxArm64: Int64(),
- Abi.linuxIA32: Int32(),
- Abi.linuxX64: Int64(),
- Abi.linuxRiscv32: Int32(),
- Abi.linuxRiscv64: Int64(),
- Abi.macosArm64: Int64(),
- Abi.macosX64: Int64(),
- Abi.windowsArm64: Int64(),
- Abi.windowsIA32: Int32(),
- Abi.windowsX64: Int64(),
-})
-class IntPtr extends AbiSpecificInteger {
- const IntPtr();
-}
-
-/// The C `uintptr_t` type.
-///
-/// The [UintPtr] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint64(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint64(),
- Abi.fuchsiaArm64: Uint64(),
- Abi.fuchsiaX64: Uint64(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint64(),
- Abi.iosX64: Uint64(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint64(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint64(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint64(),
- Abi.macosArm64: Uint64(),
- Abi.macosX64: Uint64(),
- Abi.windowsArm64: Uint64(),
- Abi.windowsIA32: Uint32(),
- Abi.windowsX64: Uint64(),
-})
-class UintPtr extends AbiSpecificInteger {
- const UintPtr();
-}
-
-/// The C `size_t` type.
-///
-/// The [Size] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint64(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint64(),
- Abi.fuchsiaArm64: Uint64(),
- Abi.fuchsiaX64: Uint64(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint64(),
- Abi.iosX64: Uint64(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint64(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint64(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint64(),
- Abi.macosArm64: Uint64(),
- Abi.macosX64: Uint64(),
- Abi.windowsArm64: Uint64(),
- Abi.windowsIA32: Uint32(),
- Abi.windowsX64: Uint64(),
-})
-class Size extends AbiSpecificInteger {
- const Size();
-}
-
-/// The C `wchar_t` type.
-///
-/// The signedness of `wchar_t` is undefined in C. Here, it is exposed as the
-/// defaults on the tested [Abi]s.
-///
-/// The [WChar] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint32(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint32(),
- Abi.fuchsiaArm64: Uint32(),
- Abi.fuchsiaX64: Int32(),
- Abi.iosArm: Int32(),
- Abi.iosArm64: Int32(),
- Abi.iosX64: Int32(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint32(),
- Abi.linuxIA32: Int32(),
- Abi.linuxX64: Int32(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint32(),
- Abi.macosArm64: Int32(),
- Abi.macosX64: Int32(),
- Abi.windowsArm64: Uint16(),
- Abi.windowsIA32: Uint16(),
- Abi.windowsX64: Uint16(),
-})
-class WChar extends AbiSpecificInteger {
- const WChar();
-}
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index 9a7afe2..b1d53a6 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -20,7 +20,6 @@
part 'native_type.dart';
part 'allocation.dart';
part 'annotations.dart';
-part 'c_type.dart';
part 'dynamic_library.dart';
part 'struct.dart';
part 'union.dart';
diff --git a/sdk/lib/ffi/native_type.dart b/sdk/lib/ffi/native_type.dart
index 55a9f6d..dbbea7c 100644
--- a/sdk/lib/ffi/native_type.dart
+++ b/sdk/lib/ffi/native_type.dart
@@ -98,6 +98,36 @@
const Uint64();
}
+/// Represents a native pointer-sized integer in C.
+///
+/// [IntPtr] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Int32(),
+ Abi.androidArm64: Int64(),
+ Abi.androidIA32: Int32(),
+ Abi.androidX64: Int64(),
+ Abi.fuchsiaArm64: Int64(),
+ Abi.fuchsiaX64: Int64(),
+ Abi.iosArm: Int32(),
+ Abi.iosArm64: Int64(),
+ Abi.iosX64: Int64(),
+ Abi.linuxArm: Int32(),
+ Abi.linuxArm64: Int64(),
+ Abi.linuxIA32: Int32(),
+ Abi.linuxX64: Int64(),
+ Abi.linuxRiscv32: Int32(),
+ Abi.linuxRiscv64: Int64(),
+ Abi.macosArm64: Int64(),
+ Abi.macosX64: Int64(),
+ Abi.windowsArm64: Int64(),
+ Abi.windowsIA32: Int32(),
+ Abi.windowsX64: Int64(),
+})
+class IntPtr extends AbiSpecificInteger {
+ const IntPtr();
+}
+
/// Represents a native 32 bit float in C.
///
/// [Float] is not constructible in the Dart code and serves purely as marker
diff --git a/tests/ffi/abi_specific_int_test.dart b/tests/ffi/abi_specific_int_test.dart
index cea45b1..266655c 100644
--- a/tests/ffi/abi_specific_int_test.dart
+++ b/tests/ffi/abi_specific_int_test.dart
@@ -8,6 +8,8 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
+import 'abi_specific_ints.dart';
+
void main() {
testSizeOf();
testStoreLoad();
diff --git a/tests/ffi/abi_specific_ints.dart b/tests/ffi/abi_specific_ints.dart
new file mode 100644
index 0000000..c0cd3f0
--- /dev/null
+++ b/tests/ffi/abi_specific_ints.dart
@@ -0,0 +1,145 @@
+// Copyright (c) 2021, 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:ffi';
+
+// TODO(dacoharkes): These should move to `package:ffi`.
+
+// `int` in C.
+typedef Int = Int32;
+
+// `unsigned int` in C.
+typedef UnsignedInt = Uint32;
+
+// `size_t` in C.
+typedef Size = UintPtr;
+
+// `ssize_t` in C.
+typedef SSize = IntPtr;
+
+// `off_t` in C.
+typedef Off = Long;
+
+/// Represents a native unsigned pointer-sized integer in C.
+///
+/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint64(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint64(),
+ Abi.fuchsiaArm64: Uint64(),
+ Abi.fuchsiaX64: Uint64(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint64(),
+ Abi.iosX64: Uint64(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint64(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint64(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint64(),
+ Abi.macosArm64: Uint64(),
+ Abi.macosX64: Uint64(),
+ Abi.windowsArm64: Uint64(),
+ Abi.windowsIA32: Uint32(),
+ Abi.windowsX64: Uint64(),
+})
+class UintPtr extends AbiSpecificInteger {
+ const UintPtr();
+}
+
+/// `long` in C.
+///
+/// [Long] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Int32(),
+ Abi.androidArm64: Int64(),
+ Abi.androidIA32: Int32(),
+ Abi.androidX64: Int64(),
+ Abi.fuchsiaArm64: Int64(),
+ Abi.fuchsiaX64: Int64(),
+ Abi.iosArm: Int32(),
+ Abi.iosArm64: Int64(),
+ Abi.iosX64: Int64(),
+ Abi.linuxArm: Int32(),
+ Abi.linuxArm64: Int64(),
+ Abi.linuxIA32: Int32(),
+ Abi.linuxX64: Int64(),
+ Abi.linuxRiscv32: Int32(),
+ Abi.linuxRiscv64: Int64(),
+ Abi.macosArm64: Int64(),
+ Abi.macosX64: Int64(),
+ Abi.windowsArm64: Int32(),
+ Abi.windowsIA32: Int32(),
+ Abi.windowsX64: Int32(),
+})
+class Long extends AbiSpecificInteger {
+ const Long();
+}
+
+/// `unsigned long` in C.
+///
+/// [UnsignedLong] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint64(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint64(),
+ Abi.fuchsiaArm64: Uint64(),
+ Abi.fuchsiaX64: Uint64(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint64(),
+ Abi.iosX64: Uint64(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint64(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint64(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint64(),
+ Abi.macosArm64: Uint64(),
+ Abi.macosX64: Uint64(),
+ Abi.windowsArm64: Uint32(),
+ Abi.windowsIA32: Uint32(),
+ Abi.windowsX64: Uint32(),
+})
+class UnsignedLong extends AbiSpecificInteger {
+ const UnsignedLong();
+}
+
+/// `wchar_t` in C.
+///
+/// The signedness of `wchar_t` is undefined in C. Here, it is exposed as an
+/// unsigned integer.
+///
+/// [WChar] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint32(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint32(),
+ Abi.fuchsiaArm64: Uint32(),
+ Abi.fuchsiaX64: Uint32(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint32(),
+ Abi.iosX64: Uint32(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint32(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint32(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint32(),
+ Abi.macosArm64: Uint32(),
+ Abi.macosX64: Uint32(),
+ Abi.windowsArm64: Uint16(),
+ Abi.windowsIA32: Uint16(),
+ Abi.windowsX64: Uint16(),
+})
+class WChar extends AbiSpecificInteger {
+ const WChar();
+}
diff --git a/tests/ffi/c_types_test.dart b/tests/ffi/c_types_test.dart
index 3c2e815..d423c2c 100644
--- a/tests/ffi/c_types_test.dart
+++ b/tests/ffi/c_types_test.dart
@@ -7,11 +7,11 @@
// SharedObjects=ffi_test_functions
import 'dart:ffi';
+
+import "package:expect/expect.dart";
import 'dart:io' show Platform;
-import 'package:expect/expect.dart';
-import 'package:ffi/ffi.dart';
-
+import 'abi_specific_ints.dart';
import 'ffi_test_helpers.dart';
void main() {
@@ -20,162 +20,62 @@
testIntAssumptions();
testSizeTAssumptions();
testLongAssumptions();
+ testOffTAssumptions();
testWCharTAssumptions();
}
class CType {
final int ffiSize;
- final int Function(Pointer)? ffiLoad;
final String modifier;
final String type;
- final String type2;
- CType(this.ffiSize, this.type,
- {this.type2 = '', this.modifier = '', this.ffiLoad});
+ CType(this.ffiSize, this.type, [this.modifier = ""]);
- String get cRepresentation => '$modifier $type $type2'.trim();
+ String get cRepresentation => "$modifier $type".trim();
- String get _getSizeName => 'FfiSizeOf_$modifier\_$type\_$type2';
-
- String get _getSignName => 'FfiSignOf_$modifier\_$type\_$type2';
+ String get _getSizeName => "FfiSizeOf_$modifier\_$type";
int Function() get sizeFunction => ffiTestFunctions
.lookupFunction<Uint64 Function(), int Function()>(_getSizeName);
- int Function() get signFunction => ffiTestFunctions
- .lookupFunction<Uint64 Function(), int Function()>(_getSignName);
-
int get size => sizeFunction();
- bool get isSigned => signFunction() != 0;
-
- bool? get ffiIsSigned {
- final ffiLoad_ = ffiLoad;
- if (ffiLoad_ == null) {
- return null;
- }
- assert(size < 8);
- return using((Arena arena) {
- final p = arena<Int64>()..value = -1;
- return ffiLoad_(p) < 0;
- });
- }
-
String toString() => cRepresentation;
}
-final char = CType(
- sizeOf<Char>(),
- 'char',
- ffiLoad: (Pointer p) => p.cast<Char>().value,
-);
-final uchar = CType(
- sizeOf<UnsignedChar>(),
- 'char',
- modifier: 'unsigned',
- ffiLoad: (Pointer p) => p.cast<UnsignedChar>().value,
-);
-final schar = CType(
- sizeOf<SignedChar>(),
- 'char',
- modifier: 'signed',
- ffiLoad: (Pointer p) => p.cast<SignedChar>().value,
-);
-final short = CType(
- sizeOf<Short>(),
- 'short',
- ffiLoad: (Pointer p) => p.cast<Short>().value,
-);
-final ushort = CType(
- sizeOf<UnsignedShort>(),
- 'short',
- modifier: 'unsigned',
- ffiLoad: (Pointer p) => p.cast<UnsignedShort>().value,
-);
-final int_ = CType(
- sizeOf<Int>(),
- 'int',
- ffiLoad: (Pointer p) => p.cast<Int>().value,
-);
-final uint = CType(
- sizeOf<UnsignedInt>(),
- 'int',
- modifier: 'unsigned',
- ffiLoad: (Pointer p) => p.cast<UnsignedInt>().value,
-);
-final long = CType(
- sizeOf<Long>(),
- 'long',
-);
-final ulong = CType(
- sizeOf<UnsignedLong>(),
- 'long',
- modifier: 'unsigned',
-);
-final longlong = CType(
- sizeOf<LongLong>(),
- 'long',
- type2: 'long',
-);
-final ulonglong = CType(
- sizeOf<UnsignedLongLong>(),
- 'long',
- type2: 'long',
- modifier: 'unsigned',
-);
-final intptr_t = CType(
- sizeOf<IntPtr>(),
- 'intptr_t',
-);
-final uintptr_t = CType(
- sizeOf<UintPtr>(),
- 'uintptr_t',
-);
-final size_t = CType(
- sizeOf<Size>(),
- 'size_t',
-);
-final wchar_t = CType(
- sizeOf<WChar>(),
- 'wchar_t',
- ffiLoad: (Pointer p) => p.cast<WChar>().value,
-);
+final intptr_t = CType(sizeOf<IntPtr>(), "intptr_t");
+final uintptr_t = CType(sizeOf<UintPtr>(), "uintptr_t");
+final int_ = CType(sizeOf<Int>(), "int");
+final uint = CType(sizeOf<UnsignedInt>(), "int", "unsigned");
+final long = CType(sizeOf<Long>(), "long");
+final ulong = CType(sizeOf<UnsignedLong>(), "long", "unsigned");
+final wchar_t = CType(sizeOf<WChar>(), "wchar_t");
+final size_t = CType(sizeOf<Size>(), "size_t");
+final ssize_t = CType(sizeOf<SSize>(), "ssize_t");
+final off_t = CType(sizeOf<Off>(), "off_t");
final cTypes = [
- char,
- uchar,
- schar,
- short,
- ushort,
+ intptr_t,
+ uintptr_t,
int_,
uint,
long,
ulong,
- longlong,
- ulonglong,
- intptr_t,
- uintptr_t,
- size_t,
wchar_t,
+ size_t,
+ ssize_t,
+ off_t
];
void printSizes() {
cTypes.forEach((element) {
- final cName = element.cRepresentation.padRight(20);
- final size = element.size;
- final signed = element.isSigned ? 'signed' : 'unsigned';
- print('$cName: $size $signed');
+ print("${element.cRepresentation.padRight(20)}: ${element.size}");
});
}
void testSizes() {
cTypes.forEach((element) {
- print(element);
Expect.equals(element.size, element.ffiSize);
- final ffiIsSigned = element.ffiIsSigned;
- if (ffiIsSigned != null) {
- Expect.equals(element.isSigned, ffiIsSigned);
- }
});
}
@@ -186,6 +86,7 @@
void testSizeTAssumptions() {
Expect.equals(intptr_t.size, size_t.size);
+ Expect.equals(intptr_t.size, ssize_t.size);
}
void testLongAssumptions() {
@@ -198,9 +99,13 @@
}
}
+void testOffTAssumptions() {
+ Expect.equals(long.size, off_t.size);
+}
+
void testWCharTAssumptions() {
- final bool isSigned = wchar_t.isSigned;
- print('wchar_t isSigned $isSigned');
+ final bool isSigned = wCharMinValue() != 0;
+ print("wchar_t isSigned $isSigned");
if (Platform.isWindows) {
Expect.equals(2, wchar_t.size);
if (isSigned) {
diff --git a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
index 2fbccd1..2276d2f 100644
--- a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
@@ -16,6 +16,9 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
import 'callback_tests_utils.dart';
import 'dylib_utils.dart';
diff --git a/tests/ffi/function_structs_by_value_generated_compounds.dart b/tests/ffi/function_structs_by_value_generated_compounds.dart
index 666ef20..439e9a34 100644
--- a/tests/ffi/function_structs_by_value_generated_compounds.dart
+++ b/tests/ffi/function_structs_by_value_generated_compounds.dart
@@ -7,6 +7,9 @@
import 'dart:ffi';
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
class Struct1ByteBool extends Struct {
@Bool()
external bool a0;
diff --git a/tests/ffi/function_structs_by_value_generated_leaf_test.dart b/tests/ffi/function_structs_by_value_generated_leaf_test.dart
index 7704417..283faad 100644
--- a/tests/ffi/function_structs_by_value_generated_leaf_test.dart
+++ b/tests/ffi/function_structs_by_value_generated_leaf_test.dart
@@ -16,6 +16,9 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
import 'dylib_utils.dart';
// Reuse the compound classes.
diff --git a/tests/ffi/function_structs_by_value_generated_test.dart b/tests/ffi/function_structs_by_value_generated_test.dart
index 897472c..1f4c5d3 100644
--- a/tests/ffi/function_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_structs_by_value_generated_test.dart
@@ -16,6 +16,9 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
import 'dylib_utils.dart';
// Reuse the compound classes.
diff --git a/tests/ffi/generator/structs_by_value_tests_generator.dart b/tests/ffi/generator/structs_by_value_tests_generator.dart
index 3a18095..4c260b9 100644
--- a/tests/ffi/generator/structs_by_value_tests_generator.dart
+++ b/tests/ffi/generator/structs_by_value_tests_generator.dart
@@ -922,6 +922,8 @@
import 'dart:ffi';
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
""";
}
@@ -965,6 +967,8 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
import 'dylib_utils.dart';
@@ -1025,6 +1029,8 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
import 'callback_tests_utils.dart';
diff --git a/tests/ffi_2/abi_specific_int_test.dart b/tests/ffi_2/abi_specific_int_test.dart
index 57daa3f..152c159 100644
--- a/tests/ffi_2/abi_specific_int_test.dart
+++ b/tests/ffi_2/abi_specific_int_test.dart
@@ -10,6 +10,8 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
+import 'abi_specific_ints.dart';
+
void main() {
testSizeOf();
testStoreLoad();
diff --git a/tests/ffi_2/abi_specific_ints.dart b/tests/ffi_2/abi_specific_ints.dart
new file mode 100644
index 0000000..c1d8302
--- /dev/null
+++ b/tests/ffi_2/abi_specific_ints.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2021, 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.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+// TODO(dacoharkes): These should move to `package:ffi`.
+
+/// Represents a native unsigned pointer-sized integer in C.
+///
+/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint64(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint64(),
+ Abi.fuchsiaArm64: Uint64(),
+ Abi.fuchsiaX64: Uint64(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint64(),
+ Abi.iosX64: Uint64(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint64(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint64(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint64(),
+ Abi.macosArm64: Uint64(),
+ Abi.macosX64: Uint64(),
+ Abi.windowsArm64: Uint64(),
+ Abi.windowsIA32: Uint32(),
+ Abi.windowsX64: Uint64(),
+})
+class UintPtr extends AbiSpecificInteger {
+ const UintPtr();
+}
+
+/// `long` in C.
+///
+/// [Long] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Int32(),
+ Abi.androidArm64: Int64(),
+ Abi.androidIA32: Int32(),
+ Abi.androidX64: Int64(),
+ Abi.fuchsiaArm64: Int64(),
+ Abi.fuchsiaX64: Int64(),
+ Abi.iosArm: Int32(),
+ Abi.iosArm64: Int64(),
+ Abi.iosX64: Int64(),
+ Abi.linuxArm: Int32(),
+ Abi.linuxArm64: Int64(),
+ Abi.linuxIA32: Int32(),
+ Abi.linuxX64: Int64(),
+ Abi.linuxRiscv32: Int32(),
+ Abi.linuxRiscv64: Int64(),
+ Abi.macosArm64: Int64(),
+ Abi.macosX64: Int64(),
+ Abi.windowsArm64: Int32(),
+ Abi.windowsIA32: Int32(),
+ Abi.windowsX64: Int32(),
+})
+class Long extends AbiSpecificInteger {
+ const Long();
+}
+
+/// `unsigned long` in C.
+///
+/// [UnsignedLong] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint64(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint64(),
+ Abi.fuchsiaArm64: Uint64(),
+ Abi.fuchsiaX64: Uint64(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint64(),
+ Abi.iosX64: Uint64(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint64(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint64(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint64(),
+ Abi.macosArm64: Uint64(),
+ Abi.macosX64: Uint64(),
+ Abi.windowsArm64: Uint32(),
+ Abi.windowsIA32: Uint32(),
+ Abi.windowsX64: Uint32(),
+})
+class UnsignedLong extends AbiSpecificInteger {
+ const UnsignedLong();
+}
+
+/// `wchar_t` in C.
+///
+/// The signedness of `wchar_t` is undefined in C. Here, it is exposed as an
+/// unsigned integer.
+///
+/// [WChar] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint32(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint32(),
+ Abi.fuchsiaArm64: Uint32(),
+ Abi.fuchsiaX64: Uint32(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint32(),
+ Abi.iosX64: Uint32(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint32(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint32(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint32(),
+ Abi.macosArm64: Uint32(),
+ Abi.macosX64: Uint32(),
+ Abi.windowsArm64: Uint16(),
+ Abi.windowsIA32: Uint16(),
+ Abi.windowsX64: Uint16(),
+})
+class WChar extends AbiSpecificInteger {
+ const WChar();
+}
diff --git a/tests/ffi_2/c_types_test.dart b/tests/ffi_2/c_types_test.dart
index 7a651ce..fa762bd 100644
--- a/tests/ffi_2/c_types_test.dart
+++ b/tests/ffi_2/c_types_test.dart
@@ -9,187 +9,65 @@
// @dart = 2.9
import 'dart:ffi';
+
+import "package:expect/expect.dart";
import 'dart:io' show Platform;
-import 'package:expect/expect.dart';
-import 'package:ffi/ffi.dart';
-
+import 'abi_specific_ints.dart';
import 'ffi_test_helpers.dart';
void main() {
printSizes();
testSizes();
- testIntAssumptions();
- testSizeTAssumptions();
testLongAssumptions();
testWCharTAssumptions();
}
class CType {
final int ffiSize;
- final int Function(Pointer) ffiLoad;
final String modifier;
final String type;
- final String type2;
- CType(this.ffiSize, this.type,
- {this.type2 = '', this.modifier = '', this.ffiLoad});
+ CType(this.ffiSize, this.type, [this.modifier = ""]);
- String get cRepresentation => '$modifier $type $type2'.trim();
+ String get cRepresentation => "$modifier $type".trim();
- String get _getSizeName => 'FfiSizeOf_$modifier\_$type\_$type2';
-
- String get _getSignName => 'FfiSignOf_$modifier\_$type\_$type2';
+ String get _getSizeName => "FfiSizeOf_$modifier\_$type";
int Function() get sizeFunction => ffiTestFunctions
.lookupFunction<Uint64 Function(), int Function()>(_getSizeName);
- int Function() get signFunction => ffiTestFunctions
- .lookupFunction<Uint64 Function(), int Function()>(_getSignName);
-
int get size => sizeFunction();
- bool get isSigned => signFunction() != 0;
-
- bool get ffiIsSigned {
- final ffiLoad_ = ffiLoad;
- if (ffiLoad_ == null) {
- return null;
- }
- assert(size < 8);
- return using((Arena arena) {
- final p = arena<Int64>()..value = -1;
- return ffiLoad_(p) < 0;
- });
- }
-
String toString() => cRepresentation;
}
-final char = CType(
- sizeOf<Char>(),
- 'char',
- ffiLoad: (Pointer p) => p.cast<Char>().value,
-);
-final uchar = CType(
- sizeOf<UnsignedChar>(),
- 'char',
- modifier: 'unsigned',
- ffiLoad: (Pointer p) => p.cast<UnsignedChar>().value,
-);
-final schar = CType(
- sizeOf<SignedChar>(),
- 'char',
- modifier: 'signed',
- ffiLoad: (Pointer p) => p.cast<SignedChar>().value,
-);
-final short = CType(
- sizeOf<Short>(),
- 'short',
- ffiLoad: (Pointer p) => p.cast<Short>().value,
-);
-final ushort = CType(
- sizeOf<UnsignedShort>(),
- 'short',
- modifier: 'unsigned',
- ffiLoad: (Pointer p) => p.cast<UnsignedShort>().value,
-);
-final int_ = CType(
- sizeOf<Int>(),
- 'int',
- ffiLoad: (Pointer p) => p.cast<Int>().value,
-);
-final uint = CType(
- sizeOf<UnsignedInt>(),
- 'int',
- modifier: 'unsigned',
- ffiLoad: (Pointer p) => p.cast<UnsignedInt>().value,
-);
-final long = CType(
- sizeOf<Long>(),
- 'long',
-);
-final ulong = CType(
- sizeOf<UnsignedLong>(),
- 'long',
- modifier: 'unsigned',
-);
-final longlong = CType(
- sizeOf<LongLong>(),
- 'long',
- type2: 'long',
-);
-final ulonglong = CType(
- sizeOf<UnsignedLongLong>(),
- 'long',
- type2: 'long',
- modifier: 'unsigned',
-);
-final intptr_t = CType(
- sizeOf<IntPtr>(),
- 'intptr_t',
-);
-final uintptr_t = CType(
- sizeOf<UintPtr>(),
- 'uintptr_t',
-);
-final size_t = CType(
- sizeOf<Size>(),
- 'size_t',
-);
-final wchar_t = CType(
- sizeOf<WChar>(),
- 'wchar_t',
- ffiLoad: (Pointer p) => p.cast<WChar>().value,
-);
+final intptr_t = CType(sizeOf<IntPtr>(), "intptr_t");
+final uintptr_t = CType(sizeOf<UintPtr>(), "uintptr_t");
+final long = CType(sizeOf<Long>(), "long");
+final ulong = CType(sizeOf<UnsignedLong>(), "long", "unsigned");
+final wchar_t = CType(sizeOf<WChar>(), "wchar_t");
final cTypes = [
- char,
- uchar,
- schar,
- short,
- ushort,
- int_,
- uint,
- long,
- ulong,
- longlong,
- ulonglong,
intptr_t,
uintptr_t,
- size_t,
+ long,
+ ulong,
wchar_t,
];
void printSizes() {
cTypes.forEach((element) {
- final cName = element.cRepresentation.padRight(20);
- final size = element.size;
- final signed = element.isSigned ? 'signed' : 'unsigned';
- print('$cName: $size $signed');
+ print("${element.cRepresentation.padRight(20)}: ${element.size}");
});
}
void testSizes() {
cTypes.forEach((element) {
- print(element);
Expect.equals(element.size, element.ffiSize);
- final ffiIsSigned = element.ffiIsSigned;
- if (ffiIsSigned != null) {
- Expect.equals(element.isSigned, ffiIsSigned);
- }
});
}
-void testIntAssumptions() {
- Expect.equals(4, int_.size);
- Expect.equals(4, uint.size);
-}
-
-void testSizeTAssumptions() {
- Expect.equals(intptr_t.size, size_t.size);
-}
-
void testLongAssumptions() {
if (Platform.isWindows) {
Expect.equals(4, long.size);
@@ -201,8 +79,8 @@
}
void testWCharTAssumptions() {
- final bool isSigned = wchar_t.isSigned;
- print('wchar_t isSigned $isSigned');
+ final bool isSigned = wCharMinValue() != 0;
+ print("wchar_t isSigned $isSigned");
if (Platform.isWindows) {
Expect.equals(2, wchar_t.size);
if (isSigned) {
diff --git a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
index b890cbc..f4100fb 100644
--- a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
@@ -18,6 +18,9 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
import 'callback_tests_utils.dart';
import 'dylib_utils.dart';
diff --git a/tests/ffi_2/function_structs_by_value_generated_compounds.dart b/tests/ffi_2/function_structs_by_value_generated_compounds.dart
index cd3fdf1..6908177 100644
--- a/tests/ffi_2/function_structs_by_value_generated_compounds.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_compounds.dart
@@ -9,6 +9,9 @@
import 'dart:ffi';
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
class Struct1ByteBool extends Struct {
@Bool()
bool a0;
diff --git a/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart b/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart
index 8c01056..7c64296 100644
--- a/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart
@@ -18,6 +18,9 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
import 'dylib_utils.dart';
// Reuse the compound classes.
diff --git a/tests/ffi_2/function_structs_by_value_generated_test.dart b/tests/ffi_2/function_structs_by_value_generated_test.dart
index 6329287..ef24ad2 100644
--- a/tests/ffi_2/function_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_test.dart
@@ -18,6 +18,9 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
import 'dylib_utils.dart';
// Reuse the compound classes.
diff --git a/tools/VERSION b/tools/VERSION
index 58a37e5..9d1057b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 42
+PRERELEASE 43
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index 3d7f966..1b96929 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -328,19 +328,19 @@
DART_CONFIGURATION=ReleaseX64 pkg/vm/tool/precompiler2 --sound-null-safety --packages=.packages hello.dart blob.bin
DART_CONFIGURATION=ReleaseX64 pkg/vm/tool/dart_precompiled_runtime2 --profile-period=10000 blob.bin
out/ReleaseX64/dart --profile-period=10000 --packages=.packages --optimization-counter-threshold=-1 hello.dart
- out/ReleaseX64/dart-sdk/bin/dart2js --packages=.packages --out=out.js -m hello.dart
+ out/ReleaseX64/dart-sdk/bin/dart compile js --packages=.packages --out=out.js -m hello.dart
third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
- out/ReleaseX64/dart-sdk/bin/dart2js --sound-null-safety --packages=.packages --out=out.js -m hello.dart
+ out/ReleaseX64/dart-sdk/bin/dart compile js --sound-null-safety --packages=.packages --out=out.js -m hello.dart
third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
- out/ReleaseX64/dart-sdk/bin/dart2js --packages=.packages --out=out.js -m hello.dart
+ out/ReleaseX64/dart-sdk/bin/dart compile js --packages=.packages --out=out.js -m hello.dart
LD_LIBRARY_PATH=third_party/firefox_jsshell/ third_party/firefox_jsshell/js -f sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js -f out.js
- out/ReleaseX64/dart-sdk/bin/dart2js --sound-null-safety --packages=.packages --out=out.js -m hello.dart
+ out/ReleaseX64/dart-sdk/bin/dart compile js --sound-null-safety --packages=.packages --out=out.js -m hello.dart
LD_LIBRARY_PATH=third_party/firefox_jsshell/ third_party/firefox_jsshell/js -f sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js -f out.js
- out/ReleaseX64/dart-sdk/bin/dart2js --benchmarking-production --packages=.packages --out=out.js -m hello.dart
+ out/ReleaseX64/dart-sdk/bin/dart compile js --benchmarking-production --packages=.packages --out=out.js -m hello.dart
third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
- out/ReleaseX64/dart-sdk/bin/dart2js --sound-null-safety --benchmarking-production --packages=.packages --out=out.js -m hello.dart
+ out/ReleaseX64/dart-sdk/bin/dart compile js --sound-null-safety --benchmarking-production --packages=.packages --out=out.js -m hello.dart
third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
- out/ReleaseX64/dart-sdk/bin/dart2js --benchmarking-x --packages=.packages --out=out.js -m hello.dart
+ out/ReleaseX64/dart-sdk/bin/dart compile js --benchmarking-x --packages=.packages --out=out.js -m hello.dart
third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
out/ReleaseX64/dart-sdk/bin/dart pkg/dev_compiler/tool/ddb -r d8 -b third_party/d8/linux/x64/d8 hello.dart
out/ReleaseX64/dart-sdk/bin/dart pkg/dev_compiler/tool/ddb -r d8 -b third_party/d8/linux/x64/d8 --mode=compile --compile-vm-options=--print-metrics --packages=.packages --out out.js hello.dart