Version 2.15.0-234.0.dev
Merge commit '311760f49cd4b4c435506ca117a861710a19dc2e' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1ed45f0..f165f47 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -412,6 +412,12 @@
- Add `Enum.compareByName` helper function for comparing enum values by name.
- Add extension methods on `Iterable<T extends Enum>`, intended for
`SomeEnumType.values` lists, to look up values by name.
+- Deprecate `IntegerDivisionByZeroException`.
+ Makes the class also implement `Error`. Code throwing the exception will be
+ migrated to throwing an `Error` instead until the class is unused and
+ ready to be removed.
+ Code catching the class should move to catching `Error` instead
+ (or, for integers, check first for whether it's dividing by zero).
#### `dart:io`
@@ -421,6 +427,25 @@
- Add `RawSocket.sendMessage`, `RawSocket.receiveMessage` that allow passing of
file handle references via Unix domain sockets.
+#### `dart:js_util`
+
+- The `js_util` methods `getProperty`, `setProperty`, `callMethod`,
+ `callConstructor`, and `newObject` now support a generic type argument
+ to specify the return type.
+
+#### `dart:web_sql`
+
+- **Breaking Change** [#46316](https://github.com/dart-lang/sdk/issues/46316):
+ The WebSQL standard was abandoned more than 10
+ years ago and is not supported by many browsers. This release completely
+ deletes the `dart:web_sql` library.
+
+#### `dart:html`
+
+- **Breaking Change** [#46316](https://github.com/dart-lang/sdk/issues/46316):
+ Related to the removal of `dart:web_sql` (see above), the
+ `window.openDatabase` has been removed as well.
+
### Tools
#### Dart command line
@@ -651,6 +676,7 @@
- The `Symbol` constructor now accepts any string as argument. Symbols are equal
if they were created from the same string.
+
#### `dart:ffi`
- Adds the `DynamicLibrary.providesSymbol` function to check whether a symbol is
diff --git a/DEPS b/DEPS
index aea5e2a..3f5007c 100644
--- a/DEPS
+++ b/DEPS
@@ -139,7 +139,7 @@
"pool_rev": "7abe634002a1ba8a0928eded086062f1307ccfae",
"process_rev": "56ece43b53b64c63ae51ec184b76bd5360c28d0b",
"protobuf_rev": "c1eb6cb51af39ccbaa1a8e19349546586a5c8e31",
- "pub_rev": "35681b0126a1fb48bf2062dd09f74296715402c2",
+ "pub_rev": "400f21e9883ce6555b66d3ef82f0b732ba9b9fc8",
"pub_semver_rev": "a43ad72fb6b7869607581b5fedcb186d1e74276a",
"root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
"rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index 07b7e12..249b33d 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -1302,9 +1302,9 @@
test('initialize() does not promote when final', () {
var h = Harness();
- var x = Var('x', 'int?');
+ var x = Var('x', 'int?', isFinal: true);
h.run([
- declareInitialized(x, expr('int'), isFinal: true),
+ declareInitialized(x, expr('int')),
checkNotPromoted(x),
]);
});
@@ -1326,9 +1326,9 @@
var h = Harness()
..addSubtype('T&int', 'T', true)
..addFactor('T', 'T&int', 'T');
- var x = Var('x', 'T', isImplicitlyTyped: true);
+ var x = Var('x', 'T', isFinal: true, isImplicitlyTyped: true);
h.run([
- declareInitialized(x, expr('T&int'), isFinal: true),
+ declareInitialized(x, expr('T&int')),
checkPromoted(x, 'T&int'),
]);
});
@@ -1348,9 +1348,9 @@
test('when final', () {
var h = Harness();
- var x = Var('x', 'T');
+ var x = Var('x', 'T', isFinal: true);
h.run([
- declareInitialized(x, expr('T&int'), isFinal: true),
+ declareInitialized(x, expr('T&int')),
checkNotPromoted(x),
]);
});
@@ -1370,9 +1370,9 @@
test('when final', () {
var h = Harness();
- var x = Var('x', 'dynamic', isImplicitlyTyped: true);
+ var x = Var('x', 'dynamic', isFinal: true, isImplicitlyTyped: true);
h.run([
- declareInitialized(x, expr('Null'), isFinal: true),
+ declareInitialized(x, expr('Null')),
checkNotPromoted(x),
]);
});
@@ -1398,10 +1398,10 @@
test('initialize() does not store expressionInfo when late', () {
var h = Harness();
- var x = Var('x', 'Object');
+ var x = Var('x', 'Object', isLate: true);
var y = Var('y', 'int?');
h.run([
- declareInitialized(x, y.expr.eq(nullLiteral), isLate: true),
+ declareInitialized(x, y.expr.eq(nullLiteral)),
getSsaNodes((nodes) {
expect(nodes[x]!.expressionInfo, isNull);
}),
diff --git a/pkg/_fe_analyzer_shared/test/mini_ast.dart b/pkg/_fe_analyzer_shared/test/mini_ast.dart
index 57ce172..85ae066 100644
--- a/pkg/_fe_analyzer_shared/test/mini_ast.dart
+++ b/pkg/_fe_analyzer_shared/test/mini_ast.dart
@@ -55,16 +55,11 @@
Statement continue_() => new _Continue();
-Statement declare(Var variable,
- {required bool initialized,
- bool isFinal = false,
- bool isLate = false}) =>
- new _Declare(variable, initialized ? expr(variable.type.type) : null,
- isFinal, isLate);
+Statement declare(Var variable, {required bool initialized}) =>
+ new _Declare(variable, initialized ? expr(variable.type.type) : null);
-Statement declareInitialized(Var variable, Expression initializer,
- {bool isFinal = false, bool isLate = false}) =>
- new _Declare(variable, initializer, isFinal, isLate);
+Statement declareInitialized(Var variable, Expression initializer) =>
+ new _Declare(variable, initializer);
Statement do_(List<Statement> body, Expression condition) =>
_Do(block(body), condition);
@@ -664,9 +659,14 @@
class Var {
final String name;
final Type type;
+ final bool isFinal;
final bool isImplicitlyTyped;
+ final bool isLate;
- Var(this.name, String typeStr, {this.isImplicitlyTyped = false})
+ Var(this.name, String typeStr,
+ {this.isFinal = false,
+ this.isImplicitlyTyped = false,
+ this.isLate = false})
: type = Type(typeStr);
/// Creates an L-value representing a reference to this variable.
@@ -882,6 +882,7 @@
class _CheckUnassigned extends Statement {
final Var variable;
final bool expectedUnassignedState;
+ final StackTrace _creationTrace = StackTrace.current;
_CheckUnassigned(this.variable, this.expectedUnassignedState) : super._();
@@ -896,7 +897,8 @@
@override
void _visit(Harness h) {
- expect(h._flow.isUnassigned(variable), expectedUnassignedState);
+ expect(h._flow.isUnassigned(variable), expectedUnassignedState,
+ reason: '$_creationTrace');
h._irBuilder.atom('null');
}
}
@@ -948,16 +950,13 @@
class _Declare extends Statement {
final Var variable;
final Expression? initializer;
- final bool isFinal;
- final bool isLate;
- _Declare(this.variable, this.initializer, this.isFinal, this.isLate)
- : super._();
+ _Declare(this.variable, this.initializer) : super._();
@override
String toString() {
- var latePart = isLate ? 'late ' : '';
- var finalPart = isFinal ? 'final ' : '';
+ var latePart = variable.isLate ? 'late ' : '';
+ var finalPart = variable.isFinal ? 'final ' : '';
var initializerPart = initializer != null ? ' = $initializer' : '';
return '$latePart$finalPart$variable${initializerPart};';
}
@@ -972,9 +971,11 @@
h._irBuilder.atom(variable.name);
h._typeAnalyzer.analyzeVariableDeclaration(
this, variable.type, variable, initializer,
- isFinal: isFinal, isLate: isLate);
+ isFinal: variable.isFinal, isLate: variable.isLate);
h._irBuilder.apply(
- ['declare', if (isLate) 'late', if (isFinal) 'final'].join('_'), 2);
+ ['declare', if (variable.isLate) 'late', if (variable.isFinal) 'final']
+ .join('_'),
+ 2);
}
}
diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
index add033d..2e4f847 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
@@ -138,6 +138,8 @@
Arguments([
VariableGet(function.positionalParameters.first),
StringLiteral(_getExtensionMemberName(node))
+ ], types: [
+ DynamicType()
]))
..fileOffset = node.fileOffset;
return ReturnStatement(
@@ -157,6 +159,8 @@
VariableGet(function.positionalParameters.first),
StringLiteral(_getExtensionMemberName(node)),
VariableGet(function.positionalParameters.last)
+ ], types: [
+ DynamicType()
]))
..fileOffset = node.fileOffset;
return ReturnStatement(AsExpression(
@@ -178,6 +182,8 @@
.sublist(1)
.map((argument) => VariableGet(argument))
.toList())
+ ], types: [
+ DynamicType()
]))
..fileOffset = node.fileOffset;
return ReturnStatement(AsExpression(
@@ -224,7 +230,6 @@
/// Removing the checks allows further inlining by the compilers.
StaticInvocation _lowerSetProperty(StaticInvocation node) {
Arguments arguments = node.arguments;
- assert(arguments.types.isEmpty);
assert(arguments.positional.length == 3);
assert(arguments.named.isEmpty);
@@ -244,7 +249,6 @@
/// Removing the checks allows further inlining by the compilers.
StaticInvocation _lowerCallMethod(StaticInvocation node) {
Arguments arguments = node.arguments;
- assert(arguments.types.isEmpty);
assert(arguments.positional.length == 3);
assert(arguments.named.isEmpty);
@@ -260,7 +264,6 @@
/// Removing the checks allows further inlining by the compilers.
StaticInvocation _lowerCallConstructor(StaticInvocation node) {
Arguments arguments = node.arguments;
- assert(arguments.types.isEmpty);
assert(arguments.positional.length == 2);
assert(arguments.named.isEmpty);
@@ -283,8 +286,13 @@
// Lower arguments in a List.empty factory call.
if (argumentsList is StaticInvocation &&
argumentsList.target == _listEmptyFactory) {
- return _createCallUncheckedNode(callUncheckedTargets, [],
- originalArguments, node.fileOffset, node.arguments.fileOffset);
+ return _createCallUncheckedNode(
+ callUncheckedTargets,
+ node.arguments.types,
+ [],
+ originalArguments,
+ node.fileOffset,
+ node.arguments.fileOffset);
}
// Lower arguments in other kinds of Lists.
@@ -323,6 +331,7 @@
return _createCallUncheckedNode(
callUncheckedTargets,
+ node.arguments.types,
callUncheckedArguments,
originalArguments,
node.fileOffset,
@@ -333,6 +342,7 @@
/// with the given 0-4 arguments.
StaticInvocation _createCallUncheckedNode(
List<Procedure> callUncheckedTargets,
+ List<DartType> callUncheckedTypes,
List<Expression> callUncheckedArguments,
List<Expression> originalArguments,
int nodeFileOffset,
@@ -342,7 +352,7 @@
callUncheckedTargets[callUncheckedArguments.length],
Arguments(
[...originalArguments, ...callUncheckedArguments],
- types: [],
+ types: callUncheckedTypes,
)..fileOffset = argumentsFileOffset)
..fileOffset = nodeFileOffset;
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
index c120d04..41fa61c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
@@ -2,10 +2,13 @@
// 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:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/utilities/extensions/completion_request.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
/// A contributor that produces suggestions based on the named constructors
/// defined on a given class. More concretely, this class produces suggestions
@@ -21,28 +24,40 @@
Future<void> computeSuggestions() async {
var node = request.target.containingNode;
if (node is ConstructorName) {
- var libraryElement = request.libraryElement;
- var namedType = node.type2;
- var type = namedType.type;
- if (type != null) {
- var element = type.element;
+ if (node.parent is ConstructorReference) {
+ var element = node.type2.name.staticElement;
if (element is ClassElement) {
- _buildSuggestions(request, builder, libraryElement, element);
+ _buildSuggestions(element);
}
+ } else {
+ var type = node.type2.type;
+ if (type is InterfaceType) {
+ var element = type.element;
+ _buildSuggestions(element);
+ }
+ }
+ } else if (node is PrefixedIdentifier) {
+ var element = node.prefix.staticElement;
+ if (element is ClassElement) {
+ _buildSuggestions(element);
}
}
}
- void _buildSuggestions(
- DartCompletionRequest request,
- SuggestionBuilder builder,
- LibraryElement libElem,
- ClassElement classElem) {
- var isLocalClassDecl = classElem.library == libElem;
- for (var constructor in classElem.constructors) {
+ void _buildSuggestions(ClassElement element) {
+ var tearOff = request.shouldSuggestTearOff(element);
+ var isLocalClassDecl = element.library == request.libraryElement;
+ for (var constructor in element.constructors) {
if (isLocalClassDecl || !constructor.isPrivate) {
- if (!classElem.isAbstract || constructor.isFactory) {
- builder.suggestConstructor(constructor, hasClassName: true);
+ if (!element.isAbstract || constructor.isFactory) {
+ builder.suggestConstructor(
+ constructor,
+ hasClassName: true,
+ kind: tearOff
+ ? protocol.CompletionSuggestionKind.IDENTIFIER
+ : protocol.CompletionSuggestionKind.INVOCATION,
+ tearOff: tearOff,
+ );
}
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
index 1faa088..9aa546b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -4,6 +4,7 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/utilities/extensions/completion_request.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -36,10 +37,12 @@
builder.suggestAccessor(accessor, inheritanceDistance: 0.0);
}
}
- for (var constructor in element.constructors) {
- if (isVisible(constructor)) {
- if (!element.isAbstract || constructor.isFactory) {
- builder.suggestConstructor(constructor, hasClassName: true);
+ if (!request.shouldSuggestTearOff(element)) {
+ for (var constructor in element.constructors) {
+ if (isVisible(constructor)) {
+ if (!element.isAbstract || constructor.isFactory) {
+ builder.suggestConstructor(constructor, hasClassName: true);
+ }
}
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index a5aab9e..fd83310 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -352,10 +352,13 @@
/// period, and hence should not include the name of the class. If the class
/// can only be referenced using a prefix, and the class name is to be
/// included in the completion, then the [prefix] should be provided.
- void suggestConstructor(ConstructorElement constructor,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
- bool hasClassName = false,
- String? prefix}) {
+ void suggestConstructor(
+ ConstructorElement constructor, {
+ CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
+ bool tearOff = false,
+ bool hasClassName = false,
+ String? prefix,
+ }) {
// If the class name is already in the text, then we don't support
// prepending a prefix.
assert(!hasClassName || prefix == null);
@@ -366,7 +369,11 @@
}
var completion = constructor.name;
- if (!hasClassName && className.isNotEmpty) {
+ if (tearOff && completion.isEmpty) {
+ completion = 'new';
+ }
+
+ if (!hasClassName) {
if (completion.isEmpty) {
completion = className;
} else {
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 825ff4b..586a217 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -88,7 +88,7 @@
AddDiagnosticPropertyReference.newInstance,
AddNotNullAssert.newInstance,
AddReturnType.newInstance,
- AddTypeAnnotation.newInstance,
+ AddTypeAnnotation.newInstanceBulkFixable,
AssignToLocalVariable.newInstance,
ConvertAddAllToSpread.newInstance,
ConvertClassToMixin.newInstance,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
index 32499c0..2ba981e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
@@ -19,6 +19,14 @@
AddAsync(this.isForMissingReturn);
@override
+ // Not predictably the correct action.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Not predictably the correct action.
+ bool get canBeAppliedToFile => false;
+
+ @override
FixKind get fixKind => DartFixKind.ADD_ASYNC;
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
index 84d563c..2d5231c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
@@ -17,6 +17,14 @@
String _missingParameterName = '';
@override
+ // Not a stand-alone fix; requires follow-up actions.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Not a stand-alone fix; requires follow-up actions.
+ bool get canBeAppliedToFile => false;
+
+ @override
List<Object> get fixArguments => [_missingParameterName];
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
index b5aed2b..a66c22c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
@@ -158,11 +158,7 @@
if (current == null) {
returnType = type;
} else {
- if (current is InterfaceType && type is InterfaceType) {
- returnType = InterfaceType.getSmartLeastUpperBound(current, type);
- } else {
- returnType = typeSystem.leastUpperBound(current, type);
- }
+ returnType = typeSystem.leastUpperBound(current, type);
}
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_trailing_comma.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_trailing_comma.dart
index c66a0a1..0995f2f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_trailing_comma.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_trailing_comma.dart
@@ -25,8 +25,6 @@
Future<void> compute(ChangeBuilder builder) async {
final node = this.node;
if (node is! ArgumentList) return;
- final parent = node.parent;
- if (parent == null) return;
await builder.addDartFileEdit(file, (builder) {
builder.addSimpleInsertion(node.arguments.last.end, ',');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
index f0e0091..9bb8c12 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
@@ -19,6 +19,16 @@
class AddTypeAnnotation extends CorrectionProducer {
@override
+ bool canBeAppliedInBulk;
+
+ @override
+ bool canBeAppliedToFile;
+
+ AddTypeAnnotation(bool multi)
+ : canBeAppliedInBulk = multi,
+ canBeAppliedToFile = multi;
+
+ @override
AssistKind get assistKind => DartAssistKind.ADD_TYPE_ANNOTATION;
@override
@@ -180,7 +190,11 @@
}
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
- static AddTypeAnnotation newInstance() => AddTypeAnnotation();
+ static AddTypeAnnotation newInstance() => AddTypeAnnotation(false);
+
+ /// Return an instance of this class that can apply bulk and in-file fixes.
+ /// Used as a tear-off in `FixProcessor`.
+ static AddTypeAnnotation newInstanceBulkFixable() => AddTypeAnnotation(true);
}
class _AssignedTypeCollector extends RecursiveAstVisitor<void> {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart
index dbbea0b..6f97951 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart
@@ -6,11 +6,11 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
import '../fix.dart';
@@ -38,11 +38,10 @@
// prepare prefix
var prefix = utils.getNodePrefix(body.parent!);
var indent = utils.getIndent(1);
- var start = body.beginToken.previous!.end;
- var length = body.end - start;
+ var sourceRange = range.endEnd(body.beginToken.previous!, body);
await builder.addDartFileEdit(file, (builder) {
- builder.addReplacement(SourceRange(start, length), (builder) {
+ builder.addReplacement(sourceRange, (builder) {
builder.write(' ');
if (body.isAsynchronous) {
builder.write('async ');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
index 7bcfe13..7f643b6 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
@@ -67,6 +67,18 @@
AssistKind get assistKind => DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING;
@override
+ bool get canBeAppliedInBulk => true;
+
+ @override
+ bool get canBeAppliedToFile => true;
+
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_DOUBLE_QUOTED_STRING;
+
+ @override
+ FixKind get multiFixKind => DartFixKind.CONVERT_TO_DOUBLE_QUOTED_STRING_MULTI;
+
+ @override
bool get _fromDouble => false;
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
index 17594f4..2c03724 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
@@ -15,6 +15,14 @@
String _annotationName = '';
@override
+ // Not predictably the correct action.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Not predictably the correct action.
+ bool get canBeAppliedToFile => false;
+
+ @override
List<Object> get fixArguments => [_annotationName];
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.dart
index 9f349e7..7f70107 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.dart
@@ -12,6 +12,14 @@
class RemoveDeadCode extends CorrectionProducer {
@override
+ // Not predictably the correct action.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Not predictably the correct action.
+ bool get canBeAppliedToFile => false;
+
+ @override
FixKind get fixKind => DartFixKind.REMOVE_DEAD_CODE;
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.dart
index b6da5d0..889378a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.dart
@@ -14,6 +14,14 @@
String _combinatorKind = '';
@override
+ // Not predictably the correct action.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Not predictably the correct action.
+ bool get canBeAppliedToFile => false;
+
+ @override
List<Object> get fixArguments => [_combinatorKind];
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
index adc0a5e..25d4016 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
@@ -16,6 +16,14 @@
class RemoveUnusedElement extends _RemoveUnused {
@override
+ // Not predictably the correct action.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Not predictably the correct action.
+ bool get canBeAppliedToFile => false;
+
+ @override
FixKind get fixKind => DartFixKind.REMOVE_UNUSED_ELEMENT;
@override
@@ -70,6 +78,14 @@
class RemoveUnusedField extends _RemoveUnused {
@override
+ // Not predictably the correct action.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Not predictably the correct action.
+ bool get canBeAppliedToFile => false;
+
+ @override
FixKind get fixKind => DartFixKind.REMOVE_UNUSED_FIELD;
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.dart
index 655a778..02fb02d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.dart
@@ -11,6 +11,7 @@
class RemoveUnusedImport extends CorrectionProducer {
@override
+ // Bulk application is supported by a distinct import cleanup fix phase.
bool get canBeAppliedInBulk => false;
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.dart
index 8f182e9..b06462f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.dart
@@ -11,6 +11,14 @@
class RemoveUnusedLabel extends CorrectionProducer {
@override
+ // Not predictably the correct action.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Not predictably the correct action.
+ bool get canBeAppliedToFile => false;
+
+ @override
FixKind get fixKind => DartFixKind.REMOVE_UNUSED_LABEL;
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
index f64a7a1..bfc7681 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
@@ -14,6 +14,14 @@
class RemoveUnusedLocalVariable extends CorrectionProducer {
@override
+ // Not predictably the correct action.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Not predictably the correct action.
+ bool get canBeAppliedToFile => false;
+
+ @override
FixKind get fixKind => DartFixKind.REMOVE_UNUSED_LOCAL_VARIABLE;
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.dart
index 822442d..d990668 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.dart
@@ -16,6 +16,18 @@
ReplaceWithNullAware(this.correctionKind);
@override
+ // NNBD makes this obsolete in the "chain" application; for the "single"
+ // application, there are other options and a null-aware replacement is not
+ // predictably correct.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // NNBD makes this obsolete in the "chain" application; for the "single"
+ // application, there are other options and a null-aware replacement is not
+ // predictably correct.
+ bool get canBeAppliedToFile => false;
+
+ @override
FixKind get fixKind => DartFixKind.REPLACE_WITH_NULL_AWARE;
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/update_sdk_constraints.dart b/pkg/analysis_server/lib/src/services/correction/dart/update_sdk_constraints.dart
index 2ade5a5..c12a2e2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/update_sdk_constraints.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/update_sdk_constraints.dart
@@ -19,6 +19,14 @@
UpdateSdkConstraints(this._minimumVersion);
@override
+ // Too nuanced to do unattended.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Not applicable (there can only be one constraint per file).
+ bool get canBeAppliedToFile => false;
+
+ @override
FixKind get fixKind => DartFixKind.UPDATE_SDK_CONSTRAINTS;
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index c9ec3cf..7dd6fff 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -344,6 +344,16 @@
DartFixKindPriority.IN_FILE,
"Convert to using 'contains' everywhere in file",
);
+ static const CONVERT_TO_DOUBLE_QUOTED_STRING = FixKind(
+ 'dart.fix.convert.toDoubleQuotedString',
+ DartFixKindPriority.DEFAULT,
+ 'Convert to double quoted string',
+ );
+ static const CONVERT_TO_DOUBLE_QUOTED_STRING_MULTI = FixKind(
+ 'dart.fix.convert.toDoubleQuotedString.multi',
+ DartFixKindPriority.IN_FILE,
+ 'Convert to double quoted strings everywhere in file',
+ );
static const CONVERT_TO_FOR_ELEMENT = FixKind(
'dart.fix.convert.toForElement',
DartFixKindPriority.DEFAULT,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 89bc91f..3b5ed58 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -334,8 +334,7 @@
AddRequired.newInstance,
],
LintNames.always_specify_types: [
- // TODO(brianwilkerson) Consider applying in bulk.
- AddTypeAnnotation.newInstance,
+ AddTypeAnnotation.newInstanceBulkFixable,
],
LintNames.annotate_overrides: [
AddOverride.newInstance,
@@ -470,6 +469,9 @@
LintNames.prefer_contains: [
ConvertToContains.newInstance,
],
+ LintNames.prefer_double_quotes: [
+ ConvertToDoubleQuotes.newInstance,
+ ],
LintNames.prefer_equal_for_default_values: [
ReplaceColonWithEquals.newInstance,
],
@@ -540,7 +542,7 @@
ConvertAddAllToSpread.newInstance,
],
LintNames.prefer_typing_uninitialized_variables: [
- AddTypeAnnotation.newInstance,
+ AddTypeAnnotation.newInstanceBulkFixable,
],
LintNames.prefer_void_to_null: [
ReplaceNullWithVoid.newInstance,
@@ -558,8 +560,7 @@
AddTrailingComma.newInstance,
],
LintNames.type_annotate_public_apis: [
- // TODO(brianwilkerson) Consider applying in bulk.
- AddTypeAnnotation.newInstance,
+ AddTypeAnnotation.newInstanceBulkFixable,
],
LintNames.type_init_formals: [
RemoveTypeAnnotation.newInstance,
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index b43b980..52aee05 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -71,6 +71,7 @@
static const String prefer_const_literals_to_create_immutables =
'prefer_const_literals_to_create_immutables';
static const String prefer_contains = 'prefer_contains';
+ static const String prefer_double_quotes = 'prefer_double_quotes';
static const String prefer_equal_for_default_values =
'prefer_equal_for_default_values';
static const String prefer_expression_function_bodies =
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 4b470bf..163572e 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -1327,11 +1327,7 @@
if (returnType == null) {
return type;
} else {
- if (returnType is InterfaceType && type is InterfaceType) {
- return InterfaceType.getSmartLeastUpperBound(returnType, type);
- } else {
- return typeSystem.leastUpperBound(returnType, type);
- }
+ return typeSystem.leastUpperBound(returnType, type);
}
}
}
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/completion_request.dart b/pkg/analysis_server/lib/src/utilities/extensions/completion_request.dart
new file mode 100644
index 0000000..f0af690
--- /dev/null
+++ b/pkg/analysis_server/lib/src/utilities/extensions/completion_request.dart
@@ -0,0 +1,41 @@
+// 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.
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+
+extension DartCompletionRequestExtensions on DartCompletionRequest {
+ /// Return `true` if the constructor tear-offs feature is enabled, and the
+ /// context type is a function type that matches an instantiation of the
+ /// [element].
+ ///
+ /// TODO(scheglov) Validate that suggesting a tear-off instead of invocation
+ /// is statistically a good choice.
+ bool shouldSuggestTearOff(ClassElement element) {
+ if (!libraryElement.featureSet.isEnabled(Feature.constructor_tearoffs)) {
+ return false;
+ }
+
+ final contextType = this.contextType;
+ if (contextType is! FunctionType) {
+ return false;
+ }
+
+ var bottomInstance = element.instantiate(
+ typeArguments: List.filled(
+ element.typeParameters.length,
+ libraryElement.typeProvider.neverType,
+ ),
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+
+ return libraryElement.typeSystem.isSubtypeOf(
+ bottomInstance,
+ contextType.returnType,
+ );
+ }
+}
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 4c466d1..d727774 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -69,6 +69,8 @@
'${ExperimentStatus.currentVersion.major}.'
'${ExperimentStatus.currentVersion.minor}';
+ Folder get sdkRoot => newFolder('/sdk');
+
AnalysisSession get session => contextFor('/home/test').currentSession;
String? get testPackageLanguageVersion => latestLanguageVersion;
@@ -184,8 +186,9 @@
setupResourceProvider();
- MockSdk(
+ createMockSdk(
resourceProvider: resourceProvider,
+ root: sdkRoot,
);
writeTestPackageConfig();
@@ -292,7 +295,7 @@
enableIndex: true,
includedPaths: collectionIncludedPaths.map(convertPath).toList(),
resourceProvider: resourceProvider,
- sdkPath: convertPath(sdkRoot),
+ sdkPath: sdkRoot.path,
);
_addAnalyzedFilesToDrivers();
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 8a7d311..809d27a 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -93,7 +93,12 @@
//
// Create an SDK in the mock file system.
//
- MockSdk(resourceProvider: resourceProvider);
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+
//
// Create server
//
@@ -102,7 +107,7 @@
serverChannel,
resourceProvider,
options,
- DartSdkManager(resourceProvider.convertPath('/sdk')),
+ DartSdkManager(sdkRoot.path),
CrashReportingAttachmentsBuilder.empty,
InstrumentationService.NULL_SERVICE);
}
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index ca5385e..4b41a22 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -76,13 +76,19 @@
void setUp() {
channel = MockServerChannel();
+
// Create an SDK in the mock file system.
- MockSdk(resourceProvider: resourceProvider);
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+
server = AnalysisServer(
channel,
resourceProvider,
AnalysisServerOptions(),
- DartSdkManager(convertPath('/sdk')),
+ DartSdkManager(sdkRoot.path),
CrashReportingAttachmentsBuilder.empty,
InstrumentationService.NULL_SERVICE);
}
diff --git a/pkg/analysis_server/test/client/completion_driver_test.dart b/pkg/analysis_server/test/client/completion_driver_test.dart
index 3f888c5..c705575 100644
--- a/pkg/analysis_server/test/client/completion_driver_test.dart
+++ b/pkg/analysis_server/test/client/completion_driver_test.dart
@@ -104,18 +104,8 @@
Future<List<CompletionSuggestion>> getSuggestions() async {
if (supportsAvailableSuggestions) {
- // todo (pq): consider moving
- const internalLibs = [
- 'dart:async2',
- 'dart:_interceptors',
- 'dart:_internal',
- ];
- for (var lib in driver.sdk.sdkLibraries) {
- var uri = lib.shortName;
- if (!internalLibs.contains(uri)) {
- await driver.waitForSetWithUri(uri);
- }
- }
+ await driver.waitForSetWithUri('dart:core');
+ await driver.waitForSetWithUri('dart:async');
}
suggestions = await driver.getSuggestions();
diff --git a/pkg/analysis_server/test/client/impl/abstract_client.dart b/pkg/analysis_server/test/client/impl/abstract_client.dart
index d067b8d..51bd14d 100644
--- a/pkg/analysis_server/test/client/impl/abstract_client.dart
+++ b/pkg/analysis_server/test/client/impl/abstract_client.dart
@@ -35,8 +35,6 @@
final String testFilePath;
late String testCode;
- late MockSdk sdk;
-
final AnalysisServerOptions serverOptions;
AbstractClient({
@@ -106,7 +104,10 @@
/// Create an analysis server with the given [sdkPath].
AnalysisServer createAnalysisServer(String sdkPath) {
- sdk = MockSdk(resourceProvider: resourceProvider);
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: newFolder(sdkPath),
+ );
return AnalysisServer(
serverChannel,
resourceProvider,
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 0eee133..8ea43c3 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -1437,13 +1437,19 @@
projectPath = convertPath('/project');
testFile = convertPath('/project/bin/test.dart');
serverChannel = MockServerChannel();
+
// Create an SDK in the mock file system.
- MockSdk(resourceProvider: resourceProvider);
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+
server = AnalysisServer(
serverChannel,
resourceProvider,
AnalysisServerOptions(),
- DartSdkManager(convertPath('/sdk')),
+ DartSdkManager(sdkRoot.path),
CrashReportingAttachmentsBuilder.empty,
InstrumentationService.NULL_SERVICE);
handler = AnalysisDomainHandler(server);
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 26cd616..6b8ba52 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -183,14 +183,20 @@
httpClient = MockHttpClient();
processRunner = MockProcessRunner();
channel = MockLspServerChannel(debugPrintCommunication);
+
// Create an SDK in the mock file system.
- MockSdk(resourceProvider: resourceProvider);
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+
pluginManager = TestPluginManager();
server = LspAnalysisServer(
channel,
resourceProvider,
serverOptions,
- DartSdkManager(convertPath('/sdk')),
+ DartSdkManager(sdkRoot.path),
CrashReportingAttachmentsBuilder.empty,
InstrumentationService.NULL_SERVICE,
httpClient: httpClient,
diff --git a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
index 2c3ed18..87db577 100644
--- a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
@@ -19,15 +19,26 @@
@reflectiveTest
class NamedConstructorContributorTest extends DartCompletionContributorTest {
- CompletionSuggestion assertSuggestNamedConstructor(
- String completion,
- String returnType, {
+ CompletionSuggestion assertConstructorReference({
required String elementName,
+ required String name,
+ required String returnType,
}) {
- var cs = assertSuggest(
- completion,
- csKind: CompletionSuggestionKind.INVOCATION,
+ return assertSuggestNamedConstructor(
+ elementName: elementName,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ name: name,
+ returnType: returnType,
);
+ }
+
+ CompletionSuggestion assertSuggestNamedConstructor({
+ required String elementName,
+ CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
+ required String name,
+ required String returnType,
+ }) {
+ var cs = assertSuggest(name, csKind: kind);
var element = cs.element!;
expect(element.kind, equals(ElementKind.CONSTRUCTOR));
expect(element.name, equals(elementName));
@@ -47,6 +58,236 @@
return NamedConstructorContributor(request, builder);
}
+ Future<void>
+ test_className_period_identifier_functionTypeContext_matchingReturnType() async {
+ addTestSource('''
+class A {
+ A();
+ A.named();
+}
+
+void f() {
+ A Function() v = A.na^;
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset - 2);
+ expect(replacementLength, 2);
+ assertConstructorReference(
+ elementName: 'A',
+ name: 'new',
+ returnType: 'A',
+ );
+ assertConstructorReference(
+ elementName: 'A.named',
+ name: 'named',
+ returnType: 'A',
+ );
+ }
+
+ Future<void> test_className_period_identifier_interfaceTypeContext() async {
+ addTestSource('''
+class A {
+ A();
+ A.named();
+}
+
+void f() {
+ int v = A.na^;
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset - 2);
+ expect(replacementLength, 2);
+ assertSuggestNamedConstructor(
+ elementName: 'A.named',
+ name: 'named',
+ returnType: 'A',
+ );
+ }
+
+ Future<void>
+ test_className_period_nothing_functionTypeContext_matchingReturnType() async {
+ addTestSource('''
+class A {
+ A();
+ A.named();
+}
+
+void f() {
+ A Function() v = A.^;
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertConstructorReference(
+ elementName: 'A',
+ name: 'new',
+ returnType: 'A',
+ );
+ assertConstructorReference(
+ elementName: 'A.named',
+ name: 'named',
+ returnType: 'A',
+ );
+ }
+
+ Future<void> test_className_period_nothing_interfaceTypeContext() async {
+ addTestSource('''
+class A {
+ A();
+ A.named();
+}
+
+void f() {
+ int v = A.^;
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestNamedConstructor(
+ elementName: 'A.named',
+ name: 'named',
+ returnType: 'A',
+ );
+ }
+
+ Future<void>
+ test_className_typeArguments_period_identifier_functionTypeContext_matchingReturnType() async {
+ addTestSource('''
+class A<T> {
+ A.named();
+ A.new();
+}
+
+void f() {
+ A<int> Function() v = A<int>.na^;
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset - 2);
+ expect(replacementLength, 2);
+ assertConstructorReference(
+ elementName: 'A',
+ name: 'new',
+ returnType: 'A<T>',
+ );
+ assertConstructorReference(
+ elementName: 'A.named',
+ name: 'named',
+ returnType: 'A<T>',
+ );
+ }
+
+ Future<void>
+ test_className_typeArguments_period_nothing_functionTypeContext_matchingReturnType() async {
+ addTestSource('''
+class A<T> {
+ A.named();
+ A.new();
+}
+
+void f() {
+ A<int> Function() v = A<int>.^;
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertConstructorReference(
+ elementName: 'A',
+ name: 'new',
+ returnType: 'A<T>',
+ );
+ assertConstructorReference(
+ elementName: 'A.named',
+ name: 'named',
+ returnType: 'A<T>',
+ );
+ }
+
+ Future<void>
+ test_className_typeArguments_period_nothing_functionTypeContext_matchingReturnType2() async {
+ addTestSource('''
+class A {}
+
+class B<T> extends A {
+ B.named();
+ B.new();
+}
+
+void f() {
+ A Function() v = B<int>.^;
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertConstructorReference(
+ elementName: 'B',
+ name: 'new',
+ returnType: 'B<T>',
+ );
+ assertConstructorReference(
+ elementName: 'B.named',
+ name: 'named',
+ returnType: 'B<T>',
+ );
+ }
+
+ Future<void>
+ test_className_typeArguments_period_nothing_functionTypeContext_notMatchingReturnType() async {
+ addTestSource('''
+class A<T> {
+ A.named();
+}
+
+void f() {
+ List<int> Function() v = A<int>.^;
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestNamedConstructor(
+ elementName: 'A.named',
+ name: 'named',
+ returnType: 'A<T>',
+ );
+ }
+
+ Future<void>
+ test_className_typeArguments_period_nothing_interfaceContextType() async {
+ addTestSource('''
+class A<T> {
+ A.named();
+}
+
+void f() {
+ A<int> v = A<int>.^;
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestNamedConstructor(
+ elementName: 'A.named',
+ name: 'named',
+ returnType: 'A<T>',
+ );
+ }
+
Future<void> test_ConstructorName_importedClass() async {
// SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
// InstanceCreationExpression
@@ -63,7 +304,11 @@
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestNamedConstructor('c', 'X', elementName: 'X.c');
+ assertSuggestNamedConstructor(
+ elementName: 'X.c',
+ name: 'c',
+ returnType: 'X',
+ );
assertNotSuggested('F1');
assertNotSuggested('T1');
assertNotSuggested('_d');
@@ -88,7 +333,11 @@
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestNamedConstructor('c', 'X', elementName: 'X.c');
+ assertSuggestNamedConstructor(
+ elementName: 'X.c',
+ name: 'c',
+ returnType: 'X',
+ );
assertNotSuggested('F1');
assertNotSuggested('T1');
assertNotSuggested('_d');
@@ -112,7 +361,11 @@
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestNamedConstructor('c', 'X', elementName: 'X.c');
+ assertSuggestNamedConstructor(
+ elementName: 'X.c',
+ name: 'c',
+ returnType: 'X',
+ );
assertNotSuggested('F1');
assertNotSuggested('T1');
assertNotSuggested('_d');
@@ -129,9 +382,9 @@
expect(replacementOffset, completionOffset - 2);
expect(replacementLength, 13);
assertSuggestNamedConstructor(
- 'fromCharCodes',
- 'String',
elementName: 'String.fromCharCodes',
+ name: 'fromCharCodes',
+ returnType: 'String',
);
assertNotSuggested('isEmpty');
assertNotSuggested('isNotEmpty');
@@ -151,8 +404,16 @@
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestNamedConstructor('c', 'X', elementName: 'X.c');
- assertSuggestNamedConstructor('_d', 'X', elementName: 'X._d');
+ assertSuggestNamedConstructor(
+ elementName: 'X.c',
+ name: 'c',
+ returnType: 'X',
+ );
+ assertSuggestNamedConstructor(
+ elementName: 'X._d',
+ name: '_d',
+ returnType: 'X',
+ );
assertNotSuggested('F1');
assertNotSuggested('T1');
assertNotSuggested('z');
@@ -170,11 +431,50 @@
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestNamedConstructor('c', 'X', elementName: 'X.c');
- assertSuggestNamedConstructor('_d', 'X', elementName: 'X._d');
+ assertSuggestNamedConstructor(
+ elementName: 'X.c',
+ name: 'c',
+ returnType: 'X',
+ );
+ assertSuggestNamedConstructor(
+ elementName: 'X._d',
+ name: '_d',
+ returnType: 'X',
+ );
assertNotSuggested('F1');
assertNotSuggested('T1');
assertNotSuggested('z');
assertNotSuggested('m');
}
+
+ Future<void>
+ test_importPrefix_className_typeArguments_period_nothing_functionTypeContext_matchingReturnType() async {
+ addSource('/home/test/lib/a.dart', '''
+class A<T> {
+ A.named();
+ A.new();
+}
+''');
+ addTestSource('''
+import 'a.dart' as prefix;
+
+void f() {
+ A<int> Function() v = prefix.A<int>.^;
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertConstructorReference(
+ elementName: 'A',
+ name: 'new',
+ returnType: 'A<T>',
+ );
+ assertConstructorReference(
+ elementName: 'A.named',
+ name: 'named',
+ returnType: 'A<T>',
+ );
+ }
}
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
index 1c6e558..919e175 100644
--- a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -178,6 +178,48 @@
assertSuggestConstructor('bar', elementName: 'A.bar');
}
+ Future<void>
+ test_implicitCreation_functionContextType_matchingReturnType() async {
+ addSource('/home/test/lib/a.dart', '''
+class A {
+ A.foo();
+ A.bar();
+}
+''');
+ addTestSource('''
+import 'a.dart';
+
+main() {
+ A Function() v = A.^;
+}
+''');
+ await computeSuggestions();
+
+ assertNotSuggested('foo');
+ assertNotSuggested('bar');
+ }
+
+ Future<void>
+ test_implicitCreation_functionContextType_notMatchingReturnType() async {
+ addSource('/home/test/lib/a.dart', '''
+class A {
+ A.foo();
+ A.bar();
+}
+''');
+ addTestSource('''
+import 'a.dart';
+
+main() {
+ int Function() v = A.^;
+}
+''');
+ await computeSuggestions();
+
+ assertSuggestConstructor('foo', elementName: 'A.foo');
+ assertSuggestConstructor('bar', elementName: 'A.bar');
+ }
+
Future<void> test_keyword() async {
addTestSource('class C { static C get instance => null; } main() {C.in^}');
await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 6e99c97..527b60f 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -2806,7 +2806,7 @@
// end
}
-List<dynamic> res(bool b) {
+List<Object> res(bool b) {
if (b) {
print(true);
return <int>[];
diff --git a/pkg/analysis_server/test/src/cider/cider_service.dart b/pkg/analysis_server/test/src/cider/cider_service.dart
index b4d2492..32aafc2 100644
--- a/pkg/analysis_server/test/src/cider/cider_service.dart
+++ b/pkg/analysis_server/test/src/cider/cider_service.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/micro/resolve_file.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/workspace/bazel.dart';
@@ -15,7 +16,6 @@
class CiderServiceTest with ResourceProviderMixin {
final StringBuffer logBuffer = StringBuffer();
late PerformanceLog logger;
- late MockSdk sdk;
late FileResolver fileResolver;
@@ -23,6 +23,13 @@
/// Create a new [FileResolver] into [fileResolver].
void createFileResolver() {
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+ var sdk = FolderBasedDartSdk(resourceProvider, sdkRoot);
+
var workspace = BazelWorkspace.find(
resourceProvider,
convertPath(testPath),
@@ -43,7 +50,6 @@
registerLintRules();
logger = PerformanceLog(logBuffer);
- sdk = MockSdk(resourceProvider: resourceProvider);
newFile('/workspace/WORKSPACE');
newFile('/workspace/dart/test/BUILD');
diff --git a/pkg/analysis_server/test/src/g3/fixes_test.dart b/pkg/analysis_server/test/src/g3/fixes_test.dart
index 7aab591..34bdfbf 100644
--- a/pkg/analysis_server/test/src/g3/fixes_test.dart
+++ b/pkg/analysis_server/test/src/g3/fixes_test.dart
@@ -4,6 +4,7 @@
import 'package:analysis_server/src/g3/fixes.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:linter/src/rules.dart';
@@ -18,9 +19,14 @@
@reflectiveTest
class G3FixesTest with ResourceProviderMixin {
+ Folder get sdkRoot => newFolder('/sdk');
+
void setUp() {
registerLintRules();
- MockSdk(resourceProvider: resourceProvider);
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
}
Future<void> test_awaitOnlyFutures() async {
@@ -126,7 +132,7 @@
var tester = LintFixTester(
resourceProvider: resourceProvider,
- sdkPath: convertPath(sdkRoot),
+ sdkPath: sdkRoot.path,
packageConfigPath: null,
);
@@ -157,7 +163,7 @@
var tester = LintFixTester(
resourceProvider: resourceProvider,
- sdkPath: convertPath(sdkRoot),
+ sdkPath: sdkRoot.path,
packageConfigPath: null,
);
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
index edf86dc..c693fe8 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
@@ -5,6 +5,7 @@
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/expect.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'fix_processor.dart';
@@ -12,8 +13,15 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(AddTypeAnnotationTest);
+ defineReflectiveTests(AlwaysSpecifyTypesBulkTest);
+ defineReflectiveTests(AlwaysSpecifyTypesInFileTest);
defineReflectiveTests(AlwaysSpecifyTypesLintTest);
+ defineReflectiveTests(PreferTypingUninitializedVariablesBulkTest);
+ defineReflectiveTests(PreferTypingUninitializedVariablesInFileTest);
defineReflectiveTests(PreferTypingUninitializedVariablesLintTest);
+ defineReflectiveTests(TypeAnnotatePublicAPIsBulkTest);
+ defineReflectiveTests(TypeAnnotatePublicAPIsInFileTest);
+ defineReflectiveTests(TypeAnnotatePublicAPIsLintTest);
});
}
@@ -52,6 +60,48 @@
}
@reflectiveTest
+class AlwaysSpecifyTypesBulkTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.always_specify_types;
+
+ Future<void> test_bulk() async {
+ await resolveTestCode('''
+final a = 0;
+class A {
+ final b = 1;
+}
+''');
+ await assertHasFix('''
+final int a = 0;
+class A {
+ final int b = 1;
+}
+''');
+ }
+}
+
+@reflectiveTest
+class AlwaysSpecifyTypesInFileTest extends FixInFileProcessorTest {
+ Future<void> test_File() async {
+ createAnalysisOptionsFile(lints: [LintNames.always_specify_types]);
+ await resolveTestCode(r'''
+final a = 0;
+class A {
+ final b = 1;
+}
+''');
+ var fixes = await getFixesForFirstError();
+ expect(fixes, hasLength(1));
+ assertProduces(fixes.first, r'''
+final int a = 0;
+class A {
+ final int b = 1;
+}
+''');
+ }
+}
+
+@reflectiveTest
class AlwaysSpecifyTypesLintTest extends FixProcessorLintTest {
@override
FixKind get kind => DartFixKind.ADD_TYPE_ANNOTATION;
@@ -76,6 +126,62 @@
}
@reflectiveTest
+class PreferTypingUninitializedVariablesBulkTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.prefer_typing_uninitialized_variables;
+
+ Future<void> test_bulk() async {
+ await resolveTestCode('''
+void f() {
+ var a, b;
+ a = 0;
+ b = 1;
+ print(a);
+ print(b);
+}
+''');
+ await assertHasFix('''
+void f() {
+ int a, b;
+ a = 0;
+ b = 1;
+ print(a);
+ print(b);
+}
+''');
+ }
+}
+
+@reflectiveTest
+class PreferTypingUninitializedVariablesInFileTest
+ extends FixInFileProcessorTest {
+ Future<void> test_File() async {
+ createAnalysisOptionsFile(
+ lints: [LintNames.prefer_typing_uninitialized_variables]);
+ await resolveTestCode(r'''
+void f() {
+ var a, b;
+ a = 0;
+ b = 1;
+ print(a);
+ print(b);
+}
+''');
+ var fixes = await getFixesForFirstError();
+ expect(fixes, hasLength(1));
+ assertProduces(fixes.first, r'''
+void f() {
+ int a, b;
+ a = 0;
+ b = 1;
+ print(a);
+ print(b);
+}
+''');
+ }
+}
+
+@reflectiveTest
class PreferTypingUninitializedVariablesLintTest extends FixProcessorLintTest {
@override
FixKind get kind => DartFixKind.ADD_TYPE_ANNOTATION;
@@ -102,3 +208,51 @@
''');
}
}
+
+@reflectiveTest
+class TypeAnnotatePublicAPIsBulkTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.type_annotate_public_apis;
+
+ Future<void> test_bulk() async {
+ await resolveTestCode('''
+var a = '', b = '';
+''');
+ await assertHasFix('''
+String a = '', b = '';
+''');
+ }
+}
+
+@reflectiveTest
+class TypeAnnotatePublicAPIsInFileTest extends FixInFileProcessorTest {
+ Future<void> test_File() async {
+ createAnalysisOptionsFile(lints: [LintNames.type_annotate_public_apis]);
+ await resolveTestCode(r'''
+var a = '', b = '';
+''');
+ var fixes = await getFixesForFirstError();
+ expect(fixes, hasLength(1));
+ assertProduces(fixes.first, r'''
+String a = '', b = '';
+''');
+ }
+}
+
+@reflectiveTest
+class TypeAnnotatePublicAPIsLintTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_TYPE_ANNOTATION;
+
+ @override
+ String get lintCode => LintNames.type_annotate_public_apis;
+
+ Future<void> test_local() async {
+ await resolveTestCode('''
+var a = '';
+''');
+ await assertHasFix('''
+String a = '';
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_double_quoted_string_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_double_quoted_string_test.dart
new file mode 100644
index 0000000..69058c9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_double_quoted_string_test.dart
@@ -0,0 +1,101 @@
+// 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/expect.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToDoubleQuotedStringBulkTest);
+ defineReflectiveTests(ConvertToDoubleQuotedStringInFileTest);
+ defineReflectiveTests(ConvertToDoubleQuotedStringTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToDoubleQuotedStringBulkTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.prefer_double_quotes;
+
+ Future<void> test_singleFile() async {
+ await resolveTestCode('''
+void f() {
+ print('abc');
+ print('e' + 'f' + 'g');
+}
+''');
+ await assertHasFix('''
+void f() {
+ print("abc");
+ print("e" + "f" + "g");
+}
+''');
+ }
+}
+
+@reflectiveTest
+class ConvertToDoubleQuotedStringInFileTest extends FixInFileProcessorTest {
+ Future<void> test_File() async {
+ createAnalysisOptionsFile(lints: [LintNames.prefer_double_quotes]);
+ await resolveTestCode(r'''
+void f() {
+ print('abc');
+ print('e' + 'f' + 'g');
+}
+''');
+ var fixes = await getFixesForFirstError();
+ expect(fixes, hasLength(1));
+ assertProduces(fixes.first, r'''
+void f() {
+ print("abc");
+ print("e" + "f" + "g");
+}
+''');
+ }
+}
+
+@reflectiveTest
+class ConvertToDoubleQuotedStringTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.CONVERT_TO_DOUBLE_QUOTED_STRING;
+
+ @override
+ String get lintCode => LintNames.prefer_double_quotes;
+
+ Future<void> test_one_interpolation() async {
+ await resolveTestCode(r'''
+void f() {
+ var b = "b";
+ var c = "c";
+ print('a $b-${c} d');
+}
+''');
+ await assertHasFix(r'''
+void f() {
+ var b = "b";
+ var c = "c";
+ print("a $b-${c} d");
+}
+''');
+ }
+
+ /// More coverage in the `convert_to_double_quoted_string_test.dart` assist test.
+ Future<void> test_one_simple() async {
+ await resolveTestCode('''
+void f() {
+ print('abc');
+}
+''');
+ await assertHasFix('''
+void f() {
+ print("abc");
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart
index 42e0f6e..42125b3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart
@@ -5,6 +5,7 @@
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/expect.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'fix_processor.dart';
@@ -12,6 +13,7 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(ConvertToSingleQuotedStringBulkTest);
+ defineReflectiveTests(ConvertToSingleQuotedStringInFileTest);
defineReflectiveTests(ConvertToSingleQuotedStringTest);
});
}
@@ -38,6 +40,27 @@
}
@reflectiveTest
+class ConvertToSingleQuotedStringInFileTest extends FixInFileProcessorTest {
+ Future<void> test_File() async {
+ createAnalysisOptionsFile(lints: [LintNames.prefer_single_quotes]);
+ await resolveTestCode(r'''
+void f() {
+ print("abc");
+ print("e" + "f" + "g");
+}
+''');
+ var fixes = await getFixesForFirstError();
+ expect(fixes, hasLength(1));
+ assertProduces(fixes.first, r'''
+void f() {
+ print('abc');
+ print('e' + 'f' + 'g');
+}
+''');
+ }
+}
+
+@reflectiveTest
class ConvertToSingleQuotedStringTest extends FixProcessorLintTest {
@override
FixKind get kind => DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_test.dart
index a154782..72a5b03 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_test.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_manager.dart';
-import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'data_driven_test_support.dart';
@@ -18,7 +17,7 @@
class AbstractSdkFixTest extends DataDrivenFixProcessorTest {
void addSdkDataFile(String content) {
- newFile('$sdkRoot/lib/_internal/${TransformSetManager.dataFileName}',
+ newFile('${sdkRoot.path}/lib/_internal/${TransformSetManager.dataFileName}',
content: content);
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart
index 736da8c..87759cd 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart
@@ -21,7 +21,7 @@
@override
String get lintCode => LintNames.avoid_redundant_argument_values;
- Future<void> test_singleFile() async {
+ Future<void> test_independentInvocations() async {
await resolveTestCode('''
void f({bool valWithDefault = true, bool val}) {}
void f2({bool valWithDefault = true, bool val}) {}
@@ -41,6 +41,23 @@
}
''');
}
+
+ Future<void> test_multipleInSingleInvocation() async {
+ await resolveTestCode('''
+void f() {
+ g(a: 0, b: 1, c: 2);
+}
+
+void g({int a = 0, int b = 1, int c = 2}) {}
+''');
+ await assertHasFix('''
+void f() {
+ g();
+}
+
+void g({int a = 0, int b = 1, int c = 2}) {}
+''');
+ }
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index fb32189..ac07949 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -55,6 +55,8 @@
import 'convert_into_is_not_test.dart' as convert_into_is_not;
import 'convert_quotes_test.dart' as convert_quotes;
import 'convert_to_contains_test.dart' as convert_to_contains;
+import 'convert_to_double_quoted_string_test.dart'
+ as convert_to_double_quoted_string;
import 'convert_to_for_element_test.dart' as convert_to_for_element;
import 'convert_to_generic_function_syntax_test.dart'
as convert_to_generic_function_syntax;
@@ -252,6 +254,7 @@
convert_into_is_not.main();
convert_quotes.main();
convert_to_contains.main();
+ convert_to_double_quoted_string.main();
convert_to_for_element.main();
convert_to_generic_function_syntax.main();
convert_to_if_element.main();
diff --git a/pkg/analysis_server/tool/bulk_fix/parse_utils.dart b/pkg/analysis_server/tool/bulk_fix/parse_utils.dart
new file mode 100644
index 0000000..84cf49b
--- /dev/null
+++ b/pkg/analysis_server/tool/bulk_fix/parse_utils.dart
@@ -0,0 +1,73 @@
+// 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.
+
+import 'dart:io';
+
+import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer_utilities/package_root.dart';
+
+class BulkFixDetails {
+ Future<Map<String, CorrectionDetails>> collectOverrides() async {
+ var overrideDetails = <String, CorrectionDetails>{};
+
+ var pkgRootPath =
+ PhysicalResourceProvider.INSTANCE.pathContext.normalize(packageRoot);
+ var directory = Directory(
+ '$pkgRootPath/analysis_server/lib/src/services/correction/dart');
+ var collection = AnalysisContextCollection(
+ includedPaths: [directory.absolute.path],
+ resourceProvider: PhysicalResourceProvider.INSTANCE,
+ );
+ var context = collection.contexts[0];
+
+ for (var file in directory.listSync()) {
+ var resolvedFile = await context.currentSession
+ .getResolvedUnit(file.absolute.path) as ResolvedUnitResult;
+ for (var classDecl
+ in resolvedFile.unit.declarations.whereType<ClassDeclaration>()) {
+ var classElement = classDecl.declaredElement;
+ if (classElement != null &&
+ classElement.allSupertypes.any(
+ (element) => element.element.name == 'CorrectionProducer')) {
+ var correctionName = classDecl.name.name;
+
+ for (var method in classDecl.members.whereType<MethodDeclaration>()) {
+ if (method.name.name == 'canBeAppliedInBulk') {
+ var hasComment =
+ method.returnType?.beginToken.precedingComments != null;
+
+ var body = method.body;
+ if (body is BlockFunctionBody) {
+ var last = body.block.statements.last;
+ if (last is ReturnStatement) {
+ var canBeBulkApplied =
+ (last.expression as BooleanLiteral).value;
+ overrideDetails[correctionName] = CorrectionDetails(
+ canBeBulkApplied: canBeBulkApplied,
+ hasComment: hasComment);
+ }
+ } else if (body is ExpressionFunctionBody) {
+ var expression = body.expression;
+ var canBeBulkApplied = (expression as BooleanLiteral).value;
+ overrideDetails[correctionName] = CorrectionDetails(
+ canBeBulkApplied: canBeBulkApplied, hasComment: hasComment);
+ }
+ }
+ }
+ }
+ }
+ }
+ return overrideDetails;
+ }
+}
+
+class CorrectionDetails {
+ bool canBeBulkApplied;
+ bool hasComment;
+
+ CorrectionDetails({required this.canBeBulkApplied, required this.hasComment});
+}
diff --git a/pkg/analysis_server/tool/bulk_fix/supported_hints.dart b/pkg/analysis_server/tool/bulk_fix/supported_hints.dart
new file mode 100644
index 0000000..ccc3938
--- /dev/null
+++ b/pkg/analysis_server/tool/bulk_fix/supported_hints.dart
@@ -0,0 +1,47 @@
+// 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.
+
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer/error/error.dart';
+
+import 'parse_utils.dart';
+
+/// Print hint bulk-fix info.
+Future<void> main() async {
+ var overrideDetails = await BulkFixDetails().collectOverrides();
+
+ print('hints w/ correction producers:\n');
+
+ var hintEntries = FixProcessor.nonLintProducerMap.entries
+ .where((e) => e.key.type == ErrorType.HINT);
+ for (var hint in hintEntries) {
+ var canBeAppliedInBulk = false;
+ var missingExplanations = <String>[];
+ var hasOverride = false;
+ for (var generator in hint.value) {
+ var producer = generator();
+ if (!producer.canBeAppliedInBulk) {
+ var producerName = producer.runtimeType.toString();
+ if (overrideDetails.containsKey(producerName)) {
+ hasOverride = true;
+ var override = overrideDetails[producerName];
+ var hasComment = override!.hasComment;
+ if (!hasComment) {
+ missingExplanations.add(producerName);
+ }
+ }
+ } else {
+ canBeAppliedInBulk = true;
+ }
+ }
+
+ print('${hint.key} bulk fixable: $canBeAppliedInBulk');
+ if (!canBeAppliedInBulk && !hasOverride) {
+ print(' => override missing');
+ }
+ for (var producer in missingExplanations) {
+ print(' => override explanation missing for: $producer');
+ }
+ }
+}
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 492681f..aa7d370 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,5 +1,7 @@
## 2.7.0-dev
* Updated `ConstructorElement.displayName` to either `Class` or `Class.constructor`.
+* Deprecated `InterfaceType.getSmartLeastUpperBound`, use `TypeSystem.leastUpperBound` instead.
+* Deprecated `MockSdk`, use `createMockSdk` and `FolderBasedDartSdk` instead.
## 2.6.0
* Deprecated `AnalysisResult.state`, check for specific valid or invalid subtypes.
diff --git a/pkg/analyzer/lib/dart/analysis/features.dart b/pkg/analyzer/lib/dart/analysis/features.dart
index a2ca408..9264322 100644
--- a/pkg/analyzer/lib/dart/analysis/features.dart
+++ b/pkg/analyzer/lib/dart/analysis/features.dart
@@ -41,6 +41,10 @@
/// Feature information for the triple-shift operator.
static final triple_shift = ExperimentalFeatures.triple_shift;
+ /// Feature information for named arguments anywhere.
+ static final named_arguments_anywhere =
+ ExperimentalFeatures.named_arguments_anywhere;
+
/// Feature information for non-function type aliases.
static final nonfunction_type_aliases =
ExperimentalFeatures.nonfunction_type_aliases;
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 5e9079a..2e1f80a 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -555,7 +555,7 @@
/// arguments, attempts to find a compatible set of type arguments.
///
/// Otherwise, returns the same result as [DartType.getLeastUpperBound].
- // TODO(brianwilkerson) This needs to be deprecated and moved to TypeSystem.
+ @Deprecated('Use TypeSystem.leastUpperBound instead')
static InterfaceType getSmartLeastUpperBound(
InterfaceType first, InterfaceType second) =>
InterfaceTypeImpl.getSmartLeastUpperBound(first, second);
diff --git a/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart b/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
index d2062c5..c87a35f 100644
--- a/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
+++ b/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
@@ -106,7 +106,7 @@
Reference.root(),
);
- var linkResult = link(elementFactory, inputLibraries, false);
+ var linkResult = link(elementFactory, inputLibraries);
var bundleBuilder = PackageBundleBuilder();
for (var library in inputLibraries) {
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 1871a08..f6c195c 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -226,6 +226,7 @@
CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
+ CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION,
CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY,
CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC,
CompileTimeErrorCode.INSTANTIATE_ABSTRACT_CLASS,
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 72092ad..af4763e 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -175,7 +175,7 @@
link2.LinkResult linkResult;
try {
timerLinking.start();
- linkResult = link2.link(elementFactory, inputLibraries, true);
+ linkResult = link2.link(elementFactory, inputLibraries);
librariesLinked += cycle.libraries.length;
counterLinkedLibraries += inputLibraries.length;
timerLinking.stop();
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 121484e..9e95612 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -1314,12 +1314,7 @@
var element = _element;
var otherElement = rightOperand._element;
- var elementsAreEqual = identical(element, otherElement) ||
- (element != null &&
- otherElement != null &&
- otherElement.kind == element.kind &&
- otherElement.location == element.location);
- if (!elementsAreEqual) {
+ if (element?.declaration != otherElement?.declaration) {
return BoolState.FALSE_STATE;
}
var typeArguments = _typeArguments;
@@ -1332,7 +1327,10 @@
return BoolState.FALSE_STATE;
}
for (var i = 0; i < typeArguments.length; i++) {
- if (typeArguments[i] != otherTypeArguments[i]) {
+ if (!typeSystem.runtimeTypesEqual(
+ typeArguments[i],
+ otherTypeArguments[i],
+ )) {
return BoolState.FALSE_STATE;
}
}
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 5e1f329..17fa3c2 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1354,6 +1354,7 @@
/// arguments, attempts to find a compatible set of type arguments.
///
/// Otherwise, calls [DartType.getLeastUpperBound].
+ @Deprecated('Use TypeSystem.leastUpperBound instead')
static InterfaceType getSmartLeastUpperBound(
InterfaceType first, InterfaceType second) {
// TODO(paulberry): this needs to be deprecated and replaced with a method
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
index 62ea343..e0f5728 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
@@ -1486,7 +1486,7 @@
// ```
static const HintCode INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION = HintCode(
'INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION',
- "The declaration '{0}' is annotated with 'visibleForOverriding'. Because '{0}' isn't an interface member that could be overridden, the annotation is meaningless.",
+ "The annotation 'visibleForOverriding' can only be applied to a public instance member that can be overridden.",
hasPublishedDocs: true,
);
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index ab564f3..7ff94e7 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -877,7 +877,7 @@
}
inputsTimer.stop();
- var linkResult = link2.link(elementFactory, inputLibraries, true);
+ var linkResult = link2.link(elementFactory, inputLibraries);
librariesLinked += cycle.libraries.length;
resolutionBytes = linkResult.resolutionBytes;
diff --git a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
index 7882635..53c06aa 100644
--- a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
@@ -128,7 +128,7 @@
/// when it returns 'void'. Or, in rare cases, when other types of expressions
/// are void, such as identifiers.
///
- /// See [StaticWarningCode.USE_OF_VOID_RESULT].
+ /// See [CompileTimeErrorCode.USE_OF_VOID_RESULT].
/// TODO(scheglov) this is duplicate
bool _checkForUseOfVoidResult(Expression expression) {
if (!identical(expression.staticType, VoidTypeImpl.instance)) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
index 3f5ac4f..6e59428 100644
--- a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
@@ -35,6 +35,9 @@
bool get _genericMetadataIsEnabled =>
_resolver.definingLibrary.featureSet.isEnabled(Feature.generic_metadata);
+ bool get _isNonNullableByDefault =>
+ _resolver.definingLibrary.featureSet.isEnabled(Feature.non_nullable);
+
TypeProvider get _typeProvider => _resolver.typeProvider;
TypeSystemImpl get _typeSystem => _resolver.typeSystem;
@@ -73,9 +76,15 @@
nameEntity.length,
[
name,
- noneMoreSpecific
- .map((e) => e.extension.name ?? '<unnamed>')
- .quotedAndCommaSeparatedWithAnd,
+ noneMoreSpecific.map((e) {
+ var name = e.extension.name;
+ if (name != null) {
+ return "extension '$name'";
+ }
+ var type = e.extension.extendedType
+ .getDisplayString(withNullability: _isNonNullableByDefault);
+ return "unnamed extension on '$type'";
+ }).commaSeparatedWithAnd,
],
);
return ResolutionResult.ambiguous;
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
index 48a6c65..42070dc 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
@@ -84,7 +84,7 @@
/// when it returns 'void'. Or, in rare cases, when other types of expressions
/// are void, such as identifiers.
///
- /// See [StaticWarningCode.USE_OF_VOID_RESULT].
+ /// See [CompileTimeErrorCode.USE_OF_VOID_RESULT].
///
/// TODO(scheglov) this is duplicate
bool _checkForUseOfVoidResult(Expression expression, DartType type) {
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 386da13..d55bcaa 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -164,14 +164,26 @@
[enclosingElement.displayName],
);
}
+ } else if (enclosingElement is ExtensionElement &&
+ enclosingElement.name == null) {
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode
+ .INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION,
+ nameNode,
+ [
+ nameNode.name,
+ element.kind.displayName,
+ ]);
} else {
+ // It is safe to assume that `enclosingElement.name` is non-`null` because
+ // it can only be `null` for extensions, and we handle that case above.
_resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
nameNode,
[
nameNode.name,
element.kind.displayName,
- enclosingElement.name ?? '<unnamed>',
+ enclosingElement.name!,
enclosingElement is ClassElement && enclosingElement.isMixin
? 'mixin'
: enclosingElement.kind.displayName,
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 e75d2be..7070eac 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -234,14 +234,26 @@
[enclosingElement.displayName],
);
}
+ } else if (enclosingElement is ExtensionElement &&
+ enclosingElement.name == null) {
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode
+ .INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION,
+ nameNode,
+ [
+ nameNode.name,
+ element.kind.displayName,
+ ]);
} else {
+ // It is safe to assume that `enclosingElement.name` is non-`null` because
+ // it can only be `null` for extensions, and we handle that case above.
_resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
nameNode,
[
nameNode.name,
element.kind.displayName,
- enclosingElement.name ?? '<unnamed>',
+ enclosingElement.name!,
enclosingElement is ClassElement && enclosingElement.isMixin
? 'mixin'
: enclosingElement.kind.displayName,
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 787d963..84cc019 100644
--- a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
@@ -275,16 +275,31 @@
);
} else {
var enclosingElement = element.enclosingElement;
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
- propertyName, [
- propertyName,
- element.kind.displayName,
- enclosingElement.name ?? '<unnamed>',
- enclosingElement is ClassElement && enclosingElement.isMixin
- ? 'mixin'
- : enclosingElement.kind.displayName,
- ]);
+ if (enclosingElement is ExtensionElement &&
+ enclosingElement.name == null) {
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode
+ .INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION,
+ propertyName,
+ [
+ propertyName.name,
+ element.kind.displayName,
+ ]);
+ } else {
+ // It is safe to assume that `enclosingElement.name` is non-`null`
+ // because it can only be `null` for extensions, and we handle that
+ // case above.
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
+ propertyName, [
+ propertyName.name,
+ element.kind.displayName,
+ enclosingElement.name!,
+ enclosingElement is ClassElement && enclosingElement.isMixin
+ ? 'mixin'
+ : enclosingElement.kind.displayName,
+ ]);
+ }
}
}
}
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index a8de577..4d6d9a3 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -232,9 +232,7 @@
void reportInvalidVisibleForOverriding(Element declaredElement) {
_errorReporter.reportErrorForNode(
- HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION,
- node,
- [declaredElement.name ?? '<unnamed>']);
+ HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, node);
}
if (parent is TopLevelVariableDeclaration) {
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index 2e29e47..50bdab7 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -184,8 +184,7 @@
/**
* Parameters:
* 0: the name of the member
- * 1: the name of the first declaring extension
- * 2: the name of the second declaring extension
+ * 1: the names of the declaring extensions
*/
// #### Description
//
@@ -244,7 +243,7 @@
static const CompileTimeErrorCode AMBIGUOUS_EXTENSION_MEMBER_ACCESS =
CompileTimeErrorCode(
'AMBIGUOUS_EXTENSION_MEMBER_ACCESS',
- "A member named '{0}' is defined in extensions {1}, and none are more specific.",
+ "A member named '{0}' is defined in {1}, and none are more specific.",
correctionMessage:
"Try using an extension override to specify the extension you want to be chosen.",
hasPublishedDocs: true,
@@ -4157,8 +4156,7 @@
/**
* Parameters:
- * 0: the name of the extension defining the conflicting member
- * 1: the name of the conflicting static member
+ * 0: the name of the conflicting static member
*/
// #### Description
//
@@ -4193,7 +4191,7 @@
static const CompileTimeErrorCode EXTENSION_CONFLICTING_STATIC_AND_INSTANCE =
CompileTimeErrorCode(
'EXTENSION_CONFLICTING_STATIC_AND_INSTANCE',
- "Extension '{0}' can't define static member '{1}' and an instance member with the same name.",
+ "An extension can't define static member '{0}' and an instance member with the same name.",
correctionMessage:
"Try renaming the member to a name that doesn't conflict.",
hasPublishedDocs: true,
@@ -6254,6 +6252,20 @@
);
/**
+ * Parameters:
+ * 0: the name of the static member
+ * 1: the kind of the static member (field, getter, setter, or method)
+ */
+ static const CompileTimeErrorCode
+ INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION =
+ CompileTimeErrorCode(
+ 'INSTANCE_ACCESS_TO_STATIC_MEMBER',
+ "The static {1} '{0}' can't be accessed through an instance.",
+ hasPublishedDocs: true,
+ uniqueName: 'INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION',
+ );
+
+ /**
* No parameters.
*/
// #### Description
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index 684e1ac8..113dae0 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -112,7 +112,7 @@
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
identifier,
- [node.declaredElement!.name ?? '<unnamed>', name],
+ [name],
);
}
}
@@ -126,7 +126,7 @@
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
identifier,
- [node.declaredElement!.name ?? '<unnamed>', name],
+ [name],
);
}
}
diff --git a/pkg/analyzer/lib/src/error/use_result_verifier.dart b/pkg/analyzer/lib/src/error/use_result_verifier.dart
index 1899064..c6939dec 100644
--- a/pkg/analyzer/lib/src/error/use_result_verifier.dart
+++ b/pkg/analyzer/lib/src/error/use_result_verifier.dart
@@ -154,6 +154,8 @@
}
return parent is ArgumentList ||
+ // Node should always be RHS so no need to check for a property assignment.
+ parent is AssignmentExpression ||
parent is VariableDeclaration ||
parent is MethodInvocation ||
parent is PropertyAccess ||
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 4951088..e88c858 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -144,9 +144,12 @@
/// `true` if constructor tearoffs are enabled
final bool enableConstructorTearoffs;
- /// `true` if extension types are enabled;
+ /// `true` if extension types are enabled
final bool enableExtensionTypes;
+ /// `true` if named arguments anywhere are enabled
+ final bool enableNamedArgumentsAnywhere;
+
final FeatureSet _featureSet;
AstBuilder(ErrorReporter? errorReporter, this.fileUri, this.isFullAst,
@@ -165,6 +168,8 @@
enableConstructorTearoffs =
_featureSet.isEnabled(Feature.constructor_tearoffs),
enableExtensionTypes = _featureSet.isEnabled(Feature.extension_types),
+ enableNamedArgumentsAnywhere =
+ _featureSet.isEnabled(Feature.named_arguments_anywhere),
uri = uri ?? fileUri;
NodeList<ClassMember> get currentDeclarationMembers {
@@ -579,14 +584,16 @@
ArgumentList arguments =
ast.argumentList(leftParenthesis, expressions, rightParenthesis);
- bool hasSeenNamedArgument = false;
- for (Expression expression in expressions) {
- if (expression is NamedExpression) {
- hasSeenNamedArgument = true;
- } else if (hasSeenNamedArgument) {
- // Positional argument after named argument.
- handleRecoverableError(messagePositionalAfterNamedArgument,
- expression.beginToken, expression.endToken);
+ if (!enableNamedArgumentsAnywhere) {
+ bool hasSeenNamedArgument = false;
+ for (Expression expression in expressions) {
+ if (expression is NamedExpression) {
+ hasSeenNamedArgument = true;
+ } else if (hasSeenNamedArgument) {
+ // Positional argument after named argument.
+ handleRecoverableError(messagePositionalAfterNamedArgument,
+ expression.beginToken, expression.endToken);
+ }
}
}
diff --git a/pkg/analyzer/lib/src/generated/error_detection_helpers.dart b/pkg/analyzer/lib/src/generated/error_detection_helpers.dart
index b53515f..7903c73 100644
--- a/pkg/analyzer/lib/src/generated/error_detection_helpers.dart
+++ b/pkg/analyzer/lib/src/generated/error_detection_helpers.dart
@@ -51,7 +51,7 @@
/// This method corresponds to
/// [BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument].
///
- /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
+ /// See [CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
void checkForArgumentTypeNotAssignableForArgument(Expression argument,
{bool promoteParameterToNullable = false,
Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
@@ -68,7 +68,7 @@
/// from the name in the [ConstructorFieldInitializer].
///
/// See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and
- /// [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE].
+ /// [CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE].
void checkForFieldInitializerNotAssignable(
ConstructorFieldInitializer initializer, FieldElement fieldElement,
{required bool isConstConstructor,
@@ -169,7 +169,7 @@
/// when it returns 'void'. Or, in rare cases, when other types of expressions
/// are void, such as identifiers.
///
- /// See [StaticWarningCode.USE_OF_VOID_RESULT].
+ /// See [CompileTimeErrorCode.USE_OF_VOID_RESULT].
bool checkForUseOfVoidResult(Expression expression) {
if (!identical(expression.staticType, VoidTypeImpl.instance)) {
return false;
@@ -265,13 +265,10 @@
/// Verify that the given [expression] can be assigned to its corresponding
/// parameters.
///
- /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE],
+ /// See [CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE],
/// [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
- /// [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
- /// [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
- /// [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
- /// [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
- /// [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
+ /// [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
+ /// [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
void _checkForArgumentTypeNotAssignableWithExpectedTypes(
Expression expression,
DartType? expectedStaticType,
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 2b6b30d..d2658e5 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -1507,9 +1507,9 @@
/// Verify that the given [expression] is not final.
///
- /// See [StaticWarningCode.ASSIGNMENT_TO_CONST],
- /// [StaticWarningCode.ASSIGNMENT_TO_FINAL], and
- /// [StaticWarningCode.ASSIGNMENT_TO_METHOD].
+ /// See [CompileTimeErrorCode.ASSIGNMENT_TO_CONST],
+ /// [CompileTimeErrorCode.ASSIGNMENT_TO_FINAL], and
+ /// [CompileTimeErrorCode.ASSIGNMENT_TO_METHOD].
void _checkForAssignmentToFinal(Expression expression) {
// TODO(scheglov) Check SimpleIdentifier(s) as all other nodes.
if (expression is! SimpleIdentifier) return;
@@ -1650,7 +1650,7 @@
/// Verify that the given [switchCase] is terminated with 'break', 'continue',
/// 'return' or 'throw'.
///
- /// see [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED].
+ /// see [CompileTimeErrorCode.CASE_BLOCK_NOT_TERMINATED].
void _checkForCaseBlockNotTerminated(SwitchCase switchCase) {
NodeList<Statement> statements = switchCase.statements;
if (statements.isEmpty) {
@@ -1692,7 +1692,7 @@
/// Verify that the switch cases in the given switch [statement] are
/// terminated with 'break', 'continue', 'rethrow', 'return' or 'throw'.
///
- /// See [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED].
+ /// See [CompileTimeErrorCode.CASE_BLOCK_NOT_TERMINATED].
void _checkForCaseBlocksNotTerminated(SwitchStatement statement) {
if (_isNonNullableByDefault) return;
@@ -2432,7 +2432,7 @@
/// variables if the list is final or const.
///
/// See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and
- /// [StaticWarningCode.FINAL_NOT_INITIALIZED].
+ /// [CompileTimeErrorCode.FINAL_NOT_INITIALIZED].
void _checkForFinalNotInitialized(VariableDeclarationList list) {
if (_isInNativeClass || list.isSynthetic) {
return;
@@ -2481,7 +2481,7 @@
/// constructor are handled in [_checkForAllFinalInitializedErrorCodes].
///
/// See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and
- /// [StaticWarningCode.FINAL_NOT_INITIALIZED].
+ /// [CompileTimeErrorCode.FINAL_NOT_INITIALIZED].
void _checkForFinalNotInitializedInClass(List<ClassMember> members) {
for (ClassMember classMember in members) {
if (classMember is ConstructorDeclaration) {
@@ -2665,7 +2665,7 @@
/// given [argument]. This is used for prefix and postfix expressions where
/// the argument value is implicit.
///
- /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
+ /// See [CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
void _checkForIntNotAssignable(Expression argument) {
var staticParameterElement = argument.staticParameterElement;
var staticParameterType = staticParameterElement?.type;
@@ -2839,8 +2839,7 @@
/// Verify that the elements of the given list [literal] are subtypes of the
/// list's static type.
///
- /// See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and
- /// [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE].
+ /// See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE].
void _checkForListElementTypeNotAssignable(ListLiteral literal) {
// Determine the list's element type. We base this on the static type and
// not the literal's type arguments because in strong mode, the type
@@ -3255,7 +3254,7 @@
/// This method assumes that the instance creation was tested to be 'new'
/// before being called.
///
- /// See [StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR].
+ /// See [CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR].
void _checkForNewWithUndefinedConstructor(
InstanceCreationExpression expression,
ConstructorName constructorName,
@@ -3400,7 +3399,7 @@
/// Verify that the given method [declaration] of operator `[]=`, has `void`
/// return type.
///
- /// See [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR].
+ /// See [CompileTimeErrorCode.NON_VOID_RETURN_FOR_OPERATOR].
void _checkForNonVoidReturnTypeForOperator(MethodDeclaration declaration) {
// check that []= operator
SimpleIdentifier name = declaration.name;
@@ -3421,7 +3420,7 @@
/// Verify the [namedType], used as the return type of a setter, is valid
/// (either `null` or the type 'void').
///
- /// See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER].
+ /// See [CompileTimeErrorCode.NON_VOID_RETURN_FOR_SETTER].
void _checkForNonVoidReturnTypeForSetter(TypeAnnotation? namedType) {
if (namedType != null) {
DartType type = namedType.typeOrThrow;
@@ -3880,8 +3879,7 @@
/// Verify that the elements in the given set [literal] are subtypes of the
/// set's static type.
///
- /// See [CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE], and
- /// [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE].
+ /// See [CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE].
void _checkForSetElementTypeNotAssignable3(SetOrMapLiteral literal) {
// Determine the set's element type. We base this on the static type and
// not the literal's type arguments because in strong mode, the type
@@ -3916,7 +3914,7 @@
/// Check the given [typeReference] and that the [name] is not a reference to
/// an instance member.
///
- /// See [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER].
+ /// See [CompileTimeErrorCode.STATIC_ACCESS_TO_INSTANCE_MEMBER].
void _checkForStaticAccessToInstanceMember(
ClassElement? typeReference, SimpleIdentifier name) {
// OK, in comment
@@ -3944,7 +3942,7 @@
/// Check that the type of the expression in the given 'switch' [statement] is
/// assignable to the type of the 'case' members.
///
- /// See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE].
+ /// See [CompileTimeErrorCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE].
void _checkForSwitchExpressionNotAssignable(SwitchStatement statement) {
// For NNBD we verify runtime types of values, and subtyping.
if (_isNonNullableByDefault) {
@@ -4010,7 +4008,7 @@
/// Verify that the [type] is not a deferred type.
///
- /// See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS].
+ /// See [CompileTimeErrorCode.TYPE_ANNOTATION_DEFERRED_CLASS].
void _checkForTypeAnnotationDeferredClass(TypeAnnotation? type) {
if (type is NamedType && type.isDeferred) {
errorReporter.reportErrorForNode(
@@ -4077,7 +4075,7 @@
///
/// See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT],
/// [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and
- /// [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT].
+ /// [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT].
void _checkForUndefinedConstructorInInitializerImplicit(
ConstructorDeclaration constructor) {
if (_enclosingClass == null) {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 919a698..a136006 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -451,10 +451,7 @@
/// Verify that the arguments in the given [argumentList] can be assigned to
/// their corresponding parameters.
///
- /// This method corresponds to
- /// [BestPracticesVerifier.checkForArgumentTypesNotAssignableInList].
- ///
- /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
+ /// See [CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
void checkForArgumentTypesNotAssignableInList(ArgumentList argumentList,
List<WhyNotPromotedGetter> whyNotPromotedList) {
var arguments = argumentList.arguments;
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index db4d362..5665fb5 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -25,12 +25,10 @@
var timerLinkingLinkingBundle = Stopwatch();
/// Note that AST units and tokens of [inputLibraries] will be damaged.
-///
-/// TODO(scheglov) deprecate `withInformative`.
LinkResult link(
LinkedElementFactory elementFactory,
List<LinkInputLibrary> inputLibraries, [
- bool? withInformative,
+ @Deprecated('Not used anymore') bool? withInformative,
]) {
var linker = Linker(elementFactory);
linker.link(inputLibraries);
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 456548e..74e80c2 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -15,8 +15,8 @@
final AnalysisContextImpl analysisContext;
final AnalysisSessionImpl analysisSession;
final Reference rootReference;
- final Map<String, LibraryReader> libraryReaders = {};
- final _exportsOfLibrary = <String, List<Reference>>{};
+ final Map<String, LibraryReader> _libraryReaders = {};
+ final Map<String, List<Reference>> _exportsOfLibrary = {};
bool isApplyingInformativeData = false;
@@ -34,7 +34,7 @@
}
bool get hasDartCore {
- return libraryReaders.containsKey('dart:core');
+ return _libraryReaders.containsKey('dart:core');
}
void addBundle(BundleReader bundle) {
@@ -42,7 +42,7 @@
}
void addLibraries(Map<String, LibraryReader> libraries) {
- libraryReaders.addAll(libraries);
+ _libraryReaders.addAll(libraries);
}
Namespace buildExportNamespace(Uri uri) {
@@ -73,11 +73,11 @@
// The URI cannot be resolved, we don't know the library.
if (librarySource == null) return null;
- var reader = libraryReaders[uriStr];
+ var reader = _libraryReaders[uriStr];
if (reader == null) {
throw ArgumentError(
'Missing library: $uriStr\n'
- 'Available libraries: ${libraryReaders.keys.toList()}',
+ 'Available libraries: ${_libraryReaders.keys.toList()}',
);
}
@@ -154,14 +154,14 @@
if (exports != null) return exports;
// TODO(scheglov) Use [setExportsOfLibrary] instead
- var library = libraryReaders[uriStr];
+ var library = _libraryReaders[uriStr];
if (library == null) return const [];
return library.exports;
}
bool hasLibrary(String uriStr) {
- return libraryReaders[uriStr] != null;
+ return _libraryReaders[uriStr] != null;
}
/// We are about to discard this factory, mark all libraries invalid.
@@ -195,7 +195,7 @@
void removeLibraries(Set<String> uriStrSet) {
for (var uriStr in uriStrSet) {
_exportsOfLibrary.remove(uriStr);
- libraryReaders.remove(uriStr);
+ _libraryReaders.remove(uriStr);
var libraryReference = rootReference.removeChild(uriStr);
_invalidateLibrary(libraryReference);
}
@@ -212,10 +212,10 @@
'${uriStrSet.toList()}',
);
}
- if (libraryReaders.isNotEmpty) {
+ if (_libraryReaders.isNotEmpty) {
throw StateError(
'Expected to link dart:core and dart:async first: '
- '${libraryReaders.keys.toList()}',
+ '${_libraryReaders.keys.toList()}',
);
}
analysisContext.clearTypeProvider();
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 006dde9..374580cfb 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -9,15 +9,14 @@
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:pub_semver/src/version.dart';
+import 'package:meta/meta.dart';
+@Deprecated('Use createMockSdk() instead')
const String sdkRoot = '/sdk';
-final MockSdkLibrary _LIB_ASYNC = MockSdkLibrary([
+final MockSdkLibrary _LIB_ASYNC = MockSdkLibrary('async', [
MockSdkLibraryUnit(
- 'dart:async',
- '$sdkRoot/lib/async/async.dart',
+ 'async/async.dart',
'''
library dart.async;
@@ -76,8 +75,7 @@
''',
),
MockSdkLibraryUnit(
- 'dart:async/stream.dart',
- '$sdkRoot/lib/async/stream.dart',
+ 'async/stream.dart',
r'''
part of dart.async;
@@ -114,10 +112,9 @@
)
]);
-final MockSdkLibrary _LIB_ASYNC2 = MockSdkLibrary([
+final MockSdkLibrary _LIB_ASYNC2 = MockSdkLibrary('async2', [
MockSdkLibraryUnit(
- 'dart:async2',
- '$sdkRoot/lib/async2/async2.dart',
+ 'async2/async2.dart',
'''
library dart.async2;
@@ -126,10 +123,9 @@
)
]);
-final MockSdkLibrary _LIB_COLLECTION = MockSdkLibrary([
+final MockSdkLibrary _LIB_COLLECTION = MockSdkLibrary('collection', [
MockSdkLibraryUnit(
- 'dart:collection',
- '$sdkRoot/lib/collection/collection.dart',
+ 'collection/collection.dart',
'''
library dart.collection;
@@ -222,10 +218,10 @@
]);
final MockSdkLibrary _LIB_CONVERT = MockSdkLibrary(
+ 'convert',
[
MockSdkLibraryUnit(
- 'dart:convert',
- '$sdkRoot/lib/convert/convert.dart',
+ 'convert/convert.dart',
'''
library dart.convert;
@@ -253,10 +249,10 @@
);
final MockSdkLibrary _LIB_CORE = MockSdkLibrary(
+ 'core',
[
MockSdkLibraryUnit(
- 'dart:core',
- '$sdkRoot/lib/core/core.dart',
+ 'core/core.dart',
'''
library dart.core;
@@ -655,10 +651,9 @@
],
);
-final MockSdkLibrary _LIB_FFI = MockSdkLibrary([
+final MockSdkLibrary _LIB_FFI = MockSdkLibrary('ffi', [
MockSdkLibraryUnit(
- 'dart:ffi',
- '$sdkRoot/lib/ffi/ffi.dart',
+ 'ffi/ffi.dart',
'''
library dart.ffi;
@@ -799,10 +794,10 @@
]);
final MockSdkLibrary _LIB_HTML_DART2JS = MockSdkLibrary(
+ 'html',
[
MockSdkLibraryUnit(
- 'dart:html',
- '$sdkRoot/lib/html/dart2js/html_dart2js.dart',
+ 'html/dart2js/html_dart2js.dart',
'''
library dart.dom.html;
@@ -1008,10 +1003,10 @@
);
final MockSdkLibrary _LIB_INTERCEPTORS = MockSdkLibrary(
+ '_interceptors',
[
MockSdkLibraryUnit(
- 'dart:_interceptors',
- '$sdkRoot/lib/_internal/js_runtime/lib/interceptors.dart',
+ '_internal/js_runtime/lib/interceptors.dart',
'''
library dart._interceptors;
''',
@@ -1020,10 +1015,10 @@
);
final MockSdkLibrary _LIB_INTERNAL = MockSdkLibrary(
+ '_internal',
[
MockSdkLibraryUnit(
- 'dart:_internal',
- '$sdkRoot/lib/_internal/internal.dart',
+ '_internal/internal.dart',
'''
library dart._internal;
@@ -1040,13 +1035,14 @@
''',
)
],
+ categories: '',
);
final MockSdkLibrary _LIB_IO = MockSdkLibrary(
+ 'io',
[
MockSdkLibraryUnit(
- 'dart:io',
- '$sdkRoot/lib/io/io.dart',
+ 'io/io.dart',
'''
library dart.io;
@@ -1129,10 +1125,9 @@
],
);
-final MockSdkLibrary _LIB_ISOLATE = MockSdkLibrary([
+final MockSdkLibrary _LIB_ISOLATE = MockSdkLibrary('isolate', [
MockSdkLibraryUnit(
- 'dart:isolate',
- '$sdkRoot/lib/isolate/isolate.dart',
+ 'isolate.dart',
'''
library dart.isolate;
@@ -1160,10 +1155,10 @@
]);
final MockSdkLibrary _LIB_MATH = MockSdkLibrary(
+ 'math',
[
MockSdkLibraryUnit(
- 'dart:math',
- '$sdkRoot/lib/math/math.dart',
+ 'math/math.dart',
'''
library dart.math;
@@ -1206,213 +1201,111 @@
_LIB_INTERNAL,
];
-final Map<String, String> _librariesDartEntries = {
- 'async': 'const LibraryInfo("async/async.dart")',
- 'collection': 'const LibraryInfo("collection/collection.dart")',
- 'convert': 'const LibraryInfo("convert/convert.dart")',
- 'core': 'const LibraryInfo("core/core.dart")',
- 'ffi': 'const LibraryInfo("ffi/ffi.dart")',
- 'html': 'const LibraryInfo("html/dart2js/html_dart2js.dart")',
- 'io': 'const LibraryInfo("io/io.dart")',
- 'isolate': 'const LibraryInfo("isolate/isolate.dart")',
- 'math': 'const LibraryInfo("math/math.dart")',
- '_internal': 'const LibraryInfo("_internal/internal.dart", categories: "")',
-};
+/// Create a reduced approximation of Dart SDK in the [path].
+///
+/// It has enough libraries to run analyzer and analysis server tests,
+/// but some libraries, classes, and methods are missing.
+void createMockSdk({
+ required MemoryResourceProvider resourceProvider,
+ required Folder root,
+ @internal List<MockSdkLibrary> additionalLibraries = const [],
+}) {
+ var lib = root.getChildAssumingFolder('lib');
+ var libInternal = lib.getChildAssumingFolder('_internal');
-class MockSdk implements DartSdk {
- final MemoryResourceProvider resourceProvider;
+ var currentVersion = ExperimentStatus.currentVersion;
+ var currentVersionStr = '${currentVersion.major}.${currentVersion.minor}.0';
+ root.getChildAssumingFile('version').writeAsStringSync(currentVersionStr);
- final Map<String, String> uriMap = {};
+ var librariesBuffer = StringBuffer();
+ librariesBuffer.writeln(
+ 'const Map<String, LibraryInfo> libraries = const {',
+ );
- @override
- final List<MockSdkLibrary> sdkLibraries = [];
-
- late final File _versionFile;
-
- /// Optional [additionalLibraries] should have unique URIs, and paths in
- /// their units are relative (will be put into `sdkRoot/lib`).
- ///
- /// [nullSafePackages], if supplied, is a list of packages names that should
- /// be included in the null safety allow list.
- ///
- /// [sdkVersion], if supplied will override the version stored in the mock
- /// SDK's `version` file.
- MockSdk({
- required this.resourceProvider,
- List<MockSdkLibrary> additionalLibraries = const [],
- List<String> nullSafePackages = const [],
- String? sdkVersion,
- }) {
- sdkVersion ??= '${ExperimentStatus.currentVersion.major}.'
- '${ExperimentStatus.currentVersion.minor}.0';
- _versionFile = resourceProvider
- .getFolder(resourceProvider.convertPath(sdkRoot))
- .getChildAssumingFile('version');
- _versionFile.writeAsStringSync(sdkVersion);
-
- for (MockSdkLibrary library in _LIBRARIES) {
- var convertedLibrary = library._toProvider(resourceProvider);
- sdkLibraries.add(convertedLibrary);
+ for (var library in [..._LIBRARIES, ...additionalLibraries]) {
+ for (var unit in library.units) {
+ var file = lib.getChildAssumingFile(unit.path);
+ file.writeAsStringSync(unit.content);
}
- for (MockSdkLibrary library in additionalLibraries) {
- sdkLibraries.add(
- MockSdkLibrary(
- library.units.map(
- (unit) {
- var pathContext = resourceProvider.pathContext;
- var absoluteUri = pathContext.join(sdkRoot, 'lib', unit.path);
- return MockSdkLibraryUnit(
- unit.uriStr,
- resourceProvider.convertPath(absoluteUri),
- unit.content,
- );
- },
- ).toList(),
- ),
- );
- }
-
- for (MockSdkLibrary library in sdkLibraries) {
- for (var unit in library.units) {
- resourceProvider.newFile(unit.path, unit.content);
- uriMap[unit.uriStr] = unit.path;
- }
- }
-
- {
- var buffer = StringBuffer();
- buffer.writeln('const Map<String, LibraryInfo> libraries = const {');
- for (var e in _librariesDartEntries.entries) {
- buffer.writeln('"${e.key}": ${e.value},');
- }
- for (var library in additionalLibraries) {
- for (var unit in library.units) {
- var name = unit.uriStr.substring(5);
- var libraryInfo = 'const LibraryInfo("${unit.path}")';
- buffer.writeln('"$name": $libraryInfo,');
- }
- }
- buffer.writeln('};');
- resourceProvider.newFile(
- resourceProvider.convertPath(
- '$sdkRoot/lib/_internal/sdk_library_metadata/lib/libraries.dart',
- ),
- buffer.toString(),
- );
- }
-
- resourceProvider.newFile(
- resourceProvider.convertPath(
- '$sdkRoot/lib/_internal/allowed_experiments.json',
- ),
- json.encode({
- 'version': 1,
- 'experimentSets': {
- 'nullSafety': ['non-nullable']
- },
- 'sdk': {
- 'default': {'experimentSet': 'nullSafety'}
- },
- if (nullSafePackages.isNotEmpty)
- 'packages': {
- for (var package in nullSafePackages)
- package: {'experimentSet': 'nullSafety'}
- }
- }),
+ librariesBuffer.writeln(
+ ' "${library.name}": const LibraryInfo("${library.path}", '
+ 'categories: "${library.categories}"),',
);
}
+ librariesBuffer.writeln('};');
+ libInternal
+ .getChildAssumingFile('sdk_library_metadata/lib/libraries.dart')
+ .writeAsStringSync('$librariesBuffer');
+
+ libInternal
+ .getChildAssumingFile('allowed_experiments.json')
+ .writeAsStringSync(
+ json.encode({
+ 'version': 1,
+ 'experimentSets': {
+ 'sdkExperiments': <String>[],
+ 'nullSafety': ['non-nullable']
+ },
+ 'sdk': {
+ 'default': {'experimentSet': 'sdkExperiments'},
+ },
+ 'packages': <String, Object>{},
+ }),
+ );
+}
+
+@Deprecated('Use createMockSdk() and FolderBasedDartSdk instead.')
+class MockSdk extends FolderBasedDartSdk {
+ /// Optional [additionalLibraries] should have unique URIs, and paths in
+ /// their units are relative (will be put into `sdkRoot/lib`).
+ factory MockSdk({
+ required MemoryResourceProvider resourceProvider,
+ List<MockSdkLibrary> additionalLibraries = const [],
+ }) {
+ var sdkDirectory = resourceProvider.getFolder(
+ resourceProvider.convertPath(sdkRoot),
+ );
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkDirectory,
+ additionalLibraries: additionalLibraries,
+ );
+ return MockSdk._(resourceProvider, sdkDirectory);
+ }
+
+ /// Initialize a newly created SDK to represent the Dart SDK installed in the
+ /// [sdkDirectory].
+ MockSdk._(ResourceProvider resourceProvider, Folder sdkDirectory)
+ : super(resourceProvider, sdkDirectory);
+
@override
- String? get allowedExperimentsJson {
- try {
- var convertedRoot = resourceProvider.convertPath(sdkRoot);
- return resourceProvider
- .getFolder(convertedRoot)
- .getChildAssumingFolder('lib')
- .getChildAssumingFolder('_internal')
- .getChildAssumingFile('allowed_experiments.json')
- .readAsStringSync();
- } catch (_) {
- return null;
- }
+ MemoryResourceProvider get resourceProvider {
+ return super.resourceProvider as MemoryResourceProvider;
}
@override
- Version get languageVersion {
- var sdkVersionStr = _versionFile.readAsStringSync();
- return languageVersionFromSdkVersion(sdkVersionStr);
- }
-
- @override
- String get sdkVersion => throw UnimplementedError();
-
- @override
- List<String> get uris =>
- sdkLibraries.map((SdkLibrary library) => library.shortName).toList();
-
- @override
- Source? fromFileUri(Uri uri) {
- String filePath = resourceProvider.pathContext.fromUri(uri);
- if (!filePath.startsWith(resourceProvider.convertPath('$sdkRoot/lib/'))) {
- return null;
- }
- for (SdkLibrary library in sdkLibraries) {
- String libraryPath = library.path;
- if (filePath == libraryPath) {
- try {
- var file = resourceProvider.getFile(filePath);
- Uri dartUri = Uri.parse(library.shortName);
- return file.createSource(dartUri);
- } catch (exception) {
- return null;
- }
- }
- String libraryRootPath =
- resourceProvider.pathContext.dirname(libraryPath) +
- resourceProvider.pathContext.separator;
- if (filePath.startsWith(libraryRootPath)) {
- String pathInLibrary = filePath.substring(libraryRootPath.length);
- String uriStr = '${library.shortName}/$pathInLibrary';
- try {
- var file = resourceProvider.getFile(filePath);
- Uri dartUri = Uri.parse(uriStr);
- return file.createSource(dartUri);
- } catch (exception) {
- return null;
- }
- }
- }
- return null;
- }
-
- @override
- SdkLibrary? getSdkLibrary(String dartUri) {
- for (SdkLibrary library in _LIBRARIES) {
- if (library.shortName == dartUri) {
+ List<SdkLibraryImpl> get sdkLibraries {
+ return super.sdkLibraries.map((library) {
+ var pathContext = resourceProvider.pathContext;
+ var path = library.path;
+ if (pathContext.isAbsolute(path)) {
return library;
}
- }
- return null;
- }
-
- @override
- Source? mapDartUri(String dartUri) {
- var path = uriMap[dartUri];
- if (path != null) {
- var file = resourceProvider.getFile(path);
- Uri uri = Uri(scheme: 'dart', path: dartUri.substring(5));
- return file.createSource(uri);
- }
- // If we reach here then we tried to use a dartUri that's not in the
- // table above.
- return null;
+ return SdkLibraryImpl(library.shortName)
+ ..path = pathContext.join(directory.path, 'lib', path)
+ ..category = library.category
+ ..documented = library.isDocumented;
+ }).toList();
}
}
class MockSdkLibrary implements SdkLibrary {
+ final String name;
+ final String categories;
final List<MockSdkLibraryUnit> units;
- MockSdkLibrary(this.units);
+ MockSdkLibrary(this.name, this.units, {this.categories = 'Shared'});
@override
String get category => throw UnimplementedError();
@@ -1439,27 +1332,12 @@
String get path => units[0].path;
@override
- String get shortName => units[0].uriStr;
-
- MockSdkLibrary _toProvider(MemoryResourceProvider provider) {
- return MockSdkLibrary(
- units.map((unit) => unit._toProvider(provider)).toList(),
- );
- }
+ String get shortName => 'dart:$name';
}
class MockSdkLibraryUnit {
- final String uriStr;
final String path;
final String content;
- MockSdkLibraryUnit(this.uriStr, this.path, this.content);
-
- MockSdkLibraryUnit _toProvider(MemoryResourceProvider provider) {
- return MockSdkLibraryUnit(
- uriStr,
- provider.convertPath(path),
- content,
- );
- }
+ MockSdkLibraryUnit(this.path, this.content);
}
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 2f331e2..b496a4f 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -305,14 +305,13 @@
export 'b.dart' hide C;
```
AMBIGUOUS_EXTENSION_MEMBER_ACCESS:
- problemMessage: "A member named '{0}' is defined in extensions {1}, and none are more specific."
+ problemMessage: "A member named '{0}' is defined in {1}, and none are more specific."
correctionMessage: Try using an extension override to specify the extension you want to be chosen.
hasPublishedDocs: true
comment: |-
Parameters:
0: the name of the member
- 1: the name of the first declaring extension
- 2: the name of the second declaring extension
+ 1: the names of the declaring extensions
documentation: |-
#### Description
@@ -3717,13 +3716,12 @@
var x = E.m();
```
EXTENSION_CONFLICTING_STATIC_AND_INSTANCE:
- problemMessage: "Extension '{0}' can't define static member '{1}' and an instance member with the same name."
+ problemMessage: "An extension can't define static member '{0}' and an instance member with the same name."
correctionMessage: "Try renaming the member to a name that doesn't conflict."
hasPublishedDocs: true
comment: |-
Parameters:
- 0: the name of the extension defining the conflicting member
- 1: the name of the conflicting static member
+ 0: the name of the conflicting static member
documentation: |-
#### Description
@@ -5543,6 +5541,14 @@
static int zero = 0;
}
```
+ INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION:
+ sharedName: INSTANCE_ACCESS_TO_STATIC_MEMBER
+ problemMessage: "The static {1} '{0}' can't be accessed through an instance."
+ hasPublishedDocs: true
+ comment: |-
+ Parameters:
+ 0: the name of the static member
+ 1: the kind of the static member (field, getter, setter, or method)
INSTANCE_MEMBER_ACCESS_FROM_FACTORY:
problemMessage: "Instance members can't be accessed from a factory constructor."
correctionMessage: Try removing the reference to the instance member.
@@ -15207,7 +15213,7 @@
void f() => someFunction();
```
INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION:
- problemMessage: "The declaration '{0}' is annotated with 'visibleForOverriding'. Because '{0}' isn't an interface member that could be overridden, the annotation is meaningless."
+ problemMessage: "The annotation 'visibleForOverriding' can only be applied to a public instance member that can be overridden."
hasPublishedDocs: true
comment: No parameters.
documentation: |-
diff --git a/pkg/analyzer/test/generated/sdk_test.dart b/pkg/analyzer/test/generated/sdk_test.dart
index a5b3fef..c274178 100644
--- a/pkg/analyzer/test/generated/sdk_test.dart
+++ b/pkg/analyzer/test/generated/sdk_test.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -22,7 +21,7 @@
expect(manager.anySdk, isNull);
SdkDescription description = SdkDescription('/c/d');
- DartSdk sdk = MockSdk(resourceProvider: resourceProvider);
+ DartSdk sdk = _DartSdkMock();
manager.getSdk(description, () => sdk);
expect(manager.anySdk, same(sdk));
@@ -32,12 +31,12 @@
DartSdkManager manager = DartSdkManager('/a/b/c');
SdkDescription description1 = SdkDescription('/c/d');
- DartSdk sdk1 = MockSdk(resourceProvider: resourceProvider);
+ DartSdk sdk1 = _DartSdkMock();
DartSdk result1 = manager.getSdk(description1, () => sdk1);
expect(result1, same(sdk1));
SdkDescription description2 = SdkDescription('/e/f');
- DartSdk sdk2 = MockSdk(resourceProvider: resourceProvider);
+ DartSdk sdk2 = _DartSdkMock();
DartSdk result2 = manager.getSdk(description2, () => sdk2);
expect(result2, same(sdk2));
@@ -49,7 +48,7 @@
DartSdkManager manager = DartSdkManager('/a/b/c');
SdkDescription description = SdkDescription('/c/d');
- DartSdk sdk = MockSdk(resourceProvider: resourceProvider);
+ DartSdk sdk = _DartSdkMock();
DartSdk result = manager.getSdk(description, () => sdk);
expect(result, same(sdk));
@@ -82,3 +81,8 @@
expect(left == right, isTrue);
}
}
+
+class _DartSdkMock implements DartSdk {
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart b/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
index d532b29..e8c8c62 100644
--- a/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.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/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
@@ -19,8 +20,13 @@
@reflectiveTest
class AnalysisContextCollectionTest with ResourceProviderMixin {
+ Folder get sdkRoot => newFolder('/sdk');
+
void setUp() {
- MockSdk(resourceProvider: resourceProvider);
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
registerLintRules();
}
@@ -168,7 +174,7 @@
return AnalysisContextCollectionImpl(
resourceProvider: resourceProvider,
includedPaths: includedPaths,
- sdkPath: convertPath(sdkRoot),
+ sdkPath: sdkRoot.path,
);
}
}
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index 536922f..7f3d1cb 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/status.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -127,7 +128,13 @@
}
void setUp() {
- sdk = MockSdk(resourceProvider: resourceProvider);
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+ sdk = FolderBasedDartSdk(resourceProvider, sdkRoot);
+
testProject = convertPath('/test');
testFile = convertPath('/test/lib/test.dart');
logger = PerformanceLog(logBuffer);
diff --git a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
index 44a7634..17144c0 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
@@ -35,6 +35,8 @@
late final ContextBuilderImpl contextBuilder;
late final ContextRoot contextRoot;
+ Folder get sdkRoot => newFolder('/sdk');
+
void assertEquals(DeclaredVariables actual, DeclaredVariables expected) {
Iterable<String> actualNames = actual.variableNames;
Iterable<String> expectedNames = expected.variableNames;
@@ -45,6 +47,11 @@
}
void setUp() {
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+
var folder = newFolder('/home/test');
contextBuilder = ContextBuilderImpl(resourceProvider: resourceProvider);
var workspace = BasicWorkspace.find(resourceProvider, {}, folder.path);
@@ -52,8 +59,6 @@
}
void test_analysisOptions_invalid() {
- MockSdk(resourceProvider: resourceProvider);
-
var projectPath = convertPath('/home/test');
newAnalysisOptionsYamlFile(projectPath, content: ';');
@@ -63,8 +68,6 @@
}
void test_analysisOptions_languageOptions() {
- MockSdk(resourceProvider: resourceProvider);
-
var projectPath = convertPath('/home/test');
newAnalysisOptionsYamlFile(
projectPath,
@@ -82,8 +85,6 @@
}
void test_analysisOptions_sdkVersionConstraint_hasPubspec_hasSdk() {
- MockSdk(resourceProvider: resourceProvider);
-
var projectPath = convertPath('/home/test');
newPubspecYamlFile(projectPath, '''
environment:
@@ -96,8 +97,6 @@
}
void test_analysisOptions_sdkVersionConstraint_noPubspec() {
- MockSdk(resourceProvider: resourceProvider);
-
var projectPath = convertPath('/home/test');
newFile('$projectPath/lib/a.dart');
@@ -107,13 +106,12 @@
}
test_createContext_declaredVariables() {
- MockSdk(resourceProvider: resourceProvider);
DeclaredVariables declaredVariables =
DeclaredVariables.fromMap({'foo': 'true'});
var context = contextBuilder.createContext(
contextRoot: contextRoot,
declaredVariables: declaredVariables,
- sdkPath: resourceProvider.convertPath(sdkRoot),
+ sdkPath: sdkRoot.path,
);
expect(context.analysisOptions, isNotNull);
expect(context.contextRoot, contextRoot);
@@ -123,54 +121,51 @@
test_createContext_declaredVariables_sdkPath() {
DeclaredVariables declaredVariables =
DeclaredVariables.fromMap({'bar': 'true'});
- MockSdk sdk = MockSdk(resourceProvider: resourceProvider);
var context = contextBuilder.createContext(
contextRoot: contextRoot,
declaredVariables: declaredVariables,
- sdkPath: resourceProvider.convertPath(sdkRoot),
+ sdkPath: sdkRoot.path,
);
expect(context.analysisOptions, isNotNull);
expect(context.contextRoot, contextRoot);
assertEquals(context.driver.declaredVariables, declaredVariables);
- expect(context.driver.sourceFactory.dartSdk!.mapDartUri('dart:core'),
- sdk.mapDartUri('dart:core'));
+ expect(
+ context.driver.sourceFactory.dartSdk!.mapDartUri('dart:core')!.fullName,
+ sdkRoot.getChildAssumingFile('lib/core/core.dart').path,
+ );
}
test_createContext_defaults() {
- MockSdk(resourceProvider: resourceProvider);
AnalysisContext context = contextBuilder.createContext(
contextRoot: contextRoot,
- sdkPath: resourceProvider.convertPath(sdkRoot),
+ sdkPath: sdkRoot.path,
);
expect(context.analysisOptions, isNotNull);
expect(context.contextRoot, contextRoot);
}
test_createContext_sdkPath() {
- MockSdk sdk = MockSdk(resourceProvider: resourceProvider);
var context = contextBuilder.createContext(
contextRoot: contextRoot,
- sdkPath: resourceProvider.convertPath(sdkRoot),
+ sdkPath: sdkRoot.path,
);
expect(context.analysisOptions, isNotNull);
expect(context.contextRoot, contextRoot);
- expect(context.driver.sourceFactory.dartSdk!.mapDartUri('dart:core'),
- sdk.mapDartUri('dart:core'));
+ expect(
+ context.driver.sourceFactory.dartSdk!.mapDartUri('dart:core')!.fullName,
+ sdkRoot.getChildAssumingFile('lib/core/core.dart').path,
+ );
}
test_createContext_sdkRoot() {
- MockSdk(resourceProvider: resourceProvider);
var context = contextBuilder.createContext(
- contextRoot: contextRoot,
- sdkPath: resourceProvider.convertPath(sdkRoot));
+ contextRoot: contextRoot, sdkPath: sdkRoot.path);
expect(context.analysisOptions, isNotNull);
expect(context.contextRoot, contextRoot);
- expect(context.sdkRoot?.path, resourceProvider.convertPath(sdkRoot));
+ expect(context.sdkRoot, sdkRoot);
}
void test_sourceFactory_bazelWorkspace() {
- MockSdk(resourceProvider: resourceProvider);
-
var projectPath = convertPath('/workspace/my/module');
newFile('/workspace/WORKSPACE');
newFolder('/workspace/bazel-bin');
@@ -190,8 +185,6 @@
}
void test_sourceFactory_pubWorkspace() {
- MockSdk(resourceProvider: resourceProvider);
-
var projectPath = convertPath('/home/my');
newFile('/home/my/pubspec.yaml');
@@ -218,7 +211,7 @@
resourceProvider: resourceProvider,
).createContext(
contextRoot: roots.single,
- sdkPath: convertPath(sdkRoot),
+ sdkPath: sdkRoot.path,
);
}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index f47fff4..59cdc3b 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -15,10 +16,9 @@
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/constant/evaluation.dart';
import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
-import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
@@ -51,7 +51,6 @@
@reflectiveTest
class AnalysisDriverSchedulerTest with ResourceProviderMixin {
- late DartSdk sdk;
final ByteStore byteStore = MemoryByteStore();
final StringBuffer logBuffer = StringBuffer();
@@ -61,8 +60,10 @@
final List<AnalysisResultWithErrors> allResults = [];
+ Folder get sdkRoot => newFolder('/sdk');
+
AnalysisDriver newDriver() {
- sdk = MockSdk(resourceProvider: resourceProvider);
+ var sdk = FolderBasedDartSdk(resourceProvider, sdkRoot);
AnalysisDriver driver = AnalysisDriver.tmp1(
scheduler: scheduler,
logger: logger,
@@ -83,7 +84,10 @@
}
void setUp() {
- sdk = MockSdk(resourceProvider: resourceProvider);
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
logger = PerformanceLog(logBuffer);
scheduler = AnalysisDriverScheduler(logger);
scheduler.start();
diff --git a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
index 86df8d9..dfcbe51 100644
--- a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
@@ -9,6 +9,7 @@
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/analysis/experiments_impl.dart';
import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
@@ -25,14 +26,19 @@
@reflectiveTest
class FeatureSetProviderTest with ResourceProviderMixin {
- late final MockSdk mockSdk;
late SourceFactory sourceFactory;
late FeatureSetProvider provider;
+ Folder get sdkRoot => newFolder('/sdk');
+
void setUp() {
newFile('/test/lib/test.dart', content: '');
- mockSdk = MockSdk(resourceProvider: resourceProvider);
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+
_createSourceFactory();
}
@@ -430,7 +436,9 @@
resolvers.add(packageUriResolver);
}
resolvers.addAll([
- DartUriResolver(mockSdk),
+ DartUriResolver(
+ FolderBasedDartSdk(resourceProvider, sdkRoot),
+ ),
ResourceUriResolver(resourceProvider),
]);
sourceFactory = SourceFactoryImpl(resolvers);
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index a4da5db..b298989 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -16,6 +16,7 @@
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/library_graph.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart'
show AnalysisOptions, AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart';
@@ -37,8 +38,6 @@
@reflectiveTest
class FileSystemStateTest with ResourceProviderMixin {
- late final MockSdk sdk;
-
final ByteStore byteStore = MemoryByteStore();
final FileContentOverlay contentOverlay = FileContentOverlay();
@@ -52,7 +51,13 @@
void setUp() {
logger = PerformanceLog(logBuffer);
- sdk = MockSdk(resourceProvider: resourceProvider);
+
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+ var sdk = FolderBasedDartSdk(resourceProvider, sdkRoot);
var packageMap = <String, List<Folder>>{
'aaa': [getFolder('/aaa/lib')],
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index a188ec0..564c216 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -141,7 +141,11 @@
late final String testPath;
void setUp() {
- MockSdk(resourceProvider: resourceProvider);
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
testContextPath = newFolder('/home/test').path;
aaaContextPath = newFolder('/home/aaa').path;
@@ -154,7 +158,7 @@
contextCollection = AnalysisContextCollectionImpl(
includedPaths: [testContextPath, aaaContextPath, bbbContextPath],
resourceProvider: resourceProvider,
- sdkPath: convertPath(sdkRoot),
+ sdkPath: sdkRoot.path,
);
context = contextCollection.contextFor(testContextPath);
session = context.currentSession as AnalysisSessionImpl;
diff --git a/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart b/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart
index f8d8c23..2b229fc 100644
--- a/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart
@@ -8,6 +8,7 @@
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/uri_converter.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
@@ -30,8 +31,16 @@
Folder barFolder = newFolder('/packages/bar/lib');
Folder fooFolder = newFolder('/packages/foo/lib');
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+
SourceFactory sourceFactory = SourceFactory([
- DartUriResolver(MockSdk(resourceProvider: resourceProvider)),
+ DartUriResolver(
+ FolderBasedDartSdk(resourceProvider, sdkRoot),
+ ),
PackageMapUriResolver(resourceProvider, {
'foo': [fooFolder],
'bar': [barFolder],
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index d756acf..24b6f96 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -169,6 +169,18 @@
);
}
+ test_identical_functionReference_explicitTypeArgs_sameElement_runtimeTypeEquality() async {
+ await resolveTestCode('''
+import 'dart:async';
+void foo<T>(T a) {}
+const g = identical(foo<Object>, foo<FutureOr<Object>>);
+''');
+ expect(
+ _evaluateConstant('g'),
+ _boolValue(true),
+ );
+ }
+
test_identical_functionReference_implicitTypeArgs_differentTypes() async {
await resolveTestCode('''
void foo<T>(T a) {}
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index 3c85527..5836465 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -5,9 +5,11 @@
import 'dart:convert';
import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
import 'package:analyzer/src/dart/micro/resolve_file.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/test_utilities/find_element.dart';
import 'package:analyzer/src/test_utilities/find_node.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
@@ -27,10 +29,11 @@
final StringBuffer logBuffer = StringBuffer();
late PerformanceLog logger;
- late MockSdk sdk;
late FileResolver fileResolver;
+ Folder get sdkRoot => newFolder('/sdk');
+
@override
void addTestFile(String content) {
newFile(_testFile, content: content);
@@ -50,7 +53,10 @@
logger: logger,
resourceProvider: resourceProvider,
byteStore: byteStore,
- sourceFactory: workspace.createSourceFactory(sdk, null),
+ sourceFactory: workspace.createSourceFactory(
+ FolderBasedDartSdk(resourceProvider, sdkRoot),
+ null,
+ ),
getFileDigest: (String path) => _getDigest(path),
workspace: workspace,
prefetchFiles: null,
@@ -82,7 +88,10 @@
registerLintRules();
logger = PerformanceLog(logBuffer);
- sdk = MockSdk(resourceProvider: resourceProvider);
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
newFile('/workspace/WORKSPACE', content: '');
newFile('/workspace/dart/test/BUILD', content: '');
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 db0e26c..814951e 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -138,6 +138,8 @@
bool get retainDataForTesting => false;
+ Folder get sdkRoot => newFolder('/sdk');
+
void assertBasicWorkspaceFor(String path) {
var workspace = contextFor(path).contextRoot.workspace;
expect(workspace, TypeMatcher<BasicWorkspace>());
@@ -200,8 +202,9 @@
_lintRulesAreRegistered = true;
}
- MockSdk(
+ createMockSdk(
resourceProvider: resourceProvider,
+ root: sdkRoot,
additionalLibraries: additionalMockSdkLibraries,
);
}
@@ -234,7 +237,7 @@
includedPaths: collectionIncludedPaths.map(convertPath).toList(),
resourceProvider: resourceProvider,
retainDataForTesting: retainDataForTesting,
- sdkPath: convertPath('/sdk'),
+ sdkPath: sdkRoot.path,
);
verifyCreatedCollection();
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
index 73f39f6..8cc8ab5 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
@@ -71,8 +71,8 @@
extends PubPackageResolutionTest with WithoutNullSafetyMixin {
@override
List<MockSdkLibrary> get additionalMockSdkLibraries => [
- MockSdkLibrary([
- MockSdkLibraryUnit('dart:test1', 'test1/test1.dart', r'''
+ MockSdkLibrary('test1', [
+ MockSdkLibraryUnit('test1/test1.dart', r'''
extension E on Object {
int get a => 1;
}
@@ -80,8 +80,8 @@
class A {}
'''),
]),
- MockSdkLibrary([
- MockSdkLibraryUnit('dart:test2', 'test2/test2.dart', r'''
+ MockSdkLibrary('test2', [
+ MockSdkLibraryUnit('test2/test2.dart', r'''
extension E on Object {
int get a => 1;
}
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 0238785..1a2adbb 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -444,8 +444,11 @@
static void m<T>(T t) {}
}
''', [
- error(CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 40, 1,
- correctionContains: "extension '<unnamed>'"),
+ error(
+ CompileTimeErrorCode
+ .INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION,
+ 40,
+ 1),
]);
assertFunctionReference(findNode.functionReference('foo.m<int>;'),
diff --git a/pkg/analyzer/test/src/dart/resolution/language_version_test.dart b/pkg/analyzer/test/src/dart/resolution/language_version_test.dart
index d0681f0..a9868b6 100644
--- a/pkg/analyzer/test/src/dart/resolution/language_version_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/language_version_test.dart
@@ -4,7 +4,6 @@
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
@@ -258,7 +257,7 @@
void _newSdkExperimentsFile(String content) {
newFile(
- '$sdkRoot/lib/_internal/allowed_experiments.json',
+ '${sdkRoot.path}/lib/_internal/allowed_experiments.json',
content: content,
);
}
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
index 6355201..4c7e2f7 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
@@ -106,7 +106,7 @@
}
''', [
error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS, 129, 3,
- messageContains: "'E1' and 'E2'"),
+ messageContains: "in extension 'E1' and extension 'E2',"),
]);
}
@@ -131,7 +131,7 @@
}
''', [
error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS, 129, 3,
- messageContains: "'E1' and 'E2'"),
+ messageContains: "in extension 'E1' and extension 'E2',"),
]);
}
@@ -177,7 +177,7 @@
}
''', [
error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS, 129, 3,
- messageContains: "'E1' and 'E2'"),
+ messageContains: "in extension 'E1' and extension 'E2',"),
]);
}
@@ -192,7 +192,8 @@
}
''', [
error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS, 167, 3,
- messageContains: "'E1', 'E2', and 'E3'"),
+ messageContains:
+ "in extension 'E1', extension 'E2', and extension 'E3',"),
]);
}
@@ -346,4 +347,31 @@
assertTypeDynamic(access);
}
}
+
+ test_unnamed_extensions() async {
+ await assertErrorsInCode('''
+class A {}
+class B {}
+class C extends A implements B {}
+
+extension on List<A> {
+ int call() => 0;
+}
+
+extension on List<B> {
+ int call() => 0;
+}
+
+int f(List<C> x) => x();
+
+// Additional calls to avoid UNUSED_ELEMENT
+int g(List<A> x) => x();
+int h(List<B> x) => x();
+''', [
+ error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS, 167, 1,
+ messageContains:
+ "in unnamed extension on 'List<A>' and unnamed extension on "
+ "'List<B>',"),
+ ]);
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart b/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
index b85b744..1c98aba 100644
--- a/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
@@ -94,7 +94,7 @@
}
''', [
error(HintCode.UNUSED_FIELD, 35, 3),
- error(_errorCode, 35, 3, messageContains: "Extension '<unnamed>'"),
+ error(_errorCode, 35, 3),
error(HintCode.UNUSED_ELEMENT, 54, 3),
]);
}
@@ -106,7 +106,7 @@
void foo() {}
}
''', [
- error(_errorCode, 37, 3, messageContains: "Extension 'E'"),
+ error(_errorCode, 37, 3),
]);
}
@@ -128,7 +128,7 @@
int get foo => 0;
}
''', [
- error(_errorCode, 41, 3, messageContains: "Extension 'E'"),
+ error(_errorCode, 41, 3),
]);
}
@@ -140,7 +140,7 @@
}
''', [
error(HintCode.UNUSED_ELEMENT, 39, 3),
- error(_errorCode, 39, 3, messageContains: "Extension '<unnamed>'"),
+ error(_errorCode, 39, 3),
error(HintCode.UNUSED_ELEMENT, 59, 3),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/instance_access_to_static_member_test.dart b/pkg/analyzer/test/src/diagnostics/instance_access_to_static_member_test.dart
index 1142a36..620441c 100644
--- a/pkg/analyzer/test/src/diagnostics/instance_access_to_static_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/instance_access_to_static_member_test.dart
@@ -56,6 +56,31 @@
);
}
+ test_extension_getter_unnamed() async {
+ await assertErrorsInCode('''
+class C {}
+
+extension on C {
+ static int get a => 0;
+}
+
+C g(C c) => C();
+f(C c) {
+ g(c).a;
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION,
+ 90,
+ 1),
+ ]);
+ assertElement(
+ findNode.simple('a;'),
+ findElement.getter('a'),
+ );
+ }
+
test_extension_method() async {
await assertErrorsInCode('''
class C {}
@@ -89,8 +114,11 @@
c.a();
}
''', [
- error(CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 66, 1,
- correctionContains: "extension '<unnamed>'"),
+ error(
+ CompileTimeErrorCode
+ .INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION,
+ 66,
+ 1),
]);
assertElement(
findNode.methodInvocation('a();'),
@@ -187,8 +215,11 @@
a.m<int>;
}
''', [
- error(CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 55, 1,
- correctionContains: "extension '<unnamed>'"),
+ error(
+ CompileTimeErrorCode
+ .INSTANCE_ACCESS_TO_STATIC_MEMBER_OF_UNNAMED_EXTENSION,
+ 55,
+ 1),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart
index 9fa9832..ee5acb0 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart
@@ -27,10 +27,7 @@
import 'package:meta/meta.dart';
@visibleForOverriding
class C {}
-''', [
- error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21,
- messageContains: "The declaration 'C'")
- ]);
+''', [error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21)]);
}
test_invalid_constructor() async {
@@ -50,10 +47,7 @@
import 'package:meta/meta.dart';
@visibleForOverriding
extension on double {}
-''', [
- error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21,
- messageContains: "The declaration '<unnamed>'")
- ]);
+''', [error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21)]);
}
test_invalid_extensionMember() async {
@@ -104,7 +98,6 @@
@visibleForOverriding var a = 1, b;
''', [
error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21),
- error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_result_test.dart b/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
index 250479b..9d42982 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
@@ -611,6 +611,22 @@
''');
}
+ /// https://github.com/dart-lang/sdk/issues/47473
+ test_topLevelFunction_result_assigned_if() async {
+ await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+@useResult
+String foo() => '';
+
+String f(bool b) {
+ var f = '';
+ if (b) f = foo();
+ return f;
+}
+''');
+ }
+
test_topLevelFunction_result_optionNamedParam_unassigned_parameterDefined() async {
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
diff --git a/pkg/analyzer/test/src/services/available_declarations_test.dart b/pkg/analyzer/test/src/services/available_declarations_test.dart
index 5c4c599..17908dd 100644
--- a/pkg/analyzer/test/src/services/available_declarations_test.dart
+++ b/pkg/analyzer/test/src/services/available_declarations_test.dart
@@ -36,6 +36,8 @@
String get analysisOptionsPath =>
convertPath('/home/test/analysis_options.yaml');
+ Folder get sdkRoot => newFolder('/sdk');
+
void addDotPackagesDependency(String path, String name, String rootPath) {
var packagesFile = getFile(path);
@@ -68,7 +70,7 @@
analysisContextCollection = AnalysisContextCollectionImpl(
includedPaths: [convertPath('/home')],
resourceProvider: resourceProvider,
- sdkPath: convertPath('/sdk'),
+ sdkPath: sdkRoot.path,
);
var testPath = convertPath('/home/test');
@@ -99,7 +101,10 @@
}
setUp() {
- MockSdk(resourceProvider: resourceProvider);
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
newFolder('/home/test');
newDotPackagesFile('/home/test', content: '''
diff --git a/pkg/analyzer/test/src/source/source_resource_test.dart b/pkg/analyzer/test/src/source/source_resource_test.dart
index 0dc63d4..fb3b7b8a 100644
--- a/pkg/analyzer/test/src/source/source_resource_test.dart
+++ b/pkg/analyzer/test/src/source/source_resource_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/java_engine_io.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -162,6 +163,11 @@
}
DartSdk _createSdk() {
- return MockSdk(resourceProvider: resourceProvider);
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+ return FolderBasedDartSdk(resourceProvider, sdkRoot);
}
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index bc041e1..b1f2a75 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -84,7 +84,7 @@
Reference.root(),
);
- var sdkLinkResult = link(elementFactory, inputLibraries, true);
+ var sdkLinkResult = link(elementFactory, inputLibraries);
return _sdkBundle = _SdkBundle(
resolutionBytes: sdkLinkResult.resolutionBytes,
@@ -128,7 +128,7 @@
),
);
- var linkResult = link(elementFactory, inputLibraries, true);
+ var linkResult = link(elementFactory, inputLibraries);
if (!keepLinkingLibraries) {
elementFactory.removeBundle(
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 1a70ed9..60a785c 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -10,6 +10,7 @@
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/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
@@ -29,14 +30,19 @@
DeclaredVariables declaredVariables = DeclaredVariables();
late final SourceFactory sourceFactory;
- late final MockSdk sdk;
+ late final FolderBasedDartSdk sdk;
late String testFile;
late Source testSource;
Set<Source> otherLibrarySources = <Source>{};
AbstractResynthesizeTest() {
- sdk = MockSdk(resourceProvider: resourceProvider);
+ var sdkRoot = newFolder('/sdk');
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+ sdk = FolderBasedDartSdk(resourceProvider, sdkRoot);
sourceFactory = SourceFactory(
[
diff --git a/pkg/analyzer/test/util/id_testing_helper.dart b/pkg/analyzer/test/util/id_testing_helper.dart
index aeb8011..2024150 100644
--- a/pkg/analyzer/test/util/id_testing_helper.dart
+++ b/pkg/analyzer/test/util/id_testing_helper.dart
@@ -21,6 +21,7 @@
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/testing_data.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
@@ -128,7 +129,14 @@
resourceProvider.newFile(
resourceProvider.convertPath(testUri.path), entry.value);
}
- var sdk = MockSdk(resourceProvider: resourceProvider);
+ var sdkRoot = resourceProvider.newFolder(
+ resourceProvider.convertPath('/sdk'),
+ );
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
+ var sdk = FolderBasedDartSdk(resourceProvider, sdkRoot);
var logBuffer = StringBuffer();
var logger = PerformanceLog(logBuffer);
var scheduler = AnalysisDriverScheduler(logger);
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 7aefd9d..14c6b3e 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -398,7 +398,7 @@
### ambiguous_extension_member_access
-_A member named '{0}' is defined in extensions {1}, and none are more specific._
+_A member named '{0}' is defined in {1}, and none are more specific._
#### Description
@@ -4223,8 +4223,8 @@
### extension_conflicting_static_and_instance
-_Extension '{0}' can't define static member '{1}' and an instance member with
-the same name._
+_An extension can't define static member '{0}' and an instance member with the
+same name._
#### Description
@@ -7422,8 +7422,8 @@
### invalid_visible_for_overriding_annotation
-_The declaration '{0}' is annotated with 'visibleForOverriding'. Because '{0}'
-isn't an interface member that could be overridden, the annotation is meaningless._
+_The annotation 'visibleForOverriding' can only be applied to a public instance
+member that can be overridden._
#### Description
diff --git a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
index 777ccda..459974c 100644
--- a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
+++ b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
@@ -4,6 +4,7 @@
import 'dart:collection';
import 'dart:convert' hide JsonDecoder;
+import 'dart:math' as math;
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -28,6 +29,17 @@
/// If the invariants can't be preserved, then a [ConflictingEditException] is
/// thrown.
void addEditForSource(SourceFileEdit sourceFileEdit, SourceEdit sourceEdit) {
+ /// If the [leftEdit] and the [rightEdit] can be merged, then merge them.
+ SourceEdit? _merge(SourceEdit leftEdit, SourceEdit rightEdit) {
+ assert(leftEdit.offset <= rightEdit.offset);
+ if (leftEdit.isDeletion && rightEdit.isDeletion) {
+ var offset = leftEdit.offset;
+ var end = math.max(leftEdit.end, rightEdit.end);
+ return SourceEdit(offset, end - offset, '');
+ }
+ return null;
+ }
+
var edits = sourceFileEdit.edits;
var length = edits.length;
var index = 0;
@@ -39,7 +51,12 @@
// The [previousEdit] has an offset that is strictly greater than the offset
// of the [sourceEdit] so we only need to look at the end of the
// [sourceEdit] to know whether they overlap.
- if (sourceEdit.offset + sourceEdit.length > previousEdit.offset) {
+ if (sourceEdit.end > previousEdit.offset) {
+ var mergedEdit = _merge(sourceEdit, previousEdit);
+ if (mergedEdit != null) {
+ edits[index - 1] = mergedEdit;
+ return;
+ }
throw ConflictingEditException(
newEdit: sourceEdit, existingEdit: previousEdit);
}
@@ -54,7 +71,12 @@
if ((sourceEdit.offset == nextEdit.offset &&
sourceEdit.length > 0 &&
nextEdit.length > 0) ||
- nextEdit.offset + nextEdit.length > sourceEdit.offset) {
+ nextEdit.end > sourceEdit.offset) {
+ var mergedEdit = _merge(nextEdit, sourceEdit);
+ if (mergedEdit != null) {
+ edits[index] = mergedEdit;
+ return;
+ }
throw ConflictingEditException(
newEdit: sourceEdit, existingEdit: nextEdit);
}
@@ -468,3 +490,11 @@
/// the given [id], where the request was received at the given [requestTime].
Response toResponse(String id, int requestTime);
}
+
+extension SourceEditExtensions on SourceEdit {
+ /// Return `true` if this source edit represents a deletion.
+ bool get isDeletion => replacement.isEmpty;
+
+ /// Return `true` if this source edit represents an insertion.
+ bool get isInsertion => length == 0;
+}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
index a571f04..6ed22f9 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
@@ -17,6 +17,7 @@
defineReflectiveSuite(() {
defineReflectiveTests(ChangeBuilderImplTest);
defineReflectiveTests(EditBuilderImplTest);
+ defineReflectiveTests(FileEditBuilderImpl_ConflictingTest);
defineReflectiveTests(FileEditBuilderImplTest);
defineReflectiveTests(LinkedEditBuilderImplTest);
});
@@ -297,6 +298,229 @@
}
}
+/// Tests that are specifically targeted at the handling of conflicting edits.
+@reflectiveTest
+class FileEditBuilderImpl_ConflictingTest extends AbstractChangeBuilderTest {
+ String path = '/test.dart';
+
+ Matcher get hasConflict => throwsA(isA<ConflictingEditException>());
+
+ Future<void> test_deletion_deletion_adjacent_left() async {
+ var firstOffset = 30;
+ var firstLength = 5;
+ var secondOffset = 23;
+ var secondLength = 7;
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addDeletion(SourceRange(firstOffset, firstLength));
+ builder.addDeletion(SourceRange(secondOffset, secondLength));
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(2));
+ expect(edits[0].offset, firstOffset);
+ expect(edits[0].length, firstLength);
+ expect(edits[0].replacement, isEmpty);
+ expect(edits[1].offset, secondOffset);
+ expect(edits[1].length, secondLength);
+ expect(edits[1].replacement, isEmpty);
+ }
+
+ Future<void> test_deletion_deletion_adjacent_right() async {
+ var firstOffset = 23;
+ var firstLength = 7;
+ var secondOffset = 30;
+ var secondLength = 5;
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addDeletion(SourceRange(firstOffset, firstLength));
+ builder.addDeletion(SourceRange(secondOffset, secondLength));
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(2));
+ expect(edits[0].offset, secondOffset);
+ expect(edits[0].length, secondLength);
+ expect(edits[0].replacement, isEmpty);
+ expect(edits[1].offset, firstOffset);
+ expect(edits[1].length, firstLength);
+ expect(edits[1].replacement, isEmpty);
+ }
+
+ Future<void> test_deletion_deletion_overlap_left() async {
+ var firstOffset = 27;
+ var firstLength = 8;
+ var secondOffset = 23;
+ var secondLength = 7;
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addDeletion(SourceRange(firstOffset, firstLength));
+ builder.addDeletion(SourceRange(secondOffset, secondLength));
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(1));
+ expect(edits[0].offset, secondOffset);
+ expect(edits[0].length, firstOffset + firstLength - secondOffset);
+ expect(edits[0].replacement, isEmpty);
+ }
+
+ Future<void> test_deletion_deletion_overlap_right() async {
+ var firstOffset = 23;
+ var firstLength = 7;
+ var secondOffset = 27;
+ var secondLength = 8;
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addDeletion(SourceRange(firstOffset, firstLength));
+ builder.addDeletion(SourceRange(secondOffset, secondLength));
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(1));
+ expect(edits[0].offset, firstOffset);
+ expect(edits[0].length, secondOffset + secondLength - firstOffset);
+ expect(edits[0].replacement, isEmpty);
+ }
+
+ Future<void> test_deletion_insertion_adjacent_left() async {
+ var deletionOffset = 23;
+ var deletionLength = 7;
+ var insertionOffset = 23;
+ var insertionText = 'x';
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addDeletion(SourceRange(deletionOffset, deletionLength));
+ expect(() {
+ builder.addSimpleInsertion(insertionOffset, insertionText);
+ }, hasConflict);
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(1));
+ expect(edits[0].offset, deletionOffset);
+ expect(edits[0].length, deletionLength);
+ expect(edits[0].replacement, '');
+ }
+
+ Future<void> test_deletion_insertion_adjacent_right() async {
+ var deletionOffset = 23;
+ var deletionLength = 7;
+ var insertionOffset = 30;
+ var insertionText = 'x';
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addDeletion(SourceRange(deletionOffset, deletionLength));
+ builder.addSimpleInsertion(insertionOffset, insertionText);
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(2));
+ expect(edits[0].offset, insertionOffset);
+ expect(edits[0].length, 0);
+ expect(edits[0].replacement, insertionText);
+ expect(edits[1].offset, deletionOffset);
+ expect(edits[1].length, deletionLength);
+ expect(edits[1].replacement, isEmpty);
+ }
+
+ Future<void> test_deletion_insertion_overlap() async {
+ var deletionOffset = 23;
+ var deletionLength = 7;
+ var insertionOffset = 26;
+ var insertionText = 'x';
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addDeletion(SourceRange(deletionOffset, deletionLength));
+ expect(() {
+ builder.addSimpleInsertion(insertionOffset, insertionText);
+ }, hasConflict);
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(1));
+ expect(edits[0].offset, deletionOffset);
+ expect(edits[0].length, deletionLength);
+ expect(edits[0].replacement, '');
+ }
+
+ Future<void> test_insertion_deletion_adjacent_left() async {
+ var deletionOffset = 23;
+ var deletionLength = 7;
+ var insertionOffset = 23;
+ var insertionText = 'x';
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addSimpleInsertion(insertionOffset, insertionText);
+ builder.addDeletion(SourceRange(deletionOffset, deletionLength));
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(2));
+ expect(edits[0].offset, deletionOffset);
+ expect(edits[0].length, deletionLength);
+ expect(edits[0].replacement, isEmpty);
+ expect(edits[1].offset, insertionOffset);
+ expect(edits[1].length, 0);
+ expect(edits[1].replacement, insertionText);
+ }
+
+ Future<void> test_insertion_deletion_adjacent_right() async {
+ var deletionOffset = 23;
+ var deletionLength = 7;
+ var insertionOffset = 30;
+ var insertionText = 'x';
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addSimpleInsertion(insertionOffset, insertionText);
+ builder.addDeletion(SourceRange(deletionOffset, deletionLength));
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(2));
+ expect(edits[0].offset, insertionOffset);
+ expect(edits[0].length, 0);
+ expect(edits[0].replacement, insertionText);
+ expect(edits[1].offset, deletionOffset);
+ expect(edits[1].length, deletionLength);
+ expect(edits[1].replacement, isEmpty);
+ }
+
+ Future<void> test_insertion_deletion_overlap() async {
+ var deletionOffset = 23;
+ var deletionLength = 7;
+ var insertionOffset = 26;
+ var insertionText = 'x';
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addSimpleInsertion(insertionOffset, insertionText);
+ expect(() {
+ builder.addDeletion(SourceRange(deletionOffset, deletionLength));
+ }, hasConflict);
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(1));
+ expect(edits[0].offset, insertionOffset);
+ expect(edits[0].length, 0);
+ expect(edits[0].replacement, insertionText);
+ }
+
+ Future<void> test_replacement_replacement_overlap_left() async {
+ var offset = 23;
+ var length = 7;
+ var text = 'x';
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addSimpleReplacement(SourceRange(offset, length), text);
+ expect(() {
+ builder.addSimpleReplacement(SourceRange(offset - 2, length), text);
+ }, hasConflict);
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(1));
+ expect(edits[0].offset, offset);
+ expect(edits[0].length, length);
+ expect(edits[0].replacement, text);
+ }
+
+ Future<void> test_replacement_replacement_overlap_right() async {
+ var offset = 23;
+ var length = 7;
+ var text = 'x';
+ await builder.addGenericFileEdit(path, (builder) {
+ builder.addSimpleReplacement(SourceRange(offset, length), text);
+ expect(() {
+ builder.addSimpleReplacement(SourceRange(offset + 2, length), text);
+ }, hasConflict);
+ });
+ var edits = builder.sourceChange.edits[0].edits;
+ expect(edits, hasLength(1));
+ expect(edits[0].offset, offset);
+ expect(edits[0].length, length);
+ expect(edits[0].replacement, text);
+ }
+}
+
@reflectiveTest
class FileEditBuilderImplTest extends AbstractChangeBuilderTest {
String path = '/test.dart';
@@ -314,68 +538,6 @@
expect(edits[0].replacement, isEmpty);
}
- Future<void> test_addDeletion_adjacent_lowerOffsetFirst() async {
- // TODO(brianwilkerson) This should also merge the deletions, but is written
- // to ensure that existing uses of FileEditBuilder continue to work even
- // without that change.
- var firstOffset = 23;
- var firstLength = 7;
- var secondOffset = 30;
- var secondLength = 5;
- await builder.addGenericFileEdit(path, (builder) {
- builder.addDeletion(SourceRange(firstOffset, firstLength));
- builder.addDeletion(SourceRange(secondOffset, secondLength));
- });
- var edits = builder.sourceChange.edits[0].edits;
- expect(edits, hasLength(2));
- expect(edits[0].offset, secondOffset);
- expect(edits[0].length, secondLength);
- expect(edits[0].replacement, isEmpty);
- expect(edits[1].offset, firstOffset);
- expect(edits[1].length, firstLength);
- expect(edits[1].replacement, isEmpty);
- }
-
- Future<void> test_addDeletion_adjacent_lowerOffsetSecond() async {
- // TODO(brianwilkerson) This should also merge the deletions, but is written
- // to ensure that existing uses of FileEditBuilder continue to work even
- // without that change.
- var firstOffset = 23;
- var firstLength = 7;
- var secondOffset = 30;
- var secondLength = 5;
- await builder.addGenericFileEdit(path, (builder) {
- builder.addDeletion(SourceRange(secondOffset, secondLength));
- builder.addDeletion(SourceRange(firstOffset, firstLength));
- });
- var edits = builder.sourceChange.edits[0].edits;
- expect(edits, hasLength(2));
- expect(edits[0].offset, secondOffset);
- expect(edits[0].length, secondLength);
- expect(edits[0].replacement, isEmpty);
- expect(edits[1].offset, firstOffset);
- expect(edits[1].length, firstLength);
- expect(edits[1].replacement, isEmpty);
- }
-
- @failingTest
- Future<void> test_addDeletion_overlapping() async {
- // This support is not yet implemented.
- var firstOffset = 23;
- var firstLength = 7;
- var secondOffset = 27;
- var secondLength = 8;
- await builder.addGenericFileEdit(path, (builder) {
- builder.addDeletion(SourceRange(firstOffset, firstLength));
- builder.addDeletion(SourceRange(secondOffset, secondLength));
- });
- var edits = builder.sourceChange.edits[0].edits;
- expect(edits, hasLength(1));
- expect(edits[0].offset, firstOffset);
- expect(edits[0].length, secondOffset + secondLength - firstOffset);
- expect(edits[0].replacement, isEmpty);
- }
-
Future<void> test_addInsertion() async {
await builder.addGenericFileEdit(path, (builder) {
builder.addInsertion(10, (builder) {
@@ -472,40 +634,6 @@
expect(edits[1].replacement, text);
}
- Future<void> test_addSimpleReplacement_overlapsHead() async {
- var offset = 23;
- var length = 7;
- var text = 'xyz';
- await builder.addGenericFileEdit(path, (builder) {
- builder.addSimpleReplacement(SourceRange(offset, length), text);
- expect(() {
- builder.addSimpleReplacement(SourceRange(offset - 2, length), text);
- }, throwsA(isA<ConflictingEditException>()));
- });
- var edits = builder.sourceChange.edits[0].edits;
- expect(edits, hasLength(1));
- expect(edits[0].offset, offset);
- expect(edits[0].length, length);
- expect(edits[0].replacement, text);
- }
-
- Future<void> test_addSimpleReplacement_overlapsTail() async {
- var offset = 23;
- var length = 7;
- var text = 'xyz';
- await builder.addGenericFileEdit(path, (builder) {
- builder.addSimpleReplacement(SourceRange(offset, length), text);
- expect(() {
- builder.addSimpleReplacement(SourceRange(offset + 2, length), text);
- }, throwsA(isA<ConflictingEditException>()));
- });
- var edits = builder.sourceChange.edits[0].edits;
- expect(edits, hasLength(1));
- expect(edits[0].offset, offset);
- expect(edits[0].length, length);
- expect(edits[0].replacement, text);
- }
-
Future<void> test_createEditBuilder() async {
await builder.addGenericFileEdit(path, (builder) {
var offset = 4;
diff --git a/pkg/analyzer_plugin/test/support/abstract_context.dart b/pkg/analyzer_plugin/test/support/abstract_context.dart
index 33577e7..426644f 100644
--- a/pkg/analyzer_plugin/test/support/abstract_context.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_context.dart
@@ -44,6 +44,8 @@
List<String> get collectionIncludedPaths => [workspaceRootPath];
+ Folder get sdkRoot => newFolder('/sdk');
+
AnalysisSession get session => contextFor(testPackageRootPath).currentSession;
/// The file system-specific `analysis_options.yaml` path.
@@ -101,7 +103,10 @@
}
void setUp() {
- MockSdk(resourceProvider: resourceProvider);
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
newFolder(testPackageRootPath);
writeTestPackageConfig();
@@ -156,7 +161,7 @@
enableIndex: true,
includedPaths: collectionIncludedPaths.map(convertPath).toList(),
resourceProvider: resourceProvider,
- sdkPath: convertPath('/sdk'),
+ sdkPath: sdkRoot.path,
);
}
}
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 74804d7..024be8a 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -224,9 +224,6 @@
/// The URI for 'dart:web_gl'.
static final Uri dart_web_gl = Uri(scheme: 'dart', path: 'web_gl');
- /// The URI for 'dart:web_sql'.
- static final Uri dart_web_sql = Uri(scheme: 'dart', path: 'web_sql');
-
/// The URI for 'dart:_js_helper'.
static final Uri dart__js_helper = Uri(scheme: 'dart', path: '_js_helper');
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
index 11e86e2..5f3b75b 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
@@ -513,13 +513,27 @@
});
for (GenericInstantiation instantiation in _genericInstantiations) {
+ ParameterStructure instantiationParameterStructure =
+ ParameterStructure.fromType(instantiation.functionType);
+ ClassEntity implementationClass = _commonElements
+ .getInstantiationClass(instantiation.typeArguments.length);
+
void processEntity(Entity entity) {
MethodNode node = _getMethodNode(entity);
- if (node.parameterStructure ==
- ParameterStructure.fromType(instantiation.functionType)) {
+ // TODO(sra,johnniwinther): Use more information from the instantiation
+ // site. At many sites the instantiated element known, and for other
+ // sites the static type could filter more entities.
+ if (node.parameterStructure == instantiationParameterStructure) {
_instantiationMap.putIfAbsent(entity, () => {}).add(instantiation);
for (DartType type in instantiation.typeArguments) {
registerDependenciesForInstantiation(node, type);
+ // The instantiation is implemented by a generic class (a subclass
+ // of 'Closure'). The implementation of generic instantiation
+ // equality places a need on the type parameters of the generic
+ // class. Making the class a dependency on the instantiation's
+ // parameters allows the dependency to propagate back to the helper
+ // function that is called to create the instantiation.
+ registerDependencies(_getClassNode(implementationClass), type);
}
}
}
@@ -1337,6 +1351,7 @@
}
if (neededOnAll) break;
}
+
Set<ClassEntity> allClassesNeedingRuntimeType;
if (neededOnAll) {
neededOnFunctions = true;
@@ -1399,13 +1414,19 @@
Set<int> instantiationsNeedingTypeArguments = {};
typeVariableTests.forEachInstantiatedEntity(
(Entity target, Set<GenericInstantiation> instantiations) {
- if (methodsNeedingTypeArguments.contains(target) ||
- localFunctionsNeedingTypeArguments.contains(target)) {
- // TODO(johnniwinther): Use the static type of the instantiated
- // expression.
- instantiationsNeedingTypeArguments
- .add(instantiations.first.typeArguments.length);
- if (retainDataForTesting) {
+ // An instantiation needs type arguments if the class implementing the
+ // instantiation needs type arguments.
+ int arity = instantiations.first.typeArguments.length;
+ if (!instantiationsNeedingTypeArguments.contains(arity)) {
+ if (classesNeedingTypeArguments
+ .contains(commonElements.getInstantiationClass(arity))) {
+ instantiationsNeedingTypeArguments.add(arity);
+ }
+ }
+
+ if (retainDataForTesting) {
+ if (methodsNeedingTypeArguments.contains(target) ||
+ localFunctionsNeedingTypeArguments.contains(target)) {
_instantiatedEntitiesNeedingTypeArgumentsForTesting ??= {};
_instantiatedEntitiesNeedingTypeArgumentsForTesting
.putIfAbsent(target, () => {})
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index e079b78..3bb766f 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -1359,7 +1359,6 @@
type ??= findIn(Uris.dart_svg);
type ??= findIn(Uris.dart_web_audio);
type ??= findIn(Uris.dart_web_gl);
- type ??= findIn(Uris.dart_web_sql);
type ??= findIn(Uris.dart_indexed_db);
type ??= findIn(Uris.dart_typed_data);
type ??= findIn(Uris.dart__rti);
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 3b8b71b..ae463a8 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -36,7 +36,6 @@
'_native_typed_data',
'web_audio',
'web_gl',
- 'web_sql'
];
List<Pattern> _allowedNativeTestPatterns = [
@@ -246,7 +245,6 @@
'dart:svg',
'dart:web_audio',
'dart:web_gl',
- 'dart:web_sql',
],
'dart2js_server': [
'dart:_dart2js_runtime_metrics',
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 0bd2619..827bf20 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -949,7 +949,6 @@
type ??= findIn(Uris.dart_svg);
type ??= findIn(Uris.dart_web_audio);
type ??= findIn(Uris.dart_web_gl);
- type ??= findIn(Uris.dart_web_sql);
type ??= findIn(Uris.dart_indexed_db);
type ??= findIn(Uris.dart_typed_data);
type ??= findIn(Uris.dart__rti);
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 38609ea..d0a06d4 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -72,10 +72,14 @@
FeatureOption useContentSecurityPolicy = FeatureOption('csp');
/// [FeatureOption]s which default to enabled.
- late final List<FeatureOption> shipping = [legacyJavaScript, newHolders];
+ late final List<FeatureOption> shipping = [
+ legacyJavaScript,
+ newHolders,
+ useContentSecurityPolicy
+ ];
/// [FeatureOption]s which default to disabled.
- late final List<FeatureOption> canary = [useContentSecurityPolicy];
+ late final List<FeatureOption> canary = [];
/// Forces canary feature on. This must run after [Option].parse.
void forceCanary() {
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index cf8fb72..56683e5 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -5134,25 +5134,10 @@
List<HInstruction> arguments = [];
node.expression.accept(this);
arguments.add(pop());
- StaticType expressionType = _getStaticType(node.expression);
- FunctionType functionType = expressionType.type.withoutNullability;
- bool typeArgumentsNeeded = _rtiNeed.instantiationNeedsTypeArguments(
- functionType, node.typeArguments.length);
- List<DartType> typeArguments = node.typeArguments
- .map((type) => typeArgumentsNeeded
- ? _elementMap.getDartType(type)
- : _commonElements.dynamicType)
- .toList();
- registry.registerGenericInstantiation(
- GenericInstantiation(functionType, typeArguments));
- // TODO(johnniwinther): Can we avoid creating the instantiation object?
- for (DartType type in typeArguments) {
- HInstruction instruction =
- _typeBuilder.analyzeTypeArgument(type, sourceElement);
- arguments.add(instruction);
- }
+
+ // A generic function instantiation is created by calling a helper function
+ // which takes the arguments.
int typeArgumentCount = node.typeArguments.length;
- bool targetCanThrow = false; // TODO(sra): Is this true?
FunctionEntity target =
_commonElements.getInstantiateFunction(typeArgumentCount);
if (target == null) {
@@ -5163,10 +5148,36 @@
stack.add(graph.addConstantNull(closedWorld));
return;
}
+
+ StaticType expressionType = _getStaticType(node.expression);
+ FunctionType functionType = expressionType.type.withoutNullability;
+ bool typeArgumentsNeeded = _rtiNeed.methodNeedsTypeArguments(target);
+
+ List<DartType> typeArguments = node.typeArguments
+ .map((type) => typeArgumentsNeeded
+ ? _elementMap.getDartType(type)
+ : _commonElements.dynamicType)
+ .toList();
+ registry.registerGenericInstantiation(
+ GenericInstantiation(functionType, typeArguments));
+
+ // TODO(sra): Add instantiations to SourceInformationBuilder.
+ SourceInformation sourceInformation = null;
+
+ // TODO(47484): Allow callee to have different calling convention for type
+ // arguments.
+ if (typeArgumentsNeeded) {
+ _addTypeArguments(arguments, typeArguments, sourceInformation);
+ }
+
+ bool targetCanThrow = false; // TODO(sra): Is this true?
+
+ // TODO(sra): Use [_pushStaticInvocation] to allow inlining. We don't now
+ // because inference can't tell that the call has no side-effects.
HInstruction instruction = HInvokeStatic(
target, arguments, _abstractValueDomain.functionType, <DartType>[],
targetCanThrow: targetCanThrow);
- // TODO(sra): ..sourceInformation = sourceInformation
+ instruction.sourceInformation = sourceInformation;
instruction.sideEffects
..clearAllDependencies()
..clearAllSideEffects();
diff --git a/pkg/compiler/test/closure/data/instantiation.dart b/pkg/compiler/test/closure/data/instantiation.dart
index dfebcb4..cb95806 100644
--- a/pkg/compiler/test/closure/data/instantiation.dart
+++ b/pkg/compiler/test/closure/data/instantiation.dart
@@ -7,7 +7,7 @@
T id<T>(T t) => t;
method<S>(S s) {
- /*spec.fields=[S],free=[S]*/
+ /*fields=[S],free=[S]*/
S Function(S) getId() => id;
return getId();
}
diff --git a/pkg/compiler/test/closure/data/instantiation1.dart b/pkg/compiler/test/closure/data/instantiation1.dart
index 32c3043..d132094 100644
--- a/pkg/compiler/test/closure/data/instantiation1.dart
+++ b/pkg/compiler/test/closure/data/instantiation1.dart
@@ -13,8 +13,7 @@
/*member: B.method:hasThis*/
method() {
return
- /*spec.fields=[this],free=[this],hasThis*/
- /*prod.hasThis*/
+ /*fields=[this],free=[this],hasThis*/
() {
F<S> c = f;
return c;
diff --git a/pkg/compiler/test/closure/data/instantiation3.dart b/pkg/compiler/test/closure/data/instantiation3.dart
index a379626..da4ade4 100644
--- a/pkg/compiler/test/closure/data/instantiation3.dart
+++ b/pkg/compiler/test/closure/data/instantiation3.dart
@@ -10,7 +10,7 @@
method<S>() {
return
- /*spec.fields=[S],free=[S]*/
+ /*fields=[S],free=[S]*/
() {
F<S> c = f;
return c;
diff --git a/pkg/compiler/test/impact/data/jsinterop.dart b/pkg/compiler/test/impact/data/jsinterop.dart
index 3f41558..b39e444 100644
--- a/pkg/compiler/test/impact/data/jsinterop.dart
+++ b/pkg/compiler/test/impact/data/jsinterop.dart
@@ -43,8 +43,7 @@
native:OverconstrainedError,
native:PositionError,
native:SensorErrorEvent,
- native:SpeechRecognitionError,
- native:SqlError]
+ native:SpeechRecognitionError]
*/
@JS()
external double method();
diff --git a/pkg/compiler/test/impact/data/jsinterop_setter1.dart b/pkg/compiler/test/impact/data/jsinterop_setter1.dart
index b2b6e34..eb917cb 100644
--- a/pkg/compiler/test/impact/data/jsinterop_setter1.dart
+++ b/pkg/compiler/test/impact/data/jsinterop_setter1.dart
@@ -61,7 +61,6 @@
native:PositionError,
native:SensorErrorEvent,
native:SpeechRecognitionError,
- native:SqlError,
param:Function*]
*/
@JS()
diff --git a/pkg/compiler/test/impact/data/jsinterop_setter2.dart b/pkg/compiler/test/impact/data/jsinterop_setter2.dart
index 4c63bbb..7f5b60b 100644
--- a/pkg/compiler/test/impact/data/jsinterop_setter2.dart
+++ b/pkg/compiler/test/impact/data/jsinterop_setter2.dart
@@ -68,7 +68,6 @@
native:PositionError,
native:SensorErrorEvent,
native:SpeechRecognitionError,
- native:SqlError,
param:void Function(String*,File*)*]
*/
@JS()
diff --git a/pkg/compiler/test/impact/data/native.dart b/pkg/compiler/test/impact/data/native.dart
index b4d4c7f..8b4031b 100644
--- a/pkg/compiler/test/impact/data/native.dart
+++ b/pkg/compiler/test/impact/data/native.dart
@@ -29,7 +29,7 @@
type=[inst:JSNull,inst:JSString,native:bool,native:int]
*/
testJSCall() => foreign.JS(
- 'int|bool|NativeUint8List|Rectangle|IdbFactory|SqlDatabase|TypedData|ContextAttributes',
+ 'int|bool|NativeUint8List|Rectangle|IdbFactory|TypedData|ContextAttributes',
'#',
null);
diff --git a/pkg/compiler/test/rti/data/instantiation1.dart b/pkg/compiler/test/rti/data/instantiation1.dart
index c838bbe..0ea6b96 100644
--- a/pkg/compiler/test/rti/data/instantiation1.dart
+++ b/pkg/compiler/test/rti/data/instantiation1.dart
@@ -11,6 +11,7 @@
typedef int F<R>(R a);
/*spec.class: B:explicit=[int* Function(B.S*)*],implicit=[B.S],indirect,needsArgs*/
+/*prod.class: B:needsArgs*/
class B<S> {
F<S> c;
diff --git a/pkg/compiler/test/rti/data/instantiation3.dart b/pkg/compiler/test/rti/data/instantiation3.dart
index 682672d..4c13f62 100644
--- a/pkg/compiler/test/rti/data/instantiation3.dart
+++ b/pkg/compiler/test/rti/data/instantiation3.dart
@@ -11,6 +11,7 @@
typedef int F<R>(R a);
/*spec.class: B:direct,explicit=[int* Function(B.S*)*],implicit=[B.S],needsArgs*/
+/*prod.class: B:needsArgs*/
class B<S> {
F<S> c;
diff --git a/pkg/compiler/test/rti/data/instantiation5.dart b/pkg/compiler/test/rti/data/instantiation5.dart
index 525be33..3c37996 100644
--- a/pkg/compiler/test/rti/data/instantiation5.dart
+++ b/pkg/compiler/test/rti/data/instantiation5.dart
@@ -11,6 +11,7 @@
typedef int F<R>(R a);
/*spec.member: method:implicit=[method.S],indirect,needsArgs*/
+/*prod.member: method:needsArgs*/
method<S>() {
F<S> c;
diff --git a/pkg/compiler/test/rti/data/instantiation7.dart b/pkg/compiler/test/rti/data/instantiation7.dart
index a47924b..216c83d 100644
--- a/pkg/compiler/test/rti/data/instantiation7.dart
+++ b/pkg/compiler/test/rti/data/instantiation7.dart
@@ -21,6 +21,7 @@
typedef int F3<R, P, Q>(R a, P b, Q c);
/*spec.member: method:implicit=[method.X,method.Y,method.Z],indirect,needsArgs*/
+/*prod.member: method:needsArgs*/
method<X, Y, Z>() {
F1<X> c1;
F2<X, Y> c2;
diff --git a/pkg/compiler/test/rti/data/instantiation8.dart b/pkg/compiler/test/rti/data/instantiation8.dart
index f3750a1..0e57865 100644
--- a/pkg/compiler/test/rti/data/instantiation8.dart
+++ b/pkg/compiler/test/rti/data/instantiation8.dart
@@ -14,6 +14,7 @@
if (a != b) throw '$a != $b';
}
+/*member: test:needsArgs*/
test<T>(f) {
Class<T> Function() g = create;
equals(f, g);
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
index 0a1e1c2..fa46af3 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
@@ -416,7 +416,7 @@
Future<Library> _getLibrary(Uri libraryUri) async {
return await _compiler.context.runInContext((_) async {
- var builder = _compiler.userCode.loader.lookupLibraryBuilder(libraryUri);
+ var builder = _compiler.userCode.loader.builders[libraryUri];
if (builder != null) {
var library =
_compiler.userCode.loader.read(libraryUri, -1, accessor: builder);
diff --git a/pkg/dev_compiler/lib/src/kernel/native_types.dart b/pkg/dev_compiler/lib/src/kernel/native_types.dart
index 5a81641..ef37392 100644
--- a/pkg/dev_compiler/lib/src/kernel/native_types.dart
+++ b/pkg/dev_compiler/lib/src/kernel/native_types.dart
@@ -71,7 +71,6 @@
_addPendingExtensionTypes(sdk.getLibrary('dart:svg'));
_addPendingExtensionTypes(sdk.getLibrary('dart:web_audio'));
_addPendingExtensionTypes(sdk.getLibrary('dart:web_gl'));
- _addPendingExtensionTypes(sdk.getLibrary('dart:web_sql'));
// For testing purposes only, we add extension types outside the Dart SDK.
// These are only allowed for native tests (see allowedNativeTest).
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 47cd497..7985eb6 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -45,7 +45,6 @@
'dart.library.ui': 'false',
'dart.library.web_audio': 'true',
'dart.library.web_gl': 'true',
- 'dart.library.web_sql': 'true',
};
/// A kernel [Target] to configure the Dart Front End for dartdevc.
@@ -114,7 +113,6 @@
'dart:svg',
'dart:web_audio',
'dart:web_gl',
- 'dart:web_sql'
];
// The libraries required to be indexed via CoreTypes.
@@ -130,7 +128,6 @@
'dart:svg',
'dart:web_audio',
'dart:web_gl',
- 'dart:web_sql',
'dart:_foreign_helper',
'dart:_interceptors',
'dart:_js_helper',
diff --git a/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart b/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart
index 7d89f6d0..e1af8a8 100644
--- a/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart
+++ b/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart
@@ -451,7 +451,7 @@
${options.dartLangComment}
class A {
- String get publicInstanceGetter() => 'Fosse';
+ String get publicInstanceGetter => 'Fosse';
}
''';
setUpAll(() async {
@@ -484,7 +484,7 @@
${options.dartLangComment}
class A {
- String get _privateInstanceGetter() => 'Fosse';
+ String get _privateInstanceGetter => 'Fosse';
}
''';
setUpAll(() async {
@@ -517,7 +517,8 @@
${options.dartLangComment}
class A {
- var _value
+ var _value;
+ A(this._value);
set publicInstanceSetter(String v) => _value = v;
}
''';
@@ -551,7 +552,8 @@
${options.dartLangComment}
class A {
- var _value
+ var _value;
+ A(this._value);
set _privateInstanceSetter(String v) => _value = v;
}
''';
@@ -585,7 +587,7 @@
${options.dartLangComment}
class A {
- static String get publicStaticGetter() => 'Fosse';
+ static String get publicStaticGetter => 'Fosse';
}
''';
setUpAll(() async {
@@ -618,7 +620,7 @@
${options.dartLangComment}
class A {
- static String get _privateStaticGetter() => 'Fosse';
+ static String get _privateStaticGetter => 'Fosse';
}
''';
setUpAll(() async {
@@ -651,7 +653,7 @@
${options.dartLangComment}
class A {
- var _value;
+ static String _value = 'Cello';
static set publicStaticSetter(String v) => _value = v;
}
''';
@@ -685,7 +687,7 @@
${options.dartLangComment}
class A {
- var _value;
+ static String _value = 'Cello';
static set _privateStaticSetter(String v) => _value = v;
}
''';
diff --git a/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart b/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart
index 13bdd4a..4fb6eb6 100644
--- a/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart
+++ b/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart
@@ -23,6 +23,10 @@
var compiler = DevelopmentIncrementalCompiler(setup.options, input);
var component = await compiler.computeDelta();
component.computeCanonicalNames();
+ var errors = setup.errors.where((e) => e.contains('Error'));
+ if (errors.isNotEmpty) {
+ throw Exception('Compilation failed: \n${errors.join('\n')}');
+ }
// Initialize DDC.
var moduleName = 'foo.dart';
@@ -93,6 +97,7 @@
void cleanUp() {
tempDir.delete(recursive: true);
+ options.errors.clear();
}
}
diff --git a/pkg/dev_compiler/test/module_symbols/variable_symbols_test.dart b/pkg/dev_compiler/test/module_symbols/variable_symbols_test.dart
index f74b54c..64b3e57 100644
--- a/pkg/dev_compiler/test/module_symbols/variable_symbols_test.dart
+++ b/pkg/dev_compiler/test/module_symbols/variable_symbols_test.dart
@@ -96,7 +96,9 @@
final source = '''
${options.dartLangComment}
- class A {}
+ class A {
+ const A();
+ }
const localVariable = A();
''';
setUpAll(() async {
diff --git a/pkg/front_end/lib/src/fasta/TESTING.md b/pkg/front_end/lib/src/fasta/TESTING.md
index e89d5c9..6837c2f 100644
--- a/pkg/front_end/lib/src/fasta/TESTING.md
+++ b/pkg/front_end/lib/src/fasta/TESTING.md
@@ -26,10 +26,10 @@
```
# Unit tests for dart2js
-./tools/test.py --dart2js-batch --time -pcolor --report -aia32 -mrelease --checked dart2js
+./tools/test.py --time -pcolor --report -aia32 -mrelease --checked dart2js
# Language and co19, dart2js.
-./tools/test.py --dart2js-batch --time -pcolor --report -aia32 -mrelease -cdart2js -rd8 language co19
+./tools/test.py --time -pcolor --report -aia32 -mrelease -cdart2js -rd8 language co19
```
## Testing the Dart VM
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index edf5ede..8d60ebc 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -396,7 +396,7 @@
} else {
unhandled("${node.runtimeType}", "finalizeExports", -1, fileUri);
}
- LibraryBuilder? library = loader.lookupLibraryBuilder(libraryUri);
+ LibraryBuilder? library = loader.builders[libraryUri];
if (library == null) {
internalProblem(
templateUnspecified
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
index 9524f5b..3a4bdc0 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
@@ -47,10 +47,8 @@
class DillLoader extends Loader {
SourceLoader? currentSourceLoader;
- final Map<Uri, DillLibraryBuilder> _knownLibraryBuilders =
- <Uri, DillLibraryBuilder>{};
-
- final Map<Uri, DillLibraryBuilder> _builders = <Uri, DillLibraryBuilder>{};
+ @override
+ final Map<Uri, DillLibraryBuilder> builders = <Uri, DillLibraryBuilder>{};
final Queue<DillLibraryBuilder> _unparsedLibraries =
new Queue<DillLibraryBuilder>();
@@ -89,18 +87,12 @@
@override
LibraryBuilder get coreLibrary => _coreLibrary!;
+ void set coreLibrary(LibraryBuilder value) {
+ _coreLibrary = value;
+ }
+
Ticker get ticker => target.ticker;
- void registerKnownLibrary(Library library) {
- _knownLibraryBuilders[library.importUri] =
- new DillLibraryBuilder(library, this);
- }
-
- // TODO(johnniwinther): This is never called!?!
- void releaseAncillaryResources() {
- _knownLibraryBuilders.clear();
- }
-
/// Look up a library builder by the [uri], or if such doesn't exist, create
/// one. The canonical URI of the library is [uri], and its actual location is
/// [fileUri].
@@ -113,16 +105,12 @@
/// directive. If [accessor] isn't allowed to access [uri], it's a
/// compile-time error.
DillLibraryBuilder read(Uri uri, int charOffset, {LibraryBuilder? accessor}) {
- DillLibraryBuilder? libraryBuilder = _builders[uri];
- if (libraryBuilder == null) {
- libraryBuilder = _knownLibraryBuilders.remove(uri);
- // ignore: unnecessary_null_comparison
- assert(libraryBuilder != null, "No library found for $uri.");
- _builders[uri] = libraryBuilder!;
- assert(libraryBuilder.loader == this);
+ DillLibraryBuilder builder = builders.putIfAbsent(uri, () {
+ DillLibraryBuilder library = target.createLibraryBuilder(uri);
+ assert(library.loader == this);
if (uri.scheme == "dart") {
if (uri.path == "core") {
- _coreLibrary = libraryBuilder;
+ _coreLibrary = library;
}
}
{
@@ -130,18 +118,19 @@
// firstSourceUri and first library should be done as early as
// possible.
firstSourceUri ??= uri;
- first ??= libraryBuilder;
+ first ??= library;
}
- if (_coreLibrary == libraryBuilder) {
+ if (_coreLibrary == library) {
target.loadExtraRequiredLibraries(this);
}
if (target.backendTarget.mayDefineRestrictedType(uri)) {
- libraryBuilder.mayImplementRestrictedTypes = true;
+ library.mayImplementRestrictedTypes = true;
}
- _unparsedLibraries.addLast(libraryBuilder);
- }
+ _unparsedLibraries.addLast(library);
+ return library;
+ });
if (accessor != null) {
- libraryBuilder.recordAccess(charOffset, noLength, accessor.fileUri);
+ builder.recordAccess(charOffset, noLength, accessor.fileUri);
if (!accessor.isPatch &&
!accessor.isPart &&
!target.backendTarget
@@ -150,7 +139,7 @@
noLength, accessor.fileUri);
}
}
- return libraryBuilder;
+ return builder;
}
void _ensureCoreLibrary() {
@@ -176,7 +165,7 @@
void _logSummary(Template<SummaryTemplate> template) {
ticker.log((Duration elapsed, Duration sinceStart) {
int libraryCount = 0;
- for (DillLibraryBuilder library in libraryBuilders) {
+ for (DillLibraryBuilder library in builders.values) {
assert(library.loader == this);
libraryCount++;
}
@@ -275,7 +264,7 @@
Uri uri = library.importUri;
if (filter == null || filter(library.importUri)) {
libraries.add(library);
- registerKnownLibrary(library);
+ target.registerLibrary(library);
requestedLibraries.add(uri);
requestedLibrariesFileUri.add(library.fileUri);
}
@@ -301,7 +290,7 @@
//
// Create dill library builder (adds it to a map where it's fetched
// again momentarily).
- registerKnownLibrary(library);
+ target.registerLibrary(library);
// Set up the dill library builder (fetch it from the map again, add it to
// another map and setup some auxiliary things).
return read(library.importUri, -1);
@@ -316,8 +305,9 @@
}
void finalizeExports({bool suppressFinalizationErrors: false}) {
- for (DillLibraryBuilder builder in libraryBuilders) {
- builder.markAsReadyToFinalizeExports(
+ for (LibraryBuilder builder in builders.values) {
+ DillLibraryBuilder library = builder as DillLibraryBuilder;
+ library.markAsReadyToFinalizeExports(
suppressFinalizationErrors: suppressFinalizationErrors);
}
}
@@ -325,10 +315,9 @@
@override
ClassBuilder computeClassBuilderFromTargetClass(Class cls) {
Library kernelLibrary = cls.enclosingLibrary;
- LibraryBuilder? library = lookupLibraryBuilder(kernelLibrary.importUri);
+ LibraryBuilder? library = builders[kernelLibrary.importUri];
if (library == null) {
- library =
- currentSourceLoader?.lookupLibraryBuilder(kernelLibrary.importUri);
+ library = currentSourceLoader?.builders[kernelLibrary.importUri];
}
return library!.lookupLocalMember(cls.name, required: true) as ClassBuilder;
}
@@ -337,28 +326,4 @@
TypeBuilder computeTypeBuilder(DartType type) {
return type.accept(new TypeBuilderComputer(this));
}
-
- bool containsLibraryBuilder(Uri importUri) =>
- _builders.containsKey(importUri);
-
- @override
- DillLibraryBuilder? lookupLibraryBuilder(Uri importUri) =>
- _builders[importUri];
-
- Iterable<DillLibraryBuilder> get libraryBuilders => _builders.values;
-
- Iterable<Uri> get libraryImportUris => _builders.keys;
-
- void registerLibraryBuilder(DillLibraryBuilder libraryBuilder) {
- Uri importUri = libraryBuilder.importUri;
- libraryBuilder.loader = this;
- if (importUri.scheme == "dart" && importUri.path == "core") {
- _coreLibrary = libraryBuilder;
- }
- _builders[importUri] = libraryBuilder;
- }
-
- DillLibraryBuilder? deregisterLibraryBuilder(Uri importUri) {
- return _builders.remove(importUri);
- }
}
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_target.dart b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
index b5b737e..28ccfbc 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_target.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
@@ -4,7 +4,7 @@
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-import 'package:kernel/ast.dart' show Source;
+import 'package:kernel/ast.dart' show Library, Source;
import 'package:kernel/target/targets.dart' show Target;
@@ -20,11 +20,16 @@
import '../target_implementation.dart' show TargetImplementation;
+import 'dill_library_builder.dart' show DillLibraryBuilder;
+
import 'dill_loader.dart' show DillLoader;
class DillTarget extends TargetImplementation {
final Ticker ticker;
+ final Map<Uri, DillLibraryBuilder> _knownLibraryBuilders =
+ <Uri, DillLibraryBuilder>{};
+
bool isLoaded = false;
late final DillLoader loader;
@@ -87,4 +92,24 @@
}
isLoaded = true;
}
+
+ /// Returns the [DillLibraryBuilder] corresponding to [uri].
+ ///
+ /// The [DillLibraryBuilder] is pulled from [_knownLibraryBuilders].
+ DillLibraryBuilder createLibraryBuilder(Uri uri) {
+ DillLibraryBuilder libraryBuilder =
+ _knownLibraryBuilders.remove(uri) as DillLibraryBuilder;
+ // ignore: unnecessary_null_comparison
+ assert(libraryBuilder != null, "No library found for $uri.");
+ return libraryBuilder;
+ }
+
+ void registerLibrary(Library library) {
+ _knownLibraryBuilders[library.importUri] =
+ new DillLibraryBuilder(library, loader);
+ }
+
+ void releaseAncillaryResources() {
+ _knownLibraryBuilders.clear();
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 61bdb2e..a188b12 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -102,7 +102,6 @@
import 'dill/dill_library_builder.dart' show DillLibraryBuilder;
-import 'dill/dill_loader.dart' show DillLoader;
import 'dill/dill_target.dart' show DillTarget;
import 'export.dart' show Export;
@@ -284,7 +283,7 @@
// non-null.
if (userCode != null) {
ticker.logMs("Decided to reuse ${reusedLibraries.length}"
- " of ${userCode!.loader.libraryBuilders.length} libraries");
+ " of ${userCode!.loader.builders.length} libraries");
}
// For modular compilation we can be asked to load components and track
@@ -369,7 +368,7 @@
// calculation has the potential to work.
// ignore: unnecessary_null_comparison
if (componentWithDill == null) {
- userCode!.loader.clearLibraryBuilders();
+ userCode!.loader.builders.clear();
userCode = userCodeOld;
dillLoadedData!.loader.currentSourceLoader = userCode!.loader;
} else {
@@ -416,16 +415,14 @@
Set<Library> newDillLibraryBuilders = new Set<Library>();
userBuilders ??= <Uri, LibraryBuilder>{};
Map<LibraryBuilder, List<LibraryBuilder>>? convertedLibraries;
- for (LibraryBuilder builder in userCode!.loader.libraryBuilders) {
- if (builder is SourceLibraryBuilder) {
+ for (MapEntry<Uri, LibraryBuilder> entry
+ in userCode!.loader.builders.entries) {
+ if (entry.value is SourceLibraryBuilder) {
+ SourceLibraryBuilder builder = entry.value as SourceLibraryBuilder;
DillLibraryBuilder dillBuilder =
dillLoadedData!.loader.appendLibrary(builder.library);
- userCode!.loader.registerLibraryBuilder(
- // TODO(johnniwinther): Why do we need to create
- // [DillLibraryBuilder]s for the patch library file uris?
- dillBuilder,
- builder.isPatch ? builder.fileUri : null);
- userBuilders![builder.importUri] = dillBuilder;
+ userCode!.loader.builders[entry.key] = dillBuilder;
+ userBuilders![entry.key] = dillBuilder;
newDillLibraryBuilders.add(builder.library);
if (userCode!.loader.first == builder) {
userCode!.loader.first = dillBuilder;
@@ -442,7 +439,8 @@
// We suppress finalization errors because they have already been
// reported.
dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
- assert(_checkEquivalentScopes(userCode!.loader, dillLoadedData!.loader));
+ assert(_checkEquivalentScopes(
+ userCode!.loader.builders, dillLoadedData!.loader.builders));
if (experimentalInvalidation != null) {
/// If doing experimental invalidation that means that some of the old
@@ -487,19 +485,18 @@
return newDillLibraryBuilders;
}
- bool _checkEquivalentScopes(
- SourceLoader sourceLoader, DillLoader dillLoader) {
- for (LibraryBuilder sourceLibraryBuilder in sourceLoader.libraryBuilders) {
+ bool _checkEquivalentScopes(Map<Uri, LibraryBuilder> sourceLibraries,
+ Map<Uri, LibraryBuilder> dillLibraries) {
+ sourceLibraries.forEach((Uri uri, LibraryBuilder sourceLibraryBuilder) {
if (sourceLibraryBuilder is SourceLibraryBuilder) {
- Uri uri = sourceLibraryBuilder.importUri;
DillLibraryBuilder dillLibraryBuilder =
- dillLoader.lookupLibraryBuilder(uri)!;
+ dillLibraries[uri] as DillLibraryBuilder;
assert(
_hasEquivalentScopes(sourceLibraryBuilder, dillLibraryBuilder) ==
null,
_hasEquivalentScopes(sourceLibraryBuilder, dillLibraryBuilder));
}
- }
+ });
return true;
}
@@ -637,7 +634,7 @@
// evaluator - that comes from dill - are marked.
Set<Library> librariesUsedByConstantEvaluator = userCode!.librariesUsed;
- for (LibraryBuilder builder in dillLoadedData!.loader.libraryBuilders) {
+ for (LibraryBuilder builder in dillLoadedData!.loader.builders.values) {
if (builder is DillLibraryBuilder) {
if (builder.isBuiltAndMarked ||
librariesUsedByConstantEvaluator.contains(builder.library)) {
@@ -843,7 +840,11 @@
List<bool> seenModes = [false, false, false, false];
for (LibraryBuilder library in reusedLibraries) {
seenModes[library.library.nonNullableByDefaultCompiledMode.index] = true;
- userCode!.loader.registerLibraryBuilder(library);
+ userCode!.loader.builders[library.importUri] = library;
+ if (library.importUri.scheme == "dart" &&
+ library.importUri.path == "core") {
+ userCode!.loader.coreLibrary = library;
+ }
}
// Check compilation mode up against what we've seen here and set
// `hasInvalidNnbdModeLibrary` accordingly.
@@ -905,12 +906,10 @@
? firstEntryPoint
: null);
}
- if (userCode!.loader.first == null) {
- LibraryBuilder? libraryBuilder =
- userCode!.loader.lookupLibraryBuilder(firstEntryPointImportUri);
- if (libraryBuilder != null) {
- userCode!.loader.first = libraryBuilder;
- }
+ if (userCode!.loader.first == null &&
+ userCode!.loader.builders[firstEntryPointImportUri] != null) {
+ userCode!.loader.first =
+ userCode!.loader.builders[firstEntryPointImportUri];
}
}
@@ -920,7 +919,7 @@
void resetTrackingOfUsedLibraries(ClassHierarchy? hierarchy) {
if (trackNeededDillLibraries) {
// Reset dill loaders and kernel class hierarchy.
- for (LibraryBuilder builder in dillLoadedData!.loader.libraryBuilders) {
+ for (LibraryBuilder builder in dillLoadedData!.loader.builders.values) {
if (builder is DillLibraryBuilder) {
if (builder.isBuiltAndMarked) {
// Clear cached calculations in classes which upon calculation can
@@ -977,9 +976,13 @@
// Make sure the dill loader is on the same page.
DillTarget oldDillLoadedData = dillLoadedData!;
dillLoadedData = new DillTarget(ticker, uriTranslator, c.options.target);
- for (DillLibraryBuilder library
- in oldDillLoadedData.loader.libraryBuilders) {
- dillLoadedData!.loader.registerLibraryBuilder(library);
+ for (LibraryBuilder library in oldDillLoadedData.loader.builders.values) {
+ (library as DillLibraryBuilder).loader = dillLoadedData!.loader;
+ dillLoadedData!.loader.builders[library.importUri] = library;
+ if (library.importUri.scheme == "dart" &&
+ library.importUri.path == "core") {
+ dillLoadedData!.loader.coreLibrary = library;
+ }
}
dillLoadedData!.loader.first = oldDillLoadedData.loader.first;
dillLoadedData!.loader.libraries
@@ -1003,7 +1006,7 @@
incrementalSerializer?.invalidate(builder.fileUri);
LibraryBuilder? dillBuilder =
- dillLoadedData!.loader.deregisterLibraryBuilder(builder.importUri);
+ dillLoadedData!.loader.builders.remove(builder.importUri);
if (dillBuilder != null) {
removedDillBuilders = true;
userBuilders?.remove(builder.importUri);
@@ -1284,14 +1287,13 @@
dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
userBuilders = <Uri, LibraryBuilder>{};
platformBuilders = <LibraryBuilder>[];
- for (DillLibraryBuilder builder
- in dillLoadedData!.loader.libraryBuilders) {
+ dillLoadedData!.loader.builders.forEach((uri, builder) {
if (builder.importUri.scheme == "dart") {
platformBuilders!.add(builder);
} else {
- userBuilders![builder.importUri] = builder;
+ userBuilders![uri] = builder;
}
- }
+ });
if (userBuilders!.isEmpty) userBuilders = null;
}
data.initializationBytes = null;
@@ -1380,7 +1382,7 @@
Library library = c.enclosingLibrary;
// Only add if loaded from a dill file (and wasn't a 'dill' that was
// converted from source builders to dill builders).
- if (dillLoadedData!.loader.containsLibraryBuilder(library.importUri) &&
+ if (dillLoadedData!.loader.builders.containsKey(library.importUri) &&
(previousSourceBuilders == null ||
!previousSourceBuilders!.contains(library))) {
neededDillLibraries!.add(library);
@@ -1391,10 +1393,10 @@
// if all bets are off: Add everything (except for the libraries we just
// converted from source builders to dill builders).
neededDillLibraries = new Set<Library>();
- for (DillLibraryBuilder builder
- in dillLoadedData!.loader.libraryBuilders) {
- if (previousSourceBuilders == null ||
- !previousSourceBuilders!.contains(builder.library)) {
+ for (LibraryBuilder builder in dillLoadedData!.loader.builders.values) {
+ if (builder is DillLibraryBuilder &&
+ (previousSourceBuilders == null ||
+ !previousSourceBuilders!.contains(builder.library))) {
neededDillLibraries!.add(builder.library);
}
}
@@ -1424,9 +1426,9 @@
for (Component module in modulesToLoad!) {
bool usedComponent = false;
for (Library lib in module.libraries) {
- if (!dillLoadedData!.loader.containsLibraryBuilder(lib.importUri)) {
+ if (!dillLoadedData!.loader.builders.containsKey(lib.importUri)) {
dillLoadedData!.loader.libraries.add(lib);
- dillLoadedData!.loader.registerKnownLibrary(lib);
+ dillLoadedData!.registerLibrary(lib);
reusedLibraries.add(dillLoadedData!.loader.read(lib.importUri, -1));
usedComponent = true;
}
@@ -1442,14 +1444,13 @@
dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
userBuilders = <Uri, LibraryBuilder>{};
platformBuilders = <LibraryBuilder>[];
- for (DillLibraryBuilder builder
- in dillLoadedData!.loader.libraryBuilders) {
+ dillLoadedData!.loader.builders.forEach((uri, builder) {
if (builder.importUri.scheme == "dart") {
platformBuilders!.add(builder);
} else {
- userBuilders![builder.importUri] = builder;
+ userBuilders![uri] = builder;
}
- }
+ });
if (userBuilders!.isEmpty) {
userBuilders = null;
}
@@ -1517,7 +1518,7 @@
// a new error.
Set<LibraryBuilder> builders = {};
SourceLoader loader = userCode!.loader;
- for (LibraryBuilder builder in loader.libraryBuilders) {
+ for (LibraryBuilder builder in loader.builders.values) {
if (strongModeNNBDPackageOptOutUris.contains(builder.fileUri)) {
builders.add(builder);
}
@@ -1633,11 +1634,11 @@
bool removedDillBuilders = false;
for (Uri uri in potentiallyReferencedLibraries.keys) {
if (uri.scheme == "package") continue;
- LibraryBuilder? builder = userCode!.loader.deregisterLibraryBuilder(uri);
+ LibraryBuilder? builder = userCode!.loader.builders.remove(uri);
if (builder != null) {
Library lib = builder.library;
removedLibraries.add(lib);
- if (dillLoadedData!.loader.deregisterLibraryBuilder(uri) != null) {
+ if (dillLoadedData!.loader.builders.remove(uri) != null) {
removedDillBuilders = true;
}
cleanupSourcesForBuilder(null, builder, uriTranslator,
@@ -1665,7 +1666,7 @@
/// This method syncs the [libraries] list with the data in [builders].
void makeDillLoaderLibrariesUpToDateWithBuildersMap() {
dillLoadedData!.loader.libraries.clear();
- for (LibraryBuilder builder in dillLoadedData!.loader.libraryBuilders) {
+ for (LibraryBuilder builder in dillLoadedData!.loader.builders.values) {
dillLoadedData!.loader.libraries.add(builder.library);
}
}
@@ -1694,7 +1695,7 @@
if (userCode?.loader != null) {
Uri? partImportUri = uriToSource[partFileUri]?.importUri;
if (partImportUri != null &&
- userCode!.loader.containsLibraryBuilder(partImportUri)) {
+ userCode!.loader.builders.containsKey(partImportUri)) {
continue;
}
} else if (reusedResult != null) {
@@ -2200,9 +2201,7 @@
if (userCode != null) {
// userCode already contains the builders from userBuilders.
- for (LibraryBuilder libraryBuilder in userCode!.loader.libraryBuilders) {
- addBuilderAndInvalidateUris(libraryBuilder.importUri, libraryBuilder);
- }
+ userCode!.loader.builders.forEach(addBuilderAndInvalidateUris);
} else {
// userCode was null so we explicitly have to add the builders from
// userBuilders (which cannot be null as we checked initially that one of
@@ -2292,8 +2291,8 @@
@override
void invalidateAllSources() {
if (userCode != null) {
- Set<Uri> uris = new Set<Uri>.from(userCode!.loader.libraryImportUris);
- uris.removeAll(dillLoadedData!.loader.libraryImportUris);
+ Set<Uri> uris = new Set<Uri>.from(userCode!.loader.builders.keys);
+ uris.removeAll(dillLoadedData!.loader.builders.keys);
if (previousSourceBuilders != null) {
for (Library library in previousSourceBuilders!) {
uris.add(library.importUri);
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index af63914..452d6e7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1267,10 +1267,10 @@
void ensureLoaded(Member? member) {
if (member == null) return;
Library ensureLibraryLoaded = member.enclosingLibrary;
- LibraryBuilder? builder = libraryBuilder.loader
- .lookupLibraryBuilder(ensureLibraryLoaded.importUri) ??
- libraryBuilder.loader.target.dillTarget.loader
- .lookupLibraryBuilder(ensureLibraryLoaded.importUri);
+ LibraryBuilder? builder =
+ libraryBuilder.loader.builders[ensureLibraryLoaded.importUri] ??
+ libraryBuilder.loader.target.dillTarget.loader
+ .builders[ensureLibraryLoaded.importUri];
if (builder is DillLibraryBuilder) {
builder.ensureLoaded();
}
@@ -1285,10 +1285,10 @@
bool isLoaded(Member? member) {
if (member == null) return true;
Library ensureLibraryLoaded = member.enclosingLibrary;
- LibraryBuilder? builder = libraryBuilder.loader
- .lookupLibraryBuilder(ensureLibraryLoaded.importUri) ??
- libraryBuilder.loader.target.dillTarget.loader
- .lookupLibraryBuilder(ensureLibraryLoaded.importUri);
+ LibraryBuilder? builder =
+ libraryBuilder.loader.builders[ensureLibraryLoaded.importUri] ??
+ libraryBuilder.loader.target.dillTarget.loader
+ .builders[ensureLibraryLoaded.importUri];
if (builder is DillLibraryBuilder) {
return builder.isBuiltAndMarked;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
index af210a0..67be0a6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
@@ -20,9 +20,9 @@
@override
void report(LocatedMessage message, [List<LocatedMessage>? context]) {
// Try to find library.
- LibraryBuilder? builder = loader.lookupLibraryBuilder(message.uri!);
+ LibraryBuilder? builder = loader.builders[message.uri];
if (builder == null) {
- for (LibraryBuilder candidate in loader.libraryBuilders) {
+ for (LibraryBuilder candidate in loader.builders.values) {
if (candidate.fileUri == message.uri) {
// Found it.
builder = candidate;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 890bf9d..2f595eb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -40,6 +40,7 @@
import '../builder/void_type_declaration_builder.dart';
import '../compiler_context.dart' show CompilerContext;
import '../crash.dart' show withCrashReporting;
+import '../dill/dill_library_builder.dart' show DillLibraryBuilder;
import '../dill/dill_member_builder.dart' show DillMemberBuilder;
import '../dill/dill_target.dart' show DillTarget;
import '../kernel/constructor_tearoff_lowering.dart';
@@ -49,11 +50,16 @@
FormattedMessage,
LocatedMessage,
Message,
+ messageAgnosticWithStrongDillLibrary,
+ messageAgnosticWithWeakDillLibrary,
messageConstConstructorLateFinalFieldCause,
messageConstConstructorLateFinalFieldError,
messageConstConstructorNonFinalField,
messageConstConstructorNonFinalFieldCause,
messageConstConstructorRedirectionToNonConst,
+ messageInvalidNnbdDillLibrary,
+ messageStrongWithWeakDillLibrary,
+ messageWeakWithStrongDillLibrary,
noLength,
templateFieldNonNullableNotInitializedByConstructorError,
templateFieldNonNullableWithoutInitializerError,
@@ -66,7 +72,8 @@
import '../scope.dart' show AmbiguousBuilder;
import '../source/name_scheme.dart';
import '../source/source_class_builder.dart' show SourceClassBuilder;
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import '../source/source_library_builder.dart'
+ show LanguageVersion, SourceLibraryBuilder;
import '../source/source_loader.dart' show SourceLoader;
import '../target_implementation.dart' show TargetImplementation;
import '../ticker.dart' show Ticker;
@@ -361,10 +368,94 @@
return entryPoint;
}
+ /// Creates a [LibraryBuilder] corresponding to [uri], if one doesn't exist
+ /// already.
+ ///
+ /// [fileUri] must not be null and is a URI that can be passed to FileSystem
+ /// to locate the corresponding file.
+ ///
+ /// [origin] is non-null if the created library is a patch to [origin].
+ ///
+ /// [packageUri] is the base uri for the package which the library belongs to.
+ /// For instance 'package:foo'.
+ ///
+ /// This is used to associate libraries in for instance the 'bin' and 'test'
+ /// folders of a package source with the package uri of the 'lib' folder.
+ ///
+ /// If the [packageUri] is `null` the package association of this library is
+ /// based on its [importUri].
+ ///
+ /// For libraries with a 'package:' [importUri], the package path must match
+ /// the path in the [importUri]. For libraries with a 'dart:' [importUri] the
+ /// [packageUri] must be `null`.
+ ///
+ /// [packageLanguageVersion] is the language version defined by the package
+ /// which the library belongs to, or the current sdk version if the library
+ /// doesn't belong to a package.
+ LibraryBuilder createLibraryBuilder(
+ Uri uri,
+ Uri fileUri,
+ Uri? packageUri,
+ LanguageVersion packageLanguageVersion,
+ SourceLibraryBuilder? origin,
+ Library? referencesFrom,
+ bool? referenceIsPartOwner) {
+ if (dillTarget.isLoaded) {
+ DillLibraryBuilder? builder = dillTarget.loader.builders[uri];
+ if (builder != null) {
+ if (!builder.isNonNullableByDefault &&
+ (loader.nnbdMode == NnbdMode.Strong ||
+ loader.nnbdMode == NnbdMode.Agnostic)) {
+ loader.registerStrongOptOutLibrary(builder);
+ } else {
+ NonNullableByDefaultCompiledMode libraryMode =
+ builder.library.nonNullableByDefaultCompiledMode;
+ if (libraryMode == NonNullableByDefaultCompiledMode.Invalid) {
+ loader.registerNnbdMismatchLibrary(
+ builder, messageInvalidNnbdDillLibrary);
+ } else {
+ switch (loader.nnbdMode) {
+ case NnbdMode.Weak:
+ if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic &&
+ libraryMode != NonNullableByDefaultCompiledMode.Weak) {
+ loader.registerNnbdMismatchLibrary(
+ builder, messageWeakWithStrongDillLibrary);
+ }
+ break;
+ case NnbdMode.Strong:
+ if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic &&
+ libraryMode != NonNullableByDefaultCompiledMode.Strong) {
+ loader.registerNnbdMismatchLibrary(
+ builder, messageStrongWithWeakDillLibrary);
+ }
+ break;
+ case NnbdMode.Agnostic:
+ if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic) {
+ if (libraryMode == NonNullableByDefaultCompiledMode.Strong) {
+ loader.registerNnbdMismatchLibrary(
+ builder, messageAgnosticWithStrongDillLibrary);
+ } else {
+ loader.registerNnbdMismatchLibrary(
+ builder, messageAgnosticWithWeakDillLibrary);
+ }
+ }
+ break;
+ }
+ }
+ }
+ return builder;
+ }
+ }
+ return new SourceLibraryBuilder(
+ uri, fileUri, packageUri, packageLanguageVersion, loader, origin,
+ referencesFrom: referencesFrom,
+ referenceIsPartOwner: referenceIsPartOwner);
+ }
+
/// Returns classes defined in libraries in [loader].
List<SourceClassBuilder> collectMyClasses() {
List<SourceClassBuilder> result = <SourceClassBuilder>[];
- for (LibraryBuilder library in loader.libraryBuilders) {
+ for (LibraryBuilder library in loader.builders.values) {
if (library.loader == loader) {
Iterator<Builder> iterator = library.iterator;
while (iterator.moveNext()) {
@@ -623,7 +714,7 @@
void installDefaultSupertypes() {
Class objectClass = this.objectClass;
- for (LibraryBuilder library in loader.libraryBuilders) {
+ for (LibraryBuilder library in loader.builders.values) {
if (library.loader == loader) {
Iterator<Builder> iterator = library.iterator;
while (iterator.moveNext()) {
@@ -767,8 +858,23 @@
Reference? constructorReference;
Reference? tearOffReference;
if (indexedClass != null) {
- constructorReference = indexedClass.lookupConstructorReference(
- new Name(name, indexedClass.library));
+ constructorReference = indexedClass
+ // We use the name of the member builder here since it refers to
+ // the library of the original declaration when private. For
+ // instance:
+ //
+ // // lib1:
+ // class Super { Super._() }
+ // class Subclass extends Class {
+ // Subclass() : super._();
+ // }
+ // // lib2:
+ // class Mixin {}
+ // class Class = Super with Mixin;
+ //
+ // Here `super._()` in `Subclass` targets the forwarding stub
+ // added to `Class` whose name is `_` private to `lib1`.
+ .lookupConstructorReference(memberBuilder.member.name);
tearOffReference = indexedClass.lookupGetterReference(
constructorTearOffName(name, indexedClass.library));
}
@@ -995,7 +1101,7 @@
...backendTarget.extraIndexedLibraries
]) {
Uri uri = Uri.parse(platformLibrary);
- LibraryBuilder? libraryBuilder = loader.lookupLibraryBuilder(uri);
+ LibraryBuilder? libraryBuilder = loader.builders[uri];
if (libraryBuilder == null) {
// TODO(ahe): This is working around a bug in kernel_driver_test or
// kernel_driver.
@@ -1392,8 +1498,8 @@
if (loader.target.context.options
.isExperimentEnabledGlobally(ExperimentalFlag.valueClass)) {
- valueClass.transformComponent(
- component!, loader.coreTypes, loader.hierarchy, environment);
+ valueClass.transformComponent(component!, loader.coreTypes,
+ loader.hierarchy, loader.referenceFromIndex, environment);
ticker.logMs("Lowered value classes");
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
index 52d0a58..341c589 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
@@ -181,8 +181,7 @@
} else if (kernelClassOrTypeDef is Typedef) {
kernelLibrary = kernelClassOrTypeDef.enclosingLibrary;
}
- LibraryBuilder library =
- loader.lookupLibraryBuilder(kernelLibrary!.importUri)!;
+ LibraryBuilder library = loader.builders[kernelLibrary!.importUri]!;
return new NamedTypeBuilder(
parameter.name!,
new NullabilityBuilder.fromNullability(node.nullability),
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index 4173b42..5b07db1 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -21,7 +21,7 @@
abstract class Loader {
TargetImplementation get target;
- LibraryBuilder? lookupLibraryBuilder(Uri importUri);
+ Map<Uri, LibraryBuilder> get builders;
/// Register [message] as a problem with a severity determined by the
/// intrinsic severity of the message.
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index cfb438c..189058e 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -691,7 +691,7 @@
if (!loader.target.uriTranslator.isLibrarySupported(dottedName)) return "";
LibraryBuilder? imported =
- loader.lookupLibraryBuilder(new Uri(scheme: "dart", path: dottedName));
+ loader.builders[new Uri(scheme: "dart", path: dottedName)];
if (imported == null) {
LibraryBuilder coreLibrary = loader.read(
@@ -699,8 +699,8 @@
new Uri(scheme: "dart", path: "core").toString(), -1),
-1,
accessor: loader.first);
- imported = coreLibrary.loader
- .lookupLibraryBuilder(new Uri(scheme: 'dart', path: dottedName));
+ imported = coreLibrary
+ .loader.builders[new Uri(scheme: 'dart', path: dottedName)];
}
return imported != null && !imported.isSynthetic ? "true" : "";
}
@@ -2259,10 +2259,13 @@
bool isStatic = (modifiers & staticMask) != 0;
bool isExternal = (modifiers & externalMask) != 0;
final bool fieldIsLateWithLowering = isLate &&
- loader.target.backendTarget.isLateFieldLoweringEnabled(
- hasInitializer: hasInitializer,
- isFinal: isFinal,
- isStatic: isTopLevel || isStatic);
+ (loader.target.backendTarget.isLateFieldLoweringEnabled(
+ hasInitializer: hasInitializer,
+ isFinal: isFinal,
+ isStatic: isTopLevel || isStatic) ||
+ (loader.target.backendTarget.useStaticFieldLowering &&
+ (isStatic || isTopLevel)));
+
final bool isInstanceMember = currentTypeParameterScopeBuilder.kind !=
TypeParameterScopeKind.library &&
(modifiers & staticMask) == 0;
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 29c7861..4c38811 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -34,7 +34,6 @@
import '../../base/common.dart';
import '../../base/instrumentation.dart' show Instrumentation;
import '../../base/nnbd_mode.dart';
-import '../dill/dill_library_builder.dart';
import '../builder/builder.dart';
import '../builder/class_builder.dart';
import '../builder/constructor_builder.dart';
@@ -142,7 +141,8 @@
final SourceLoaderDataForTesting? dataForTesting;
- final Map<Uri, LibraryBuilder> _builders = <Uri, LibraryBuilder>{};
+ @override
+ final Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
final Queue<LibraryBuilder> _unparsedLibraries = new Queue<LibraryBuilder>();
@@ -203,256 +203,15 @@
: dataForTesting =
retainDataForTesting ? new SourceLoaderDataForTesting() : null;
- bool containsLibraryBuilder(Uri importUri) =>
- _builders.containsKey(importUri);
-
- @override
- LibraryBuilder? lookupLibraryBuilder(Uri importUri) => _builders[importUri];
-
- Iterable<LibraryBuilder> get libraryBuilders => _builders.values;
-
- Iterable<Uri> get libraryImportUris => _builders.keys;
-
- void registerLibraryBuilder(LibraryBuilder libraryBuilder, [Uri? uri]) {
- uri ??= libraryBuilder.importUri;
- if (uri.scheme == "dart" && uri.path == "core") {
- _coreLibrary = libraryBuilder;
- }
- _builders[uri] = libraryBuilder;
- }
-
- LibraryBuilder? deregisterLibraryBuilder(Uri importUri) {
- return _builders.remove(importUri);
- }
-
- void clearLibraryBuilders() {
- _builders.clear();
- }
-
@override
LibraryBuilder get coreLibrary => _coreLibrary!;
+ void set coreLibrary(LibraryBuilder value) {
+ _coreLibrary = value;
+ }
+
Ticker get ticker => target.ticker;
- /// Creates a [SourceLibraryBuilder] corresponding to [uri], if one doesn't
- /// exist already.
- ///
- /// [fileUri] must not be null and is a URI that can be passed to FileSystem
- /// to locate the corresponding file.
- ///
- /// [origin] is non-null if the created library is a patch to [origin].
- ///
- /// [packageUri] is the base uri for the package which the library belongs to.
- /// For instance 'package:foo'.
- ///
- /// This is used to associate libraries in for instance the 'bin' and 'test'
- /// folders of a package source with the package uri of the 'lib' folder.
- ///
- /// If the [packageUri] is `null` the package association of this library is
- /// based on its [importUri].
- ///
- /// For libraries with a 'package:' [importUri], the package path must match
- /// the path in the [importUri]. For libraries with a 'dart:' [importUri] the
- /// [packageUri] must be `null`.
- ///
- /// [packageLanguageVersion] is the language version defined by the package
- /// which the library belongs to, or the current sdk version if the library
- /// doesn't belong to a package.
- SourceLibraryBuilder createLibraryBuilder(
- Uri uri,
- Uri fileUri,
- Uri? packageUri,
- LanguageVersion packageLanguageVersion,
- SourceLibraryBuilder? origin,
- Library? referencesFrom,
- bool? referenceIsPartOwner) {
- return new SourceLibraryBuilder(
- uri, fileUri, packageUri, packageLanguageVersion, this, origin,
- referencesFrom: referencesFrom,
- referenceIsPartOwner: referenceIsPartOwner);
- }
-
- SourceLibraryBuilder _createSourceLibraryBuilder(
- Uri uri,
- Uri? fileUri,
- SourceLibraryBuilder? origin,
- Library? referencesFrom,
- bool? referenceIsPartOwner) {
- if (fileUri != null &&
- (fileUri.scheme == "dart" ||
- fileUri.scheme == "package" ||
- fileUri.scheme == "dart-ext")) {
- fileUri = null;
- }
- package_config.Package? packageForLanguageVersion;
- if (fileUri == null) {
- switch (uri.scheme) {
- case "package":
- case "dart":
- fileUri = target.translateUri(uri) ??
- new Uri(
- scheme: untranslatableUriScheme,
- path: Uri.encodeComponent("$uri"));
- if (uri.scheme == "package") {
- packageForLanguageVersion = target.uriTranslator.getPackage(uri);
- } else {
- packageForLanguageVersion =
- target.uriTranslator.packages.packageOf(fileUri);
- }
- break;
-
- default:
- fileUri = uri;
- packageForLanguageVersion =
- target.uriTranslator.packages.packageOf(fileUri);
- break;
- }
- } else {
- packageForLanguageVersion =
- target.uriTranslator.packages.packageOf(fileUri);
- }
- LanguageVersion? packageLanguageVersion;
- Uri? packageUri;
- Message? packageLanguageVersionProblem;
- if (packageForLanguageVersion != null) {
- Uri importUri = origin?.importUri ?? uri;
- if (importUri.scheme != 'dart' &&
- importUri.scheme != 'package' &&
- // ignore: unnecessary_null_comparison
- packageForLanguageVersion.name != null) {
- packageUri =
- new Uri(scheme: 'package', path: packageForLanguageVersion.name);
- }
- if (packageForLanguageVersion.languageVersion != null) {
- if (packageForLanguageVersion.languageVersion
- is package_config.InvalidLanguageVersion) {
- packageLanguageVersionProblem =
- messageLanguageVersionInvalidInDotPackages;
- packageLanguageVersion = new InvalidLanguageVersion(
- fileUri, 0, noLength, target.currentSdkVersion, false);
- } else {
- Version version = new Version(
- packageForLanguageVersion.languageVersion!.major,
- packageForLanguageVersion.languageVersion!.minor);
- if (version > target.currentSdkVersion) {
- packageLanguageVersionProblem =
- templateLanguageVersionTooHigh.withArguments(
- target.currentSdkVersion.major,
- target.currentSdkVersion.minor);
- packageLanguageVersion = new InvalidLanguageVersion(
- fileUri, 0, noLength, target.currentSdkVersion, false);
- } else {
- packageLanguageVersion = new ImplicitLanguageVersion(version);
- }
- }
- }
- }
- packageLanguageVersion ??=
- new ImplicitLanguageVersion(target.currentSdkVersion);
-
- SourceLibraryBuilder libraryBuilder = createLibraryBuilder(
- uri,
- fileUri,
- packageUri,
- packageLanguageVersion,
- origin,
- referencesFrom,
- referenceIsPartOwner);
- if (packageLanguageVersionProblem != null) {
- libraryBuilder.addPostponedProblem(
- packageLanguageVersionProblem, 0, noLength, libraryBuilder.fileUri);
- }
-
- // Add any additional logic after this block. Setting the
- // firstSourceUri and first library should be done as early as
- // possible.
- firstSourceUri ??= uri;
- first ??= libraryBuilder;
-
- _checkForDartCore(uri, libraryBuilder);
-
- Uri libraryUri = origin?.importUri ?? uri;
- if (target.backendTarget.mayDefineRestrictedType(libraryUri)) {
- libraryBuilder.mayImplementRestrictedTypes = true;
- }
- if (uri.scheme == "dart") {
- target.readPatchFiles(libraryBuilder);
- }
- _unparsedLibraries.addLast(libraryBuilder);
-
- return libraryBuilder;
- }
-
- DillLibraryBuilder? _lookupDillLibraryBuilder(Uri uri) {
- DillLibraryBuilder? libraryBuilder =
- target.dillTarget.loader.lookupLibraryBuilder(uri);
- if (libraryBuilder != null) {
- _checkDillLibraryBuilderNnbdMode(libraryBuilder);
- _checkForDartCore(uri, libraryBuilder);
- }
- return libraryBuilder;
- }
-
- void _checkDillLibraryBuilderNnbdMode(DillLibraryBuilder libraryBuilder) {
- if (!libraryBuilder.isNonNullableByDefault &&
- (nnbdMode == NnbdMode.Strong || nnbdMode == NnbdMode.Agnostic)) {
- registerStrongOptOutLibrary(libraryBuilder);
- } else {
- NonNullableByDefaultCompiledMode libraryMode =
- libraryBuilder.library.nonNullableByDefaultCompiledMode;
- if (libraryMode == NonNullableByDefaultCompiledMode.Invalid) {
- registerNnbdMismatchLibrary(
- libraryBuilder, messageInvalidNnbdDillLibrary);
- } else {
- switch (nnbdMode) {
- case NnbdMode.Weak:
- if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic &&
- libraryMode != NonNullableByDefaultCompiledMode.Weak) {
- registerNnbdMismatchLibrary(
- libraryBuilder, messageWeakWithStrongDillLibrary);
- }
- break;
- case NnbdMode.Strong:
- if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic &&
- libraryMode != NonNullableByDefaultCompiledMode.Strong) {
- registerNnbdMismatchLibrary(
- libraryBuilder, messageStrongWithWeakDillLibrary);
- }
- break;
- case NnbdMode.Agnostic:
- if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic) {
- if (libraryMode == NonNullableByDefaultCompiledMode.Strong) {
- registerNnbdMismatchLibrary(
- libraryBuilder, messageAgnosticWithStrongDillLibrary);
- } else {
- registerNnbdMismatchLibrary(
- libraryBuilder, messageAgnosticWithWeakDillLibrary);
- }
- }
- break;
- }
- }
- }
- }
-
- void _checkForDartCore(Uri uri, LibraryBuilder libraryBuilder) {
- if (uri.scheme == "dart") {
- if (uri.path == "core") {
- _coreLibrary = libraryBuilder;
- } else if (uri.path == "typed_data") {
- typedDataLibrary = libraryBuilder;
- }
- }
- // TODO(johnniwinther): If we save the created library in [_builders]
- // here, i.e. before calling `target.loadExtraRequiredLibraries` below,
- // the order of the libraries change, making `dart:core` come before the
- // required arguments. Currently [DillLoader.appendLibrary] one works
- // when this is not the case.
- if (_coreLibrary == libraryBuilder) {
- target.loadExtraRequiredLibraries(this);
- }
- }
-
/// Look up a library builder by the [uri], or if such doesn't exist, create
/// one. The canonical URI of the library is [uri], and its actual location is
/// [fileUri].
@@ -470,28 +229,135 @@
LibraryBuilder? origin,
Library? referencesFrom,
bool? referenceIsPartOwner}) {
- LibraryBuilder? libraryBuilder = _builders[uri];
- if (libraryBuilder == null) {
- if (target.dillTarget.isLoaded) {
- libraryBuilder = _lookupDillLibraryBuilder(uri);
+ LibraryBuilder builder = builders.putIfAbsent(uri, () {
+ if (fileUri != null &&
+ (fileUri!.scheme == "dart" ||
+ fileUri!.scheme == "package" ||
+ fileUri!.scheme == "dart-ext")) {
+ fileUri = null;
}
- if (libraryBuilder == null) {
- libraryBuilder = _createSourceLibraryBuilder(
- uri,
- fileUri,
- origin as SourceLibraryBuilder?,
- referencesFrom,
- referenceIsPartOwner);
+ package_config.Package? packageForLanguageVersion;
+ if (fileUri == null) {
+ switch (uri.scheme) {
+ case "package":
+ case "dart":
+ fileUri = target.translateUri(uri) ??
+ new Uri(
+ scheme: untranslatableUriScheme,
+ path: Uri.encodeComponent("$uri"));
+ if (uri.scheme == "package") {
+ packageForLanguageVersion = target.uriTranslator.getPackage(uri);
+ } else {
+ packageForLanguageVersion =
+ target.uriTranslator.packages.packageOf(fileUri!);
+ }
+ break;
+
+ default:
+ fileUri = uri;
+ packageForLanguageVersion =
+ target.uriTranslator.packages.packageOf(fileUri!);
+ break;
+ }
+ } else {
+ packageForLanguageVersion =
+ target.uriTranslator.packages.packageOf(fileUri!);
+ }
+ LanguageVersion? packageLanguageVersion;
+ Uri? packageUri;
+ Message? packageLanguageVersionProblem;
+ if (packageForLanguageVersion != null) {
+ Uri importUri = origin?.importUri ?? uri;
+ if (importUri.scheme != 'dart' &&
+ importUri.scheme != 'package' &&
+ // ignore: unnecessary_null_comparison
+ packageForLanguageVersion.name != null) {
+ packageUri =
+ new Uri(scheme: 'package', path: packageForLanguageVersion.name);
+ }
+ if (packageForLanguageVersion.languageVersion != null) {
+ if (packageForLanguageVersion.languageVersion
+ is package_config.InvalidLanguageVersion) {
+ packageLanguageVersionProblem =
+ messageLanguageVersionInvalidInDotPackages;
+ packageLanguageVersion = new InvalidLanguageVersion(
+ fileUri!, 0, noLength, target.currentSdkVersion, false);
+ } else {
+ Version version = new Version(
+ packageForLanguageVersion.languageVersion!.major,
+ packageForLanguageVersion.languageVersion!.minor);
+ if (version > target.currentSdkVersion) {
+ packageLanguageVersionProblem =
+ templateLanguageVersionTooHigh.withArguments(
+ target.currentSdkVersion.major,
+ target.currentSdkVersion.minor);
+ packageLanguageVersion = new InvalidLanguageVersion(
+ fileUri!, 0, noLength, target.currentSdkVersion, false);
+ } else {
+ packageLanguageVersion = new ImplicitLanguageVersion(version);
+ }
+ }
+ }
+ }
+ packageLanguageVersion ??=
+ new ImplicitLanguageVersion(target.currentSdkVersion);
+
+ LibraryBuilder library = target.createLibraryBuilder(
+ uri,
+ fileUri!,
+ packageUri,
+ packageLanguageVersion,
+ origin as SourceLibraryBuilder?,
+ referencesFrom,
+ referenceIsPartOwner);
+ if (packageLanguageVersionProblem != null &&
+ library is SourceLibraryBuilder) {
+ library.addPostponedProblem(
+ packageLanguageVersionProblem, 0, noLength, library.fileUri);
}
- _builders[uri] = libraryBuilder;
- }
+ if (uri.scheme == "dart") {
+ if (uri.path == "core") {
+ _coreLibrary = library;
+ } else if (uri.path == "typed_data") {
+ typedDataLibrary = library;
+ }
+ }
+ if (library.loader != this) {
+ if (_coreLibrary == library) {
+ target.loadExtraRequiredLibraries(this);
+ }
+ // This library isn't owned by this loader, so no further processing
+ // should be attempted.
+ return library;
+ }
+
+ {
+ // Add any additional logic after this block. Setting the
+ // firstSourceUri and first library should be done as early as
+ // possible.
+ firstSourceUri ??= uri;
+ first ??= library;
+ }
+ if (_coreLibrary == library) {
+ target.loadExtraRequiredLibraries(this);
+ }
+ Uri libraryUri = origin?.importUri ?? uri;
+ if (target.backendTarget.mayDefineRestrictedType(libraryUri)) {
+ library.mayImplementRestrictedTypes = true;
+ }
+ if (uri.scheme == "dart") {
+ target.readPatchFiles(library as SourceLibraryBuilder);
+ }
+ _unparsedLibraries.addLast(library);
+ return library;
+ });
if (accessor == null) {
- if (libraryBuilder.loader == this && first != libraryBuilder) {
+ if (builder.loader == this && first != builder) {
unhandled("null", "accessor", charOffset, uri);
}
} else {
- libraryBuilder.recordAccess(charOffset, noLength, accessor.fileUri);
+ builder.recordAccess(charOffset, noLength, accessor.fileUri);
if (!accessor.isPatch &&
!accessor.isPart &&
!target.backendTarget
@@ -500,7 +366,7 @@
noLength, accessor.fileUri);
}
}
- return libraryBuilder;
+ return builder;
}
void _ensureCoreLibrary() {
@@ -516,7 +382,7 @@
Future<Null> buildBodies() async {
assert(_coreLibrary != null);
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
currentUriForCrashReporting = library.importUri;
await buildBody(library);
@@ -529,7 +395,7 @@
void logSummary(Template<SummaryTemplate> template) {
ticker.log((Duration elapsed, Duration sinceStart) {
int libraryCount = 0;
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) libraryCount++;
}
double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
@@ -1046,7 +912,7 @@
void resolveParts() {
List<Uri> parts = <Uri>[];
List<SourceLibraryBuilder> libraries = <SourceLibraryBuilder>[];
- _builders.forEach((Uri uri, LibraryBuilder library) {
+ builders.forEach((Uri uri, LibraryBuilder library) {
if (library.loader == this) {
if (library.isPart) {
parts.add(uri);
@@ -1061,17 +927,16 @@
}
for (Uri uri in parts) {
if (usedParts.contains(uri)) {
- _builders.remove(uri);
+ builders.remove(uri);
} else {
- SourceLibraryBuilder part =
- lookupLibraryBuilder(uri) as SourceLibraryBuilder;
+ SourceLibraryBuilder part = builders[uri] as SourceLibraryBuilder;
part.addProblem(messagePartOrphan, 0, 1, part.fileUri);
part.validatePart(null, null);
}
}
ticker.logMs("Resolved parts");
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
library.applyPatches();
}
@@ -1082,7 +947,7 @@
void computeLibraryScopes() {
Set<LibraryBuilder> exporters = new Set<LibraryBuilder>();
Set<LibraryBuilder> exportees = new Set<LibraryBuilder>();
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
SourceLibraryBuilder sourceLibrary = library as SourceLibraryBuilder;
sourceLibrary.buildInitialScopes();
@@ -1116,7 +981,7 @@
}
}
} while (wasChanged);
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
SourceLibraryBuilder sourceLibrary = library as SourceLibraryBuilder;
sourceLibrary.addImportsToScope();
@@ -1135,7 +1000,7 @@
void debugPrintExports() {
// TODO(sigmund): should be `covariant SourceLibraryBuilder`.
- _builders.forEach((Uri uri, dynamic l) {
+ builders.forEach((Uri uri, dynamic l) {
SourceLibraryBuilder library = l;
Set<Builder> members = new Set<Builder>();
Iterator<Builder> iterator = library.iterator;
@@ -1159,7 +1024,7 @@
void resolveTypes() {
int typeCount = 0;
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
SourceLibraryBuilder sourceLibrary = library as SourceLibraryBuilder;
typeCount += sourceLibrary.resolveTypes();
@@ -1170,7 +1035,7 @@
void finishDeferredLoadTearoffs() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
count += library.finishDeferredLoadTearoffs();
}
@@ -1180,7 +1045,7 @@
void finishNoSuchMethodForwarders() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
count += library.finishForwarders();
}
@@ -1190,7 +1055,7 @@
void resolveConstructors() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
count += library.resolveConstructors(null);
}
@@ -1200,7 +1065,7 @@
void installTypedefTearOffs() {
if (target.backendTarget.isTypedefTearOffLoweringEnabled) {
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this && library is SourceLibraryBuilder) {
library.installTypedefTearOffs();
}
@@ -1210,7 +1075,7 @@
void finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType) {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
count += library.finishTypeVariables(object, dynamicType);
}
@@ -1220,7 +1085,7 @@
void computeVariances() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
count += library.computeVariances();
}
@@ -1231,7 +1096,7 @@
void computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder nullType,
TypeBuilder bottomType, ClassBuilder objectClass) {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
count += library.computeDefaultTypes(
dynamicType, nullType, bottomType, objectClass);
@@ -1242,7 +1107,7 @@
void finishNativeMethods() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
count += library.finishNativeMethods();
}
@@ -1252,7 +1117,7 @@
void finishPatchMethods() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
count += library.finishPatchMethods();
}
@@ -1291,7 +1156,7 @@
List<SourceClassBuilder> handleHierarchyCycles(ClassBuilder objectClass) {
// Compute the initial work list of all classes declared in this loader.
List<SourceClassBuilder> workList = <SourceClassBuilder>[];
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
Iterator<Builder> members = library.iterator;
while (members.moveNext()) {
@@ -1490,7 +1355,7 @@
/// Builds the core AST structure needed for the outline of the component.
void buildComponent() {
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
SourceLibraryBuilder sourceLibrary = library as SourceLibraryBuilder;
Library target = sourceLibrary.build(coreLibrary);
@@ -1510,7 +1375,7 @@
Component computeFullComponent() {
Set<Library> libraries = new Set<Library>();
List<Library> workList = <Library>[];
- for (LibraryBuilder libraryBuilder in libraryBuilders) {
+ for (LibraryBuilder libraryBuilder in builders.values) {
if (!libraryBuilder.isPatch &&
(libraryBuilder.loader == this ||
libraryBuilder.importUri.scheme == "dart" ||
@@ -1557,7 +1422,7 @@
}
void computeShowHideElements() {
- for (LibraryBuilder libraryBuilder in libraryBuilders) {
+ for (LibraryBuilder libraryBuilder in builders.values) {
if (libraryBuilder.loader == this &&
libraryBuilder is SourceLibraryBuilder) {
libraryBuilder.computeShowHideElements(_builderHierarchy!);
@@ -1605,7 +1470,7 @@
}
void checkTypes() {
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library is SourceLibraryBuilder) {
if (library.loader == this) {
library
@@ -1686,7 +1551,7 @@
List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
List<DelayedActionPerformer> delayedActionPerformers =
<DelayedActionPerformer>[];
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
(library as SourceLibraryBuilder).buildOutlineExpressions();
Iterator<Builder> iterator = library.iterator;
@@ -1743,7 +1608,7 @@
builderHierarchy.computeTypes();
List<FieldBuilder> allImplicitlyTypedFields = <FieldBuilder>[];
- for (LibraryBuilder library in libraryBuilders) {
+ for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
List<FieldBuilder>? implicitlyTypedFields =
library.takeImplicitlyTypedFields();
@@ -1839,7 +1704,7 @@
void checkMainMethods() {
DartType? listOfString;
- for (LibraryBuilder libraryBuilder in libraryBuilders) {
+ for (LibraryBuilder libraryBuilder in builders.values) {
if (libraryBuilder.loader == this &&
libraryBuilder.isNonNullableByDefault) {
Builder? mainBuilder =
@@ -1968,7 +1833,7 @@
hierarchy = null;
_builderHierarchy = null;
_typeInferenceEngine = null;
- _builders.clear();
+ builders.clear();
libraries.clear();
first = null;
sourceBytes.clear();
@@ -1982,7 +1847,7 @@
@override
ClassBuilder computeClassBuilderFromTargetClass(Class cls) {
Library kernelLibrary = cls.enclosingLibrary;
- LibraryBuilder? library = lookupLibraryBuilder(kernelLibrary.importUri);
+ LibraryBuilder? library = builders[kernelLibrary.importUri];
if (library == null) {
return target.dillTarget.loader.computeClassBuilderFromTargetClass(cls);
}
diff --git a/pkg/front_end/lib/src/testing/id_testing_utils.dart b/pkg/front_end/lib/src/testing/id_testing_utils.dart
index 4c4f476..02297a9 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -124,7 +124,7 @@
InternalCompilerResult compilerResult, Library library,
{bool required: true}) {
SourceLoader loader = compilerResult.kernelTargetForTesting!.loader;
- LibraryBuilder? builder = loader.lookupLibraryBuilder(library.importUri);
+ LibraryBuilder? builder = loader.builders[library.importUri];
if (builder == null && required) {
throw new ArgumentError("DeclarationBuilder for $library not found.");
}
diff --git a/pkg/front_end/test/crashing_test_case_minimizer_impl.dart b/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
index dfd6efa..e8e1ed7 100644
--- a/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
+++ b/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
@@ -1767,8 +1767,7 @@
bool _knownByCompiler(Uri uri) {
LibraryBuilder? libraryBuilder = _latestCrashingIncrementalCompiler!
- .userCode!.loader
- .lookupLibraryBuilder(_getImportUri(uri));
+ .userCode!.loader.builders[_getImportUri(uri)];
if (libraryBuilder != null) {
return true;
}
@@ -1786,14 +1785,13 @@
bool _isUriNnbd(Uri uri, {bool crashOnFail: true}) {
Uri asImportUri = _getImportUri(uri);
LibraryBuilder? libraryBuilder = _latestCrashingIncrementalCompiler!
- .userCode!.loader
- .lookupLibraryBuilder(asImportUri);
+ .userCode!.loader.builders[asImportUri];
if (libraryBuilder != null) {
return libraryBuilder.isNonNullableByDefault;
}
print("Couldn't lookup $uri");
for (LibraryBuilder libraryBuilder in _latestCrashingIncrementalCompiler!
- .userCode!.loader.libraryBuilders) {
+ .userCode!.loader.builders.values) {
if (libraryBuilder.importUri == uri) {
print("Found $uri as ${libraryBuilder.importUri} (!= ${asImportUri})");
return libraryBuilder.isNonNullableByDefault;
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 0c88143..b933c35 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -1343,7 +1343,7 @@
// Create lookup-table from file uri to whatever.
Map<Uri, LibraryBuilder> builders = {};
for (LibraryBuilder builder
- in incrementalCompiler.userCode!.loader.libraryBuilders) {
+ in incrementalCompiler.userCode!.loader.builders.values) {
if (builder.importUri.scheme == "dart" && !builder.isSynthetic) continue;
builders[builder.fileUri] = builder;
for (LibraryPart part in builder.library.parts) {
diff --git a/pkg/front_end/test/incremental_suite.dart b/pkg/front_end/test/incremental_suite.dart
index 2ce5c81..30745c3 100644
--- a/pkg/front_end/test/incremental_suite.dart
+++ b/pkg/front_end/test/incremental_suite.dart
@@ -1941,7 +1941,7 @@
.computeDelta(entryPoints: entryPoints, fullComponent: fullComponent);
// We should at least have the SDK builders available. Slight smoke test.
- if (!dillLoadedData!.loader.libraryImportUris
+ if (!dillLoadedData!.loader.builders.keys
.map((uri) => uri.toString())
.contains("dart:core")) {
throw "Loaders builder should contain the sdk, "
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 5746a68..44c927d 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -317,7 +317,6 @@
deps
dereferenced
dereferencing
-deregister
descent
deserializer
deserializers
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index d2a057e..bc37385 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -248,7 +248,7 @@
"pattern": [
"pkg/front_end/.*\\.dart$",
"pkg/front_end/.*\\.crash_dart$",
- "/tests/.*\\.dart$"
+ "tests/.*\\.dart$"
],
"exclude": []
},
@@ -392,7 +392,7 @@
"kind": "test_dart",
"arch": "x64",
"mode": "release",
- "common": "--dart2js-batch --time -pcolor --report -ax64 -mrelease --write-result-log",
+ "common": "--time -pcolor --report -ax64 -mrelease --write-result-log",
"command-lines": [
"--checked dart2js",
"-cdart2js -rd8 --exclude-suite=observatory_ui",
@@ -418,7 +418,7 @@
"kind": "test_dart",
"arch": "x64",
"mode": "release",
- "common": "--dart2js-batch --time -pcolor --report -ax64 -mrelease --write-result-log",
+ "common": "--time -pcolor --report -ax64 -mrelease --write-result-log",
"command-lines": [
"-t240 --checked pkg/(kernel|front_end|fasta) dart2js",
"-cdartk -rvm",
@@ -432,7 +432,7 @@
"kind": "test_dart",
"arch": "x64",
"mode": "release",
- "common": "--dart2js-batch --time -pcolor --report -ax64 -mrelease --write-result-log",
+ "common": "--time -pcolor --report -ax64 -mrelease --write-result-log",
"command-lines": [
"-cdart2js -rd8 --use-sdk --minified language language_2 web_2 corelib corelib_2"
]
diff --git a/pkg/front_end/tool/dart_doctest_impl.dart b/pkg/front_end/tool/dart_doctest_impl.dart
index 1e51b84..3ef774c 100644
--- a/pkg/front_end/tool/dart_doctest_impl.dart
+++ b/pkg/front_end/tool/dart_doctest_impl.dart
@@ -51,7 +51,6 @@
show useImplicitCreationExpressionInCfe;
// ignore: import_of_legacy_library_into_null_safe
import 'package:front_end/src/fasta/source/source_library_builder.dart';
-import 'package:front_end/src/fasta/source/source_loader.dart';
import 'package:front_end/src/fasta/uri_translator.dart';
import 'package:kernel/kernel.dart' as kernel
show Combinator, Component, LibraryDependency, Library, Location, Source;
@@ -879,20 +878,7 @@
: super(fileSystem, includeComments, dillTarget, uriTranslator);
@override
- SourceLoader createLoader() {
- return new DocTestSourceLoader(compiler, fileSystem, includeComments, this);
- }
-}
-
-class DocTestSourceLoader extends SourceLoader {
- final DocTestIncrementalCompiler compiler;
-
- DocTestSourceLoader(this.compiler, FileSystem fileSystem,
- bool includeComments, DocTestIncrementalKernelTarget target)
- : super(fileSystem, includeComments, target);
-
- @override
- SourceLibraryBuilder createLibraryBuilder(
+ LibraryBuilder createLibraryBuilder(
Uri uri,
Uri fileUri,
Uri? packageUri,
diff --git a/pkg/frontend_server/test/src/javascript_bundle_test.dart b/pkg/frontend_server/test/src/javascript_bundle_test.dart
index d927f82..69a7156 100644
--- a/pkg/frontend_server/test/src/javascript_bundle_test.dart
+++ b/pkg/frontend_server/test/src/javascript_bundle_test.dart
@@ -40,7 +40,6 @@
'dart:svg': [],
'dart:web_audio': [],
'dart:web_gl': [],
- 'dart:web_sql': [],
'dart:_js_helper': [
'PrivateSymbol',
'LinkedMap',
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 19b2465..3bddafe 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -3181,6 +3181,9 @@
function = v.transform(function);
function.parent = this;
}
+ if (signatureType != null) {
+ signatureType = v.visitDartType(signatureType!) as FunctionType;
+ }
}
@override
@@ -3191,6 +3194,15 @@
function = v.transform(function);
function.parent = this;
}
+ if (signatureType != null) {
+ DartType newSignatureType =
+ v.visitDartType(signatureType!, dummyDartType);
+ if (identical(newSignatureType, dummyDartType)) {
+ signatureType = null;
+ } else {
+ signatureType = newSignatureType as FunctionType;
+ }
+ }
}
@override
diff --git a/pkg/kernel/lib/transformations/value_class.dart b/pkg/kernel/lib/transformations/value_class.dart
index 2a96ffd..f69a386 100644
--- a/pkg/kernel/lib/transformations/value_class.dart
+++ b/pkg/kernel/lib/transformations/value_class.dart
@@ -9,6 +9,7 @@
import '../ast.dart';
import '../core_types.dart' show CoreTypes;
import '../class_hierarchy.dart' show ClassHierarchy;
+import '../reference_from_index.dart';
import './scanner.dart';
class ValueClassScanner extends ClassScanner<Null> {
@@ -64,12 +65,23 @@
}
}
-void transformComponent(Component node, CoreTypes coreTypes,
- ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {
+void transformComponent(
+ Component node,
+ CoreTypes coreTypes,
+ ClassHierarchy hierarchy,
+ ReferenceFromIndex? referenceFromIndex,
+ TypeEnvironment typeEnvironment) {
ValueClassScanner scanner = new ValueClassScanner();
ScanResult<Class, Null> valueClasses = scanner.scan(node);
for (Class valueClass in valueClasses.targets.keys) {
- transformValueClass(valueClass, coreTypes, hierarchy, typeEnvironment);
+ transformValueClass(
+ valueClass,
+ coreTypes,
+ hierarchy,
+ referenceFromIndex
+ ?.lookupLibrary(valueClass.enclosingLibrary)
+ ?.lookupIndexedClass(valueClass.name),
+ typeEnvironment);
}
treatCopyWithCallSites(node, coreTypes, typeEnvironment, hierarchy);
@@ -79,8 +91,12 @@
}
}
-void transformValueClass(Class cls, CoreTypes coreTypes,
- ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {
+void transformValueClass(
+ Class cls,
+ CoreTypes coreTypes,
+ ClassHierarchy hierarchy,
+ IndexedClass? indexedClass,
+ TypeEnvironment typeEnvironment) {
Constructor? syntheticConstructor = null;
for (Constructor constructor in cls.constructors) {
if (constructor.isSynthetic) {
@@ -93,11 +109,11 @@
allVariablesList.sort((a, b) => a.name!.compareTo(b.name!));
addConstructor(cls, coreTypes, syntheticConstructor!);
- addEqualsOperator(cls, coreTypes, hierarchy, allVariablesList);
- addHashCode(cls, coreTypes, hierarchy, allVariablesList);
- addToString(cls, coreTypes, hierarchy, allVariablesList);
- addCopyWith(cls, coreTypes, hierarchy, allVariablesList, syntheticConstructor,
- typeEnvironment);
+ addEqualsOperator(cls, coreTypes, hierarchy, indexedClass, allVariablesList);
+ addHashCode(cls, coreTypes, hierarchy, indexedClass, allVariablesList);
+ addToString(cls, coreTypes, hierarchy, indexedClass, allVariablesList);
+ addCopyWith(cls, coreTypes, hierarchy, indexedClass, allVariablesList,
+ syntheticConstructor, typeEnvironment);
}
void addConstructor(
@@ -137,7 +153,7 @@
}
void addEqualsOperator(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
- List<VariableDeclaration> allVariablesList) {
+ IndexedClass? indexedClass, List<VariableDeclaration> allVariablesList) {
List<VariableDeclaration> allVariables = allVariablesList.toList();
for (Procedure procedure in cls.procedures) {
if (procedure.kind == ProcedureKind.Operator &&
@@ -167,8 +183,9 @@
targets[variable] = target;
}
+ Name name = Name("==");
Procedure equalsOperator = Procedure(
- Name("=="),
+ name,
ProcedureKind.Operator,
FunctionNode(
ReturnStatement(allVariables
@@ -184,13 +201,14 @@
previousValue!, LogicalExpressionOperator.AND, element))),
returnType: returnType,
positionalParameters: [other]),
- fileUri: cls.fileUri)
+ fileUri: cls.fileUri,
+ reference: indexedClass?.lookupGetterReference(name))
..fileOffset = cls.fileOffset;
cls.addProcedure(equalsOperator);
}
void addHashCode(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
- List<VariableDeclaration> allVariablesList) {
+ IndexedClass? indexedClass, List<VariableDeclaration> allVariablesList) {
List<VariableDeclaration> allVariables = allVariablesList.toList();
for (Procedure procedure in cls.procedures) {
if (procedure.kind == ProcedureKind.Getter &&
@@ -234,8 +252,9 @@
targetsHashcode[variable] = targetHashcode;
targets[variable] = target;
}
+ Name name = Name("hashCode");
cls.addProcedure(Procedure(
- Name("hashCode"),
+ name,
ProcedureKind.Getter,
FunctionNode(
ReturnStatement(StaticInvocation(
@@ -259,12 +278,13 @@
hashCombine!, Arguments([previousValue, element])))
]))),
returnType: returnType),
- fileUri: cls.fileUri)
+ fileUri: cls.fileUri,
+ reference: indexedClass?.lookupGetterReference(name))
..fileOffset = cls.fileOffset);
}
void addToString(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
- List<VariableDeclaration> allVariablesList) {
+ IndexedClass? indexedClass, List<VariableDeclaration> allVariablesList) {
List<Expression> wording = [StringLiteral("${cls.name}(")];
for (VariableDeclaration variable in allVariablesList) {
@@ -291,12 +311,14 @@
}
DartType returnType =
coreTypes.stringRawType(cls.enclosingLibrary.nonNullable);
+ Name name = Name("toString");
cls.addProcedure(Procedure(
- Name("toString"),
+ name,
ProcedureKind.Method,
FunctionNode(ReturnStatement(StringConcatenation(wording)),
returnType: returnType),
- fileUri: cls.fileUri)
+ fileUri: cls.fileUri,
+ reference: indexedClass?.lookupGetterReference(name))
..fileOffset = cls.fileOffset);
}
@@ -304,6 +326,7 @@
Class cls,
CoreTypes coreTypes,
ClassHierarchy hierarchy,
+ IndexedClass? indexedClass,
List<VariableDeclaration> allVariablesList,
Constructor syntheticConstructor,
TypeEnvironment typeEnvironment) {
@@ -324,8 +347,9 @@
targets[variable] = target;
}
+ Name name = Name("copyWith");
cls.addProcedure(Procedure(
- Name("copyWith"),
+ name,
ProcedureKind.Method,
FunctionNode(
ReturnStatement(ConstructorInvocation(
@@ -335,7 +359,8 @@
.map((f) => NamedExpression(f.name!, VariableGet(f)))
.toList()))),
namedParameters: allVariables),
- fileUri: cls.fileUri)
+ fileUri: cls.fileUri,
+ reference: indexedClass?.lookupGetterReference(name))
..fileOffset = cls.fileOffset);
}
diff --git a/pkg/nnbd_migration/test/abstract_context.dart b/pkg/nnbd_migration/test/abstract_context.dart
index 88ee434..3d5267f 100644
--- a/pkg/nnbd_migration/test/abstract_context.dart
+++ b/pkg/nnbd_migration/test/abstract_context.dart
@@ -41,6 +41,8 @@
String get homePath => '/home';
+ Folder get sdkRoot => newFolder('/sdk');
+
AnalysisSession get session => driver!.currentSession;
String get testsPath => '$homePath/tests';
@@ -164,7 +166,10 @@
setupResourceProvider();
overlayResourceProvider = OverlayResourceProvider(resourceProvider);
- MockSdk(resourceProvider: resourceProvider);
+ createMockSdk(
+ resourceProvider: resourceProvider,
+ root: sdkRoot,
+ );
newFolder(testsPath);
newFile('$testsPath/.packages', content: '''
@@ -217,7 +222,7 @@
includedPaths: [convertPath(homePath)],
enableIndex: true,
resourceProvider: overlayResourceProvider,
- sdkPath: convertPath('/sdk'),
+ sdkPath: sdkRoot.path,
);
_driver = getDriver(convertPath(testsPath));
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index e4df376..08b16bc 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -41,6 +41,8 @@
});
}
+const sdkRootPathPosix = '/sdk';
+
/// Specialization of [InstrumentationListener] that generates artificial
/// exceptions, so that we can test they are properly propagated to top level.
class _ExceptionGeneratingInstrumentationListener
@@ -97,7 +99,7 @@
binaryName: 'nnbd_migration',
loggerFactory: (isVerbose) => _test.logger = TestLogger(isVerbose),
defaultSdkPathOverride:
- _test.resourceProvider.convertPath(mock_sdk.sdkRoot),
+ _test.resourceProvider.convertPath(sdkRootPathPosix),
resourceProvider: _test.resourceProvider,
environmentVariables: _test.environmentVariables);
@@ -450,7 +452,7 @@
// the signature that was present prior to NNBD. (This is what the
// migration tool uses to detect an old SDK).
var coreLib = resourceProvider.getFile(
- resourceProvider.convertPath('${mock_sdk.sdkRoot}/lib/core/core.dart'));
+ resourceProvider.convertPath('$sdkRootPathPosix/lib/core/core.dart'));
var oldCoreLibText = coreLib.readAsStringSync();
var newCoreLibText = oldCoreLibText.replaceAll(
'external bool operator ==(Object other)',
@@ -470,7 +472,7 @@
// the signature that was present prior to NNBD. (This is what the
// migration tool uses to detect an old SDK).
var coreLib = resourceProvider.getFile(
- resourceProvider.convertPath('${mock_sdk.sdkRoot}/lib/core/core.dart'));
+ resourceProvider.convertPath('$sdkRootPathPosix/lib/core/core.dart'));
var oldCoreLibText = coreLib.readAsStringSync();
var newCoreLibText = oldCoreLibText.replaceAll(
'external bool operator ==(Object other)',
@@ -597,7 +599,7 @@
var projectContents = createProject();
var projectDir = createProjectDir(projectContents);
- var cliRunner = _createCli(nullSafePackages: ['test'])
+ var cliRunner = _createCli()
.decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]))!;
await cliRunner.run();
assertNormalExit(cliRunner);
@@ -2140,58 +2142,6 @@
'''));
}
- test_pubspec_with_sdk_version_beta() async {
- var projectDir = createProjectDir(simpleProject());
- var cliRunner = _createCli(sdkVersion: '2.12.0-1.2.beta')
- .decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]))!;
- await cliRunner.run();
- assertProjectContents(
- projectDir, simpleProject(migrated: true, pubspecText: '''
-name: test
-environment:
- sdk: '>=2.12.0-1.2.beta <3.0.0'
-'''));
- }
-
- test_pubspec_with_sdk_version_dev() async {
- var projectDir = createProjectDir(simpleProject());
- var cliRunner = _createCli(sdkVersion: '2.12.0-1.2.dev')
- .decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]))!;
- await cliRunner.run();
- assertProjectContents(
- projectDir, simpleProject(migrated: true, pubspecText: '''
-name: test
-environment:
- sdk: '>=2.12.0-0 <3.0.0'
-'''));
- }
-
- test_pubspec_with_sdk_version_edge() async {
- var projectDir = createProjectDir(simpleProject());
- var cliRunner = _createCli(sdkVersion: '2.12.0-edge.1234567')
- .decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]))!;
- await cliRunner.run();
- assertProjectContents(
- projectDir, simpleProject(migrated: true, pubspecText: '''
-name: test
-environment:
- sdk: '>=2.12.0-0 <3.0.0'
-'''));
- }
-
- test_pubspec_with_sdk_version_internal() async {
- var projectDir = createProjectDir(simpleProject());
- var cliRunner = _createCli(sdkVersion: '2.12.0-1234567')
- .decodeCommandLineArgs(_parseArgs(['--apply-changes', projectDir]))!;
- await cliRunner.run();
- assertProjectContents(
- projectDir, simpleProject(migrated: true, pubspecText: '''
-name: test
-environment:
- sdk: '>=2.12.0-0 <3.0.0'
-'''));
- }
-
test_uses_physical_resource_provider_by_default() {
var cli = MigrationCli(binaryName: 'nnbd_migration');
expect(cli.resourceProvider, same(PhysicalResourceProvider.INSTANCE));
@@ -2206,12 +2156,13 @@
headers: {'Content-Type': 'application/json; charset=UTF-8'});
}
- _MigrationCli _createCli(
- {List<String> nullSafePackages = const [], String? sdkVersion}) {
- mock_sdk.MockSdk(
- resourceProvider: resourceProvider,
- nullSafePackages: nullSafePackages,
- sdkVersion: sdkVersion);
+ _MigrationCli _createCli() {
+ mock_sdk.createMockSdk(
+ resourceProvider: resourceProvider,
+ root: resourceProvider.newFolder(
+ resourceProvider.convertPath(sdkRootPathPosix),
+ ),
+ );
return _MigrationCli(this);
}
diff --git a/pkg/test_runner/lib/src/configuration.dart b/pkg/test_runner/lib/src/configuration.dart
index 2201710..51110c0 100644
--- a/pkg/test_runner/lib/src/configuration.dart
+++ b/pkg/test_runner/lib/src/configuration.dart
@@ -31,7 +31,6 @@
this.testList,
this.repeat,
this.batch,
- this.batchDart2JS,
this.copyCoreDumps,
this.rr,
this.isVerbose,
@@ -81,7 +80,6 @@
// Boolean flags.
final bool batch;
- final bool batchDart2JS;
final bool build;
final bool copyCoreDumps;
final bool rr;
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index fe3b012..bfe16f6 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -263,9 +263,7 @@
_Option('output_directory',
'The name of the output directory for storing log files.',
defaultsTo: "logs", hide: true),
- _Option.bool('noBatch', 'Do not run tests in batch mode.', hide: true),
- _Option.bool('dart2js_batch', 'Run dart2js tests in batch mode.',
- hide: true),
+ _Option.bool('no_batch', 'Do not run tests in batch mode.', hide: true),
_Option.bool('write_debug_log',
'Don\'t write debug messages to stdout but rather to a logfile.',
hide: true),
@@ -744,8 +742,7 @@
build: data["build"] as bool,
testList: data["test_list_contents"] as List<String>,
repeat: data["repeat"] as int,
- batch: !(data["noBatch"] as bool),
- batchDart2JS: data["dart2js_batch"] as bool,
+ batch: !(data["no_batch"] as bool),
copyCoreDumps: data["copy_coredumps"] as bool,
rr: data["rr"] as bool,
isVerbose: data["verbose"] as bool,
diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart
index 2943b26..2965f44 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -568,16 +568,12 @@
assert(name == 'vm_compile_to_kernel');
return _getBatchRunner(name)
.runCommand(name, command, timeout, command.arguments);
- } else if (command is CompilationCommand &&
- globalConfiguration.batchDart2JS &&
- command.displayName == 'dart2js') {
- return _getBatchRunner("dart2js")
- .runCommand("dart2js", command, timeout, command.arguments);
} else if (command is AnalysisCommand && globalConfiguration.batch) {
return _getBatchRunner(command.displayName)
.runCommand(command.displayName, command, timeout, command.arguments);
} else if (command is CompilationCommand &&
- (command.displayName == 'dartdevc' ||
+ (command.displayName == 'dart2js' ||
+ command.displayName == 'dartdevc' ||
command.displayName == 'dartdevk' ||
command.displayName == 'fasta') &&
globalConfiguration.batch) {
diff --git a/pkg/test_runner/lib/src/test_configurations.dart b/pkg/test_runner/lib/src/test_configurations.dart
index bbacb13..6d7f1f8 100644
--- a/pkg/test_runner/lib/src/test_configurations.dart
+++ b/pkg/test_runner/lib/src/test_configurations.dart
@@ -268,8 +268,7 @@
await Future.wait(serverFutures);
}
- // [firstConf] is needed here, since the ProcessQueue needs to know the
- // settings of 'noBatch' and 'local_ip'
+ // [firstConf] is needed here, because the ProcessQueue uses some settings.
ProcessQueue(firstConf, maxProcesses, maxBrowserProcesses, testSuites,
eventListener, allTestsFinished, verbose, adbDevicePool);
}
diff --git a/pkg/test_runner/test/test_runner_test.dart b/pkg/test_runner/test/test_runner_test.dart
index 3d9ab93..2fd217a 100644
--- a/pkg/test_runner/test/test_runner_test.dart
+++ b/pkg/test_runner/test/test_runner_test.dart
@@ -120,7 +120,7 @@
void testProcessQueue() {
var maxProcesses = 2;
var maxBrowserProcesses = maxProcesses;
- var config = OptionsParser().parse(['--noBatch'])[0];
+ var config = OptionsParser().parse(['--no-batch'])[0];
ProcessQueue(config, maxProcesses, maxBrowserProcesses,
[CustomTestSuite(config)], [EventListener()], TestController.finished);
}
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 4316715..cb866c8 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -18,12 +18,12 @@
import '../transformations/call_site_annotator.dart' as callSiteAnnotator;
import '../transformations/lowering.dart' as lowering
show transformLibraries, transformProcedure;
-import '../transformations/ffi.dart' as ffiHelper show importsFfi;
-import '../transformations/ffi_definitions.dart' as transformFfiDefinitions
+import '../transformations/ffi/common.dart' as ffiHelper show importsFfi;
+import '../transformations/ffi/definitions.dart' as transformFfiDefinitions
show transformLibraries;
-import '../transformations/ffi_native.dart' as transformFfiNative
+import '../transformations/ffi/native.dart' as transformFfiNative
show transformLibraries;
-import '../transformations/ffi_use_sites.dart' as transformFfiUseSites
+import '../transformations/ffi/use_sites.dart' as transformFfiUseSites
show transformLibraries;
/// Specializes the kernel IR to the Dart VM.
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi/common.dart
similarity index 100%
rename from pkg/vm/lib/transformations/ffi.dart
rename to pkg/vm/lib/transformations/ffi/common.dart
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi/definitions.dart
similarity index 99%
rename from pkg/vm/lib/transformations/ffi_definitions.dart
rename to pkg/vm/lib/transformations/ffi/definitions.dart
index f9ef464..49a4b8d 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi/definitions.dart
@@ -31,7 +31,7 @@
import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
import 'package:kernel/util/graph.dart';
-import 'ffi.dart';
+import 'common.dart';
/// Checks and elaborates the dart:ffi compounds and their fields.
///
diff --git a/pkg/vm/lib/transformations/ffi_native.dart b/pkg/vm/lib/transformations/ffi/native.dart
similarity index 98%
rename from pkg/vm/lib/transformations/ffi_native.dart
rename to pkg/vm/lib/transformations/ffi/native.dart
index ebd2cf6..bf8a531 100644
--- a/pkg/vm/lib/transformations/ffi_native.dart
+++ b/pkg/vm/lib/transformations/ffi/native.dart
@@ -17,7 +17,7 @@
import 'package:kernel/target/targets.dart' show DiagnosticReporter;
import 'package:kernel/type_environment.dart';
-import 'ffi.dart' show FfiTransformer;
+import 'common.dart' show FfiTransformer;
/// Transform @FfiNative annotated functions into FFI native function pointer
/// functions.
@@ -180,6 +180,13 @@
named: [NamedExpression('isLeaf', BoolLiteral(isLeaf.value))]))
..fileOffset = fileOffset;
+ var fileUri = currentLibrary.fileUri;
+ if (parent is Class) {
+ fileUri = parent.fileUri;
+ } else if (parent is Library) {
+ fileUri = parent.fileUri;
+ }
+
// static final _doXyz$FfiNative$Ptr = ...
final fieldName =
Name('_$dartFunctionName\$FfiNative\$Ptr', currentLibrary);
@@ -188,7 +195,7 @@
initializer: asFunctionInvocation,
isStatic: true,
isFinal: true,
- fileUri: currentLibrary.fileUri,
+ fileUri: fileUri,
getterReference: currentLibraryIndex?.lookupGetterReference(fieldName))
..fileOffset = fileOffset;
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi/use_sites.dart
similarity index 99%
rename from pkg/vm/lib/transformations/ffi_use_sites.dart
rename to pkg/vm/lib/transformations/ffi/use_sites.dart
index 403feb9..744bc00 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi/use_sites.dart
@@ -26,7 +26,7 @@
import 'package:kernel/type_algebra.dart' show Substitution;
import 'package:kernel/type_environment.dart';
-import 'ffi.dart'
+import 'common.dart'
show
NativeType,
FfiTransformer,
diff --git a/pkg/vm/lib/transformations/ffi_checks.md b/pkg/vm/lib/transformations/ffi_checks.md
deleted file mode 100644
index ed1ce41..0000000
--- a/pkg/vm/lib/transformations/ffi_checks.md
+++ /dev/null
@@ -1,69 +0,0 @@
-# FFI static checks
-
-## Translating FFI types
-
-The FFI library defines a number of "native" types, which have corresponding
-Dart types. This is a many-to-one mapping, defined by `DartRepresentationOf` in
-`native_type.dart`.
-
-## Subtyping restrictions
-
-No class may extend, implement or mixin any classes inside the FFI library, with
-the following exception. Any class may extend (but not implement or mixin)
-`ffi.Struct`. In this case, the subclass is considered a *struct class*. No
-class may extend, implement or mixin a struct class.
-
-## Struct rules
-
-The following restrictions apply to struct classes:
-
-- A struct class must not be generic.
-- A struct class `X` must extend `Struct<X>`. That is, the type argument to the
- superclass must be exactly the subclass itself.
-
-Some restrictions apply to fields of struct classes:
-
-- A field of a struct class must not have an initializer.
-- A field of a struct class must either have a type which is a subtype of
- `ffi.Pointer` or else be annotated by one of the following types:
- - `ffi.UintN` or `ffi.IntN` for any N
- - `ffi.Float` or `ffi.Double`
- If the field is annotated, the Dart version of the annotated type must be
- identical to the field's declared type. Note that struct classes currently
- must not be used as fields.
-- A field of a struct class must not have more than one annotation corresponding
- to an FFI native type.
-
-Finally, struct classes must not have constructors with field initializers.
-
-## `fromFunction` rules
-
-The following restrictions apply to static invocations of the factory
-constructor `Pointer<T>.fromFunction(f, e)`. Dynamic invocations of this method,
-e.g. through mirrors, are runtime errors. `T` must be a subtype of
-`NativeFunction<T'>` for some `T'`. Let `F` be the Dart type which corresponds
-to static type of `T'` and `R` be the return type of `F`.
-
-- `T` must be instantiated; i.e., it must not reference any class or function
- type parameters.
-- The static type of `f` must be a subtype of `F`.
-- Struct classes are not allowed as the top-level class in a parameter or return
- type of `F`.
-- The static type of `e` must be a subtype of `R`.
-- `e` must be an expression which is legal in a constant context.
-- `f` must be a direct reference to a top-level method.
-- `e` must not be provided if `R` is `void` or `ffi.Pointer`.
-- `e` must be provided otherwise.
-
-## `asFunction` and `lookupFunction ` rules
-
-The following restrictions apply to statically resolved invocations of the
-instance method `Pointer<T>.asFunction<F>()` and
-`DynamicLibrary.lookupFunction<S, F>()`. Dynamic invocations of these methods,
-e.g. through mirrors or a receiver of static type `dynamic`, are runtime errors.
-`T` must be a subtype of `NativeFunction<T'>` for some `T'`. Let `F'` be the
-Dart type which corresponds to static type of `T'`/`S`.
-
-- `T`, `S` and `F` must be constants; i.e., they must not reference any class or
- function type parameters.
-- `F'` must be a subtype of `F`.
diff --git a/pkg/vm/test/transformations/ffinative_test.dart b/pkg/vm/test/transformations/ffinative_test.dart
index dfcb6f4..a6326a1 100644
--- a/pkg/vm/test/transformations/ffinative_test.dart
+++ b/pkg/vm/test/transformations/ffinative_test.dart
@@ -13,7 +13,7 @@
import 'package:test/test.dart';
-import 'package:vm/transformations/ffi_native.dart' show transformLibraries;
+import 'package:vm/transformations/ffi/native.dart' show transformLibraries;
import '../common_test_utils.dart';
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 727ccb9..ea7d40d 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -203,6 +203,7 @@
frameworks = [
"CoreFoundation.framework",
"CoreServices.framework",
+ "Foundation.framework",
]
}
@@ -336,6 +337,12 @@
"io_natives.cc",
"io_natives.h",
]
+ if (is_ios || is_mac) {
+ sources += [
+ "platform_macos_cocoa.h",
+ "platform_macos_cocoa.mm",
+ ]
+ }
include_dirs = [
"..",
@@ -412,6 +419,7 @@
frameworks = [
"CoreFoundation.framework",
"Security.framework",
+ "Foundation.framework",
]
if (is_mac) {
@@ -437,6 +445,12 @@
"io_natives.cc",
"io_natives.h",
] + extra_sources
+ if (is_ios || is_mac) {
+ sources += [
+ "platform_macos_cocoa.h",
+ "platform_macos_cocoa.mm",
+ ]
+ }
if (is_linux || is_win || is_fuchsia) {
if (dart_use_fallback_root_certificates) {
diff --git a/runtime/bin/io_impl_sources.gni b/runtime/bin/io_impl_sources.gni
index 8c368bb..33090f3 100644
--- a/runtime/bin/io_impl_sources.gni
+++ b/runtime/bin/io_impl_sources.gni
@@ -109,7 +109,4 @@
"typed_data_utils.h",
]
-io_impl_tests = [
- "platform_macos_test.cc",
- "secure_socket_utils_test.cc",
-]
+io_impl_tests = [ "secure_socket_utils_test.cc" ]
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 26f40a4..0c22675 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -22,8 +22,11 @@
#include <sys/utsname.h> // NOLINT
#include <unistd.h> // NOLINT
+#include <string>
+
#include "bin/console.h"
#include "bin/file.h"
+#include "bin/platform_macos_cocoa.h"
namespace dart {
namespace bin {
@@ -113,89 +116,9 @@
#endif
}
-char* ExtractsOSVersionFromString(char* str) {
- char* pos = strstr(str, "<key>ProductVersion</key>");
- if (pos == NULL) {
- return NULL;
- }
- pos = strstr(pos, "<string>");
- if (pos == NULL) {
- return NULL;
- }
- // Shift the index by the length of "<string>".
- pos += 8;
- char* end_pos = strstr(pos, "</string>");
- if (end_pos == NULL) {
- return NULL;
- }
-
- int length = end_pos - pos;
- char* result =
- reinterpret_cast<char*>(Dart_ScopeAllocate(length * sizeof(char)) + 1);
- strncpy(result, pos, length);
- result[length] = '\0';
- return result;
-}
-
-static char* GetOSVersionFromPlist() {
- const char* path = "/System/Library/CoreServices/SystemVersion.plist";
- File* file = File::Open(NULL, path, File::kRead);
- if (file == NULL) {
- return NULL;
- }
- int length = file->Length();
- if (length < 0) {
- return NULL;
- }
- char* buffer =
- reinterpret_cast<char*>(Dart_ScopeAllocate(length * sizeof(char) + 1));
- int bytes = file->ReadFully(buffer, length);
- buffer[length * sizeof(char)] = '\0';
- file->Close();
- file->Release();
- if (bytes < 0) {
- return NULL;
- }
- return ExtractsOSVersionFromString(buffer);
-}
-
const char* Platform::OperatingSystemVersion() {
- char str[64];
- size_t size = sizeof(str);
- // This is only available to some versions later than 10.13.*. If it failed,
- // try to read from "SystemVersion.plist".
- int res = sysctlbyname("kern.osproductversion", str, &size, NULL, 0);
- if (res == 0) {
- int len = snprintf(NULL, 0, "%s", str);
- char* result_string = DartUtils::ScopedCString(len + 1);
- strncpy(result_string, str, len);
- result_string[len] = '\0';
- return result_string;
- }
- char* result_string = GetOSVersionFromPlist();
- if (result_string != NULL) {
- return result_string;
- }
-
- struct utsname info;
- int ret = uname(&info);
- if (ret != 0) {
- return NULL;
- }
- const char* kFormat = "%s %s %s";
- int len =
- snprintf(NULL, 0, kFormat, info.sysname, info.release, info.version);
- if (len <= 0) {
- return NULL;
- }
- char* result = DartUtils::ScopedCString(len + 1);
- ASSERT(result != NULL);
- len = snprintf(result, len + 1, kFormat, info.sysname, info.release,
- info.version);
- if (len <= 0) {
- return NULL;
- }
- return result;
+ std::string version(NSProcessInfoOperatingSystemVersionString());
+ return DartUtils::ScopedCopyCString(version.c_str());
}
const char* Platform::LibraryPrefix() {
diff --git a/runtime/bin/platform_macos_cocoa.h b/runtime/bin/platform_macos_cocoa.h
new file mode 100644
index 0000000..b166432
--- /dev/null
+++ b/runtime/bin/platform_macos_cocoa.h
@@ -0,0 +1,30 @@
+// 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.
+
+#ifndef RUNTIME_BIN_PLATFORM_MACOS_COCOA_H_
+#define RUNTIME_BIN_PLATFORM_MACOS_COCOA_H_
+
+// platform_macos_cocoa[.h,.mm] defines a new compilation unit, written
+// in Objective-C++, that acts as a minimal bridge between platform_macos
+// and the Cocoa (https://en.wikipedia.org/wiki/Cocoa_(API)) API.
+
+#include "platform/globals.h"
+
+#if !defined(DART_HOST_OS_MACOS)
+#error Do not include platform_macos_cocoa.h on non-MacOS platforms.
+#endif
+
+#include <string>
+
+namespace dart {
+namespace bin {
+
+// Return the operating system version string.
+// See https://developer.apple.com/documentation/foundation/nsprocessinfo/1408730-operatingsystemversionstring.
+std::string NSProcessInfoOperatingSystemVersionString();
+
+} // namespace bin
+} // namespace dart
+
+#endif // RUNTIME_BIN_PLATFORM_MACOS_COCOA_H_
diff --git a/runtime/bin/platform_macos_cocoa.mm b/runtime/bin/platform_macos_cocoa.mm
new file mode 100644
index 0000000..4a364e9
--- /dev/null
+++ b/runtime/bin/platform_macos_cocoa.mm
@@ -0,0 +1,29 @@
+// 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.
+
+#include "platform/globals.h"
+
+#if !defined(DART_HOST_OS_MACOS)
+#error Do not build platform_macos_cocoa.mm on non-MacOS platforms.
+#endif
+
+#include "bin/platform_macos_cocoa.h"
+
+#import <Foundation/NSProcessInfo.h>
+#import <Foundation/NSString.h>
+
+namespace dart {
+namespace bin {
+
+std::string NSProcessInfoOperatingSystemVersionString() {
+ @autoreleasepool {
+ // `operatingSystemVersionString` has been available since iOS 2.0+ and macOS 10.2+.
+ NSString* version =
+ [[NSProcessInfo processInfo] operatingSystemVersionString];
+ return std::string([version UTF8String]);
+ }
+}
+
+} // namespace bin
+} // namespace dart
diff --git a/runtime/bin/platform_macos_test.cc b/runtime/bin/platform_macos_test.cc
deleted file mode 100644
index 3c37901..0000000
--- a/runtime/bin/platform_macos_test.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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.
-
-#if defined(DART_HOST_OS_MACOS)
-#include "bin/platform.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-TEST_CASE(Platform_ExtractsOSVersionFromString) {
- char str[] =
- "some overheads\n<key>ProductVersion</key>\nsome bytes<string>Fake "
- "version</string>";
- char* result = bin::ExtractsOSVersionFromString(str);
- EXPECT(result != NULL);
- EXPECT_STREQ("Fake version", result);
-
- EXPECT(bin::ExtractsOSVersionFromString("<key>ProductVersion</key>") == NULL);
-
- // Incomplete file
- EXPECT(bin::ExtractsOSVersionFromString(
- "<key>ProductVersion</key><string>Fake version</string") != NULL);
-
- // A copy of actual SystemVersion.plist on mac.
- str =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
- "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
- "<plist version=\"1.0\">\n"
- "<dict>\n"
- " <key>ProductBuildVersion</key>\n"
- " <string>19E287</string>\n"
- " <key>ProductCopyright</key>\n"
- " <string>1983-2020 Apple Inc.</string>\n"
- " <key>ProductName</key>\n"
- " <string>Mac OS X</string>\n"
- " <key>ProductUserVisibleVersion</key>\n"
- " <string>10.15.4</string>\n"
- " <key>ProductVersion</key>\n"
- " <string>10.15.4</string>\n"
- " <key>iOSSupportVersion</key>\n"
- " <string>13.4</string>\n"
- "</dict>\n"
- "</plist>"
-
- result = bin::ExtractsOSVersionFromString(str);
- EXPECT(result != NULL);
- EXPECT_STREQ("10.15.4", result);
-}
-
-} // namespace dart
-#endif // defined(DART_HOST_OS_MACOS)
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index aa96c5a..ce64f09 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -6082,14 +6082,14 @@
compiler::Label* deopt =
compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op);
- __ tbnz(deopt, right, kBitsPerWord - 1);
+ __ tbnz(deopt, right, compiler::target::kSmiBits + 1);
}
EmitShiftUint32ByRegister(compiler, op_kind(), out, left, right);
if (!shift_count_in_range) {
// If shift value is > 31, return zero.
- __ CompareImmediate(right, 31);
+ __ CompareImmediate(right, 31, compiler::kObjectBytes);
__ csel(out, out, ZR, LE);
}
}
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index b3c92e0..2ad4305 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -6608,12 +6608,12 @@
compiler::Label* deopt =
compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op);
- __ testq(RCX, RCX);
+ __ OBJ(test)(RCX, RCX);
__ j(LESS, deopt);
}
compiler::Label cont;
- __ cmpq(RCX, compiler::Immediate(kUint32ShiftCountLimit));
+ __ OBJ(cmp)(RCX, compiler::Immediate(kUint32ShiftCountLimit));
__ j(LESS_EQUAL, &cont);
__ xorl(left, left);
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index 8897dda..7cc5b8c 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -1109,8 +1109,10 @@
// TODO(rmacnak): Investigate collecting a history of idle period durations.
intptr_t used_in_words = UsedInWords();
+ intptr_t external_in_words = ExternalInWords();
// Normal reason: new space is getting full.
- bool for_new_space = used_in_words >= idle_scavenge_threshold_in_words_;
+ bool for_new_space = (used_in_words >= idle_scavenge_threshold_in_words_) ||
+ (external_in_words >= idle_scavenge_threshold_in_words_);
// New-space objects are roots during old-space GC. This means that even
// unreachable new-space objects prevent old-space objects they reference
// from being collected during an old-space GC. Normally this is not an
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 1581c44..ad7d3bc 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -40,6 +40,7 @@
- [evaluateInFrame](#evaluateinframe)
- [getAllocationProfile](#getallocationprofile)
- [getAllocationTraces](#getallocationtraces)
+ - [getClassList](#getclasslist)
- [getCpuSamples](#getcpusamples)
- [getFlagList](#getflaglist)
- [getInstances](#getinstances)
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index b0482a8..49845a2 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -139,10 +139,6 @@
categories: "Client",
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM),
- "web_sql": const LibraryInfo("web_sql/dart2js/web_sql_dart2js.dart",
- categories: "Client",
- maturity: Maturity.WEB_STABLE,
- platforms: DART2JS_PLATFORM),
"_internal": const LibraryInfo("internal/internal.dart",
categories: "",
documented: false,
diff --git a/sdk/lib/_internal/vm/lib/math_patch.dart b/sdk/lib/_internal/vm/lib/math_patch.dart
index cc1c7c0..270bbbc 100644
--- a/sdk/lib/_internal/vm/lib/math_patch.dart
+++ b/sdk/lib/_internal/vm/lib/math_patch.dart
@@ -206,6 +206,8 @@
// TODO(iposva): Handle patch methods within a patch class correctly.
@patch
class Random {
+ static final Random _secureRandom = _SecureRandom();
+
@patch
factory Random([int? seed]) {
var state = _Random._setupSeed((seed == null) ? _Random._nextSeed() : seed);
@@ -218,9 +220,7 @@
}
@patch
- factory Random.secure() {
- return new _SecureRandom();
- }
+ factory Random.secure() => _secureRandom;
}
class _Random implements Random {
diff --git a/sdk/lib/core/exceptions.dart b/sdk/lib/core/exceptions.dart
index 5904ec5..889c991 100644
--- a/sdk/lib/core/exceptions.dart
+++ b/sdk/lib/core/exceptions.dart
@@ -166,8 +166,11 @@
// Exception thrown when doing integer division with a zero divisor.
// TODO(30743): Should be removed, and division by zero should just throw an
-// [ArgumentError].
-class IntegerDivisionByZeroException implements Exception {
+// [UnsupportedError].
+@Deprecated("Use UnsupportedError instead")
+class IntegerDivisionByZeroException implements Exception, UnsupportedError {
+ String? get message => "Division resulted in non-finite value";
+ StackTrace? get stackTrace => null;
@pragma("vm:entry-point")
const IntegerDivisionByZeroException();
String toString() => "IntegerDivisionByZeroException";
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index 74dfd78..f7b72a5 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.dart
@@ -142,11 +142,19 @@
/// Truncating division operator.
///
- /// If either operand is a [double] then the result of the truncating division
- /// `a ~/ b` is equivalent to `(a / b).truncate().toInt()`.
+ /// Performs truncating division of this number by [other].
+ /// Truncating division is division where a fractional result
+ /// is converted to an integer by rounding towards zero.
///
- /// If both operands are [int]s then `a ~/ b` performs the truncating
- /// integer division.
+ /// If both operands are [int]s then [other] must not be zero.
+ /// Then `a ~/ b` corresponds to `a.remainder(b)`
+ /// such that `a == (a ~/ b) * b + a.remainder(b)`.
+ ///
+ /// If either operand is a [double] then the other operand is converted
+ /// to a double before performing the division and truncation of the result.
+ /// Then `a ~/ b` is equivalent to `(a / b).truncate()`.
+ /// This means that the intermediate result of the double division
+ /// must be a finite integer (not an infinity or [double.nan]).
int operator ~/(num other);
/// The negation of this value.
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 5d53fb1..0bdc1ef 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -31,7 +31,6 @@
import 'dart:web_audio' show AudioBuffer, AudioTrack, AudioTrackList;
import 'dart:web_gl' as gl;
import 'dart:web_gl' show RenderingContext, RenderingContext2;
-import 'dart:web_sql';
import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
import 'dart:js_util' as js_util;
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -9212,13 +9211,6 @@
// WARNING: Do not edit - generated code.
-typedef void DatabaseCallback(SqlDatabase database);
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
typedef void DecodeErrorCallback(DomException error);
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -32982,16 +32974,6 @@
@JSName('moveTo')
void _moveTo(int x, int y) native;
- @JSName('openDatabase')
-
- /// *Deprecated.*
- @SupportedBrowser(SupportedBrowser.CHROME)
- @SupportedBrowser(SupportedBrowser.SAFARI)
- @Creates('SqlDatabase')
- SqlDatabase _openDatabase(
- String name, String version, String displayName, int estimatedSize,
- [DatabaseCallback? creationCallback]) native;
-
void postMessage(/*any*/ message, String targetOrigin,
[List<Object>? transfer]) {
if (transfer != null) {
@@ -33679,26 +33661,6 @@
_moveTo(p.x.toInt(), p.y.toInt());
}
- @JSName('openDatabase')
- @SupportedBrowser(SupportedBrowser.CHROME)
- @SupportedBrowser(SupportedBrowser.SAFARI)
- @Creates('SqlDatabase')
- @deprecated
- SqlDatabase openDatabase(
- String name, String version, String displayName, int estimatedSize,
- [DatabaseCallback? creationCallback]) {
- var db;
- if (creationCallback == null)
- db = _openDatabase(name, version, displayName, estimatedSize);
- else
- db = _openDatabase(
- name, version, displayName, estimatedSize, creationCallback);
-
- applyExtension('Database', db);
-
- return db;
- }
-
int get pageXOffset => JS<num>('num', '#.pageXOffset', this).round();
int get pageYOffset => JS<num>('num', '#.pageYOffset', this).round();
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index 72053f5..06dd98f 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -121,7 +121,7 @@
/// "mycomputer"
///
/// Uses the platform
- /// [`gethostname`](https://pubs.opengroup.org/onlinepubs/9699919799/)
+ /// [`gethostname`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html)
/// implementation.
static String get localHostname => _localHostname;
diff --git a/sdk/lib/js_util/js_util.dart b/sdk/lib/js_util/js_util.dart
index db385b6..7842a32 100644
--- a/sdk/lib/js_util/js_util.dart
+++ b/sdk/lib/js_util/js_util.dart
@@ -64,65 +64,63 @@
return _convert(data)!;
}
-dynamic newObject() => JS('=Object', '{}');
+T newObject<T>() => JS('=Object', '{}');
bool hasProperty(Object o, Object name) => JS('bool', '# in #', name, o);
-// A CFE transformation will optimize all calls to `getProperty`.
-dynamic getProperty(Object o, Object name) =>
- JS('Object|Null', '#[#]', o, name);
+T getProperty<T>(Object o, Object name) => JS('Object|Null', '#[#]', o, name);
// A CFE transformation may optimize calls to `setProperty`, when [value] is
// statically known to be a non-function.
-dynamic setProperty(Object o, Object name, Object? value) {
+T setProperty<T>(Object o, Object name, T? value) {
assertInterop(value);
return JS('', '#[#]=#', o, name, value);
}
/// Unchecked version of setProperty, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _setPropertyUnchecked(Object o, Object name, Object? value) {
+T _setPropertyUnchecked<T>(Object o, Object name, T? value) {
return JS('', '#[#]=#', o, name, value);
}
// A CFE transformation may optimize calls to `callMethod` when [args] is a
// a list literal or const list containing at most 4 values, all of which are
// statically known to be non-functions.
-dynamic callMethod(Object o, String method, List<Object?> args) {
+T callMethod<T>(Object o, String method, List<Object?> args) {
assertInteropArgs(args);
return JS('Object|Null', '#[#].apply(#, #)', o, method, o, args);
}
/// Unchecked version for 0 arguments, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _callMethodUnchecked0(Object o, String method) {
+T _callMethodUnchecked0<T>(Object o, String method) {
return JS('Object|Null', '#[#]()', o, method);
}
/// Unchecked version for 1 argument, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _callMethodUnchecked1(Object o, String method, Object? arg1) {
+T _callMethodUnchecked1<T>(Object o, String method, Object? arg1) {
return JS('Object|Null', '#[#](#)', o, method, arg1);
}
/// Unchecked version for 2 arguments, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _callMethodUnchecked2(
+T _callMethodUnchecked2<T>(
Object o, String method, Object? arg1, Object? arg2) {
return JS('Object|Null', '#[#](#, #)', o, method, arg1, arg2);
}
/// Unchecked version for 3 arguments, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _callMethodUnchecked3(
+T _callMethodUnchecked3<T>(
Object o, String method, Object? arg1, Object? arg2, Object? arg3) {
return JS('Object|Null', '#[#](#, #, #)', o, method, arg1, arg2, arg3);
}
/// Unchecked version for 4 arguments, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _callMethodUnchecked4(Object o, String method, Object? arg1,
- Object? arg2, Object? arg3, Object? arg4) {
+T _callMethodUnchecked4<T>(Object o, String method, Object? arg1, Object? arg2,
+ Object? arg3, Object? arg4) {
return JS(
'Object|Null', '#[#](#, #, #, #)', o, method, arg1, arg2, arg3, arg4);
}
@@ -134,7 +132,7 @@
bool instanceof(Object? o, Object type) =>
JS('bool', '# instanceof #', o, type);
-dynamic callConstructor(Object constr, List<Object?>? arguments) {
+T callConstructor<T>(Object constr, List<Object?>? arguments) {
if (arguments == null) {
return JS('Object', 'new #()', constr);
} else {
@@ -197,32 +195,32 @@
/// Unchecked version for 0 arguments, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _callConstructorUnchecked0(Object constr) {
+T _callConstructorUnchecked0<T>(Object constr) {
return JS('Object', 'new #()', constr);
}
/// Unchecked version for 1 argument, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _callConstructorUnchecked1(Object constr, Object? arg1) {
+T _callConstructorUnchecked1<T>(Object constr, Object? arg1) {
return JS('Object', 'new #(#)', constr, arg1);
}
/// Unchecked version for 2 arguments, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _callConstructorUnchecked2(Object constr, Object? arg1, Object? arg2) {
+T _callConstructorUnchecked2<T>(Object constr, Object? arg1, Object? arg2) {
return JS('Object', 'new #(#, #)', constr, arg1, arg2);
}
/// Unchecked version for 3 arguments, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _callConstructorUnchecked3(
+T _callConstructorUnchecked3<T>(
Object constr, Object? arg1, Object? arg2, Object? arg3) {
return JS('Object', 'new #(#, #, #)', constr, arg1, arg2, arg3);
}
/// Unchecked version for 4 arguments, only used in a CFE transformation.
@pragma('dart2js:tryInline')
-dynamic _callConstructorUnchecked4(
+T _callConstructorUnchecked4<T>(
Object constr, Object? arg1, Object? arg2, Object? arg3, Object? arg4) {
return JS('Object', 'new #(#, #, #, #)', constr, arg1, arg2, arg3, arg4);
}
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 2ca5b70..c59dc6f 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -231,9 +231,6 @@
"web_gl": {
"uri": "web_gl/dart2js/web_gl_dart2js.dart"
},
- "web_sql": {
- "uri": "web_sql/dart2js/web_sql_dart2js.dart"
- },
"_dart2js_runtime_metrics": {
"uri": "_internal/js_runtime/lib/dart2js_runtime_metrics.dart"
},
@@ -476,10 +473,7 @@
},
"web_gl": {
"uri": "web_gl/dart2js/web_gl_dart2js.dart"
- },
- "web_sql": {
- "uri": "web_sql/dart2js/web_sql_dart2js.dart"
}
}
}
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index 1066ab0..812487a 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -229,9 +229,6 @@
web_gl:
uri: "web_gl/dart2js/web_gl_dart2js.dart"
- web_sql:
- uri: "web_sql/dart2js/web_sql_dart2js.dart"
-
_dart2js_runtime_metrics:
uri: "_internal/js_runtime/lib/dart2js_runtime_metrics.dart"
@@ -470,6 +467,3 @@
web_gl:
uri: "web_gl/dart2js/web_gl_dart2js.dart"
-
- web_sql:
- uri: "web_sql/dart2js/web_sql_dart2js.dart"
diff --git a/tests/corelib/duration_test.dart b/tests/corelib/duration_test.dart
index 1f8c543..7080723 100644
--- a/tests/corelib/duration_test.dart
+++ b/tests/corelib/duration_test.dart
@@ -205,7 +205,7 @@
Expect.equals(-3600000000, d.inMicroseconds);
d = d1 * 0;
Expect.equals(0, d.inMicroseconds);
- Expect.throws(() => d1 ~/ 0, (e) => e is IntegerDivisionByZeroException);
+ Expect.throws(() => d1 ~/ 0, (e) => e is UnsupportedError);
d = new Duration(microseconds: 0);
Expect.isTrue(d < new Duration(microseconds: 1));
diff --git a/tests/corelib_2/duration_test.dart b/tests/corelib_2/duration_test.dart
index 1e5c5a3..fb80464 100644
--- a/tests/corelib_2/duration_test.dart
+++ b/tests/corelib_2/duration_test.dart
@@ -207,7 +207,7 @@
Expect.equals(-3600000000, d.inMicroseconds);
d = d1 * 0;
Expect.equals(0, d.inMicroseconds);
- Expect.throws(() => d1 ~/ 0, (e) => e is IntegerDivisionByZeroException);
+ Expect.throws(() => d1 ~/ 0, (e) => e is UnsupportedError);
d = new Duration(microseconds: 0);
Expect.isTrue(d < new Duration(microseconds: 1));
diff --git a/tests/language/library/env_test.dart b/tests/language/library/env_test.dart
index a80b8c1..9adcf8d 100644
--- a/tests/language/library/env_test.dart
+++ b/tests/language/library/env_test.dart
@@ -47,10 +47,6 @@
expectedResult,
const bool.fromEnvironment("dart.library.web_gl",
defaultValue: NOT_PRESENT));
- Expect.equals(
- expectedResult,
- const bool.fromEnvironment("dart.library.web_sql",
- defaultValue: NOT_PRESENT));
}
bool? hasIoSupport;
diff --git a/tests/language/operator/div_with_power_of_two2_test.dart b/tests/language/operator/div_with_power_of_two2_test.dart
index ef58026..72cddc6 100644
--- a/tests/language/operator/div_with_power_of_two2_test.dart
+++ b/tests/language/operator/div_with_power_of_two2_test.dart
@@ -146,7 +146,6 @@
Expect.equals(res, f(arg));
}
}
- Expect.throws(() => divBy0(4),
- (e) => e is IntegerDivisionByZeroException || e is UnsupportedError);
+ Expect.throws<UnsupportedError>(() => divBy0(4));
}
}
diff --git a/tests/language/operator/integer_division_by_zero_test.dart b/tests/language/operator/integer_division_by_zero_test.dart
index 03cd661..117bd18 100644
--- a/tests/language/operator/integer_division_by_zero_test.dart
+++ b/tests/language/operator/integer_division_by_zero_test.dart
@@ -7,8 +7,43 @@
import "package:expect/expect.dart";
-divBy0(a) => a ~/ 0;
+num divBy(num a, num b) => a ~/ b;
main() {
- Expect.throws(() => divBy0(4), (e) => e is IntegerDivisionByZeroException);
+ // Dividing integers by zero is an error.
+ Expect.throws<Error>(() => divBy(1, 0));
+ Expect.throws<Error>(() => divBy(0, 0));
+
+ // Dividing doubles by zero is an error (result is never finite).
+ Expect.throws<Error>(() => divBy(1.0, 0));
+ Expect.throws<Error>(() => divBy(1, 0.0));
+ Expect.throws<Error>(() => divBy(1, -0.0));
+ Expect.throws<Error>(() => divBy(1.0, 0.0));
+ // Double division yielding infinity is an error, even when not dividing
+ // by zero.
+ Expect.throws<Error>(() => divBy(double.maxFinite, 0.5));
+ Expect.throws<Error>(() => divBy(1, double.minPositive));
+ Expect.throws<Error>(() => divBy(double.infinity, 2.0));
+ Expect.throws<Error>(() => divBy(-double.maxFinite, 0.5));
+ Expect.throws<Error>(() => divBy(-1, double.minPositive));
+ Expect.throws<Error>(() => divBy(-double.infinity, 2.0));
+ // Double division yielding NaN is an error.
+ Expect.throws<Error>(() => divBy(0.0, 0.0));
+ Expect.throws<Error>(() => divBy(double.infinity, double.infinity));
+ Expect.throws<Error>(() => divBy(-0.0, 0.0));
+ Expect.throws<Error>(() => divBy(-double.infinity, double.infinity));
+
+ // Truncating division containing a double truncates to max integer
+ // on non-web.
+ num one = 1;
+ if (one is! double) {
+ var minInt = -0x8000000000000000;
+ var maxInt = minInt - 1;
+ Expect.isTrue(maxInt > 0);
+ // Not on web.
+ Expect.equals(divBy(double.maxFinite, 2), maxInt);
+ Expect.equals(divBy(-double.maxFinite, 2), minInt);
+ Expect.equals(divBy(maxInt, 0.25), maxInt);
+ Expect.equals(divBy(minInt, 0.25), minInt);
+ }
}
diff --git a/tests/language/operator/modulo_test.dart b/tests/language/operator/modulo_test.dart
index ae55626..8f20730 100644
--- a/tests/language/operator/modulo_test.dart
+++ b/tests/language/operator/modulo_test.dart
@@ -13,11 +13,11 @@
for (int i = -30; i < 30; i++) {
Expect.equals(i % 256, foo(i));
Expect.equals(i % -256, boo(i));
- Expect.throws(() => hoo(i), (e) => e is IntegerDivisionByZeroException);
+ Expect.throws(() => hoo(i), (e) => e is UnsupportedError);
Expect.equals(i ~/ 254 + i % 254, fooTwo(i));
Expect.equals(i ~/ -254 + i % -254, booTwo(i));
- Expect.throws(() => hooTwo(i), (e) => e is IntegerDivisionByZeroException);
+ Expect.throws(() => hooTwo(i), (e) => e is UnsupportedError);
if (i > 0) {
Expect.equals(i % 10, noDom(i));
} else {
@@ -35,8 +35,8 @@
Expect.equals(i ~/ i + i % i, fooTwo2(i));
}
}
- Expect.throws(() => foo2(0), (e) => e is IntegerDivisionByZeroException);
- Expect.throws(() => fooTwo2(0), (e) => e is IntegerDivisionByZeroException);
+ Expect.throws(() => foo2(0), (e) => e is UnsupportedError);
+ Expect.throws(() => fooTwo2(0), (e) => e is UnsupportedError);
}
foo(i) => i % 256; // This will get optimized to AND instruction.
diff --git a/tests/language/operator/truncdiv_test.dart b/tests/language/operator/truncdiv_test.dart
index bd043d1..12b53fe 100644
--- a/tests/language/operator/truncdiv_test.dart
+++ b/tests/language/operator/truncdiv_test.dart
@@ -17,10 +17,8 @@
}
}
// We don't specify the exact exception type here, that is covered in
- // truncdiv_zero_test. The correct answer is IntegerDivisionByZeroException,
- // but the web platform has only one num type and can't distinguish between
- // int and double, so it throws UnsupportedError (the behaviour for double).
- Expect.throws(() => foo2(0));
+ // truncdiv_zero_test.
+ Expect.throws<UnsupportedError>(() => foo2(0));
}
foo(i, x) => i % x;
diff --git a/tests/language/operator/truncdiv_zero_test.dart b/tests/language/operator/truncdiv_zero_test.dart
index 34cecc3..11f0bb4 100644
--- a/tests/language/operator/truncdiv_zero_test.dart
+++ b/tests/language/operator/truncdiv_zero_test.dart
@@ -9,6 +9,6 @@
import "truncdiv_test.dart" as truncdiv_test show foo, foo2;
main() {
- Expect.throws<IntegerDivisionByZeroException>(() => truncdiv_test.foo(12, 0));
- Expect.throws<IntegerDivisionByZeroException>(() => truncdiv_test.foo2(0));
+ Expect.throws<UnsupportedError>(() => truncdiv_test.foo(12, 0));
+ Expect.throws<UnsupportedError>(() => truncdiv_test.foo2(0));
}
diff --git a/tests/language/regress/regress31596_covariant_declaration_test.dart b/tests/language/regress/regress31596_covariant_declaration_test.dart
index c9c9053..9b91bd4 100644
--- a/tests/language/regress/regress31596_covariant_declaration_test.dart
+++ b/tests/language/regress/regress31596_covariant_declaration_test.dart
@@ -2,6 +2,10 @@
// 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 the treatment of a method whose signature has a covariant parameter
+// in the interface of a class `C`, when the implementation of that method
+// is inherited and its parameter is not covariant.
+
class I0 {}
class A {}
@@ -16,9 +20,7 @@
void f(covariant A x);
}
+// As of dart-lang/language#1833 this is not a compile-time.
class D extends C implements I {}
-// ^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_IMPLEMENTATION_OVERRIDE
-// [cfe] unspecified
main() {}
diff --git a/tests/language/vm/div_mod_test.dart b/tests/language/vm/div_mod_test.dart
index ea22240..84c8c71 100755
--- a/tests/language/vm/div_mod_test.dart
+++ b/tests/language/vm/div_mod_test.dart
@@ -138,7 +138,7 @@
bool threw = false;
try {
div0(i);
- } on IntegerDivisionByZeroException catch (e) {
+ } on UnsupportedError catch (e) {
threw = true;
}
Expect.isTrue(threw);
@@ -149,7 +149,7 @@
bool threw = false;
try {
mod0(i);
- } on IntegerDivisionByZeroException catch (e) {
+ } on UnsupportedError catch (e) {
threw = true;
}
Expect.isTrue(threw);
diff --git a/tests/language/vm/modtruncdiv_int_test.dart b/tests/language/vm/modtruncdiv_int_test.dart
index 9fc5b53..5948647 100644
--- a/tests/language/vm/modtruncdiv_int_test.dart
+++ b/tests/language/vm/modtruncdiv_int_test.dart
@@ -285,14 +285,14 @@
try {
doModVars(9, 9, -9, 0);
acc = 0; // don't reach!
- } on IntegerDivisionByZeroException catch (e, s) {}
+ } on UnsupportedError catch (e, s) {}
Expect.equals(12, acc);
acc = 0;
try {
doTruncDivVars(9, 9, -9, 0);
acc = 0; // don't reach!
- } on IntegerDivisionByZeroException catch (e, s) {}
+ } on UnsupportedError catch (e, s) {}
Expect.equals(-23, acc);
}
}
diff --git a/tests/language/vm/regression_37622_test.dart b/tests/language/vm/regression_37622_test.dart
index d5999fc..b11e9a4 100755
--- a/tests/language/vm/regression_37622_test.dart
+++ b/tests/language/vm/regression_37622_test.dart
@@ -30,7 +30,7 @@
bool d = false;
try {
x = foo();
- } on IntegerDivisionByZeroException catch (e) {
+ } on UnsupportedError catch (e) {
d = true;
}
Expect.equals(x, 0);
diff --git a/tests/language_2/library/env_test.dart b/tests/language_2/library/env_test.dart
index 9367eb5..8df205b 100644
--- a/tests/language_2/library/env_test.dart
+++ b/tests/language_2/library/env_test.dart
@@ -49,10 +49,6 @@
expectedResult,
const bool.fromEnvironment("dart.library.web_gl",
defaultValue: NOT_PRESENT));
- Expect.equals(
- expectedResult,
- const bool.fromEnvironment("dart.library.web_sql",
- defaultValue: NOT_PRESENT));
}
bool hasIoSupport;
diff --git a/tests/language_2/operator/div_with_power_of_two2_test.dart b/tests/language_2/operator/div_with_power_of_two2_test.dart
index fdbf571..b3db5ce 100644
--- a/tests/language_2/operator/div_with_power_of_two2_test.dart
+++ b/tests/language_2/operator/div_with_power_of_two2_test.dart
@@ -148,7 +148,7 @@
Expect.equals(res, f(arg));
}
}
- Expect.throws(() => divBy0(4),
- (e) => e is IntegerDivisionByZeroException || e is UnsupportedError);
+ Expect.throws<UnsupportedError>(() => divBy0(4));
+ ;
}
}
diff --git a/tests/language_2/operator/integer_division_by_zero_test.dart b/tests/language_2/operator/integer_division_by_zero_test.dart
index 3ba518a..e1fc343 100644
--- a/tests/language_2/operator/integer_division_by_zero_test.dart
+++ b/tests/language_2/operator/integer_division_by_zero_test.dart
@@ -9,8 +9,43 @@
import "package:expect/expect.dart";
-divBy0(a) => a ~/ 0;
+num divBy(num a, num b) => a ~/ b;
main() {
- Expect.throws(() => divBy0(4), (e) => e is IntegerDivisionByZeroException);
+ // Dividing integers by zero is an error.
+ Expect.throws<Error>(() => divBy(1, 0));
+ Expect.throws<Error>(() => divBy(0, 0));
+
+ // Dividing doubles by zero is an error (result is never finite).
+ Expect.throws<Error>(() => divBy(1.0, 0));
+ Expect.throws<Error>(() => divBy(1, 0.0));
+ Expect.throws<Error>(() => divBy(1, -0.0));
+ Expect.throws<Error>(() => divBy(1.0, 0.0));
+ // Double division yielding infinity is an error, even when not dividing
+ // by zero.
+ Expect.throws<Error>(() => divBy(double.maxFinite, 0.5));
+ Expect.throws<Error>(() => divBy(1, double.minPositive));
+ Expect.throws<Error>(() => divBy(double.infinity, 2.0));
+ Expect.throws<Error>(() => divBy(-double.maxFinite, 0.5));
+ Expect.throws<Error>(() => divBy(-1, double.minPositive));
+ Expect.throws<Error>(() => divBy(-double.infinity, 2.0));
+ // Double division yielding NaN is an error.
+ Expect.throws<Error>(() => divBy(0.0, 0.0));
+ Expect.throws<Error>(() => divBy(double.infinity, double.infinity));
+ Expect.throws<Error>(() => divBy(-0.0, 0.0));
+ Expect.throws<Error>(() => divBy(-double.infinity, double.infinity));
+
+ // Truncating division containing a double truncates to max integer
+ // on non-web.
+ num one = 1;
+ if (one is! double) {
+ var minInt = -0x8000000000000000;
+ var maxInt = minInt - 1;
+ Expect.isTrue(maxInt > 0);
+ // Not on web.
+ Expect.equals(divBy(double.maxFinite, 2), maxInt);
+ Expect.equals(divBy(-double.maxFinite, 2), minInt);
+ Expect.equals(divBy(maxInt, 0.25), maxInt);
+ Expect.equals(divBy(minInt, 0.25), minInt);
+ }
}
diff --git a/tests/language_2/operator/modulo_test.dart b/tests/language_2/operator/modulo_test.dart
index 6e38c09..417c556 100644
--- a/tests/language_2/operator/modulo_test.dart
+++ b/tests/language_2/operator/modulo_test.dart
@@ -15,11 +15,11 @@
for (int i = -30; i < 30; i++) {
Expect.equals(i % 256, foo(i));
Expect.equals(i % -256, boo(i));
- Expect.throws(() => hoo(i), (e) => e is IntegerDivisionByZeroException);
+ Expect.throws(() => hoo(i), (e) => e is UnsupportedError);
Expect.equals(i ~/ 254 + i % 254, fooTwo(i));
Expect.equals(i ~/ -254 + i % -254, booTwo(i));
- Expect.throws(() => hooTwo(i), (e) => e is IntegerDivisionByZeroException);
+ Expect.throws(() => hooTwo(i), (e) => e is UnsupportedError);
if (i > 0) {
Expect.equals(i % 10, noDom(i));
} else {
@@ -37,8 +37,8 @@
Expect.equals(i ~/ i + i % i, fooTwo2(i));
}
}
- Expect.throws(() => foo2(0), (e) => e is IntegerDivisionByZeroException);
- Expect.throws(() => fooTwo2(0), (e) => e is IntegerDivisionByZeroException);
+ Expect.throws(() => foo2(0), (e) => e is UnsupportedError);
+ Expect.throws(() => fooTwo2(0), (e) => e is UnsupportedError);
}
foo(i) => i % 256; // This will get optimized to AND instruction.
diff --git a/tests/language_2/operator/truncdiv_test.dart b/tests/language_2/operator/truncdiv_test.dart
index b3f3cbd..e8d7d92 100644
--- a/tests/language_2/operator/truncdiv_test.dart
+++ b/tests/language_2/operator/truncdiv_test.dart
@@ -19,10 +19,8 @@
}
}
// We don't specify the exact exception type here, that is covered in
- // truncdiv_zero_test. The correct answer is IntegerDivisionByZeroException,
- // but the web platform has only one num type and can't distinguish between
- // int and double, so it throws UnsupportedError (the behaviour for double).
- Expect.throws(() => foo2(0));
+ // truncdiv_zero_test.
+ Expect.throws<UnsupportedError>(() => foo2(0));
}
foo(i, x) => i % x;
diff --git a/tests/language_2/operator/truncdiv_zero_test.dart b/tests/language_2/operator/truncdiv_zero_test.dart
index ed41090..c69b928 100644
--- a/tests/language_2/operator/truncdiv_zero_test.dart
+++ b/tests/language_2/operator/truncdiv_zero_test.dart
@@ -11,6 +11,6 @@
import "truncdiv_test.dart" as truncdiv_test show foo, foo2;
main() {
- Expect.throws<IntegerDivisionByZeroException>(() => truncdiv_test.foo(12, 0));
- Expect.throws<IntegerDivisionByZeroException>(() => truncdiv_test.foo2(0));
+ Expect.throws<UnsupportedError>(() => truncdiv_test.foo(12, 0));
+ Expect.throws<UnsupportedError>(() => truncdiv_test.foo2(0));
}
diff --git a/tests/language_2/regress/regress31596_covariant_declaration_test.dart b/tests/language_2/regress/regress31596_covariant_declaration_test.dart
index 6c6297e..677efe6 100644
--- a/tests/language_2/regress/regress31596_covariant_declaration_test.dart
+++ b/tests/language_2/regress/regress31596_covariant_declaration_test.dart
@@ -4,6 +4,10 @@
// @dart = 2.9
+// Test the treatment of a method whose signature has a covariant parameter
+// in the interface of a class `C`, when the implementation of that method
+// is inherited and its parameter is not covariant.
+
class I0 {}
class A {}
@@ -18,9 +22,7 @@
void f(covariant A x);
}
+// As of dart-lang/language#1833 this is not a compile-time error.
class D extends C implements I {}
-// ^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_IMPLEMENTATION_OVERRIDE
-// [cfe] unspecified
main() {}
diff --git a/tests/language_2/vm/div_mod_test.dart b/tests/language_2/vm/div_mod_test.dart
index 0ce3c28..47d3b0b 100755
--- a/tests/language_2/vm/div_mod_test.dart
+++ b/tests/language_2/vm/div_mod_test.dart
@@ -138,7 +138,7 @@
bool threw = false;
try {
div0(i);
- } on IntegerDivisionByZeroException catch (e) {
+ } on UnsupportedError catch (e) {
threw = true;
}
Expect.isTrue(threw);
@@ -149,7 +149,7 @@
bool threw = false;
try {
mod0(i);
- } on IntegerDivisionByZeroException catch (e) {
+ } on UnsupportedError catch (e) {
threw = true;
}
Expect.isTrue(threw);
diff --git a/tests/language_2/vm/modtruncdiv_int_test.dart b/tests/language_2/vm/modtruncdiv_int_test.dart
index 907f912..b34ac76 100644
--- a/tests/language_2/vm/modtruncdiv_int_test.dart
+++ b/tests/language_2/vm/modtruncdiv_int_test.dart
@@ -287,14 +287,14 @@
try {
doModVars(9, 9, -9, 0);
acc = 0; // don't reach!
- } on IntegerDivisionByZeroException catch (e, s) {}
+ } on UnsupportedError catch (e, s) {}
Expect.equals(12, acc);
acc = 0;
try {
doTruncDivVars(9, 9, -9, 0);
acc = 0; // don't reach!
- } on IntegerDivisionByZeroException catch (e, s) {}
+ } on UnsupportedError catch (e, s) {}
Expect.equals(-23, acc);
}
}
diff --git a/tests/language_2/vm/regression_37622_test.dart b/tests/language_2/vm/regression_37622_test.dart
index c7ef6f0..48562f5 100755
--- a/tests/language_2/vm/regression_37622_test.dart
+++ b/tests/language_2/vm/regression_37622_test.dart
@@ -31,7 +31,7 @@
bool d = false;
try {
x = foo();
- } on IntegerDivisionByZeroException catch (e) {
+ } on UnsupportedError catch (e) {
d = true;
}
Expect.equals(x, 0);
diff --git a/tests/lib/html/websql_static_test.dart b/tests/lib/html/websql_static_test.dart
new file mode 100644
index 0000000..c4a84b2
--- /dev/null
+++ b/tests/lib/html/websql_static_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+import 'dart:web_sql';
+// ^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.URI_DOES_NOT_EXIST
+// [cfe] Not found: 'dart:web_sql'
+
+void main() {}
diff --git a/tests/lib/html/websql_test.dart b/tests/lib/html/websql_test.dart
deleted file mode 100644
index 3445764..0000000
--- a/tests/lib/html/websql_test.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// 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.
-
-library WebDBTest;
-
-import 'dart:async';
-import 'dart:html';
-import 'dart:web_sql';
-
-import 'package:async_helper/async_minitest.dart';
-
-Future<SqlResultSet> createTable(
- SqlTransaction transaction, String tableName, String columnName) async {
- return transaction.executeSql('CREATE TABLE $tableName ($columnName)', []);
-}
-
-Future<SqlResultSet> insertTable(SqlTransaction transaction, String tableName,
- String columnName, value) async {
- final sql = 'INSERT INTO $tableName ($columnName) VALUES (?)';
- return transaction.executeSql(sql, [value]);
-}
-
-Future<SqlResultSet> queryTable(
- SqlTransaction transaction, String tableName) async {
- final sql = 'SELECT * FROM $tableName';
- return transaction.executeSql(sql, []);
-}
-
-Future<SqlResultSet?> dropTable(SqlTransaction transaction, String tableName,
- [bool ignoreFailure = false]) async {
- try {
- var result = await transaction.executeSql('DROP TABLE $tableName', []);
- return result;
- } catch (error) {
- if (!ignoreFailure) throw error;
- }
-}
-
-final tableName = 'test_table';
-final columnName = 'test_data';
-
-late SqlDatabase db;
-late SqlTransaction tx;
-
-Future setup() async {
- if (SqlDatabase.supported) {
- db = await window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024);
- expect(db, isNotNull, reason: 'Unable to open database');
-
- tx = await db.transaction_future();
- expect(tx, isNotNull, reason: "Transaction not ready");
- }
-}
-
-main() async {
- await setup();
-
- group('Database', () {
- test('Open/Transaction', () async {
- if (!SqlDatabase.supported) return;
-
- expect(tx, isNotNull, reason: "Transaction not ready");
-
- // Should not succeed table doesn't exist to be dropped.
- try {
- await dropTable(tx, tableName);
- expect(false, true, reason: "dropTable should fail");
- } on DomException catch (error) {
- expect(error.message,
- "could not prepare statement (1 no such table: test_table)");
- }
- });
-
- test('create', () async {
- if (!SqlDatabase.supported) return;
-
- expect(tx, isNotNull, reason: "Transaction not ready");
- try {
- SqlResultSet createResult =
- await createTable(tx, tableName, columnName);
- expect(createResult.insertId, 0);
- } on DomException catch (error) {
- expect(false, true, reason: "createTable failed - ${error.message}");
- }
- });
-
- test('insert', () async {
- if (!SqlDatabase.supported) return;
-
- expect(tx, isNotNull, reason: "Transaction not ready");
- try {
- SqlResultSet insertResult =
- await insertTable(tx, tableName, columnName, 'Some text data');
- expect(insertResult.insertId, 1);
- expect(insertResult.rowsAffected, 1);
- } on DomException catch (error) {
- expect(false, true, reason: "insert failed - ${error.message}");
- }
- });
-
- test('query', () async {
- if (!SqlDatabase.supported) return;
-
- expect(tx, isNotNull, reason: "Transaction not ready");
- try {
- SqlResultSet queryResult = await queryTable(tx, tableName);
- expect(queryResult.rows!.length, 1);
- expect(queryResult.rows![0]['test_data'], "Some text data");
- } on DomException catch (error) {
- expect(false, true, reason: "queryTable failed - ${error.message}");
- }
- });
-
- test('cleanup', () async {
- if (!SqlDatabase.supported) return;
-
- expect(tx, isNotNull, reason: "Transaction not ready");
- await dropTable(tx, tableName, true);
- });
- });
-}
diff --git a/tests/lib_2/html/websql_static_test.dart b/tests/lib_2/html/websql_static_test.dart
new file mode 100644
index 0000000..9acdce6
--- /dev/null
+++ b/tests/lib_2/html/websql_static_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+// @dart = 2.9
+
+import 'dart:web_sql';
+// ^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.URI_DOES_NOT_EXIST
+// [cfe] Not found: 'dart:web_sql'
+
+void main() {}
diff --git a/tests/lib_2/html/websql_test.dart b/tests/lib_2/html/websql_test.dart
deleted file mode 100644
index bcd6231..0000000
--- a/tests/lib_2/html/websql_test.dart
+++ /dev/null
@@ -1,120 +0,0 @@
-
-// @dart = 2.9
-library WebDBTest;
-
-import 'dart:async';
-import 'dart:html';
-import 'dart:web_sql';
-
-import 'package:async_helper/async_minitest.dart';
-
-Future<SqlResultSet> createTable(
- SqlTransaction transaction, String tableName, String columnName) async {
- return transaction.executeSql('CREATE TABLE $tableName ($columnName)', []);
-}
-
-Future<SqlResultSet> insertTable(SqlTransaction transaction, String tableName,
- String columnName, value) async {
- final sql = 'INSERT INTO $tableName ($columnName) VALUES (?)';
- return transaction.executeSql(sql, [value]);
-}
-
-Future<SqlResultSet> queryTable(
- SqlTransaction transaction, String tableName) async {
- final sql = 'SELECT * FROM $tableName';
- return transaction.executeSql(sql, []);
-}
-
-Future<SqlResultSet> dropTable(SqlTransaction transaction, String tableName,
- [bool ignoreFailure = false]) async {
- try {
- var result = await transaction.executeSql('DROP TABLE $tableName', []);
- return result;
- } catch (error) {
- if (!ignoreFailure) throw error;
- }
-}
-
-final tableName = 'test_table';
-final columnName = 'test_data';
-
-SqlDatabase db;
-SqlTransaction tx;
-
-Future setup() async {
- if (SqlDatabase.supported) {
- db = await window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024);
- expect(db, isNotNull, reason: 'Unable to open database');
-
- tx = await db.transaction_future();
- expect(tx, isNotNull, reason: "Transaction not ready");
- }
-}
-
-main() async {
- await setup();
-
- group('Database', () {
- test('Open/Transaction', () async {
- if (!SqlDatabase.supported) return;
-
- expect(tx, isNotNull, reason: "Transaction not ready");
-
- // Should not succeed table doesn't exist to be dropped.
- try {
- await dropTable(tx, tableName);
- expect(false, true, reason: "dropTable should fail");
- } catch (error) {
- expect(error.message,
- "could not prepare statement (1 no such table: test_table)");
- }
- });
-
- test('create', () async {
- if (!SqlDatabase.supported) return;
-
- expect(tx, isNotNull, reason: "Transaction not ready");
- try {
- SqlResultSet createResult =
- await createTable(tx, tableName, columnName);
- expect(createResult.insertId, 0);
- } catch (error) {
- expect(false, true, reason: "createTable failed - ${error.message}");
- }
- });
-
- test('insert', () async {
- if (!SqlDatabase.supported) return;
-
- expect(tx, isNotNull, reason: "Transaction not ready");
- try {
- SqlResultSet insertResult =
- await insertTable(tx, tableName, columnName, 'Some text data');
- expect(insertResult.insertId, 1);
- expect(insertResult.rowsAffected, 1);
- } catch (error) {
- expect(false, true, reason: "insert failed - ${error.message}");
- }
- });
-
- test('query', () async {
- if (!SqlDatabase.supported) return;
-
- expect(tx, isNotNull, reason: "Transaction not ready");
- try {
- SqlResultSet queryResult = await queryTable(tx, tableName);
- expect(queryResult.rows.length, 1);
- expect(queryResult.rows[0]['test_data'], "Some text data");
- } catch (error) {
- expect(false, true, reason: "queryTable failed - ${error.message}");
- }
- });
-
- test('cleanup', () async {
- if (!SqlDatabase.supported) return;
-
- expect(tx, isNotNull, reason: "Transaction not ready");
- await dropTable(tx, tableName, true);
- });
- });
-}
diff --git a/tests/standalone/io/platform_os_version_test.dart b/tests/standalone/io/platform_os_version_test.dart
index fff7335..f16b059 100644
--- a/tests/standalone/io/platform_os_version_test.dart
+++ b/tests/standalone/io/platform_os_version_test.dart
@@ -10,4 +10,5 @@
var version = Platform.operatingSystemVersion;
Expect.isNotNull(version);
Expect.isTrue(version is String);
+ Expect.notEquals("", version);
}
diff --git a/tests/standalone_2/io/platform_os_version_test.dart b/tests/standalone_2/io/platform_os_version_test.dart
index dde94c4..cf312c4 100644
--- a/tests/standalone_2/io/platform_os_version_test.dart
+++ b/tests/standalone_2/io/platform_os_version_test.dart
@@ -12,4 +12,5 @@
var version = Platform.operatingSystemVersion;
Expect.isNotNull(version);
Expect.isTrue(version is String);
+ Expect.notEquals("", version);
}
diff --git a/tests/web/lax_runtime_type_instantiate_to_string_test.dart b/tests/web/lax_runtime_type_instantiate_to_string_test.dart
index 26ba4e8..25e1b97 100644
--- a/tests/web/lax_runtime_type_instantiate_to_string_test.dart
+++ b/tests/web/lax_runtime_type_instantiate_to_string_test.dart
@@ -14,7 +14,10 @@
// `true` if non-minified.
// The signature of `id` is not otherwise needed so the instantiation
// wrapper doesn't have a function type.
- Expect.equals("Instantiation1<dynamic>", toString);
+ // The type parameter is present since it is required because `==`
+ // distinguishes instantiations of the same generic function with different
+ // types.
+ Expect.equals("Instantiation1<int>", toString);
}
print(toString);
}
diff --git a/tests/web_2/lax_runtime_type_instantiate_to_string_test.dart b/tests/web_2/lax_runtime_type_instantiate_to_string_test.dart
index 0e4d623..9d7c13c 100644
--- a/tests/web_2/lax_runtime_type_instantiate_to_string_test.dart
+++ b/tests/web_2/lax_runtime_type_instantiate_to_string_test.dart
@@ -16,7 +16,10 @@
// `true` if non-minified.
// The signature of `id` is not otherwise needed so the instantiation
// wrapper doesn't have a function type.
- Expect.equals("Instantiation1<dynamic>", toString);
+ // The type parameter is present since it is required because `==`
+ // distinguishes instantiations of the same generic function with different
+ // types.
+ Expect.equals("Instantiation1<int>", toString);
}
print(toString);
}
diff --git a/tools/VERSION b/tools/VERSION
index f8b3ab0..2748fd6 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 233
+PRERELEASE 234
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 9c1191c..ab04c56 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -565,17 +565,17 @@
},
"dart2js-win-ie11": {
"options": {
- "use-sdk": true,
- "babel": "{\"presets\":[\"es2015\"]}"
+ "babel": "{\"presets\":[\"es2015\"]}",
+ "use-sdk": true
}
},
"dart2js-win-ie11-unsound": {
"options": {
- "use-sdk": true,
"babel": "{\"presets\":[\"es2015\"]}",
"dart2js-options": [
"--no-sound-null-safety"
- ]
+ ],
+ "use-sdk": true
}
},
"dart2js-win-edge": {
@@ -2490,7 +2490,6 @@
"name": "dart2js tests",
"arguments": [
"-ndart2js-hostasserts-linux-ia32-d8",
- "--dart2js-batch",
"--exclude_suite=observatory_ui"
],
"shards": 6,
@@ -2500,7 +2499,6 @@
"name": "dart2js co19_2 tests",
"arguments": [
"-ndart2js-hostasserts-linux-ia32-d8",
- "--dart2js-batch",
"co19_2"
],
"shards": 6,
@@ -2510,7 +2508,6 @@
"name": "dart2js package tests",
"arguments": [
"-ndart2js-hostasserts-linux-ia32-d8",
- "--dart2js-batch",
"pkg"
]
},
@@ -2518,7 +2515,6 @@
"name": "dart2js observatory-ui tests",
"arguments": [
"-ndart2js-hostasserts-linux-ia32-d8-unsound",
- "--dart2js-batch",
"observatory_ui"
]
},
@@ -2526,7 +2522,6 @@
"name": "dart2js extra tests",
"arguments": [
"-ndart2js-hostasserts-linux-ia32-d8",
- "--dart2js-batch",
"web_2"
]
}
@@ -2558,7 +2553,6 @@
"name": "dart2js tests",
"arguments": [
"-ndart2js-${system}-${runtime}",
- "--dart2js-batch",
"--reset-browser-configuration",
"--exclude_suite=observatory_ui"
],
@@ -2569,7 +2563,6 @@
"name": "dart2js co19_2 tests",
"arguments": [
"-ndart2js-${system}-${runtime}",
- "--dart2js-batch",
"--reset-browser-configuration",
"co19_2"
],
@@ -2580,7 +2573,6 @@
"name": "dart2js package tests",
"arguments": [
"-ndart2js-${system}-${runtime}",
- "--dart2js-batch",
"--reset-browser-configuration",
"pkg"
]
@@ -2589,7 +2581,6 @@
"name": "dart2js observatory-ui tests",
"arguments": [
"-ndart2js-${system}-${runtime}-unsound",
- "--dart2js-batch",
"--reset-browser-configuration",
"observatory_ui"
]
@@ -2598,7 +2589,6 @@
"name": "dart2js extra tests",
"arguments": [
"-ndart2js-${system}-${runtime}",
- "--dart2js-batch",
"--reset-browser-configuration",
"web_2"
]
@@ -2624,7 +2614,6 @@
"name": "dart2js tests",
"arguments": [
"-ndart2js-minified-linux-d8",
- "--dart2js-batch",
"--exclude_suite=observatory_ui"
],
"shards": 6,
@@ -2634,7 +2623,6 @@
"name": "dart2js package tests",
"arguments": [
"-ndart2js-minified-linux-d8",
- "--dart2js-batch",
"pkg"
]
},
@@ -2642,7 +2630,6 @@
"name": "dart2js observatory-ui tests",
"arguments": [
"-ndart2js-minified-linux-d8-unsound",
- "--dart2js-batch",
"observatory_ui"
]
},
@@ -2650,7 +2637,6 @@
"name": "dart2js extra tests",
"arguments": [
"-ndart2js-minified-linux-d8",
- "--dart2js-batch",
"web_2"
]
},
@@ -2658,7 +2644,6 @@
"name": "dart2js production tests",
"arguments": [
"-ndart2js-production-linux-d8",
- "--dart2js-batch",
"--exclude_suite=observatory_ui"
],
"shards": 6,
@@ -2668,7 +2653,6 @@
"name": "dart2js production extra tests",
"arguments": [
"-ndart2js-production-linux-d8",
- "--dart2js-batch",
"web_2"
]
},
@@ -2676,7 +2660,6 @@
"name": "dart2js -O0 smoke tests",
"arguments": [
"-ndart2js-o0-linux-d8",
- "--dart2js-batch",
"web_2"
]
},
@@ -2684,7 +2667,6 @@
"name": "dart2js --canary smoke tests",
"arguments": [
"-ndart2js-modern-linux-d8",
- "--dart2js-batch",
"web_2"
]
},
@@ -2692,7 +2674,6 @@
"name": "dart2js d8 fragment merging tests",
"arguments": [
"-ndart2js-minified-hostasserts-weak-max-fragments-linux-x64-d8",
- "--dart2js-batch",
"web/deferred/"
],
"shards": 1,
@@ -2719,7 +2700,6 @@
"name": "dart2js tests",
"arguments": [
"-ndart2js-minified-csp-linux-chrome",
- "--dart2js-batch",
"--reset-browser-configuration",
"--exclude_suite=observatory_ui"
],
@@ -2730,7 +2710,6 @@
"name": "dart2js package tests",
"arguments": [
"-ndart2js-minified-csp-linux-chrome",
- "--dart2js-batch",
"--reset-browser-configuration",
"pkg"
]
@@ -2739,7 +2718,6 @@
"name": "dart2js observatory-ui tests",
"arguments": [
"-ndart2js-minified-csp-linux-chrome-unsound",
- "--dart2js-batch",
"--reset-browser-configuration",
"observatory_ui"
]
@@ -2748,7 +2726,6 @@
"name": "dart2js extra tests",
"arguments": [
"-ndart2js-minified-csp-linux-chrome",
- "--dart2js-batch",
"web_2"
]
},
@@ -2756,7 +2733,6 @@
"name": "dart2js d8 fragment merging tests",
"arguments": [
"-ndart2js-minified-csp-max-fragments-linux-chrome",
- "--dart2js-batch",
"web/deferred/"
]
}
@@ -2782,7 +2758,6 @@
"name": "dart2js nnbd weak d8 tests",
"arguments": [
"-ndart2js-hostasserts-weak-linux-x64-d8",
- "--dart2js-batch",
"language",
"corelib"
],
@@ -2793,7 +2768,6 @@
"name": "dart2js nnbd weak d8 fragment merging tests",
"arguments": [
"-ndart2js-hostasserts-weak-max-fragments-linux-x64-d8",
- "--dart2js-batch",
"web/deferred/"
],
"shards": 1,
@@ -2803,7 +2777,6 @@
"name": "dart2js nnbd weak chrome tests",
"arguments": [
"-ndart2js-hostasserts-weak-linux-x64-chrome",
- "--dart2js-batch",
"web"
],
"shards": 3,
@@ -2813,7 +2786,6 @@
"name": "dart2js nnbd weak lib tests",
"arguments": [
"-ndart2js-hostasserts-weak-linux-x64-chrome",
- "--dart2js-batch",
"lib"
],
"shards": 3,
@@ -2823,7 +2795,6 @@
"name": "dart2js nnbd weak co19 tests",
"arguments": [
"-ndart2js-hostasserts-weak-linux-x64-chrome",
- "--dart2js-batch",
"co19"
],
"shards": 6,
@@ -2833,7 +2804,6 @@
"name": "dart2js nnbd strong d8 tests",
"arguments": [
"-ndart2js-hostasserts-strong-linux-x64-d8",
- "--dart2js-batch",
"language",
"corelib"
],
@@ -2844,7 +2814,6 @@
"name": "dart2js nnbd strong d8 fragment merging tests",
"arguments": [
"-ndart2js-hostasserts-strong-max-fragments-linux-x64-d8",
- "--dart2js-batch",
"web/deferred/"
],
"shards": 1,
@@ -2854,7 +2823,6 @@
"name": "dart2js nnbd strong chrome tests",
"arguments": [
"-ndart2js-hostasserts-strong-linux-x64-chrome",
- "--dart2js-batch",
"web"
],
"shards": 3,
@@ -2864,7 +2832,6 @@
"name": "dart2js nnbd strong lib tests",
"arguments": [
"-ndart2js-hostasserts-strong-linux-x64-chrome",
- "--dart2js-batch",
"lib"
],
"shards": 3,
@@ -2874,7 +2841,6 @@
"name": "dart2js nnbd strong co19 tests",
"arguments": [
"-ndart2js-hostasserts-strong-linux-x64-chrome",
- "--dart2js-batch",
"co19"
],
"shards": 6,
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 96cdf8a..7e84e7c 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -146,6 +146,7 @@
'CSSValue',
'Counter',
'DOMFileSystemSync', # Workers
+ 'DatabaseCallback', # WebSql was removed
'DatabaseSync', # Workers
'DirectoryEntrySync', # Workers
'DirectoryReaderSync', # Workers
@@ -527,7 +528,6 @@
'Window.getComputedStyle',
'Window.clearInterval',
'Window.clearTimeout',
- 'Window.openDatabase',
# TODO(tll): These have been converted from int to double in Chrome 39 for
# subpixel precision. Special case for backward compatibility.
'Window.pageXOffset',
@@ -704,6 +704,7 @@
'Window.createImageBitmap',
'Window.get:frames',
'Window.get:length',
+ 'Window.openDatabase',
'Window.on:beforeUnload',
'Window.on:webkitTransitionEnd',
'Window.pagePopupController',
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index d1e9e6b..b3dc526 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -39,7 +39,6 @@
import 'dart:web_audio' show AudioBuffer, AudioTrack, AudioTrackList;
import 'dart:web_gl' as gl;
import 'dart:web_gl' show RenderingContext,RenderingContext2;
-import 'dart:web_sql';
import 'dart:_js_helper' show
convertDartClosureToJS, Creates, JavaScriptIndexingBehavior,
JSName, Native, Returns,
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index 15f8219..a433f83 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -222,26 +222,6 @@
_moveTo(p.x.toInt(), p.y.toInt());
}
- @JSName('openDatabase')
- @SupportedBrowser(SupportedBrowser.CHROME)
- @SupportedBrowser(SupportedBrowser.SAFARI)
- @Creates('SqlDatabase')
- @deprecated
- SqlDatabase openDatabase(
- String name, String version, String displayName, int estimatedSize,
- [DatabaseCallback$NULLABLE creationCallback]) {
- var db;
- if (creationCallback == null)
- db = _openDatabase(name, version, displayName, estimatedSize);
- else
- db = _openDatabase(
- name, version, displayName, estimatedSize, creationCallback);
-
- applyExtension('Database', db);
-
- return db;
- }
-
int get pageXOffset => JS<num>('num', '#.pageXOffset', this).round();
int get pageYOffset => JS<num>('num', '#.pageYOffset', this).round();
diff --git a/tools/verify_docs/README.md b/tools/verify_docs/README.md
index aa44c8a..a79aa7c 100644
--- a/tools/verify_docs/README.md
+++ b/tools/verify_docs/README.md
@@ -73,3 +73,17 @@
For most code sample, the auto-detection code will select `template:main` or
`template:expression`.
+
+### Including additional code for analysis
+
+You can declare code that should be included in the analysis but not shown in
+the API docs by adding a comment "// Examples can assume:" to the file (usually
+at the top of the file, after the imports), following by one or more
+commented-out lines of code. That code is included verbatim in the analysis. For
+example:
+
+```dart
+// Examples can assume:
+// final BuildContext context;
+// final String userAvatarUrl;
+```
diff --git a/tools/verify_docs/bin/verify_docs.dart b/tools/verify_docs/bin/verify_docs.dart
index 686b734..aee1176 100644
--- a/tools/verify_docs/bin/verify_docs.dart
+++ b/tools/verify_docs/bin/verify_docs.dart
@@ -31,7 +31,7 @@
print('To run this tool, run `dart tools/verify_docs/bin/verify_docs.dart`.');
print('');
print('For documentation about how to author dart: code samples,'
- ' see tools/verify_docs/README.md');
+ ' see tools/verify_docs/README.md.');
print('');
final coreLibraries = args.isEmpty
@@ -103,11 +103,14 @@
throw Exception(syntacticErrors);
}
+ final sampleAssumptions = findFileAssumptions(text);
+
var visitor = ValidateCommentCodeSamplesVisitor(
analysisHelper,
coreLibName,
file.path,
parseResult.lineInfo,
+ sampleAssumptions,
);
await visitor.process(parseResult);
if (visitor.errors.isNotEmpty) {
@@ -118,13 +121,14 @@
return visitor.errors.isEmpty;
}
-/// Visit a compilation unit and collect the list of code samples found in
-/// dartdoc comments.
+/// Visit a compilation unit and validate the code samples found in dartdoc
+/// comments.
class ValidateCommentCodeSamplesVisitor extends GeneralizingAstVisitor {
final AnalysisHelper analysisHelper;
final String coreLibName;
final String filePath;
final LineInfo lineInfo;
+ final String? sampleAssumptions;
final List<CodeSample> samples = [];
final StringBuffer errors = StringBuffer();
@@ -134,6 +138,7 @@
this.coreLibName,
this.filePath,
this.lineInfo,
+ this.sampleAssumptions,
);
Future process(ParseStringResult parseResult) async {
@@ -226,13 +231,15 @@
}
}
+ final assumptions = sampleAssumptions ?? '';
+
if (!hasImports) {
if (template == 'none') {
// just use the sample text as is
} else if (template == 'main') {
- text = "main() async {\n${text.trimRight()}\n}\n";
+ text = "${assumptions}main() async {\n${text.trimRight()}\n}\n";
} else if (template == 'expression') {
- text = "main() async {\n${text.trimRight()}\n;\n}\n";
+ text = "${assumptions}main() async {\n${text.trimRight()}\n;\n}\n";
} else {
throw 'unexpected template directive: $template';
}
@@ -341,6 +348,24 @@
}
}
+/// Find and return any '// Examples can assume:' sample text.
+String? findFileAssumptions(String text) {
+ var inAssumptions = false;
+ var assumptions = <String>[];
+
+ for (final line in text.split('\n')) {
+ if (line == '// Examples can assume:') {
+ inAssumptions = true;
+ } else if (line.trim().isEmpty && inAssumptions) {
+ inAssumptions = false;
+ } else if (inAssumptions) {
+ assumptions.add(line.substring('// '.length));
+ }
+ }
+
+ return '${assumptions.join('\n')}\n';
+}
+
String _severity(Severity severity) {
switch (severity) {
case Severity.info: