Version 2.12.0-119.0.dev
Merge commit '4ab36120d7af0234b75f062cb6c4a36b04a4e5e6' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 207e58c..976602f 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
"constraint, update this by running tools/generate_package_config.dart."
],
"configVersion": 2,
- "generated": "2020-11-15T14:18:10.587065",
+ "generated": "2020-12-03T14:26:48.568312",
"generator": "tools/generate_package_config.dart",
"packages": [
{
@@ -101,7 +101,7 @@
"name": "args",
"rootUri": "../third_party/pkg/args",
"packageUri": "lib/",
- "languageVersion": "2.3"
+ "languageVersion": "2.12"
},
{
"name": "async",
diff --git a/DEPS b/DEPS
index a5eac9a..1dd8ce4 100644
--- a/DEPS
+++ b/DEPS
@@ -68,7 +68,7 @@
"gperftools_revision": "180bfa10d7cb38e8b3784d60943d50e8fcef0dcb",
# Revisions of /third_party/* dependencies.
- "args_tag": "1.6.0",
+ "args_rev": "139140125126661fac88c9aa5882165936d01c91",
"async_rev": "695b3ac280f107c84adf7488743abfdfaaeea68f",
"bazel_worker_rev": "060c55a933d39798681a4f533b161b81dc48d77e",
"benchmark_harness_rev": "ec6b646f5443faa871e126ac1ba248c94ca06257",
@@ -84,7 +84,7 @@
"convert_rev": "dd3bd28f63be7cb8ab961f38bc73229e4473b555",
"crypto_rev": "f7c48b334b1386bc5ab0f706fbcd6df8496a87fc",
"csslib_rev": "6f77b3dcee957d3e2d5083f666221a220e9ed1f1",
- "dart2js_info_rev" : "83504e459e13862cc6a61c147147ef7892a0d285",
+ "dart2js_info_rev" : "e0acfeb5affdf94c53067e68bd836adf589628fd",
# Note: Updates to dart_style have to be coordinated with the infrastructure
# team so that the internal formatter in `tools/sdks/dart-sdk/bin/dartfmt`
@@ -301,7 +301,7 @@
"@" + Var("gperftools_revision"),
Var("dart_root") + "/third_party/pkg/args":
- Var("dart_git") + "args.git" + "@" + Var("args_tag"),
+ Var("dart_git") + "args.git" + "@" + Var("args_rev"),
Var("dart_root") + "/third_party/pkg/async":
Var("dart_git") + "async.git" + "@" + Var("async_rev"),
Var("dart_root") + "/third_party/pkg/bazel_worker":
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables_test.dart
index 10196f4..cae1c1c 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables_test.dart
@@ -137,13 +137,17 @@
assignedVariables.declare(v1);
assignedVariables.beginNode();
assignedVariables.beginNode();
+ assignedVariables.beginNode();
assignedVariables.write(v1);
assignedVariables.endNode(_Node(),
isClosureOrLateVariableInitializer: true);
- var node = _Node();
- assignedVariables.endNode(node);
+ var innerNode = _Node();
+ assignedVariables.endNode(innerNode);
+ var outerNode = _Node();
+ assignedVariables.endNode(outerNode);
assignedVariables.finish();
- expect(assignedVariables.capturedInNode(node), {v1});
+ expect(assignedVariables.capturedInNode(innerNode), {v1});
+ expect(assignedVariables.capturedInNode(outerNode), {v1});
});
group('Variables do not percolate beyond the scope they were declared in',
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index b355d68..0d5d964 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -229,6 +229,7 @@
engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
engine.ElementKind.NAME: ElementKind.UNKNOWN,
engine.ElementKind.NEVER: ElementKind.UNKNOWN,
+ engine.ElementKind.TYPE_ALIAS: ElementKind.UNKNOWN,
engine.ElementKind.UNIVERSE: ElementKind.UNKNOWN
});
}
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index fdbd60f..809579d 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -2933,6 +2933,7 @@
/// Set the equal sign separating the name being defined from the function
/// type to the given [token].
+ @Deprecated('Clients should not build AST manually')
set equals(Token token);
/// Return the type of function being defined by the alias.
@@ -2943,6 +2944,7 @@
/// Set the type of function being defined by the alias to the given
/// [functionType].
+ @Deprecated('Clients should not build AST manually')
set functionType(GenericFunctionType functionType);
/// Return the type being defined by the alias.
@@ -2954,6 +2956,7 @@
/// Set the type parameters for the function type to the given list of
/// [typeParameters].
+ @Deprecated('Clients should not build AST manually')
set typeParameters(TypeParameterList typeParameters);
}
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index be7a1eb..44d3ec9 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -408,6 +408,10 @@
/// compilation unit.
List<TopLevelVariableElement> get topLevelVariables;
+ /// Return a list containing all of the type aliases contained in this
+ /// compilation unit.
+ List<TypeAliasElement> get typeAliases;
+
/// Return a list containing all of the classes contained in this compilation
/// unit.
List<ClassElement> get types;
@@ -859,7 +863,10 @@
static const ElementKind TYPE_PARAMETER =
ElementKind('TYPE_PARAMETER', 24, "type parameter");
- static const ElementKind UNIVERSE = ElementKind('UNIVERSE', 25, "<universe>");
+ static const ElementKind TYPE_ALIAS =
+ ElementKind('TYPE_ALIAS', 25, "type alias");
+
+ static const ElementKind UNIVERSE = ElementKind('UNIVERSE', 26, "<universe>");
static const List<ElementKind> values = [
CLASS,
@@ -1653,6 +1660,19 @@
/// Clients may not extend, implement or mix-in this class.
abstract class TypeAliasElement
implements TypeParameterizedElement, TypeDefiningElement {
+ /// If the aliased type has structure, return the corresponding element.
+ /// For example it could be [GenericFunctionTypeElement].
+ ///
+ /// If there is no structure, return `null`.
+ Element get aliasedElement;
+
+ /// Return the aliased type.
+ ///
+ /// If non-function type aliases feature is enabled for the enclosing library,
+ /// this type might be just anything. If the feature is disabled, return
+ /// a [FunctionType].
+ DartType get aliasedType;
+
@override
CompilationUnitElement get enclosingElement;
diff --git a/pkg/analyzer/lib/dart/element/type_system.dart b/pkg/analyzer/lib/dart/element/type_system.dart
index 298ece7..865e8d3 100644
--- a/pkg/analyzer/lib/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/dart/element/type_system.dart
@@ -38,11 +38,13 @@
/// Instantiate the given generic element using the type arguments that
/// correspond to the bounds of its type parameters.
///
- /// One and only one of [classElement] or [functionTypeAliasElement] must
+ /// One and only one of [classElement] or [typeAliasElement] must
/// be provided.
DartType instantiateToBounds2({
ClassElement classElement,
- FunctionTypeAliasElement functionTypeAliasElement,
+ @Deprecated("Use 'typeAliasElement' instead")
+ FunctionTypeAliasElement functionTypeAliasElement,
+ TypeAliasElement typeAliasElement,
@required NullabilitySuffix nullabilitySuffix,
});
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 38952f2..2879a63 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -85,7 +85,7 @@
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
class AnalysisDriver implements AnalysisDriverGeneric {
/// The version of data format, should be incremented on every format change.
- static const int DATA_VERSION = 114;
+ static const int DATA_VERSION = 115;
/// The length of the list returned by [_computeDeclaredVariablesSignature].
static const int _declaredVariablesSignatureLength = 4;
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
index bf11fc9..173a9e6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:typed_data';
+
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/dart/analysis/experiments_impl.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
@@ -92,14 +94,36 @@
);
}
- factory ExperimentStatus.fromStorage(List<int> encoded) {
- var allFlags = encoded.skip(2).map((e) => e != 0).toList();
- var featureCount = allFlags.length ~/ 3;
+ factory ExperimentStatus.fromStorage(Uint8List encoded) {
+ var byteIndex = 0;
+
+ int getByte() {
+ return encoded[byteIndex++];
+ }
+
+ List<bool> getBoolList(int length) {
+ var result = List<bool>.filled(length, false);
+ var byteValue = 0;
+ var bitIndex = 0;
+ for (var i = 0; i < length; i++) {
+ if (bitIndex == 0) {
+ byteValue = getByte();
+ }
+ if ((byteValue & (1 << bitIndex)) != 0) {
+ result[i] = true;
+ }
+ bitIndex = (bitIndex + 1) % 8;
+ }
+ return result;
+ }
+
+ var sdkLanguageVersion = Version(getByte(), getByte(), 0);
+ var featureCount = getByte();
return ExperimentStatus._(
- Version(encoded[0], encoded[1], 0),
- allFlags.sublist(0, featureCount),
- allFlags.sublist(featureCount, featureCount * 2),
- allFlags.sublist(featureCount * 2, featureCount * 3),
+ sdkLanguageVersion,
+ getBoolList(featureCount),
+ getBoolList(featureCount),
+ getBoolList(featureCount),
);
}
@@ -210,14 +234,43 @@
}
/// Encode into the format suitable for [ExperimentStatus.fromStorage].
- List<int> toStorage() {
- return [
- _sdkLanguageVersion.major,
- _sdkLanguageVersion.minor,
- ..._explicitEnabledFlags.map((e) => e ? 1 : 0),
- ..._explicitDisabledFlags.map((e) => e ? 1 : 0),
- ..._flags.map((e) => e ? 1 : 0),
- ];
+ Uint8List toStorage() {
+ var result = Uint8List(16);
+ var resultIndex = 0;
+
+ void addByte(int value) {
+ assert(value >= 0 && value < 256);
+ result[resultIndex++] = value;
+ }
+
+ addByte(_sdkLanguageVersion.major);
+ addByte(_sdkLanguageVersion.minor);
+
+ void addBoolList(List<bool> values) {
+ var byteValue = 0;
+ var bitIndex = 0;
+ for (var value in values) {
+ if (value) {
+ byteValue |= 1 << bitIndex;
+ }
+ bitIndex++;
+ if (bitIndex == 8) {
+ addByte(byteValue);
+ byteValue = 0;
+ bitIndex = 0;
+ }
+ }
+ if (bitIndex != 0) {
+ addByte(byteValue);
+ }
+ }
+
+ addByte(_flags.length);
+ addBoolList(_explicitEnabledFlags);
+ addBoolList(_explicitDisabledFlags);
+ addBoolList(_flags);
+
+ return result.sublist(0, resultIndex);
}
@override
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index c906376..a948a39 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -5449,8 +5449,8 @@
/// is returned.
@override
GenericFunctionType get functionType {
- var t = _type;
- return t is GenericFunctionTypeImpl ? t : null;
+ var type = _type;
+ return type is GenericFunctionTypeImpl ? type : null;
}
@override
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index c2c60cd..6e0c1a8 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -3298,14 +3298,15 @@
@override
bool visitGenericTypeAlias(GenericTypeAlias node) {
+ var nodeImpl = node as GenericTypeAliasImpl;
if (identical(node.name, _oldNode)) {
node.name = _newNode as SimpleIdentifier;
return true;
} else if (identical(node.typeParameters, _oldNode)) {
- node.typeParameters = _newNode as TypeParameterList;
+ nodeImpl.typeParameters = _newNode as TypeParameterList;
return true;
} else if (identical(node.type, _oldNode)) {
- (node as GenericTypeAliasImpl).type = _newNode as TypeAnnotation;
+ nodeImpl.type = _newNode as TypeAnnotation;
return true;
} else if (_replaceInList(node.metadata)) {
return true;
diff --git a/pkg/analyzer/lib/src/dart/element/display_string_builder.dart b/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
index 6c7dd55..20affb1 100644
--- a/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
@@ -126,14 +126,6 @@
_writeNullability(type.nullabilitySuffix);
}
- void writeFunctionTypeAliasElement(FunctionTypeAliasElementImpl element) {
- _write('typedef ');
- _write(element.displayName);
- _writeTypeParameters(element.typeParameters);
- _write(' = ');
- element.function?.appendTo(this);
- }
-
void writeGenericFunctionTypeElement(GenericFunctionTypeElementImpl element) {
_writeType(element.returnType);
_write(' Function');
@@ -170,6 +162,20 @@
_write(element.displayName);
}
+ void writeTypeAliasElement(TypeAliasElementImpl element) {
+ _write('typedef ');
+ _write(element.displayName);
+ _writeTypeParameters(element.typeParameters);
+ _write(' = ');
+
+ var aliasedElement = element.aliasedElement;
+ if (aliasedElement != null) {
+ aliasedElement.appendTo(this);
+ } else {
+ _writeType(element.aliasedType);
+ }
+ }
+
void writeTypeParameter(TypeParameterElement element) {
if (element is TypeParameterElementImpl) {
var variance = element.variance;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 5b33ad7..a41ae6b 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1218,7 +1218,11 @@
/// A list containing all of the function type aliases contained in this
/// compilation unit.
- List<FunctionTypeAliasElement> _typeAliases;
+ List<FunctionTypeAliasElement> _functionTypeAliases;
+
+ /// A list containing all of the type aliases contained in this compilation
+ /// unit.
+ List<TypeAliasElement> _typeAliases;
/// A list containing all of the classes contained in this compilation unit.
List<ClassElement> _types;
@@ -1381,30 +1385,8 @@
@override
List<FunctionTypeAliasElement> get functionTypeAliases {
- if (_typeAliases != null) return _typeAliases;
-
- if (linkedNode != null) {
- var containerRef = reference.getChild('@typeAlias');
- _typeAliases = <FunctionTypeAliasElement>[];
- for (var node in linkedContext.unit_withDeclarations.declarations) {
- String name;
- if (node is FunctionTypeAlias) {
- name = node.name.name;
- } else if (node is GenericTypeAlias) {
- name = node.name.name;
- } else {
- continue;
- }
-
- var reference = containerRef.getChild(name);
- var element = node.declaredElement as FunctionTypeAliasElement;
- element ??=
- FunctionTypeAliasElementImpl.forLinkedNode(this, reference, node);
- _typeAliases.add(element);
- }
- }
-
- return _typeAliases ?? const <FunctionTypeAliasElement>[];
+ return _functionTypeAliases ??=
+ typeAliases.whereType<FunctionTypeAliasElement>().toList();
}
@override
@@ -1485,6 +1467,34 @@
_variables = variables;
}
+ @override
+ List<TypeAliasElement> get typeAliases {
+ if (_typeAliases != null) return _typeAliases;
+
+ if (linkedNode != null) {
+ var containerRef = reference.getChild('@typeAlias');
+ _typeAliases = <TypeAliasElement>[];
+ for (var node in linkedContext.unit_withDeclarations.declarations) {
+ String name;
+ if (node is FunctionTypeAlias) {
+ name = node.name.name;
+ } else if (node is GenericTypeAlias) {
+ name = node.name.name;
+ } else {
+ continue;
+ }
+
+ var reference = containerRef.getChild(name);
+ var element = node.declaredElement as TypeAliasElement;
+ element ??=
+ TypeAliasElementImpl.forLinkedNodeFactory(this, reference, node);
+ _typeAliases.add(element);
+ }
+ }
+
+ return _typeAliases ?? const <TypeAliasElement>[];
+ }
+
/// Set the function type aliases contained in this compilation unit to the
/// given [typeAliases].
set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
@@ -1577,7 +1587,7 @@
return functionImpl;
}
}
- for (FunctionTypeAliasElementImpl typeAlias in functionTypeAliases) {
+ for (TypeAliasElementImpl typeAlias in typeAliases) {
if (typeAlias.identifier == identifier) {
return typeAlias;
}
@@ -2924,6 +2934,10 @@
/// children of this element's parent.
String get identifier => name;
+ bool get isNonFunctionTypeAliasesEnabled {
+ return library.featureSet.isEnabled(Feature.nonfunction_type_aliases);
+ }
+
@override
bool get isPrivate {
var name = this.name;
@@ -3509,7 +3523,7 @@
// Build fields for all enum constants.
var containerRef = reference.getChild('@constant');
- var constants = linkedContext.getEnumConstants(linkedNode);
+ var constants = (linkedNode as EnumDeclaration).constants;
for (var i = 0; i < constants.length; ++i) {
var constant = constants[i];
var name = constant.name.name;
@@ -4434,204 +4448,33 @@
T accept<T>(ElementVisitor<T> visitor) => visitor.visitFunctionElement(this);
}
-/// An element that represents [FunctionTypeAlias] or [GenericTypeAlias].
-///
-/// Clients may not extend, implement or mix-in this class.
-class FunctionTypeAliasElementImpl extends ElementImpl
- with TypeParameterizedElementMixin
+class FunctionTypeAliasElementImpl extends TypeAliasElementImpl
implements FunctionTypeAliasElement {
- /// The element representing the generic function type.
- GenericFunctionTypeElementImpl _function;
-
- /// TODO(scheglov) implement as modifier
- @override
- bool isSimplyBounded = true;
-
- /// Is `true` if the element has direct or indirect reference to itself
- /// from anywhere except a class element or type parameter bounds.
- bool hasSelfReference = false;
-
- /// Initialize a newly created type alias element to have the given [name].
- FunctionTypeAliasElementImpl(String name, int offset) : super(name, offset);
-
FunctionTypeAliasElementImpl.forLinkedNode(
- CompilationUnitElementImpl enclosingUnit,
- Reference reference,
- AstNode linkedNode)
- : super.forLinkedNode(enclosingUnit, reference, linkedNode) {
- if (linkedNode is FunctionTypeAlias) {
- linkedNode.name.staticElement = this;
- } else {
- (linkedNode as GenericTypeAlias).name.staticElement = this;
- }
- }
-
- @override
- int get codeLength {
- if (linkedNode != null) {
- return linkedContext.getCodeLength(linkedNode);
- }
- return super.codeLength;
- }
-
- @override
- int get codeOffset {
- if (linkedNode != null) {
- return linkedContext.getCodeOffset(linkedNode);
- }
- return super.codeOffset;
- }
-
- @override
- String get displayName => name;
-
- @override
- String get documentationComment {
- if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- var comment = context.getDocumentationComment(linkedNode);
- return getCommentNodeRawText(comment);
- }
- return super.documentationComment;
- }
-
- @override
- CompilationUnitElement get enclosingElement =>
- super.enclosingElement as CompilationUnitElement;
-
- @override
- CompilationUnitElementImpl get enclosingUnit =>
- _enclosingElement as CompilationUnitElementImpl;
+ CompilationUnitElementImpl enclosingUnit,
+ Reference reference,
+ TypeAlias linkedNode,
+ ) : super.forLinkedNode(enclosingUnit, reference, linkedNode);
@override
GenericFunctionTypeElementImpl get function {
- if (_function != null) return _function;
-
- var linkedNode = this.linkedNode;
- if (linkedNode != null) {
- if (linkedNode is GenericTypeAlias) {
- var function = linkedNode.functionType as GenericFunctionTypeImpl;
- if (function != null) {
- _function = function.declaredElement;
- _function ??= GenericFunctionTypeElementImpl.forLinkedNode(
- this,
- reference.getChild('@function'),
- function,
- );
- } else {
- _function = GenericFunctionTypeElementImpl.forOffset(-1)
- ..typeParameters = const <TypeParameterElement>[]
- ..parameters = const <ParameterElement>[]
- ..returnType = DynamicTypeImpl.instance;
- }
- } else {
- _function = GenericFunctionTypeElementImpl.forLinkedNode(
- this,
- reference.getChild('@function'),
- linkedNode,
- );
- }
- linkedContext.applyResolution(linkedNode);
- return _function;
- }
-
- return _function;
- }
-
- /// Set the function element representing the generic function type on the
- /// right side of the equals to the given [function].
- set function(GenericFunctionTypeElementImpl function) {
- if (function != null) {
- function.enclosingElement = this;
- }
- _function = function;
+ return aliasedElement as GenericFunctionTypeElementImpl;
}
@override
- ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
-
- @override
- String get name {
- if (linkedNode != null) {
- return reference.name;
- }
- return super.name;
- }
-
- @override
- int get nameOffset {
- if (linkedNode != null) {
- return enclosingUnit.linkedContext.getNameOffset(linkedNode);
- }
-
- return super.nameOffset;
- }
-
- /// Set the type parameters defined for this type to the given
- /// [typeParameters].
- set typeParameters(List<TypeParameterElement> typeParameters) {
- for (TypeParameterElement typeParameter in typeParameters) {
- (typeParameter as TypeParameterElementImpl).enclosingElement = this;
- }
- _typeParameterElements = typeParameters;
- }
-
- @override
- T accept<T>(ElementVisitor<T> visitor) =>
- visitor.visitFunctionTypeAliasElement(this);
-
- @override
- void appendTo(ElementDisplayStringBuilder builder) {
- builder.writeFunctionTypeAliasElement(this);
- }
-
- @override
- ElementImpl getChild(String identifier) {
- for (TypeParameterElement typeParameter in typeParameters) {
- TypeParameterElementImpl typeParameterImpl = typeParameter;
- if (typeParameterImpl.identifier == identifier) {
- return typeParameterImpl;
- }
- }
- return null;
+ T accept<T>(ElementVisitor<T> visitor) {
+ return visitor.visitFunctionTypeAliasElement(this);
}
@override
FunctionType instantiate({
- @required List<DartType> typeArguments,
- @required NullabilitySuffix nullabilitySuffix,
+ List<DartType> typeArguments,
+ NullabilitySuffix nullabilitySuffix,
}) {
- if (function == null) {
- return null;
- }
-
- if (typeArguments.length != typeParameters.length) {
- throw ArgumentError("typeArguments.length (${typeArguments.length}) != "
- "typeParameters.length (${typeParameters.length})");
- }
-
- var substitution = Substitution.fromPairs(typeParameters, typeArguments);
- var type = substitution.substituteType(function.type) as FunctionType;
-
- var resultNullability = type.nullabilitySuffix == NullabilitySuffix.question
- ? NullabilitySuffix.question
- : nullabilitySuffix;
-
- return FunctionTypeImpl(
- typeFormals: type.typeFormals,
- parameters: type.parameters,
- returnType: type.returnType,
- nullabilitySuffix: resultNullability,
- element: this,
+ return super.instantiate(
typeArguments: typeArguments,
- );
- }
-
- @override
- void visitChildren(ElementVisitor visitor) {
- super.visitChildren(visitor);
- safelyVisitChildren(typeParameters, visitor);
- function?.accept(visitor);
+ nullabilitySuffix: nullabilitySuffix,
+ ) as FunctionType;
}
}
@@ -7224,6 +7067,266 @@
visitor.visitTopLevelVariableElement(this);
}
+/// An element that represents [GenericTypeAlias].
+///
+/// Clients may not extend, implement or mix-in this class.
+class TypeAliasElementImpl extends ElementImpl
+ with TypeParameterizedElementMixin
+ implements TypeAliasElement {
+ /// TODO(scheglov) implement as modifier
+ @override
+ bool isSimplyBounded = true;
+
+ /// Is `true` if the element has direct or indirect reference to itself
+ /// from anywhere except a class element or type parameter bounds.
+ bool hasSelfReference = false;
+
+ bool _isRawElementReady = false;
+ ElementImpl _aliasedElement;
+ DartType _aliasedType;
+
+ TypeAliasElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+ TypeAliasElementImpl.forLinkedNode(
+ CompilationUnitElementImpl enclosingUnit,
+ Reference reference,
+ TypeAlias linkedNode,
+ ) : super.forLinkedNode(enclosingUnit, reference, linkedNode) {
+ var nameNode = linkedNode is FunctionTypeAlias
+ ? linkedNode.name
+ : (linkedNode as GenericTypeAlias).name;
+ nameNode.staticElement = this;
+ }
+
+ factory TypeAliasElementImpl.forLinkedNodeFactory(
+ CompilationUnitElementImpl enclosingUnit,
+ Reference reference,
+ TypeAlias linkedNode,
+ ) {
+ if (linkedNode is FunctionTypeAlias) {
+ return FunctionTypeAliasElementImpl.forLinkedNode(
+ enclosingUnit, reference, linkedNode);
+ } else {
+ var aliasedType = (linkedNode as GenericTypeAlias).type;
+ if (aliasedType is GenericFunctionType ||
+ !enclosingUnit.isNonFunctionTypeAliasesEnabled) {
+ return FunctionTypeAliasElementImpl.forLinkedNode(
+ enclosingUnit, reference, linkedNode);
+ } else {
+ return TypeAliasElementImpl.forLinkedNode(
+ enclosingUnit, reference, linkedNode);
+ }
+ }
+ }
+
+ @override
+ ElementImpl get aliasedElement {
+ _ensureAliasedElement();
+ return _aliasedElement;
+ }
+
+ @override
+ DartType get aliasedType {
+ if (_aliasedType != null) return _aliasedType;
+
+ _ensureAliasedElement();
+
+ var linkedNode = this.linkedNode;
+ if (linkedNode is GenericTypeAlias) {
+ var typeNode = linkedNode.type;
+ if (isNonFunctionTypeAliasesEnabled) {
+ _aliasedType = typeNode.type;
+ assert(_aliasedType != null);
+ } else if (typeNode is GenericFunctionType) {
+ _aliasedType = typeNode.type;
+ assert(_aliasedType != null);
+ } else {
+ _aliasedType = _errorFunctionType(NullabilitySuffix.none);
+ }
+ } else if (linkedNode is FunctionTypeAlias) {
+ _aliasedType = (_aliasedElement as GenericFunctionTypeElementImpl).type;
+ }
+
+ return _aliasedType;
+ }
+
+ set aliasedType(DartType rawType) {
+ _aliasedType = rawType;
+ }
+
+ @override
+ int get codeLength {
+ if (linkedNode != null) {
+ return linkedContext.getCodeLength(linkedNode);
+ }
+ return super.codeLength;
+ }
+
+ @override
+ int get codeOffset {
+ if (linkedNode != null) {
+ return linkedContext.getCodeOffset(linkedNode);
+ }
+ return super.codeOffset;
+ }
+
+ @override
+ String get displayName => name;
+
+ @override
+ String get documentationComment {
+ if (linkedNode != null) {
+ var context = enclosingUnit.linkedContext;
+ var comment = context.getDocumentationComment(linkedNode);
+ return getCommentNodeRawText(comment);
+ }
+ return super.documentationComment;
+ }
+
+ @override
+ CompilationUnitElement get enclosingElement =>
+ super.enclosingElement as CompilationUnitElement;
+
+ @override
+ ElementKind get kind {
+ if (isNonFunctionTypeAliasesEnabled) {
+ return ElementKind.TYPE_ALIAS;
+ } else {
+ return ElementKind.FUNCTION_TYPE_ALIAS;
+ }
+ }
+
+ @override
+ String get name {
+ if (linkedNode != null) {
+ return reference.name;
+ }
+ return super.name;
+ }
+
+ @override
+ int get nameOffset {
+ if (linkedNode != null) {
+ return enclosingUnit.linkedContext.getNameOffset(linkedNode);
+ }
+
+ return super.nameOffset;
+ }
+
+ /// Set the type parameters defined for this type to the given
+ /// [typeParameters].
+ set typeParameters(List<TypeParameterElement> typeParameters) {
+ for (TypeParameterElement typeParameter in typeParameters) {
+ (typeParameter as TypeParameterElementImpl).enclosingElement = this;
+ }
+ _typeParameterElements = typeParameters;
+ }
+
+ @override
+ T accept<T>(ElementVisitor<T> visitor) {
+ // TODO(scheglov) `visitTypeAliasElement`
+ throw UnimplementedError();
+ }
+
+ @override
+ void appendTo(ElementDisplayStringBuilder builder) {
+ builder.writeTypeAliasElement(this);
+ }
+
+ @override
+ ElementImpl getChild(String identifier) {
+ for (TypeParameterElement typeParameter in typeParameters) {
+ TypeParameterElementImpl typeParameterImpl = typeParameter;
+ if (typeParameterImpl.identifier == identifier) {
+ return typeParameterImpl;
+ }
+ }
+ return null;
+ }
+
+ @override
+ DartType instantiate({
+ List<DartType> typeArguments,
+ NullabilitySuffix nullabilitySuffix,
+ }) {
+ if (hasSelfReference) {
+ if (isNonFunctionTypeAliasesEnabled) {
+ return DynamicTypeImpl.instance;
+ } else {
+ return _errorFunctionType(nullabilitySuffix);
+ }
+ }
+
+ var substitution = Substitution.fromPairs(typeParameters, typeArguments);
+ var type = substitution.substituteType(aliasedType);
+
+ var resultNullability = type.nullabilitySuffix == NullabilitySuffix.question
+ ? NullabilitySuffix.question
+ : nullabilitySuffix;
+
+ if (type is FunctionType) {
+ return FunctionTypeImpl(
+ typeFormals: type.typeFormals,
+ parameters: type.parameters,
+ returnType: type.returnType,
+ nullabilitySuffix: resultNullability,
+ element: this,
+ typeArguments: typeArguments,
+ );
+ } else {
+ return (type as TypeImpl).withNullability(resultNullability);
+ }
+ }
+
+ void _ensureAliasedElement() {
+ if (_isRawElementReady) return;
+ _isRawElementReady = true;
+
+ var linkedNode = this.linkedNode;
+ if (linkedNode != null) {
+ if (linkedNode is GenericTypeAlias) {
+ var type = linkedNode.type;
+ if (type is GenericFunctionTypeImpl) {
+ _aliasedElement =
+ type.declaredElement as GenericFunctionTypeElementImpl;
+ // TODO(scheglov) Do we need this?
+ // We probably should set it when linking and when applying.
+ // TODO(scheglov) And remove the reference.
+ _aliasedElement ??= GenericFunctionTypeElementImpl.forLinkedNode(
+ this,
+ reference.getChild('@function'),
+ type,
+ );
+ } else if (isNonFunctionTypeAliasesEnabled) {
+ // No element for `typedef A<T> = List<T>;`
+ } else {
+ _aliasedElement = GenericFunctionTypeElementImpl.forOffset(-1)
+ ..typeParameters = const <TypeParameterElement>[]
+ ..parameters = const <ParameterElement>[]
+ ..returnType = DynamicTypeImpl.instance;
+ }
+ } else {
+ // TODO(scheglov) Same as above (both).
+ _aliasedElement = GenericFunctionTypeElementImpl.forLinkedNode(
+ this,
+ reference.getChild('@function'),
+ linkedNode,
+ );
+ }
+ linkedContext.applyResolution(linkedNode);
+ }
+ }
+
+ FunctionTypeImpl _errorFunctionType(NullabilitySuffix nullabilitySuffix) {
+ return FunctionTypeImpl(
+ typeFormals: const [],
+ parameters: const [],
+ returnType: DynamicTypeImpl.instance,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+}
+
/// A concrete implementation of a [TypeParameterElement].
class TypeParameterElementImpl extends ElementImpl
implements TypeParameterElement {
diff --git a/pkg/analyzer/lib/src/dart/element/scope.dart b/pkg/analyzer/lib/src/dart/element/scope.dart
index 2e1daa0..85085f8 100644
--- a/pkg/analyzer/lib/src/dart/element/scope.dart
+++ b/pkg/analyzer/lib/src/dart/element/scope.dart
@@ -174,7 +174,7 @@
compilationUnit.enums.forEach(_addGetter);
compilationUnit.extensions.forEach(_addExtension);
compilationUnit.functions.forEach(_addGetter);
- compilationUnit.functionTypeAliases.forEach(_addGetter);
+ compilationUnit.typeAliases.forEach(_addGetter);
compilationUnit.mixins.forEach(_addGetter);
compilationUnit.types.forEach(_addGetter);
}
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index d81326c..3acda34 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -502,9 +502,12 @@
@override
DartType instantiateToBounds2({
ClassElement classElement,
- FunctionTypeAliasElement functionTypeAliasElement,
+ @Deprecated("Use 'typeAliasElement' instead")
+ FunctionTypeAliasElement functionTypeAliasElement,
+ TypeAliasElement typeAliasElement,
@required NullabilitySuffix nullabilitySuffix,
}) {
+ typeAliasElement ??= functionTypeAliasElement;
if (classElement != null) {
var typeParameters = classElement.typeParameters;
var typeArguments = _defaultTypeArguments(typeParameters);
@@ -514,10 +517,10 @@
);
type = toLegacyType(type);
return type;
- } else if (functionTypeAliasElement != null) {
- var typeParameters = functionTypeAliasElement.typeParameters;
+ } else if (typeAliasElement != null) {
+ var typeParameters = typeAliasElement.typeParameters;
var typeArguments = _defaultTypeArguments(typeParameters);
- var type = functionTypeAliasElement.instantiate(
+ var type = typeAliasElement.instantiate(
typeArguments: typeArguments,
nullabilitySuffix: nullabilitySuffix,
);
diff --git a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
index c32b116..d3b354b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
@@ -245,7 +245,7 @@
node.staticType = _typeProvider.typeType;
}
return;
- } else if (element is FunctionTypeAliasElement) {
+ } else if (element is TypeAliasElement) {
if (node.inDeclarationContext() || node.parent is TypeName) {
// no type
} else {
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
index a880d32..55967cb 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
@@ -202,7 +202,7 @@
} else if (element is DynamicElementImpl) {
_buildTypeArguments(node, 0);
return DynamicTypeImpl.instance;
- } else if (element is FunctionTypeAliasElement) {
+ } else if (element is TypeAliasElement) {
var typeArguments = _buildTypeArguments(
node,
element.typeParameters.length,
@@ -249,9 +249,9 @@
return dynamicType;
} else if (element is DynamicElementImpl) {
return DynamicTypeImpl.instance;
- } else if (element is FunctionTypeAliasElement) {
+ } else if (element is TypeAliasElement) {
return typeSystem.instantiateToBounds2(
- functionTypeAliasElement: element,
+ typeAliasElement: element,
nullabilitySuffix: nullability,
);
} else if (element is NeverElementImpl) {
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index fea0326..5737b9d 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -27,7 +27,7 @@
int _mixinIndex = 0;
List<ParameterElement> _parameters;
int _parameterIndex = 0;
- List<FunctionTypeAliasElement> _typedefs;
+ List<TypeAliasElement> _typedefs;
int _typedefIndex = 0;
List<TypeParameterElement> _typeParameters;
int _typeParameterIndex = 0;
@@ -56,7 +56,7 @@
_extensions = element.extensions,
_functions = element.functions,
_mixins = element.mixins,
- _typedefs = element.functionTypeAliases,
+ _typedefs = element.typeAliases,
_variables = element.topLevelVariables.where(_isNotSynthetic).toList();
/// Creates an [ElementWalker] which walks the child elements of a compilation
@@ -85,7 +85,7 @@
/// Creates an [ElementWalker] which walks the child elements of a typedef
/// element defined using a generic function type.
- ElementWalker.forGenericTypeAlias(FunctionTypeAliasElement element)
+ ElementWalker.forGenericTypeAlias(TypeAliasElement element)
: element = element,
_typeParameters = element.typeParameters;
@@ -144,7 +144,7 @@
/// Returns the next non-synthetic child of [element] which is a typedef;
/// throws an [IndexError] if there are no more.
- FunctionTypeAliasElement getTypedef() => _typedefs[_typedefIndex++];
+ TypeAliasElement getTypedef() => _typedefs[_typedefIndex++];
/// Returns the next non-synthetic child of [element] which is a type
/// parameter; throws an [IndexError] if there are no more.
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 6a702cf..e7ba7d0 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -786,7 +786,8 @@
_checkForBuiltInIdentifierAsName(
node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
_checkForMainFunction(node.name);
- _checkForTypeAliasCannotReferenceItself(node, node.declaredElement);
+ _checkForTypeAliasCannotReferenceItself(
+ node, node.declaredElement as TypeAliasElementImpl);
super.visitFunctionTypeAlias(node);
}
@@ -823,7 +824,7 @@
node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
_checkForMainFunction(node.name);
_checkForTypeAliasCannotReferenceItself(
- node, node.declaredElement as FunctionTypeAliasElement);
+ node, node.declaredElement as TypeAliasElementImpl);
super.visitGenericTypeAlias(node);
}
@@ -4242,9 +4243,9 @@
/// See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF].
void _checkForTypeAliasCannotReferenceItself(
AstNode node,
- FunctionTypeAliasElement element,
+ TypeAliasElementImpl element,
) {
- if ((element as FunctionTypeAliasElementImpl).hasSelfReference) {
+ if (element.hasSelfReference) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
node,
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index b3a30c8..6fbe5f2 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -998,16 +998,16 @@
// TODO(scheglov) Change corresponding visiting places to visit comments
// with name scopes set for correct comments resolution.
if (parent is GenericTypeAlias) {
- var element = parent.declaredElement as FunctionTypeAliasElement;
+ var element = parent.declaredElement as TypeAliasElement;
var outerScope = nameScope;
try {
nameScope = TypeParameterScope(nameScope, element.typeParameters);
- var functionElement = element.function;
- if (functionElement != null) {
+ var aliasedElement = element.aliasedElement;
+ if (aliasedElement is GenericFunctionTypeElement) {
nameScope = FormalParameterScope(
- TypeParameterScope(nameScope, functionElement.typeParameters),
- functionElement.parameters,
+ TypeParameterScope(nameScope, aliasedElement.typeParameters),
+ aliasedElement.parameters,
);
}
@@ -2826,16 +2826,13 @@
void visitGenericTypeAlias(GenericTypeAlias node) {
Scope outerScope = nameScope;
try {
- var element = node.declaredElement as FunctionTypeAliasElement;
+ var element = node.declaredElement as TypeAliasElement;
nameScope = TypeParameterScope(nameScope, element.typeParameters);
super.visitGenericTypeAlias(node);
- GenericFunctionTypeElement functionElement = element.function;
- if (functionElement != null) {
- nameScope = FormalParameterScope(
- nameScope,
- functionElement.parameters,
- );
+ var aliasedElement = element.aliasedElement;
+ if (aliasedElement is GenericFunctionTypeElement) {
+ nameScope = FormalParameterScope(nameScope, aliasedElement.parameters);
visitGenericTypeAliasInFunctionScope(node);
}
} finally {
diff --git a/pkg/analyzer/lib/src/summary2/apply_resolution.dart b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
index dfbdab2..62ecae0 100644
--- a/pkg/analyzer/lib/src/summary2/apply_resolution.dart
+++ b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
@@ -30,7 +30,7 @@
this._localElements,
this._resolution,
) {
- _enclosingElements.add(_unitContext.unit.declaredElement as ElementImpl);
+ _enclosingElements.add(_unitContext.element);
}
/// TODO(scheglov) make private
@@ -461,13 +461,13 @@
void visitGenericTypeAlias(GenericTypeAlias node) {
_assertNoLocalElements();
- var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ var element = node.declaredElement as TypeAliasElementImpl;
assert(element != null);
_enclosingElements.add(element);
node.typeParameters?.accept(this);
- node.functionType?.accept(this);
+ node.type?.accept(this);
node.metadata?.accept(this);
element.isSimplyBounded = _resolution.readByte() != 0;
element.hasSelfReference = _resolution.readByte() != 0;
@@ -821,8 +821,8 @@
element.bound = node.bound?.type;
node.metadata.accept(this);
- element.metadata = _buildAnnotations2(
- _unitContext.reference.element,
+ element.metadata = _buildAnnotations(
+ _unitContext.element,
node.metadata,
);
@@ -894,7 +894,7 @@
}
/// Return annotations for the given [nodeList] in the [unit].
- List<ElementAnnotation> _buildAnnotations2(
+ List<ElementAnnotation> _buildAnnotations(
CompilationUnitElementImpl unit, List<Annotation> nodeList) {
var length = nodeList.length;
if (length == 0) {
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index c84049b..a1959d6 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -1001,7 +1001,7 @@
var documentationTokenIndexList = _readUint30List();
var typeParameters = _readOptionalNode() as TypeParameterList;
- var functionType = _readOptionalNode();
+ var type = _readOptionalNode();
var name = readNode() as SimpleIdentifier;
var metadata = _readNodeList<Annotation>();
@@ -1012,7 +1012,7 @@
name,
typeParameters,
Tokens.EQ,
- functionType,
+ type,
Tokens.SEMICOLON,
) as GenericTypeAliasImpl;
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
index 3c31999..9f263d7 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -119,6 +119,9 @@
static const int FunctionType = 4;
static const int NeverType = 5;
static const int InterfaceType = 6;
- static const int TypeParameterType = 7;
- static const int VoidType = 8;
+ static const int InterfaceType_noTypeArguments_none = 7;
+ static const int InterfaceType_noTypeArguments_question = 8;
+ static const int InterfaceType_noTypeArguments_star = 9;
+ static const int TypeParameterType = 10;
+ static const int VoidType = 11;
}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 9d2b3df..b8ca6df 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -131,7 +131,6 @@
void visitBooleanLiteral(BooleanLiteral node) {
_writeByte(Tag.BooleanLiteral);
_writeByte(node.value ? 1 : 0);
- // TODO(scheglov) Dont write type?
_resolutionSink?.writeType(node.staticType);
}
@@ -743,10 +742,10 @@
_pushScopeTypeParameters(node.typeParameters);
_writeOptionalNode(node.typeParameters);
- _writeOptionalNode(node.functionType);
+ _writeOptionalNode(node.type);
_storeTypeAlias(node);
- var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ var element = node.declaredElement as TypeAliasElementImpl;
// TODO(scheglov) pack into one byte
_resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
_resolutionSink.writeByte(element.hasSelfReference ? 1 : 0);
@@ -1605,11 +1604,10 @@
_sink.addDouble(value);
}
- /// TODO(scheglov) Optimize the encoding format.
void _writeFeatureSet(FeatureSet featureSet) {
var experimentStatus = featureSet as ExperimentStatus;
var encoded = experimentStatus.toStorage();
- _writeUint32List(encoded);
+ _writeUint8List(encoded);
}
void _writeInformativeUint30(int value) {
@@ -1729,11 +1727,11 @@
(value >> 8) & 0xFF, value & 0xFF);
}
- void _writeUint32List(List<int> values) {
+ void _writeUint8List(List<int> values) {
var length = values.length;
- _writeUInt32(length);
+ _writeUInt30(length);
for (var i = 0; i < length; i++) {
- _writeUInt32(values[i]);
+ _writeByte(values[i]);
}
}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index c2d6a9a..d03ace2 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -416,6 +416,27 @@
typeArguments: typeArguments,
nullabilitySuffix: nullability,
);
+ } else if (tag == Tag.InterfaceType_noTypeArguments_none) {
+ var element = nextElement();
+ return InterfaceTypeImpl(
+ element: element,
+ typeArguments: const <DartType>[],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+ } else if (tag == Tag.InterfaceType_noTypeArguments_question) {
+ var element = nextElement();
+ return InterfaceTypeImpl(
+ element: element,
+ typeArguments: const <DartType>[],
+ nullabilitySuffix: NullabilitySuffix.question,
+ );
+ } else if (tag == Tag.InterfaceType_noTypeArguments_star) {
+ var element = nextElement();
+ return InterfaceTypeImpl(
+ element: element,
+ typeArguments: const <DartType>[],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
} else if (tag == Tag.NeverType) {
var nullability = _readNullability();
return NeverTypeImpl.instance.withNullability(nullability);
@@ -679,7 +700,7 @@
astReader.offset = headerOffset;
var languageVersion = _readLanguageVersion();
- var featureSetEncoded = astReader.readUint32List();
+ var featureSetEncoded = astReader.readUint8List();
var lineInfo = _readLineInfo();
var codeLength = astReader.readUInt30();
var featureSet = ExperimentStatus.fromStorage(featureSetEncoded);
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 0da35249..9e73600 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -329,15 +329,28 @@
} else if (type is FunctionType) {
_writeFunctionType(type);
} else if (type is InterfaceType) {
- writeByte(Tag.InterfaceType);
- // TODO(scheglov) Write raw
- writeElement(type.element);
var typeArguments = type.typeArguments;
- _sink.writeUInt30(typeArguments.length);
- for (var i = 0; i < typeArguments.length; ++i) {
- writeType(typeArguments[i]);
+ var nullabilitySuffix = type.nullabilitySuffix;
+ if (typeArguments.isEmpty) {
+ if (nullabilitySuffix == NullabilitySuffix.none) {
+ writeByte(Tag.InterfaceType_noTypeArguments_none);
+ } else if (nullabilitySuffix == NullabilitySuffix.question) {
+ writeByte(Tag.InterfaceType_noTypeArguments_question);
+ } else if (nullabilitySuffix == NullabilitySuffix.star) {
+ writeByte(Tag.InterfaceType_noTypeArguments_star);
+ }
+ // TODO(scheglov) Write raw
+ writeElement(type.element);
+ } else {
+ writeByte(Tag.InterfaceType);
+ // TODO(scheglov) Write raw
+ writeElement(type.element);
+ _sink.writeUInt30(typeArguments.length);
+ for (var i = 0; i < typeArguments.length; ++i) {
+ writeType(typeArguments[i]);
+ }
+ _writeNullabilitySuffix(nullabilitySuffix);
}
- _writeNullabilitySuffix(type.nullabilitySuffix);
} else if (type is NeverType) {
writeByte(Tag.NeverType);
_writeNullabilitySuffix(type.nullabilitySuffix);
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 63b7c10..cb2155b0b 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -168,7 +168,7 @@
reference.node ??= node;
localScope.declare(name, reference);
- FunctionTypeAliasElementImpl.forLinkedNode(
+ TypeAliasElementImpl.forLinkedNodeFactory(
linkingUnit.reference.element, reference, node);
} else if (node is ast.GenericTypeAlias) {
var name = node.name.name;
@@ -177,7 +177,7 @@
localScope.declare(name, reference);
- FunctionTypeAliasElementImpl.forLinkedNode(
+ TypeAliasElementImpl.forLinkedNodeFactory(
linkingUnit.reference.element, reference, node);
} else if (node is ast.MixinDeclaration) {
var name = node.name.name;
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 9295a32..fcaa1d6 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -83,7 +83,6 @@
_computeLibraryScopes();
_createTypeSystem();
_resolveTypes();
- TypeAliasSelfReferenceFinder().perform(this);
_performTopLevelInference();
_resolveConstructors();
_resolveConstantInitializers();
@@ -245,6 +244,7 @@
}
VarianceBuilder().perform(this);
computeSimplyBounded(builders.values);
+ TypeAliasSelfReferenceFinder().perform(this);
TypesBuilder().build(nodesToBuildType);
}
}
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 58ca7e9..130671e 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -333,8 +333,7 @@
assert(reference.element != null);
return reference.element;
} else if (node is FunctionTypeAlias || node is GenericTypeAlias) {
- FunctionTypeAliasElementImpl.forLinkedNode(
- parentElement, reference, node);
+ TypeAliasElementImpl.forLinkedNodeFactory(parentElement, reference, node);
assert(reference.element != null);
return reference.element;
} else if (node is MethodDeclaration) {
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index b9d9dea..cf7722d 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -32,6 +32,10 @@
this.uriStr, this.reference, this.isSynthetic,
{@required this.unit, @required this.unitReader});
+ CompilationUnitElementImpl get element {
+ return reference.element;
+ }
+
LinkedElementFactory get elementFactory => libraryContext.elementFactory;
bool get hasPartOfDirective {
@@ -80,7 +84,6 @@
return unit;
}
- /// TODO(scheglov) make it static
void applyResolution(AstNode node) {
if (node is VariableDeclaration) {
node = node.parent.parent;
@@ -186,11 +189,6 @@
}
}
- /// TODO(scheglov) inline
- List<EnumConstantDeclaration> getEnumConstants(EnumDeclaration node) {
- return node.constants;
- }
-
String getFieldFormalParameterName(AstNode node) {
if (node is DefaultFormalParameter) {
return getFieldFormalParameterName(node.parameter);
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index 0b037aa..a00dfb8 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -10,7 +11,6 @@
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/dart/element/type_visitor.dart';
import 'package:analyzer/src/summary2/type_builder.dart';
@@ -19,7 +19,7 @@
/// The type builder for a [TypeName].
class NamedTypeBuilder extends TypeBuilder {
/// TODO(scheglov) Replace with `DartType` in `TypeAliasElementImpl`.
- static const _rawFunctionTypeKey = '_rawFunctionType';
+ static const _aliasedTypeKey = '_aliasedType';
static DynamicTypeImpl get _dynamicType => DynamicTypeImpl.instance;
/// The type system of the library with the type name.
@@ -66,6 +66,13 @@
node: node);
}
+ /// TODO(scheglov) Only when enabled both in the element, and target?
+ bool get _isNonFunctionTypeAliasesEnabled {
+ return element.library.featureSet.isEnabled(
+ Feature.nonfunction_type_aliases,
+ );
+ }
+
@override
R accept<R>(TypeVisitor<R> visitor) {
if (visitor is LinkingTypeVisitor<R>) {
@@ -92,20 +99,15 @@
);
type = typeSystem.toLegacyType(type);
_type = type;
- } else if (element is FunctionTypeAliasElement) {
- var rawType = _getRawFunctionType(element);
- if (rawType is FunctionType) {
+ } else if (element is TypeAliasElementImpl) {
+ var aliasedType = _getAliasedType(element);
+ if (aliasedType != null) {
var parameters = element.typeParameters;
var arguments = _buildArguments(parameters);
- var substitution = Substitution.fromPairs(parameters, arguments);
- var instantiated = substitution.substituteType(rawType) as FunctionType;
- var type = FunctionTypeImpl(
- typeFormals: instantiated.typeFormals,
- parameters: instantiated.parameters,
- returnType: instantiated.returnType,
- nullabilitySuffix: nullabilitySuffix,
- element: element,
+ element.aliasedType = aliasedType;
+ var type = element.instantiate(
typeArguments: arguments,
+ nullabilitySuffix: nullabilitySuffix,
);
type = typeSystem.toLegacyType(type);
_type = type;
@@ -153,6 +155,27 @@
node: node);
}
+ DartType _buildAliasedType(TypeAnnotation node) {
+ if (_isNonFunctionTypeAliasesEnabled) {
+ if (node != null) {
+ return _buildType(node?.type);
+ } else {
+ return _dynamicType;
+ }
+ } else {
+ if (node is GenericFunctionType) {
+ return _buildType(node?.type);
+ } else {
+ return FunctionTypeImpl(
+ typeFormals: const <TypeParameterElement>[],
+ parameters: const <ParameterElement>[],
+ returnType: _dynamicType,
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+ }
+ }
+ }
+
/// Build arguments that correspond to the type [parameters].
List<DartType> _buildArguments(List<TypeParameterElement> parameters) {
if (parameters.isEmpty) {
@@ -215,19 +238,6 @@
);
}
- DartType _buildGenericFunctionType(GenericFunctionType node) {
- if (node != null) {
- return _buildType(node?.type);
- } else {
- return FunctionTypeImpl(
- typeFormals: const <TypeParameterElement>[],
- parameters: const <ParameterElement>[],
- returnType: _dynamicType,
- nullabilitySuffix: NullabilitySuffix.none,
- );
- }
- }
-
DartType _buildNodeType(TypeAnnotation node) {
if (node == null) {
return _dynamicType;
@@ -246,32 +256,22 @@
}).toList();
}
- NullabilitySuffix _getNullabilitySuffix(bool hasQuestion) {
- if (hasQuestion) {
- return NullabilitySuffix.question;
- } else if (typeSystem.isNonNullableByDefault) {
- return NullabilitySuffix.none;
- } else {
- return NullabilitySuffix.star;
- }
- }
-
- DartType _getRawFunctionType(FunctionTypeAliasElementImpl element) {
+ DartType _getAliasedType(TypeAliasElementImpl element) {
// If the element is not being linked, there is no reason (or a way,
// because the linked node might be read only partially) to go through
// its node - all its types have already been built.
if (!element.linkedContext.isLinking) {
- return element.function.type;
+ return element.aliasedType;
}
var typedefNode = element.linkedNode;
// Break a possible recursion.
- var existing = typedefNode.getProperty(_rawFunctionTypeKey) as DartType;
+ var existing = typedefNode.getProperty(_aliasedTypeKey) as DartType;
if (existing != null) {
return existing;
} else {
- _setRawFunctionType(typedefNode, _dynamicType);
+ _setAliasedType(typedefNode, _dynamicType);
}
if (typedefNode is FunctionTypeAlias) {
@@ -281,18 +281,28 @@
parameterList: typedefNode.parameters,
hasQuestion: false,
);
- _setRawFunctionType(typedefNode, result);
+ _setAliasedType(typedefNode, result);
return result;
} else if (typedefNode is GenericTypeAlias) {
- var functionNode = typedefNode.functionType;
- var functionType = _buildGenericFunctionType(functionNode);
- _setRawFunctionType(typedefNode, functionType);
- return functionType;
+ var aliasedTypeNode = typedefNode.type;
+ var aliasedType = _buildAliasedType(aliasedTypeNode);
+ _setAliasedType(typedefNode, aliasedType);
+ return aliasedType;
} else {
throw StateError('(${element.runtimeType}) $element');
}
}
+ NullabilitySuffix _getNullabilitySuffix(bool hasQuestion) {
+ if (hasQuestion) {
+ return NullabilitySuffix.question;
+ } else if (typeSystem.isNonNullableByDefault) {
+ return NullabilitySuffix.none;
+ } else {
+ return NullabilitySuffix.star;
+ }
+ }
+
/// If the [type] is a [TypeBuilder], build it; otherwise return as is.
static DartType _buildType(DartType type) {
if (type is TypeBuilder) {
@@ -306,8 +316,8 @@
return List<DartType>.filled(length, _dynamicType);
}
- static void _setRawFunctionType(AstNode node, DartType type) {
- node.setProperty(_rawFunctionTypeKey, type);
+ static void _setAliasedType(AstNode node, DartType type) {
+ node.setProperty(_aliasedTypeKey, type);
}
static List<TypeParameterElement> _typeParameters(TypeParameterList node) {
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index d6f67f5..73818f7 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -316,7 +316,7 @@
var outerScope = scope;
var outerReference = reference;
- var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ var element = node.declaredElement as TypeAliasElementImpl;
reference = element.reference;
_createTypeParameterElements(element, node.typeParameters);
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index 8053556..03be657 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -46,10 +46,10 @@
var element = node2.declaredElement as ClassElementImpl;
element.isSimplyBounded = node.isSimplyBounded;
} else if (node2 is GenericTypeAlias) {
- var element = node2.declaredElement as FunctionTypeAliasElementImpl;
+ var element = node2.declaredElement as TypeAliasElementImpl;
element.isSimplyBounded = node.isSimplyBounded;
} else if (node2 is FunctionTypeAlias) {
- var element = node2.declaredElement as FunctionTypeAliasElementImpl;
+ var element = node2.declaredElement as TypeAliasElementImpl;
element.isSimplyBounded = node.isSimplyBounded;
} else {
throw UnimplementedError('${node2.runtimeType}');
diff --git a/pkg/analyzer/lib/src/summary2/type_alias.dart b/pkg/analyzer/lib/src/summary2/type_alias.dart
index 5fe9298..f69f097 100644
--- a/pkg/analyzer/lib/src/summary2/type_alias.dart
+++ b/pkg/analyzer/lib/src/summary2/type_alias.dart
@@ -2,61 +2,31 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/summary2/link.dart';
class TypeAliasSelfReferenceFinder {
- NullabilitySuffix _unitNullability;
-
/// Check typedefs and mark the ones having self references.
void perform(Linker linker) {
for (var builder in linker.builders.values) {
for (var unitContext in builder.context.units) {
- _unitNullability =
- unitContext.unit.featureSet.isEnabled(Feature.non_nullable)
- ? NullabilitySuffix.none
- : NullabilitySuffix.star;
for (var node in unitContext.unit.declarations) {
if (node is FunctionTypeAlias) {
var finder = _Finder(node);
finder.functionTypeAlias(node);
- var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ var element = node.declaredElement as TypeAliasElementImpl;
element.hasSelfReference = finder.hasSelfReference;
} else if (node is GenericTypeAlias) {
var finder = _Finder(node);
finder.genericTypeAlias(node);
- if (finder.hasSelfReference) {
- _sanitizeGenericTypeAlias(node);
- }
- var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ var element = node.declaredElement as TypeAliasElementImpl;
element.hasSelfReference = finder.hasSelfReference;
}
}
}
}
}
-
- void _sanitizeGenericTypeAlias(GenericTypeAlias node) {
- var typeParameterList = node.typeParameters;
- if (typeParameterList != null) {
- for (var typeParameter in typeParameterList.typeParameters) {
- typeParameter.bound = null;
- }
- }
- node.functionType.returnType = null;
- node.functionType.parameters.parameters.clear();
- (node.functionType as GenericFunctionTypeImpl).type = FunctionTypeImpl(
- typeFormals: const [],
- parameters: const [],
- returnType: DynamicTypeImpl.instance,
- nullabilitySuffix: _unitNullability,
- );
- }
}
class _Finder {
diff --git a/pkg/analyzer/lib/src/summary2/variance_builder.dart b/pkg/analyzer/lib/src/summary2/variance_builder.dart
index 1ee6e95..755f4c9 100644
--- a/pkg/analyzer/lib/src/summary2/variance_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/variance_builder.dart
@@ -73,8 +73,8 @@
}
}
return result;
- } else if (element is FunctionTypeAliasElementImpl) {
- _functionTypeAliasElement(element);
+ } else if (element is TypeAliasElementImpl) {
+ _typeAliasElement(element);
var result = Variance.unrelated;
@@ -177,17 +177,6 @@
}
}
- void _functionTypeAliasElement(FunctionTypeAliasElementImpl element) {
- var node = element.linkedNode;
- if (node is GenericTypeAlias) {
- _genericTypeAlias(node);
- } else if (node is FunctionTypeAlias) {
- _functionTypeAlias(node);
- } else {
- throw UnimplementedError('(${node.runtimeType}) $node');
- }
- }
-
void _genericTypeAlias(GenericTypeAlias node) {
var parameterList = node.typeParameters;
if (parameterList == null) {
@@ -227,6 +216,17 @@
}
}
+ void _typeAliasElement(TypeAliasElementImpl element) {
+ var node = element.linkedNode;
+ if (node is GenericTypeAlias) {
+ _genericTypeAlias(node);
+ } else if (node is FunctionTypeAlias) {
+ _functionTypeAlias(node);
+ } else {
+ throw UnimplementedError('(${node.runtimeType}) $node');
+ }
+ }
+
void _typeParameters(TypeParameterList parameterList) {
if (parameterList == null) {
return;
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element.dart b/pkg/analyzer/lib/src/test_utilities/find_element.dart
index ce24cde..6add61d 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_element.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_element.dart
@@ -541,6 +541,15 @@
throw StateError('Not found: $name');
}
+ TypeAliasElement typeAlias(String name) {
+ for (var element in unitElement.typeAliases) {
+ if (element.name == name) {
+ return element;
+ }
+ }
+ throw StateError('Not found: $name');
+ }
+
ConstructorElement unnamedConstructor(String name) {
return class_(name).unnamedConstructor;
}
diff --git a/pkg/analyzer/test/src/dart/element/function_type_test.dart b/pkg/analyzer/test/src/dart/element/function_type_test.dart
index 803d055..609d293 100644
--- a/pkg/analyzer/test/src/dart/element/function_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/function_type_test.dart
@@ -6,7 +6,6 @@
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:test/test.dart';
@@ -75,25 +74,6 @@
expect(f.typeFormals, typeFormals, reason: 'typeFormals');
}
- FunctionTypeAliasElementImpl functionTypeAliasElement(
- String name, {
- List<ParameterElement> parameters = const [],
- DartType returnType,
- List<TypeParameterElement> typeParameters = const [],
- List<TypeParameterElement> innerTypeParameters = const [],
- }) {
- var aliasElement = FunctionTypeAliasElementImpl(name, 0);
- aliasElement.typeParameters = typeParameters;
-
- var functionElement = GenericFunctionTypeElementImpl.forOffset(0);
- aliasElement.function = functionElement;
- functionElement.typeParameters = innerTypeParameters;
- functionElement.parameters = parameters;
- functionElement.returnType = returnType;
-
- return aliasElement;
- }
-
DartType listOf(DartType elementType) => listElement.instantiate(
typeArguments: [elementType],
nullabilitySuffix: NullabilitySuffix.star,
diff --git a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
index 90337b6..d7f4445 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/test_utilities/mock_packages.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
@@ -357,9 +358,29 @@
}
}
+mixin WithNonFunctionTypeAliasesMixin on PubPackageResolutionTest {
+ @override
+ String get testPackageLanguageVersion => null;
+
+ @override
+ bool get typeToStringWithNullability => true;
+
+ @nonVirtual
+ @override
+ void setUp() {
+ super.setUp();
+
+ writeTestPackageAnalysisOptionsFile(
+ AnalysisOptionsFileConfig(
+ experiments: [EnableString.nonfunction_type_aliases],
+ ),
+ );
+ }
+}
+
mixin WithNullSafetyMixin on PubPackageResolutionTest {
@override
- String get testPackageLanguageVersion => '2.12';
+ String get testPackageLanguageVersion => null;
@override
bool get typeToStringWithNullability => true;
diff --git a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
index 6036780..c9e0e3d 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
@@ -12,6 +12,7 @@
defineReflectiveSuite(() {
defineReflectiveTests(TypeNameResolutionTest);
defineReflectiveTests(TypeNameResolutionWithNullSafetyTest);
+ defineReflectiveTests(TypeNameResolutionWithNonFunctionTypeAliasesTest);
});
}
@@ -289,6 +290,112 @@
}
@reflectiveTest
+class TypeNameResolutionWithNonFunctionTypeAliasesTest
+ extends PubPackageResolutionTest with WithNonFunctionTypeAliasesMixin {
+ test_typeAlias_asParameter_Never_none() async {
+ await assertNoErrorsInCode(r'''
+typedef X = Never;
+void f(X a, X? b) {}
+''');
+
+ assertTypeName(
+ findNode.typeName('X a'),
+ findElement.typeAlias('X'),
+ 'Never',
+ );
+
+ assertTypeName(
+ findNode.typeName('X? b'),
+ findElement.typeAlias('X'),
+ 'Never?',
+ );
+ }
+
+ test_typeAlias_asParameter_Never_question() async {
+ await assertNoErrorsInCode(r'''
+typedef X = Never?;
+void f(X a, X? b) {}
+''');
+
+ assertTypeName(
+ findNode.typeName('X a'),
+ findElement.typeAlias('X'),
+ 'Never?',
+ );
+
+ assertTypeName(
+ findNode.typeName('X? b'),
+ findElement.typeAlias('X'),
+ 'Never?',
+ );
+ }
+
+ test_typeAlias_asParameterType_interfaceType_none() async {
+ await assertNoErrorsInCode(r'''
+typedef X<T> = Map<int, T>;
+void f(X<String> a, X<String?> b) {}
+''');
+
+ assertTypeName(
+ findNode.typeName('X<String>'),
+ findElement.typeAlias('X'),
+ 'Map<int, String>',
+ );
+
+ assertTypeName(
+ findNode.typeName('X<String?>'),
+ findElement.typeAlias('X'),
+ 'Map<int, String?>',
+ );
+ }
+
+ test_typeAlias_asParameterType_interfaceType_question() async {
+ await assertNoErrorsInCode(r'''
+typedef X<T> = List<T?>;
+void f(X<int> a, X<int?> b) {}
+''');
+
+ assertTypeName(
+ findNode.typeName('X<int>'),
+ findElement.typeAlias('X'),
+ 'List<int?>',
+ );
+
+ assertTypeName(
+ findNode.typeName('X<int?>'),
+ findElement.typeAlias('X'),
+ 'List<int?>',
+ );
+ }
+
+ test_typeAlias_asReturnType_interfaceType() async {
+ await assertNoErrorsInCode(r'''
+typedef X<T> = Map<int, T>;
+X<String> f() => {};
+''');
+
+ assertTypeName(
+ findNode.typeName('X<String>'),
+ findElement.typeAlias('X'),
+ 'Map<int, String>',
+ );
+ }
+
+ test_typeAlias_asReturnType_void() async {
+ await assertNoErrorsInCode(r'''
+typedef Nothing = void;
+Nothing f() {}
+''');
+
+ assertTypeName(
+ findNode.typeName('Nothing f()'),
+ findElement.typeAlias('Nothing'),
+ 'void',
+ );
+ }
+}
+
+@reflectiveTest
class TypeNameResolutionWithNullSafetyTest extends TypeNameResolutionTest
with WithNullSafetyMixin {
ImportFindElement get import_a {
diff --git a/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart b/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart
index c8b634c..af8a61a 100644
--- a/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart
@@ -33,7 +33,7 @@
}
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 37),
- error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 101, 1),
+ error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 38, 37),
]);
}
@@ -147,7 +147,6 @@
typedef A<T extends A<int>>();
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 30),
- error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 22, 3),
]);
}
}
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 721eb3c..d225f1a 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -413,33 +413,6 @@
buffer.writeln(' {}');
}
- void writeFunctionTypeAliasElement(FunctionTypeAliasElement e) {
- writeDocumentation(e);
- writeMetadata(e, '', '\n');
- writeIf(!e.isSimplyBounded, 'notSimplyBounded ');
-
- if (e is FunctionTypeAliasElement) {
- buffer.write('typedef ');
- writeName(e);
- writeCodeRange(e);
- writeTypeParameterElements(e.typeParameters, withDefault: true);
-
- buffer.write(' = ');
-
- var function = e.function;
- if (function != null) {
- writeType(function.returnType);
- buffer.write(' Function');
- writeTypeParameterElements(function.typeParameters, withDefault: false);
- writeParameterElements(function.parameters);
- } else {
- buffer.write('<null>');
- }
- }
-
- buffer.writeln(';');
- }
-
void writeIf(bool flag, String str) {
if (flag) {
buffer.write(str);
@@ -1044,6 +1017,32 @@
buffer.write(' ');
}
+ void writeTypeAliasElement(TypeAliasElement e) {
+ writeDocumentation(e);
+ writeMetadata(e, '', '\n');
+ writeIf(!e.isSimplyBounded, 'notSimplyBounded ');
+
+ buffer.write('typedef ');
+ writeName(e);
+ writeCodeRange(e);
+ writeTypeParameterElements(e.typeParameters, withDefault: true);
+
+ buffer.write(' = ');
+
+ var aliasedElement = e.aliasedElement;
+ if (aliasedElement is GenericFunctionTypeElement) {
+ writeType(aliasedElement.returnType);
+ buffer.write(' Function');
+ writeTypeParameterElements(aliasedElement.typeParameters,
+ withDefault: false);
+ writeParameterElements(aliasedElement.parameters);
+ } else {
+ writeType(e.aliasedType);
+ }
+
+ buffer.writeln(';');
+ }
+
void writeTypeInferenceError(Element e) {
TopLevelInferenceError inferenceError;
if (e is MethodElementImpl) {
@@ -1109,7 +1108,7 @@
buffer.writeln('unit: ${e.source?.shortName}');
buffer.writeln();
}
- e.functionTypeAliases.forEach(writeFunctionTypeAliasElement);
+ e.typeAliases.forEach(writeTypeAliasElement);
e.enums.forEach(writeClassElement);
e.types.forEach(writeClassElement);
e.mixins.forEach(writeClassElement);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 007051d..ac1621c 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
@@ -85,6 +86,12 @@
flags: [],
);
+ static final FeatureSet featureSetNonFunctionTypeAliases =
+ FeatureSet.fromEnableFlags2(
+ sdkLanguageVersion: Version.parse('2.12.0'),
+ flags: [EnableString.nonfunction_type_aliases],
+ );
+
test_class_abstract() async {
var library = await checkLibrary('abstract class C {}');
checkElementText(library, r'''
@@ -1294,8 +1301,8 @@
typedef F(C value);
''');
checkElementText(library, r'''
-notSimplyBounded typedef F = dynamic Function(C<dynamic> value);
-notSimplyBounded class C<T extends dynamic Function(C<dynamic>) = dynamic Function(C<dynamic>)> {
+notSimplyBounded typedef F = dynamic Function(C<dynamic Function()> value);
+notSimplyBounded class C<T extends dynamic Function() = dynamic Function()> {
}
''');
}
@@ -1406,9 +1413,9 @@
typedef G(F value);
''');
checkElementText(library, r'''
-notSimplyBounded typedef F = dynamic Function(dynamic Function(dynamic) value);
-notSimplyBounded typedef G = dynamic Function(dynamic value);
-notSimplyBounded class C<T extends dynamic Function(dynamic Function(dynamic)) = dynamic Function(dynamic Function(dynamic))> {
+notSimplyBounded typedef F = dynamic Function(dynamic Function() value);
+notSimplyBounded typedef G = dynamic Function(dynamic Function() value);
+notSimplyBounded class C<T extends dynamic Function() = dynamic Function()> {
}
''');
}
@@ -7476,7 +7483,7 @@
typedef F<X extends F> = Function(F);
''');
checkElementText(library, r'''
-notSimplyBounded typedef F<X> = dynamic Function();
+notSimplyBounded typedef F<X extends dynamic Function()> = dynamic Function(dynamic Function() );
''');
}
@@ -10667,7 +10674,7 @@
typedef G = F Function();
''');
checkElementText(library, r'''
-notSimplyBounded typedef F = dynamic Function();
+notSimplyBounded typedef F = dynamic Function() Function();
notSimplyBounded typedef G = dynamic Function() Function();
''');
}
@@ -10677,7 +10684,7 @@
typedef F = List<F> Function();
''');
checkElementText(library, r'''
-notSimplyBounded typedef F = dynamic Function();
+notSimplyBounded typedef F = List<dynamic Function()> Function();
''');
}
@@ -10713,7 +10720,7 @@
typedef void F<T extends F>();
''');
checkElementText(library, r'''
-notSimplyBounded typedef F<T extends void Function()> = void Function();
+notSimplyBounded typedef F<T extends dynamic Function()> = void Function();
''');
}
@@ -11988,6 +11995,189 @@
''');
}
+ /// TODO(scheglov) add `?` cases.
+ test_typedef_nonFunction_asInterfaceType_interfaceType_none() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef X<T> = A<int, T>;
+class A<T, U> {}
+class B implements X<String> {}
+''');
+ checkElementText(library, r'''
+typedef X<T> = A<int, T>;
+class A<T, U> {
+}
+class B implements A<int, String> {
+}
+''');
+ }
+
+ @failingTest
+ test_typedef_nonFunction_asInterfaceType_interfaceType_question() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef X<T> = A<T>?;
+class A<T> {}
+class B implements X<int> {}
+''');
+ checkElementText(library, r'''
+typedef X<T> = A<int, T>;
+class A<T, U> {
+}
+class B implements A<int, String> {
+}
+''');
+ }
+
+ /// TODO(scheglov) add `?` cases.
+ test_typedef_nonFunction_asInterfaceType_void() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef X = void;
+class A {}
+class B {}
+class C implements A, X, B {}
+''');
+ checkElementText(library, r'''
+typedef X = void;
+class A {
+}
+class B {
+}
+class C implements A, B {
+}
+''');
+ }
+
+ /// TODO(scheglov) add `?` cases.
+ test_typedef_nonFunction_asMixinType() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef X = A<int>;
+class A<T> {}
+class B with X {}
+''');
+ checkElementText(library, r'''
+typedef X = A<int>;
+class A<T> {
+}
+class B extends Object with A<int> {
+ synthetic B();
+}
+''');
+ }
+
+ /// TODO(scheglov) add `?` cases.
+ test_typedef_nonFunction_asSuperType_interfaceType() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef X = A<int>;
+class A<T> {}
+class B extends X {}
+''');
+ checkElementText(library, r'''
+typedef X = A<int>;
+class A<T> {
+}
+class B extends A<int> {
+}
+''');
+ }
+
+ /// TODO(scheglov) add `?` cases.
+ test_typedef_nonFunction_using_dynamic() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef A = dynamic;
+void f(A a) {}
+''');
+ checkElementText(library, r'''
+typedef A = dynamic;
+void f(dynamic a) {}
+''');
+ }
+
+ test_typedef_nonFunction_using_interface_disabled() async {
+ featureSet = featureSetNullSafe;
+ var library = await checkLibrary(r'''
+typedef A = int;
+void f(A a) {}
+''');
+
+ var alias = library.definingCompilationUnit.typeAliases[0];
+ _assertTypeStr(alias.aliasedType, 'dynamic Function()');
+
+ checkElementText(library, r'''
+typedef A = dynamic Function();
+void f(dynamic Function() a) {}
+''');
+ }
+
+ test_typedef_nonFunction_using_interface_noTypeParameters() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef A = int;
+void f(A a) {}
+''');
+ checkElementText(library, r'''
+typedef A = int;
+void f(int a) {}
+''');
+ }
+
+ test_typedef_nonFunction_using_interface_withTypeParameters() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef A<T> = Map<int, T>;
+void f(A<String> a) {}
+''');
+ checkElementText(library, r'''
+typedef A<T> = Map<int, T>;
+void f(Map<int, String> a) {}
+''');
+ }
+
+ /// TODO(scheglov) add `?` cases.
+ test_typedef_nonFunction_using_Never() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef A = Never;
+void f(A a) {}
+''');
+ checkElementText(library, r'''
+typedef A = Never;
+void f(Never a) {}
+''');
+ }
+
+ /// TODO(scheglov) add `?` cases.
+ test_typedef_nonFunction_using_typeParameter() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef A<T> = T;
+void f1(A a) {}
+void f2(A<int> a) {}
+''');
+ checkElementText(library, r'''
+typedef A<T> = T;
+void f1(dynamic a) {}
+void f2(int a) {}
+''');
+ }
+
+ /// TODO(scheglov) add `?` cases.
+ test_typedef_nonFunction_using_void() async {
+ featureSet = featureSetNonFunctionTypeAliases;
+ var library = await checkLibrary(r'''
+typedef A = void;
+void f(A a) {}
+''');
+ checkElementText(library, r'''
+typedef A = void;
+void f(void a) {}
+''');
+ }
+
test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() async {
// F is considered "not simply bounded" because it expands to a type that
// refers to C, which is not simply bounded.
@@ -12156,7 +12346,7 @@
var library = await checkLibrary('typedef void F<T extends F>();');
// Typedefs cannot reference themselves.
checkElementText(library, r'''
-notSimplyBounded typedef F<T extends void Function()> = void Function();
+notSimplyBounded typedef F<T extends dynamic Function()> = void Function();
''');
}
@@ -12164,7 +12354,7 @@
var library = await checkLibrary('typedef void F<T extends List<F>>();');
// Typedefs cannot reference themselves.
checkElementText(library, r'''
-notSimplyBounded typedef F<T extends List<void Function()>> = void Function();
+notSimplyBounded typedef F<T extends List<dynamic Function()>> = void Function();
''');
}
diff --git a/pkg/native_stack_traces/bin/decode.dart b/pkg/native_stack_traces/bin/decode.dart
index 9a7aee0..4ced1ca 100644
--- a/pkg/native_stack_traces/bin/decode.dart
+++ b/pkg/native_stack_traces/bin/decode.dart
@@ -300,12 +300,12 @@
if (options['help']) return print(_usages[options.command?.name]);
if (options.command == null) return errorWithUsage('no command provided');
- switch (options.command.name) {
+ switch (options.command!.name) {
case 'help':
- return help(options.command);
+ return help(options.command!);
case 'find':
- return find(options.command);
+ return find(options.command!);
case 'translate':
- return await translate(options.command);
+ return await translate(options.command!);
}
}
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 1d06186..9a3074b 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -83,6 +83,11 @@
defines += [ "TARGET_OS_MACOS" ]
} else if (target_os == "win") {
defines += [ "TARGET_OS_WINDOWS" ]
+ } else if (target_os == "winuwp") {
+ defines += [
+ "TARGET_OS_WINDOWS",
+ "TARGET_OS_WINDOWS_UWP",
+ ]
} else {
print("Unknown target_os: $target_os")
assert(false)
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 906eb34..40ff303 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -210,12 +210,14 @@
if (is_win) {
libs = [
"iphlpapi.lib",
- "psapi.lib",
"ws2_32.lib",
"Rpcrt4.lib",
"shlwapi.lib",
"winmm.lib",
]
+ if (target_os != "winuwp") {
+ libs += [ "psapi.lib" ]
+ }
}
}
}
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index dd11341..26d7d0b 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -932,19 +932,31 @@
}
int64_t Process::CurrentRSS() {
+// Although the documentation at
+// https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getprocessmemoryinfo
+// claims that GetProcessMemoryInfo is UWP compatible, it is actually not
+// hence this function cannot work when compiled in UWP mode.
+#ifdef TARGET_OS_WINDOWS_UWP
+ return -1;
+#else
PROCESS_MEMORY_COUNTERS pmc;
if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
return -1;
}
return pmc.WorkingSetSize;
+#endif
}
int64_t Process::MaxRSS() {
+#ifdef TARGET_OS_WINDOWS_UWP
+ return -1;
+#else
PROCESS_MEMORY_COUNTERS pmc;
if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
return -1;
}
return pmc.PeakWorkingSetSize;
+#endif
}
static SignalInfo* signal_handlers = NULL;
diff --git a/runtime/bin/security_context_win.cc b/runtime/bin/security_context_win.cc
index 1b49292..effdc5e 100644
--- a/runtime/bin/security_context_win.cc
+++ b/runtime/bin/security_context_win.cc
@@ -20,7 +20,9 @@
#include "bin/secure_socket_utils.h"
#include "platform/syslog.h"
+#ifndef TARGET_OS_WINDOWS_UWP
#pragma comment(lib, "crypt32.lib")
+#endif
namespace dart {
namespace bin {
@@ -42,6 +44,11 @@
// Add certificates from Windows trusted root store.
static bool AddCertificatesFromRootStore(X509_STORE* store) {
+// The UWP platform doesn't support CertEnumCertificatesInStore hence
+// this function cannot work when compiled in UWP mode.
+#ifdef TARGET_OS_WINDOWS_UWP
+ return false;
+#else
// Open root system store.
// Note that only current user certificates are accessible using this method,
// not the local machine store.
@@ -98,6 +105,7 @@
return false;
}
return true;
+#endif // ifdef TARGET_OS_WINDOWS_UWP
}
void SSLCertContext::TrustBuiltinRoots() {
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index bb85a96..2144be8 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -224,7 +224,7 @@
const auto& typed_data_class =
Class::Handle(zone, isolate->class_table()->At(cid));
const auto& error =
- Error::Handle(zone, typed_data_class.EnsureIsFinalized(thread));
+ Error::Handle(zone, typed_data_class.EnsureIsAllocateFinalized(thread));
if (!error.IsNull()) {
Exceptions::PropagateError(error);
}
diff --git a/runtime/lib/weak_property.cc b/runtime/lib/weak_property.cc
index 8715b6d..16eb41c 100644
--- a/runtime/lib/weak_property.cc
+++ b/runtime/lib/weak_property.cc
@@ -10,21 +10,20 @@
namespace dart {
-DEFINE_NATIVE_ENTRY(WeakProperty_new, 0, 2) {
- GET_NON_NULL_NATIVE_ARGUMENT(Instance, key, arguments->NativeArgAt(0));
- GET_NON_NULL_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(1));
- const WeakProperty& weak_property = WeakProperty::Handle(WeakProperty::New());
- weak_property.set_key(key);
- weak_property.set_value(value);
- return weak_property.raw();
-}
-
DEFINE_NATIVE_ENTRY(WeakProperty_getKey, 0, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
arguments->NativeArgAt(0));
return weak_property.key();
}
+DEFINE_NATIVE_ENTRY(WeakProperty_setKey, 0, 2) {
+ GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
+ arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, key, arguments->NativeArgAt(1));
+ weak_property.set_key(key);
+ return Object::null();
+}
+
DEFINE_NATIVE_ENTRY(WeakProperty_getValue, 0, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
arguments->NativeArgAt(0));
diff --git a/runtime/tests/vm/dart/regress_44342_test.dart b/runtime/tests/vm/dart/regress_44342_test.dart
new file mode 100644
index 0000000..98514fc
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_44342_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--deterministic --optimization_counter_threshold=100
+
+// Verifies that class of a constant participates in CHA decisions.
+// Regression test for https://github.com/dart-lang/sdk/issues/44342.
+
+import 'package:expect/expect.dart';
+
+class A {
+ const A();
+
+ int foo() => 3;
+
+ @pragma("vm:never-inline")
+ int bar() => foo();
+}
+
+class B extends A {}
+
+class C extends A {
+ const C();
+
+ int foo() => 4;
+}
+
+A x = B();
+A y = const C();
+
+main() {
+ for (int i = 0; i < 200; ++i) {
+ // Optimize A.bar() with inlined A.foo().
+ int result = x.bar();
+ Expect.equals(3, result);
+ }
+ int result = y.bar();
+ Expect.equals(4, result);
+}
diff --git a/runtime/tests/vm/dart_2/regress_44342_test.dart b/runtime/tests/vm/dart_2/regress_44342_test.dart
new file mode 100644
index 0000000..98514fc
--- /dev/null
+++ b/runtime/tests/vm/dart_2/regress_44342_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--deterministic --optimization_counter_threshold=100
+
+// Verifies that class of a constant participates in CHA decisions.
+// Regression test for https://github.com/dart-lang/sdk/issues/44342.
+
+import 'package:expect/expect.dart';
+
+class A {
+ const A();
+
+ int foo() => 3;
+
+ @pragma("vm:never-inline")
+ int bar() => foo();
+}
+
+class B extends A {}
+
+class C extends A {
+ const C();
+
+ int foo() => 4;
+}
+
+A x = B();
+A y = const C();
+
+main() {
+ for (int i = 0; i < 200; ++i) {
+ // Optimize A.bar() with inlined A.foo().
+ int result = x.bar();
+ Expect.equals(3, result);
+ }
+ int result = y.bar();
+ Expect.equals(4, result);
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index cdc1186..802cc8b 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -115,6 +115,7 @@
[ $mode == debug ]
cc/CorelibIsolateStartup: SkipByDesign # This is a benchmark that is not informative in debug mode.
+cc/SixtyThousandDartClasses: SkipSlow # Finalization of 64K classes is too slow in debug mode.
cc/VerifyExplicit_Crash: Crash # Negative tests of VerifiedMemory should crash iff in DEBUG mode. TODO(koda): Improve support for negative tests.
cc/VerifyImplicit_Crash: Crash # Negative tests of VerifiedMemory should crash iff in DEBUG mode. TODO(koda): Improve support for negative tests.
dart/appjit_cha_deopt_test: Pass, Slow # Quite slow in debug mode, uses --optimization-counter-threshold=100
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 49fac81..6fca249 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -49,8 +49,10 @@
libs = [
"advapi32.lib",
"shell32.lib",
- "dbghelp.lib",
]
+ if (target_os != "winuwp") {
+ libs += [ "dbghelp.lib" ]
+ }
} else {
libs = [ "dl" ]
if (!is_android) {
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index b1e5e653..df3b7ec 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -355,8 +355,8 @@
V(LinkedHashMap_setUsedData, 2) \
V(LinkedHashMap_getDeletedKeys, 1) \
V(LinkedHashMap_setDeletedKeys, 2) \
- V(WeakProperty_new, 2) \
V(WeakProperty_getKey, 1) \
+ V(WeakProperty_setKey, 2) \
V(WeakProperty_getValue, 1) \
V(WeakProperty_setValue, 2) \
V(Uri_isWindowsPlatform, 0) \
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 70d7a0d..023f790 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -4322,6 +4322,7 @@
Deserializer::InitializeHeader(property, kWeakPropertyCid,
WeakProperty::InstanceSize());
ReadFromTo(property);
+ property->ptr()->next_ = WeakProperty::null();
}
}
};
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index ea2fc4a..61cd91d 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -1122,7 +1122,7 @@
class_count_++;
cls.set_is_allocated(true);
- error_ = cls.EnsureIsFinalized(T);
+ error_ = cls.EnsureIsAllocateFinalized(T);
if (!error_.IsNull()) {
Jump(error_);
}
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 04c0b16..7ae73e4 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -2755,6 +2755,8 @@
case Slot::Kind::kTypeParameter_name:
case Slot::Kind::kUnhandledException_exception:
case Slot::Kind::kUnhandledException_stacktrace:
+ case Slot::Kind::kWeakProperty_key:
+ case Slot::Kind::kWeakProperty_value:
return false;
}
UNREACHABLE();
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index bc8f0ca..8a60a63 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -2736,6 +2736,8 @@
case Slot::Kind::kTypeParameter_name:
case Slot::Kind::kUnhandledException_exception:
case Slot::Kind::kUnhandledException_stacktrace:
+ case Slot::Kind::kWeakProperty_key:
+ case Slot::Kind::kWeakProperty_value:
// Not an integer valued field.
UNREACHABLE();
break;
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index ba85613..4e2414f 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -59,7 +59,9 @@
V(ClosureData, ClosureDataLayout, default_type_arguments, TypeArguments, \
FINAL) \
V(Function, FunctionLayout, type_parameters, TypeArguments, FINAL) \
- V(Type, TypeLayout, arguments, TypeArguments, FINAL)
+ V(Type, TypeLayout, arguments, TypeArguments, FINAL) \
+ V(WeakProperty, WeakPropertyLayout, key, Dynamic, VAR) \
+ V(WeakProperty, WeakPropertyLayout, value, Dynamic, VAR)
// The list of slots that correspond to non-nullable boxed fields of native
// objects in the following format:
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index d6bff45..6eb0a03 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -233,7 +233,8 @@
"%s is not loaded yet.",
klass.ToCString());
}
- const auto& obj = Object::Handle(Z, klass.EnsureIsFinalized(H.thread()));
+ const auto& obj =
+ Object::Handle(Z, klass.EnsureIsAllocateFinalized(H.thread()));
ASSERT(obj.IsNull());
ASSERT(klass.is_enum_class() || klass.is_const());
instance = Instance::New(klass, Heap::kOld);
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index e84cc87..fa468cc 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -867,6 +867,10 @@
case MethodRecognizer::kLinkedHashMap_setUsedData:
case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
+ case MethodRecognizer::kWeakProperty_getKey:
+ case MethodRecognizer::kWeakProperty_setKey:
+ case MethodRecognizer::kWeakProperty_getValue:
+ case MethodRecognizer::kWeakProperty_setValue:
case MethodRecognizer::kFfiAbi:
case MethodRecognizer::kReachabilityFence:
case MethodRecognizer::kUtf8DecoderScan:
@@ -1214,6 +1218,32 @@
StoreInstanceFieldInstr::Kind::kOther, kNoStoreBarrier);
body += NullConstant();
break;
+ case MethodRecognizer::kWeakProperty_getKey:
+ ASSERT(function.NumParameters() == 1);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadNativeField(Slot::WeakProperty_key());
+ break;
+ case MethodRecognizer::kWeakProperty_setKey:
+ ASSERT(function.NumParameters() == 2);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadLocal(parsed_function_->RawParameterVariable(1));
+ body += StoreInstanceField(TokenPosition::kNoSource,
+ Slot::WeakProperty_key());
+ body += NullConstant();
+ break;
+ case MethodRecognizer::kWeakProperty_getValue:
+ ASSERT(function.NumParameters() == 1);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadNativeField(Slot::WeakProperty_value());
+ break;
+ case MethodRecognizer::kWeakProperty_setValue:
+ ASSERT(function.NumParameters() == 2);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadLocal(parsed_function_->RawParameterVariable(1));
+ body += StoreInstanceField(TokenPosition::kNoSource,
+ Slot::WeakProperty_value());
+ body += NullConstant();
+ break;
case MethodRecognizer::kUtf8DecoderScan:
ASSERT(function.NumParameters() == 5);
body += LoadLocal(parsed_function_->RawParameterVariable(0)); // decoder
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 0892f8d..88a8b64a 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -158,6 +158,10 @@
V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0xaa10069e) \
V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0x29549b9e) \
V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0xac0f03a2) \
+ V(_WeakProperty, get:key, WeakProperty_getKey, 0x16b8624c) \
+ V(_WeakProperty, set:key, WeakProperty_setKey, 0x8b5df091) \
+ V(_WeakProperty, get:value, WeakProperty_getValue, 0x0baa0898) \
+ V(_WeakProperty, set:value, WeakProperty_setValue, 0x804f96dd) \
V(::, _classRangeCheck, ClassRangeCheck, 0x071d2ec8) \
V(::, _abi, FfiAbi, 0x54918e73) \
V(::, _asFunctionInternal, FfiAsFunctionInternal, 0x2d4e5e32) \
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 99e8810..739f168 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -384,6 +384,8 @@
return LinkedHashMap::InstanceSize();
case kUnhandledExceptionCid:
return UnhandledException::InstanceSize();
+ case kWeakPropertyCid:
+ return WeakProperty::InstanceSize();
case kByteBufferCid:
case kByteDataViewCid:
case kFfiPointerCid:
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 7ab2fdd..cb104ad 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -948,6 +948,8 @@
class WeakProperty : public AllStatic {
public:
+ static word key_offset();
+ static word value_offset();
static word InstanceSize();
static word NextFieldOffset();
};
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 2a76c83..63a046d 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -421,6 +421,8 @@
MonomorphicSmiableCall_entrypoint_offset = 12;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 8;
static constexpr dart::compiler::target::word Array_elements_start_offset = 12;
static constexpr dart::compiler::target::word Array_element_size = 4;
static constexpr dart::compiler::target::word
@@ -941,6 +943,8 @@
MonomorphicSmiableCall_entrypoint_offset = 24;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 16;
static constexpr dart::compiler::target::word Array_elements_start_offset = 24;
static constexpr dart::compiler::target::word Array_element_size = 8;
static constexpr dart::compiler::target::word
@@ -1457,6 +1461,8 @@
MonomorphicSmiableCall_entrypoint_offset = 12;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 8;
static constexpr dart::compiler::target::word Array_elements_start_offset = 12;
static constexpr dart::compiler::target::word Array_element_size = 4;
static constexpr dart::compiler::target::word
@@ -1974,6 +1980,8 @@
MonomorphicSmiableCall_entrypoint_offset = 24;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 16;
static constexpr dart::compiler::target::word Array_elements_start_offset = 24;
static constexpr dart::compiler::target::word Array_element_size = 8;
static constexpr dart::compiler::target::word
@@ -2490,6 +2498,8 @@
MonomorphicSmiableCall_entrypoint_offset = 12;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 8;
static constexpr dart::compiler::target::word Array_elements_start_offset = 12;
static constexpr dart::compiler::target::word Array_element_size = 4;
static constexpr dart::compiler::target::word
@@ -3004,6 +3014,8 @@
MonomorphicSmiableCall_entrypoint_offset = 24;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 16;
static constexpr dart::compiler::target::word Array_elements_start_offset = 24;
static constexpr dart::compiler::target::word Array_element_size = 8;
static constexpr dart::compiler::target::word
@@ -3514,6 +3526,8 @@
MonomorphicSmiableCall_entrypoint_offset = 12;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 8;
static constexpr dart::compiler::target::word Array_elements_start_offset = 12;
static constexpr dart::compiler::target::word Array_element_size = 4;
static constexpr dart::compiler::target::word
@@ -4025,6 +4039,8 @@
MonomorphicSmiableCall_entrypoint_offset = 24;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word WeakProperty_value_offset = 16;
static constexpr dart::compiler::target::word Array_elements_start_offset = 24;
static constexpr dart::compiler::target::word Array_element_size = 8;
static constexpr dart::compiler::target::word
@@ -4581,6 +4597,8 @@
AOT_MonomorphicSmiableCall_entrypoint_offset = 12;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
12;
static constexpr dart::compiler::target::word AOT_Array_element_size = 4;
@@ -5154,6 +5172,9 @@
AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset =
+ 16;
static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
24;
static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
@@ -5731,6 +5752,9 @@
AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset =
+ 16;
static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
24;
static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
@@ -6302,6 +6326,8 @@
AOT_MonomorphicSmiableCall_entrypoint_offset = 12;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 4;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
12;
static constexpr dart::compiler::target::word AOT_Array_element_size = 4;
@@ -6868,6 +6894,9 @@
AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset =
+ 16;
static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
24;
static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
@@ -7438,6 +7467,9 @@
AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_key_offset = 8;
+static constexpr dart::compiler::target::word AOT_WeakProperty_value_offset =
+ 16;
static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
24;
static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index fc6cfdc..bc52da9 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -285,6 +285,8 @@
FIELD(MonomorphicSmiableCall, expected_cid_offset) \
FIELD(MonomorphicSmiableCall, entrypoint_offset) \
FIELD(MonomorphicSmiableCall, target_offset) \
+ FIELD(WeakProperty, key_offset) \
+ FIELD(WeakProperty, value_offset) \
ARRAY(Array, element_offset) \
ARRAY(TypeArguments, type_at_offset) \
NOT_IN_PRODUCT(ARRAY(ClassTable, ClassOffsetFor)) \
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 2b0c369..49c32bc 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -4627,7 +4627,7 @@
return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
}
#endif
- CHECK_ERROR_HANDLE(cls.EnsureIsFinalized(T));
+ CHECK_ERROR_HANDLE(cls.EnsureIsAllocateFinalized(T));
return Api::NewHandle(T, AllocateObject(T, cls));
}
@@ -4653,7 +4653,7 @@
return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
}
#endif
- CHECK_ERROR_HANDLE(cls.EnsureIsFinalized(T));
+ CHECK_ERROR_HANDLE(cls.EnsureIsAllocateFinalized(T));
if (num_native_fields != cls.num_native_fields()) {
return Api::NewError(
"%s: invalid number of native fields %" Pd " passed in, expected %d",
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 53ecf122..bceb31c 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -34,7 +34,7 @@
page_space_(page_space),
work_list_(marking_stack),
deferred_work_list_(deferred_marking_stack),
- delayed_weak_properties_(nullptr),
+ delayed_weak_properties_(WeakProperty::null()),
marked_bytes_(0),
marked_micros_(0) {
ASSERT(thread_->isolate_group() == isolate_group);
@@ -48,12 +48,12 @@
bool ProcessPendingWeakProperties() {
bool marked = false;
WeakPropertyPtr cur_weak = delayed_weak_properties_;
- delayed_weak_properties_ = nullptr;
- while (cur_weak != nullptr) {
- uword next_weak = cur_weak->ptr()->next_;
+ delayed_weak_properties_ = WeakProperty::null();
+ while (cur_weak != WeakProperty::null()) {
+ WeakPropertyPtr next_weak = cur_weak->ptr()->next_;
ObjectPtr raw_key = cur_weak->ptr()->key_;
// Reset the next pointer in the weak property.
- cur_weak->ptr()->next_ = 0;
+ cur_weak->ptr()->next_ = WeakProperty::null();
if (raw_key->ptr()->IsMarked()) {
ObjectPtr raw_val = cur_weak->ptr()->value_;
marked =
@@ -67,7 +67,7 @@
EnqueueWeakProperty(cur_weak);
}
// Advance to next weak property in the queue.
- cur_weak = static_cast<WeakPropertyPtr>(next_weak);
+ cur_weak = next_weak;
}
return marked;
}
@@ -133,8 +133,8 @@
ASSERT(raw_weak->IsOldObject());
ASSERT(raw_weak->IsWeakProperty());
ASSERT(raw_weak->ptr()->IsMarked());
- ASSERT(raw_weak->ptr()->next_ == 0);
- raw_weak->ptr()->next_ = static_cast<uword>(delayed_weak_properties_);
+ ASSERT(raw_weak->ptr()->next_ == WeakProperty::null());
+ raw_weak->ptr()->next_ = delayed_weak_properties_;
delayed_weak_properties_ = raw_weak;
}
@@ -185,16 +185,16 @@
work_list_.Finalize();
// Clear pending weak properties.
WeakPropertyPtr cur_weak = delayed_weak_properties_;
- delayed_weak_properties_ = nullptr;
+ delayed_weak_properties_ = WeakProperty::null();
intptr_t weak_properties_cleared = 0;
- while (cur_weak != nullptr) {
- uword next_weak = cur_weak->ptr()->next_;
- cur_weak->ptr()->next_ = 0;
+ while (cur_weak != WeakProperty::null()) {
+ WeakPropertyPtr next_weak = cur_weak->ptr()->next_;
+ cur_weak->ptr()->next_ = WeakProperty::null();
RELEASE_ASSERT(!cur_weak->ptr()->key_->ptr()->IsMarked());
WeakProperty::Clear(cur_weak);
weak_properties_cleared++;
// Advance to next weak property in the queue.
- cur_weak = static_cast<WeakPropertyPtr>(next_weak);
+ cur_weak = next_weak;
}
}
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index f30cd08..3f6f09d 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -118,7 +118,8 @@
freelist_(freelist),
bytes_promoted_(0),
visiting_old_object_(nullptr),
- promoted_list_(promotion_stack) {}
+ promoted_list_(promotion_stack),
+ delayed_weak_properties_(WeakProperty::null()) {}
virtual void VisitTypedDataViewPointers(TypedDataViewPtr view,
ObjectPtr* first,
@@ -426,7 +427,7 @@
ObjectPtr visiting_old_object_;
PromotionWorkList promoted_list_;
- WeakPropertyPtr delayed_weak_properties_ = nullptr;
+ WeakPropertyPtr delayed_weak_properties_;
NewPage* head_ = nullptr;
NewPage* tail_ = nullptr; // Allocating from here.
@@ -1181,9 +1182,9 @@
// for which the keys have become reachable. Potentially this adds more
// objects to the to space.
WeakPropertyPtr cur_weak = delayed_weak_properties_;
- delayed_weak_properties_ = nullptr;
- while (cur_weak != nullptr) {
- uword next_weak = cur_weak->ptr()->next_;
+ delayed_weak_properties_ = WeakProperty::null();
+ while (cur_weak != WeakProperty::null()) {
+ WeakPropertyPtr next_weak = cur_weak->ptr()->next_;
// Promoted weak properties are not enqueued. So we can guarantee that
// we do not need to think about store barriers here.
ASSERT(cur_weak->IsNewObject());
@@ -1197,14 +1198,14 @@
ASSERT(from_->Contains(raw_addr));
uword header = *reinterpret_cast<uword*>(raw_addr);
// Reset the next pointer in the weak property.
- cur_weak->ptr()->next_ = 0;
+ cur_weak->ptr()->next_ = WeakProperty::null();
if (IsForwarding(header)) {
cur_weak->ptr()->VisitPointersNonvirtual(this);
} else {
EnqueueWeakProperty(cur_weak);
}
// Advance to next weak property in the queue.
- cur_weak = static_cast<WeakPropertyPtr>(next_weak);
+ cur_weak = next_weak;
}
}
@@ -1244,8 +1245,8 @@
uword header = *reinterpret_cast<uword*>(raw_addr);
ASSERT(!IsForwarding(header));
#endif // defined(DEBUG)
- ASSERT(raw_weak->ptr()->next_ == 0);
- raw_weak->ptr()->next_ = static_cast<uword>(delayed_weak_properties_);
+ ASSERT(raw_weak->ptr()->next_ == WeakProperty::null());
+ raw_weak->ptr()->next_ = delayed_weak_properties_;
delayed_weak_properties_ = raw_weak;
}
@@ -1330,11 +1331,11 @@
// The queued weak properties at this point do not refer to reachable keys,
// so we clear their key and value fields.
WeakPropertyPtr cur_weak = delayed_weak_properties_;
- delayed_weak_properties_ = nullptr;
- while (cur_weak != nullptr) {
- uword next_weak = cur_weak->ptr()->next_;
+ delayed_weak_properties_ = WeakProperty::null();
+ while (cur_weak != WeakProperty::null()) {
+ WeakPropertyPtr next_weak = cur_weak->ptr()->next_;
// Reset the next pointer in the weak property.
- cur_weak->ptr()->next_ = 0;
+ cur_weak->ptr()->next_ = WeakProperty::null();
#if defined(DEBUG)
ObjectPtr raw_key = cur_weak->ptr()->key_;
@@ -1348,7 +1349,7 @@
WeakProperty::Clear(cur_weak);
// Advance to next weak property in the queue.
- cur_weak = static_cast<WeakPropertyPtr>(next_weak);
+ cur_weak = next_weak;
}
}
diff --git a/runtime/vm/native_symbol_win.cc b/runtime/vm/native_symbol_win.cc
index 0f2c0ce..9ddc3a4 100644
--- a/runtime/vm/native_symbol_win.cc
+++ b/runtime/vm/native_symbol_win.cc
@@ -23,6 +23,10 @@
lock_ = new Mutex();
}
running_ = true;
+
+// Symbol resolution API's used in this file are not supported
+// when compiled in UWP.
+#ifndef TARGET_OS_WINDOWS_UWP
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
HANDLE hProcess = GetCurrentProcess();
if (!SymInitialize(hProcess, NULL, TRUE)) {
@@ -32,6 +36,7 @@
error);
return;
}
+#endif
}
void NativeSymbolResolver::Cleanup() {
@@ -40,6 +45,7 @@
return;
}
running_ = false;
+#ifndef TARGET_OS_WINDOWS_UWP
HANDLE hProcess = GetCurrentProcess();
if (!SymCleanup(hProcess)) {
DWORD error = GetLastError();
@@ -47,9 +53,13 @@
")\n",
error);
}
+#endif
}
char* NativeSymbolResolver::LookupSymbolName(uword pc, uword* start) {
+#ifdef TARGET_OS_WINDOWS_UWP
+ return NULL;
+#else
static const intptr_t kMaxNameLength = 2048;
static const intptr_t kSymbolInfoSize = sizeof(SYMBOL_INFO); // NOLINT.
static char buffer[kSymbolInfoSize + kMaxNameLength];
@@ -76,6 +86,7 @@
*start = pc - displacement;
}
return Utils::StrDup(pSymbol->Name);
+#endif // ifdef TARGET_OS_WINDOWS_UWP
}
void NativeSymbolResolver::FreeSymbolName(char* name) {
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 803e75c..f11ffea 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -4310,6 +4310,10 @@
UNREACHABLE();
}
}
+ // May be allocate-finalized recursively during EnsureIsFinalized.
+ if (is_allocate_finalized()) {
+ return Error::null();
+ }
error ^= ClassFinalizer::AllocateFinalizeClass(*this);
return error.raw();
}
@@ -18756,7 +18760,7 @@
InstancePtr Instance::New(const Class& cls, Heap::Space space) {
Thread* thread = Thread::Current();
- if (cls.EnsureIsFinalized(thread) != Error::null()) {
+ if (cls.EnsureIsAllocateFinalized(thread) != Error::null()) {
return Instance::null();
}
intptr_t instance_size = cls.host_instance_size();
@@ -23912,7 +23916,7 @@
const Class& cls =
Class::Handle(Isolate::Current()->class_table()->At(kFfiPointerCid));
- cls.EnsureIsFinalized(Thread::Current());
+ cls.EnsureIsAllocateFinalized(Thread::Current());
Pointer& result = Pointer::Handle(zone);
result ^= Object::Allocate(kFfiPointerCid, Pointer::InstanceSize(), space);
@@ -24713,9 +24717,7 @@
Class::null());
ObjectPtr raw = Object::Allocate(WeakProperty::kClassId,
WeakProperty::InstanceSize(), space);
- WeakPropertyPtr result = static_cast<WeakPropertyPtr>(raw);
- result->ptr()->next_ = 0; // Init the list to NULL.
- return result;
+ return static_cast<WeakPropertyPtr>(raw);
}
const char* WeakProperty::ToCString() const {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 59377eb..b729ba3 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -10968,14 +10968,16 @@
class WeakProperty : public Instance {
public:
ObjectPtr key() const { return raw_ptr()->key(); }
-
void set_key(const Object& key) const { raw_ptr()->set_key(key.raw()); }
+ static intptr_t key_offset() { return OFFSET_OF(WeakPropertyLayout, key_); }
ObjectPtr value() const { return raw_ptr()->value(); }
-
void set_value(const Object& value) const {
raw_ptr()->set_value(value.raw());
}
+ static intptr_t value_offset() {
+ return OFFSET_OF(WeakPropertyLayout, value_);
+ }
static WeakPropertyPtr New(Heap::Space space = Heap::kNew);
@@ -10984,7 +10986,7 @@
}
static void Clear(WeakPropertyPtr raw_weak) {
- ASSERT(raw_weak->ptr()->next_ == 0);
+ ASSERT(raw_weak->ptr()->next_ == WeakProperty::null());
// This action is performed by the GC. No barrier.
raw_weak->ptr()->key_ = Object::null();
raw_weak->ptr()->value_ = Object::null();
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 0f9c283..bc02ac3 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2898,9 +2898,9 @@
VISIT_TO(ObjectPtr, value)
ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
- // Linked list is chaining all pending weak properties.
- // Untyped to make it clear that it is not to be visited by GC.
- uword next_;
+ // Linked list is chaining all pending weak properties. Not visited by
+ // pointer visitors.
+ WeakPropertyPtr next_;
friend class GCMarker;
template <bool>
diff --git a/sdk/lib/_internal/vm/lib/expando_patch.dart b/sdk/lib/_internal/vm/lib/expando_patch.dart
index 1d99cab..01cbe51 100644
--- a/sdk/lib/_internal/vm/lib/expando_patch.dart
+++ b/sdk/lib/_internal/vm/lib/expando_patch.dart
@@ -13,7 +13,7 @@
_used = 0;
static const _minSize = 8;
- static final _deletedEntry = new _WeakProperty(null, null);
+ static final _deletedEntry = new _WeakProperty();
@patch
T? operator [](Object object) {
@@ -25,7 +25,7 @@
while (wp != null) {
if (identical(wp.key, object)) {
- return wp.value;
+ return unsafeCast<T?>(wp.value);
} else if (wp.key == null) {
// This entry has been cleared by the GC.
_data[idx] = _deletedEntry;
@@ -82,7 +82,10 @@
}
if (_used < _limit) {
- _data[idx] = new _WeakProperty(object, value);
+ var ephemeron = new _WeakProperty();
+ ephemeron.key = object;
+ ephemeron.value = value;
+ _data[idx] = ephemeron;
_used++;
return;
}
diff --git a/sdk/lib/_internal/vm/lib/weak_property.dart b/sdk/lib/_internal/vm/lib/weak_property.dart
index bc903e9..defcd40 100644
--- a/sdk/lib/_internal/vm/lib/weak_property.dart
+++ b/sdk/lib/_internal/vm/lib/weak_property.dart
@@ -6,15 +6,17 @@
@pragma("vm:entry-point")
class _WeakProperty {
- factory _WeakProperty(key, value) => _new(key, value);
+ @pragma("vm:recognized", "other")
+ @pragma("vm:prefer-inline")
+ get key native "WeakProperty_getKey";
+ @pragma("vm:recognized", "other")
+ @pragma("vm:prefer-inline")
+ set key(k) native "WeakProperty_setKey";
- get key => _getKey();
- get value => _getValue();
- set value(value) => _setValue(value);
-
- static _WeakProperty _new(key, value) native "WeakProperty_new";
-
- _getKey() native "WeakProperty_getKey";
- _getValue() native "WeakProperty_getValue";
- _setValue(value) native "WeakProperty_setValue";
+ @pragma("vm:recognized", "other")
+ @pragma("vm:prefer-inline")
+ get value native "WeakProperty_getValue";
+ @pragma("vm:recognized", "other")
+ @pragma("vm:prefer-inline")
+ set value(v) native "WeakProperty_setValue";
}
diff --git a/tests/language/regress/regress33479_test.dart b/tests/language/regress/regress33479_test.dart
index f1e8336..cb07911 100644
--- a/tests/language/regress/regress33479_test.dart
+++ b/tests/language/regress/regress33479_test.dart
@@ -1,28 +1,16 @@
class Hest<TypeX extends Fisk> {}
-// ^^^^
-// [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND
typedef Fisk = void Function // don't merge lines
-// [error line 5, column 1, length 462]
+// [error line 3, column 1, length 346]
// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
// ^
// [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
- <TypeY extends Hest>
- // ^^^^
- // [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT
- ();
+ <TypeY extends Hest>();
main() {
Hest hest = new Hest();
-//^^^^
-// [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT
// ^
// [cfe] A generic function type can't be used as a type argument.
-// ^^^^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// ^^^^
-// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
// [cfe] Generic function type 'void Function<TypeY>()' inferred as a type argument.
-// ^^^^
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
}
diff --git a/tests/language_2/regress/regress33479_test.dart b/tests/language_2/regress/regress33479_test.dart
index b1225c3..cb07911 100644
--- a/tests/language_2/regress/regress33479_test.dart
+++ b/tests/language_2/regress/regress33479_test.dart
@@ -1,28 +1,16 @@
class Hest<TypeX extends Fisk> {}
-// ^^^^
-// [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND
typedef Fisk = void Function // don't merge lines
-// [error line 5, column 1, length 462]
+// [error line 3, column 1, length 346]
// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
// ^
// [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
- <TypeY extends Hest>
- // ^^^^
- // [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT
- ();
+ <TypeY extends Hest>();
main() {
Hest hest = new Hest();
-//^^^^
-// [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT
// ^
// [cfe] A generic function type can't be used as a type argument.
-// ^^^^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_CAST_NEW_EXPR
// ^^^^
-// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
// [cfe] Generic function type 'void Function<TypeY>()' inferred as a type argument.
-// ^^^^
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
}
diff --git a/tests/lib/lib_dartdevc.status b/tests/lib/lib_dartdevc.status
index 61d487d..cfdf3fa 100644
--- a/tests/lib/lib_dartdevc.status
+++ b/tests/lib/lib_dartdevc.status
@@ -42,4 +42,3 @@
mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
typed_data/int64_list_load_store_test: SkipByDesign # dartdevk/c does not support Int64List
typed_data/typed_data_hierarchy_int64_test: SkipByDesign # dartdevk/c does not support Int64List
-typed_data/unmodifiable_typed_data_test: SkipByDesign # dartdevk/c does not support Int64List
diff --git a/tests/lib/math/random_big_test.dart b/tests/lib/math/random_big_test.dart
index 41a5651..25c57e7 100644
--- a/tests/lib/math/random_big_test.dart
+++ b/tests/lib/math/random_big_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// Test that Random can deal with a seed outside 64-bit range.
+// Test that Random can deal with a seed at upper end of 64-bit range.
import "package:expect/expect.dart";
import 'dart:math';
@@ -10,7 +10,7 @@
main() {
var results = [];
for (var i = 60; i < 64; i++) {
- var rng = new Random(1 << i);
+ var rng = new Random(pow(2, i) as int);
var val = rng.nextInt(100000);
print("$i: $val");
Expect.isFalse(results.contains(val));
diff --git a/tests/lib/typed_data/unmodifiable_typed_data_test.dart b/tests/lib/typed_data/unmodifiable_typed_data_test.dart
index 70708c5..2a04cd7 100644
--- a/tests/lib/typed_data/unmodifiable_typed_data_test.dart
+++ b/tests/lib/typed_data/unmodifiable_typed_data_test.dart
@@ -5,6 +5,8 @@
import 'dart:typed_data';
import 'package:expect/expect.dart';
+const bool supportsInt64 = bool.fromEnvironment('dart.isVM');
+
List<int> intList = <int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
checkReadable(List<int> list) {
@@ -157,8 +159,10 @@
uint16ListTest();
int32ListTest();
uint32ListTest();
- int64ListTest();
- uint64ListTest();
+ if (supportsInt64) {
+ int64ListTest();
+ uint64ListTest();
+ }
float32ListTest();
float64ListTest();
byteDataTest();
diff --git a/tests/lib_2/math/random_big_test.dart b/tests/lib_2/math/random_big_test.dart
index 41a5651..25c57e7 100644
--- a/tests/lib_2/math/random_big_test.dart
+++ b/tests/lib_2/math/random_big_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// Test that Random can deal with a seed outside 64-bit range.
+// Test that Random can deal with a seed at upper end of 64-bit range.
import "package:expect/expect.dart";
import 'dart:math';
@@ -10,7 +10,7 @@
main() {
var results = [];
for (var i = 60; i < 64; i++) {
- var rng = new Random(1 << i);
+ var rng = new Random(pow(2, i) as int);
var val = rng.nextInt(100000);
print("$i: $val");
Expect.isFalse(results.contains(val));
diff --git a/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart b/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
index 70708c5..2a04cd7 100644
--- a/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
+++ b/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
@@ -5,6 +5,8 @@
import 'dart:typed_data';
import 'package:expect/expect.dart';
+const bool supportsInt64 = bool.fromEnvironment('dart.isVM');
+
List<int> intList = <int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
checkReadable(List<int> list) {
@@ -157,8 +159,10 @@
uint16ListTest();
int32ListTest();
uint32ListTest();
- int64ListTest();
- uint64ListTest();
+ if (supportsInt64) {
+ int64ListTest();
+ uint64ListTest();
+ }
float32ListTest();
float64ListTest();
byteDataTest();
diff --git a/tools/VERSION b/tools/VERSION
index 4f60b94..39a0b88 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 118
+PRERELEASE 119
PRERELEASE_PATCH 0
\ No newline at end of file