Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add macro e2e test #3650

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions _test/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
include: ../analysis/analysis_options.yaml
analyzer:
enable-experiment:
- macros
1 change: 1 addition & 0 deletions _test/build.dart2js.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ targets:
- --enable-asserts
generate_for:
- web/main.dart
- web/macros/main.dart
- web/sub/main.dart
- test/configurable_uri_test.dart
- test/configurable_uri_test.dart.browser_test.dart
Expand Down
1 change: 1 addition & 0 deletions _test/build.post_process.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ targets:
build_web_compilers:entrypoint:
generate_for:
- web/main.dart
- web/macros/main.dart
- web/sub/main.dart
- test/hello_world_test.dart
- test/hello_world_test.dart.browser_test.dart
Expand Down
1 change: 1 addition & 0 deletions _test/build.throws.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ targets:
build_web_compilers:entrypoint:
generate_for:
- web/main.dart
- web/macros/main.dart
- web/sub/main.dart
- test/hello_world_test.dart
- test/hello_world_test.dart.browser_test.dart
Expand Down
1 change: 1 addition & 0 deletions _test/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ targets:
build_web_compilers:entrypoint:
generate_for:
- web/main.dart
- web/macros/main.dart
- web/sub/main.dart
- test/configurable_uri_test.dart.browser_test.dart
- test/hello_world_test.dart.browser_test.dart
Expand Down
27 changes: 27 additions & 0 deletions _test/lib/macros/debug_to_string.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';

// ignore: implementation_imports
import 'package:_fe_analyzer_shared/src/macros/api.dart';

macro class DebugToString implements ClassDeclarationsMacro {
const DebugToString();

@override
Future<void> buildDeclarationsForClass(
ClassDeclaration clazz, MemberDeclarationBuilder builder) async {
final fields = await builder.fieldsOf(clazz);
builder.declareInType(DeclarationCode.fromParts([
'String debugToString() => """\n${clazz.identifier.name} {\n',
for (var field in fields) ...[
' ${field.identifier.name}: \${',
field.identifier,
'}\n',
],
'}""";',
]));
}
}
5 changes: 5 additions & 0 deletions _test/pkgs/provides_builder/build.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
builders:
has_debug_to_string_builder:
import: "package:provides_builder/builders.dart"
builder_factories: ["hasDebugToStringBuilder"]
build_extensions: {".fail": [".hasDebugToString"]}
auto_apply: dependents
some_builder:
import: "package:provides_builder/builders.dart"
builder_factories: ["someBuilder"]
Expand Down
25 changes: 25 additions & 0 deletions _test/pkgs/provides_builder/lib/builders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:async';

import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';

class _SomeBuilder implements Builder {
Expand Down Expand Up @@ -60,9 +61,33 @@ class _ThrowingBuilder extends Builder {
}
}

class _HasDebugToStringBuilder extends Builder {
@override
final buildExtensions = {
'.dart': ['.hasDebugToString']
};

@override
Future<void> build(BuildStep buildStep) async {
final library = await buildStep.inputLibrary;
final buffer = StringBuffer()..writeln('classes:');
for (var element in library.topLevelElements) {
if (element is! ClassElement) continue;
var debugToString = element.getMethod('debugToString') ??
element.augmentation?.getMethod('debugToString');
buffer.writeln(' ${element.name}:');
buffer.writeln(' hasDebugToString: ${debugToString != null}');
}
await buildStep.writeAsString(
buildStep.inputId.changeExtension('.hasDebugToString'),
buffer.toString());
}
}

Builder someBuilder(BuilderOptions options) =>
_SomeBuilder.fromOptions(options);
Builder notApplied(BuilderOptions options) => _SomeBuilder.fromOptions(options);
PostProcessBuilder somePostProcessBuilder(BuilderOptions options) =>
_SomePostProcessBuilder.fromOptions(options);
Builder throwingBuilder(_) => _ThrowingBuilder();
Builder hasDebugToStringBuilder(_) => _HasDebugToStringBuilder();
43 changes: 42 additions & 1 deletion _test/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ name: _test
publish_to: none

environment:
sdk: ^3.0.0
sdk: ^3.3.0-0

dependencies:
_fe_analyzer_shared: any

dev_dependencies:
analyzer: any
Expand All @@ -23,12 +26,20 @@ dev_dependencies:
test_process: ^2.0.0

dependency_overrides:
_fe_analyzer_shared:
path: ../../dart-lang-sdk/sdk/pkg/_fe_analyzer_shared
_js_interop_checks:
path: ../../dart-lang-sdk/sdk/pkg/_js_interop_checks
analyzer:
path: ../../dart-lang-sdk/sdk/pkg/analyzer
build:
path: ../build
build_config:
path: ../build_config
build_daemon:
path: ../build_daemon
build_integration:
path: ../../dart-lang-sdk/sdk/pkg/build_integration
build_modules:
path: ../build_modules
build_resolvers:
Expand All @@ -41,5 +52,35 @@ dependency_overrides:
path: ../build_test
build_web_compilers:
path: ../build_web_compilers
compiler:
path: ../../dart-lang-sdk/sdk/pkg/compiler
dart2js_info:
path: ../../dart-lang-sdk/sdk/pkg/dart2js_info
dart2wasm:
path: ../../dart-lang-sdk/sdk/pkg/dart2wasm
dart_style:
path: ../../dart-lang-sdk/sdk/third_party/pkg/dart_style
dev_compiler:
path: ../../dart-lang-sdk/sdk/pkg/dev_compiler
front_end:
path: ../../dart-lang-sdk/sdk/pkg/front_end
frontend_server:
path: ../../dart-lang-sdk/sdk/pkg/frontend_server
js_ast:
path: ../../dart-lang-sdk/sdk/pkg/js_ast
js_runtime:
path: ../../dart-lang-sdk/sdk/pkg/js_runtime
js_shared:
path: ../../dart-lang-sdk/sdk/pkg/js_shared
kernel:
path: ../../dart-lang-sdk/sdk/pkg/kernel
meta:
path: ../../dart-lang-sdk/sdk/pkg/meta
mmap:
path: ../../dart-lang-sdk/sdk/pkg/mmap
scratch_space:
path: ../scratch_space
vm:
path: ../../dart-lang-sdk/sdk/pkg/vm
wasm_builder:
path: ../../dart-lang-sdk/sdk/pkg/wasm_builder
26 changes: 26 additions & 0 deletions _test/test/macro_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:_test/macros/debug_to_string.dart';

import 'package:test/test.dart';


void main() {
test('macro stuff is generated', () {
expect(User('Jill', 25).debugToString(), equals('''
User {
name: Jill
age: 25
}'''));
});
}

@DebugToString()
class User {
final String name;
final int age;

User(this.name, this.age);
}
14 changes: 14 additions & 0 deletions _test/web/macros/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>

<head>
<title>build integration tests - macros</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script defer src="main.dart.js" type="application/javascript"></script>
</head>

<body>
</body>

</html>
19 changes: 19 additions & 0 deletions _test/web/macros/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:html';

import 'package:_test/macros/debug_to_string.dart';

void main() {
document.body!.text = User('Jill', 25).debugToString();
}

@DebugToString()
class User {
final String name;
final int age;

User(this.name, this.age);
}
19 changes: 19 additions & 0 deletions build_resolvers/lib/src/analysis_driver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert';
import 'dart:io';

import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
Expand All @@ -23,6 +24,24 @@ Future<AnalysisDriverForPackageBuild> analysisDriver(
String sdkSummaryPath,
PackageConfig packageConfig,
) async {
// TODO: Necessary for kernel compilation of macros. Should the analyzer
// provide this implicitly based on its Packages instance?
buildAssetUriResolver.resourceProvider.newFile(
'/.dart_tool/package_config.json',
jsonEncode({
'configVersion': 2,
'packages': [
for (var package in packageConfig.packages)
{
'name': package.name,
'rootUri': 'file:///${package.name}',
'packageUri': 'lib/',
if (package.languageVersion != null)
'languageVersion': '${package.languageVersion!.major}.'
'${package.languageVersion!.minor}',
},
],
}));
return createAnalysisDriver(
analysisOptions: analysisOptions,
packages: _buildAnalyzerPackages(
Expand Down
15 changes: 14 additions & 1 deletion build_resolvers/lib/src/build_asset_uri_resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,20 @@ Set<AssetId> _parseDependencies(String content, AssetId from) => HashSet.of(
.whereType<String>()
.where((uriContent) =>
!_ignoredSchemes.any(Uri.parse(uriContent).isScheme))
.map((content) => AssetId.resolve(Uri.parse(content), from: from)),
.map((content) => AssetId.resolve(Uri.parse(content), from: from))
// TODO: Something better here? We assume anything depending on the
// macro APIs is a macro, and the bootstrap program we create for
// those libraries will require the macro implementations, but there
// is no transitive dependency exposed.
.followedBy(
from == AssetId('_fe_analyzer_shared', 'lib/src/macros/api.dart')
? [
AssetId('_fe_analyzer_shared',
'lib/src/macros/executor/client.dart'),
AssetId('_fe_analyzer_shared',
'lib/src/macros/executor/serialization.dart'),
]
: const []),
);

/// Read the (potentially) cached dependencies of [id] based on parsing the
Expand Down