diff --git a/pkg/front_end/lib/src/fasta/builder/extension_builder.dart b/pkg/front_end/lib/src/fasta/builder/extension_builder.dart index 8984604182d..7d63204fc12 100644 --- a/pkg/front_end/lib/src/fasta/builder/extension_builder.dart +++ b/pkg/front_end/lib/src/fasta/builder/extension_builder.dart @@ -93,4 +93,17 @@ abstract class ExtensionBuilder extends DeclarationBuilder { @override String get debugName => "ExtensionBuilder"; + + void buildOutlineExpressions(LibraryBuilder library) { + void build(String ignore, Builder declaration) { + MemberBuilder member = declaration; + member.buildOutlineExpressions(library); + } + + // TODO(johnniwinther): Handle annotations on the extension declaration. + //MetadataBuilder.buildAnnotations( + // isPatch ? origin.extension : extension, + // metadata, library, this, null); + scope.forEach(build); + } } diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart index eeb0bac1bf0..cd2c0bf4599 100644 --- a/pkg/front_end/lib/src/fasta/source/source_loader.dart +++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart @@ -37,6 +37,8 @@ import '../../base/instrumentation.dart' show Instrumentation; import '../blacklisted_classes.dart' show blacklistedCoreClasses; +import '../builder/extension_builder.dart'; + import '../export.dart' show Export; import '../import.dart' show Import; @@ -968,6 +970,8 @@ class SourceLoader extends Loader { Builder declaration = iterator.current; if (declaration is ClassBuilder) { declaration.buildOutlineExpressions(library); + } else if (declaration is ExtensionBuilder) { + declaration.buildOutlineExpressions(library); } else if (declaration is MemberBuilder) { declaration.buildOutlineExpressions(library); } diff --git a/pkg/front_end/testcases/extensions/annotations.dart b/pkg/front_end/testcases/extensions/annotations.dart new file mode 100644 index 00000000000..0e0b623b4c8 --- /dev/null +++ b/pkg/front_end/testcases/extensions/annotations.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2019, 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. + +class Class { + @pragma('dart2js:noInline') + instanceMethod() {} + + @pragma('dart2js:noInline') + static staticMethod() {} +} + +extension Extension on Class { + @pragma('dart2js:noInline') + extensionInstanceMethod() {} + + @pragma('dart2js:noInline') + static extensionStaticMethod() {} +} + +@pragma('dart2js:noInline') +topLevelMethod() {} + +main() {} diff --git a/pkg/front_end/testcases/extensions/annotations.dart.outline.expect b/pkg/front_end/testcases/extensions/annotations.dart.outline.expect new file mode 100644 index 00000000000..1c723318e51 --- /dev/null +++ b/pkg/front_end/testcases/extensions/annotations.dart.outline.expect @@ -0,0 +1,32 @@ +library; +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + synthetic constructor •() → self::Class* + ; + @core::pragma::_("dart2js:noInline") + method instanceMethod() → dynamic + ; + @core::pragma::_("dart2js:noInline") + static method staticMethod() → dynamic + ; +} +extension Extension on self::Class* { + method extensionInstanceMethod = self::Extension|extensionInstanceMethod; + tearoff extensionInstanceMethod = self::Extension|get#extensionInstanceMethod; + static method extensionStaticMethod = self::Extension|extensionStaticMethod; +} +@core::pragma::_("dart2js:noInline") +static method Extension|extensionInstanceMethod(final self::Class* #this) → dynamic + ; +static method Extension|get#extensionInstanceMethod(final self::Class* #this) → () →* dynamic + return () → dynamic => self::Extension|extensionInstanceMethod(#this); +@core::pragma::_("dart2js:noInline") +static method Extension|extensionStaticMethod() → dynamic + ; +@core::pragma::_("dart2js:noInline") +static method topLevelMethod() → dynamic + ; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/extensions/annotations.dart.strong.expect b/pkg/front_end/testcases/extensions/annotations.dart.strong.expect new file mode 100644 index 00000000000..73aac112389 --- /dev/null +++ b/pkg/front_end/testcases/extensions/annotations.dart.strong.expect @@ -0,0 +1,33 @@ +library; +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + synthetic constructor •() → self::Class* + : super core::Object::•() + ; + @#C3 + method instanceMethod() → dynamic {} + @#C3 + static method staticMethod() → dynamic {} +} +extension Extension on self::Class* { + method extensionInstanceMethod = self::Extension|extensionInstanceMethod; + tearoff extensionInstanceMethod = self::Extension|get#extensionInstanceMethod; + static method extensionStaticMethod = self::Extension|extensionStaticMethod; +} +@#C3 +static method Extension|extensionInstanceMethod(final self::Class* #this) → dynamic {} +static method Extension|get#extensionInstanceMethod(final self::Class* #this) → () →* dynamic + return () → dynamic => self::Extension|extensionInstanceMethod(#this); +@#C3 +static method Extension|extensionStaticMethod() → dynamic {} +@#C3 +static method topLevelMethod() → dynamic {} +static method main() → dynamic {} + +constants { + #C1 = "dart2js:noInline" + #C2 = null + #C3 = core::pragma {name:#C1, options:#C2} +} diff --git a/pkg/front_end/testcases/extensions/annotations.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/annotations.dart.strong.transformed.expect new file mode 100644 index 00000000000..73aac112389 --- /dev/null +++ b/pkg/front_end/testcases/extensions/annotations.dart.strong.transformed.expect @@ -0,0 +1,33 @@ +library; +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + synthetic constructor •() → self::Class* + : super core::Object::•() + ; + @#C3 + method instanceMethod() → dynamic {} + @#C3 + static method staticMethod() → dynamic {} +} +extension Extension on self::Class* { + method extensionInstanceMethod = self::Extension|extensionInstanceMethod; + tearoff extensionInstanceMethod = self::Extension|get#extensionInstanceMethod; + static method extensionStaticMethod = self::Extension|extensionStaticMethod; +} +@#C3 +static method Extension|extensionInstanceMethod(final self::Class* #this) → dynamic {} +static method Extension|get#extensionInstanceMethod(final self::Class* #this) → () →* dynamic + return () → dynamic => self::Extension|extensionInstanceMethod(#this); +@#C3 +static method Extension|extensionStaticMethod() → dynamic {} +@#C3 +static method topLevelMethod() → dynamic {} +static method main() → dynamic {} + +constants { + #C1 = "dart2js:noInline" + #C2 = null + #C3 = core::pragma {name:#C1, options:#C2} +} diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status index 678a2f49f03..8d5b8d11f87 100644 --- a/pkg/front_end/testcases/text_serialization.status +++ b/pkg/front_end/testcases/text_serialization.status @@ -9,6 +9,7 @@ all_variances: TextSerializationFailure expression/eval: TextSerializationFailure # Was: Pass expression/main: TextSerializationFailure # Was: Pass +extensions/annotations: TextSerializationFailure extensions/compounds: TextSerializationFailure extensions/conflicts: TextSerializationFailure extensions/direct_instance_access: TextSerializationFailure