Version 2.15.0-106.0.dev
Merge commit 'e08ee7abecd889a55bee49afe635ea620b28b93e' into 'dev'
diff --git a/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart b/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart
index 8180f0b..c5c8763 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart
@@ -75,7 +75,7 @@
Future<void> test_isInConstContext() async {
await testUpdate(content: '''
-const a = 0;
+const num a = 0;
const c = a is int;
''', to: '^2.2.2');
}
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 9c671fc..f037f8b 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -440,13 +440,16 @@
CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER,
CompileTimeErrorCode.UNDEFINED_FUNCTION,
CompileTimeErrorCode.UNDEFINED_GETTER,
+ CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE,
CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
CompileTimeErrorCode.UNDEFINED_IDENTIFIER_AWAIT,
CompileTimeErrorCode.UNDEFINED_METHOD,
+ CompileTimeErrorCode.UNDEFINED_METHOD_ON_FUNCTION_TYPE,
CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER,
CompileTimeErrorCode.UNDEFINED_OPERATOR,
CompileTimeErrorCode.UNDEFINED_PREFIXED_NAME,
CompileTimeErrorCode.UNDEFINED_SETTER,
+ CompileTimeErrorCode.UNDEFINED_SETTER_ON_FUNCTION_TYPE,
CompileTimeErrorCode.UNDEFINED_SUPER_GETTER,
CompileTimeErrorCode.UNDEFINED_SUPER_METHOD,
CompileTimeErrorCode.UNDEFINED_SUPER_OPERATOR,
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index f0583b2..bc6446c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -80,7 +80,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 = 177;
+ static const int DATA_VERSION = 178;
/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 0032336..66bc7a5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -1007,8 +1007,10 @@
_uriToFile.clear();
knownFilePaths.clear();
knownFiles.clear();
+ _hasUriForPath.clear();
_pathToFiles.clear();
_pathToCanonicalFile.clear();
+ _librariesWithoutPartsRead.clear();
_partToLibraries.clear();
_subtypedNameToFiles.clear();
}
diff --git a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
index 1731023..12c0ab3 100644
--- a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
@@ -264,11 +264,12 @@
@override
void visitDefaultFormalParameter(DefaultFormalParameter node) {
_visitNode(node.parameter);
- if (node.separator != null) {
- if (node.separator!.lexeme != ':') {
+ var separator = node.separator;
+ if (separator != null) {
+ if (separator.lexeme != ':') {
sink.write(' ');
}
- sink.write(node.separator!.lexeme);
+ sink.write(separator.lexeme);
_visitNode(node.defaultValue, prefix: ' ');
}
}
@@ -728,14 +729,8 @@
@override
void visitMethodInvocation(MethodInvocation node) {
- if (node.isCascaded) {
- sink.write(node.operator!.lexeme);
- } else {
- if (node.target != null) {
- node.target!.accept(this);
- sink.write(node.operator!.lexeme);
- }
- }
+ _visitNode(node.target);
+ _visitToken(node.operator);
_visitNode(node.methodName);
_visitNode(node.typeArguments);
_visitNode(node.argumentList);
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index 513220e..1dc3670 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/scope.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/ast_factory.dart';
@@ -26,7 +27,9 @@
class AstRewriter {
final ErrorReporter _errorReporter;
- AstRewriter(this._errorReporter);
+ final TypeProvider _typeProvider;
+
+ AstRewriter(this._errorReporter, this._typeProvider);
/// Possibly rewrites [node] as a [MethodInvocation] with a
/// [FunctionReference] target.
@@ -45,9 +48,15 @@
var typeName = node.constructorName.type.name;
if (typeName is SimpleIdentifier) {
var element = nameScope.lookup(typeName.name).getter;
- if (element is FunctionElement || element is MethodElement) {
+ if (element is FunctionElement ||
+ element is MethodElement ||
+ element is PropertyAccessorElement) {
return _toMethodInvocationOfFunctionReference(
node: node, function: typeName);
+ } else if (element is TypeAliasElement &&
+ element.aliasedElement is GenericFunctionTypeElement) {
+ return _toMethodInvocationOfAliasedTypeLiteral(
+ node: node, function: typeName, element: element);
}
} else if (typeName is PrefixedIdentifier) {
var prefixElement = nameScope.lookup(typeName.prefix.name).getter;
@@ -57,6 +66,10 @@
if (element is FunctionElement) {
return _toMethodInvocationOfFunctionReference(
node: node, function: typeName);
+ } else if (element is TypeAliasElement &&
+ element.aliasedElement is GenericFunctionTypeElement) {
+ return _toMethodInvocationOfAliasedTypeLiteral(
+ node: node, function: typeName, element: element);
}
// If `element` is a [ClassElement], or a [TypeAliasElement] aliasing
@@ -490,6 +503,28 @@
return instanceCreationExpression;
}
+ MethodInvocation _toMethodInvocationOfAliasedTypeLiteral({
+ required InstanceCreationExpression node,
+ required Identifier function,
+ required TypeAliasElement element,
+ }) {
+ var typeName = astFactory.typeName(node.constructorName.type.name,
+ node.constructorName.type.typeArguments);
+ typeName.type = element.aliasedType;
+ typeName.name.staticType = element.aliasedType;
+ var typeLiteral = astFactory.typeLiteral(typeName: typeName);
+ typeLiteral.staticType = _typeProvider.typeType;
+ var methodInvocation = astFactory.methodInvocation(
+ typeLiteral,
+ node.constructorName.period,
+ node.constructorName.name!,
+ null,
+ node.argumentList,
+ );
+ NodeReplacer.replace(node, methodInvocation);
+ return methodInvocation;
+ }
+
MethodInvocation _toMethodInvocationOfFunctionReference({
required InstanceCreationExpression node,
required Identifier function,
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
index aabb65f..790cd79 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -564,7 +564,13 @@
// `prefix.C<int>.name` is initially represented as a [PropertyAccess]
// with a [FunctionReference] target.
if (node.parent is PropertyAccess) {
- _resolveConstructorReference(node);
+ if (element is TypeAliasElement &&
+ element.aliasedType is FunctionType) {
+ function.staticElement = element;
+ _resolveTypeAlias(node: node, element: element, typeAlias: function);
+ } else {
+ _resolveConstructorReference(node);
+ }
return;
} else if (element is ClassElement) {
function.staticElement = element;
@@ -649,6 +655,10 @@
required DartType instantiatedType,
required Identifier name,
}) {
+ // TODO(srawlins): set the static element of [typeName].
+ // This involves a fair amount of resolution, as [name] may be a prefixed
+ // identifier, etc. [TypeName]s should be resolved in [ResolutionVisitor],
+ // and this could be done for nodes like this via [AstRewriter].
var typeName = astFactory.typeName(name, node.typeArguments);
typeName.type = instantiatedType;
typeName.name.staticType = instantiatedType;
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index d5d7b50..190ab31 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -164,6 +164,21 @@
return;
}
+ if (receiver is TypeLiteralImpl &&
+ receiver.typeName.typeArguments != null &&
+ receiver.typeName.type is FunctionType) {
+ // There is no possible resolution for a property access of a function
+ // type literal (which can only be a type instantiation of a type alias
+ // of a function type).
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.UNDEFINED_METHOD_ON_FUNCTION_TYPE,
+ nameNode,
+ [name, receiver.typeName.name.name],
+ );
+ _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
+ return;
+ }
+
_resolveReceiverType(
node: node,
receiver: receiver,
diff --git a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
index 84c1ec2..86f1008 100644
--- a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
@@ -368,6 +368,26 @@
targetType = _typeSystem.promoteToNonNull(targetType);
}
+ if (target is TypeLiteral && target.typeName.type is FunctionType) {
+ // There is no possible resolution for a property access of a function
+ // type literal (which can only be a type instantiation of a type alias
+ // of a function type).
+ if (hasRead) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE,
+ propertyName,
+ [propertyName.name, target.typeName.name.name],
+ );
+ } else {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.UNDEFINED_SETTER_ON_FUNCTION_TYPE,
+ propertyName,
+ [propertyName.name, target.typeName.name.name],
+ );
+ }
+ return PropertyElementResolverResult();
+ }
+
var result = _resolver.typePropertyResolver.resolve(
receiver: target,
receiverType: targetType,
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 9efde38..d25fcf6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -116,7 +116,7 @@
unitElement,
isNonNullableByDefault,
errorReporter,
- AstRewriter(errorReporter),
+ AstRewriter(errorReporter, typeProvider),
typeNameResolver,
nameScope,
elementWalker,
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index f7988fd1..c93f71d 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -13838,6 +13838,19 @@
/**
* Parameters:
+ * 0: the name of the getter
+ * 1: the name of the function type alias
+ */
+ static const CompileTimeErrorCode UNDEFINED_GETTER_ON_FUNCTION_TYPE =
+ CompileTimeErrorCode('UNDEFINED_GETTER',
+ "The getter '{0}' isn't defined for the '{1}' function type.",
+ correction: "Try wrapping the function type alias in parentheses in "
+ "order to access '{0}' as an extension getter on 'Type'.",
+ hasPublishedDocs: true,
+ uniqueName: 'UNDEFINED_GETTER_ON_FUNCTION_TYPE');
+
+ /**
+ * Parameters:
* 0: the name of the identifier
*/
// #### Description
@@ -13947,6 +13960,19 @@
/**
* Parameters:
+ * 0: the name of the method
+ * 1: the name of the function type alias
+ */
+ static const CompileTimeErrorCode UNDEFINED_METHOD_ON_FUNCTION_TYPE =
+ CompileTimeErrorCode('UNDEFINED_METHOD',
+ "The method '{0}' isn't defined for the '{1}' function type.",
+ correction: "Try wrapping the function type alias in parentheses in "
+ "order to access '{0}' as an extension method on 'Type'.",
+ hasPublishedDocs: true,
+ uniqueName: 'UNDEFINED_METHOD_ON_FUNCTION_TYPE');
+
+ /**
+ * Parameters:
* 0: the name of the requested named parameter
*/
// #### Description
@@ -14150,6 +14176,19 @@
/**
* Parameters:
+ * 0: the name of the setter
+ * 1: the name of the function type alias
+ */
+ static const CompileTimeErrorCode UNDEFINED_SETTER_ON_FUNCTION_TYPE =
+ CompileTimeErrorCode('UNDEFINED_SETTER',
+ "The setter '{0}' isn't defined for the '{1}' function type.",
+ correction: "Try wrapping the function type alias in parentheses in "
+ "order to access '{0}' as an extension getter on 'Type'.",
+ hasPublishedDocs: true,
+ uniqueName: 'UNDEFINED_SETTER_ON_FUNCTION_TYPE');
+
+ /**
+ * Parameters:
* 0: the name of the getter
* 1: the name of the enclosing type where the getter is being looked for
*/
@@ -15108,7 +15147,7 @@
isUnresolvedIdentifier: isUnresolvedIdentifier,
message: message,
name: name,
- uniqueName: uniqueName ?? 'CompileTimeErrorCode.$name',
+ uniqueName: 'CompileTimeErrorCode.${uniqueName ?? name}',
);
@override
@@ -15539,7 +15578,7 @@
isUnresolvedIdentifier: isUnresolvedIdentifier,
message: message,
name: name,
- uniqueName: uniqueName ?? 'StaticWarningCode.$name',
+ uniqueName: 'StaticWarningCode.${uniqueName ?? name}',
);
@override
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index a75433d..61f2728 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -805,14 +805,20 @@
var typeArguments = _readOptionalNode() as TypeArgumentList?;
var arguments = readNode() as ArgumentList;
+ Token? operator;
+ if (AstBinaryFlags.hasQuestion(flags)) {
+ operator = AstBinaryFlags.hasPeriod(flags)
+ ? Tokens.questionPeriod()
+ : Tokens.questionPeriodPeriod();
+ } else if (AstBinaryFlags.hasPeriod(flags)) {
+ operator = Tokens.period();
+ } else if (AstBinaryFlags.hasPeriod2(flags)) {
+ operator = Tokens.periodPeriod();
+ }
+
var node = astFactory.methodInvocation(
target,
- Tokens.choose(
- AstBinaryFlags.hasPeriod(flags),
- Tokens.period(),
- AstBinaryFlags.hasPeriod2(flags),
- Tokens.periodPeriod(),
- ),
+ operator,
methodName,
typeArguments,
arguments,
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 6287bc4..11fcb12 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -485,12 +485,18 @@
void visitMethodInvocation(MethodInvocation node) {
_writeByte(Tag.MethodInvocation);
+ var operatorType = node.operator?.type;
_writeByte(
AstBinaryFlags.encode(
- hasPeriod: node.operator?.type == TokenType.PERIOD,
- hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
+ hasPeriod: operatorType == TokenType.PERIOD ||
+ operatorType == TokenType.QUESTION_PERIOD,
+ hasPeriod2: operatorType == TokenType.PERIOD_PERIOD ||
+ operatorType == TokenType.QUESTION_PERIOD_PERIOD,
+ hasQuestion: operatorType == TokenType.QUESTION_PERIOD ||
+ operatorType == TokenType.QUESTION_PERIOD_PERIOD,
),
);
+
_writeOptionalNode(node.target);
_writeNode(node.methodName);
_storeInvocationExpression(node);
diff --git a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
index aa9f1fe..37dddf5 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -60,25 +60,52 @@
findElement.constructor('foo'), 'dynamic');
}
+ test_dynamicTyped() async {
+ await assertErrorsInCode('''
+dynamic i = 1;
+
+void bar() {
+ i<int>;
+}
+''', [
+ error(
+ CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 31, 1),
+ ]);
+
+ assertFunctionReference(findNode.functionReference('i<int>;'),
+ findElement.topGet('i'), 'dynamic');
+ }
+
+ test_dynamicTyped_targetOfMethodCall() async {
+ await assertErrorsInCode('''
+dynamic i = 1;
+
+void bar() {
+ i<int>.foo();
+}
+''', [
+ error(
+ CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 31, 1),
+ ]);
+
+ assertFunctionReference(findNode.functionReference('i<int>.foo();'),
+ findElement.topGet('i'), 'dynamic');
+ }
+
test_explicitReceiver_dynamicTyped() async {
await assertErrorsInCode('''
-dynamic f(dynamic x) => x;
+dynamic f() => 1;
-class C {
- T instanceMethod<T>(T t) => t;
-}
-
-main() {
- C c = new C();
- f(c).instanceMethod<int>;
+foo() {
+ f().instanceMethod<int>;
}
''', [
error(CompileTimeErrorCode.GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC,
- 102, 24),
+ 29, 23),
]);
assertFunctionReference(
- findNode.functionReference('f(c).instanceMethod<int>;'),
+ findNode.functionReference('f().instanceMethod<int>;'),
null,
'dynamic');
}
@@ -702,6 +729,22 @@
assertFunctionReference(reference, findElement.parameter('foo'), 'dynamic');
}
+ test_neverTyped() async {
+ await assertErrorsInCode('''
+external Never get i;
+
+void bar() {
+ i<int>;
+}
+''', [
+ error(
+ CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 38, 1),
+ ]);
+
+ assertFunctionReference(findNode.functionReference('i<int>;'),
+ findElement.topGet('i'), 'dynamic');
+ }
+
test_nonGenericFunction() async {
await assertErrorsInCode('''
class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/type_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_literal_test.dart
index 5391331..8172670 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_literal_test.dart
@@ -70,6 +70,18 @@
assertTypeLiteral(typeLiteral, findElement.class_('C'), 'C<dynamic>');
}
+ test_class_typeArgumentDoesNotMatchBound() async {
+ await assertErrorsInCode('''
+class C<T extends num> {}
+var t = C<String>;
+''', [
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 36, 6),
+ ]);
+
+ var typeLiteral = findNode.typeLiteral('C<String>;');
+ assertTypeLiteral(typeLiteral, findElement.class_('C'), 'C<String>');
+ }
+
test_classAlias() async {
await assertNoErrorsInCode('''
class C<T> {}
@@ -124,6 +136,19 @@
);
}
+ test_classAlias_typeArgumentDoesNotMatchBound() async {
+ await assertErrorsInCode('''
+class C<T> {}
+typedef CA<T extends num> = C<T>;
+var t = CA<String>;
+''', [
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 59, 6),
+ ]);
+
+ var typeLiteral = findNode.typeLiteral('CA<String>;');
+ assertTypeLiteral(typeLiteral, findElement.typeAlias('CA'), 'C<String>');
+ }
+
test_functionAlias() async {
await assertNoErrorsInCode('''
typedef Fn<T> = void Function(T);
@@ -135,6 +160,231 @@
typeLiteral, findElement.typeAlias('Fn'), 'void Function(int)');
}
+ test_functionAlias_importPrefix() async {
+ newFile('$testPackageLibPath/a.dart', content: '''
+typedef Fn<T> = void Function(T);
+''');
+ await assertNoErrorsInCode('''
+import 'a.dart' as a;
+var t = a.Fn<int>;
+''');
+
+ var typeLiteral = findNode.typeLiteral('Fn<int>;');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.importFind('package:test/a.dart').typeAlias('Fn'),
+ 'void Function(int)',
+ expectedPrefix: findElement.prefix('a'),
+ );
+ }
+
+ test_functionAlias_targetOfMethodCall() async {
+ await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ Fn<int>.foo();
+}
+
+extension E on Type {
+ void foo() {}
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_METHOD_ON_FUNCTION_TYPE, 58, 3),
+ ]);
+
+ var typeLiteral = findNode.typeLiteral('Fn<int>');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.typeAlias('Fn'),
+ 'void Function(int)',
+ );
+ }
+
+ test_functionAlias_targetOfMethodCall_importPrefix() async {
+ newFile('$testPackageLibPath/a.dart', content: '''
+typedef Fn<T> = void Function(T);
+''');
+ await assertErrorsInCode('''
+import 'a.dart' as a;
+
+void bar() {
+ a.Fn<int>.foo();
+}
+
+extension E on Type {
+ void foo() {}
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_METHOD_ON_FUNCTION_TYPE, 48, 3),
+ ]);
+
+ var typeLiteral = findNode.typeLiteral('Fn<int>');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.importFind('package:test/a.dart').typeAlias('Fn'),
+ 'void Function(int)',
+ expectedPrefix: findElement.prefix('a'),
+ );
+ }
+
+ test_functionAlias_targetOfMethodCall_parenthesized() async {
+ await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ (Fn<int>).foo();
+}
+
+extension E on Type {
+ void foo() {}
+}
+''');
+
+ var typeLiteral = findNode.typeLiteral('Fn<int>');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.typeAlias('Fn'),
+ 'void Function(int)',
+ );
+ }
+
+ test_functionAlias_targetOfPropertyAccess_getter() async {
+ await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ Fn<int>.foo;
+}
+
+extension E on Type {
+ int get foo => 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE, 58, 3),
+ ]);
+
+ var typeLiteral = findNode.typeLiteral('Fn<int>');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.typeAlias('Fn'),
+ 'void Function(int)',
+ );
+ }
+
+ test_functionAlias_targetOfPropertyAccess_getter_parenthesized() async {
+ await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ (Fn<int>).foo;
+}
+
+extension E on Type {
+ int get foo => 1;
+}
+''');
+
+ var typeLiteral = findNode.typeLiteral('Fn<int>');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.typeAlias('Fn'),
+ 'void Function(int)',
+ );
+ }
+
+ test_functionAlias_targetOfPropertyAccess_setter() async {
+ await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ Fn<int>.foo = 7;
+}
+
+extension E on Type {
+ set foo(int value) {}
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_SETTER_ON_FUNCTION_TYPE, 58, 3),
+ ]);
+
+ var typeLiteral = findNode.typeLiteral('Fn<int>');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.typeAlias('Fn'),
+ 'void Function(int)',
+ );
+ }
+
+ test_functionAlias_targetOfPropertyAccess_setter_parenthesized() async {
+ await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ (Fn<int>).foo = 7;
+}
+
+extension E on Type {
+ set foo(int value) {}
+}
+''');
+
+ var typeLiteral = findNode.typeLiteral('Fn<int>');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.typeAlias('Fn'),
+ 'void Function(int)',
+ );
+ }
+
+ test_functionAlias_tooFewTypeArgs() async {
+ await assertErrorsInCode('''
+typedef Fn<T, U> = void Function(T, U);
+var t = Fn<int>;
+''', [
+ error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 50, 5),
+ ]);
+
+ var typeLiteral = findNode.typeLiteral('Fn<int>;');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.typeAlias('Fn'),
+ 'void Function(dynamic, dynamic)',
+ );
+ }
+
+ test_functionAlias_tooManyTypeArgs() async {
+ await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+var t = Fn<int, String>;
+''', [
+ error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 44, 13),
+ ]);
+
+ var typeLiteral = findNode.typeLiteral('Fn<int, String>;');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.typeAlias('Fn'),
+ 'void Function(dynamic)',
+ );
+ }
+
+ test_functionAlias_typeArgumentDoesNotMatchBound() async {
+ await assertErrorsInCode('''
+typedef Fn<T extends num> = void Function(T);
+var t = Fn<String>;
+''', [
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 57, 6),
+ ]);
+
+ var typeLiteral = findNode.typeLiteral('Fn<String>;');
+ assertTypeLiteral(
+ typeLiteral,
+ findElement.typeAlias('Fn'),
+ 'void Function(String)',
+ );
+ }
+
test_mixin() async {
await assertNoErrorsInCode('''
mixin M<T> {}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
index cb85d4f..ae2410c 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
@@ -388,6 +388,36 @@
@reflectiveTest
class UndefinedGetterWithNullSafetyTest extends PubPackageResolutionTest
with UndefinedGetterTestCases {
+ test_functionAlias_typeInstantiated_getter() async {
+ await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ Fn<int>.foo;
+}
+
+extension E on Type {
+ int get foo => 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE, 58, 3),
+ ]);
+ }
+
+ test_functionAlias_typeInstantiated_getter_parenthesized() async {
+ await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ (Fn<int>).foo;
+}
+
+extension E on Type {
+ int get foo => 1;
+}
+''');
+ }
+
test_get_from_abstract_field_final_valid() async {
await assertNoErrorsInCode('''
abstract class A {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
index 34c7247..483d1dc 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
@@ -62,6 +62,50 @@
]);
}
+ test_functionAlias_notInstantiated() async {
+ await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ Fn.foo();
+}
+
+extension E on Type {
+ void foo() {}
+}
+''');
+ }
+
+ test_functionAlias_typeInstantiated() async {
+ await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ Fn<int>.foo();
+}
+
+extension E on Type {
+ void foo() {}
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_METHOD_ON_FUNCTION_TYPE, 58, 3),
+ ]);
+ }
+
+ test_functionAlias_typeInstantiated_parenthesized() async {
+ await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ (Fn<int>).foo();
+}
+
+extension E on Type {
+ void foo() {}
+}
+''');
+ }
+
test_functionExpression_callMethod_defined() async {
await assertNoErrorsInCode(r'''
main() {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
index d1674c6..d97a894 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
@@ -143,6 +143,36 @@
@reflectiveTest
class UndefinedSetterWithNullSafetyTest extends PubPackageResolutionTest
with UndefinedSetterTestCases {
+ test_functionAlias_typeInstantiated() async {
+ await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ Fn<int>.foo = 7;
+}
+
+extension E on Type {
+ set foo(int value) {}
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_SETTER_ON_FUNCTION_TYPE, 58, 3),
+ ]);
+ }
+
+ test_functionAlias_typeInstantiated_parenthesized() async {
+ await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+ (Fn<int>).foo = 7;
+}
+
+extension E on Type {
+ set foo(int value) {}
+}
+''');
+ }
+
test_new_cascade() async {
await assertErrorsInCode('''
class C {}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 41c6205..685f2f4 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -11008,6 +11008,91 @@
''');
}
+ test_const_topLevel_methodInvocation_questionPeriod() async {
+ var library = await checkLibrary(r'''
+const int? a = 0;
+const b = a?.toString();
+''');
+ checkElementText(library, r'''
+library
+ definingUnit
+ topLevelVariables
+ static const a @11
+ type: int?
+ constantInitializer
+ IntegerLiteral
+ literal: 0 @15
+ staticType: int
+ static const b @24
+ type: String?
+ constantInitializer
+ MethodInvocation
+ argumentList: ArgumentList
+ leftParenthesis: ( @39
+ rightParenthesis: ) @40
+ methodName: SimpleIdentifier
+ staticElement: dart:core::@class::int::@method::toString
+ staticType: String Function()
+ token: toString @31
+ operator: ?. @29
+ staticInvokeType: String Function()
+ staticType: String?
+ target: SimpleIdentifier
+ staticElement: self::@getter::a
+ staticType: int?
+ token: a @28
+ accessors
+ synthetic static get a @-1
+ returnType: int?
+ synthetic static get b @-1
+ returnType: String?
+''');
+ }
+
+ test_const_topLevel_methodInvocation_questionPeriodPeriod() async {
+ var library = await checkLibrary(r'''
+const int? a = 0;
+const b = a?..toString();
+''');
+ checkElementText(library, r'''
+library
+ definingUnit
+ topLevelVariables
+ static const a @11
+ type: int?
+ constantInitializer
+ IntegerLiteral
+ literal: 0 @15
+ staticType: int
+ static const b @24
+ type: int?
+ constantInitializer
+ CascadeExpression
+ cascadeSections
+ MethodInvocation
+ argumentList: ArgumentList
+ leftParenthesis: ( @40
+ rightParenthesis: ) @41
+ methodName: SimpleIdentifier
+ staticElement: dart:core::@class::int::@method::toString
+ staticType: String Function()
+ token: toString @32
+ operator: ?.. @29
+ staticInvokeType: String Function()
+ staticType: String
+ staticType: int?
+ target: SimpleIdentifier
+ staticElement: self::@getter::a
+ staticType: int?
+ token: a @28
+ accessors
+ synthetic static get a @-1
+ returnType: int?
+ synthetic static get b @-1
+ returnType: int?
+''');
+ }
+
test_const_topLevel_nullSafe_nullAware_propertyAccess() async {
var library = await checkLibrary(r'''
const String? a = '';
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 60b5987..3b82cae 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -13547,6 +13547,8 @@
### undefined_getter
+_The getter '{0}' isn't defined for the '{1}' function type._
+
_The getter '{0}' isn't defined for the type '{1}'._
#### Description
@@ -13668,6 +13670,8 @@
### undefined_method
+_The method '{0}' isn't defined for the '{1}' function type._
+
_The method '{0}' isn't defined for the type '{1}'._
#### Description
@@ -13830,6 +13834,8 @@
### undefined_setter
+_The setter '{0}' isn't defined for the '{1}' function type._
+
_The setter '{0}' isn't defined for the type '{1}'._
#### Description
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
index 4ca88ae..8740d46 100644
--- a/pkg/analyzer/tool/messages/generate.dart
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
/// This file contains code to generate scanner and parser message
/// based on the information in pkg/front_end/messages.yaml.
///
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index fdb24b7..496393a 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -1707,7 +1707,7 @@
DartType nullableType(DartType baseType) {
bool _isNullable(DartType t) =>
- // Note that we can assume NNBD is enabled here.
+ // Note that we can assume null safety is enabled here.
t.isNull ||
t is NullableType ||
t is LegacyType && _isNullable(t.baseType) ||
diff --git a/pkg/compiler/lib/src/js_backend/specialized_checks.dart b/pkg/compiler/lib/src/js_backend/specialized_checks.dart
index 431ebe7..9a887aa 100644
--- a/pkg/compiler/lib/src/js_backend/specialized_checks.dart
+++ b/pkg/compiler/lib/src/js_backend/specialized_checks.dart
@@ -72,8 +72,8 @@
}
DartTypes dartTypes = closedWorld.dartTypes;
- // Top types (here it could be Object in non-NNBD mode) should be constant
- // folded outside the specializer. This test protects logic below.
+ // Top types should be constant folded outside the specializer. This test
+ // protects logic below.
if (dartTypes.isTopType(dartType)) return null;
ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
if (!dartTypes.isSubtype(
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index 7fd39d4..37531a5 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -61,7 +61,8 @@
String targetName =
_options.compileForServer ? "dart2js_server" : "dart2js";
- // We defer selecting the platform until we've resolved the NNBD mode.
+ // We defer selecting the platform until we've resolved the null safety
+ // mode.
String getPlatformFilename() {
String platform = targetName;
if (!_options.useLegacySubtyping) {
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index 194c2b1..e81dda1 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -838,7 +838,7 @@
_behavior.typesReturned.add(type.withoutNullability);
// Breakdown nullable type into TypeWithoutNullability|Null.
- // Pre-nnbd Declared types are nullable, so we also add null in that case.
+ // Unsound declared types are nullable, so we also add null in that case.
// TODO(41960): Remove check for legacy subtyping. This was added as a
// temporary workaround to unblock the null-safe unfork. At this time some
// native APIs are typed unsoundly because they don't consider browser
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 9000dab..3c5ee61 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -69,10 +69,10 @@
FeatureOption newHolders = FeatureOption('new-holders');
/// [FeatureOption]s which default to enabled.
- late final List<FeatureOption> shipping = [legacyJavaScript];
+ late final List<FeatureOption> shipping = [legacyJavaScript, newHolders];
/// [FeatureOption]s which default to disabled.
- late final List<FeatureOption> canary = [newHolders];
+ late final List<FeatureOption> canary = [];
/// Forces canary feature on. This must run after [Option].parse.
void forceCanary() {
@@ -708,7 +708,7 @@
if (benchmarkingExperiment) {
// Set flags implied by '--benchmarking-x'.
- // TODO(sra): Use this for some NNBD variant.
+ // TODO(sra): Use this for some null safety variant.
useContentSecurityPolicy = true;
features.forceCanary();
}
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index ef0a3fa..886f1f0 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -3517,10 +3517,10 @@
/// Check for receiver or argument type when lowering operation to a primitive,
/// e.g. lowering `+` to [HAdd].
///
-/// After NNBD, `a + b` will require `a` and `b` are non-nullable and these
-/// checks will become explicit in the source (e.g. `a! + b!`). At that time,
-/// this check should be removed. If needed, the `!` check can be optimized
-/// give the same signals to the JavaScript VM.
+/// With sound null safety, `a + b` will require `a` and `b` to be non-nullable
+/// and these checks will become explicit in the source (e.g. `a! + b!`). At
+/// that time, this check should be removed. If needed, the `!` check can be
+/// optimized to give the same signals to the JavaScript VM.
class HPrimitiveCheck extends HCheck {
// Values for [kind].
static const int ARGUMENT_TYPE_CHECK = 1;
@@ -3590,8 +3590,8 @@
}
/// A check that the input to a condition (if, ?:, while, etc) is non-null. The
-/// front-end generates 'as bool' checks, but until the transition to NNBD is
-/// complete, this allows `null` to be passed to the condition.
+/// front-end generates 'as bool' checks, but until the transition to null
+/// safety is complete, this allows `null` to be passed to the condition.
///
// TODO(sra): Once NNDB is far enough along that the front-end can generate `as
// bool!` checks and the backend checks them correctly, this instruction will
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index bf83ffc..8877f33 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -1926,8 +1926,8 @@
@override
HInstruction visitAsCheck(HAsCheck node) {
// TODO(fishythefish): Correctly constant fold `null as T` (also in
- // [visitAsCheckSimple]) when running with strong NNBD. We might get this
- // for free if nullability is precisely propagated to the typemasks.
+ // [visitAsCheckSimple]) when running with sound null safety. We might get
+ // this for free if nullability is precisely propagated to the typemasks.
HInstruction typeInput = node.typeInput;
if (typeInput is HLoadType) {
diff --git a/pkg/compiler/test/closure/data/test_type_class.dart b/pkg/compiler/test/closure/data/test_type_class.dart
index 2d090d6..eff36b1 100644
--- a/pkg/compiler/test/closure/data/test_type_class.dart
+++ b/pkg/compiler/test/closure/data/test_type_class.dart
@@ -33,7 +33,7 @@
}
////////////////////////////////////////////////////////////////////////////////
-/// Implicit as-cast is only required in spec:nnbd-off mode.
+/// Implicit as-cast is only required in spec mode.
////////////////////////////////////////////////////////////////////////////////
/*member: Class3.:hasThis*/
diff --git a/pkg/compiler/test/closure/data/test_type_method.dart b/pkg/compiler/test/closure/data/test_type_method.dart
index 495ac1b..ee02292 100644
--- a/pkg/compiler/test/closure/data/test_type_method.dart
+++ b/pkg/compiler/test/closure/data/test_type_method.dart
@@ -27,7 +27,7 @@
}
////////////////////////////////////////////////////////////////////////////////
-/// Implicit as-cast is only required in spec:nnbd-off mode.
+/// Implicit as-cast is only required in spec mode.
////////////////////////////////////////////////////////////////////////////////
/*member: method3:*/
diff --git a/pkg/compiler/test/closure/data/type_annotations_class.dart b/pkg/compiler/test/closure/data/type_annotations_class.dart
index 6c0d99e..f7557f7 100644
--- a/pkg/compiler/test/closure/data/type_annotations_class.dart
+++ b/pkg/compiler/test/closure/data/type_annotations_class.dart
@@ -43,7 +43,7 @@
}
////////////////////////////////////////////////////////////////////////////////
-/// A local function parameter type is only captured in spec:nnbd-off mode.
+/// A local function parameter type is only captured in spec mode.
////////////////////////////////////////////////////////////////////////////////
/*member: Class2.:hasThis*/
@@ -58,7 +58,7 @@
}
////////////////////////////////////////////////////////////////////////////////
-/// A local function return type is only captured in spec:nnbd-off mode.
+/// A local function return type is only captured in spec mode.
////////////////////////////////////////////////////////////////////////////////
/*member: Class3.:hasThis*/
diff --git a/pkg/compiler/test/closure/data/type_annotations_method.dart b/pkg/compiler/test/closure/data/type_annotations_method.dart
index 4da1fae..1468024 100644
--- a/pkg/compiler/test/closure/data/type_annotations_method.dart
+++ b/pkg/compiler/test/closure/data/type_annotations_method.dart
@@ -19,7 +19,7 @@
}
////////////////////////////////////////////////////////////////////////////////
-/// A local function parameter type is captured in spec:nnbd-off mode.
+/// A local function parameter type is captured in spec mode.
////////////////////////////////////////////////////////////////////////////////
method2<T>() {
@@ -29,7 +29,7 @@
}
////////////////////////////////////////////////////////////////////////////////
-/// A local function return type is captured in spec:nnbd-off mode.
+/// A local function return type is captured in spec mode.
////////////////////////////////////////////////////////////////////////////////
method3<T>(dynamic o) {
diff --git a/pkg/compiler/test/codegen/data/array_add.dart b/pkg/compiler/test/codegen/data/array_add.dart
index 635192c..81ecb40 100644
--- a/pkg/compiler/test/codegen/data/array_add.dart
+++ b/pkg/compiler/test/codegen/data/array_add.dart
@@ -6,9 +6,9 @@
//
// TODO(sra): Lower when type of input does not need a generic covariant check.
@pragma('dart2js:noInline')
-/*spec.member: test1:function() {
- var t1 = H._setArrayType([], type$.JSArray_int);
- C.JSArray_methods.add$1(t1, 1);
+/*spec|canary.member: test1:function() {
+ var t1 = A._setArrayType([], type$.JSArray_int);
+ B.JSArray_methods.add$1(t1, 1);
return t1;
}*/
/*prod.member: test1:function() {
@@ -16,19 +16,11 @@
t1.push(1);
return t1;
}*/
-/*canary.member: test1:function() {
- var t1 = A._setArrayType([], type$.JSArray_int);
- B.JSArray_methods.add$1(t1, 1);
- return t1;
-}*/
test1() {
return <int>[]..add(1);
}
-/*spec|prod.member: main:function() {
- F.test1();
-}*/
-/*canary.member: main:function() {
+/*member: main:function() {
A.test1();
}*/
main() {
diff --git a/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart b/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart
index 4b47674..993e670 100644
--- a/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart
+++ b/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart
@@ -14,14 +14,11 @@
}
@pragma('dart2js:noInline')
-/*spec.member: foo2:function() {
- return C.JSString_methods.codeUnitAt$1("Hello", H._asInt(1.5));
+/*spec|canary.member: foo2:function() {
+ return B.JSString_methods.codeUnitAt$1("Hello", A._asInt(1.5));
}*/
/*prod.member: foo2:function() {
- return C.JSString_methods.codeUnitAt$1("Hello", 1.5);
-}*/
-/*canary.member: foo2:function() {
- return B.JSString_methods.codeUnitAt$1("Hello", A._asInt(1.5));
+ return B.JSString_methods.codeUnitAt$1("Hello", 1.5);
}*/
foo2() {
var a = 'Hello';
@@ -31,10 +28,7 @@
}
@pragma('dart2js:noInline')
-/*spec|prod.member: foo3:function() {
- return C.JSString_methods._codeUnitAt$1("Hello", 55);
-}*/
-/*canary.member: foo3:function() {
+/*member: foo3:function() {
return B.JSString_methods._codeUnitAt$1("Hello", 55);
}*/
foo3() {
diff --git a/pkg/compiler/test/codegen/data/shift_right_unsigned.dart b/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
index b473933..521f9d3 100644
--- a/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
+++ b/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
@@ -24,24 +24,18 @@
Object? sink;
@pragma('dart2js:noInline')
-/*spec.member: cannotRecognize:function(thing) {
- return H._asInt(J.$shru$n(thing, 1));
+/*spec|canary.member: cannotRecognize:function(thing) {
+ return A._asInt(J.$shru$n(thing, 1));
}*/
/*prod.member: cannotRecognize:function(thing) {
return J.$shru$n(thing, 1);
}*/
-/*canary.member: cannotRecognize:function(thing) {
- return A._asInt(J.$shru$n(thing, 1));
-}*/
int cannotRecognize(dynamic thing) {
return thing >>> 1;
}
@pragma('dart2js:noInline')
-/*spec|prod.member: cannotConstantFold:function() {
- return C.JSInt_methods.$shru(1, -1);
-}*/
-/*canary.member: cannotConstantFold:function() {
+/*member: cannotConstantFold:function() {
return B.JSInt_methods.$shru(1, -1);
}*/
int cannotConstantFold() {
@@ -68,10 +62,7 @@
}
@pragma('dart2js:noInline')
-/*spec|prod.member: unspecialized:function(a) {
- return C.JSInt_methods.$shru(1, a);
-}*/
-/*canary.member: unspecialized:function(a) {
+/*member: unspecialized:function(a) {
return B.JSInt_methods.$shru(1, a);
}*/
int unspecialized(int a) {
@@ -79,10 +70,7 @@
}
@pragma('dart2js:noInline')
-/*spec|prod.member: otherPositive2:function(param) {
- return C.JSInt_methods._shruOtherPositive$1(1, param ? 1 : 2);
-}*/
-/*canary.member: otherPositive2:function(param) {
+/*member: otherPositive2:function(param) {
return B.JSInt_methods._shruOtherPositive$1(1, param ? 1 : 2);
}*/
int otherPositive2(bool param) {
@@ -110,10 +98,7 @@
}
@pragma('dart2js:noInline')
-/*spec|prod.member: otherPositive6:function(a, b) {
- return C.JSInt_methods._shruOtherPositive$1(a, b);
-}*/
-/*canary.member: otherPositive6:function(a, b) {
+/*member: otherPositive6:function(a, b) {
return B.JSInt_methods._shruOtherPositive$1(a, b);
}*/
int otherPositive6(int a, int b) {
diff --git a/pkg/compiler/test/codegen/data/tdiv1.dart b/pkg/compiler/test/codegen/data/tdiv1.dart
index 9c83d58..fe6e9f6 100644
--- a/pkg/compiler/test/codegen/data/tdiv1.dart
+++ b/pkg/compiler/test/codegen/data/tdiv1.dart
@@ -45,10 +45,7 @@
}
@pragma('dart2js:noInline')
-/*spec|prod.member: foo3:function(param) {
- return C.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
-}*/
-/*canary.member: foo3:function(param) {
+/*member: foo3:function(param) {
return B.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
}*/
int foo3(bool param) {
@@ -59,10 +56,7 @@
}
@pragma('dart2js:noInline')
-/*spec|prod.member: foo4:function(param1, param2) {
- return C.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
-}*/
-/*canary.member: foo4:function(param1, param2) {
+/*member: foo4:function(param1, param2) {
return B.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
}*/
int foo4(bool param1, int param2) {
@@ -74,11 +68,7 @@
}
@pragma('dart2js:noInline')
-/*spec|prod.member: foo5:function(param1, param2) {
- var a = param1 ? 4294967295 : 0;
- return C.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
-}*/
-/*canary.member: foo5:function(param1, param2) {
+/*member: foo5:function(param1, param2) {
var a = param1 ? 4294967295 : 0;
return B.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
}*/
@@ -93,11 +83,7 @@
}
@pragma('dart2js:noInline')
-/*spec|prod.member: foo_regress_37502:function(param1, param2) {
- var a = param1 ? 1.2 : 12.3;
- return C.JSInt_methods.gcd$1(C.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
-}*/
-/*canary.member: foo_regress_37502:function(param1, param2) {
+/*member: foo_regress_37502:function(param1, param2) {
var a = param1 ? 1.2 : 12.3;
return B.JSInt_methods.gcd$1(B.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
}*/
diff --git a/pkg/compiler/test/codegen/data_2/tdiv1.dart b/pkg/compiler/test/codegen/data_2/tdiv1.dart
index 3c3e6b7..27d6c65 100644
--- a/pkg/compiler/test/codegen/data_2/tdiv1.dart
+++ b/pkg/compiler/test/codegen/data_2/tdiv1.dart
@@ -23,15 +23,12 @@
Object sink;
@pragma('dart2js:noInline')
-/*spec.member: foo1:function(param) {
- return (H.boolConversionCheck(param) ? 4294967295 : 1) / 2 | 0;
+/*spec|canary.member: foo1:function(param) {
+ return (A.boolConversionCheck(param) ? 4294967295 : 1) / 2 | 0;
}*/
/*prod.member: foo1:function(param) {
return (param ? 4294967295 : 1) / 2 | 0;
}*/
-/*canary.member: foo1:function(param) {
- return (A.boolConversionCheck(param) ? 4294967295 : 1) / 2 | 0;
-}*/
int foo1(bool param) {
var a = param ? 0xFFFFFFFF : 1;
return a ~/ 2;
@@ -40,15 +37,12 @@
}
@pragma('dart2js:noInline')
-/*spec.member: foo2:function(param) {
- return (H.boolConversionCheck(param) ? 4294967295 : 1) / 3 | 0;
+/*spec|canary.member: foo2:function(param) {
+ return (A.boolConversionCheck(param) ? 4294967295 : 1) / 3 | 0;
}*/
/*prod.member: foo2:function(param) {
return (param ? 4294967295 : 1) / 3 | 0;
}*/
-/*canary.member: foo2:function(param) {
- return (A.boolConversionCheck(param) ? 4294967295 : 1) / 3 | 0;
-}*/
int foo2(bool param) {
var a = param ? 0xFFFFFFFF : 1;
return a ~/ 3;
@@ -57,14 +51,11 @@
}
@pragma('dart2js:noInline')
-/*spec.member: foo3:function(param) {
- return C.JSInt_methods._tdivFast$1(H.boolConversionCheck(param) ? 4294967295 : -1, 2);
+/*spec|canary.member: foo3:function(param) {
+ return B.JSInt_methods._tdivFast$1(A.boolConversionCheck(param) ? 4294967295 : -1, 2);
}*/
/*prod.member: foo3:function(param) {
- return C.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
-}*/
-/*canary.member: foo3:function(param) {
- return B.JSInt_methods._tdivFast$1(A.boolConversionCheck(param) ? 4294967295 : -1, 2);
+ return B.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
}*/
int foo3(bool param) {
var a = param ? 0xFFFFFFFF : -1;
@@ -74,14 +65,11 @@
}
@pragma('dart2js:noInline')
-/*spec.member: foo4:function(param1, param2) {
- return C.JSInt_methods.$tdiv(H.boolConversionCheck(param1) ? 4294967295 : 0, param2);
+/*spec|canary.member: foo4:function(param1, param2) {
+ return B.JSInt_methods.$tdiv(A.boolConversionCheck(param1) ? 4294967295 : 0, param2);
}*/
/*prod.member: foo4:function(param1, param2) {
- return C.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
-}*/
-/*canary.member: foo4:function(param1, param2) {
- return B.JSInt_methods.$tdiv(A.boolConversionCheck(param1) ? 4294967295 : 0, param2);
+ return B.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
}*/
int foo4(bool param1, int param2) {
var a = param1 ? 0xFFFFFFFF : 0;
@@ -92,17 +80,13 @@
}
@pragma('dart2js:noInline')
-/*spec.member: foo5:function(param1, param2) {
- var a = H.boolConversionCheck(param1) ? 4294967295 : 0;
- return C.JSInt_methods.$tdiv(a, H.boolConversionCheck(param2) ? 3 : 4);
+/*spec|canary.member: foo5:function(param1, param2) {
+ var a = A.boolConversionCheck(param1) ? 4294967295 : 0;
+ return B.JSInt_methods.$tdiv(a, A.boolConversionCheck(param2) ? 3 : 4);
}*/
/*prod.member: foo5:function(param1, param2) {
var a = param1 ? 4294967295 : 0;
- return C.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
-}*/
-/*canary.member: foo5:function(param1, param2) {
- var a = A.boolConversionCheck(param1) ? 4294967295 : 0;
- return B.JSInt_methods.$tdiv(a, A.boolConversionCheck(param2) ? 3 : 4);
+ return B.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
}*/
int foo5(bool param1, bool param2) {
var a = param1 ? 0xFFFFFFFF : 0;
@@ -115,17 +99,13 @@
}
@pragma('dart2js:noInline')
-/*spec.member: foo_regress_37502:function(param1, param2) {
- var a = H.boolConversionCheck(param1) ? 1.2 : 12.3;
- return C.JSInt_methods.gcd$1(C.JSNumber_methods.$tdiv(a, H.boolConversionCheck(param2) ? 3.14 : 2.81), 2);
+/*spec|canary.member: foo_regress_37502:function(param1, param2) {
+ var a = A.boolConversionCheck(param1) ? 1.2 : 12.3;
+ return B.JSInt_methods.gcd$1(B.JSNumber_methods.$tdiv(a, A.boolConversionCheck(param2) ? 3.14 : 2.81), 2);
}*/
/*prod.member: foo_regress_37502:function(param1, param2) {
var a = param1 ? 1.2 : 12.3;
- return C.JSInt_methods.gcd$1(C.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
-}*/
-/*canary.member: foo_regress_37502:function(param1, param2) {
- var a = A.boolConversionCheck(param1) ? 1.2 : 12.3;
- return B.JSInt_methods.gcd$1(B.JSNumber_methods.$tdiv(a, A.boolConversionCheck(param2) ? 3.14 : 2.81), 2);
+ return B.JSInt_methods.gcd$1(B.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
}*/
foo_regress_37502(param1, param2) {
var a = param1 ? 1.2 : 12.3;
diff --git a/pkg/compiler/test/codegen/new_rti_is_test.dart b/pkg/compiler/test/codegen/new_rti_is_test.dart
index 1ce65e9..b6d2b53 100644
--- a/pkg/compiler/test/codegen/new_rti_is_test.dart
+++ b/pkg/compiler/test/codegen/new_rti_is_test.dart
@@ -11,7 +11,7 @@
import '../helpers/compiler_helper.dart';
// 'N' tests all have a nullable input so should not reduce is-test.
-// TODO(NNBD): Add tests with non-nullable input types.
+// TODO(sra): Add tests with non-nullable input types.
const TEST1N = r"""
foo(int a) {
diff --git a/pkg/compiler/test/inference/data/list_tracer_typed_data_length.dart b/pkg/compiler/test/inference/data/list_tracer_typed_data_length.dart
index a08ef1a..f47e3ca 100644
--- a/pkg/compiler/test/inference/data/list_tracer_typed_data_length.dart
+++ b/pkg/compiler/test/inference/data/list_tracer_typed_data_length.dart
@@ -6,8 +6,8 @@
import 'dart:typed_data';
-// TODO(johnniwinther): Fix inference for spec:nnbd-off mode. List elements should not
-// be [empty].
+// TODO(johnniwinther): Fix inference for spec mode. List elements should not be
+// [empty].
/*member: myList:Container([null|exact=NativeFloat32List], element: [subclass=JSNumber], length: 42)*/
var myList = new Float32List(42);
diff --git a/pkg/compiler/test/kernel/goldens_test.dart b/pkg/compiler/test/kernel/goldens_test.dart
index a945729..dcef219 100644
--- a/pkg/compiler/test/kernel/goldens_test.dart
+++ b/pkg/compiler/test/kernel/goldens_test.dart
@@ -14,9 +14,9 @@
final String testRootDir = Platform.script.resolve('.').toFilePath();
runTestCase(
- Uri source, List<String> experimentalFlags, bool enableNullSafety) async {
+ Uri source, List<String> experimentalFlags, bool soundNullSafety) async {
final target =
- TestingDart2jsTarget(TargetFlags(enableNullSafety: enableNullSafety));
+ TestingDart2jsTarget(TargetFlags(enableNullSafety: soundNullSafety));
Component component = await compileTestCaseToKernelProgram(source,
target: target, experimentalFlags: experimentalFlags);
@@ -33,13 +33,11 @@
in testCasesDir.listSync(recursive: true, followLinks: false)) {
final path = entry.path;
if (path.endsWith('.dart')) {
- final bool enableNullSafety = path.endsWith('_nnbd_strong.dart');
- final bool enableNNBD = enableNullSafety || path.endsWith('_nnbd.dart');
- final List<String> experimentalFlags = [
- if (enableNNBD) 'non-nullable',
- ];
- test(path,
- () => runTestCase(entry.uri, experimentalFlags, enableNullSafety));
+ final bool unsoundNullSafety = path.endsWith('_unsound.dart');
+ test(
+ path,
+ () => runTestCase(
+ entry.uri, const ['non-nullable'], !unsoundNullSafety));
}
}
}, timeout: Timeout.none);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 422e2be..02c28b2 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -3450,17 +3450,6 @@
intptr_t kernel_buffer_size);
/**
- * Returns a flattened list of pairs. The first element in each pair is the
- * importing library and and the second element is the imported library for each
- * import in the isolate of a library whose URI's scheme is [scheme].
- *
- * Requires there to be a current isolate.
- *
- * \return A handle to a list of flattened pairs of importer-importee.
- */
-DART_EXPORT Dart_Handle Dart_GetImportsOfScheme(Dart_Handle scheme);
-
-/**
* Indicates that all outstanding load requests have been satisfied.
* This finalizes all the new classes loaded and optionally completes
* deferred library futures.
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 5d21abf..94c0f77 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -5802,41 +5802,6 @@
#endif // defined(DART_PRECOMPILED_RUNTIME)
}
-DART_EXPORT Dart_Handle Dart_GetImportsOfScheme(Dart_Handle scheme) {
- DARTSCOPE(Thread::Current());
- auto IG = T->isolate_group();
- const String& scheme_vm = Api::UnwrapStringHandle(Z, scheme);
- if (scheme_vm.IsNull()) {
- RETURN_TYPE_ERROR(Z, scheme, String);
- }
-
- const GrowableObjectArray& libraries =
- GrowableObjectArray::Handle(Z, IG->object_store()->libraries());
- const GrowableObjectArray& result =
- GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
- Library& importer = Library::Handle(Z);
- Array& imports = Array::Handle(Z);
- Namespace& ns = Namespace::Handle(Z);
- Library& importee = Library::Handle(Z);
- String& importee_uri = String::Handle(Z);
- for (intptr_t i = 0; i < libraries.Length(); i++) {
- importer ^= libraries.At(i);
- imports = importer.imports();
- for (intptr_t j = 0; j < imports.Length(); j++) {
- ns ^= imports.At(j);
- if (ns.IsNull()) continue;
- importee = ns.target();
- importee_uri = importee.url();
- if (importee_uri.StartsWith(scheme_vm)) {
- result.Add(importer);
- result.Add(importee);
- }
- }
- }
-
- return Api::NewHandle(T, Array::MakeFixedLength(result));
-}
-
// Finalizes classes and invokes Dart core library function that completes
// futures of loadLibrary calls (deferred library loading).
DART_EXPORT Dart_Handle Dart_FinalizeLoading(bool complete_futures) {
diff --git a/tools/VERSION b/tools/VERSION
index 89f18db..5f3e116 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 105
+PRERELEASE 106
PRERELEASE_PATCH 0
\ No newline at end of file