Version 2.19.0-59.0.dev
Merge commit '409b426cfc7f23afe1035da4e594ddc412b6013d' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c3e6dce..2038914 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -55,11 +55,17 @@
non-final variable.
- fix`use_build_context_synchronously` to handle `await`s in `if` conditions.
+### Core libraries
+
#### `dart:io`
- **Breaking Change** [#49305](https://github.com/dart-lang/sdk/issues/49305):
Disallow negative or hexadecimal content-length headers.
+#### `dart:html`
+
+- Add constructor and `slice` to `SharedArrayBuffer`.
+
## 2.18.0
### Language
diff --git a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
index 01507f9..1f37144 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
@@ -21,17 +21,17 @@
for (var element in unitElement.classes) {
await _computeForClassElement(element);
}
- for (var element in unitElement.enums) {
+ for (var element in unitElement.enums2) {
await _computeForClassElement(element);
}
- for (var element in unitElement.mixins) {
+ for (var element in unitElement.mixins2) {
await _computeForClassElement(element);
}
}
- void _addImplementedClass(ClassElement type) {
- var offset = type.nameOffset;
- var length = type.nameLength;
+ void _addImplementedClass(InterfaceElement element) {
+ var offset = element.nameOffset;
+ var length = element.nameLength;
classes.add(protocol.ImplementedClass(offset, length));
}
@@ -50,9 +50,9 @@
}
}
- Future<void> _computeForClassElement(ClassElement element) async {
+ Future<void> _computeForClassElement(InterfaceElement element) async {
// Always include Object and its members.
- if (element.supertype == null && !element.isMixin) {
+ if (element is ClassElement && element.isDartCoreObject) {
_addImplementedClass(element);
element.accessors.forEach(_addImplementedMember);
element.fields.forEach(_addImplementedMember);
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine.dart b/pkg/analysis_server/lib/src/services/search/search_engine.dart
index 0b88104..850822d 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine.dart
@@ -49,7 +49,7 @@
/// If the [type] has subtypes, return the set of names of members which these
/// subtypes declare, possibly empty. If the [type] does not have subtypes,
/// return `null`.
- Future<Set<String>?> membersOfSubtypes(ClassElement type);
+ Future<Set<String>?> membersOfSubtypes(InterfaceElement type);
/// Returns all subtypes of the given [type].
///
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
index 2eda0d4..9ed9114 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
@@ -15,7 +15,7 @@
SearchEngineImpl(this._drivers);
@override
- Future<Set<String>?> membersOfSubtypes(ClassElement type) async {
+ Future<Set<String>?> membersOfSubtypes(InterfaceElement type) async {
var drivers = _drivers.toList();
var searchedFiles = _createSearchedFiles(drivers);
@@ -24,7 +24,8 @@
var visitedIds = <String>{};
var members = <String>{};
- Future<void> addMembers(ClassElement? type, SubtypeResult? subtype) async {
+ Future<void> addMembers(
+ InterfaceElement? type, SubtypeResult? subtype) async {
if (subtype != null && !visitedIds.add(subtype.id)) {
return;
}
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index f602efc8..17610dd 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -17,6 +17,7 @@
* Deprecated 'XyzDeclaration.name' in AST, use `name2` and `declaredElement` instead.
* Deprecated `Element.enclosingElement2`, use `enclosingElement3` instead. The meaningful change is that
`ConstructorElement.enclosingElement3` returns now `IntefaceElement`, not `ClassElement`.
+* Deprecated `get enums/mixin`, use `get enums2/mixins2` instead.
## 4.3.1
* Fix `identifier` for `LibraryExportElement` and `LibraryImportElement`.
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 3bfb26c..32230ff 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -3504,20 +3504,71 @@
MethodElement? get staticElement;
}
-/// The declaration of a mixin.
+/// The declaration of a mixin augmentation.
///
-/// mixinDeclaration ::=
-/// metadata? 'mixin' name [TypeParameterList]?
+/// mixinAugmentationDeclaration ::=
+/// 'augment' 'mixin' name [TypeParameterList]?
/// [OnClause]? [ImplementsClause]? '{' [ClassMember]* '}'
///
/// Clients may not extend, implement or mix-in this class.
-abstract class MixinDeclaration implements ClassOrMixinDeclaration {
+@experimental
+abstract class MixinAugmentationDeclaration
+ implements MixinOrAugmentationDeclaration {
+ /// The token representing the 'augment' keyword.
+ Token get augmentKeyword;
+
+ @override
+ MixinAugmentationElement? get declaredElement;
+}
+
+/// The declaration of a mixin.
+///
+/// mixinDeclaration ::=
+/// 'mixin' name [TypeParameterList]?
+/// [OnClause]? [ImplementsClause]? '{' [ClassMember]* '}'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class MixinDeclaration
+ implements MixinOrAugmentationDeclaration, ClassOrMixinDeclaration {
+ // TODO(scheglov) Uncomment when removed [ClassOrMixinDeclaration].
+ // @override
+ // MixinElement get declaredElement;
+}
+
+/// Shared interface between [MixinDeclaration] and
+/// [MixinAugmentationDeclaration].
+///
+/// Clients may not extend, implement or mix-in this class.
+@experimental
+abstract class MixinOrAugmentationDeclaration
+ implements NamedCompilationUnitMember {
+ /// Returns the `implements` clause for the mixin, or `null` if the mixin
+ /// does not implement any interfaces.
+ ImplementsClause? get implementsClause;
+
+ // @override
+ // TODO(scheglov) Uncomment when removed [ClassOrMixinDeclaration].
+ // MixinOrAugmentationElement get declaredElement;
+
+ /// Returns the left curly bracket.
+ Token get leftBracket;
+
+ /// Returns the members defined by the mixin.
+ NodeList<ClassMember> get members;
+
/// Return the token representing the 'mixin' keyword.
Token get mixinKeyword;
/// Return the on clause for the mixin, or `null` if the mixin does not have
/// any superclass constraints.
OnClause? get onClause;
+
+ /// Returns the right curly bracket.
+ Token get rightBracket;
+
+ /// Returns the type parameters for the mixin, or `null` if the mixin does
+ /// not have any type parameters.
+ TypeParameterList? get typeParameters;
}
/// A node that declares a single name within the scope of a compilation unit.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 8305498..76ea504 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -273,8 +273,13 @@
/// Return a list containing all of the enums contained in this compilation
/// unit.
+ @Deprecated('Use enums2 instead')
List<ClassElement> get enums;
+ /// Return a list containing all of the enums contained in this compilation
+ /// unit.
+ List<EnumElement> get enums2;
+
/// Return a list containing all of the extensions contained in this
/// compilation unit.
List<ExtensionElement> get extensions;
@@ -288,8 +293,13 @@
/// Return a list containing all of the mixins contained in this compilation
/// unit.
+ @Deprecated('Use mixins2 instead')
List<ClassElement> get mixins;
+ /// Return a list containing all of the mixins contained in this compilation
+ /// unit.
+ List<MixinElement> get mixins2;
+
@override
AnalysisSession get session;
@@ -304,8 +314,14 @@
/// Return the enum defined in this compilation unit that has the given
/// [name], or `null` if this compilation unit does not define an enum with
/// the given name.
+ @Deprecated('Use getEnum2() instead')
ClassElement? getEnum(String name);
+ /// Return the enum defined in this compilation unit that has the given
+ /// [name], or `null` if this compilation unit does not define an enum with
+ /// the given name.
+ EnumElement? getEnum2(String name);
+
/// Return the class defined in this compilation unit that has the given
/// [name], or `null` if this compilation unit does not define a class with
/// the given name.
@@ -1010,6 +1026,8 @@
R? visitConstructorElement(ConstructorElement element);
+ R? visitEnumElement(EnumElement element);
+
@Deprecated('Override visitLibraryExportElement() instead')
R? visitExportElement(ExportElement element);
@@ -1040,6 +1058,8 @@
R? visitMethodElement(MethodElement element);
+ R? visitMixinElement(MixinElement element);
+
R? visitMultiplyDefinedElement(MultiplyDefinedElement element);
R? visitParameterElement(ParameterElement element);
@@ -1394,12 +1414,94 @@
/// library.
InterfaceType get thisType;
+ /// Returns the unnamed constructor declared directly in this class. If the
+ /// class does not declare any constructors, a synthetic default constructor
+ /// will be returned.
+ /// TODO(scheglov) Deprecate and remove it.
+ ConstructorElement? get unnamedConstructor;
+
+ /// Returns the field (synthetic or explicit) defined directly in this
+ /// class or augmentation that has the given [name].
+ /// TODO(scheglov) Deprecate and remove it.
+ FieldElement? getField(String name);
+
+ /// Returns the getter (synthetic or explicit) defined directly in this
+ /// class or augmentation that has the given [name].
+ /// TODO(scheglov) Deprecate and remove it.
+ PropertyAccessorElement? getGetter(String name);
+
+ /// Returns the method defined directly in this class or augmentation that
+ /// has the given [name].
+ /// TODO(scheglov) Deprecate and remove it.
+ MethodElement? getMethod(String name);
+
+ /// Returns the constructor defined directly in this class or augmentation
+ /// that has the given [name].
+ /// TODO(scheglov) Deprecate and remove it.
+ ConstructorElement? getNamedConstructor(String name);
+
+ /// Returns the setter (synthetic or explicit) defined directly in this
+ /// class or augmentation that has the given [name].
+ /// TODO(scheglov) Deprecate and remove it.
+ PropertyAccessorElement? getSetter(String name);
+
/// Create the [InterfaceType] for this element with the given [typeArguments]
/// and [nullabilitySuffix].
InterfaceType instantiate({
required List<DartType> typeArguments,
required NullabilitySuffix nullabilitySuffix,
});
+
+ /// Return the element representing the getter that results from looking up
+ /// the given [getterName] in this class with respect to the given [library],
+ /// or `null` if the look up fails. The behavior of this method is defined by
+ /// the Dart Language Specification in section 16.15.2:
+ /// <blockquote>
+ /// The result of looking up getter (respectively setter) <i>m</i> in class
+ /// <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+ /// instance getter (respectively setter) named <i>m</i> that is accessible to
+ /// <i>L</i>, then that getter (respectively setter) is the result of the
+ /// lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+ /// of the lookup is the result of looking up getter (respectively setter)
+ /// <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+ /// lookup has failed.
+ /// </blockquote>
+ /// TODO(scheglov) Deprecate and remove it.
+ PropertyAccessorElement? lookUpGetter(
+ String getterName, LibraryElement library);
+
+ /// Return the element representing the method that results from looking up
+ /// the given [methodName] in the superclass of this class with respect to the
+ /// given [library], or `null` if the look up fails. The behavior of this
+ /// method is defined by the Dart Language Specification in section 16.15.1:
+ /// <blockquote>
+ /// The result of looking up method <i>m</i> in class <i>C</i> with respect to
+ /// library <i>L</i> is: If <i>C</i> declares an instance method named
+ /// <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+ /// the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+ /// result of the lookup is the result of looking up method <i>m</i> in
+ /// <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+ /// failed.
+ /// </blockquote>
+ /// TODO(scheglov) Deprecate and remove it.
+ MethodElement? lookUpInheritedMethod(
+ String methodName, LibraryElement library);
+
+ /// Return the element representing the method that results from looking up
+ /// the given [methodName] in this class with respect to the given [library],
+ /// or `null` if the look up fails. The behavior of this method is defined by
+ /// the Dart Language Specification in section 16.15.1:
+ /// <blockquote>
+ /// The result of looking up method <i>m</i> in class <i>C</i> with respect to
+ /// library <i>L</i> is: If <i>C</i> declares an instance method named
+ /// <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+ /// the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+ /// result of the lookup is the result of looking up method <i>m</i> in
+ /// <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+ /// failed.
+ /// </blockquote>
+ /// TODO(scheglov) Deprecate and remove it.
+ MethodElement? lookUpMethod(String methodName, LibraryElement library);
}
/// Shared interface between [InterfaceElement] and augmentations.
@@ -2402,37 +2504,6 @@
/// guard against infinite loops.
InterfaceType? get supertype;
- /// Returns the unnamed constructor declared directly in this class. If the
- /// class does not declare any constructors, a synthetic default constructor
- /// will be returned.
- /// TODO(scheglov) Deprecate and remove it.
- ConstructorElement? get unnamedConstructor;
-
- /// Returns the field (synthetic or explicit) defined directly in this
- /// class or augmentation that has the given [name].
- /// TODO(scheglov) Deprecate and remove it.
- FieldElement? getField(String name);
-
- /// Returns the getter (synthetic or explicit) defined directly in this
- /// class or augmentation that has the given [name].
- /// TODO(scheglov) Deprecate and remove it.
- PropertyAccessorElement? getGetter(String name);
-
- /// Returns the method defined directly in this class or augmentation that
- /// has the given [name].
- /// TODO(scheglov) Deprecate and remove it.
- MethodElement? getMethod(String name);
-
- /// Returns the constructor defined directly in this class or augmentation
- /// that has the given [name].
- /// TODO(scheglov) Deprecate and remove it.
- ConstructorElement? getNamedConstructor(String name);
-
- /// Returns the setter (synthetic or explicit) defined directly in this
- /// class or augmentation that has the given [name].
- /// TODO(scheglov) Deprecate and remove it.
- PropertyAccessorElement? getSetter(String name);
-
/// Return the element representing the method that results from looking up
/// the given [methodName] in this class with respect to the given [library],
/// ignoring abstract methods, or `null` if the look up fails. The behavior of
@@ -2452,24 +2523,6 @@
String methodName, LibraryElement library);
/// Return the element representing the getter that results from looking up
- /// the given [getterName] in this class with respect to the given [library],
- /// or `null` if the look up fails. The behavior of this method is defined by
- /// the Dart Language Specification in section 16.15.2:
- /// <blockquote>
- /// The result of looking up getter (respectively setter) <i>m</i> in class
- /// <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
- /// instance getter (respectively setter) named <i>m</i> that is accessible to
- /// <i>L</i>, then that getter (respectively setter) is the result of the
- /// lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
- /// of the lookup is the result of looking up getter (respectively setter)
- /// <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
- /// lookup has failed.
- /// </blockquote>
- /// TODO(scheglov) Deprecate and remove it.
- PropertyAccessorElement? lookUpGetter(
- String getterName, LibraryElement library);
-
- /// Return the element representing the getter that results from looking up
/// the given [getterName] in the superclass of this class with respect to the
/// given [library], ignoring abstract getters, or `null` if the look up
/// fails. The behavior of this method is defined by the Dart Language
@@ -2525,39 +2578,6 @@
PropertyAccessorElement? lookUpInheritedConcreteSetter(
String setterName, LibraryElement library);
- /// Return the element representing the method that results from looking up
- /// the given [methodName] in the superclass of this class with respect to the
- /// given [library], or `null` if the look up fails. The behavior of this
- /// method is defined by the Dart Language Specification in section 16.15.1:
- /// <blockquote>
- /// The result of looking up method <i>m</i> in class <i>C</i> with respect to
- /// library <i>L</i> is: If <i>C</i> declares an instance method named
- /// <i>m</i> that is accessible to <i>L</i>, then that method is the result of
- /// the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
- /// result of the lookup is the result of looking up method <i>m</i> in
- /// <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
- /// failed.
- /// </blockquote>
- /// TODO(scheglov) Deprecate and remove it.
- MethodElement? lookUpInheritedMethod(
- String methodName, LibraryElement library);
-
- /// Return the element representing the method that results from looking up
- /// the given [methodName] in this class with respect to the given [library],
- /// or `null` if the look up fails. The behavior of this method is defined by
- /// the Dart Language Specification in section 16.15.1:
- /// <blockquote>
- /// The result of looking up method <i>m</i> in class <i>C</i> with respect to
- /// library <i>L</i> is: If <i>C</i> declares an instance method named
- /// <i>m</i> that is accessible to <i>L</i>, then that method is the result of
- /// the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
- /// result of the lookup is the result of looking up method <i>m</i> in
- /// <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
- /// failed.
- /// </blockquote>
- /// TODO(scheglov) Deprecate and remove it.
- MethodElement? lookUpMethod(String methodName, LibraryElement library);
-
/// Return the element representing the setter that results from looking up
/// the given [setterName] in this class with respect to the given [library],
/// or `null` if the look up fails. The behavior of this method is defined by
diff --git a/pkg/analyzer/lib/dart/element/visitor.dart b/pkg/analyzer/lib/dart/element/visitor.dart
index 2ec106e..c5de555 100644
--- a/pkg/analyzer/lib/dart/element/visitor.dart
+++ b/pkg/analyzer/lib/dart/element/visitor.dart
@@ -102,6 +102,9 @@
return null;
}
+ @override
+ R? visitEnumElement(EnumElement element) => visitElement(element);
+
R? visitExecutableElement(ExecutableElement element) => visitElement(element);
@Deprecated('Override visitLibraryExportElement() instead')
@@ -169,6 +172,9 @@
visitExecutableElement(element);
@override
+ R? visitMixinElement(MixinElement element) => visitElement(element);
+
+ @override
R? visitMultiplyDefinedElement(MultiplyDefinedElement element) =>
visitElement(element);
@@ -246,6 +252,12 @@
return null;
}
+ @override
+ R? visitEnumElement(EnumElement element) {
+ element.visitChildren(this);
+ return null;
+ }
+
@Deprecated('Override visitLibraryExportElement() instead')
@override
R? visitExportElement(ExportElement element) {
@@ -333,6 +345,12 @@
}
@override
+ R? visitMixinElement(MixinElement element) {
+ element.visitChildren(this);
+ return null;
+ }
+
+ @override
R? visitMultiplyDefinedElement(MultiplyDefinedElement element) {
element.visitChildren(this);
return null;
@@ -409,6 +427,9 @@
@override
R? visitConstructorElement(ConstructorElement element) => null;
+ @override
+ R? visitEnumElement(EnumElement element) => null;
+
@Deprecated('Override visitLibraryExportElement() instead')
@override
R? visitExportElement(ExportElement element) => null;
@@ -457,6 +478,9 @@
R? visitMethodElement(MethodElement element) => null;
@override
+ R? visitMixinElement(MixinElement element) => null;
+
+ @override
R? visitMultiplyDefinedElement(MultiplyDefinedElement element) => null;
@override
@@ -510,6 +534,9 @@
@override
R? visitConstructorElement(ConstructorElement element) => _throw(element);
+ @override
+ R? visitEnumElement(EnumElement element) => _throw(element);
+
@Deprecated('Override visitLibraryExportElement() instead')
@override
R? visitExportElement(ExportElement element) => _throw(element);
@@ -558,6 +585,9 @@
R? visitMethodElement(MethodElement element) => _throw(element);
@override
+ R? visitMixinElement(MixinElement element) => _throw(element);
+
+ @override
R? visitMultiplyDefinedElement(MultiplyDefinedElement element) =>
_throw(element);
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 749d2b6..6a385ff 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -206,7 +206,7 @@
}
}
- void addElements(ClassElement element) {
+ void addElements(InterfaceElement element) {
element.accessors.forEach(addElement);
element.fields.forEach(addElement);
element.methods.forEach(addElement);
@@ -218,8 +218,8 @@
var unitResult = await _driver.getUnitElement(file);
if (unitResult is UnitElementResult) {
unitResult.element.classes.forEach(addElements);
- unitResult.element.enums.forEach(addElements);
- unitResult.element.mixins.forEach(addElements);
+ unitResult.element.enums2.forEach(addElements);
+ unitResult.element.mixins2.forEach(addElements);
}
}
}
@@ -301,7 +301,7 @@
/// Return direct [SubtypeResult]s for either the [type] or [subtype].
Future<List<SubtypeResult>> subtypes(SearchedFiles searchedFiles,
- {ClassElement? type, SubtypeResult? subtype}) async {
+ {InterfaceElement? type, SubtypeResult? subtype}) async {
String name;
String id;
if (type != null) {
@@ -351,10 +351,10 @@
CompilationUnitElement unitElement = unitResult.element;
unitElement.accessors.forEach(addElement);
unitElement.classes.forEach(addElement);
- unitElement.enums.forEach(addElement);
+ unitElement.enums2.forEach(addElement);
unitElement.extensions.forEach(addElement);
unitElement.functions.forEach(addElement);
- unitElement.mixins.forEach(addElement);
+ unitElement.mixins2.forEach(addElement);
unitElement.topLevelVariables.forEach(addElement);
unitElement.typeAliases.forEach(addElement);
}
@@ -881,7 +881,7 @@
}
}
- void _addClasses(FileState file, List<ClassElement> elements) {
+ void _addClasses(FileState file, List<InterfaceElement> elements) {
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
_addDeclaration(file, element, element.name);
@@ -1012,8 +1012,8 @@
var element = elements[i];
_addAccessors(file, element.accessors);
_addClasses(file, element.classes);
- _addClasses(file, element.enums);
- _addClasses(file, element.mixins);
+ _addClasses(file, element.enums2);
+ _addClasses(file, element.mixins2);
_addExtensions(file, element.extensions);
_addFunctions(file, element.functions);
_addTypeAliases(file, element.typeAliases);
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 35324b3..bd5a985 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -226,8 +226,17 @@
///
/// Note that type arguments are only valid if [Feature.generic_metadata] is
/// enabled.
- AnnotationImpl(this.atSign, this._name, this._typeArguments, this.period,
- this._constructorName, this._arguments) {
+ AnnotationImpl({
+ required this.atSign,
+ required IdentifierImpl name,
+ required TypeArgumentListImpl? typeArguments,
+ required this.period,
+ required SimpleIdentifierImpl? constructorName,
+ required ArgumentListImpl? arguments,
+ }) : _name = name,
+ _typeArguments = typeArguments,
+ _constructorName = constructorName,
+ _arguments = arguments {
_becomeParentOf(_name);
_becomeParentOf(_typeArguments);
_becomeParentOf(_constructorName);
@@ -1105,7 +1114,11 @@
/// statements. The [keyword] can be `null` if there is no keyword specified
/// for the block. The [star] can be `null` if there is no star following the
/// keyword (and must be `null` if there is no keyword).
- BlockFunctionBodyImpl(this.keyword, this.star, this._block) {
+ BlockFunctionBodyImpl({
+ required this.keyword,
+ required this.star,
+ required BlockImpl block,
+ }) : _block = block {
_becomeParentOf(_block);
}
@@ -1172,7 +1185,11 @@
Token rightBracket;
/// Initialize a newly created block of code.
- BlockImpl(this.leftBracket, List<Statement> statements, this.rightBracket) {
+ BlockImpl({
+ required this.leftBracket,
+ required List<Statement> statements,
+ required this.rightBracket,
+ }) {
_statements._initialize(this, statements);
}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index 78a09e7..2b88c05 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -15,32 +15,9 @@
final AstFactoryImpl astFactory = AstFactoryImpl();
class AstFactoryImpl {
- AnnotationImpl annotation(
- {required Token atSign,
- required Identifier name,
- TypeArgumentList? typeArguments,
- Token? period,
- SimpleIdentifier? constructorName,
- ArgumentList? arguments}) =>
- AnnotationImpl(
- atSign,
- name as IdentifierImpl,
- typeArguments as TypeArgumentListImpl?,
- period,
- constructorName as SimpleIdentifierImpl?,
- arguments as ArgumentListImpl?);
-
- BlockImpl block(
- Token leftBracket, List<Statement> statements, Token rightBracket) =>
- BlockImpl(leftBracket, statements, rightBracket);
-
CommentImpl blockComment(List<Token> tokens) =>
CommentImpl.createBlockComment(tokens);
- BlockFunctionBodyImpl blockFunctionBody(
- Token? keyword, Token? star, Block block) =>
- BlockFunctionBodyImpl(keyword, star, block as BlockImpl);
-
BooleanLiteralImpl booleanLiteral(Token literal, bool value) =>
BooleanLiteralImpl(literal, value);
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index cd1e068..0c9653e 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1089,7 +1089,7 @@
List<ClassElement> _classes = const [];
/// A list containing all of the enums contained in this compilation unit.
- List<ClassElement> _enums = const [];
+ List<EnumElement> _enums = const [];
/// A list containing all of the extensions contained in this compilation
/// unit.
@@ -1100,7 +1100,7 @@
List<FunctionElement> _functions = const [];
/// A list containing all of the mixins contained in this compilation unit.
- List<ClassElement> _mixins = const [];
+ List<MixinElement> _mixins = const [];
/// A list containing all of the type aliases contained in this compilation
/// unit.
@@ -1171,15 +1171,21 @@
return this;
}
+ @Deprecated('Use enums2 instead')
@override
List<ClassElement> get enums {
+ return _enums.map((e) => e as ClassElement).toList();
+ }
+
+ @override
+ List<EnumElement> get enums2 {
return _enums;
}
/// Set the enums contained in this compilation unit to the given [enums].
- set enums(List<ClassElement> enums) {
- for (ClassElement enumDeclaration in enums) {
- (enumDeclaration as EnumElementImpl).enclosingElement = this;
+ set enums2(List<EnumElement> enums) {
+ for (final element in enums) {
+ (element as EnumElementImpl).enclosingElement = this;
}
_enums = enums;
}
@@ -1227,13 +1233,19 @@
return super.metadata;
}
+ @Deprecated('Use mixins2 instead')
@override
List<ClassElement> get mixins {
+ return _mixins.map((e) => e as ClassElement).toList();
+ }
+
+ @override
+ List<MixinElement> get mixins2 {
return _mixins;
}
/// Set the mixins contained in this compilation unit to the given [mixins].
- set mixins(List<ClassElement> mixins) {
+ set mixins2(List<MixinElement> mixins) {
for (var type in mixins) {
(type as MixinElementImpl).enclosingElement = this;
}
@@ -1286,6 +1298,7 @@
builder.writeCompilationUnitElement(this);
}
+ @Deprecated('Use getEnum2() instead')
@override
ClassElement? getEnum(String enumName) {
for (ClassElement enumDeclaration in enums) {
@@ -1297,6 +1310,16 @@
}
@override
+ EnumElement? getEnum2(String name) {
+ for (final element in enums2) {
+ if (element.name == name) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ @override
ClassElement? getType(String className) {
for (ClassElement class_ in classes) {
if (class_.name == className) {
@@ -1318,10 +1341,10 @@
super.visitChildren(visitor);
safelyVisitChildren(accessors, visitor);
safelyVisitChildren(classes, visitor);
- safelyVisitChildren(enums, visitor);
+ safelyVisitChildren(enums2, visitor);
safelyVisitChildren(extensions, visitor);
safelyVisitChildren(functions, visitor);
- safelyVisitChildren(mixins, visitor);
+ safelyVisitChildren(mixins2, visitor);
safelyVisitChildren(typeAliases, visitor);
safelyVisitChildren(topLevelVariables, visitor);
}
@@ -3038,6 +3061,12 @@
}
@override
+ T? accept<T>(ElementVisitor<T> visitor) {
+ visitor.visitClassElement(this);
+ return visitor.visitEnumElement(this);
+ }
+
+ @override
void appendTo(ElementDisplayStringBuilder builder) {
builder.writeEnumElement(this);
}
@@ -4284,10 +4313,10 @@
for (var unit in units) {
yield* unit.accessors;
yield* unit.classes;
- yield* unit.enums;
+ yield* unit.enums2;
yield* unit.extensions;
yield* unit.functions;
- yield* unit.mixins;
+ yield* unit.mixins2;
yield* unit.topLevelVariables;
yield* unit.typeAliases;
}
@@ -4323,9 +4352,9 @@
..returnType = typeProvider.futureDynamicType;
}
- ClassElement? getEnum(String name) {
+ EnumElement? getEnum(String name) {
for (final unitElement in units) {
- final element = unitElement.getEnum(name);
+ final element = unitElement.getEnum2(name);
if (element != null) {
return element;
}
@@ -4948,6 +4977,12 @@
}
@override
+ T? accept<T>(ElementVisitor<T> visitor) {
+ visitor.visitClassElement(this);
+ return visitor.visitMixinElement(this);
+ }
+
+ @override
void appendTo(ElementDisplayStringBuilder builder) {
builder.writeMixinElement(this);
}
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index ad86fb1..84d0ae4 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -47,18 +47,18 @@
Name(null, FunctionElement.NO_SUCH_METHOD_METHOD_NAME);
/// Cached instance interfaces for [ClassElement].
- final Map<ClassElement, Interface> _interfaces = {};
+ final Map<InterfaceElement, Interface> _interfaces = {};
/// The set of classes that are currently being processed, used to detect
/// self-referencing cycles.
- final Set<ClassElement> _processingClasses = <ClassElement>{};
+ final Set<InterfaceElement> _processingClasses = {};
/// Combine [candidates] into a single signature in the [targetClass].
///
/// If such signature does not exist, return `null`, and if [conflicts] is
/// not `null`, add a new [Conflict] to it.
ExecutableElement? combineSignatures({
- required ClassElement targetClass,
+ required InterfaceElement targetClass,
required List<ExecutableElement> candidates,
required bool doTopMerge,
required Name name,
@@ -132,7 +132,7 @@
/// at all, or because there is no the most specific signature.
///
/// This is equivalent to `getInheritedMap2(type)[name]`.
- ExecutableElement? getInherited2(ClassElement element, Name name) {
+ ExecutableElement? getInherited2(InterfaceElement element, Name name) {
return getInheritedMap2(element)[name];
}
@@ -156,7 +156,8 @@
/// Return signatures of all concrete members that the given [element] inherits
/// from the superclasses and mixins.
- Map<Name, ExecutableElement> getInheritedConcreteMap2(ClassElement element) {
+ Map<Name, ExecutableElement> getInheritedConcreteMap2(
+ InterfaceElement element) {
var interface = getInterface(element);
return interface._superImplemented.last;
}
@@ -185,7 +186,7 @@
/// inherited from the super-interfaces (superclasses, mixins, and
/// interfaces). If there is no most specific signature for a name, the
/// corresponding name will not be included.
- Map<Name, ExecutableElement> getInheritedMap2(ClassElement element) {
+ Map<Name, ExecutableElement> getInheritedMap2(InterfaceElement element) {
var interface = getInterface(element);
var inheritedMap = interface._inheritedMap;
if (inheritedMap == null) {
@@ -202,7 +203,7 @@
/// Return the interface of the given [element]. It might include
/// private members, not necessary accessible in all libraries.
- Interface getInterface(ClassElement element) {
+ Interface getInterface(InterfaceElement element) {
var result = _interfaces[element];
if (result != null) {
return result;
@@ -214,7 +215,7 @@
}
try {
- if (element.isMixin) {
+ if (element is MixinElement) {
result = _getInterfaceMixin(element);
} else {
result = _getInterfaceClass(element);
@@ -262,7 +263,7 @@
/// given number of mixins after it are considered. For example for `1` in
/// `class C extends S with M1, M2, M3`, only `S` and `M1` are considered.
ExecutableElement? getMember2(
- ClassElement element,
+ InterfaceElement element,
Name name, {
bool concrete = false,
int forMixinIndex = -1,
@@ -339,7 +340,7 @@
void _addImplemented(
Map<Name, ExecutableElement> implemented,
- ClassElement element,
+ InterfaceElement element,
) {
var libraryUri = element.librarySource.uri;
@@ -413,7 +414,7 @@
/// such single most specific signature (i.e. no valid override), then add a
/// new conflict description.
List<Conflict> _findMostSpecificFromNamedCandidates(
- ClassElement targetClass,
+ InterfaceElement targetClass,
Map<Name, ExecutableElement> map,
Map<Name, List<ExecutableElement>> namedCandidates, {
required bool doTopMerge,
@@ -445,7 +446,7 @@
return conflicts;
}
- Interface _getInterfaceClass(ClassElement element) {
+ Interface _getInterfaceClass(InterfaceElement element) {
var classLibrary = element.library;
var isNonNullableByDefault = classLibrary.isNonNullableByDefault;
@@ -453,8 +454,16 @@
var superImplemented = <Map<Name, ExecutableElement>>[];
var implemented = <Name, ExecutableElement>{};
+ final InterfaceType? superType;
+ if (element is ClassElement) {
+ superType = element.supertype;
+ } else if (element is EnumElement) {
+ superType = element.supertype;
+ } else {
+ throw UnimplementedError('(${element.runtimeType}) $element');
+ }
+
Interface? superTypeInterface;
- var superType = element.supertype;
if (superType != null) {
var substitution = Substitution.fromInterfaceType(superType);
superTypeInterface = getInterface(superType.element);
@@ -601,7 +610,7 @@
);
var noSuchMethodForwarders = <Name>{};
- if (element.isAbstract) {
+ if (element is ClassElement && element.isAbstract) {
if (superTypeInterface != null) {
noSuchMethodForwarders = superTypeInterface._noSuchMethodForwarders;
}
@@ -644,7 +653,7 @@
);
}
- Interface _getInterfaceMixin(ClassElement element) {
+ Interface _getInterfaceMixin(MixinElement element) {
var classLibrary = element.library;
var isNonNullableByDefault = classLibrary.isNonNullableByDefault;
@@ -709,7 +718,7 @@
/// covariant. If there are no covariant parameters, or parameters to
/// update are already covariant, return the [executable] itself.
ExecutableElement _inheritCovariance(
- ClassElement class_,
+ InterfaceElement class_,
Map<Name, List<ExecutableElement>> namedCandidates,
Name name,
ExecutableElement executable,
@@ -804,7 +813,7 @@
/// signature. This signature always exists.
ExecutableElement _topMerge(
TypeSystemImpl typeSystem,
- ClassElement targetClass,
+ InterfaceElement targetClass,
List<ExecutableElement> validOverrides,
) {
var first = validOverrides[0];
@@ -876,7 +885,9 @@
}
}
- static Map<Name, ExecutableElement> _getTypeMembers(ClassElement element) {
+ static Map<Name, ExecutableElement> _getTypeMembers(
+ InterfaceElement element,
+ ) {
var declared = <Name, ExecutableElement>{};
var libraryUri = element.librarySource.uri;
diff --git a/pkg/analyzer/lib/src/dart/element/scope.dart b/pkg/analyzer/lib/src/dart/element/scope.dart
index 679e477..7e1f1e7 100644
--- a/pkg/analyzer/lib/src/dart/element/scope.dart
+++ b/pkg/analyzer/lib/src/dart/element/scope.dart
@@ -139,11 +139,11 @@
void _addUnitElements(CompilationUnitElement compilationUnit) {
compilationUnit.accessors.forEach(_addPropertyAccessor);
- compilationUnit.enums.forEach(_addGetter);
+ compilationUnit.enums2.forEach(_addGetter);
compilationUnit.extensions.forEach(_addExtension);
compilationUnit.functions.forEach(_addGetter);
compilationUnit.typeAliases.forEach(_addGetter);
- compilationUnit.mixins.forEach(_addGetter);
+ compilationUnit.mixins2.forEach(_addGetter);
compilationUnit.classes.forEach(_addGetter);
}
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index b91660b..9249da9 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -211,7 +211,7 @@
for (ClassElement element in compilationUnit.classes) {
_addIfPublic(definedNames, element);
}
- for (ClassElement element in compilationUnit.enums) {
+ for (final element in compilationUnit.enums2) {
_addIfPublic(definedNames, element);
}
for (ExtensionElement element in compilationUnit.extensions) {
@@ -220,7 +220,7 @@
for (FunctionElement element in compilationUnit.functions) {
_addIfPublic(definedNames, element);
}
- for (ClassElement element in compilationUnit.mixins) {
+ for (final element in compilationUnit.mixins2) {
_addIfPublic(definedNames, element);
}
for (TypeAliasElement element in compilationUnit.typeAliases) {
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index 3afd901..991084b 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -314,7 +314,7 @@
for (ClassElement class_ in element.classes) {
definedGetters[class_.name] = class_;
}
- for (ClassElement type in element.enums) {
+ for (final type in element.enums2) {
definedGetters[type.name] = type;
}
for (FunctionElement function in element.functions) {
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 4523131..f0ab1d9 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -786,7 +786,13 @@
debugEvent("Block");
var statements = popTypedList2<Statement>(count);
- push(ast.block(leftBracket, statements, rightBracket));
+ push(
+ BlockImpl(
+ leftBracket: leftBracket,
+ statements: statements,
+ rightBracket: rightBracket,
+ ),
+ );
}
@override
@@ -796,11 +802,21 @@
debugEvent("BlockFunctionBody");
var statements = popTypedList2<Statement>(count);
- Block block = ast.block(leftBracket, statements, rightBracket);
+ final block = BlockImpl(
+ leftBracket: leftBracket,
+ statements: statements,
+ rightBracket: rightBracket,
+ );
var star = pop() as Token?;
var asyncKeyword = pop() as Token?;
if (parseFunctionBodies) {
- push(ast.blockFunctionBody(asyncKeyword, star, block));
+ push(
+ BlockFunctionBodyImpl(
+ keyword: asyncKeyword,
+ star: star,
+ block: block,
+ ),
+ );
} else {
// TODO(danrubel): Skip the block rather than parsing it.
push(ast.emptyFunctionBody(
@@ -2112,10 +2128,10 @@
assert(optionalOrNull('.', periodBeforeName));
debugEvent("Metadata");
- var invocation = pop() as MethodInvocation?;
+ var invocation = pop() as MethodInvocationImpl?;
var constructorName =
- periodBeforeName != null ? pop() as SimpleIdentifier : null;
- var typeArguments = pop() as TypeArgumentList?;
+ periodBeforeName != null ? pop() as SimpleIdentifierImpl : null;
+ var typeArguments = pop() as TypeArgumentListImpl?;
if (typeArguments != null &&
!_featureSet.isEnabled(Feature.generic_metadata)) {
_reportFeatureNotEnabled(
@@ -2123,14 +2139,17 @@
startToken: typeArguments.beginToken,
);
}
- var name = pop() as Identifier;
- push(ast.annotation(
+ var name = pop() as IdentifierImpl;
+ push(
+ AnnotationImpl(
atSign: atSign,
name: name,
typeArguments: typeArguments,
period: periodBeforeName,
constructorName: constructorName,
- arguments: invocation?.argumentList));
+ arguments: invocation?.argumentList,
+ ),
+ );
}
@override
@@ -3493,10 +3512,20 @@
assert(optional('{', leftBracket));
assert(optional('}', leftBracket.endGroup!));
debugEvent("InvalidFunctionBody");
- Block block = ast.block(leftBracket, [], leftBracket.endGroup!);
+ final block = BlockImpl(
+ leftBracket: leftBracket,
+ statements: [],
+ rightBracket: leftBracket.endGroup!,
+ );
var star = pop() as Token?;
var asyncKeyword = pop() as Token?;
- push(ast.blockFunctionBody(asyncKeyword, star, block));
+ push(
+ BlockFunctionBodyImpl(
+ keyword: asyncKeyword,
+ star: star,
+ block: block,
+ ),
+ );
}
@override
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 5768e84..751f6ca 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -151,7 +151,7 @@
void visitConstructorFieldInitializer(
covariant ConstructorFieldInitializerImpl node) {
var fieldName = node.fieldName;
- ClassElement enclosingClass = _resolver.enclosingClass!;
+ final enclosingClass = _resolver.enclosingClass!;
var fieldElement = enclosingClass.getField(fieldName.name);
fieldName.staticElement = fieldElement;
}
@@ -302,7 +302,7 @@
void visitRedirectingConstructorInvocation(
covariant RedirectingConstructorInvocationImpl node) {
var enclosingClass = _resolver.enclosingClass;
- if (enclosingClass == null) {
+ if (enclosingClass is! ClassElement) {
// TODO(brianwilkerson) Report this error.
return;
}
@@ -336,7 +336,7 @@
void visitSuperConstructorInvocation(
covariant SuperConstructorInvocationImpl node) {
var enclosingClass = _resolver.enclosingClass;
- if (enclosingClass == null) {
+ if (enclosingClass is! ClassElement) {
// TODO(brianwilkerson) Report this error.
return;
}
diff --git a/pkg/analyzer/lib/src/generated/element_walker.dart b/pkg/analyzer/lib/src/generated/element_walker.dart
index aafabade..35f4f3a 100644
--- a/pkg/analyzer/lib/src/generated/element_walker.dart
+++ b/pkg/analyzer/lib/src/generated/element_walker.dart
@@ -19,13 +19,13 @@
int _classIndex = 0;
List<ConstructorElement>? _constructors;
int _constructorIndex = 0;
- List<ClassElement>? _enums;
+ List<EnumElement>? _enums;
int _enumIndex = 0;
List<ExtensionElement>? _extensions;
int _extensionIndex = 0;
List<ExecutableElement>? _functions;
int _functionIndex = 0;
- List<ClassElement>? _mixins;
+ List<MixinElement>? _mixins;
int _mixinIndex = 0;
List<ParameterElement>? _parameters;
int _parameterIndex = 0;
@@ -53,10 +53,10 @@
{this.libraryFilePath, this.unitFilePath})
: _accessors = element.accessors.where(_isNotSynthetic).toList(),
_classes = element.classes,
- _enums = element.enums,
+ _enums = element.enums2,
_extensions = element.extensions,
_functions = element.functions,
- _mixins = element.mixins,
+ _mixins = element.mixins2,
_typedefs = element.typeAliases,
_variables = element.topLevelVariables.where(_isNotSynthetic).toList();
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index ce5307a..f8c23a9 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -143,7 +143,7 @@
/// The class containing the AST nodes being visited,
/// or `null` if we are not in the scope of a class.
- ClassElement? enclosingClass;
+ InterfaceElement? enclosingClass;
/// The element representing the extension containing the AST nodes being
/// visited, or `null` if we are not in the scope of an extension.
@@ -716,7 +716,7 @@
/// Set information about enclosing declarations.
void prepareEnclosingDeclarations({
- ClassElement? enclosingClassElement,
+ InterfaceElement? enclosingClassElement,
ExecutableElement? enclosingExecutableElement,
}) {
enclosingClass = enclosingClassElement;
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index 28b3ace..c50db2b 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -30,22 +30,6 @@
/// rather than 'integerLiteral'.
@internal
class AstTestFactory {
- static AnnotationImpl annotation(Identifier name) => astFactory.annotation(
- atSign: TokenFactory.tokenFromType(TokenType.AT), name: name);
-
- static AnnotationImpl annotation2(Identifier name,
- SimpleIdentifier? constructorName, ArgumentList arguments,
- {TypeArgumentList? typeArguments}) =>
- astFactory.annotation(
- atSign: TokenFactory.tokenFromType(TokenType.AT),
- name: name,
- typeArguments: typeArguments,
- period: constructorName == null
- ? null
- : TokenFactory.tokenFromType(TokenType.PERIOD),
- constructorName: constructorName,
- arguments: arguments);
-
static ArgumentListImpl argumentList(
[List<Expression> arguments = const []]) =>
ArgumentListImpl(
@@ -62,13 +46,6 @@
rightHandSide: rightHandSide as ExpressionImpl,
);
- static BlockFunctionBodyImpl asyncBlockFunctionBody(
- [List<Statement> statements = const []]) =>
- astFactory.blockFunctionBody(
- TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "async"),
- null,
- block(statements));
-
static ExpressionFunctionBodyImpl asyncExpressionFunctionBody(
Expression expression) =>
astFactory.expressionFunctionBody2(
@@ -80,13 +57,6 @@
semicolon: TokenFactory.tokenFromType(TokenType.SEMICOLON),
);
- static BlockFunctionBodyImpl asyncGeneratorBlockFunctionBody(
- [List<Statement> statements = const []]) =>
- astFactory.blockFunctionBody(
- TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "async"),
- TokenFactory.tokenFromType(TokenType.STAR),
- block(statements));
-
static ExpressionFunctionBodyImpl asyncGeneratorExpressionFunctionBody(
Expression expression) =>
astFactory.expressionFunctionBody2(
@@ -98,19 +68,6 @@
semicolon: TokenFactory.tokenFromType(TokenType.SEMICOLON),
);
- static BlockImpl block([List<Statement> statements = const []]) =>
- astFactory.block(
- TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET),
- statements,
- TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
-
- static BlockFunctionBodyImpl blockFunctionBody(Block block) =>
- astFactory.blockFunctionBody(null, null, block);
-
- static BlockFunctionBodyImpl blockFunctionBody2(
- [List<Statement> statements = const []]) =>
- astFactory.blockFunctionBody(null, null, block(statements));
-
static BooleanLiteralImpl booleanLiteral(
bool value) =>
astFactory.booleanLiteral(
@@ -601,9 +558,6 @@
astFactory.functionDeclarationStatement(
functionDeclaration(type, keyword, name, functionExpression));
- static FunctionExpressionImpl functionExpression() => astFactory
- .functionExpression(null, formalParameterList(), blockFunctionBody2());
-
static FunctionExpressionImpl functionExpression2(
FormalParameterList parameters, FunctionBody body) =>
astFactory.functionExpression(null, parameters, body);
@@ -1343,20 +1297,6 @@
TokenFactory.tokenFromType(TokenType.HASH), identifierList);
}
- static BlockFunctionBodyImpl syncBlockFunctionBody(
- [List<Statement> statements = const []]) =>
- astFactory.blockFunctionBody(
- TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "sync"),
- null,
- block(statements));
-
- static BlockFunctionBodyImpl syncGeneratorBlockFunctionBody(
- [List<Statement> statements = const []]) =>
- astFactory.blockFunctionBody(
- TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "sync"),
- TokenFactory.tokenFromType(TokenType.STAR),
- block(statements));
-
static ThisExpressionImpl thisExpression() =>
astFactory.thisExpression(TokenFactory.tokenFromKeyword(Keyword.THIS));
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 9aa5440..a6937a0 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -199,11 +199,11 @@
}
Annotation _readAnnotation() {
- var name = readNode() as Identifier;
- var typeArguments = _readOptionalNode() as TypeArgumentList?;
- var constructorName = _readOptionalNode() as SimpleIdentifier?;
- var arguments = _readOptionalNode() as ArgumentList?;
- var node = astFactory.annotation(
+ var name = readNode() as IdentifierImpl;
+ var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
+ var constructorName = _readOptionalNode() as SimpleIdentifierImpl?;
+ var arguments = _readOptionalNode() as ArgumentListImpl?;
+ var node = AnnotationImpl(
atSign: Tokens.at(),
name: name,
typeArguments: typeArguments,
diff --git a/pkg/analyzer/lib/src/summary2/ast_resolver.dart b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
index e3976e43..a2a72d3 100644
--- a/pkg/analyzer/lib/src/summary2/ast_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
@@ -23,7 +23,7 @@
final FeatureSet _featureSet;
final AnalysisErrorListener _errorListener =
AnalysisErrorListener.NULL_LISTENER;
- final ClassElement? enclosingClassElement;
+ final InterfaceElement? enclosingClassElement;
final ExecutableElement? enclosingExecutableElement;
late final _resolutionVisitor = ResolutionVisitor(
unitElement: _unitElement,
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index 402d18c..70e39fc 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -796,7 +796,7 @@
Reference unitReference,
) {
var count = _reader.readUInt30();
- unitElement.enums = List.generate(count, (_) {
+ unitElement.enums2 = List.generate(count, (_) {
return _readEnumElement(unitElement, unitReference);
});
}
@@ -1141,7 +1141,7 @@
Reference unitReference,
) {
var length = _reader.readUInt30();
- unitElement.mixins = List.generate(length, (index) {
+ unitElement.mixins2 = List.generate(length, (index) {
return _readMixinElement(unitElement, unitReference);
});
}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 833951d..b1a07e3 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -227,7 +227,7 @@
}
}
- void _writeEnumElement(ClassElement element) {
+ void _writeEnumElement(EnumElement element) {
element as EnumElementImpl;
_sink.writeUInt30(_resolutionSink.offset);
_sink._writeStringReference(element.name);
@@ -408,7 +408,7 @@
});
}
- void _writeMixinElement(ClassElement element) {
+ void _writeMixinElement(MixinElement element) {
element as MixinElementImpl;
_sink.writeUInt30(_resolutionSink.offset);
@@ -545,10 +545,10 @@
_sink._writeOptionalStringReference(unitElement.uri);
_sink.writeBool(unitElement.isSynthetic);
_writeList(unitElement.classes, _writeClassElement);
- _writeList(unitElement.enums, _writeEnumElement);
+ _writeList(unitElement.enums2, _writeEnumElement);
_writeList(unitElement.extensions, _writeExtensionElement);
_writeList(unitElement.functions, _writeFunctionElement);
- _writeList(unitElement.mixins, _writeMixinElement);
+ _writeList(unitElement.mixins2, _writeMixinElement);
_writeList(unitElement.typeAliases, _writeTypeAliasElement);
_writeList(
diff --git a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
index cafb22c..56dcd51 100644
--- a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
@@ -18,16 +18,16 @@
void resolve() {
for (var unitElement in _libraryElement.units) {
- var classElements = [
+ var interfaceElements = [
...unitElement.classes,
- ...unitElement.enums,
- ...unitElement.mixins,
+ ...unitElement.enums2,
+ ...unitElement.mixins2,
];
- for (var classElement in classElements) {
- for (var constructorElement in classElement.constructors) {
+ for (var interfaceElement in interfaceElements) {
+ for (var constructorElement in interfaceElement.constructors) {
_constructor(
unitElement as CompilationUnitElementImpl,
- classElement as AbstractClassElementImpl,
+ interfaceElement as AbstractClassElementImpl,
constructorElement as ConstructorElementImpl,
);
}
diff --git a/pkg/analyzer/lib/src/summary2/default_value_resolver.dart b/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
index 8170e42..7e39cb4 100644
--- a/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
@@ -23,14 +23,14 @@
for (var unitElement in _libraryElement.units.impl) {
_UnitContext(unitElement)
..forEach(unitElement.classes, _class)
- ..forEach(unitElement.enums, _class)
+ ..forEach(unitElement.enums2, _class)
..forEach(unitElement.extensions, _extension)
..forEach(unitElement.functions, _executable)
- ..forEach(unitElement.mixins, _class);
+ ..forEach(unitElement.mixins2, _class);
}
}
- void _class(_UnitContext context, ClassElement element) {
+ void _class(_UnitContext context, InterfaceElement element) {
_ClassContext(context, element)
..forEach(element.constructors, _constructor)
..forEach(element.methods, _executable);
@@ -92,7 +92,7 @@
final _UnitContext unitContext;
@override
- final ClassElement classElement;
+ final InterfaceElement classElement;
_ClassContext(this.unitContext, this.classElement);
@@ -103,7 +103,7 @@
}
abstract class _Context {
- ClassElement? get classElement => null;
+ InterfaceElement? get classElement => null;
CompilationUnitElementImpl get unitElement;
}
@@ -120,7 +120,9 @@
});
@override
- ClassElement? get classElement => enclosingContext.classElement;
+ InterfaceElement? get classElement {
+ return enclosingContext.classElement;
+ }
@override
CompilationUnitElementImpl get unitElement {
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 446b4d1..a9bb9a2 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -49,10 +49,10 @@
_visitPropertyFirst<TopLevelVariableDeclaration>(unit.declarations);
_unitElement.accessors = _enclosingContext.propertyAccessors;
_unitElement.classes = _enclosingContext.classes;
- _unitElement.enums = _enclosingContext.enums;
+ _unitElement.enums2 = _enclosingContext.enums;
_unitElement.extensions = _enclosingContext.extensions;
_unitElement.functions = _enclosingContext.functions;
- _unitElement.mixins = _enclosingContext.mixins;
+ _unitElement.mixins2 = _enclosingContext.mixins;
_unitElement.topLevelVariables = _enclosingContext.properties
.whereType<TopLevelVariableElementImpl>()
.toList();
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
index 482012f..3b1d277 100644
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -109,7 +109,7 @@
);
forCorrespondingPairs(
- unitElement.enums, unitInfo.enums, _applyToEnumDeclaration);
+ unitElement.enums2, unitInfo.enums, _applyToEnumDeclaration);
forCorrespondingPairs(unitElement.extensions, unitInfo.extensions,
_applyToExtensionDeclaration);
@@ -117,7 +117,7 @@
forCorrespondingPairs(unitElement.functions, unitInfo.functions,
_applyToFunctionDeclaration);
- forCorrespondingPairs(unitElement.mixins, unitInfo.mixinDeclarations,
+ forCorrespondingPairs(unitElement.mixins2, unitInfo.mixinDeclarations,
_applyToMixinDeclaration);
forCorrespondingPairs(unitElement.topLevelVariables,
@@ -306,7 +306,7 @@
}
void _applyToEnumDeclaration(
- ClassElement element,
+ EnumElement element,
_InfoClassDeclaration info,
) {
element as EnumElementImpl;
@@ -573,7 +573,7 @@
}
void _applyToMixinDeclaration(
- ClassElement element,
+ MixinElement element,
_InfoClassDeclaration info,
) {
element as MixinElementImpl;
diff --git a/pkg/analyzer/lib/src/summary2/not_serializable_nodes.dart b/pkg/analyzer/lib/src/summary2/not_serializable_nodes.dart
index 95e3adf..4c20261 100644
--- a/pkg/analyzer/lib/src/summary2/not_serializable_nodes.dart
+++ b/pkg/analyzer/lib/src/summary2/not_serializable_nodes.dart
@@ -19,13 +19,13 @@
null,
Tokens.closeParenthesis(),
),
- astFactory.blockFunctionBody(
- null,
- null,
- astFactory.block(
- Tokens.openCurlyBracket(),
- [],
- Tokens.closeCurlyBracket(),
+ BlockFunctionBodyImpl(
+ keyword: null,
+ star: null,
+ block: BlockImpl(
+ leftBracket: Tokens.openCurlyBracket(),
+ statements: [],
+ rightBracket: Tokens.closeCurlyBracket(),
),
),
);
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index 660df6f..19ac2d7 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -21,11 +21,11 @@
var node = walker.getNode(element);
nodes.add(node);
}
- for (var element in unit.enums) {
+ for (var element in unit.enums2) {
var node = walker.getNode(element);
nodes.add(node);
}
- for (var element in unit.mixins) {
+ for (var element in unit.mixins2) {
var node = walker.getNode(element);
nodes.add(node);
}
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 1b096ae..a5a5f13 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -42,10 +42,10 @@
_library = builder.element;
for (var unit in _library.units) {
_unitElement = unit as CompilationUnitElementImpl;
- unit.classes.forEach(_resolveClassFields);
- unit.enums.forEach(_resolveClassFields);
+ unit.classes.forEach(_resolveInterfaceFields);
+ unit.enums2.forEach(_resolveInterfaceFields);
unit.extensions.forEach(_resolveExtensionFields);
- unit.mixins.forEach(_resolveClassFields);
+ unit.mixins2.forEach(_resolveInterfaceFields);
_scope = unit.enclosingElement3.scope;
unit.topLevelVariables.forEach(_resolveVariable);
@@ -53,7 +53,15 @@
}
}
- void _resolveClassFields(ClassElement class_) {
+ void _resolveExtensionFields(ExtensionElement extension_) {
+ var node = linker.getLinkingNode(extension_)!;
+ _scope = LinkingNodeContext.get(node).scope;
+ for (var element in extension_.fields) {
+ _resolveVariable(element);
+ }
+ }
+
+ void _resolveInterfaceFields(InterfaceElement class_) {
_enclosingClassHasConstConstructor =
class_.constructors.any((c) => c.isConst);
@@ -65,14 +73,6 @@
_enclosingClassHasConstConstructor = false;
}
- void _resolveExtensionFields(ExtensionElement extension_) {
- var node = linker.getLinkingNode(extension_)!;
- _scope = LinkingNodeContext.get(node).scope;
- for (var element in extension_.fields) {
- _resolveVariable(element);
- }
- }
-
void _resolveVariable(PropertyInducingElement element) {
element as PropertyInducingElementImpl;
@@ -351,10 +351,10 @@
_unitElement = unit as CompilationUnitElementImpl;
unit.classes.forEach(_addClassConstructorFieldFormals);
unit.classes.forEach(_addClassElementFields);
- unit.enums.forEach(_addClassConstructorFieldFormals);
- unit.enums.forEach(_addClassElementFields);
+ unit.enums2.forEach(_addClassConstructorFieldFormals);
+ unit.enums2.forEach(_addClassElementFields);
unit.extensions.forEach(_addExtensionElementFields);
- unit.mixins.forEach(_addClassElementFields);
+ unit.mixins2.forEach(_addClassElementFields);
_scope = unit.enclosingElement3.scope;
for (var element in unit.topLevelVariables) {
@@ -368,7 +368,7 @@
_walker.walkNodes();
}
- void _addClassConstructorFieldFormals(ClassElement class_) {
+ void _addClassConstructorFieldFormals(InterfaceElement class_) {
for (var constructor in class_.constructors) {
constructor as ConstructorElementImpl;
var inferenceNode = _ConstructorInferenceNode(_walker, constructor);
@@ -376,7 +376,7 @@
}
}
- void _addClassElementFields(ClassElement class_) {
+ void _addClassElementFields(InterfaceElement class_) {
var node = _linker.getLinkingNode(class_)!;
_scope = LinkingNodeContext.get(node).scope;
for (var element in class_.fields) {
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index d0b5ca2..ee331d8 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -35,7 +35,7 @@
typeSystem = unit.library.typeSystem as TypeSystemImpl;
isNonNullableByDefault = typeSystem.isNonNullableByDefault;
_inferClasses(unit.classes);
- _inferClasses(unit.mixins);
+ _inferClasses(unit.mixins2);
}
/// Return `true` if the elements corresponding to the [elements] have the
@@ -308,7 +308,7 @@
/// Infer type information for all of the instance members in the given
/// [classElement].
- void _inferClass(ClassElement classElement) {
+ void _inferClass(InterfaceElement classElement) {
if (classElement is ClassElementImpl) {
if (classElement.hasBeenInferred) {
return;
@@ -359,8 +359,8 @@
}
}
- void _inferClasses(List<ClassElement> elements) {
- for (ClassElement element in elements) {
+ void _inferClasses(List<InterfaceElement> elements) {
+ for (final element in elements) {
try {
_inferClass(element);
} on _CycleException {
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element.dart b/pkg/analyzer/lib/src/test_utilities/find_element.dart
index 31801f0..aa8aef9 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_element.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_element.dart
@@ -171,7 +171,7 @@
}
}
- void findInClasses(List<ClassElement> classes) {
+ void findInClasses(List<InterfaceElement> classes) {
for (var class_ in classes) {
findInExecutables(class_.accessors);
findInExecutables(class_.constructors);
@@ -183,8 +183,8 @@
findInExecutables(unitElement.functions);
findInClasses(unitElement.classes);
- findInClasses(unitElement.enums);
- findInClasses(unitElement.mixins);
+ findInClasses(unitElement.enums2);
+ findInClasses(unitElement.mixins2);
for (var extension_ in unitElement.extensions) {
findInExecutables(extension_.accessors);
@@ -264,7 +264,7 @@
}
}
- void findInClass(ClassElement class_) {
+ void findInClass(InterfaceElement class_) {
findIn(class_.typeParameters);
for (var method in class_.methods) {
findIn(method.typeParameters);
@@ -288,7 +288,7 @@
findInClass(class_);
}
- for (var enum_ in unitElement.enums) {
+ for (var enum_ in unitElement.enums2) {
findInClass(enum_);
}
@@ -296,7 +296,7 @@
findIn(extension_.typeParameters);
}
- for (var mixin in unitElement.mixins) {
+ for (var mixin in unitElement.mixins2) {
findInClass(mixin);
}
@@ -342,13 +342,13 @@
throw StateError('Not found: $name');
}
- ClassElement classOrMixin(String name) {
+ InterfaceElement classOrMixin(String name) {
for (var class_ in unitElement.classes) {
if (class_.name == name) {
return class_;
}
}
- for (var mixin in unitElement.mixins) {
+ for (var mixin in unitElement.mixins2) {
if (mixin.name == name) {
return mixin;
}
@@ -378,7 +378,7 @@
}
}
- for (var enum_ in unitElement.enums) {
+ for (var enum_ in unitElement.enums2) {
if (of == null || enum_.name == of) {
findIn(enum_.constructors);
}
@@ -390,8 +390,8 @@
throw StateError('Not found: $name');
}
- ClassElement enum_(String name) {
- for (var enum_ in unitElement.enums) {
+ EnumElement enum_(String name) {
+ for (var enum_ in unitElement.enums2) {
if (enum_.name == name) {
return enum_;
}
@@ -432,8 +432,8 @@
);
}
- ClassElement mixin(String name) {
- for (var mixin in unitElement.mixins) {
+ MixinElement mixin(String name) {
+ for (var mixin in unitElement.mixins2) {
if (mixin.name == name) {
return mixin;
}
@@ -516,7 +516,7 @@
T _findInClassesLike<T extends Element>({
required String? className,
- required T? Function(ClassElement element) fromClass,
+ required T? Function(InterfaceElement element) fromClass,
required T? Function(ExtensionElement element) fromExtension,
}) {
bool filter(Element element) {
@@ -525,8 +525,8 @@
var classes = [
...unitElement.classes,
- ...unitElement.enums,
- ...unitElement.mixins,
+ ...unitElement.enums2,
+ ...unitElement.mixins2,
];
var results = [
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index ef1da68..b4e5a11 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -21251,11 +21251,19 @@
The analyzer produces this diagnostic when a private declaration isn't
referenced in the library that contains the declaration. The following
kinds of declarations are analyzed:
- - Private top-level declarations, such as classes, enums, mixins, typedefs,
- top-level variables, and top-level functions
- - Private static and instance methods
+ - Private top-level declarations and all of their members
+ - Private members of public declarations
- Optional parameters of private functions for which a value is never
- passed, even when the parameter doesn't have a private name
+ passed
+
+ Not all references to an element will mark it as "used":
+ - Assigning a value to a top-level variable (with a standard `=`
+ assignment, or a null-aware `??=` assignment) does not count as using
+ it.
+ - Refering to an element in a doc comment reference does not count as
+ using it.
+ - Refering to a class, mixin, or enum in the right side of an `is`
+ expression does not count as using it.
#### Example
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index a569500..3e6441a 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -11,6 +11,7 @@
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -1504,7 +1505,11 @@
void test_inGetterContext_forEachLoop() {
SimpleIdentifier identifier = AstTestFactory.identifier3("a");
Expression iterator = AstTestFactory.listLiteral();
- Statement body = AstTestFactory.block();
+ Statement body = BlockImpl(
+ leftBracket: Tokens.openCurlyBracket(),
+ statements: [],
+ rightBracket: Tokens.closeCurlyBracket(),
+ );
AstTestFactory.forStatement(
AstTestFactory.forEachPartsWithIdentifier(identifier, iterator), body);
expect(identifier.inGetterContext(), isFalse);
@@ -1544,7 +1549,11 @@
void test_inSetterContext_forEachLoop() {
SimpleIdentifier identifier = AstTestFactory.identifier3("a");
Expression iterator = AstTestFactory.listLiteral();
- Statement body = AstTestFactory.block();
+ Statement body = BlockImpl(
+ leftBracket: Tokens.openCurlyBracket(),
+ statements: [],
+ rightBracket: Tokens.closeCurlyBracket(),
+ );
AstTestFactory.forStatement(
AstTestFactory.forEachPartsWithIdentifier(identifier, iterator), body);
expect(identifier.inSetterContext(), isTrue);
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index b3245ba..dcb1633 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -526,7 +526,7 @@
mixin A {} // 1
class B extends Object with A {} // 2
''');
- ClassElement elementA = findElement.mixin('A');
+ final elementA = findElement.mixin('A');
assertThat(elementA)
..isMixedInAt('A {} // 2', false)
..isReferencedAt('A {} // 2', false);
@@ -546,7 +546,7 @@
mixin A {} // 1
class B = Object with A; // 2
''');
- ClassElement elementA = findElement.mixin('A');
+ final elementA = findElement.mixin('A');
assertThat(elementA).isMixedInAt('A; // 2', false);
}
@@ -622,7 +622,7 @@
MyEnum.a;
}
''');
- ClassElement element = findElement.enum_('MyEnum');
+ final element = findElement.enum_('MyEnum');
assertThat(element)
..isReferencedAt('MyEnum p) {', false)
..isReferencedAt('MyEnum v;', false)
@@ -1169,7 +1169,7 @@
print(MyEnum.B);
}
''');
- ClassElement enumElement = findElement.enum_('MyEnum');
+ final enumElement = findElement.enum_('MyEnum');
assertThat(enumElement.getGetter('values')!)
.isReferencedAt('values);', true);
assertThat(typeProvider.enumElement!.getGetter('index')!)
diff --git a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
index ccfc496..9ed16ce 100644
--- a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
@@ -35,24 +35,30 @@
}
void test_visitAnnotation_constant() {
- _assertSource(
- "@A", AstTestFactory.annotation(AstTestFactory.identifier3("A")));
+ final code = '@A';
+ final findNode = _parseStringToFindNode('''
+$code
+void f() {}
+''');
+ _assertSource(code, findNode.annotation(code));
}
void test_visitAnnotation_constructor() {
- _assertSource(
- "@A.c()",
- AstTestFactory.annotation2(AstTestFactory.identifier3("A"),
- AstTestFactory.identifier3("c"), AstTestFactory.argumentList()));
+ final code = '@A.foo()';
+ final findNode = _parseStringToFindNode('''
+$code
+void f() {}
+''');
+ _assertSource(code, findNode.annotation(code));
}
void test_visitAnnotation_constructor_generic() {
- _assertSource(
- "@A<T>.c()",
- AstTestFactory.annotation2(AstTestFactory.identifier3("A"),
- AstTestFactory.identifier3("c"), AstTestFactory.argumentList(),
- typeArguments: AstTestFactory.typeArgumentList2(
- [AstTestFactory.namedType4('T')])));
+ final code = '@A<int>.foo()';
+ final findNode = _parseStringToFindNode('''
+$code
+void f() {}
+''');
+ _assertSource(code, findNode.annotation(code));
}
void test_visitArgumentList() {
@@ -146,37 +152,51 @@
}
void test_visitBlock_empty() {
- _assertSource("{}", AstTestFactory.block());
+ final code = '{}';
+ final findNode = _parseStringToFindNode('''
+void f() $code
+''');
+ _assertSource(code, findNode.block(code));
}
void test_visitBlock_nonEmpty() {
- _assertSource(
- "{break; break;}",
- AstTestFactory.block([
- AstTestFactory.breakStatement(),
- AstTestFactory.breakStatement()
- ]));
+ final code = '{foo(); bar();}';
+ final findNode = _parseStringToFindNode('''
+void f() $code
+''');
+ _assertSource(code, findNode.block(code));
}
void test_visitBlockFunctionBody_async() {
- _assertSource("async {}", AstTestFactory.asyncBlockFunctionBody());
+ final code = 'async {}';
+ final findNode = _parseStringToFindNode('''
+void f() $code
+''');
+ _assertSource(code, findNode.blockFunctionBody(code));
}
void test_visitBlockFunctionBody_async_star() {
- _assertSource(
- "async* {}", AstTestFactory.asyncGeneratorBlockFunctionBody());
+ final code = 'async* {}';
+ final findNode = _parseStringToFindNode('''
+void f() $code
+''');
+ _assertSource(code, findNode.blockFunctionBody(code));
}
void test_visitBlockFunctionBody_simple() {
- _assertSource("{}", AstTestFactory.blockFunctionBody2());
- }
-
- void test_visitBlockFunctionBody_sync() {
- _assertSource("sync {}", AstTestFactory.syncBlockFunctionBody());
+ final code = '{}';
+ final findNode = _parseStringToFindNode('''
+void f() $code
+''');
+ _assertSource(code, findNode.blockFunctionBody(code));
}
void test_visitBlockFunctionBody_sync_star() {
- _assertSource("sync* {}", AstTestFactory.syncGeneratorBlockFunctionBody());
+ final code = 'sync* {}';
+ final findNode = _parseStringToFindNode('''
+void f() $code
+''');
+ _assertSource(code, findNode.blockFunctionBody(code));
}
void test_visitBooleanLiteral_false() {
@@ -457,11 +477,9 @@
}
void test_visitClassDeclaration_withMetadata() {
- ClassDeclaration declaration =
- AstTestFactory.classDeclaration(null, "C", null, null, null, null);
- declaration.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated class C {}", declaration);
+ final code = '@deprecated class C {}';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.classDeclaration(code));
}
void test_visitClassTypeAlias_abstract() {
@@ -609,16 +627,9 @@
}
void test_visitClassTypeAlias_withMetadata() {
- ClassTypeAlias declaration = AstTestFactory.classTypeAlias(
- "C",
- null,
- null,
- AstTestFactory.namedType4("S"),
- AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
- null);
- declaration.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated class C = S with M1;", declaration);
+ final code = '@deprecated class A = S with M;';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.classTypeAlias(code));
}
void test_visitComment() {
@@ -704,16 +715,13 @@
}
void test_visitConstructorDeclaration_const() {
- _assertSource(
- "const C() {}",
- AstTestFactory.constructorDeclaration2(
- Keyword.CONST,
- null,
- AstTestFactory.identifier3("C"),
- null,
- AstTestFactory.formalParameterList(),
- [],
- AstTestFactory.blockFunctionBody2()));
+ final code = 'const A();';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.constructor(code));
}
void test_visitConstructorDeclaration_external() {
@@ -724,93 +732,63 @@
}
void test_visitConstructorDeclaration_minimal() {
- _assertSource(
- "C() {}",
- AstTestFactory.constructorDeclaration2(
- null,
- null,
- AstTestFactory.identifier3("C"),
- null,
- AstTestFactory.formalParameterList(),
- [],
- AstTestFactory.blockFunctionBody2()));
+ final code = 'A();';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.constructor(code));
}
void test_visitConstructorDeclaration_multipleInitializers() {
- _assertSource(
- "C() : a = b, c = d {}",
- AstTestFactory.constructorDeclaration2(
- null,
- null,
- AstTestFactory.identifier3("C"),
- null,
- AstTestFactory.formalParameterList(),
- [
- AstTestFactory.constructorFieldInitializer(
- false, "a", AstTestFactory.identifier3("b")),
- AstTestFactory.constructorFieldInitializer(
- false, "c", AstTestFactory.identifier3("d"))
- ],
- AstTestFactory.blockFunctionBody2()));
+ final code = 'A() : a = b, c = d {}';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.constructor(code));
}
void test_visitConstructorDeclaration_multipleParameters() {
- _assertSource(
- "C(var a, var b) {}",
- AstTestFactory.constructorDeclaration2(
- null,
- null,
- AstTestFactory.identifier3("C"),
- null,
- AstTestFactory.formalParameterList([
- AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
- AstTestFactory.simpleFormalParameter(Keyword.VAR, "b")
- ]),
- [],
- AstTestFactory.blockFunctionBody2()));
+ final code = 'A(int a, double b);';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.constructor(code));
}
void test_visitConstructorDeclaration_named() {
- _assertSource(
- "C.m() {}",
- AstTestFactory.constructorDeclaration2(
- null,
- null,
- AstTestFactory.identifier3("C"),
- "m",
- AstTestFactory.formalParameterList(),
- [],
- AstTestFactory.blockFunctionBody2()));
+ final code = 'A.foo();';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.constructor(code));
}
void test_visitConstructorDeclaration_singleInitializer() {
- _assertSource(
- "C() : a = b {}",
- AstTestFactory.constructorDeclaration2(
- null,
- null,
- AstTestFactory.identifier3("C"),
- null,
- AstTestFactory.formalParameterList(),
- [
- AstTestFactory.constructorFieldInitializer(
- false, "a", AstTestFactory.identifier3("b"))
- ],
- AstTestFactory.blockFunctionBody2()));
+ final code = 'A() : a = b;';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.constructor(code));
}
void test_visitConstructorDeclaration_withMetadata() {
- ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
- null,
- null,
- AstTestFactory.identifier3("C"),
- null,
- AstTestFactory.formalParameterList(),
- [],
- AstTestFactory.blockFunctionBody2());
- declaration.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated C() {}", declaration);
+ final code = '@deprecated C() {}';
+ final findNode = _parseStringToFindNode('''
+class C {
+ $code
+}
+''');
+ _assertSource(code, findNode.constructor(code));
}
void test_visitConstructorFieldInitializer_withoutThis() {
@@ -856,11 +834,11 @@
}
void test_visitDefaultFormalParameter_annotation() {
- DefaultFormalParameter parameter = AstTestFactory.positionalFormalParameter(
- AstTestFactory.simpleFormalParameter3("p"), AstTestFactory.integer(0));
- parameter.metadata
- .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
- _assertSource('@A p = 0', parameter);
+ final code = '@deprecated p = 0';
+ final findNode = _parseStringToFindNode('''
+void f([$code]) {}
+''');
+ _assertSource(code, findNode.defaultParameter(code));
}
void test_visitDefaultFormalParameter_named_noValue() {
@@ -894,10 +872,13 @@
}
void test_visitDoStatement() {
- _assertSource(
- "do {} while (c);",
- AstTestFactory.doStatement(
- AstTestFactory.block(), AstTestFactory.identifier3("c")));
+ final code = 'do {} while (true);';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.doStatement(code));
}
void test_visitDoubleLiteral() {
@@ -1032,10 +1013,9 @@
}
void test_visitExportDirective_withMetadata() {
- ExportDirective directive = AstTestFactory.exportDirective2("a.dart");
- directive.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated export 'a.dart';", directive);
+ final code = '@deprecated export "a.dart";';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.export(code));
}
void test_visitExpressionFunctionBody_async() {
@@ -1427,18 +1407,24 @@
}
void test_visitFieldDeclaration_withMetadata() {
- FieldDeclaration declaration = AstTestFactory.fieldDeclaration2(
- false, Keyword.VAR, [AstTestFactory.variableDeclaration("a")]);
- declaration.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated var a;", declaration);
+ final code = '@deprecated var a;';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.fieldDeclaration(code));
}
void test_visitFieldFormalParameter_annotation() {
- FieldFormalParameter parameter = AstTestFactory.fieldFormalParameter2('f');
- parameter.metadata
- .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
- _assertSource('@A this.f', parameter);
+ final code = '@deprecated this.foo';
+ final findNode = _parseStringToFindNode('''
+class A {
+ final int foo;
+ A($code);
+}
+''');
+ _assertSource(code, findNode.fieldFormalParameter(code));
}
void test_visitFieldFormalParameter_functionTyped() {
@@ -1511,42 +1497,33 @@
}
void test_visitForEachStatement_declared() {
- _assertSource(
- "for (var a in b) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forEachPartsWithDeclaration(
- AstTestFactory.declaredIdentifier3("a"),
- AstTestFactory.identifier3("b")),
- AstTestFactory.block()));
+ final code = 'for (final a in b) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForEachStatement_variable() {
- _assertSource(
- "for (a in b) {}",
- astFactory.forStatement(
- forKeyword: TokenFactory.tokenFromKeyword(Keyword.FOR),
- leftParenthesis: TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
- forLoopParts: astFactory.forEachPartsWithIdentifier(
- identifier: AstTestFactory.identifier3("a"),
- inKeyword: TokenFactory.tokenFromKeyword(Keyword.IN),
- iterable: AstTestFactory.identifier3("b")),
- rightParenthesis: TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
- body: AstTestFactory.block()));
+ final code = 'for (a in b) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForEachStatement_variable_await() {
- _assertSource(
- "await for (a in b) {}",
- astFactory.forStatement(
- awaitKeyword: TokenFactory.tokenFromString("await"),
- forKeyword: TokenFactory.tokenFromKeyword(Keyword.FOR),
- leftParenthesis: TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
- forLoopParts: astFactory.forEachPartsWithIdentifier(
- identifier: AstTestFactory.identifier3("a"),
- inKeyword: TokenFactory.tokenFromKeyword(Keyword.IN),
- iterable: AstTestFactory.identifier3("b")),
- rightParenthesis: TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
- body: AstTestFactory.block()));
+ final code = 'await for (final a in b) {}';
+ final findNode = _parseStringToFindNode('''
+void f() async {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForElement() {
@@ -1792,122 +1769,113 @@
}
void test_visitForStatement_c() {
- _assertSource(
- "for (; c;) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithExpression(
- null, AstTestFactory.identifier3("c"), null),
- AstTestFactory.block()));
+ final code = 'for (; c;) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForStatement_cu() {
- _assertSource(
- "for (; c; u) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithExpression(
- null,
- AstTestFactory.identifier3("c"),
- [AstTestFactory.identifier3("u")]),
- AstTestFactory.block()));
+ final code = 'for (; c; u) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForStatement_e() {
- _assertSource(
- "for (e;;) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithExpression(
- AstTestFactory.identifier3("e"), null, null),
- AstTestFactory.block()));
+ final code = 'for (e;;) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForStatement_ec() {
- _assertSource(
- "for (e; c;) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithExpression(
- AstTestFactory.identifier3("e"),
- AstTestFactory.identifier3("c"),
- null),
- AstTestFactory.block()));
+ final code = 'for (e; c;) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForStatement_ecu() {
- _assertSource(
- "for (e; c; u) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithExpression(
- AstTestFactory.identifier3("e"),
- AstTestFactory.identifier3("c"),
- [AstTestFactory.identifier3("u")]),
- AstTestFactory.block()));
+ final code = 'for (e; c; u) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForStatement_eu() {
- _assertSource(
- "for (e;; u) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithExpression(
- AstTestFactory.identifier3("e"),
- null,
- [AstTestFactory.identifier3("u")]),
- AstTestFactory.block()));
+ final code = 'for (e;; u) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForStatement_i() {
- _assertSource(
- "for (var i;;) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithDeclarations(
- AstTestFactory.variableDeclarationList2(
- Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
- null,
- null),
- AstTestFactory.block()));
+ final code = 'for (var i;;) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForStatement_ic() {
- _assertSource(
- "for (var i; c;) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithDeclarations(
- AstTestFactory.variableDeclarationList2(
- Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
- AstTestFactory.identifier3("c"),
- null),
- AstTestFactory.block()));
+ final code = 'for (var i; c;) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForStatement_icu() {
- _assertSource(
- "for (var i; c; u) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithDeclarations(
- AstTestFactory.variableDeclarationList2(
- Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
- AstTestFactory.identifier3("c"),
- [AstTestFactory.identifier3("u")]),
- AstTestFactory.block()));
+ final code = 'for (var i; c; u) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForStatement_iu() {
- _assertSource(
- "for (var i;; u) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithDeclarations(
- AstTestFactory.variableDeclarationList2(
- Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
- null,
- [AstTestFactory.identifier3("u")]),
- AstTestFactory.block()));
+ final code = 'for (var i;; u) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitForStatement_u() {
- _assertSource(
- "for (;; u) {}",
- AstTestFactory.forStatement(
- AstTestFactory.forPartsWithExpression(
- null, null, [AstTestFactory.identifier3("u")]),
- AstTestFactory.block()));
+ final code = 'for (;; u) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.forStatement(code));
}
void test_visitFunctionDeclaration_external() {
@@ -1923,107 +1891,79 @@
}
void test_visitFunctionDeclaration_getter() {
- _assertSource(
- "get f() {}",
- AstTestFactory.functionDeclaration(
- null, Keyword.GET, "f", AstTestFactory.functionExpression()));
+ final code = 'get foo {}';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.functionDeclaration(code));
}
void test_visitFunctionDeclaration_local_blockBody() {
- FunctionDeclaration f = AstTestFactory.functionDeclaration(
- null, null, "f", AstTestFactory.functionExpression());
- FunctionDeclarationStatement fStatement =
- astFactory.functionDeclarationStatement(f);
- _assertSource(
- "main() {f() {} 42;}",
- AstTestFactory.functionDeclaration(
- null,
- null,
- "main",
- AstTestFactory.functionExpression2(
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2([
- fStatement,
- AstTestFactory.expressionStatement(AstTestFactory.integer(42))
- ]))));
+ final code = 'void foo() {}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ $code
+}
+''');
+ _assertSource(code, findNode.functionDeclaration(code));
}
void test_visitFunctionDeclaration_local_expressionBody() {
- FunctionDeclaration f = AstTestFactory.functionDeclaration(
- null,
- null,
- "f",
- AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
- AstTestFactory.expressionFunctionBody(AstTestFactory.integer(1))));
- FunctionDeclarationStatement fStatement =
- astFactory.functionDeclarationStatement(f);
- _assertSource(
- "main() {f() => 1; 2;}",
- AstTestFactory.functionDeclaration(
- null,
- null,
- "main",
- AstTestFactory.functionExpression2(
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2([
- fStatement,
- AstTestFactory.expressionStatement(AstTestFactory.integer(2))
- ]))));
+ final code = 'int foo() => 42;';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ $code
+}
+''');
+ _assertSource(code, findNode.functionDeclaration(code));
}
void test_visitFunctionDeclaration_normal() {
- _assertSource(
- "f() {}",
- AstTestFactory.functionDeclaration(
- null, null, "f", AstTestFactory.functionExpression()));
+ final code = 'void foo() {}';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.functionDeclaration(code));
}
void test_visitFunctionDeclaration_setter() {
- _assertSource(
- "set f() {}",
- AstTestFactory.functionDeclaration(
- null, Keyword.SET, "f", AstTestFactory.functionExpression()));
+ final code = 'set foo(int _) {}';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.functionDeclaration(code));
}
void test_visitFunctionDeclaration_typeParameters() {
- _assertSource(
- "f<E>() {}",
- AstTestFactory.functionDeclaration(
- null,
- null,
- "f",
- AstTestFactory.functionExpression3(
- AstTestFactory.typeParameterList2(['E']),
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2())));
+ final code = 'void foo<T>() {}';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.functionDeclaration(code));
}
void test_visitFunctionDeclaration_withMetadata() {
- FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
- null, null, "f", AstTestFactory.functionExpression());
- declaration.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated f() {}", declaration);
+ final code = '@deprecated void f() {}';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.functionDeclaration(code));
}
void test_visitFunctionDeclarationStatement() {
- _assertSource(
- "f() {}",
- AstTestFactory.functionDeclarationStatement(
- null, null, "f", AstTestFactory.functionExpression()));
+ final code = 'void foo() {}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ $code
+}
+''');
+ _assertSource(code, findNode.functionDeclaration(code));
}
void test_visitFunctionExpression() {
- _assertSource("() {}", AstTestFactory.functionExpression());
+ final code = '() {}';
+ final findNode = _parseStringToFindNode('''
+final f = $code;
+''');
+ _assertSource(code, findNode.functionExpression(code));
}
void test_visitFunctionExpression_typeParameters() {
- _assertSource(
- "<E>() {}",
- AstTestFactory.functionExpression3(
- AstTestFactory.typeParameterList2(['E']),
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2()));
+ final code = '<T>() {}';
+ final findNode = _parseStringToFindNode('''
+final f = $code;
+''');
+ _assertSource(code, findNode.functionExpression(code));
}
void test_visitFunctionExpressionInvocation_minimal() {
@@ -2059,22 +1999,17 @@
}
void test_visitFunctionTypeAlias_withMetadata() {
- FunctionTypeAlias declaration = AstTestFactory.typeAlias(
- AstTestFactory.namedType4("A"),
- "F",
- null,
- AstTestFactory.formalParameterList());
- declaration.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated typedef A F();", declaration);
+ final code = '@deprecated typedef void F();';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.functionTypeAlias(code));
}
void test_visitFunctionTypedFormalParameter_annotation() {
- FunctionTypedFormalParameter parameter =
- AstTestFactory.functionTypedFormalParameter(null, "f");
- parameter.metadata
- .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
- _assertSource('@A f()', parameter);
+ final code = '@deprecated g()';
+ final findNode = _parseStringToFindNode('''
+void f($code) {}
+''');
+ _assertSource(code, findNode.functionTypedFormalParameter(code));
}
void test_visitFunctionTypedFormalParameter_noType() {
@@ -2182,17 +2117,23 @@
}
void test_visitIfStatement_withElse() {
- _assertSource(
- "if (c) {} else {}",
- AstTestFactory.ifStatement2(AstTestFactory.identifier3("c"),
- AstTestFactory.block(), AstTestFactory.block()));
+ final code = 'if (c) {} else {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.ifStatement(code));
}
void test_visitIfStatement_withoutElse() {
- _assertSource(
- "if (c) {}",
- AstTestFactory.ifStatement(
- AstTestFactory.identifier3("c"), AstTestFactory.block()));
+ final code = 'if (c) {}';
+ final findNode = _parseStringToFindNode('''
+void f () {
+ $code
+}
+''');
+ _assertSource(code, findNode.ifStatement(code));
}
void test_visitImplementsClause_multiple() {
@@ -2272,10 +2213,9 @@
}
void test_visitImportDirective_withMetadata() {
- ImportDirective directive = AstTestFactory.importDirective3("a.dart", null);
- directive.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated import 'a.dart';", directive);
+ final code = '@deprecated import "a.dart";';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.import(code));
}
void test_visitImportHideCombinator_multiple() {
@@ -2404,10 +2344,9 @@
}
void test_visitLibraryDirective_withMetadata() {
- LibraryDirective directive = AstTestFactory.libraryDirective2("l");
- directive.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated library l;", directive);
+ final code = '@deprecated library my;';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.library(code));
}
void test_visitLibraryIdentifier_multiple() {
@@ -2569,179 +2508,133 @@
}
void test_visitMethodDeclaration_getter() {
- _assertSource(
- "get m {}",
- AstTestFactory.methodDeclaration2(
- null,
- null,
- Keyword.GET,
- null,
- AstTestFactory.identifier3("m"),
- null,
- AstTestFactory.blockFunctionBody2()));
+ final code = 'get foo => 0;';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_getter_returnType() {
- _assertSource(
- "T get m {}",
- AstTestFactory.methodDeclaration2(
- null,
- AstTestFactory.namedType4("T"),
- Keyword.GET,
- null,
- AstTestFactory.identifier3("m"),
- null,
- AstTestFactory.blockFunctionBody2()));
- }
-
- void test_visitMethodDeclaration_getter_seturnType() {
- _assertSource(
- "T set m(var v) {}",
- AstTestFactory.methodDeclaration2(
- null,
- AstTestFactory.namedType4("T"),
- Keyword.SET,
- null,
- AstTestFactory.identifier3("m"),
- AstTestFactory.formalParameterList(
- [AstTestFactory.simpleFormalParameter(Keyword.VAR, "v")]),
- AstTestFactory.blockFunctionBody2()));
+ final code = 'int get foo => 0;';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_minimal() {
- _assertSource(
- "m() {}",
- AstTestFactory.methodDeclaration2(
- null,
- null,
- null,
- null,
- AstTestFactory.identifier3("m"),
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2()));
+ final code = 'foo() {}';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_multipleParameters() {
- _assertSource(
- "m(var a, var b) {}",
- AstTestFactory.methodDeclaration2(
- null,
- null,
- null,
- null,
- AstTestFactory.identifier3("m"),
- AstTestFactory.formalParameterList([
- AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
- AstTestFactory.simpleFormalParameter(Keyword.VAR, "b")
- ]),
- AstTestFactory.blockFunctionBody2()));
+ final code = 'void foo(int a, double b) {}';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_operator() {
- _assertSource(
- "operator +() {}",
- AstTestFactory.methodDeclaration2(
- null,
- null,
- null,
- Keyword.OPERATOR,
- AstTestFactory.identifier3("+"),
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2()));
+ final code = 'operator +(int other) {}';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_operator_returnType() {
- _assertSource(
- "T operator +() {}",
- AstTestFactory.methodDeclaration2(
- null,
- AstTestFactory.namedType4("T"),
- null,
- Keyword.OPERATOR,
- AstTestFactory.identifier3("+"),
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2()));
+ final code = 'int operator +(int other) => 0;';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_returnType() {
- _assertSource(
- "T m() {}",
- AstTestFactory.methodDeclaration2(
- null,
- AstTestFactory.namedType4("T"),
- null,
- null,
- AstTestFactory.identifier3("m"),
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2()));
+ final code = 'int foo() => 0;';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_setter() {
- _assertSource(
- "set m(var v) {}",
- AstTestFactory.methodDeclaration2(
- null,
- null,
- Keyword.SET,
- null,
- AstTestFactory.identifier3("m"),
- AstTestFactory.formalParameterList(
- [AstTestFactory.simpleFormalParameter(Keyword.VAR, "v")]),
- AstTestFactory.blockFunctionBody2()));
+ final code = 'set foo(int _) {}';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
+ }
+
+ void test_visitMethodDeclaration_setter_returnType() {
+ final code = 'void set foo(int _) {}';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_static() {
- _assertSource(
- "static m() {}",
- AstTestFactory.methodDeclaration2(
- Keyword.STATIC,
- null,
- null,
- null,
- AstTestFactory.identifier3("m"),
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2()));
+ final code = 'static foo() {}';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_static_returnType() {
- _assertSource(
- "static T m() {}",
- AstTestFactory.methodDeclaration2(
- Keyword.STATIC,
- AstTestFactory.namedType4("T"),
- null,
- null,
- AstTestFactory.identifier3("m"),
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2()));
+ final code = 'static void foo() {}';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_typeParameters() {
- _assertSource(
- "m<E>() {}",
- AstTestFactory.methodDeclaration3(
- null,
- null,
- null,
- null,
- AstTestFactory.identifier3("m"),
- AstTestFactory.typeParameterList(['E']),
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2()));
+ final code = 'void foo<T>() {}';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodDeclaration_withMetadata() {
- MethodDeclaration declaration = AstTestFactory.methodDeclaration2(
- null,
- null,
- null,
- null,
- AstTestFactory.identifier3("m"),
- AstTestFactory.formalParameterList(),
- AstTestFactory.blockFunctionBody2());
- declaration.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated m() {}", declaration);
+ final code = '@deprecated void foo() {}';
+ final findNode = _parseStringToFindNode('''
+class A {
+ $code
+}
+''');
+ _assertSource(code, findNode.methodDeclaration(code));
}
void test_visitMethodInvocation_conditional() {
@@ -2804,10 +2697,9 @@
}
void test_visitPartDirective_withMetadata() {
- PartDirective directive = AstTestFactory.partDirective2("a.dart");
- directive.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated part 'a.dart';", directive);
+ final code = '@deprecated part "a.dart";';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.part(code));
}
void test_visitPartOfDirective_name() {
@@ -2823,11 +2715,9 @@
}
void test_visitPartOfDirective_withMetadata() {
- PartOfDirective directive = AstTestFactory.partOfDirective(
- AstTestFactory.libraryIdentifier2(["l"]));
- directive.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated part of l;", directive);
+ final code = '@deprecated part of my.lib;';
+ final findNode = _parseStringToFindNode(code);
+ _assertSource(code, findNode.partOf(code));
}
void test_visitPositionalFormalParameter() {
@@ -3096,11 +2986,11 @@
}
void test_visitSimpleFormalParameter_annotation() {
- SimpleFormalParameter parameter =
- AstTestFactory.simpleFormalParameter3('x');
- parameter.metadata
- .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
- _assertSource('@A x', parameter);
+ final code = '@deprecated int x';
+ final findNode = _parseStringToFindNode('''
+void f($code) {}
+''');
+ _assertSource(code, findNode.simpleFormalParameter(code));
}
void test_visitSimpleFormalParameter_keyword() {
@@ -3193,10 +3083,13 @@
}
void test_visitSuperFormalParameter_annotation() {
- SuperFormalParameter parameter = AstTestFactory.superFormalParameter2('f');
- parameter.metadata
- .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
- _assertSource('@A super.f', parameter);
+ final code = '@deprecated super.foo';
+ final findNode = _parseStringToFindNode('''
+class A {
+ A($code);
+}
+''');
+ _assertSource(code, findNode.superFormalParameter(code));
}
void test_visitSuperFormalParameter_functionTyped() {
@@ -3251,70 +3144,109 @@
}
void test_visitSwitchCase_multipleLabels() {
- _assertSource(
- "l1: l2: case a: {}",
- AstTestFactory.switchCase2(
- [AstTestFactory.label2("l1"), AstTestFactory.label2("l2")],
- AstTestFactory.identifier3("a"),
- [AstTestFactory.block()]));
+ final code = 'l1: l2: case a: {}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ switch (x) {
+ $code
+ }
+}
+''');
+ _assertSource(code, findNode.switchCase(code));
}
void test_visitSwitchCase_multipleStatements() {
- _assertSource(
- "case a: {} {}",
- AstTestFactory.switchCase(AstTestFactory.identifier3("a"),
- [AstTestFactory.block(), AstTestFactory.block()]));
+ final code = 'case a: foo(); bar();';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ switch (x) {
+ $code
+ }
+}
+''');
+ _assertSource(code, findNode.switchCase(code));
}
void test_visitSwitchCase_noLabels() {
- _assertSource(
- "case a: {}",
- AstTestFactory.switchCase(
- AstTestFactory.identifier3("a"), [AstTestFactory.block()]));
+ final code = 'case a: {}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ switch (x) {
+ $code
+ }
+}
+''');
+ _assertSource(code, findNode.switchCase(code));
}
void test_visitSwitchCase_singleLabel() {
- _assertSource(
- "l1: case a: {}",
- AstTestFactory.switchCase2([AstTestFactory.label2("l1")],
- AstTestFactory.identifier3("a"), [AstTestFactory.block()]));
+ final code = 'l1: case a: {}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ switch (x) {
+ $code
+ }
+}
+''');
+ _assertSource(code, findNode.switchCase(code));
}
void test_visitSwitchDefault_multipleLabels() {
- _assertSource(
- "l1: l2: default: {}",
- AstTestFactory.switchDefault(
- [AstTestFactory.label2("l1"), AstTestFactory.label2("l2")],
- [AstTestFactory.block()]));
+ final code = 'l1: l2: default: {}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ switch (x) {
+ $code
+ }
+}
+''');
+ _assertSource(code, findNode.switchDefault(code));
}
void test_visitSwitchDefault_multipleStatements() {
- _assertSource(
- "default: {} {}",
- AstTestFactory.switchDefault2(
- [AstTestFactory.block(), AstTestFactory.block()]));
+ final code = 'default: foo(); bar();';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ switch (x) {
+ $code
+ }
+}
+''');
+ _assertSource(code, findNode.switchDefault(code));
}
void test_visitSwitchDefault_noLabels() {
- _assertSource(
- "default: {}", AstTestFactory.switchDefault2([AstTestFactory.block()]));
+ final code = 'default: {}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ switch (x) {
+ $code
+ }
+}
+''');
+ _assertSource(code, findNode.switchDefault(code));
}
void test_visitSwitchDefault_singleLabel() {
- _assertSource(
- "l1: default: {}",
- AstTestFactory.switchDefault(
- [AstTestFactory.label2("l1")], [AstTestFactory.block()]));
+ final code = 'l1: default: {}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ switch (x) {
+ $code
+ }
+}
+''');
+ _assertSource(code, findNode.switchDefault(code));
}
void test_visitSwitchStatement() {
- _assertSource(
- "switch (a) {case 'b': {} default: {}}",
- AstTestFactory.switchStatement(AstTestFactory.identifier3("a"), [
- AstTestFactory.switchCase(
- AstTestFactory.string2("b"), [AstTestFactory.block()]),
- AstTestFactory.switchDefault2([AstTestFactory.block()])
- ]));
+ final code = 'switch (x) {case 0: foo(); default: bar();}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ $code
+}
+''');
+ _assertSource(code, findNode.switchStatement(code));
}
void test_visitSymbolLiteral_multiple() {
@@ -3389,10 +3321,13 @@
}
void test_visitTryStatement_finally() {
- _assertSource(
- "try {} finally {}",
- AstTestFactory.tryStatement(
- AstTestFactory.block(), AstTestFactory.block()));
+ final code = 'try {} finally {}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ $code
+}
+''');
+ _assertSource(code, findNode.tryStatement(code));
}
void test_visitTypeArgumentList_multiple() {
@@ -3458,10 +3393,11 @@
}
void test_visitTypeParameter_withMetadata() {
- TypeParameter parameter = AstTestFactory.typeParameter("E");
- parameter.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated E", parameter);
+ final code = '@deprecated T';
+ final findNode = _parseStringToFindNode('''
+class A<$code> {}
+''');
+ _assertSource(code, findNode.typeParameter(code));
}
void test_visitTypeParameter_withoutExtends() {
@@ -3487,13 +3423,6 @@
_assertSource("a", AstTestFactory.variableDeclaration("a"));
}
- void test_visitVariableDeclaration_withMetadata() {
- VariableDeclaration declaration = AstTestFactory.variableDeclaration("a");
- declaration.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated a", declaration);
- }
-
void test_visitVariableDeclarationList_const_type() {
_assertSource(
"const C a, b",
@@ -3513,17 +3442,6 @@
]));
}
- void test_visitVariableDeclarationList_final_withMetadata() {
- VariableDeclarationList declarationList =
- AstTestFactory.variableDeclarationList2(Keyword.FINAL, [
- AstTestFactory.variableDeclaration("a"),
- AstTestFactory.variableDeclaration("b")
- ]);
- declarationList.metadata.add(
- AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
- _assertSource("@deprecated final a, b", declarationList);
- }
-
void test_visitVariableDeclarationList_type() {
_assertSource(
"C a, b",
@@ -3553,10 +3471,13 @@
}
void test_visitWhileStatement() {
- _assertSource(
- "while (c) {}",
- AstTestFactory.whileStatement(
- AstTestFactory.identifier3("c"), AstTestFactory.block()));
+ final code = 'while (true) {}';
+ final findNode = _parseStringToFindNode('''
+void f() {
+ $code
+}
+''');
+ _assertSource(code, findNode.whileStatement(code));
}
void test_visitWithClause_multiple() {
diff --git a/pkg/analyzer/test/src/dart/constant/utilities_test.dart b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
index 8a22db8..6d3619b 100644
--- a/pkg/analyzer/test/src/dart/constant/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
@@ -5,254 +5,21 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../generated/test_support.dart';
-
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(ConstantFinderTest);
defineReflectiveTests(ReferenceFinderTest);
});
}
@reflectiveTest
-class ConstantFinderTest {
- late final AstNode _node;
- late final TypeProvider _typeProvider;
- late final Source _source;
-
- void setUp() {
- _typeProvider = TestTypeProvider();
- _source = TestSource();
- }
-
- /// Test an annotation that consists solely of an identifier (and hence
- /// represents a reference to a compile-time constant variable).
- void test_visitAnnotation_constantVariable() {
- var compilationUnitElement =
- ElementFactory.compilationUnit(source: _source);
- ElementFactory.library(_AnalysisContextMock(), 'L')
- .definingCompilationUnit = compilationUnitElement;
- ElementAnnotationImpl elementAnnotation =
- ElementAnnotationImpl(compilationUnitElement);
- var annotation = AstTestFactory.annotation(AstTestFactory.identifier3('x'));
- _node = elementAnnotation.annotationAst = annotation
- ..elementAnnotation = elementAnnotation;
- expect(_findAnnotations(), contains(_node));
- }
-
- /// Test an annotation that represents the invocation of a constant
- /// constructor.
- void test_visitAnnotation_invocation() {
- var compilationUnitElement =
- ElementFactory.compilationUnit(source: _source);
- ElementFactory.library(_AnalysisContextMock(), 'L')
- .definingCompilationUnit = compilationUnitElement;
- ElementAnnotationImpl elementAnnotation =
- ElementAnnotationImpl(compilationUnitElement);
- var annotation = AstTestFactory.annotation2(
- AstTestFactory.identifier3('A'), null, AstTestFactory.argumentList());
- _node = elementAnnotation.annotationAst = annotation
- ..elementAnnotation = elementAnnotation;
- expect(_findAnnotations(), contains(_node));
- }
-
- void test_visitAnnotation_partOf() {
- // Analyzer ignores annotations on "part of" directives.
- Annotation annotation = AstTestFactory.annotation2(
- AstTestFactory.identifier3('A'), null, AstTestFactory.argumentList());
- _node = AstTestFactory.partOfDirective2(<Annotation>[annotation],
- AstTestFactory.libraryIdentifier2(<String>['L']));
- expect(_findConstants(), isEmpty);
- }
-
- void test_visitConstructorDeclaration_const() {
- ConstructorElement element = _setupConstructorDeclaration("A", true);
- expect(_findConstants(), contains(element));
- }
-
- void test_visitConstructorDeclaration_nonConst() {
- _setupConstructorDeclaration("A", false);
- expect(_findConstants(), isEmpty);
- }
-
- void test_visitVariableDeclaration_const() {
- VariableElement element = _setupVariableDeclaration("v", true, true);
- expect(_findConstants(), contains(element));
- }
-
- void test_visitVariableDeclaration_final_inClass() {
- _setupFieldDeclaration('C', 'f', Keyword.FINAL);
- expect(_findConstants(), isEmpty);
- }
-
- void test_visitVariableDeclaration_final_inClassWithConstConstructor() {
- VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
- hasConstConstructor: true);
- expect(_findConstants(), contains(field.declaredElement));
- }
-
- void test_visitVariableDeclaration_final_outsideClass() {
- _setupVariableDeclaration('v', false, true, isFinal: true);
- expect(_findConstants(), isEmpty);
- }
-
- void test_visitVariableDeclaration_noInitializer() {
- _setupVariableDeclaration("v", true, false);
- expect(_findConstants(), isEmpty);
- }
-
- void test_visitVariableDeclaration_nonConst() {
- _setupVariableDeclaration("v", false, true);
- expect(_findConstants(), isEmpty);
- }
-
- void test_visitVariableDeclaration_static_const_inClass() {
- VariableDeclaration field =
- _setupFieldDeclaration('C', 'f', Keyword.CONST, isStatic: true);
- expect(_findConstants(), contains(field.declaredElement));
- }
-
- void
- test_visitVariableDeclaration_static_const_inClassWithConstConstructor() {
- VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.CONST,
- isStatic: true, hasConstConstructor: true);
- expect(_findConstants(), contains(field.declaredElement));
- }
-
- void
- test_visitVariableDeclaration_static_final_inClassWithConstConstructor() {
- VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
- isStatic: true, hasConstConstructor: true);
- expect(_findConstants(), isNot(contains(field.declaredElement)));
- }
-
- void
- test_visitVariableDeclaration_uninitialized_final_inClassWithConstConstructor() {
- VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
- isInitialized: false, hasConstConstructor: true);
- expect(_findConstants(), isNot(contains(field.declaredElement)));
- }
-
- void test_visitVariableDeclaration_uninitialized_static_const_inClass() {
- _setupFieldDeclaration('C', 'f', Keyword.CONST,
- isStatic: true, isInitialized: false);
- expect(_findConstants(), isEmpty);
- }
-
- List<Annotation> _findAnnotations() {
- Set<Annotation> annotations = <Annotation>{};
- for (ConstantEvaluationTarget target in _findConstants()) {
- if (target is ElementAnnotationImpl) {
- expect(target.source, same(_source));
- annotations.add(target.annotationAst);
- }
- }
- return List<Annotation>.from(annotations);
- }
-
- List<ConstantEvaluationTarget> _findConstants() {
- ConstantFinder finder = ConstantFinder();
- _node.accept(finder);
- List<ConstantEvaluationTarget> constants = finder.constantsToCompute;
- expect(constants, isNotNull);
- return constants;
- }
-
- ConstructorElement _setupConstructorDeclaration(String name, bool isConst) {
- var constKeyword = isConst ? Keyword.CONST : null;
- var constructorDeclaration = AstTestFactory.constructorDeclaration2(
- constKeyword,
- null,
- AstTestFactory.identifier3(name),
- null,
- AstTestFactory.formalParameterList(),
- [],
- AstTestFactory.blockFunctionBody2());
- ClassElement classElement = ElementFactory.classElement2(name);
- ConstructorElement element =
- ElementFactory.constructorElement(classElement, name, isConst);
- constructorDeclaration.declaredElement = element;
- _node = constructorDeclaration;
- return element;
- }
-
- VariableDeclaration _setupFieldDeclaration(
- String className, String fieldName, Keyword keyword,
- {bool isInitialized = true,
- bool isStatic = false,
- bool hasConstConstructor = false}) {
- var variableDeclaration = isInitialized
- ? AstTestFactory.variableDeclaration2(
- fieldName, AstTestFactory.integer(0))
- : AstTestFactory.variableDeclaration(fieldName);
- var fieldElement = ElementFactory.fieldElement(
- fieldName,
- isStatic,
- keyword == Keyword.FINAL,
- keyword == Keyword.CONST,
- _typeProvider.intType);
- variableDeclaration.declaredElement = fieldElement;
- FieldDeclaration fieldDeclaration = AstTestFactory.fieldDeclaration2(
- isStatic, keyword, <VariableDeclaration>[variableDeclaration]);
- var classDeclaration = AstTestFactory.classDeclaration(
- null, className, null, null, null, null);
- classDeclaration.members.add(fieldDeclaration);
- _node = classDeclaration;
- ClassElementImpl classElement = ElementFactory.classElement2(className);
- classElement.fields = <FieldElement>[fieldElement];
- classDeclaration.declaredElement = classElement;
- if (hasConstConstructor) {
- var constructorDeclaration = AstTestFactory.constructorDeclaration2(
- Keyword.CONST,
- null,
- AstTestFactory.identifier3(className),
- null,
- AstTestFactory.formalParameterList(),
- [],
- AstTestFactory.blockFunctionBody2());
- classDeclaration.members.add(constructorDeclaration);
- ConstructorElement constructorElement =
- ElementFactory.constructorElement(classElement, '', true);
- constructorDeclaration.declaredElement = constructorElement;
- classElement.constructors = <ConstructorElement>[constructorElement];
- } else {
- classElement.constructors = const <ConstructorElement>[];
- }
- return variableDeclaration;
- }
-
- VariableElement _setupVariableDeclaration(
- String name, bool isConst, bool isInitialized,
- {isFinal = false}) {
- var variableDeclaration = isInitialized
- ? AstTestFactory.variableDeclaration2(name, AstTestFactory.integer(0))
- : AstTestFactory.variableDeclaration(name);
- VariableElement element = ElementFactory.localVariableElement2(name);
- variableDeclaration.declaredElement = element;
- var keyword = isConst
- ? Keyword.CONST
- : isFinal
- ? Keyword.FINAL
- : null;
- AstTestFactory.variableDeclarationList2(keyword, [variableDeclaration]);
- _node = variableDeclaration;
- return element;
- }
-}
-
-@reflectiveTest
class ReferenceFinderTest {
late final Element _tail;
final List<ConstantEvaluationTarget> _dependencies = [];
@@ -330,8 +97,3 @@
node.accept(referenceFinder);
}
}
-
-class _AnalysisContextMock implements AnalysisContext {
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/analyzer/test/src/dart/element/class_element_test.dart b/pkg/analyzer/test/src/dart/element/class_element_test.dart
index 744578e..7270987 100644
--- a/pkg/analyzer/test/src/dart/element/class_element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/class_element_test.dart
@@ -74,13 +74,6 @@
_assertIsEnumLike(findElement.class_('A'), false);
}
- test_isEnumLike_false_isMixin() async {
- await assertNoErrorsInCode('''
-mixin M {}
-''');
- _assertIsEnumLike(findElement.mixin('M'), false);
- }
-
test_isEnumLike_true() async {
await assertNoErrorsInCode('''
class A {
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 98b3f3b..3eb5228 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -289,20 +289,24 @@
}
}
- void _writeClassElement(ClassElement e) {
+ void _writeClassElement(InterfaceElement e) {
_writeIndentedLine(() {
- _writeIf(e.isAbstract && !e.isMixin, 'abstract ');
- _writeIf(e.isMacro, 'macro ');
+ if (e is ClassElement) {
+ _writeIf(e.isAbstract && !e.isMixin, 'abstract ');
+ _writeIf(e.isMacro, 'macro ');
+ }
_writeIf(!e.isSimplyBounded, 'notSimplyBounded ');
- if (e.isEnum) {
+ if (e is EnumElement) {
buffer.write('enum ');
- } else if (e.isMixin) {
+ } else if (e is MixinElement) {
buffer.write('mixin ');
} else {
buffer.write('class ');
}
- _writeIf(e.isMixinApplication, 'alias ');
+ if (e is ClassElement) {
+ _writeIf(e.isMixinApplication, 'alias ');
+ }
_writeName(e);
});
@@ -313,13 +317,18 @@
_writeCodeRange(e);
_writeTypeParameterElements(e.typeParameters);
- var supertype = e.supertype;
+ InterfaceType? supertype;
+ if (e is ClassElement) {
+ supertype = e.supertype;
+ } else if (e is EnumElement) {
+ supertype = e.supertype;
+ }
if (supertype != null &&
(supertype.element.name != 'Object' || e.mixins.isNotEmpty)) {
_writeType('supertype', supertype);
}
- if (e.isMixin) {
+ if (e is MixinElement) {
var superclassConstraints = e.superclassConstraints;
if (superclassConstraints.isEmpty) {
throw StateError('At least Object is expected.');
@@ -333,7 +342,7 @@
_writeElements('fields', e.fields, _writePropertyInducingElement);
var constructors = e.constructors;
- if (e.isMixin) {
+ if (e is MixinElement) {
expect(constructors, isEmpty);
} else {
expect(constructors, isNotEmpty);
@@ -1026,9 +1035,9 @@
void _writeUnitElement(CompilationUnitElement e) {
_writeElements('classes', e.classes, _writeClassElement);
- _writeElements('enums', e.enums, _writeClassElement);
+ _writeElements('enums', e.enums2, _writeClassElement);
_writeElements('extensions', e.extensions, _writeExtensionElement);
- _writeElements('mixins', e.mixins, _writeClassElement);
+ _writeElements('mixins', e.mixins2, _writeClassElement);
_writeElements('typeAliases', e.typeAliases, _writeTypeAliasElement);
_writeElements(
'topLevelVariables',
diff --git a/pkg/analyzer/test/src/summary/elements_test.dart b/pkg/analyzer/test/src/summary/elements_test.dart
index f86beeb..6fa83b4 100644
--- a/pkg/analyzer/test/src/summary/elements_test.dart
+++ b/pkg/analyzer/test/src/summary/elements_test.dart
@@ -32467,7 +32467,7 @@
// We intentionally ask `mixins` directly, to check that we can ask them
// separately, without asking classes.
- var mixins = library.definingCompilationUnit.mixins;
+ var mixins = library.definingCompilationUnit.mixins2;
expect(mixins, hasLength(1));
expect(mixins[0].name, 'M');
}
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index a63e5b4..1a3ee99 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -19398,11 +19398,19 @@
The analyzer produces this diagnostic when a private declaration isn't
referenced in the library that contains the declaration. The following
kinds of declarations are analyzed:
-- Private top-level declarations, such as classes, enums, mixins, typedefs,
- top-level variables, and top-level functions
-- Private static and instance methods
+- Private top-level declarations and all of their members
+- Private members of public declarations
- Optional parameters of private functions for which a value is never
- passed, even when the parameter doesn't have a private name
+ passed
+
+Not all references to an element will mark it as "used":
+- Assigning a value to a top-level variable (with a standard `=`
+ assignment, or a null-aware `??=` assignment) does not count as using
+ it.
+- Refering to an element in a doc comment reference does not count as
+ using it.
+- Refering to a class, mixin, or enum in the right side of an `is`
+ expression does not count as using it.
#### Example
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index 09bae68..06f1d0f 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -3032,11 +3032,11 @@
var path = convertPath('/home/test/lib/test.dart');
addSource(path, content);
- ClassElement? targetElement;
+ InterfaceElement? targetElement;
{
var unitResult = (await resolveFile(path)).unit;
if (targetMixinName != null) {
- targetElement = unitResult.declaredElement!.mixins
+ targetElement = unitResult.declaredElement!.mixins2
.firstWhere((e) => e.name == targetMixinName);
} else {
targetElement = unitResult.declaredElement!.classes
diff --git a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
index 8873cd0..5b04212 100644
--- a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
+++ b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
@@ -98,13 +98,18 @@
/// Get all the decorated immediate supertypes of the non-migrated class
/// [class_].
- Iterable<DecoratedType> getImmediateSupertypes(ClassElement class_) {
+ Iterable<DecoratedType> getImmediateSupertypes(InterfaceElement class_) {
var allSupertypes = <DartType>[];
- var supertype = class_.supertype;
+ InterfaceType? supertype;
+ if (class_ is ClassElement) {
+ supertype = class_.supertype;
+ }
if (supertype != null) {
allSupertypes.add(supertype);
}
- allSupertypes.addAll(class_.superclassConstraints);
+ if (class_ is MixinElement) {
+ allSupertypes.addAll(class_.superclassConstraints);
+ }
allSupertypes.addAll(class_.preMigrationInterfaces);
allSupertypes.addAll(class_.mixins);
var type = class_.thisType;
@@ -119,7 +124,7 @@
}
}
-extension on ClassElement {
+extension on InterfaceElement {
List<InterfaceType> get preMigrationInterfaces {
var previousElementTypeProvider = ElementTypeProvider.current;
try {
diff --git a/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart b/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
index 519bd12..1baa2ce 100644
--- a/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
@@ -21,7 +21,7 @@
/// Cache for speeding up the computation of
/// [_getGenericSupertypeDecorations].
- final Map<ClassElement, Map<ClassElement, DecoratedType>>
+ final Map<InterfaceElement, Map<ClassElement, DecoratedType>>
_genericSupertypeDecorations = {};
DecoratedClassHierarchy(this._variables, this._graph);
@@ -52,7 +52,7 @@
/// because the relationship between a class and its superclass is not
/// nullable.
DecoratedType getDecoratedSupertype(
- ClassElement class_, InterfaceElement superclass) {
+ InterfaceElement class_, InterfaceElement superclass) {
assert(!(class_.library.isDartCore && class_.name == 'Null'));
if (superclass.typeParameters.isEmpty) {
return DecoratedType(
@@ -70,7 +70,7 @@
/// Computes a map whose keys are all the superclasses of [class_], and whose
/// values indicate how [class_] implements each superclass.
Map<ClassElement, DecoratedType> _getGenericSupertypeDecorations(
- ClassElement class_) {
+ InterfaceElement class_) {
var decorations = _genericSupertypeDecorations[class_];
if (decorations == null) {
// Call ourselves recursively to compute how each of [class_]'s direct
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index 681852f..1ff963c 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -49,7 +49,7 @@
final _decoratedElementTypes = <Element?, DecoratedType?>{};
final _decoratedDirectSupertypes =
- <ClassElement, Map<ClassElement, DecoratedType?>>{};
+ <InterfaceElement, Map<ClassElement, DecoratedType?>>{};
final _decoratedTypeAnnotations = <Source?, Map<int, DecoratedType>>{};
@@ -76,7 +76,7 @@
/// Given a [class_], gets the decorated type information for the superclasses
/// it directly implements/extends/etc.
Map<ClassElement, DecoratedType?> decoratedDirectSupertypes(
- ClassElement class_) {
+ InterfaceElement class_) {
return _decoratedDirectSupertypes[class_] ??=
_decorateDirectSupertypes(class_);
}
@@ -418,7 +418,7 @@
/// Creates an entry [_decoratedDirectSupertypes] for an already-migrated
/// class.
Map<ClassElement, DecoratedType> _decorateDirectSupertypes(
- ClassElement class_) {
+ InterfaceElement class_) {
var result = <ClassElement, DecoratedType>{};
for (var decoratedSupertype
in _alreadyMigratedCodeDecorator.getImmediateSupertypes(class_)) {
diff --git a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
index eefd869..57d6285 100644
--- a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
+++ b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
@@ -427,7 +427,7 @@
'mixin C on num {}',
);
var unitElement = withUnit.unitElement;
- var mixin_ = unitElement.mixins.single;
+ var mixin_ = unitElement.mixins2.single;
var withElement = withUnit.withElement(mixin_);
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 1f097a6..2ba066f 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -8296,7 +8296,7 @@
@override
DecoratedType getDecoratedSupertype(
- ClassElement class_, InterfaceElement superclass) {
+ InterfaceElement class_, InterfaceElement superclass) {
throw UnimplementedError('TODO(paulberry)');
}
}
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 64576491..02122a3 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -662,6 +662,20 @@
}
}
+void Assembler::LoadSImmediate(VRegister vd, float imms) {
+ int32_t imm32 = bit_cast<int32_t, float>(imms);
+ if (imm32 == 0) {
+ veor(vd, vd, vd);
+ } else if (constant_pool_allowed()) {
+ intptr_t index = object_pool_builder().FindImmediate(imm32);
+ intptr_t offset = target::ObjectPool::element_offset(index);
+ LoadSFromOffset(vd, PP, offset);
+ } else {
+ LoadImmediate(TMP, imm32);
+ fmovsr(vd, TMP);
+ }
+}
+
void Assembler::LoadDImmediate(VRegister vd, double immd) {
if (fmovdi(vd, immd)) return;
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index ea47f52..56b0fda 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -2066,6 +2066,7 @@
LoadImmediate(reg, imm.value());
}
+ void LoadSImmediate(VRegister reg, float immd);
void LoadDImmediate(VRegister reg, double immd);
void LoadQImmediate(VRegister reg, simd128_value_t immq);
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 51c1fa9..73d84a5 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -2199,6 +2199,13 @@
addl(dest, inc_imm);
}
+void Assembler::LoadSImmediate(XmmRegister dst, float value) {
+ int32_t constant = bit_cast<int32_t, float>(value);
+ pushl(Immediate(constant));
+ movss(dst, Address(ESP, 0));
+ addl(ESP, Immediate(target::kWordSize));
+}
+
void Assembler::LoadDImmediate(XmmRegister dst, double value) {
// TODO(5410843): Need to have a code constants table.
int64_t constant = bit_cast<int64_t, double>(value);
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 7ef5339..77b453b 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -759,6 +759,7 @@
LoadImmediate(reg, immediate.value());
}
+ void LoadSImmediate(XmmRegister dst, float value);
void LoadDImmediate(XmmRegister dst, double value);
void Drop(intptr_t stack_elements);
diff --git a/runtime/vm/compiler/assembler/assembler_riscv.cc b/runtime/vm/compiler/assembler/assembler_riscv.cc
index 10beeac..08a4b28 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv.cc
+++ b/runtime/vm/compiler/assembler/assembler_riscv.cc
@@ -3351,6 +3351,18 @@
}
}
+void Assembler::LoadSImmediate(FRegister reg, float imms) {
+ int32_t imm = bit_cast<int32_t, float>(imms);
+ if (imm == 0) {
+ fmvwx(reg, ZR); // bit_cast uint32_t -> float
+ } else {
+ ASSERT(constant_pool_allowed());
+ intptr_t index = object_pool_builder().FindImmediate(imm);
+ intptr_t offset = target::ObjectPool::element_offset(index);
+ LoadSFromOffset(reg, PP, offset);
+ }
+}
+
void Assembler::LoadDImmediate(FRegister reg, double immd) {
int64_t imm = bit_cast<int64_t, double>(immd);
if (imm == 0) {
diff --git a/runtime/vm/compiler/assembler/assembler_riscv.h b/runtime/vm/compiler/assembler/assembler_riscv.h
index cefa220..18eeb4a 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv.h
+++ b/runtime/vm/compiler/assembler/assembler_riscv.h
@@ -432,6 +432,8 @@
void feqs(Register rd, FRegister rs1, FRegister rs2);
void flts(Register rd, FRegister rs1, FRegister rs2);
void fles(Register rd, FRegister rs1, FRegister rs2);
+ void fgts(Register rd, FRegister rs1, FRegister rs2) { flts(rd, rs2, rs1); }
+ void fges(Register rd, FRegister rs1, FRegister rs2) { fles(rd, rs2, rs1); }
void fclasss(Register rd, FRegister rs1);
// int32_t <- float
void fcvtws(Register rd, FRegister rs1, RoundingMode rounding = RNE);
@@ -517,6 +519,8 @@
void feqd(Register rd, FRegister rs1, FRegister rs2);
void fltd(Register rd, FRegister rs1, FRegister rs2);
void fled(Register rd, FRegister rs1, FRegister rs2);
+ void fgtd(Register rd, FRegister rs1, FRegister rs2) { fltd(rd, rs2, rs1); }
+ void fged(Register rd, FRegister rs1, FRegister rs2) { fled(rd, rs2, rs1); }
void fclassd(Register rd, FRegister rs1);
// int32_t <- double
void fcvtwd(Register rd, FRegister rs1, RoundingMode rounding = RNE);
@@ -1018,6 +1022,9 @@
Register index);
void LoadSFromOffset(FRegister dest, Register base, int32_t offset);
void LoadDFromOffset(FRegister dest, Register base, int32_t offset);
+ void LoadSFieldFromOffset(FRegister dest, Register base, int32_t offset) {
+ LoadSFromOffset(dest, base, offset - kHeapObjectTag);
+ }
void LoadDFieldFromOffset(FRegister dest, Register base, int32_t offset) {
LoadDFromOffset(dest, base, offset - kHeapObjectTag);
}
@@ -1043,6 +1050,9 @@
sx(ZR, address);
}
void StoreSToOffset(FRegister src, Register base, int32_t offset);
+ void StoreSFieldToOffset(FRegister src, Register base, int32_t offset) {
+ StoreSToOffset(src, base, offset - kHeapObjectTag);
+ }
void StoreDToOffset(FRegister src, Register base, int32_t offset);
void StoreDFieldToOffset(FRegister src, Register base, int32_t offset) {
StoreDToOffset(src, base, offset - kHeapObjectTag);
@@ -1182,6 +1192,7 @@
// Note: the function never clobbers TMP, TMP2 scratch registers.
void LoadImmediate(Register reg, intx_t imm);
+ void LoadSImmediate(FRegister reg, float imms);
void LoadDImmediate(FRegister reg, double immd);
void LoadQImmediate(FRegister reg, simd128_value_t immq);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index bfed044..b7e098c 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1394,6 +1394,17 @@
}
}
+void Assembler::LoadSImmediate(FpuRegister dst, float immediate) {
+ int32_t bits = bit_cast<int32_t>(immediate);
+ if (bits == 0) {
+ xorps(dst, dst);
+ } else {
+ intptr_t index = object_pool_builder().FindImmediate(bits);
+ LoadUnboxedSingle(
+ dst, PP, target::ObjectPool::element_offset(index) - kHeapObjectTag);
+ }
+}
+
void Assembler::LoadDImmediate(FpuRegister dst, double immediate) {
int64_t bits = bit_cast<int64_t>(immediate);
if (bits == 0) {
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index eafff9b..d0b48f8 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -787,6 +787,7 @@
void LoadImmediate(Register reg, int32_t immediate) {
LoadImmediate(reg, Immediate(immediate));
}
+ void LoadSImmediate(FpuRegister dst, float immediate);
void LoadDImmediate(FpuRegister dst, double immediate);
void LoadQImmediate(FpuRegister dst, simd128_value_t immediate);
@@ -1082,6 +1083,9 @@
movq(Address(base, offset), src);
}
+ void LoadUnboxedSingle(FpuRegister dst, Register base, int32_t offset) {
+ movss(dst, Address(base, offset));
+ }
void LoadUnboxedDouble(FpuRegister dst, Register base, int32_t offset) {
movsd(dst, Address(base, offset));
}
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
index 4a36631..de4c656 100644
--- a/runtime/vm/compiler/backend/block_builder.h
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -136,6 +136,8 @@
entry_->AsJoinEntry()->InsertPhi(phi);
}
+ Instruction* last() const { return current_; }
+
private:
static CompileType* TypeForRepresentation(Representation rep) {
switch (rep) {
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 8456490..8e53015 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -872,6 +872,16 @@
}
}
+void ConstantPropagator::VisitBoolToInt(BoolToIntInstr* instr) {
+ // TODO(riscv)
+ SetValue(instr, non_constant_);
+}
+
+void ConstantPropagator::VisitIntToBool(IntToBoolInstr* instr) {
+ // TODO(riscv)
+ SetValue(instr, non_constant_);
+}
+
void ConstantPropagator::VisitInstanceOf(InstanceOfInstr* instr) {
Definition* def = instr->value()->definition();
const Object& value = def->constant_value();
@@ -1216,8 +1226,27 @@
VisitUnaryIntegerOp(instr);
}
+static bool IsIntegerOrDouble(const Object& value) {
+ return value.IsInteger() || value.IsDouble();
+}
+
+static double ToDouble(const Object& value) {
+ return value.IsInteger() ? Integer::Cast(value).AsDoubleValue()
+ : Double::Cast(value).value();
+}
+
void ConstantPropagator::VisitUnaryDoubleOp(UnaryDoubleOpInstr* instr) {
- // TODO(kmillikin): Handle unary operations.
+ const Object& value = instr->value()->definition()->constant_value();
+ if (IsUnknown(value)) {
+ return;
+ }
+ if (value.IsDouble()) {
+ const double result_val = Evaluator::EvaluateUnaryDoubleOp(
+ ToDouble(value), instr->op_kind(), instr->representation());
+ const Double& result = Double::ZoneHandle(Double::NewCanonical(result_val));
+ SetValue(instr, result);
+ return;
+ }
SetValue(instr, non_constant_);
}
@@ -1273,11 +1302,6 @@
SetValue(instr, non_constant_);
}
-void ConstantPropagator::VisitDoubleToDouble(DoubleToDoubleInstr* instr) {
- // TODO(kmillikin): Handle conversion.
- SetValue(instr, non_constant_);
-}
-
void ConstantPropagator::VisitDoubleToFloat(DoubleToFloatInstr* instr) {
// TODO(kmillikin): Handle conversion.
SetValue(instr, non_constant_);
@@ -1288,6 +1312,11 @@
SetValue(instr, non_constant_);
}
+void ConstantPropagator::VisitFloatCompare(FloatCompareInstr* instr) {
+ // TODO(riscv)
+ SetValue(instr, non_constant_);
+}
+
void ConstantPropagator::VisitInvokeMathCFunction(
InvokeMathCFunctionInstr* instr) {
// TODO(kmillikin): Handle conversion.
@@ -1303,6 +1332,25 @@
SetValue(instr, non_constant_);
}
+void ConstantPropagator::VisitUnboxLane(UnboxLaneInstr* instr) {
+ if (BoxLanesInstr* box = instr->value()->definition()->AsBoxLanes()) {
+ const Object& value =
+ box->InputAt(instr->lane())->definition()->constant_value();
+ if (IsUnknown(value)) {
+ return;
+ }
+ SetValue(instr, value);
+ return;
+ }
+
+ SetValue(instr, non_constant_);
+}
+
+void ConstantPropagator::VisitBoxLanes(BoxLanesInstr* instr) {
+ // TODO(riscv)
+ SetValue(instr, non_constant_);
+}
+
void ConstantPropagator::VisitConstant(ConstantInstr* instr) {
SetValue(instr, instr->value());
}
@@ -1321,15 +1369,6 @@
UNREACHABLE();
}
-static bool IsIntegerOrDouble(const Object& value) {
- return value.IsInteger() || value.IsDouble();
-}
-
-static double ToDouble(const Object& value) {
- return value.IsInteger() ? Integer::Cast(value).AsDoubleValue()
- : Double::Cast(value).value();
-}
-
void ConstantPropagator::VisitBinaryDoubleOp(BinaryDoubleOpInstr* instr) {
const Object& left = instr->left()->definition()->constant_value();
const Object& right = instr->right()->definition()->constant_value();
@@ -1343,8 +1382,9 @@
const bool both_are_integers = left.IsInteger() && right.IsInteger();
if (IsIntegerOrDouble(left) && IsIntegerOrDouble(right) &&
!both_are_integers) {
- const double result_val = Evaluator::EvaluateDoubleOp(
- ToDouble(left), ToDouble(right), instr->op_kind());
+ const double result_val = Evaluator::EvaluateBinaryDoubleOp(
+ ToDouble(left), ToDouble(right), instr->op_kind(),
+ instr->representation());
const Double& result = Double::ZoneHandle(Double::NewCanonical(result_val));
SetValue(instr, result);
return;
@@ -1384,11 +1424,6 @@
SetValue(instr, non_constant_);
}
-void ConstantPropagator::VisitMathUnary(MathUnaryInstr* instr) {
- // TODO(kmillikin): Handle Math's unary operations (sqrt, cos, sin).
- SetValue(instr, non_constant_);
-}
-
void ConstantPropagator::VisitMathMinMax(MathMinMaxInstr* instr) {
// TODO(srdjan): Handle min and max.
SetValue(instr, non_constant_);
diff --git a/runtime/vm/compiler/backend/evaluator.cc b/runtime/vm/compiler/backend/evaluator.cc
index 9ab7d39..2f9e3b3 100644
--- a/runtime/vm/compiler/backend/evaluator.cc
+++ b/runtime/vm/compiler/backend/evaluator.cc
@@ -189,20 +189,91 @@
return result.ptr();
}
-double Evaluator::EvaluateDoubleOp(const double left,
- const double right,
- Token::Kind token_kind) {
- switch (token_kind) {
- case Token::kADD:
- return left + right;
- case Token::kSUB:
- return left - right;
- case Token::kMUL:
- return left * right;
- case Token::kDIV:
- return left / right;
- default:
- UNREACHABLE();
+double Evaluator::EvaluateUnaryDoubleOp(const double value,
+ Token::Kind token_kind,
+ Representation representation) {
+ // The different set of operations for float32 and float64 is due to the
+ // different set of operations made available by dart:core.double and
+ // dart:typed_data.Float64x2 versus dart:typed_data.Float32x4.
+ if (representation == kUnboxedDouble) {
+ switch (token_kind) {
+ case Token::kABS:
+ return fabs(value);
+ case Token::kNEGATE:
+ return -value;
+ case Token::kSQRT:
+ return sqrt(value);
+ case Token::kSQUARE:
+ return value * value;
+ case Token::kTRUNCATE:
+ return trunc(value);
+ case Token::kFLOOR:
+ return floor(value);
+ case Token::kCEILING:
+ return ceil(value);
+ default:
+ UNREACHABLE();
+ }
+ } else {
+ ASSERT(representation == kUnboxedFloat);
+ switch (token_kind) {
+ case Token::kABS:
+ return fabsf(static_cast<float>(value));
+ case Token::kNEGATE:
+ return -static_cast<float>(value);
+ case Token::kRECIPROCAL:
+ return 1.0f / static_cast<float>(value);
+ case Token::kRECIPROCAL_SQRT:
+ return sqrtf(1.0f / static_cast<float>(value));
+ case Token::kSQRT:
+ return sqrtf(static_cast<float>(value));
+ case Token::kSQUARE:
+ return static_cast<float>(value) * static_cast<float>(value);
+ default:
+ UNREACHABLE();
+ }
+ }
+}
+
+double Evaluator::EvaluateBinaryDoubleOp(const double left,
+ const double right,
+ Token::Kind token_kind,
+ Representation representation) {
+ if (representation == kUnboxedDouble) {
+ switch (token_kind) {
+ case Token::kADD:
+ return left + right;
+ case Token::kSUB:
+ return left - right;
+ case Token::kMUL:
+ return left * right;
+ case Token::kDIV:
+ return left / right;
+ case Token::kMIN:
+ return fmin(left, right);
+ case Token::kMAX:
+ return fmax(left, right);
+ default:
+ UNREACHABLE();
+ }
+ } else {
+ ASSERT(representation == kUnboxedFloat);
+ switch (token_kind) {
+ case Token::kADD:
+ return static_cast<float>(left) + static_cast<float>(right);
+ case Token::kSUB:
+ return static_cast<float>(left) - static_cast<float>(right);
+ case Token::kMUL:
+ return static_cast<float>(left) * static_cast<float>(right);
+ case Token::kDIV:
+ return static_cast<float>(left) / static_cast<float>(right);
+ case Token::kMIN:
+ return fminf(static_cast<float>(left), static_cast<float>(right));
+ case Token::kMAX:
+ return fmaxf(static_cast<float>(left), static_cast<float>(right));
+ default:
+ UNREACHABLE();
+ }
}
}
diff --git a/runtime/vm/compiler/backend/evaluator.h b/runtime/vm/compiler/backend/evaluator.h
index dca583a..afd05ed 100644
--- a/runtime/vm/compiler/backend/evaluator.h
+++ b/runtime/vm/compiler/backend/evaluator.h
@@ -44,10 +44,16 @@
Representation representation,
Thread* thread);
+ // Evaluates a unary double operation and returns the result.
+ static double EvaluateUnaryDoubleOp(const double value,
+ Token::Kind token_kind,
+ Representation representation);
+
// Evaluates a binary double operation and returns the result.
- static double EvaluateDoubleOp(const double left,
- const double right,
- Token::Kind token_kind);
+ static double EvaluateBinaryDoubleOp(const double left,
+ const double right,
+ Token::Kind token_kind,
+ Representation representation);
// Returns whether the value is an int64, and returns the int64 value
// through the result parameter.
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 95691ce..d167f2d 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -220,6 +220,7 @@
case kUnboxedInt64:
return value.IsInteger();
+ case kUnboxedFloat:
case kUnboxedDouble:
return value.IsInteger() || value.IsDouble();
@@ -238,11 +239,13 @@
return op;
}
- if (representation == kUnboxedDouble && value.IsInteger()) {
- // Convert the boxed constant from int to double.
+ if (((representation == kUnboxedFloat) ||
+ (representation == kUnboxedDouble)) &&
+ value.IsInteger()) {
+ // Convert the boxed constant from int to float/double.
return GetConstant(Double::Handle(Double::NewCanonical(
Integer::Cast(value).AsDoubleValue())),
- kUnboxedDouble);
+ representation);
}
return GetConstant(value, representation);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 6355ea9..b0a50c6 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -395,6 +395,9 @@
case kUnboxedUint32:
src_kind = CatchEntryMove::SourceKind::kUint32Slot;
break;
+ case kUnboxedFloat:
+ src_kind = CatchEntryMove::SourceKind::kFloatSlot;
+ break;
case kUnboxedDouble:
src_kind = CatchEntryMove::SourceKind::kDoubleSlot;
break;
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index e7f9172..6be93b4 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -547,7 +547,8 @@
while (true) {
Definition* orig;
if (def->IsConstraint() || def->IsBox() || def->IsUnbox() ||
- def->IsIntConverter()) {
+ def->IsIntConverter() || def->IsFloatToDouble() ||
+ def->IsDoubleToFloat()) {
orig = def->InputAt(0)->definition();
} else {
orig = def->OriginalDefinition();
@@ -2131,32 +2132,26 @@
}
Definition* DoubleToFloatInstr::Canonicalize(FlowGraph* flow_graph) {
-#ifdef DEBUG
- // Must only be used in Float32 StoreIndexedInstr, FloatToDoubleInstr,
- // Phis introduce by load forwarding, or MaterializeObject for
- // eliminated Float32 array.
- ASSERT(env_use_list() == NULL);
- for (Value* use = input_use_list(); use != NULL; use = use->next_use()) {
- ASSERT(use->instruction()->IsPhi() ||
- use->instruction()->IsFloatToDouble() ||
- (use->instruction()->IsStoreIndexed() &&
- (use->instruction()->AsStoreIndexed()->class_id() ==
- kTypedDataFloat32ArrayCid)) ||
- (use->instruction()->IsMaterializeObject() &&
- (use->instruction()->AsMaterializeObject()->cls().id() ==
- kTypedDataFloat32ArrayCid)));
- }
-#endif
if (!HasUses()) return NULL;
if (value()->definition()->IsFloatToDouble()) {
// F2D(D2F(v)) == v.
return value()->definition()->AsFloatToDouble()->value()->definition();
}
+ if (value()->BindsToConstant()) {
+ double narrowed_val =
+ static_cast<float>(Double::Cast(value()->BoundConstant()).value());
+ return flow_graph->GetConstant(
+ Double::ZoneHandle(Double::NewCanonical(narrowed_val)), kUnboxedFloat);
+ }
return this;
}
Definition* FloatToDoubleInstr::Canonicalize(FlowGraph* flow_graph) {
- return HasUses() ? this : NULL;
+ if (!HasUses()) return NULL;
+ if (value()->BindsToConstant()) {
+ return flow_graph->GetConstant(value()->BoundConstant(), kUnboxedDouble);
+ }
+ return this;
}
Definition* BinaryDoubleOpInstr::Canonicalize(FlowGraph* flow_graph) {
@@ -2176,11 +2171,11 @@
if ((op_kind() == Token::kMUL) &&
(left()->definition() == right()->definition())) {
- MathUnaryInstr* math_unary = new MathUnaryInstr(
- MathUnaryInstr::kDoubleSquare, new Value(left()->definition()),
- DeoptimizationTarget());
- flow_graph->InsertBefore(this, math_unary, env(), FlowGraph::kValue);
- return math_unary;
+ UnaryDoubleOpInstr* square = new UnaryDoubleOpInstr(
+ Token::kSQUARE, new Value(left()->definition()), DeoptimizationTarget(),
+ speculative_mode_, representation());
+ flow_graph->InsertBefore(this, square, env(), FlowGraph::kValue);
+ return square;
}
return this;
@@ -2621,13 +2616,6 @@
return HasUses() ? this : NULL;
}
-// A math unary instruction has a side effect (exception
-// thrown) if the argument is not a number.
-// TODO(srdjan): eliminate if has no uses and input is guaranteed to be number.
-Definition* MathUnaryInstr::Canonicalize(FlowGraph* flow_graph) {
- return this;
-}
-
bool LoadFieldInstr::TryEvaluateLoad(const Object& instance,
const Slot& field,
Object* result) {
@@ -2992,12 +2980,30 @@
if ((unbox_defn != NULL) &&
(unbox_defn->representation() == from_representation()) &&
(unbox_defn->value()->Type()->ToCid() == Type()->ToCid())) {
+ if (from_representation() == kUnboxedFloat) {
+ // This is a narrowing conversion.
+ return this;
+ }
return unbox_defn->value()->definition();
}
return this;
}
+Definition* BoxLanesInstr::Canonicalize(FlowGraph* flow_graph) {
+ return HasUses() ? this : NULL;
+}
+
+Definition* UnboxLaneInstr::Canonicalize(FlowGraph* flow_graph) {
+ if (!HasUses()) return NULL;
+
+ if (BoxLanesInstr* box = value()->definition()->AsBoxLanes()) {
+ return box->InputAt(lane())->definition();
+ }
+
+ return this;
+}
+
bool BoxIntegerInstr::ValueFitsSmi() const {
Range* range = value()->definition()->range();
return RangeUtils::Fits(range, RangeBoundary::kRangeBoundarySmi);
@@ -3054,11 +3060,28 @@
Definition* UnboxInstr::Canonicalize(FlowGraph* flow_graph) {
if (!HasUses() && !CanDeoptimize()) return NULL;
- // Fold away Unbox<rep>(Box<rep>(v)).
BoxInstr* box_defn = value()->definition()->AsBox();
- if ((box_defn != NULL) &&
- (box_defn->from_representation() == representation())) {
- return box_defn->value()->definition();
+ if (box_defn != NULL) {
+ // Fold away Unbox<rep>(Box<rep>(v)).
+ if (box_defn->from_representation() == representation()) {
+ return box_defn->value()->definition();
+ }
+
+ if ((box_defn->from_representation() == kUnboxedDouble) &&
+ (representation() == kUnboxedFloat)) {
+ Definition* replacement = new DoubleToFloatInstr(
+ box_defn->value()->CopyWithType(), DeoptId::kNone);
+ flow_graph->InsertBefore(this, replacement, NULL, FlowGraph::kValue);
+ return replacement;
+ }
+
+ if ((box_defn->from_representation() == kUnboxedFloat) &&
+ (representation() == kUnboxedDouble)) {
+ Definition* replacement = new FloatToDoubleInstr(
+ box_defn->value()->CopyWithType(), DeoptId::kNone);
+ flow_graph->InsertBefore(this, replacement, NULL, FlowGraph::kValue);
+ return replacement;
+ }
}
if (representation() == kUnboxedDouble && value()->BindsToConstant()) {
@@ -3073,6 +3096,22 @@
}
}
+ if (representation() == kUnboxedFloat && value()->BindsToConstant()) {
+ const Object& val = value()->BoundConstant();
+ if (val.IsInteger()) {
+ double narrowed_val =
+ static_cast<float>(Integer::Cast(val).AsDoubleValue());
+ return flow_graph->GetConstant(
+ Double::ZoneHandle(Double::NewCanonical(narrowed_val)),
+ kUnboxedFloat);
+ } else if (val.IsDouble()) {
+ double narrowed_val = static_cast<float>(Double::Cast(val).value());
+ return flow_graph->GetConstant(
+ Double::ZoneHandle(Double::NewCanonical(narrowed_val)),
+ kUnboxedFloat);
+ }
+ }
+
return this;
}
@@ -6431,19 +6470,6 @@
return kLibcPowRuntimeEntry;
}
-const char* MathUnaryInstr::KindToCString(MathUnaryKind kind) {
- switch (kind) {
- case kIllegal:
- return "illegal";
- case kSqrt:
- return "sqrt";
- case kDoubleSquare:
- return "double-square";
- }
- UNREACHABLE();
- return "";
-}
-
TruncDivModInstr::TruncDivModInstr(Value* lhs, Value* rhs, intptr_t deopt_id)
: TemplateDefinition(deopt_id) {
SetInputAt(0, lhs);
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index af9f8b1..d4df4c7 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -451,6 +451,8 @@
M(LoadStaticField, _) \
M(StoreStaticField, kNoGC) \
M(BooleanNegate, kNoGC) \
+ M(BoolToInt, kNoGC) \
+ M(IntToBool, kNoGC) \
M(InstanceOf, _) \
M(CreateArray, _) \
M(AllocateObject, _) \
@@ -474,9 +476,9 @@
M(Int64ToDouble, kNoGC) \
M(DoubleToInteger, _) \
M(DoubleToSmi, kNoGC) \
- M(DoubleToDouble, kNoGC) \
M(DoubleToFloat, kNoGC) \
M(FloatToDouble, kNoGC) \
+ M(FloatCompare, kNoGC) \
M(CheckClass, kNoGC) \
M(CheckClassId, kNoGC) \
M(CheckSmi, kNoGC) \
@@ -487,7 +489,6 @@
M(CheckEitherNonSmi, kNoGC) \
M(BinaryDoubleOp, kNoGC) \
M(DoubleTestOp, kNoGC) \
- M(MathUnary, kNoGC) \
M(MathMinMax, kNoGC) \
M(Box, _) \
M(Unbox, kNoGC) \
@@ -515,6 +516,8 @@
M(TestSmi, kNoGC) \
M(TestCids, kNoGC) \
M(ExtractNthOutput, kNoGC) \
+ M(UnboxLane, kNoGC) \
+ M(BoxLanes, _) \
M(BinaryUint32Op, kNoGC) \
M(ShiftUint32Op, kNoGC) \
M(SpeculativeShiftUint32Op, kNoGC) \
@@ -6251,6 +6254,58 @@
DISALLOW_COPY_AND_ASSIGN(BooleanNegateInstr);
};
+// bool ? -1 : 0
+class BoolToIntInstr : public TemplateDefinition<1, NoThrow> {
+ public:
+ explicit BoolToIntInstr(Value* value) {
+ ASSERT(value->definition()->representation() == kTagged);
+ SetInputAt(0, value);
+ }
+
+ DECLARE_INSTRUCTION(BoolToInt)
+ virtual CompileType ComputeType() const;
+
+ Value* value() const { return inputs_[0]; }
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+ return kTagged;
+ }
+ virtual Representation representation() const { return kUnboxedInt32; }
+
+ virtual bool ComputeCanDeoptimize() const { return false; }
+
+ virtual bool HasUnknownSideEffects() const { return false; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BoolToIntInstr);
+};
+
+// int == 0 ? false : true
+class IntToBoolInstr : public TemplateDefinition<1, NoThrow> {
+ public:
+ explicit IntToBoolInstr(Value* value) {
+ ASSERT(value->definition()->representation() == kUnboxedInt32);
+ SetInputAt(0, value);
+ }
+
+ DECLARE_INSTRUCTION(IntToBool)
+ virtual CompileType ComputeType() const;
+
+ Value* value() const { return inputs_[0]; }
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+ return kUnboxedInt32;
+ }
+ virtual Representation representation() const { return kTagged; }
+
+ virtual bool ComputeCanDeoptimize() const { return false; }
+
+ virtual bool HasUnknownSideEffects() const { return false; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IntToBoolInstr);
+};
+
class InstanceOfInstr : public TemplateDefinition<3, Throws> {
public:
InstanceOfInstr(const InstructionSource& source,
@@ -7490,60 +7545,6 @@
IsBoxInt64() || IsUnboxInt64();
}
-class MathUnaryInstr : public TemplateDefinition<1, NoThrow, Pure> {
- public:
- enum MathUnaryKind {
- kIllegal,
- kSqrt,
- kDoubleSquare,
- };
- MathUnaryInstr(MathUnaryKind kind, Value* value, intptr_t deopt_id)
- : TemplateDefinition(deopt_id), kind_(kind) {
- SetInputAt(0, value);
- }
-
- Value* value() const { return inputs_[0]; }
- MathUnaryKind kind() const { return kind_; }
-
- virtual bool ComputeCanDeoptimize() const { return false; }
-
- virtual Representation representation() const { return kUnboxedDouble; }
-
- virtual Representation RequiredInputRepresentation(intptr_t idx) const {
- ASSERT(idx == 0);
- return kUnboxedDouble;
- }
-
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
- ASSERT(idx == 0);
- return kNotSpeculative;
- }
-
- virtual intptr_t DeoptimizationTarget() const {
- // Direct access since this instruction cannot deoptimize, and the deopt-id
- // was inherited from another instruction that could deoptimize.
- return GetDeoptId();
- }
-
- DECLARE_INSTRUCTION(MathUnary)
- virtual CompileType ComputeType() const;
-
- virtual bool AttributesEqual(const Instruction& other) const {
- return kind() == other.AsMathUnary()->kind();
- }
-
- Definition* Canonicalize(FlowGraph* flow_graph);
-
- static const char* KindToCString(MathUnaryKind kind);
-
- PRINT_OPERANDS_TO_SUPPORT
-
- private:
- const MathUnaryKind kind_;
-
- DISALLOW_COPY_AND_ASSIGN(MathUnaryInstr);
-};
-
// Calls into the runtime and performs a case-insensitive comparison of the
// UTF16 strings (i.e. TwoByteString or ExternalTwoByteString) located at
// str[lhs_index:lhs_index + length] and str[rhs_index:rhs_index + length].
@@ -7663,11 +7664,15 @@
Value* right,
intptr_t deopt_id,
const InstructionSource& source,
- SpeculativeMode speculative_mode = kGuardInputs)
+ SpeculativeMode speculative_mode = kGuardInputs,
+ Representation representation = kUnboxedDouble)
: TemplateDefinition(source, deopt_id),
op_kind_(op_kind),
token_pos_(source.token_pos),
- speculative_mode_(speculative_mode) {
+ speculative_mode_(speculative_mode),
+ representation_(representation) {
+ ASSERT((representation == kUnboxedFloat) ||
+ (representation == kUnboxedDouble));
SetInputAt(0, left);
SetInputAt(1, right);
}
@@ -7681,11 +7686,11 @@
virtual bool ComputeCanDeoptimize() const { return false; }
- virtual Representation representation() const { return kUnboxedDouble; }
+ virtual Representation representation() const { return representation_; }
virtual Representation RequiredInputRepresentation(intptr_t idx) const {
ASSERT((idx == 0) || (idx == 1));
- return kUnboxedDouble;
+ return representation_;
}
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
@@ -7708,13 +7713,15 @@
virtual bool AttributesEqual(const Instruction& other) const {
auto const other_bin_op = other.AsBinaryDoubleOp();
return (op_kind() == other_bin_op->op_kind()) &&
- (speculative_mode_ == other_bin_op->speculative_mode_);
+ (speculative_mode_ == other_bin_op->speculative_mode_) &&
+ (representation_ == other_bin_op->representation_);
}
private:
const Token::Kind op_kind_;
const TokenPosition token_pos_;
const SpeculativeMode speculative_mode_;
+ const Representation representation_;
DISALLOW_COPY_AND_ASSIGN(BinaryDoubleOpInstr);
};
@@ -8297,17 +8304,19 @@
DISALLOW_COPY_AND_ASSIGN(SpeculativeShiftUint32OpInstr);
};
-// Handles only NEGATE.
class UnaryDoubleOpInstr : public TemplateDefinition<1, NoThrow, Pure> {
public:
UnaryDoubleOpInstr(Token::Kind op_kind,
Value* value,
intptr_t deopt_id,
- SpeculativeMode speculative_mode = kGuardInputs)
+ SpeculativeMode speculative_mode = kGuardInputs,
+ Representation representation = kUnboxedDouble)
: TemplateDefinition(deopt_id),
op_kind_(op_kind),
- speculative_mode_(speculative_mode) {
- ASSERT(op_kind == Token::kNEGATE);
+ speculative_mode_(speculative_mode),
+ representation_(representation) {
+ ASSERT((representation == kUnboxedFloat) ||
+ (representation == kUnboxedDouble));
SetInputAt(0, value);
}
@@ -8325,11 +8334,11 @@
return GetDeoptId();
}
- virtual Representation representation() const { return kUnboxedDouble; }
+ virtual Representation representation() const { return representation_; }
virtual Representation RequiredInputRepresentation(intptr_t idx) const {
ASSERT(idx == 0);
- return kUnboxedDouble;
+ return representation_;
}
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
@@ -8337,7 +8346,8 @@
}
virtual bool AttributesEqual(const Instruction& other) const {
- return speculative_mode_ == other.AsUnaryDoubleOp()->speculative_mode_;
+ return (speculative_mode_ == other.AsUnaryDoubleOp()->speculative_mode_) &&
+ (representation_ == other.AsUnaryDoubleOp()->representation_);
}
PRINT_OPERANDS_TO_SUPPORT
@@ -8345,6 +8355,7 @@
private:
const Token::Kind op_kind_;
const SpeculativeMode speculative_mode_;
+ const Representation representation_;
DISALLOW_COPY_AND_ASSIGN(UnaryDoubleOpInstr);
};
@@ -8574,51 +8585,6 @@
DISALLOW_COPY_AND_ASSIGN(DoubleToSmiInstr);
};
-class DoubleToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> {
- public:
- DoubleToDoubleInstr(Value* value,
- MethodRecognizer::Kind recognized_kind,
- intptr_t deopt_id)
- : TemplateDefinition(deopt_id), recognized_kind_(recognized_kind) {
- ASSERT((recognized_kind == MethodRecognizer::kDoubleTruncateToDouble) ||
- (recognized_kind == MethodRecognizer::kDoubleFloorToDouble) ||
- (recognized_kind == MethodRecognizer::kDoubleCeilToDouble));
- SetInputAt(0, value);
- }
-
- Value* value() const { return inputs_[0]; }
-
- MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; }
-
- DECLARE_INSTRUCTION(DoubleToDouble)
- virtual CompileType ComputeType() const;
-
- virtual bool ComputeCanDeoptimize() const { return false; }
-
- virtual Representation representation() const { return kUnboxedDouble; }
-
- virtual Representation RequiredInputRepresentation(intptr_t idx) const {
- ASSERT(idx == 0);
- return kUnboxedDouble;
- }
-
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
- ASSERT(idx == 0);
- return kNotSpeculative;
- }
-
- virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }
-
- virtual bool AttributesEqual(const Instruction& other) const {
- return other.AsDoubleToDouble()->recognized_kind() == recognized_kind();
- }
-
- private:
- const MethodRecognizer::Kind recognized_kind_;
-
- DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleInstr);
-};
-
class DoubleToFloatInstr : public TemplateDefinition<1, NoThrow, Pure> {
public:
DoubleToFloatInstr(Value* value,
@@ -8691,6 +8657,42 @@
DISALLOW_COPY_AND_ASSIGN(FloatToDoubleInstr);
};
+// left op right ? -1 : 0
+class FloatCompareInstr : public TemplateDefinition<2, NoThrow, Pure> {
+ public:
+ FloatCompareInstr(Token::Kind op_kind, Value* left, Value* right)
+ : op_kind_(op_kind) {
+ SetInputAt(0, left);
+ SetInputAt(1, right);
+ }
+
+ Value* left() const { return inputs_[0]; }
+ Value* right() const { return inputs_[1]; }
+
+ Token::Kind op_kind() const { return op_kind_; }
+
+ DECLARE_INSTRUCTION(FloatCompare)
+
+ virtual CompileType ComputeType() const;
+
+ virtual bool ComputeCanDeoptimize() const { return false; }
+
+ virtual Representation representation() const { return kUnboxedInt32; }
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+ return kUnboxedFloat;
+ }
+
+ virtual bool AttributesEqual(const Instruction& other) const {
+ return other.AsFloatCompare()->op_kind() == op_kind();
+ }
+
+ private:
+ const Token::Kind op_kind_;
+
+ DISALLOW_COPY_AND_ASSIGN(FloatCompareInstr);
+};
+
// TODO(sjindel): Replace with FFICallInstr.
class InvokeMathCFunctionInstr : public PureDefinition {
public:
@@ -8803,6 +8805,136 @@
DISALLOW_COPY_AND_ASSIGN(ExtractNthOutputInstr);
};
+class UnboxLaneInstr : public TemplateDefinition<1, NoThrow, Pure> {
+ public:
+ UnboxLaneInstr(Value* value,
+ intptr_t n,
+ Representation definition_rep,
+ intptr_t definition_cid)
+ : lane_(n),
+ definition_rep_(definition_rep),
+ definition_cid_(definition_cid) {
+ SetInputAt(0, value);
+ }
+
+ Value* value() const { return inputs_[0]; }
+
+ DECLARE_INSTRUCTION(UnboxLane)
+
+ virtual CompileType ComputeType() const;
+ virtual bool ComputeCanDeoptimize() const { return false; }
+
+ intptr_t lane() const { return lane_; }
+
+ virtual Representation representation() const { return definition_rep_; }
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+ ASSERT(idx == 0);
+ return kTagged;
+ }
+
+ virtual bool AttributesEqual(const Instruction& other) const {
+ auto const other_split = other.AsUnboxLane();
+ return (other_split->representation() == representation()) &&
+ (other_split->lane() == lane());
+ }
+
+ Definition* Canonicalize(FlowGraph* flow_graph);
+
+ PRINT_OPERANDS_TO_SUPPORT
+
+ private:
+ const intptr_t lane_;
+ const Representation definition_rep_;
+ const intptr_t definition_cid_;
+ DISALLOW_COPY_AND_ASSIGN(UnboxLaneInstr);
+};
+
+class BoxLanesInstr : public TemplateDefinition<4, NoThrow, Pure> {
+ public:
+ BoxLanesInstr(Representation from_representation, Value* x, Value* y)
+ : from_representation_(from_representation) {
+ ASSERT(from_representation == kUnboxedDouble);
+ ASSERT(x->definition()->representation() == from_representation);
+ ASSERT(y->definition()->representation() == from_representation);
+ SetInputAt(0, x);
+ SetInputAt(1, y);
+ }
+ BoxLanesInstr(Representation from_representation,
+ Value* x,
+ Value* y,
+ Value* z,
+ Value* w)
+ : from_representation_(from_representation) {
+ ASSERT((from_representation == kUnboxedInt32) ||
+ (from_representation == kUnboxedFloat));
+ ASSERT(x->definition()->representation() == from_representation);
+ ASSERT(y->definition()->representation() == from_representation);
+ ASSERT(z->definition()->representation() == from_representation);
+ ASSERT(w->definition()->representation() == from_representation);
+ SetInputAt(0, x);
+ SetInputAt(1, y);
+ SetInputAt(2, z);
+ SetInputAt(3, w);
+ }
+
+ intptr_t InputCount() const {
+ switch (from_representation_) {
+ case kUnboxedDouble:
+ return 2;
+ case kUnboxedFloat:
+ return 4;
+ case kUnboxedInt32:
+ return 4;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+ }
+ Value* x() const { return inputs_[0]; }
+ Value* y() const { return inputs_[1]; }
+ Value* z() const {
+ ASSERT((from_representation() == kUnboxedInt32) ||
+ (from_representation() == kUnboxedFloat));
+ return inputs_[2];
+ }
+ Value* w() const {
+ ASSERT((from_representation() == kUnboxedInt32) ||
+ (from_representation() == kUnboxedFloat));
+ return inputs_[3];
+ }
+ Representation from_representation() const { return from_representation_; }
+
+ DECLARE_INSTRUCTION(BoxLanes)
+ virtual CompileType ComputeType() const;
+
+ virtual bool ComputeCanDeoptimize() const { return false; }
+ virtual intptr_t DeoptimizationTarget() const { return DeoptId::kNone; }
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+ ASSERT(idx == 0 || idx == 1 || idx == 2 || idx == 3);
+ return from_representation();
+ }
+
+ virtual bool AttributesEqual(const Instruction& other) const {
+ return other.AsBoxLanes()->from_representation() == from_representation();
+ }
+
+ Definition* Canonicalize(FlowGraph* flow_graph);
+
+ virtual TokenPosition token_pos() const { return TokenPosition::kBox; }
+
+ virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
+ return kNotSpeculative;
+ }
+
+ PRINT_OPERANDS_TO_SUPPORT
+
+ private:
+ const Representation from_representation_;
+ DISALLOW_COPY_AND_ASSIGN(BoxLanesInstr);
+};
+
class TruncDivModInstr : public TemplateDefinition<2, NoThrow, Pure> {
public:
TruncDivModInstr(Value* lhs, Value* rhs, intptr_t deopt_id);
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index e4bc74b..0e131fa 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -698,11 +698,10 @@
}
} else if (destination.IsFpuRegister()) {
const DRegister dst = EvenDRegisterOf(destination.fpu_reg());
- if (Utils::DoublesBitEqual(Double::Cast(value_).value(), 0.0) &&
- TargetCPUFeatures::neon_supported()) {
- QRegister qdst = destination.fpu_reg();
- __ veorq(qdst, qdst, qdst);
+ if (representation() == kUnboxedFloat) {
+ __ LoadSImmediate(EvenSRegisterOf(dst), Double::Cast(value_).value());
} else {
+ ASSERT(representation() == kUnboxedDouble);
ASSERT(tmp != kNoRegister);
__ LoadDImmediate(dst, Double::Cast(value_).value(), tmp);
}
@@ -5704,33 +5703,6 @@
#undef DEFINE_EMIT
-LocationSummary* MathUnaryInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
- ASSERT((kind() == MathUnaryInstr::kSqrt) ||
- (kind() == MathUnaryInstr::kDoubleSquare));
- const intptr_t kNumInputs = 1;
- const intptr_t kNumTemps = 0;
- LocationSummary* summary = new (zone)
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresFpuRegister());
- summary->set_out(0, Location::RequiresFpuRegister());
- return summary;
-}
-
-void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- if (kind() == MathUnaryInstr::kSqrt) {
- const DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg());
- const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
- __ vsqrtd(result, val);
- } else if (kind() == MathUnaryInstr::kDoubleSquare) {
- const DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg());
- const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
- __ vmuld(result, val, val);
- } else {
- UNREACHABLE();
- }
-}
-
LocationSummary* CaseInsensitiveCompareInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {
@@ -5883,9 +5855,22 @@
}
void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ ASSERT(representation() == kUnboxedDouble);
const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg());
- __ vnegd(result, value);
+ switch (op_kind()) {
+ case Token::kNEGATE:
+ __ vnegd(result, value);
+ break;
+ case Token::kSQRT:
+ __ vsqrtd(result, value);
+ break;
+ case Token::kSQUARE:
+ __ vmuld(result, value, value);
+ break;
+ default:
+ UNREACHABLE();
+ }
}
LocationSummary* Int32ToDoubleInstr::MakeLocationSummary(Zone* zone,
@@ -6000,16 +5985,6 @@
__ SmiTag(result);
}
-LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
- UNIMPLEMENTED();
- return NULL;
-}
-
-void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
-}
-
LocationSummary* DoubleToFloatInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 1;
@@ -6048,6 +6023,16 @@
__ vcvtds(result, value);
}
+LocationSummary* FloatCompareInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void FloatCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
ASSERT((InputCount() == 1) || (InputCount() == 2));
@@ -6298,6 +6283,26 @@
}
}
+LocationSummary* UnboxLaneInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void UnboxLaneInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
+LocationSummary* BoxLanesInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void BoxLanesInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* TruncDivModInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 2;
@@ -7577,6 +7582,26 @@
compiler::Operand(compiler::target::ObjectAlignment::kBoolValueMask));
}
+LocationSummary* BoolToIntInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void BoolToIntInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
+LocationSummary* IntToBoolInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void IntToBoolInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = (type_arguments() != nullptr) ? 1 : 0;
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index ca277fb..e61557a 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -625,6 +625,12 @@
} else if (destination.IsFpuRegister()) {
const VRegister dst = destination.fpu_reg();
__ LoadDImmediate(dst, Double::Cast(value_).value());
+ if (representation() == kUnboxedFloat) {
+ __ LoadSImmediate(dst, Double::Cast(value_).value());
+ } else {
+ ASSERT(representation() == kUnboxedDouble);
+ __ LoadDImmediate(dst, Double::Cast(value_).value());
+ }
} else if (destination.IsDoubleStackSlot()) {
const intptr_t dest_offset = destination.ToStackSlotOffset();
if (Utils::DoublesBitEqual(Double::Cast(value_).value(), 0.0)) {
@@ -4796,33 +4802,6 @@
#undef DEFINE_EMIT
-LocationSummary* MathUnaryInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
- ASSERT((kind() == MathUnaryInstr::kSqrt) ||
- (kind() == MathUnaryInstr::kDoubleSquare));
- const intptr_t kNumInputs = 1;
- const intptr_t kNumTemps = 0;
- LocationSummary* summary = new (zone)
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresFpuRegister());
- summary->set_out(0, Location::RequiresFpuRegister());
- return summary;
-}
-
-void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- if (kind() == MathUnaryInstr::kSqrt) {
- const VRegister val = locs()->in(0).fpu_reg();
- const VRegister result = locs()->out(0).fpu_reg();
- __ fsqrtd(result, val);
- } else if (kind() == MathUnaryInstr::kDoubleSquare) {
- const VRegister val = locs()->in(0).fpu_reg();
- const VRegister result = locs()->out(0).fpu_reg();
- __ fmuld(result, val, val);
- } else {
- UNREACHABLE();
- }
-}
-
LocationSummary* CaseInsensitiveCompareInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {
@@ -4975,9 +4954,22 @@
}
void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ ASSERT(representation() == kUnboxedDouble);
const VRegister result = locs()->out(0).fpu_reg();
const VRegister value = locs()->in(0).fpu_reg();
- __ fnegd(result, value);
+ switch (op_kind()) {
+ case Token::kNEGATE:
+ __ fnegd(result, value);
+ break;
+ case Token::kSQRT:
+ __ fsqrtd(result, value);
+ break;
+ case Token::kSQUARE:
+ __ fmuld(result, value, value);
+ break;
+ default:
+ UNREACHABLE();
+ }
}
LocationSummary* Int32ToDoubleInstr::MakeLocationSummary(Zone* zone,
@@ -5126,16 +5118,6 @@
__ SmiTag(result);
}
-LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
- UNIMPLEMENTED();
- return NULL;
-}
-
-void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
-}
-
LocationSummary* DoubleToFloatInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 1;
@@ -5170,6 +5152,16 @@
__ fcvtds(result, value);
}
+LocationSummary* FloatCompareInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void FloatCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
ASSERT((InputCount() == 1) || (InputCount() == 2));
@@ -5372,6 +5364,26 @@
}
}
+LocationSummary* UnboxLaneInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void UnboxLaneInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
+LocationSummary* BoxLanesInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void BoxLanesInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* TruncDivModInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 2;
@@ -6675,6 +6687,26 @@
compiler::Immediate(compiler::target::ObjectAlignment::kBoolValueMask));
}
+LocationSummary* BoolToIntInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void BoolToIntInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
+LocationSummary* IntToBoolInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void IntToBoolInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = (type_arguments() != nullptr) ? 1 : 0;
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index b84f33e..4d24aa2 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -421,18 +421,23 @@
__ LoadObjectSafely(destination.reg(), value_);
}
} else if (destination.IsFpuRegister()) {
- const double value_as_double = Double::Cast(value_).value();
- uword addr = FindDoubleConstant(value_as_double);
- if (addr == 0) {
- __ pushl(EAX);
- __ LoadObject(EAX, value_);
- __ movsd(destination.fpu_reg(),
- compiler::FieldAddress(EAX, Double::value_offset()));
- __ popl(EAX);
- } else if (Utils::DoublesBitEqual(value_as_double, 0.0)) {
- __ xorps(destination.fpu_reg(), destination.fpu_reg());
+ if (representation() == kUnboxedFloat) {
+ __ LoadSImmediate(destination.fpu_reg(),
+ static_cast<float>(Double::Cast(value_).value()));
} else {
- __ movsd(destination.fpu_reg(), compiler::Address::Absolute(addr));
+ const double value_as_double = Double::Cast(value_).value();
+ uword addr = FindDoubleConstant(value_as_double);
+ if (addr == 0) {
+ __ pushl(EAX);
+ __ LoadObject(EAX, value_);
+ __ movsd(destination.fpu_reg(),
+ compiler::FieldAddress(EAX, Double::value_offset()));
+ __ popl(EAX);
+ } else if (Utils::DoublesBitEqual(value_as_double, 0.0)) {
+ __ xorps(destination.fpu_reg(), destination.fpu_reg());
+ } else {
+ __ movsd(destination.fpu_reg(), compiler::Address::Absolute(addr));
+ }
}
} else if (destination.IsDoubleStackSlot()) {
const double value_as_double = Double::Cast(value_).value();
@@ -4817,35 +4822,6 @@
#undef DEFINE_EMIT
-LocationSummary* MathUnaryInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
- ASSERT((kind() == MathUnaryInstr::kSqrt) ||
- (kind() == MathUnaryInstr::kDoubleSquare));
- const intptr_t kNumInputs = 1;
- const intptr_t kNumTemps = 0;
- LocationSummary* summary = new (zone)
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresFpuRegister());
- if (kind() == MathUnaryInstr::kDoubleSquare) {
- summary->set_out(0, Location::SameAsFirstInput());
- } else {
- summary->set_out(0, Location::RequiresFpuRegister());
- }
- return summary;
-}
-
-void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- if (kind() == MathUnaryInstr::kSqrt) {
- __ sqrtsd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
- } else if (kind() == MathUnaryInstr::kDoubleSquare) {
- XmmRegister value_reg = locs()->in(0).fpu_reg();
- __ mulsd(value_reg, value_reg);
- ASSERT(value_reg == locs()->out(0).fpu_reg());
- } else {
- UNREACHABLE();
- }
-}
-
LocationSummary* CaseInsensitiveCompareInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {
@@ -5001,9 +4977,31 @@
}
void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ ASSERT(representation() == kUnboxedDouble);
XmmRegister value = locs()->in(0).fpu_reg();
ASSERT(locs()->out(0).fpu_reg() == value);
- __ DoubleNegate(value);
+ switch (op_kind()) {
+ case Token::kNEGATE:
+ __ DoubleNegate(value);
+ break;
+ case Token::kSQRT:
+ __ sqrtsd(value, value);
+ break;
+ case Token::kSQUARE:
+ __ mulsd(value, value);
+ break;
+ case Token::kTRUNCATE:
+ __ roundsd(value, value, compiler::Assembler::kRoundToZero);
+ break;
+ case Token::kFLOOR:
+ __ roundsd(value, value, compiler::Assembler::kRoundDown);
+ break;
+ case Token::kCEILING:
+ __ roundsd(value, value, compiler::Assembler::kRoundUp);
+ break;
+ default:
+ UNREACHABLE();
+ }
}
LocationSummary* Int32ToDoubleInstr::MakeLocationSummary(Zone* zone,
@@ -5126,35 +5124,6 @@
__ SmiTag(result);
}
-LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
- const intptr_t kNumInputs = 1;
- const intptr_t kNumTemps = 0;
- LocationSummary* result = new (zone)
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- result->set_in(0, Location::RequiresFpuRegister());
- result->set_out(0, Location::RequiresFpuRegister());
- return result;
-}
-
-void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- XmmRegister value = locs()->in(0).fpu_reg();
- XmmRegister result = locs()->out(0).fpu_reg();
- switch (recognized_kind()) {
- case MethodRecognizer::kDoubleTruncateToDouble:
- __ roundsd(result, value, compiler::Assembler::kRoundToZero);
- break;
- case MethodRecognizer::kDoubleFloorToDouble:
- __ roundsd(result, value, compiler::Assembler::kRoundDown);
- break;
- case MethodRecognizer::kDoubleCeilToDouble:
- __ roundsd(result, value, compiler::Assembler::kRoundUp);
- break;
- default:
- UNREACHABLE();
- }
-}
-
LocationSummary* DoubleToFloatInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 1;
@@ -5185,6 +5154,16 @@
__ cvtss2sd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
}
+LocationSummary* FloatCompareInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void FloatCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
ASSERT((InputCount() == 1) || (InputCount() == 2));
@@ -5411,6 +5390,26 @@
}
}
+LocationSummary* UnboxLaneInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void UnboxLaneInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
+LocationSummary* BoxLanesInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void BoxLanesInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* TruncDivModInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 2;
@@ -6662,6 +6661,26 @@
compiler::target::ObjectAlignment::kBoolValueMask));
}
+LocationSummary* BoolToIntInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void BoolToIntInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
+LocationSummary* IntToBoolInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void IntToBoolInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = (type_arguments() != nullptr) ? 1 : 0;
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index 05b7050..da9c0c9 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -484,7 +484,9 @@
range_->PrintTo(f);
}
- if (type_ != NULL) {
+ if (representation() != kNoRepresentation && representation() != kTagged) {
+ f->Printf(" %s", RepresentationToCString(representation()));
+ } else if (type_ != NULL) {
f->AddString(" ");
type_->PrintTo(f);
}
@@ -553,10 +555,6 @@
buffer[pos] = '\0';
f->Printf("#%s\\n...", buffer);
}
-
- if (representation() != kNoRepresentation && representation() != kTagged) {
- f->Printf(" %s", RepresentationToCString(representation()));
- }
}
void ConstraintInstr::PrintOperandsTo(BaseTextBuffer* f) const {
@@ -910,11 +908,6 @@
TemplateAllocation::PrintOperandsTo(f);
}
-void MathUnaryInstr::PrintOperandsTo(BaseTextBuffer* f) const {
- f->Printf("'%s', ", MathUnaryInstr::KindToCString(kind()));
- value()->PrintTo(f);
-}
-
void TruncDivModInstr::PrintOperandsTo(BaseTextBuffer* f) const {
Definition::PrintOperandsTo(f);
}
@@ -924,6 +917,15 @@
Definition::PrintOperandsTo(f);
}
+void UnboxLaneInstr::PrintOperandsTo(BaseTextBuffer* f) const {
+ Definition::PrintOperandsTo(f);
+ f->Printf(", lane %" Pd, lane());
+}
+
+void BoxLanesInstr::PrintOperandsTo(BaseTextBuffer* f) const {
+ Definition::PrintOperandsTo(f);
+}
+
void UnaryIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
f->Printf("%s, ", Token::Str(op_kind()));
value()->PrintTo(f);
diff --git a/runtime/vm/compiler/backend/il_riscv.cc b/runtime/vm/compiler/backend/il_riscv.cc
index 041f180..2222f9b 100644
--- a/runtime/vm/compiler/backend/il_riscv.cc
+++ b/runtime/vm/compiler/backend/il_riscv.cc
@@ -715,7 +715,12 @@
}
} else if (destination.IsFpuRegister()) {
const FRegister dst = destination.fpu_reg();
- __ LoadDImmediate(dst, Double::Cast(value_).value());
+ if (representation() == kUnboxedFloat) {
+ __ LoadSImmediate(dst, Double::Cast(value_).value());
+ } else {
+ ASSERT(representation() == kUnboxedDouble);
+ __ LoadDImmediate(dst, Double::Cast(value_).value());
+ }
} else if (destination.IsDoubleStackSlot()) {
const intptr_t dest_offset = destination.ToStackSlotOffset();
#if XLEN == 32
@@ -1198,7 +1203,7 @@
__ CompareImmediate(TMP, 0);
return NE;
case Token::kGT:
- __ fltd(TMP, right, left);
+ __ fgtd(TMP, left, right);
__ CompareImmediate(TMP, 0);
return NE;
case Token::kLTE:
@@ -1206,7 +1211,7 @@
__ CompareImmediate(TMP, 0);
return NE;
case Token::kGTE:
- __ fled(TMP, right, left);
+ __ fged(TMP, left, right);
__ CompareImmediate(TMP, 0);
return NE;
default:
@@ -3363,9 +3368,11 @@
__ LoadDFieldFromOffset(result, temp, Double::value_offset());
break;
case kFloat32x4Cid:
+ __ Comment("UnboxedFloat32x4LoadFieldInstr");
UNIMPLEMENTED();
break;
case kFloat64x2Cid:
+ __ Comment("UnboxedFloat64x2LoadFieldInstr");
UNIMPLEMENTED();
break;
default:
@@ -4434,6 +4441,16 @@
}
#endif
+ case kUnboxedFloat: {
+ const FRegister result = locs()->out(0).fpu_reg();
+ __ SmiUntag(TMP, box);
+#if XLEN == 32
+ __ fcvtsw(result, TMP);
+#elif XLEN == 64
+ __ fcvtsl(result, TMP);
+#endif
+ break;
+ }
case kUnboxedDouble: {
const FRegister result = locs()->out(0).fpu_reg();
__ SmiUntag(TMP, box);
@@ -4808,21 +4825,53 @@
const FRegister left = locs()->in(0).fpu_reg();
const FRegister right = locs()->in(1).fpu_reg();
const FRegister result = locs()->out(0).fpu_reg();
- switch (op_kind()) {
- case Token::kADD:
- __ faddd(result, left, right);
- break;
- case Token::kSUB:
- __ fsubd(result, left, right);
- break;
- case Token::kMUL:
- __ fmuld(result, left, right);
- break;
- case Token::kDIV:
- __ fdivd(result, left, right);
- break;
- default:
- UNREACHABLE();
+ if (representation() == kUnboxedDouble) {
+ switch (op_kind()) {
+ case Token::kADD:
+ __ faddd(result, left, right);
+ break;
+ case Token::kSUB:
+ __ fsubd(result, left, right);
+ break;
+ case Token::kMUL:
+ __ fmuld(result, left, right);
+ break;
+ case Token::kDIV:
+ __ fdivd(result, left, right);
+ break;
+ case Token::kMIN:
+ __ fmind(result, left, right);
+ break;
+ case Token::kMAX:
+ __ fmaxd(result, left, right);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ } else {
+ ASSERT(representation() == kUnboxedFloat);
+ switch (op_kind()) {
+ case Token::kADD:
+ __ fadds(result, left, right);
+ break;
+ case Token::kSUB:
+ __ fsubs(result, left, right);
+ break;
+ case Token::kMUL:
+ __ fmuls(result, left, right);
+ break;
+ case Token::kDIV:
+ __ fdivs(result, left, right);
+ break;
+ case Token::kMIN:
+ __ fmins(result, left, right);
+ break;
+ case Token::kMAX:
+ __ fmaxs(result, left, right);
+ break;
+ default:
+ UNREACHABLE();
+ }
}
}
@@ -4853,259 +4902,13 @@
return kind() == Token::kEQ ? NOT_ZERO : ZERO;
}
-// SIMD
-
-#define DEFINE_EMIT(Name, Args) \
- static void Emit##Name(FlowGraphCompiler* compiler, SimdOpInstr* instr, \
- PP_APPLY(PP_UNPACK, Args))
-
-#define SIMD_OP_FLOAT_ARITH(V, Name, op) \
- V(Float32x4##Name, op##s) \
- V(Float64x2##Name, op##d)
-
-#define SIMD_OP_SIMPLE_BINARY(V) \
- SIMD_OP_FLOAT_ARITH(V, Add, vadd) \
- SIMD_OP_FLOAT_ARITH(V, Sub, vsub) \
- SIMD_OP_FLOAT_ARITH(V, Mul, vmul) \
- SIMD_OP_FLOAT_ARITH(V, Div, vdiv) \
- SIMD_OP_FLOAT_ARITH(V, Min, vmin) \
- SIMD_OP_FLOAT_ARITH(V, Max, vmax) \
- V(Int32x4Add, vaddw) \
- V(Int32x4Sub, vsubw) \
- V(Int32x4BitAnd, vand) \
- V(Int32x4BitOr, vorr) \
- V(Int32x4BitXor, veor) \
- V(Float32x4Equal, vceqs) \
- V(Float32x4GreaterThan, vcgts) \
- V(Float32x4GreaterThanOrEqual, vcges)
-
-DEFINE_EMIT(SimdBinaryOp, (FRegister result, FRegister left, FRegister right)) {
- UNIMPLEMENTED();
-}
-
-#define SIMD_OP_SIMPLE_UNARY(V) \
- SIMD_OP_FLOAT_ARITH(V, Sqrt, vsqrt) \
- SIMD_OP_FLOAT_ARITH(V, Negate, vneg) \
- SIMD_OP_FLOAT_ARITH(V, Abs, vabs) \
- V(Float32x4Reciprocal, VRecps) \
- V(Float32x4ReciprocalSqrt, VRSqrts)
-
-DEFINE_EMIT(SimdUnaryOp, (FRegister result, FRegister value)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(Simd32x4GetSignMask,
- (Register out, FRegister value, Temp<Register> temp)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(
- Float32x4FromDoubles,
- (FRegister r, FRegister v0, FRegister v1, FRegister v2, FRegister v3)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(
- Float32x4Clamp,
- (FRegister result, FRegister value, FRegister lower, FRegister upper)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(
- Float64x2Clamp,
- (FRegister result, FRegister value, FRegister lower, FRegister upper)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(Float32x4With,
- (FRegister result, FRegister replacement, FRegister value)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(Simd32x4ToSimd32x4, (SameAsFirstInput, FRegister value)) {
- // TODO(dartbug.com/30949) these operations are essentially nop and should
- // not generate any code. They should be removed from the graph before
- // code generation.
-}
-
-DEFINE_EMIT(SimdZero, (FRegister v)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(Float64x2GetSignMask, (Register out, FRegister value)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(Float64x2With,
- (SameAsFirstInput, FRegister left, FRegister right)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(
- Int32x4FromInts,
- (FRegister result, Register v0, Register v1, Register v2, Register v3)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(Int32x4FromBools,
- (FRegister result,
- Register v0,
- Register v1,
- Register v2,
- Register v3,
- Temp<Register> temp)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(Int32x4GetFlag, (Register result, FRegister value)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(Int32x4Select,
- (FRegister out,
- FRegister mask,
- FRegister trueValue,
- FRegister falseValue,
- Temp<FRegister> temp)) {
- UNIMPLEMENTED();
-}
-
-DEFINE_EMIT(Int32x4WithFlag,
- (SameAsFirstInput, FRegister mask, Register flag)) {
- UNIMPLEMENTED();
-}
-
-// Map SimdOpInstr::Kind-s to corresponding emit functions. Uses the following
-// format:
-//
-// CASE(OpA) CASE(OpB) ____(Emitter) - Emitter is used to emit OpA and OpB.
-// SIMPLE(OpA) - Emitter with name OpA is used to emit OpA.
-//
-#define SIMD_OP_VARIANTS(CASE, ____) \
- SIMD_OP_SIMPLE_BINARY(CASE) \
- CASE(Float32x4ShuffleMix) \
- CASE(Int32x4ShuffleMix) \
- CASE(Float32x4NotEqual) \
- CASE(Float32x4LessThan) \
- CASE(Float32x4LessThanOrEqual) \
- CASE(Float32x4Scale) \
- CASE(Float64x2FromDoubles) \
- CASE(Float64x2Scale) \
- ____(SimdBinaryOp) \
- SIMD_OP_SIMPLE_UNARY(CASE) \
- CASE(Float32x4GetX) \
- CASE(Float32x4GetY) \
- CASE(Float32x4GetZ) \
- CASE(Float32x4GetW) \
- CASE(Int32x4Shuffle) \
- CASE(Float32x4Shuffle) \
- CASE(Float32x4Splat) \
- CASE(Float64x2GetX) \
- CASE(Float64x2GetY) \
- CASE(Float64x2Splat) \
- CASE(Float64x2ToFloat32x4) \
- CASE(Float32x4ToFloat64x2) \
- ____(SimdUnaryOp) \
- CASE(Float32x4GetSignMask) \
- CASE(Int32x4GetSignMask) \
- ____(Simd32x4GetSignMask) \
- CASE(Float32x4FromDoubles) \
- ____(Float32x4FromDoubles) \
- CASE(Float32x4Zero) \
- CASE(Float64x2Zero) \
- ____(SimdZero) \
- CASE(Float32x4Clamp) \
- ____(Float32x4Clamp) \
- CASE(Float64x2Clamp) \
- ____(Float64x2Clamp) \
- CASE(Float32x4WithX) \
- CASE(Float32x4WithY) \
- CASE(Float32x4WithZ) \
- CASE(Float32x4WithW) \
- ____(Float32x4With) \
- CASE(Float32x4ToInt32x4) \
- CASE(Int32x4ToFloat32x4) \
- ____(Simd32x4ToSimd32x4) \
- CASE(Float64x2GetSignMask) \
- ____(Float64x2GetSignMask) \
- CASE(Float64x2WithX) \
- CASE(Float64x2WithY) \
- ____(Float64x2With) \
- CASE(Int32x4FromInts) \
- ____(Int32x4FromInts) \
- CASE(Int32x4FromBools) \
- ____(Int32x4FromBools) \
- CASE(Int32x4GetFlagX) \
- CASE(Int32x4GetFlagY) \
- CASE(Int32x4GetFlagZ) \
- CASE(Int32x4GetFlagW) \
- ____(Int32x4GetFlag) \
- CASE(Int32x4Select) \
- ____(Int32x4Select) \
- CASE(Int32x4WithFlagX) \
- CASE(Int32x4WithFlagY) \
- CASE(Int32x4WithFlagZ) \
- CASE(Int32x4WithFlagW) \
- ____(Int32x4WithFlag)
-
LocationSummary* SimdOpInstr::MakeLocationSummary(Zone* zone, bool opt) const {
- switch (kind()) {
-#define CASE(Name, ...) case k##Name:
-#define EMIT(Name) \
- return MakeLocationSummaryFromEmitter(zone, this, &Emit##Name);
- SIMD_OP_VARIANTS(CASE, EMIT)
-#undef CASE
-#undef EMIT
- case kIllegalSimdOp:
- UNREACHABLE();
- break;
- }
UNREACHABLE();
return NULL;
}
void SimdOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- switch (kind()) {
-#define CASE(Name, ...) case k##Name:
-#define EMIT(Name) \
- InvokeEmitter(compiler, this, &Emit##Name); \
- break;
- SIMD_OP_VARIANTS(CASE, EMIT)
-#undef CASE
-#undef EMIT
- case kIllegalSimdOp:
- UNREACHABLE();
- break;
- }
-}
-
-#undef DEFINE_EMIT
-
-LocationSummary* MathUnaryInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
- ASSERT((kind() == MathUnaryInstr::kSqrt) ||
- (kind() == MathUnaryInstr::kDoubleSquare));
- const intptr_t kNumInputs = 1;
- const intptr_t kNumTemps = 0;
- LocationSummary* summary = new (zone)
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresFpuRegister());
- summary->set_out(0, Location::RequiresFpuRegister());
- return summary;
-}
-
-void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- if (kind() == MathUnaryInstr::kSqrt) {
- const FRegister val = locs()->in(0).fpu_reg();
- const FRegister result = locs()->out(0).fpu_reg();
- __ fsqrtd(result, val);
- } else if (kind() == MathUnaryInstr::kDoubleSquare) {
- const FRegister val = locs()->in(0).fpu_reg();
- const FRegister result = locs()->out(0).fpu_reg();
- __ fmuld(result, val, val);
- } else {
- UNREACHABLE();
- }
+ UNREACHABLE();
}
LocationSummary* CaseInsensitiveCompareInstr::MakeLocationSummary(
@@ -5249,7 +5052,53 @@
void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const FRegister result = locs()->out(0).fpu_reg();
const FRegister value = locs()->in(0).fpu_reg();
- __ fnegd(result, value);
+ if (representation() == kUnboxedDouble) {
+ switch (op_kind()) {
+ case Token::kABS:
+ __ fabsd(result, value);
+ break;
+ case Token::kNEGATE:
+ __ fnegd(result, value);
+ break;
+ case Token::kSQRT:
+ __ fsqrtd(result, value);
+ break;
+ case Token::kSQUARE:
+ __ fmuld(result, value, value);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ } else {
+ ASSERT(representation() == kUnboxedFloat);
+ switch (op_kind()) {
+ case Token::kABS:
+ __ fabss(result, value);
+ break;
+ case Token::kNEGATE:
+ __ fnegs(result, value);
+ break;
+ case Token::kRECIPROCAL:
+ __ li(TMP, 1);
+ __ fcvtsw(FTMP, TMP);
+ __ fdivs(result, FTMP, value);
+ break;
+ case Token::kRECIPROCAL_SQRT:
+ __ li(TMP, 1);
+ __ fcvtsw(FTMP, TMP);
+ __ fdivs(result, FTMP, value);
+ __ fsqrts(result, result);
+ break;
+ case Token::kSQRT:
+ __ fsqrts(result, value);
+ break;
+ case Token::kSQUARE:
+ __ fmuls(result, value, value);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
}
LocationSummary* Int32ToDoubleInstr::MakeLocationSummary(Zone* zone,
@@ -5397,16 +5246,6 @@
__ bne(TMP, TMP2, deopt);
}
-LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
- UNIMPLEMENTED();
- return NULL;
-}
-
-void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
-}
-
LocationSummary* DoubleToFloatInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 1;
@@ -5441,6 +5280,45 @@
__ fcvtds(result, value);
}
+LocationSummary* FloatCompareInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ const intptr_t kNumInputs = 2;
+ const intptr_t kNumTemps = 0;
+ LocationSummary* result = new (zone)
+ LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ result->set_in(0, Location::RequiresFpuRegister());
+ result->set_in(1, Location::RequiresFpuRegister());
+ result->set_out(0, Location::RequiresRegister());
+ return result;
+}
+
+void FloatCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ const FRegister lhs = locs()->in(0).fpu_reg();
+ const FRegister rhs = locs()->in(1).fpu_reg();
+ const Register result = locs()->out(0).reg();
+
+ switch (op_kind()) {
+ case Token::kEQ:
+ __ feqs(result, lhs, rhs); // lhs op rhs ? 1 : 0
+ break;
+ case Token::kLT:
+ __ flts(result, lhs, rhs);
+ break;
+ case Token::kLTE:
+ __ fles(result, lhs, rhs);
+ break;
+ case Token::kGT:
+ __ fgts(result, lhs, rhs);
+ break;
+ case Token::kGTE:
+ __ fges(result, lhs, rhs);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ __ neg(result, result); // lhs op rhs ? -1 : 0
+}
+
LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
ASSERT((InputCount() == 1) || (InputCount() == 2));
@@ -5522,6 +5400,119 @@
}
}
+LocationSummary* UnboxLaneInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ const intptr_t kNumInputs = 1;
+ LocationSummary* summary =
+ new (zone) LocationSummary(zone, kNumInputs, 0, LocationSummary::kNoCall);
+ summary->set_in(0, Location::RequiresRegister());
+ switch (representation()) {
+ case kUnboxedDouble:
+ case kUnboxedFloat:
+ summary->set_out(0, Location::RequiresFpuRegister());
+ break;
+ case kUnboxedInt32:
+ summary->set_out(0, Location::RequiresRegister());
+ break;
+ default:
+ UNREACHABLE();
+ }
+ return summary;
+}
+
+void UnboxLaneInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ Register in = locs()->in(0).reg();
+ switch (representation()) {
+ case kUnboxedDouble:
+ __ fld(locs()->out(0).fpu_reg(),
+ compiler::FieldAddress(
+ in, compiler::target::Float64x2::value_offset() +
+ lane() * sizeof(double)));
+ break;
+ case kUnboxedFloat:
+ __ flw(locs()->out(0).fpu_reg(),
+ compiler::FieldAddress(
+ in, compiler::target::Float32x4::value_offset() +
+ lane() * sizeof(float)));
+ break;
+ case kUnboxedInt32:
+ __ lw(
+ locs()->out(0).reg(),
+ compiler::FieldAddress(in, compiler::target::Int32x4::value_offset() +
+ lane() * sizeof(int32_t)));
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+LocationSummary* BoxLanesInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ const intptr_t kNumInputs = InputCount();
+ LocationSummary* summary = new (zone)
+ LocationSummary(zone, kNumInputs, 0, LocationSummary::kCallOnSlowPath);
+ switch (from_representation()) {
+ case kUnboxedDouble:
+ summary->set_in(0, Location::RequiresFpuRegister());
+ summary->set_in(1, Location::RequiresFpuRegister());
+ break;
+ case kUnboxedFloat:
+ summary->set_in(0, Location::RequiresFpuRegister());
+ summary->set_in(1, Location::RequiresFpuRegister());
+ summary->set_in(2, Location::RequiresFpuRegister());
+ summary->set_in(3, Location::RequiresFpuRegister());
+ break;
+ case kUnboxedInt32:
+ summary->set_in(0, Location::RequiresRegister());
+ summary->set_in(1, Location::RequiresRegister());
+ summary->set_in(2, Location::RequiresRegister());
+ summary->set_in(3, Location::RequiresRegister());
+ break;
+ default:
+ UNREACHABLE();
+ }
+ summary->set_out(0, Location::RequiresRegister());
+ return summary;
+}
+
+void BoxLanesInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ Register result = locs()->out(0).reg();
+ switch (from_representation()) {
+ case kUnboxedDouble:
+ BoxAllocationSlowPath::Allocate(compiler, this,
+ compiler->float64x2_class(), result, TMP);
+ for (intptr_t i = 0; i < 2; i++) {
+ __ fsd(locs()->in(i).fpu_reg(),
+ compiler::FieldAddress(
+ result, compiler::target::Float64x2::value_offset() +
+ i * sizeof(double)));
+ }
+ break;
+ case kUnboxedFloat:
+ BoxAllocationSlowPath::Allocate(compiler, this,
+ compiler->float32x4_class(), result, TMP);
+ for (intptr_t i = 0; i < 4; i++) {
+ __ fsw(locs()->in(i).fpu_reg(),
+ compiler::FieldAddress(
+ result, compiler::target::Float32x4::value_offset() +
+ i * sizeof(float)));
+ }
+ break;
+ case kUnboxedInt32:
+ BoxAllocationSlowPath::Allocate(compiler, this, compiler->int32x4_class(),
+ result, TMP);
+ for (intptr_t i = 0; i < 4; i++) {
+ __ sw(locs()->in(i).reg(),
+ compiler::FieldAddress(result,
+ compiler::target::Int32x4::value_offset() +
+ i * sizeof(int32_t)));
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
LocationSummary* TruncDivModInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 2;
@@ -7615,6 +7606,36 @@
__ xori(result, input, compiler::target::ObjectAlignment::kBoolValueMask);
}
+LocationSummary* BoolToIntInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ return LocationSummary::Make(zone, 1, Location::RequiresRegister(),
+ LocationSummary::kNoCall);
+}
+
+void BoolToIntInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ const Register input = locs()->in(0).reg();
+ const Register result = locs()->out(0).reg();
+ __ LoadObject(TMP, Bool::True());
+ __ xor_(TMP, TMP, input);
+ __ seqz(TMP, TMP);
+ __ neg(result, TMP);
+}
+
+LocationSummary* IntToBoolInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ return LocationSummary::Make(zone, 1, Location::RequiresRegister(),
+ LocationSummary::kNoCall);
+}
+
+void IntToBoolInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ const Register input = locs()->in(0).reg();
+ const Register result = locs()->out(0).reg();
+ __ seqz(result, input);
+ __ slli(result, result, kBoolValueBitPosition);
+ __ add(result, result, NULL_REG);
+ __ addi(result, result, kTrueOffsetFromNull);
+}
+
LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = (type_arguments() != nullptr) ? 1 : 0;
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index b7bca3f..c91ed77 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -567,7 +567,12 @@
__ LoadObject(destination.reg(), value_);
}
} else if (destination.IsFpuRegister()) {
- __ LoadDImmediate(destination.fpu_reg(), Double::Cast(value_).value());
+ if (representation() == kUnboxedFloat) {
+ __ LoadSImmediate(destination.fpu_reg(), Double::Cast(value_).value());
+ } else {
+ ASSERT(representation() == kUnboxedDouble);
+ __ LoadDImmediate(destination.fpu_reg(), Double::Cast(value_).value());
+ }
} else if (destination.IsDoubleStackSlot()) {
__ LoadDImmediate(FpuTMP, Double::Cast(value_).value());
__ movsd(LocationToStackSlotAddress(destination), FpuTMP);
@@ -5043,35 +5048,6 @@
#undef DEFINE_EMIT
-LocationSummary* MathUnaryInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
- ASSERT((kind() == MathUnaryInstr::kSqrt) ||
- (kind() == MathUnaryInstr::kDoubleSquare));
- const intptr_t kNumInputs = 1;
- const intptr_t kNumTemps = 0;
- LocationSummary* summary = new (zone)
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresFpuRegister());
- if (kind() == MathUnaryInstr::kDoubleSquare) {
- summary->set_out(0, Location::SameAsFirstInput());
- } else {
- summary->set_out(0, Location::RequiresFpuRegister());
- }
- return summary;
-}
-
-void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- if (kind() == MathUnaryInstr::kSqrt) {
- __ sqrtsd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
- } else if (kind() == MathUnaryInstr::kDoubleSquare) {
- XmmRegister value_reg = locs()->in(0).fpu_reg();
- __ mulsd(value_reg, value_reg);
- ASSERT(value_reg == locs()->out(0).fpu_reg());
- } else {
- UNREACHABLE();
- }
-}
-
LocationSummary* CaseInsensitiveCompareInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {
@@ -5129,14 +5105,39 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresFpuRegister());
- summary->set_out(0, Location::SameAsFirstInput());
+ summary->set_out(0, Location::RequiresFpuRegister());
return summary;
}
void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ ASSERT(representation() == kUnboxedDouble);
+ XmmRegister result = locs()->out(0).fpu_reg();
XmmRegister value = locs()->in(0).fpu_reg();
- ASSERT(locs()->out(0).fpu_reg() == value);
- __ DoubleNegate(value, value);
+ switch (op_kind()) {
+ case Token::kNEGATE:
+ __ DoubleNegate(result, value);
+ break;
+ case Token::kSQRT:
+ __ sqrtsd(result, value);
+ break;
+ case Token::kSQUARE:
+ if (result != value) {
+ __ movsd(result, value);
+ }
+ __ mulsd(result, value);
+ break;
+ case Token::kTRUNCATE:
+ __ roundsd(result, value, compiler::Assembler::kRoundToZero);
+ break;
+ case Token::kFLOOR:
+ __ roundsd(result, value, compiler::Assembler::kRoundDown);
+ break;
+ case Token::kCEILING:
+ __ roundsd(result, value, compiler::Assembler::kRoundUp);
+ break;
+ default:
+ UNREACHABLE();
+ }
}
LocationSummary* MathMinMaxInstr::MakeLocationSummary(Zone* zone,
@@ -5361,40 +5362,6 @@
__ SmiTag(result);
}
-LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
- const intptr_t kNumInputs = 1;
- const intptr_t kNumTemps = 0;
- LocationSummary* result = new (zone)
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- result->set_in(0, Location::RequiresFpuRegister());
- result->set_out(0, Location::RequiresFpuRegister());
- return result;
-}
-
-void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- XmmRegister value = locs()->in(0).fpu_reg();
- XmmRegister result = locs()->out(0).fpu_reg();
- if (value != result) {
- // Clear full register to avoid false dependency due to
- // a partial access to XMM register in roundsd instruction.
- __ xorps(result, result);
- }
- switch (recognized_kind()) {
- case MethodRecognizer::kDoubleTruncateToDouble:
- __ roundsd(result, value, compiler::Assembler::kRoundToZero);
- break;
- case MethodRecognizer::kDoubleFloorToDouble:
- __ roundsd(result, value, compiler::Assembler::kRoundDown);
- break;
- case MethodRecognizer::kDoubleCeilToDouble:
- __ roundsd(result, value, compiler::Assembler::kRoundUp);
- break;
- default:
- UNREACHABLE();
- }
-}
-
LocationSummary* DoubleToFloatInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 1;
@@ -5425,6 +5392,16 @@
__ cvtss2sd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
}
+LocationSummary* FloatCompareInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void FloatCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
// Calling convention on x64 uses XMM0 and XMM1 to pass the first two
@@ -5650,6 +5627,26 @@
}
}
+LocationSummary* UnboxLaneInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void UnboxLaneInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
+LocationSummary* BoxLanesInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void BoxLanesInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* TruncDivModInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = 2;
@@ -7012,6 +7009,26 @@
compiler::target::ObjectAlignment::kBoolValueMask));
}
+LocationSummary* BoolToIntInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void BoolToIntInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
+LocationSummary* IntToBoolInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ UNREACHABLE();
+ return NULL;
+}
+
+void IntToBoolInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
const intptr_t kNumInputs = (type_arguments() != nullptr) ? 1 : 0;
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index dd8279d..7fdd085 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -78,6 +78,7 @@
"Max. number of inlined calls per depth");
DEFINE_FLAG(bool, print_inlining_tree, false, "Print inlining tree");
+DECLARE_FLAG(bool, enable_simd_inline);
DECLARE_FLAG(int, max_deoptimization_counter_threshold);
DECLARE_FLAG(bool, print_flow_graph);
DECLARE_FLAG(bool, print_flow_graph_optimized);
@@ -807,7 +808,8 @@
for (intptr_t i = 0; i < defns->length(); ++i) {
ConstantInstr* constant = (*defns)[i]->AsConstant();
if (constant != nullptr && constant->HasUses()) {
- constant->ReplaceUsesWith(caller_graph->GetConstant(constant->value()));
+ constant->ReplaceUsesWith(caller_graph->GetConstant(
+ constant->value(), constant->representation()));
}
}
@@ -815,7 +817,8 @@
for (intptr_t i = 0; i < defns->length(); ++i) {
ConstantInstr* constant = (*defns)[i]->AsConstant();
if (constant != nullptr && constant->HasUses()) {
- constant->ReplaceUsesWith(caller_graph->GetConstant(constant->value()));
+ constant->ReplaceUsesWith(caller_graph->GetConstant(
+ constant->value(), constant->representation()));
}
SpecialParameterInstr* param = (*defns)[i]->AsSpecialParameter();
@@ -3537,6 +3540,585 @@
return true;
}
+class SimdLowering : public ValueObject {
+ public:
+ SimdLowering(FlowGraph* flow_graph,
+ Instruction* call,
+ GraphEntryInstr* graph_entry,
+ FunctionEntryInstr** entry,
+ Instruction** last,
+ Definition** result)
+ : flow_graph_(flow_graph),
+ call_(call),
+ graph_entry_(graph_entry),
+ entry_(entry),
+ last_(last),
+ result_(result) {
+ *entry_ = new (zone())
+ FunctionEntryInstr(graph_entry_, flow_graph_->allocate_block_id(),
+ call_->GetBlock()->try_index(), call_->deopt_id());
+ *last = *entry_;
+ }
+
+ bool TryInline(MethodRecognizer::Kind kind) {
+ switch (kind) {
+ // ==== Int32x4 ====
+ case MethodRecognizer::kInt32x4FromInts:
+ UnboxScalar(0, kUnboxedInt32, 4);
+ UnboxScalar(1, kUnboxedInt32, 4);
+ UnboxScalar(2, kUnboxedInt32, 4);
+ UnboxScalar(3, kUnboxedInt32, 4);
+ Gather(4);
+ BoxVector(kUnboxedInt32, 4);
+ return true;
+ case MethodRecognizer::kInt32x4FromBools:
+ UnboxBool(0, 4);
+ UnboxBool(1, 4);
+ UnboxBool(2, 4);
+ UnboxBool(3, 4);
+ Gather(4);
+ BoxVector(kUnboxedInt32, 4);
+ return true;
+ case MethodRecognizer::kInt32x4GetFlagX:
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4);
+ IntToBool();
+ Return(0);
+ return true;
+ case MethodRecognizer::kInt32x4GetFlagY:
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4);
+ IntToBool();
+ Return(1);
+ return true;
+ case MethodRecognizer::kInt32x4GetFlagZ:
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4);
+ IntToBool();
+ Return(2);
+ return true;
+ case MethodRecognizer::kInt32x4GetFlagW:
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4);
+ IntToBool();
+ Return(3);
+ return true;
+ case MethodRecognizer::kInt32x4WithFlagX:
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4);
+ UnboxBool(1, 4);
+ With(0);
+ BoxVector(kUnboxedInt32, 4);
+ return true;
+ case MethodRecognizer::kInt32x4WithFlagY:
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4);
+ UnboxBool(1, 4);
+ With(1);
+ BoxVector(kUnboxedInt32, 4);
+ return true;
+ case MethodRecognizer::kInt32x4WithFlagZ:
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4);
+ UnboxBool(1, 4);
+ With(2);
+ BoxVector(kUnboxedInt32, 4);
+ return true;
+ case MethodRecognizer::kInt32x4WithFlagW:
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4);
+ UnboxBool(1, 4);
+ With(3);
+ BoxVector(kUnboxedInt32, 4);
+ return true;
+ case MethodRecognizer::kInt32x4Shuffle: {
+ Definition* mask_definition =
+ call_->ArgumentAt(call_->ArgumentCount() - 1);
+ intptr_t mask = 0;
+ if (!CheckMask(mask_definition, &mask)) {
+ return false;
+ }
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4);
+ Shuffle(mask);
+ BoxVector(kUnboxedInt32, 4);
+ return true;
+ }
+ case MethodRecognizer::kInt32x4ShuffleMix: {
+ Definition* mask_definition =
+ call_->ArgumentAt(call_->ArgumentCount() - 1);
+ intptr_t mask = 0;
+ if (!CheckMask(mask_definition, &mask)) {
+ return false;
+ }
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4);
+ UnboxVector(1, kUnboxedInt32, kMintCid, 4);
+ ShuffleMix(mask);
+ BoxVector(kUnboxedInt32, 4);
+ return true;
+ }
+ case MethodRecognizer::kInt32x4GetSignMask:
+ case MethodRecognizer::kInt32x4Select:
+ // TODO(riscv)
+ return false;
+
+ // ==== Float32x4 ====
+ case MethodRecognizer::kFloat32x4Abs:
+ Float32x4Unary(Token::kABS);
+ return true;
+ case MethodRecognizer::kFloat32x4Negate:
+ Float32x4Unary(Token::kNEGATE);
+ return true;
+ case MethodRecognizer::kFloat32x4Sqrt:
+ Float32x4Unary(Token::kSQRT);
+ return true;
+ case MethodRecognizer::kFloat32x4Reciprocal:
+ Float32x4Unary(Token::kRECIPROCAL);
+ return true;
+ case MethodRecognizer::kFloat32x4ReciprocalSqrt:
+ Float32x4Unary(Token::kRECIPROCAL_SQRT);
+ return true;
+ case MethodRecognizer::kFloat32x4GetSignMask:
+ // TODO(riscv)
+ return false;
+ case MethodRecognizer::kFloat32x4Equal:
+ Float32x4Compare(Token::kEQ);
+ return true;
+ case MethodRecognizer::kFloat32x4GreaterThan:
+ Float32x4Compare(Token::kGT);
+ return true;
+ case MethodRecognizer::kFloat32x4GreaterThanOrEqual:
+ Float32x4Compare(Token::kGTE);
+ return true;
+ case MethodRecognizer::kFloat32x4LessThan:
+ Float32x4Compare(Token::kLT);
+ return true;
+ case MethodRecognizer::kFloat32x4LessThanOrEqual:
+ Float32x4Compare(Token::kLTE);
+ return true;
+ case MethodRecognizer::kFloat32x4Add:
+ Float32x4Binary(Token::kADD);
+ return true;
+ case MethodRecognizer::kFloat32x4Sub:
+ Float32x4Binary(Token::kSUB);
+ return true;
+ case MethodRecognizer::kFloat32x4Mul:
+ Float32x4Binary(Token::kMUL);
+ return true;
+ case MethodRecognizer::kFloat32x4Div:
+ Float32x4Binary(Token::kDIV);
+ return true;
+ case MethodRecognizer::kFloat32x4Min:
+ Float32x4Binary(Token::kMIN);
+ return true;
+ case MethodRecognizer::kFloat32x4Max:
+ Float32x4Binary(Token::kMAX);
+ return true;
+ case MethodRecognizer::kFloat32x4Scale:
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ UnboxScalar(1, kUnboxedFloat, 4);
+ BinaryDoubleOp(Token::kMUL, kUnboxedFloat, 4);
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ case MethodRecognizer::kFloat32x4Splat:
+ UnboxScalar(0, kUnboxedFloat, 4);
+ Splat(4);
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ case MethodRecognizer::kFloat32x4WithX:
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ UnboxScalar(1, kUnboxedFloat, 4);
+ With(0);
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ case MethodRecognizer::kFloat32x4WithY:
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ UnboxScalar(1, kUnboxedFloat, 4);
+ With(1);
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ case MethodRecognizer::kFloat32x4WithZ:
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ UnboxScalar(1, kUnboxedFloat, 4);
+ With(2);
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ case MethodRecognizer::kFloat32x4WithW:
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ UnboxScalar(1, kUnboxedFloat, 4);
+ With(3);
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ case MethodRecognizer::kFloat32x4Zero:
+ UnboxDoubleZero(kUnboxedFloat, 4);
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ case MethodRecognizer::kFloat32x4FromDoubles:
+ UnboxScalar(0, kUnboxedFloat, 4);
+ UnboxScalar(1, kUnboxedFloat, 4);
+ UnboxScalar(2, kUnboxedFloat, 4);
+ UnboxScalar(3, kUnboxedFloat, 4);
+ Gather(4);
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ case MethodRecognizer::kFloat32x4GetX:
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ BoxScalar(0, kUnboxedFloat);
+ return true;
+ case MethodRecognizer::kFloat32x4GetY:
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ BoxScalar(1, kUnboxedFloat);
+ return true;
+ case MethodRecognizer::kFloat32x4GetZ:
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ BoxScalar(2, kUnboxedFloat);
+ return true;
+ case MethodRecognizer::kFloat32x4GetW:
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ BoxScalar(3, kUnboxedFloat);
+ return true;
+ case MethodRecognizer::kFloat32x4Shuffle: {
+ Definition* mask_definition =
+ call_->ArgumentAt(call_->ArgumentCount() - 1);
+ intptr_t mask = 0;
+ if (!CheckMask(mask_definition, &mask)) {
+ return false;
+ }
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ Shuffle(mask);
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ }
+ case MethodRecognizer::kFloat32x4ShuffleMix: {
+ Definition* mask_definition =
+ call_->ArgumentAt(call_->ArgumentCount() - 1);
+ intptr_t mask = 0;
+ if (!CheckMask(mask_definition, &mask)) {
+ return false;
+ }
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ UnboxVector(1, kUnboxedFloat, kDoubleCid, 4);
+ ShuffleMix(mask);
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ }
+
+ // ==== Float64x2 ====
+ case MethodRecognizer::kFloat64x2Abs:
+ Float64x2Unary(Token::kABS);
+ return true;
+ case MethodRecognizer::kFloat64x2Negate:
+ Float64x2Unary(Token::kNEGATE);
+ return true;
+ case MethodRecognizer::kFloat64x2Sqrt:
+ Float64x2Unary(Token::kSQRT);
+ return true;
+ case MethodRecognizer::kFloat64x2Add:
+ Float64x2Binary(Token::kADD);
+ return true;
+ case MethodRecognizer::kFloat64x2Sub:
+ Float64x2Binary(Token::kSUB);
+ return true;
+ case MethodRecognizer::kFloat64x2Mul:
+ Float64x2Binary(Token::kMUL);
+ return true;
+ case MethodRecognizer::kFloat64x2Div:
+ Float64x2Binary(Token::kDIV);
+ return true;
+ case MethodRecognizer::kFloat64x2Min:
+ Float64x2Binary(Token::kMIN);
+ return true;
+ case MethodRecognizer::kFloat64x2Max:
+ Float64x2Binary(Token::kMAX);
+ return true;
+ case MethodRecognizer::kFloat64x2Scale:
+ UnboxVector(0, kUnboxedDouble, kDoubleCid, 2);
+ UnboxScalar(1, kUnboxedDouble, 2);
+ BinaryDoubleOp(Token::kMUL, kUnboxedDouble, 2);
+ BoxVector(kUnboxedDouble, 2);
+ return true;
+ case MethodRecognizer::kFloat64x2Splat:
+ UnboxScalar(0, kUnboxedDouble, 2);
+ Splat(2);
+ BoxVector(kUnboxedDouble, 2);
+ return true;
+ case MethodRecognizer::kFloat64x2WithX:
+ UnboxVector(0, kUnboxedDouble, kDoubleCid, 2);
+ UnboxScalar(1, kUnboxedDouble, 2);
+ With(0);
+ BoxVector(kUnboxedDouble, 2);
+ return true;
+ case MethodRecognizer::kFloat64x2WithY:
+ UnboxVector(0, kUnboxedDouble, kDoubleCid, 2);
+ UnboxScalar(1, kUnboxedDouble, 2);
+ With(1);
+ BoxVector(kUnboxedDouble, 2);
+ return true;
+ case MethodRecognizer::kFloat64x2Zero:
+ UnboxDoubleZero(kUnboxedDouble, 2);
+ BoxVector(kUnboxedDouble, 2);
+ return true;
+ case MethodRecognizer::kFloat64x2FromDoubles:
+ UnboxScalar(0, kUnboxedDouble, 2);
+ UnboxScalar(1, kUnboxedDouble, 2);
+ Gather(2);
+ BoxVector(kUnboxedDouble, 2);
+ return true;
+ case MethodRecognizer::kFloat64x2GetX:
+ UnboxVector(0, kUnboxedDouble, kDoubleCid, 2);
+ BoxScalar(0, kUnboxedDouble);
+ return true;
+ case MethodRecognizer::kFloat64x2GetY:
+ UnboxVector(0, kUnboxedDouble, kDoubleCid, 2);
+ BoxScalar(1, kUnboxedDouble);
+ return true;
+
+ // Mixed
+ case MethodRecognizer::kFloat32x4ToFloat64x2: {
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4, 1);
+ Float32x4ToFloat64x2();
+ BoxVector(kUnboxedDouble, 2);
+ return true;
+ }
+ case MethodRecognizer::kFloat64x2ToFloat32x4: {
+ UnboxVector(0, kUnboxedDouble, kDoubleCid, 2, 1);
+ Float64x2ToFloat32x4();
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ }
+ case MethodRecognizer::kInt32x4ToFloat32x4:
+ UnboxVector(0, kUnboxedInt32, kMintCid, 4, 1);
+ Int32x4ToFloat32x4();
+ BoxVector(kUnboxedFloat, 4);
+ return true;
+ case MethodRecognizer::kFloat32x4ToInt32x4:
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4, 1);
+ Float32x4ToInt32x4();
+ BoxVector(kUnboxedInt32, 4);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private:
+ void Float32x4Unary(Token::Kind op) {
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ UnaryDoubleOp(op, kUnboxedFloat, 4);
+ BoxVector(kUnboxedFloat, 4);
+ }
+ void Float32x4Binary(Token::Kind op) {
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ UnboxVector(1, kUnboxedFloat, kDoubleCid, 4);
+ BinaryDoubleOp(op, kUnboxedFloat, 4);
+ BoxVector(kUnboxedFloat, 4);
+ }
+ void Float32x4Compare(Token::Kind op) {
+ UnboxVector(0, kUnboxedFloat, kDoubleCid, 4);
+ UnboxVector(1, kUnboxedFloat, kDoubleCid, 4);
+ FloatCompare(op);
+ BoxVector(kUnboxedInt32, 4);
+ }
+ void Float64x2Unary(Token::Kind op) {
+ UnboxVector(0, kUnboxedDouble, kDoubleCid, 2);
+ UnaryDoubleOp(op, kUnboxedDouble, 2);
+ BoxVector(kUnboxedDouble, 2);
+ }
+ void Float64x2Binary(Token::Kind op) {
+ UnboxVector(0, kUnboxedDouble, kDoubleCid, 2);
+ UnboxVector(1, kUnboxedDouble, kDoubleCid, 2);
+ BinaryDoubleOp(op, kUnboxedDouble, 2);
+ BoxVector(kUnboxedDouble, 2);
+ }
+
+ void UnboxVector(intptr_t i,
+ Representation rep,
+ intptr_t cid,
+ intptr_t n,
+ intptr_t type_args = 0) {
+ Definition* arg = call_->ArgumentAt(i + type_args);
+ if (CompilerState::Current().is_aot()) {
+ // Add null-checks in case of the arguments are known to be compatible
+ // but they are possibly nullable.
+ // By inserting the null-check, we can allow the unbox instruction later
+ // inserted to be non-speculative.
+ arg = AddDefinition(new (zone()) CheckNullInstr(
+ new (zone()) Value(arg), Symbols::SecondArg(), call_->deopt_id(),
+ call_->source(), CheckNullInstr::kArgumentError));
+ }
+ for (intptr_t lane = 0; lane < n; lane++) {
+ in_[i][lane] = AddDefinition(
+ new (zone()) UnboxLaneInstr(new (zone()) Value(arg), lane, rep, cid));
+ }
+ }
+
+ void UnboxScalar(intptr_t i,
+ Representation rep,
+ intptr_t n,
+ intptr_t type_args = 0) {
+ Definition* arg = call_->ArgumentAt(i + type_args);
+ if (CompilerState::Current().is_aot()) {
+ // Add null-checks in case of the arguments are known to be compatible
+ // but they are possibly nullable.
+ // By inserting the null-check, we can allow the unbox instruction later
+ // inserted to be non-speculative.
+ arg = AddDefinition(new (zone()) CheckNullInstr(
+ new (zone()) Value(arg), Symbols::SecondArg(), call_->deopt_id(),
+ call_->source(), CheckNullInstr::kArgumentError));
+ }
+ Definition* unbox = AddDefinition(
+ UnboxInstr::Create(rep, new (zone()) Value(arg), DeoptId::kNone,
+ Instruction::kNotSpeculative));
+ for (intptr_t lane = 0; lane < n; lane++) {
+ in_[i][lane] = unbox;
+ }
+ }
+
+ void UnboxBool(intptr_t i, intptr_t n) {
+ Definition* unbox = AddDefinition(new (zone()) BoolToIntInstr(
+ call_->ArgumentValueAt(i)->CopyWithType(zone())));
+ for (intptr_t lane = 0; lane < n; lane++) {
+ in_[i][lane] = unbox;
+ }
+ }
+
+ void UnboxDoubleZero(Representation rep, intptr_t n) {
+ Definition* zero = flow_graph_->GetConstant(
+ Double::ZoneHandle(Double::NewCanonical(0.0)), rep);
+ for (intptr_t lane = 0; lane < n; lane++) {
+ op_[lane] = zero;
+ }
+ }
+
+ void UnaryDoubleOp(Token::Kind op, Representation rep, intptr_t n) {
+ for (intptr_t lane = 0; lane < n; lane++) {
+ op_[lane] = AddDefinition(new (zone()) UnaryDoubleOpInstr(
+ op, new (zone()) Value(in_[0][lane]), call_->deopt_id(),
+ Instruction::kNotSpeculative, rep));
+ }
+ }
+
+ void BinaryDoubleOp(Token::Kind op, Representation rep, intptr_t n) {
+ for (intptr_t lane = 0; lane < n; lane++) {
+ op_[lane] = AddDefinition(new (zone()) BinaryDoubleOpInstr(
+ op, new (zone()) Value(in_[0][lane]),
+ new (zone()) Value(in_[1][lane]), call_->deopt_id(), call_->source(),
+ Instruction::kNotSpeculative, rep));
+ }
+ }
+
+ void FloatCompare(Token::Kind op) {
+ for (intptr_t lane = 0; lane < 4; lane++) {
+ op_[lane] = AddDefinition(
+ new (zone()) FloatCompareInstr(op, new (zone()) Value(in_[0][lane]),
+ new (zone()) Value(in_[1][lane])));
+ }
+ }
+
+ void With(intptr_t i) {
+ for (intptr_t lane = 0; lane < 4; lane++) {
+ op_[lane] = in_[0][lane];
+ }
+ op_[i] = in_[1][0];
+ }
+ void Splat(intptr_t n) {
+ for (intptr_t lane = 0; lane < n; lane++) {
+ op_[lane] = in_[0][0];
+ }
+ }
+ void Gather(intptr_t n) {
+ for (intptr_t lane = 0; lane < n; lane++) {
+ op_[lane] = in_[lane][0];
+ }
+ }
+ void Shuffle(intptr_t mask) {
+ op_[0] = in_[0][(mask >> 0) & 3];
+ op_[1] = in_[0][(mask >> 2) & 3];
+ op_[2] = in_[0][(mask >> 4) & 3];
+ op_[3] = in_[0][(mask >> 6) & 3];
+ }
+ void ShuffleMix(intptr_t mask) {
+ op_[0] = in_[0][(mask >> 0) & 3];
+ op_[1] = in_[0][(mask >> 2) & 3];
+ op_[2] = in_[1][(mask >> 4) & 3];
+ op_[3] = in_[1][(mask >> 6) & 3];
+ }
+ void Float32x4ToFloat64x2() {
+ for (intptr_t lane = 0; lane < 2; lane++) {
+ op_[lane] = AddDefinition(new (zone()) FloatToDoubleInstr(
+ new (zone()) Value(in_[0][lane]), DeoptId::kNone));
+ }
+ }
+ void Float64x2ToFloat32x4() {
+ for (intptr_t lane = 0; lane < 2; lane++) {
+ op_[lane] = AddDefinition(new (zone()) DoubleToFloatInstr(
+ new (zone()) Value(in_[0][lane]), DeoptId::kNone));
+ }
+ Definition* zero = flow_graph_->GetConstant(
+ Double::ZoneHandle(Double::NewCanonical(0.0)), kUnboxedFloat);
+ op_[2] = zero;
+ op_[3] = zero;
+ }
+ void Int32x4ToFloat32x4() {
+ for (intptr_t lane = 0; lane < 4; lane++) {
+ op_[lane] = AddDefinition(new (zone()) BitCastInstr(
+ kUnboxedInt32, kUnboxedFloat, new (zone()) Value(in_[0][lane])));
+ }
+ }
+ void Float32x4ToInt32x4() {
+ for (intptr_t lane = 0; lane < 4; lane++) {
+ op_[lane] = AddDefinition(new (zone()) BitCastInstr(
+ kUnboxedFloat, kUnboxedInt32, new (zone()) Value(in_[0][lane])));
+ }
+ }
+ void IntToBool() {
+ for (intptr_t lane = 0; lane < 4; lane++) {
+ op_[lane] = AddDefinition(
+ new (zone()) IntToBoolInstr(new (zone()) Value(in_[0][lane])));
+ }
+ }
+
+ void BoxVector(Representation rep, intptr_t n) {
+ Definition* box;
+ if (n == 2) {
+ box = new (zone()) BoxLanesInstr(rep, new (zone()) Value(op_[0]),
+ new (zone()) Value(op_[1]));
+ } else {
+ ASSERT(n == 4);
+ box = new (zone()) BoxLanesInstr(
+ rep, new (zone()) Value(op_[0]), new (zone()) Value(op_[1]),
+ new (zone()) Value(op_[2]), new (zone()) Value(op_[3]));
+ }
+ Done(AddDefinition(box));
+ }
+
+ void BoxScalar(intptr_t lane, Representation rep) {
+ Definition* box = BoxInstr::Create(rep, new (zone()) Value(in_[0][lane]));
+ Done(AddDefinition(box));
+ }
+
+ void Return(intptr_t lane) { Done(op_[lane]); }
+
+ void Done(Definition* result) {
+ // InheritDeoptTarget also inherits environment (which may add 'entry' into
+ // env_use_list()), so InheritDeoptTarget should be done only after decided
+ // to inline.
+ (*entry_)->InheritDeoptTarget(zone(), call_);
+ *result_ = result;
+ }
+
+ Definition* AddDefinition(Definition* def) {
+ *last_ = flow_graph_->AppendTo(
+ *last_, def, call_->deopt_id() != DeoptId::kNone ? call_->env() : NULL,
+ FlowGraph::kValue);
+ return def;
+ }
+ Zone* zone() { return flow_graph_->zone(); }
+
+ FlowGraph* flow_graph_;
+ Instruction* call_;
+ GraphEntryInstr* graph_entry_;
+ FunctionEntryInstr** entry_;
+ Instruction** last_;
+ Definition** result_;
+
+ // First index is the argment number, second index is the lane number.
+ Definition* in_[4][4];
+ // Index is the lane number.
+ Definition* op_[4];
+};
+
static bool InlineSimdOp(FlowGraph* flow_graph,
bool is_dynamic_call,
Instruction* call,
@@ -3546,9 +4128,6 @@
FunctionEntryInstr** entry,
Instruction** last,
Definition** result) {
- if (!ShouldInlineSimd()) {
- return false;
- }
if (is_dynamic_call && call->ArgumentCount() > 1) {
// Issue(dartbug.com/37737): Dynamic invocation forwarders have the
// same recognized kind as the method they are forwarding to.
@@ -3563,6 +4142,19 @@
return false;
}
+ if (!FLAG_enable_simd_inline) {
+ return false;
+ }
+
+ if (!FlowGraphCompiler::SupportsUnboxedSimd128()) {
+#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
+ SimdLowering lowering(flow_graph, call, graph_entry, entry, last, result);
+ return lowering.TryInline(kind);
+#else
+ UNREACHABLE();
+#endif
+ }
+
*entry =
new (Z) FunctionEntryInstr(graph_entry, flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), DeoptId::kNone);
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index b9804d5..f4e263b 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1323,6 +1323,14 @@
return CompileType::Bool();
}
+CompileType BoolToIntInstr::ComputeType() const {
+ return CompileType::Int();
+}
+
+CompileType IntToBoolInstr::ComputeType() const {
+ return CompileType::Bool();
+}
+
CompileType InstanceOfInstr::ComputeType() const {
return CompileType::Bool();
}
@@ -1754,10 +1762,6 @@
return CompileType::FromCid(simd_op_result_cids[kind()]);
}
-CompileType MathUnaryInstr::ComputeType() const {
- return CompileType::FromCid(kDoubleCid);
-}
-
CompileType MathMinMaxInstr::ComputeType() const {
return CompileType::FromCid(result_cid_);
}
@@ -1811,6 +1815,20 @@
}
}
+CompileType BoxLanesInstr::ComputeType() const {
+ switch (from_representation()) {
+ case kUnboxedFloat:
+ return CompileType::FromCid(kFloat32x4Cid);
+ case kUnboxedDouble:
+ return CompileType::FromCid(kFloat64x2Cid);
+ case kUnboxedInt32:
+ return CompileType::FromCid(kInt32x4Cid);
+ default:
+ UNREACHABLE();
+ return CompileType::Dynamic();
+ }
+}
+
CompileType Int32ToDoubleInstr::ComputeType() const {
return CompileType::FromCid(kDoubleCid);
}
@@ -1823,12 +1841,12 @@
return CompileType::FromCid(kDoubleCid);
}
-CompileType DoubleToDoubleInstr::ComputeType() const {
+CompileType FloatToDoubleInstr::ComputeType() const {
return CompileType::FromCid(kDoubleCid);
}
-CompileType FloatToDoubleInstr::ComputeType() const {
- return CompileType::FromCid(kDoubleCid);
+CompileType FloatCompareInstr::ComputeType() const {
+ return CompileType::Int();
}
CompileType DoubleToFloatInstr::ComputeType() const {
@@ -1848,6 +1866,10 @@
return CompileType::FromCid(definition_cid_);
}
+CompileType UnboxLaneInstr::ComputeType() const {
+ return CompileType::FromCid(definition_cid_);
+}
+
static AbstractTypePtr ExtractElementTypeFromArrayType(
const AbstractType& array_type) {
if (array_type.IsTypeParameter()) {
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index 7cd28de..c48dc65 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -1244,15 +1244,6 @@
return Fragment(instr);
}
-Fragment BaseFlowGraphBuilder::DoubleToDouble(
- MethodRecognizer::Kind recognized_kind) {
- Value* value = Pop();
- auto* instr =
- new (Z) DoubleToDoubleInstr(value, recognized_kind, GetNextDeoptId());
- Push(instr);
- return Fragment(instr);
-}
-
Fragment BaseFlowGraphBuilder::DoubleToInteger(
MethodRecognizer::Kind recognized_kind) {
Value* value = Pop();
@@ -1262,9 +1253,10 @@
return Fragment(instr);
}
-Fragment BaseFlowGraphBuilder::MathUnary(MathUnaryInstr::MathUnaryKind kind) {
+Fragment BaseFlowGraphBuilder::UnaryDoubleOp(Token::Kind op) {
Value* value = Pop();
- auto* instr = new (Z) MathUnaryInstr(kind, value, GetNextDeoptId());
+ auto* instr = new (Z) UnaryDoubleOpInstr(op, value, GetNextDeoptId(),
+ Instruction::kNotSpeculative);
Push(instr);
return Fragment(instr);
}
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index a91212e..0632510 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -455,18 +455,13 @@
Fragment InvokeMathCFunction(MethodRecognizer::Kind recognized_kind,
intptr_t num_inputs);
- // Pops double value and converts it to double as specified
- // by the recognized method (kDoubleTruncateToDouble,
- // kDoubleFloorToDouble or kDoubleCeilToDouble).
- Fragment DoubleToDouble(MethodRecognizer::Kind recognized_kind);
-
// Pops double value and converts it to int as specified
// by the recognized method (kDoubleToInteger,
// kDoubleFloorToInt or kDoubleCeilToInt).
Fragment DoubleToInteger(MethodRecognizer::Kind recognized_kind);
// Pops double value and applies unary math operation.
- Fragment MathUnary(MathUnaryInstr::MathUnaryKind kind);
+ Fragment UnaryDoubleOp(Token::Kind op);
// Records coverage for this position, if the current VM mode supports it.
Fragment RecordCoverage(TokenPosition position);
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 1e3707e..b1cc2ff 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1634,14 +1634,26 @@
((kind == MethodRecognizer::kDoubleTruncateToDouble) ||
(kind == MethodRecognizer::kDoubleFloorToDouble) ||
(kind == MethodRecognizer::kDoubleCeilToDouble))) {
- body += DoubleToDouble(kind);
+ switch (kind) {
+ case MethodRecognizer::kDoubleTruncateToDouble:
+ body += UnaryDoubleOp(Token::kTRUNCATE);
+ break;
+ case MethodRecognizer::kDoubleFloorToDouble:
+ body += UnaryDoubleOp(Token::kFLOOR);
+ break;
+ case MethodRecognizer::kDoubleCeilToDouble:
+ body += UnaryDoubleOp(Token::kCEILING);
+ break;
+ default:
+ UNREACHABLE();
+ }
} else {
body += InvokeMathCFunction(kind, function.NumParameters());
}
} break;
case MethodRecognizer::kMathSqrt: {
body += LoadLocal(parsed_function_->RawParameterVariable(0));
- body += MathUnary(MathUnaryInstr::kSqrt);
+ body += UnaryDoubleOp(Token::kSQRT);
} break;
case MethodRecognizer::kFinalizerBase_setIsolate:
ASSERT_EQUAL(function.NumParameters(), 1);
diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc
index b64d7dd..de229ac 100644
--- a/runtime/vm/deferred_objects.cc
+++ b/runtime/vm/deferred_objects.cc
@@ -395,15 +395,9 @@
static_cast<uint64_t>(Integer::Cast(value).AsInt64Value()));
break;
case kTypedDataFloat32ArrayCid:
- // Although element of Float32 array is represented with Double,
- // it is already converted to 32-bit float via DoubleToFloat
- // instruction before it was stored.
- // Reinterpret double value as float to get the value back.
typed_data.SetFloat32(
element_offset,
- bit_cast<float, uint32_t>(
- static_cast<uint32_t>(bit_cast<uint64_t, double>(
- Double::Cast(value).value()))));
+ static_cast<float>(Double::Cast(value).value()));
break;
case kTypedDataFloat64ArrayCid:
typed_data.SetFloat64(element_offset,
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 20eec15..497c453 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -232,6 +232,7 @@
case DeoptInstr::kInt32x4:
case DeoptInstr::kFloat64x2:
case DeoptInstr::kWord:
+ case DeoptInstr::kFloat:
case DeoptInstr::kDouble:
case DeoptInstr::kMint:
case DeoptInstr::kMintPair:
@@ -668,6 +669,12 @@
DISALLOW_COPY_AND_ASSIGN(DeoptFpuInstr);
};
+typedef DeoptFpuInstr<DeoptInstr::kFloat,
+ CatchEntryMove::SourceKind::kFloatSlot,
+ float,
+ DoublePtr>
+ DeoptFloatInstr;
+
typedef DeoptFpuInstr<DeoptInstr::kDouble,
CatchEntryMove::SourceKind::kDoubleSlot,
double,
@@ -902,6 +909,8 @@
switch (kind) {
case kWord:
return new DeoptWordInstr(source_index);
+ case kFloat:
+ return new DeoptFloatInstr(source_index);
case kDouble:
return new DeoptDoubleInstr(source_index);
case kMint:
@@ -945,6 +954,8 @@
switch (kind) {
case kWord:
return "word";
+ case kFloat:
+ return "float";
case kDouble:
return "double";
case kMint:
@@ -1127,6 +1138,9 @@
new (zone()) DeoptUint32Instr(ToCpuRegisterSource(source_loc));
break;
case kUnboxedFloat:
+ deopt_instr = new (zone()) DeoptFloatInstr(
+ ToFpuRegisterSource(source_loc, Location::kDoubleStackSlot));
+ break;
case kUnboxedDouble:
deopt_instr = new (zone()) DeoptDoubleInstr(
ToFpuRegisterSource(source_loc, Location::kDoubleStackSlot));
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index cbd15c2..ccfff06 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -82,7 +82,15 @@
return cpu_registers_[reg];
}
- double FpuRegisterValue(FpuRegister reg) const {
+ float FpuRegisterValueAsFloat(FpuRegister reg) const {
+ ASSERT(FlowGraphCompiler::SupportsUnboxedDoubles());
+ ASSERT(fpu_registers_ != NULL);
+ ASSERT(reg >= 0);
+ ASSERT(reg < kNumberOfFpuRegisters);
+ return *reinterpret_cast<float*>(&fpu_registers_[reg]);
+ }
+
+ double FpuRegisterValueAsDouble(FpuRegister reg) const {
ASSERT(FlowGraphCompiler::SupportsUnboxedDoubles());
ASSERT(fpu_registers_ != NULL);
ASSERT(reg >= 0);
@@ -159,6 +167,11 @@
idx, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
}
+ void DeferMaterialization(float value, DoublePtr* slot) {
+ deferred_slots_ = new DeferredDouble(
+ value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
+ }
+
void DeferMaterialization(double value, DoublePtr* slot) {
deferred_slots_ = new DeferredDouble(
value, reinterpret_cast<ObjectPtr*>(slot), deferred_slots_);
@@ -267,6 +280,7 @@
kRetAddress,
kConstant,
kWord,
+ kFloat,
kDouble,
kFloat32x4,
kFloat64x2,
@@ -358,9 +372,16 @@
};
template <>
+struct RegisterReader<FpuRegister, float> {
+ static double Read(DeoptContext* context, FpuRegister reg) {
+ return context->FpuRegisterValueAsFloat(reg);
+ }
+};
+
+template <>
struct RegisterReader<FpuRegister, double> {
static double Read(DeoptContext* context, FpuRegister reg) {
- return context->FpuRegisterValue(reg);
+ return context->FpuRegisterValueAsDouble(reg);
}
};
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 23e9aa2..0d71595 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -237,6 +237,10 @@
value = *TaggedSlotAt(fp, move.src_slot());
break;
+ case CatchEntryMove::SourceKind::kFloatSlot:
+ value = Double::New(*SlotAt<float>(fp, move.src_slot()));
+ break;
+
case CatchEntryMove::SourceKind::kDoubleSlot:
value = Double::New(*SlotAt<double>(fp, move.src_slot()));
break;
@@ -369,6 +373,11 @@
Utils::SNPrint(from, ARRAY_SIZE(from), "fp[%" Pd "]", src_slot());
break;
+ case SourceKind::kFloatSlot:
+ Utils::SNPrint(from, ARRAY_SIZE(from), "f32 [fp + %" Pd "]",
+ src_slot() * compiler::target::kWordSize);
+ break;
+
case SourceKind::kDoubleSlot:
Utils::SNPrint(from, ARRAY_SIZE(from), "f64 [fp + %" Pd "]",
src_slot() * compiler::target::kWordSize);
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 89090a6..f87201d 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -147,6 +147,7 @@
enum class SourceKind {
kConstant,
kTaggedSlot,
+ kFloatSlot,
kDoubleSlot,
kFloat32x4Slot,
kFloat64x2Slot,
diff --git a/runtime/vm/token.cc b/runtime/vm/token.cc
index ba33707..ad55e39 100644
--- a/runtime/vm/token.cc
+++ b/runtime/vm/token.cc
@@ -56,6 +56,8 @@
case Token::kSHL:
case Token::kSHR:
case Token::kUSHR:
+ case Token::kMAX:
+ case Token::kMIN:
return true;
default:
return false;
@@ -63,7 +65,21 @@
}
bool Token::IsUnaryArithmeticOperator(Token::Kind token) {
- return (token == kBIT_NOT) || (token == kNEGATE);
+ switch (token) {
+ case Token::kBIT_NOT:
+ case Token::kNEGATE:
+ case Token::kABS:
+ case Token::kSQRT:
+ case Token::kSQUARE:
+ case Token::kRECIPROCAL:
+ case Token::kRECIPROCAL_SQRT:
+ case Token::kTRUNCATE:
+ case Token::kFLOOR:
+ case Token::kCEILING:
+ return true;
+ default:
+ return false;
+ }
}
bool Token::IsBinaryBitwiseOperator(Token::Kind token) {
diff --git a/runtime/vm/token.h b/runtime/vm/token.h
index e2fc074..174af7d 100644
--- a/runtime/vm/token.h
+++ b/runtime/vm/token.h
@@ -140,7 +140,17 @@
TOK(kSCRIPTTAG, "#!", 0, kNoAttribute) \
\
/* Support for optimized code */ \
- TOK(kREM, "", 0, kNoAttribute)
+ TOK(kREM, "rem", 0, kNoAttribute) \
+ TOK(kABS, "abs", 0, kNoAttribute) \
+ TOK(kSQRT, "sqrt", 0, kNoAttribute) \
+ TOK(kMIN, "min", 0, kNoAttribute) \
+ TOK(kMAX, "max", 0, kNoAttribute) \
+ TOK(kRECIPROCAL, "reciprocal", 0, kNoAttribute) \
+ TOK(kRECIPROCAL_SQRT, "reciprocal-sqrt", 0, kNoAttribute) \
+ TOK(kSQUARE, "square", 0, kNoAttribute) \
+ TOK(kTRUNCATE, "truncate", 0, kNoAttribute) \
+ TOK(kFLOOR, "floor", 0, kNoAttribute) \
+ TOK(kCEILING, "ceiling", 0, kNoAttribute)
// List of keywords. The list must be alphabetically ordered. The
// keyword recognition code depends on the ordering.
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index ae7f8f3..6f210df 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -28225,7 +28225,20 @@
throw new UnsupportedError("Not supported");
}
+ factory SharedArrayBuffer([int? length]) {
+ if (length != null) {
+ return SharedArrayBuffer._create_1(length);
+ }
+ return SharedArrayBuffer._create_2();
+ }
+ static SharedArrayBuffer _create_1(length) =>
+ JS('SharedArrayBuffer', 'new SharedArrayBuffer(#)', length);
+ static SharedArrayBuffer _create_2() =>
+ JS('SharedArrayBuffer', 'new SharedArrayBuffer()');
+
int? get byteLength native;
+
+ SharedArrayBuffer slice([int? begin, int? end]) native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 7dce112..661b998 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -2456,21 +2456,75 @@
Float32x4 operator /(Float32x4 other);
/// Relational less than.
+ ///
+ /// Equivalent to:
+ ///
+ /// ```
+ /// Int32x4(this.x < other.x ? -1 : 0,
+ /// this.y < other.y ? -1 : 0,
+ /// this.z < other.z ? -1 : 0,
+ /// this.w < other.w ? -1 : 0);
+ /// ```
Int32x4 lessThan(Float32x4 other);
/// Relational less than or equal.
+ ///
+ /// Equivalent to:
+ ///
+ /// ```
+ /// Int32x4(this.x <= other.x ? -1 : 0,
+ /// this.y <= other.y ? -1 : 0,
+ /// this.z <= other.z ? -1 : 0,
+ /// this.w <= other.w ? -1 : 0);
+ /// ```
Int32x4 lessThanOrEqual(Float32x4 other);
/// Relational greater than.
+ ///
+ /// Equivalent to:
+ ///
+ /// ```
+ /// Int32x4(this.x > other.x ? -1 : 0,
+ /// this.y > other.y ? -1 : 0,
+ /// this.z > other.z ? -1 : 0,
+ /// this.w > other.w ? -1 : 0);
+ /// ```
Int32x4 greaterThan(Float32x4 other);
/// Relational greater than or equal.
+ ///
+ /// Equivalent to:
+ ///
+ /// ```
+ /// Int32x4(this.x >= other.x ? -1 : 0,
+ /// this.y >= other.y ? -1 : 0,
+ /// this.z >= other.z ? -1 : 0,
+ /// this.w >= other.w ? -1 : 0);
+ /// ```
Int32x4 greaterThanOrEqual(Float32x4 other);
/// Relational equal.
+ ///
+ /// Equivalent to:
+ ///
+ /// ```
+ /// Int32x4(this.x == other.x ? -1 : 0,
+ /// this.y == other.y ? -1 : 0,
+ /// this.z == other.z ? -1 : 0,
+ /// this.w == other.w ? -1 : 0);
+ /// ```
Int32x4 equal(Float32x4 other);
/// Relational not-equal.
+ ///
+ /// Equivalent to:
+ ///
+ /// ```
+ /// Int32x4(this.x != other.x ? -1 : 0,
+ /// this.y != other.y ? -1 : 0,
+ /// this.z != other.z ? -1 : 0,
+ /// this.w != other.w ? -1 : 0);
+ /// ```
Int32x4 notEqual(Float32x4 other);
/// Returns a copy of [this] each lane being scaled by [s].
@@ -2802,7 +2856,14 @@
/// The lanes are "x", "y", "z", and "w" respectively.
abstract class Int32x4 {
external factory Int32x4(int x, int y, int z, int w);
+
+ /// Equivalent to:
+ ///
+ /// ```
+ /// Int32x4(x ? -1 : 0, y ? -1 : 0, z ? -1 : 0, w ? -1 : 0)
+ /// ```
external factory Int32x4.bool(bool x, bool y, bool z, bool w);
+
external factory Int32x4.fromFloat32x4Bits(Float32x4 x);
/// The bit-wise or operator.
diff --git a/tools/VERSION b/tools/VERSION
index a27dd14..a7d80de 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 19
PATCH 0
-PRERELEASE 58
+PRERELEASE 59
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/dom/dom.json b/tools/dom/dom.json
index 45493dc..e8d59ee 100644
--- a/tools/dom/dom.json
+++ b/tools/dom/dom.json
@@ -21240,8 +21240,12 @@
},
"SharedArrayBuffer": {
"members": {
+ "SharedArrayBuffer": {},
"byteLength": {
"support_level": "untriaged"
+ },
+ "slice": {
+ "support_level": "untriaged"
}
},
"support_level": "untriaged"
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index 4665656..597dc45 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -683,3 +683,10 @@
callback PositionCallback = void(object position);
interface MathMLElement : Element {};
+
+[DartSupplemental,
+ CustomConstructor,
+ Constructor(optional unsigned long length)
+] interface SharedArrayBuffer {
+ SharedArrayBuffer slice(optional unsigned long begin, optional unsigned long end);
+};