Version 2.12.0-216.0.dev
Merge commit '8b0fba90a68943649471e3fc3fbec7f44b90df3e' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart b/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
index efe93db..946989a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
@@ -13,6 +13,7 @@
import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_manager.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart' show LibraryElement;
+import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:meta/meta.dart';
@@ -24,7 +25,6 @@
@override
Iterable<CorrectionProducer> get producers sync* {
- var name = _name;
var importedUris = <Uri>[];
var library = resolvedResult.libraryElement;
for (var importElement in library.imports) {
@@ -36,8 +36,16 @@
importedUris.add(Uri.parse(uri));
}
}
+ var components = _computeComponents();
+ if (components == null) {
+ // If we couldn't compute the components it's because the node doesn't
+ // represent an element that can be transformed.
+ return;
+ }
var matcher = ElementMatcher(
- importedUris: importedUris, name: name, kinds: _kindsForNode(node));
+ importedUris: importedUris,
+ components: components,
+ kinds: _kindsForNode(node));
for (var set in _availableTransformSetsForLibrary(library)) {
for (var transform
in set.transformsFor(matcher, applyingBulkFixes: applyingBulkFixes)) {
@@ -46,48 +54,6 @@
}
}
- /// Return the name of the element that was changed.
- String get _name {
- String nameFromParent(AstNode node) {
- var parent = node.parent;
- if (parent is MethodInvocation) {
- return parent.methodName.name;
- } else if (parent is InstanceCreationExpression) {
- var constructorName = parent.constructorName;
- if (constructorName.name != null) {
- return constructorName.name.name;
- }
- return constructorName.type.name.name;
- } else if (parent is ExtensionOverride) {
- return parent.extensionName.name;
- }
- return null;
- }
-
- var node = this.node;
- if (node is SimpleIdentifier) {
- var parent = node.parent;
- if (parent is Label && parent.parent is NamedExpression) {
- // The parent of the named expression is an argument list. Because we
- // don't represent parameters as elements, the element we need to match
- // against is the invocation containing those arguments.
- return nameFromParent(parent.parent.parent);
- }
- return node.name;
- } else if (node is ConstructorName) {
- return node.name.name;
- } else if (node is NamedType) {
- return node.name.name;
- } else if (node is TypeArgumentList) {
- return nameFromParent(node);
- } else if (node is ArgumentList) {
- return nameFromParent(node);
- } else if (node?.parent is ArgumentList) {
- return nameFromParent(node.parent);
- }
- return null;
- }
-
/// Return the transform sets that are available for fixing issues in the
/// given [library].
List<TransformSet> _availableTransformSetsForLibrary(LibraryElement library) {
@@ -97,6 +63,89 @@
return TransformSetManager.instance.forLibrary(library);
}
+ /// Return the components for the element associated with the given [node] by
+ /// looking at the parent of the [node].
+ List<String> _componentsFromParent(AstNode node) {
+ var parent = node.parent;
+ if (parent is ArgumentList) {
+ parent = parent.parent;
+ }
+ if (parent is Annotation) {
+ return [parent.constructorName?.name ?? '', parent.name.name];
+ } else if (parent is ExtensionOverride) {
+ return [parent.extensionName.name];
+ } else if (parent is InstanceCreationExpression) {
+ var constructorName = parent.constructorName;
+ return [constructorName.name?.name ?? '', constructorName.type.name.name];
+ } else if (parent is MethodInvocation) {
+ var target = _nameOfTarget(parent.realTarget);
+ if (target != null) {
+ return [parent.methodName.name, target];
+ }
+ var ancestor = parent.parent;
+ while (ancestor != null) {
+ if (ancestor is ClassOrMixinDeclaration) {
+ return [parent.methodName.name, ancestor.name.name];
+ } else if (ancestor is ExtensionDeclaration) {
+ return [parent.methodName.name, ancestor.name.name];
+ }
+ ancestor = ancestor.parent;
+ }
+ return [parent.methodName.name];
+ } else if (parent is RedirectingConstructorInvocation) {
+ var ancestor = parent.parent;
+ if (ancestor is ConstructorDeclaration) {
+ return [parent.constructorName?.name ?? '', ancestor.returnType.name];
+ }
+ } else if (parent is SuperConstructorInvocation) {
+ var ancestor = parent.parent;
+ if (ancestor is ConstructorDeclaration) {
+ return [parent.constructorName?.name ?? '', ancestor.returnType.name];
+ }
+ }
+ return null;
+ }
+
+ /// Return the components of the path of the element associated with the
+ /// diagnostic. The components are ordered from the most local to the most
+ /// global. For example, for a constructor this would be the name of the
+ /// constructor followed by the name of the class in which the constructor is
+ /// declared (with an empty string for the unnamed constructor).
+ List<String> _computeComponents() {
+ var node = this.node;
+ if (node is SimpleIdentifier) {
+ var parent = node.parent;
+ if (parent is Label && parent.parent is NamedExpression) {
+ // The parent of the named expression is an argument list. Because we
+ // don't represent parameters as elements, the element we need to match
+ // against is the invocation containing those arguments.
+ return _componentsFromParent(parent.parent.parent);
+ } else if (parent is TypeName && parent.parent is ConstructorName) {
+ return ['', node.name];
+ } else if (parent is MethodInvocation) {
+ return _componentsFromParent(node);
+ }
+ return [node.name];
+ } else if (node is PrefixedIdentifier) {
+ var parent = node.parent;
+ if (parent is TypeName && parent.parent is ConstructorName) {
+ return ['', node.identifier.name];
+ }
+ return [node.identifier.name];
+ } else if (node is ConstructorName) {
+ return [node.name.name];
+ } else if (node is NamedType) {
+ return [node.name.name];
+ } else if (node is TypeArgumentList) {
+ return _componentsFromParent(node);
+ } else if (node is ArgumentList) {
+ return _componentsFromParent(node);
+ } else if (node?.parent is ArgumentList) {
+ return _componentsFromParent(node.parent);
+ }
+ return null;
+ }
+
List<ElementKind> _kindsForNode(AstNode node, {AstNode child}) {
if (node is ConstructorName) {
return const [ElementKind.constructorKind];
@@ -158,6 +207,30 @@
return null;
}
+ /// Return the name of the class associated with the given [target].
+ String _nameOfTarget(Expression target) {
+ if (target is SimpleIdentifier) {
+ var type = target.staticType;
+ if (type != null) {
+ if (type is InterfaceType) {
+ return type.element.name;
+ } else if (type.isDynamic) {
+ // The name is likely to be undefined.
+ return target.name;
+ }
+ return null;
+ }
+ return target.name;
+ } else if (target != null) {
+ var type = target.staticType;
+ if (type is InterfaceType) {
+ return type.element.name;
+ }
+ return null;
+ }
+ return null;
+ }
+
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
static DataDriven newInstance() => DataDriven();
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
index 2520805..ae3f501 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
@@ -16,7 +16,8 @@
/// The kind of element that was changed.
final ElementKind kind;
- /// The components that uniquely identify the element within its library.
+ /// The components that uniquely identify the element within its library. The
+ /// components are ordered from the most local to the most global.
final List<String> components;
/// Initialize a newly created element descriptor to describe an element
@@ -47,27 +48,27 @@
if (node is Annotation) {
var className = _nameFromIdentifier(node.name);
var constructorName = node.constructorName ?? '';
- if (components[0] == className && components[1] == constructorName) {
+ if (components[0] == constructorName && components[1] == className) {
return true;
}
} else if (node is InstanceCreationExpression) {
var name = node.constructorName;
var className = _nameFromIdentifier(name.type.name);
var constructorName = name.name?.name ?? '';
- if (components[0] == className && components[1] == constructorName) {
+ if (components[0] == constructorName && components[1] == className) {
return true;
}
} else if (node is MethodInvocation) {
var target = node.target;
if (target == null) {
- if (components[0] == node.methodName.name && components[1] == '') {
+ if (components[0] == '' && components[1] == node.methodName.name) {
return true;
}
} else if (target is Identifier) {
var className = _nameFromIdentifier(target);
var constructorName = node.methodName.name;
- if (components[0] == className &&
- components[1] == constructorName) {
+ if (components[0] == constructorName &&
+ components[1] == className) {
return true;
}
}
@@ -95,7 +96,7 @@
return false;
case ElementKind.methodKind:
if (node is MethodInvocation) {
- if (components[1] == node.methodName.name) {
+ if (components[0] == node.methodName.name) {
var target = node.realTarget;
if (target == null) {
// TODO(brianwilkerson) If `node.target == null` then the invocation
@@ -115,12 +116,12 @@
// that the method might have been in the element's class.
return true;
}
- if (components[0] == type.element.name) {
+ if (components[1] == type.element.name) {
return true;
}
if (type is InterfaceType) {
for (var supertype in type.allSupertypes) {
- if (components[0] == supertype.element.name) {
+ if (components[1] == supertype.element.name) {
return true;
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
index aac5dff..a938d2c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
@@ -13,38 +13,74 @@
/// reference.
final List<Uri> importedUris;
- /// The name of the element being referenced.
- final String name;
+ /// The components of the element being referenced. The components are ordered
+ /// from the most local to the most global.
+ final List<String> components;
/// A list of the kinds of elements that are appropriate for some given
/// location in the code An empty list represents all kinds rather than no
/// kinds.
- List<ElementKind> validKinds;
+ final List<ElementKind> validKinds;
/// Initialize a newly created matcher representing a reference to an element
/// with the given [name] in a library that imports the [importedUris].
ElementMatcher(
{@required this.importedUris,
- @required this.name,
+ @required this.components,
List<ElementKind> kinds})
- : validKinds = kinds ?? const [];
+ : assert(components != null && components.isNotEmpty),
+ validKinds = kinds ?? const [];
/// Return `true` if this matcher matches the given [element].
bool matches(ElementDescriptor element) {
- var components = element.components;
- var lastComponent = components.last;
- if (lastComponent.isEmpty) {
- if (components[components.length - 2] != name) {
+ //
+ // Check that the components in the element's name match the node.
+ //
+ // This algorithm is probably too general given that there will currently
+ // always be either one or two components.
+ //
+ var elementComponents = element.components;
+ var elementComponentCount = elementComponents.length;
+ var nodeComponentCount = components.length;
+ if (nodeComponentCount == elementComponentCount) {
+ // The component counts are the same, so we can just compare the two
+ // lists.
+ for (var i = 0; i < nodeComponentCount; i++) {
+ if (elementComponents[i] != components[i]) {
+ return false;
+ }
+ }
+ } else if (nodeComponentCount < elementComponentCount) {
+ // The node has fewer components, which can happen, for example, when we
+ // can't figure out the class that used to define a field. We treat the
+ // missing components as wildcards and match the rest.
+ for (var i = 0; i < nodeComponentCount; i++) {
+ if (elementComponents[i] != components[i]) {
+ return false;
+ }
+ }
+ } else {
+ // The node has more components than the element, which can happen when a
+ // constructor is implicitly renamed because the class was renamed.
+ // TODO(brianwilkerson) Figure out whether we want to support this or
+ // whether we want to require fix data authors to explicitly include the
+ // change to the constructor. On the one hand it's more work for the
+ // author, on the other hand it give us more data so we're less likely to
+ // make apply a fix in invalid circumstances.
+ if (elementComponents[0] != components[1]) {
return false;
}
- } else if (lastComponent != name) {
- return false;
}
-
+ //
+ // Check whether the kind of element matches the possible kinds that the
+ // node might have.
+ //
if (validKinds.isNotEmpty && !validKinds.contains(element.kind)) {
return false;
}
-
+ //
+ // Check whether the element is in an imported library.
+ //
var libraryUris = element.libraryUris;
for (var importedUri in importedUris) {
if (libraryUris.contains(importedUri)) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
index 351608c..b0c122c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
@@ -657,7 +657,7 @@
return null;
}
} else {
- components.insert(0, containerName);
+ components.add(containerName);
}
}
if (uris == null) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart
index 88e911a..f39851f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart
@@ -939,6 +939,44 @@
}
''');
}
+
+ Future<void> test_rename_removed_onlyFixOne() async {
+ setPackageContent('''
+class A {
+ void n(int x) {}
+}
+class B {}
+''');
+ addPackageDataFile('''
+version: 1
+transforms:
+- title: 'Rename to new'
+ date: 2020-09-01
+ element:
+ uris: ['$importUri']
+ method: 'o'
+ inClass: 'A'
+ changes:
+ - kind: 'rename'
+ newName: 'n'
+''');
+ await resolveTestCode('''
+import '$importUri';
+
+void f(A a, B b) {
+ a.o(0);
+ b.o(1);
+}
+''');
+ await assertHasFix('''
+import '$importUri';
+
+void f(A a, B b) {
+ a.n(0);
+ b.o(1);
+}
+''');
+ }
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart
index 5ed784f..dcda4bc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/add_type_parameter_test.dart
@@ -483,7 +483,7 @@
element: ElementDescriptor(
libraryUris: [Uri.parse(importUri)],
kind: ElementKindUtilities.fromName(_kind),
- components: components ?? ['C', 'm']),
+ components: components ?? ['m', 'C']),
bulkApply: false,
changesSelector: UnconditionalChangesSelector([
AddTypeParameter(
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
index cca4aef..f6359cd 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
@@ -1045,7 +1045,6 @@
await assertNoFix();
}
- @failingTest
Future<void> test_material_Scaffold_of_wrongType() async {
setPackageContent('''
class Theme {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
index 30f1bce..d67d30e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
@@ -34,7 +34,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(0, 'a', false, false, null)],
+ ['m', 'C'], [AddParameter(0, 'a', false, false, null)],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -61,7 +61,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(0, 'a', false, true, codeTemplate('0'))],
+ ['m', 'C'], [AddParameter(0, 'a', false, true, codeTemplate('0'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -88,7 +88,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(0, 'a', true, false, codeTemplate('0'))],
+ ['m', 'C'], [AddParameter(0, 'a', true, false, codeTemplate('0'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -115,7 +115,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(0, 'a', true, true, codeTemplate('0'))],
+ ['m', 'C'], [AddParameter(0, 'a', true, true, codeTemplate('0'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -142,7 +142,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(1, 'b', false, false, null)],
+ ['m', 'C'], [AddParameter(1, 'b', false, false, null)],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -169,7 +169,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(1, 'b', false, true, codeTemplate('1'))],
+ ['m', 'C'], [AddParameter(1, 'b', false, true, codeTemplate('1'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -196,7 +196,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(1, 'b', true, false, codeTemplate('1'))],
+ ['m', 'C'], [AddParameter(1, 'b', true, false, codeTemplate('1'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -223,7 +223,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(1, 'b', true, true, codeTemplate('1'))],
+ ['m', 'C'], [AddParameter(1, 'b', true, true, codeTemplate('1'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -250,8 +250,8 @@
}
''');
setPackageData(_modify([
- 'C',
- 'm'
+ 'm',
+ 'C'
], [
AddParameter(1, 'b', true, true, codeTemplate('1')),
AddParameter(2, 'c', true, true, codeTemplate('2')),
@@ -280,7 +280,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(0, 'a', true, true, codeTemplate('0'))],
+ ['m', 'C'], [AddParameter(0, 'a', true, true, codeTemplate('0'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -305,7 +305,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(0, 'a', true, true, codeTemplate('0'))]));
+ ['m', 'C'], [AddParameter(0, 'a', true, true, codeTemplate('0'))]));
await resolveTestCode('''
import '$importUri';
@@ -331,8 +331,8 @@
}
''');
setPackageData(_modify([
- 'C',
- 'm'
+ 'm',
+ 'C'
], [
RemoveParameter(PositionalParameterReference(0)),
AddParameter(2, 'c', true, true, codeTemplate('2'))
@@ -362,8 +362,8 @@
}
''');
setPackageData(_modify([
- 'C',
- 'm'
+ 'm',
+ 'C'
], [
RemoveParameter(PositionalParameterReference(1)),
AddParameter(0, 'a', true, true, codeTemplate('0'))
@@ -393,8 +393,8 @@
}
''');
setPackageData(_modify([
- 'C',
- 'm1'
+ 'm1',
+ 'C'
], [
RemoveParameter(PositionalParameterReference(0)),
RemoveParameter(PositionalParameterReference(1)),
@@ -425,8 +425,8 @@
}
''');
setPackageData(_modify([
- 'C',
- 'm1'
+ 'm1',
+ 'C'
], [
RemoveParameter(PositionalParameterReference(1)),
RemoveParameter(PositionalParameterReference(2)),
@@ -457,8 +457,8 @@
}
''');
setPackageData(_modify([
- 'C',
- 'm1'
+ 'm1',
+ 'C'
], [
AddParameter(0, 'a', true, true, codeTemplate('0')),
RemoveParameter(PositionalParameterReference(1)),
@@ -490,8 +490,8 @@
}
''');
setPackageData(_modify([
- 'C',
- 'm1'
+ 'm1',
+ 'C'
], [
AddParameter(0, 'b', true, false, codeTemplate('0')),
RemoveParameter(NamedParameterReference('a')),
@@ -521,7 +521,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(NamedParameterReference('a'))],
+ ['m', 'C'], [RemoveParameter(NamedParameterReference('a'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -548,7 +548,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(PositionalParameterReference(0))],
+ ['m', 'C'], [RemoveParameter(PositionalParameterReference(0))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -575,7 +575,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(PositionalParameterReference(0))],
+ ['m', 'C'], [RemoveParameter(PositionalParameterReference(0))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -602,7 +602,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(NamedParameterReference('b'))],
+ ['m', 'C'], [RemoveParameter(NamedParameterReference('b'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -629,7 +629,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(PositionalParameterReference(1))],
+ ['m', 'C'], [RemoveParameter(PositionalParameterReference(1))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -656,7 +656,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(PositionalParameterReference(1))],
+ ['m', 'C'], [RemoveParameter(PositionalParameterReference(1))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -682,7 +682,7 @@
}
''');
setPackageData(
- _modify(['C', 'm'], [RemoveParameter(NamedParameterReference('b'))]));
+ _modify(['m', 'C'], [RemoveParameter(NamedParameterReference('b'))]));
await resolveTestCode('''
import '$importUri';
@@ -708,8 +708,8 @@
}
''');
setPackageData(_modify([
- 'C',
- 'm'
+ 'm',
+ 'C'
], [
RemoveParameter(PositionalParameterReference(0)),
RemoveParameter(PositionalParameterReference(2)),
@@ -740,7 +740,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(NamedParameterReference('a'))],
+ ['m', 'C'], [RemoveParameter(NamedParameterReference('a'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -767,7 +767,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(NamedParameterReference('a'))],
+ ['m', 'C'], [RemoveParameter(NamedParameterReference('a'))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -794,7 +794,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(PositionalParameterReference(0))],
+ ['m', 'C'], [RemoveParameter(PositionalParameterReference(0))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -822,7 +822,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(PositionalParameterReference(0))],
+ ['m', 'C'], [RemoveParameter(PositionalParameterReference(0))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
@@ -849,7 +849,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [RemoveParameter(PositionalParameterReference(0))],
+ ['m', 'C'], [RemoveParameter(PositionalParameterReference(0))],
newName: 'm2'));
await resolveTestCode('''
import '$importUri';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_parameter_test.dart
index f892cd6..3a189c0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_parameter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_parameter_test.dart
@@ -30,7 +30,7 @@
C.named({int b, @deprecated int a});
}
''');
- setPackageData(_rename(['C', 'named'], 'a', 'b'));
+ setPackageData(_rename(['named', 'C'], 'a', 'b'));
await resolveTestCode('''
import '$importUri';
@@ -53,7 +53,7 @@
C.named({int b});
}
''');
- setPackageData(_rename(['C', 'named'], 'a', 'b'));
+ setPackageData(_rename(['named', 'C'], 'a', 'b'));
await resolveTestCode('''
import '$importUri';
@@ -76,7 +76,7 @@
C({int b, @deprecated int a});
}
''');
- setPackageData(_rename(['C', ''], 'a', 'b'));
+ setPackageData(_rename(['', 'C'], 'a', 'b'));
await resolveTestCode('''
import '$importUri';
@@ -99,7 +99,7 @@
C({int b});
}
''');
- setPackageData(_rename(['C', ''], 'a', 'b'));
+ setPackageData(_rename(['', 'C'], 'a', 'b'));
await resolveTestCode('''
import '$importUri';
@@ -128,7 +128,7 @@
int m({int b, @deprecated int a}) => 0;
}
''');
- setPackageData(_rename(['D', 'm'], 'a', 'nbew'));
+ setPackageData(_rename(['m', 'D'], 'a', 'nbew'));
await resolveTestCode('''
import '$importUri';
@@ -145,7 +145,7 @@
int m({int b, @deprecated int a}) => 0;
}
''');
- setPackageData(_rename(['C', 'm'], 'a', 'b'));
+ setPackageData(_rename(['m', 'C'], 'a', 'b'));
await resolveTestCode('''
import '$importUri';
@@ -170,7 +170,7 @@
int m({int b}) => 0;
}
''');
- setPackageData(_rename(['C', 'm'], 'a', 'b'));
+ setPackageData(_rename(['m', 'C'], 'a', 'b'));
await resolveTestCode('''
import '$importUri';
@@ -195,7 +195,7 @@
int m({int b, @deprecated int a}) => 0;
}
''');
- setPackageData(_rename(['C', 'm'], 'a', 'b'));
+ setPackageData(_rename(['m', 'C'], 'a', 'b'));
await resolveTestCode('''
import '$importUri';
@@ -218,7 +218,7 @@
int m({int b}) => 0;
}
''');
- setPackageData(_rename(['C', 'm'], 'a', 'b'));
+ setPackageData(_rename(['m', 'C'], 'a', 'b'));
await resolveTestCode('''
import '$importUri';
@@ -241,7 +241,7 @@
static int m({int b, @deprecated int a}) => 0;
}
''');
- setPackageData(_rename(['C', 'm'], 'a', 'b'));
+ setPackageData(_rename(['m', 'C'], 'a', 'b'));
await resolveTestCode('''
import '$importUri';
@@ -264,7 +264,7 @@
static int m({int b}) => 0;
}
''');
- setPackageData(_rename(['C', 'm'], 'a', 'b'));
+ setPackageData(_rename(['m', 'C'], 'a', 'b'));
await resolveTestCode('''
import '$importUri';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_test.dart
index 2edc72d..6e0ce4a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_test.dart
@@ -366,7 +366,7 @@
C.b();
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -389,7 +389,7 @@
C.b();
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -414,7 +414,7 @@
C();
}
''');
- setPackageData(_rename(['C', 'old'], ''));
+ setPackageData(_rename(['old', 'C'], ''));
await resolveTestCode('''
import '$importUri';
@@ -437,7 +437,7 @@
C();
}
''');
- setPackageData(_rename(['C', 'old'], ''));
+ setPackageData(_rename(['old', 'C'], ''));
await resolveTestCode('''
import '$importUri';
@@ -462,7 +462,7 @@
C.a();
}
''');
- setPackageData(_rename(['C', ''], 'a'));
+ setPackageData(_rename(['', 'C'], 'a'));
await resolveTestCode('''
import '$importUri';
@@ -485,7 +485,7 @@
C.a();
}
''');
- setPackageData(_rename(['C', ''], 'a'));
+ setPackageData(_rename(['', 'C'], 'a'));
await resolveTestCode('''
import '$importUri';
@@ -606,7 +606,7 @@
int b;
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -629,7 +629,7 @@
int b;
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -654,7 +654,7 @@
static int b;
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -677,7 +677,7 @@
static int b;
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -702,7 +702,7 @@
static int b;
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -725,7 +725,7 @@
static int b;
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -760,7 +760,7 @@
void a(int b) {}
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -782,7 +782,7 @@
D({@deprecated int a; int c});
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -799,7 +799,7 @@
int get b => 1;
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -822,7 +822,7 @@
int get b => 1;
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -850,7 +850,7 @@
C c() => C();
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -876,7 +876,7 @@
C c() => C();
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -952,7 +952,7 @@
int b() => 0;
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -977,7 +977,7 @@
int b() => 0;
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -1004,7 +1004,7 @@
int b() {}
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -1027,7 +1027,7 @@
int b() {}
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -1052,7 +1052,7 @@
static int b() {}
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
@@ -1075,7 +1075,7 @@
static int b() {}
}
''');
- setPackageData(_rename(['C', 'a'], 'b'));
+ setPackageData(_rename(['a', 'C'], 'b'));
await resolveTestCode('''
import '$importUri';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
index 27d339c..d2789c8 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
@@ -728,7 +728,7 @@
(transform.changesSelector as UnconditionalChangesSelector).changes;
ElementMatcher _matcher(String name) =>
- ElementMatcher(importedUris: uris, name: name);
+ ElementMatcher(importedUris: uris, components: [name]);
List<Transform> _transforms(String name) =>
result.transformsFor(_matcher(name), applyingBulkFixes: false);
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index d5a70ba..fcc224f 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -1492,7 +1492,6 @@
sink.writeEnum(JsNodeKind.literalExpression);
sink.begin(JsNodeTags.literalExpression);
sink.writeString(node.template);
- visitList(node.inputs);
sink.end(JsNodeTags.literalExpression);
_writeInfo(node);
}
@@ -1961,9 +1960,7 @@
break;
case JsNodeKind.literalExpression:
source.begin(JsNodeTags.literalExpression);
- String template = source.readString();
- List<js.Expression> inputs = readList();
- node = new js.LiteralExpression.withData(template, inputs);
+ node = new js.LiteralExpression(source.readString());
source.end(JsNodeTags.literalExpression);
break;
case JsNodeKind.dartYield:
diff --git a/pkg/compiler/lib/src/js/size_estimator.dart b/pkg/compiler/lib/src/js/size_estimator.dart
index 347c146..257fa70 100644
--- a/pkg/compiler/lib/src/js/size_estimator.dart
+++ b/pkg/compiler/lib/src/js/size_estimator.dart
@@ -982,21 +982,7 @@
@override
void visitLiteralExpression(LiteralExpression node) {
- String template = node.template;
- List<Expression> inputs = node.inputs;
-
- List<String> parts = template.split('#');
- int inputsLength = inputs == null ? 0 : inputs.length;
- if (parts.length != inputsLength + 1) {
- throw UnsupportedError('Wrong number of arguments for JS: $template');
- }
- // Code that uses JS must take care of operator precedences, and
- // put parenthesis if needed.
- out(parts[0]); // '${parts[0]}'
- for (int i = 0; i < inputsLength; i++) {
- visit(inputs[i]);
- out(parts[i + 1]); // '${parts[i + 1]}'
- }
+ out(node.template); // '${node.template}'
}
@override
diff --git a/pkg/dds/test/smoke_test.dart b/pkg/dds/test/smoke_test.dart
index d317893..983a2da 100644
--- a/pkg/dds/test/smoke_test.dart
+++ b/pkg/dds/test/smoke_test.dart
@@ -82,35 +82,6 @@
createSmokeTest(true, false);
createSmokeTest(false, false);
createSmokeTest(true, true);
-
- test('startup fails when VM service has existing clients', () async {
- Uri httpToWebSocketUri(Uri httpUri) {
- final segments = (httpUri.pathSegments.isNotEmpty)
- ? (httpUri.pathSegments.toList()..removeLast())
- : <String>[];
- segments.add('ws');
- return httpUri.replace(
- scheme: 'ws',
- pathSegments: segments,
- );
- }
-
- final _ = await vmServiceConnectUri(
- httpToWebSocketUri(remoteVmServiceUri).toString(),
- );
- try {
- dds = await DartDevelopmentService.startDartDevelopmentService(
- remoteVmServiceUri,
- );
- fail(
- 'DDS startup should fail if there are existing VM service clients.');
- } on DartDevelopmentServiceException catch (e) {
- expect(e.message,
- 'Existing VM service clients prevent DDS from taking control.');
- expect(e.errorCode,
- DartDevelopmentServiceException.existingDdsInstanceError);
- }
- });
});
test('Invalid args test', () async {
diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
index 137bfd4..bdfb6c9 100644
--- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
@@ -906,28 +906,19 @@
class LiteralExpression extends Expression {
final String template;
- final List<Expression> inputs;
-
- LiteralExpression(this.template) : inputs = const [];
- LiteralExpression.withData(this.template, this.inputs);
+ LiteralExpression(this.template);
@override
T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralExpression(this);
@override
- void visitChildren(NodeVisitor visitor) {
- if (inputs != null) {
- for (Expression expr in inputs) {
- expr.accept(visitor);
- }
- }
- }
+ void visitChildren(NodeVisitor visitor) {}
@override
- LiteralExpression _clone() => LiteralExpression.withData(template, inputs);
+ LiteralExpression _clone() => LiteralExpression(template);
- // Code that uses JS must take care of operator precedences, and
- // put parenthesis if needed.
+ // Code that uses LiteralExpression must take care of operator precedences,
+ // and put parenthesis if needed.
@override
int get precedenceLevel => PRIMARY;
}
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart
index d62126b..9fabc56 100644
--- a/pkg/dev_compiler/lib/src/js_ast/printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart
@@ -1355,21 +1355,7 @@
@override
visitLiteralExpression(LiteralExpression node) {
- String template = node.template;
- List<Expression> inputs = node.inputs;
-
- List<String> parts = template.split('#');
- int inputsLength = inputs == null ? 0 : inputs.length;
- if (parts.length != inputsLength + 1) {
- context.error('Wrong number of arguments for JS: $template');
- }
- // Code that uses JS must take care of operator precedences, and
- // put parenthesis if needed.
- out(parts[0]);
- for (int i = 0; i < inputsLength; i++) {
- visit(inputs[i]);
- out(parts[i + 1]);
- }
+ out(node.template);
}
@override
diff --git a/pkg/dev_compiler/tool/check_nnbd_sdk.dart b/pkg/dev_compiler/tool/check_nnbd_sdk.dart
index 80ba657..c329e26 100644
--- a/pkg/dev_compiler/tool/check_nnbd_sdk.dart
+++ b/pkg/dev_compiler/tool/check_nnbd_sdk.dart
@@ -134,6 +134,12 @@
// Trim temporary directory paths and sort errors.
errors = errors.replaceAll(sdkDir, '');
+ if (!(args['keep-lines'] as bool)) {
+ // Golden files change frequenty if line numbers are recorded.
+ // We remove them by default but provide an option to show them if
+ // they can be helpful.
+ errors = errors.replaceAll(RegExp(r'\|[0-9]*\|[0-9]*\|[0-9]*\|'), '|');
+ }
var errorList = errors.isEmpty ? <String>[] : errors.trim().split('\n');
var count = errorList.length;
print('$count analyzer errors.');
@@ -209,4 +215,6 @@
allowed: ['dartdevc', 'dart2js', 'dart2js_server', 'vm', 'flutter'],
defaultsTo: 'dartdevc')
..addFlag('update-golden', help: 'Update the golden file.', defaultsTo: false)
+ ..addFlag('keep-lines',
+ help: 'Show line numbers on errors.', defaultsTo: false)
..addFlag('help', abbr: 'h', help: 'Display this message.');
diff --git a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
index 91c4e1e..960c5e4 100644
--- a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
@@ -1,10 +1,10 @@
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1718|7|5|Superinterfaces don't have a valid override for '&': JSNumber.& (num Function(num)), int.& (int Function(int)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1718|7|5|Superinterfaces don't have a valid override for '<<': JSNumber.<< (num Function(num)), int.<< (int Function(int)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1718|7|5|Superinterfaces don't have a valid override for '>>': JSNumber.>> (num Function(num)), int.>> (int Function(int)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1718|7|5|Superinterfaces don't have a valid override for '\|': JSNumber.\| (num Function(num)), int.\| (int Function(int)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1718|7|5|Superinterfaces don't have a valid override for '^': JSNumber.^ (num Function(num)), int.^ (int Function(int)).
-ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1735|28|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1737|27|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1740|17|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1745|18|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1745|44|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '&': JSNumber.& (num Function(num)), int.& (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '<<': JSNumber.<< (num Function(num)), int.<< (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '>>': JSNumber.>> (num Function(num)), int.>> (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '\|': JSNumber.\| (num Function(num)), int.\| (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '^': JSNumber.^ (num Function(num)), int.^ (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|The operator '&' isn't defined for the type 'JSInt'.
diff --git a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
index dd6530e..3adfa76 100644
--- a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
@@ -1,8 +1,8 @@
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3679|5|94|Const constructors can't throw exceptions.
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7888|5|97|Const constructors can't throw exceptions.
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|893|5|95|Const constructors can't throw exceptions.
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|926|5|94|Const constructors can't throw exceptions.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3677|3|5|Only redirecting factory constructors can be declared to be 'const'.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7886|3|5|Only redirecting factory constructors can be declared to be 'const'.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|891|3|5|Only redirecting factory constructors can be declared to be 'const'.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|924|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|Const constructors can't throw exceptions.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|Only redirecting factory constructors can be declared to be 'const'.
diff --git a/pkg/js_ast/lib/src/equivalence_visitor.dart b/pkg/js_ast/lib/src/equivalence_visitor.dart
index 42801c0..d06f50f 100644
--- a/pkg/js_ast/lib/src/equivalence_visitor.dart
+++ b/pkg/js_ast/lib/src/equivalence_visitor.dart
@@ -341,8 +341,7 @@
bool visitLiteralExpression(LiteralExpression node, Node arg) {
if (arg is! LiteralExpression) return failAt(node, arg);
LiteralExpression other = arg;
- return testValues(node, node.template, other, other.template) &&
- testNodeLists(node.inputs, other.inputs);
+ return testValues(node, node.template, other, other.template);
}
@override
diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart
index 7a9298a..b9cc51f 100644
--- a/pkg/js_ast/lib/src/nodes.dart
+++ b/pkg/js_ast/lib/src/nodes.dart
@@ -1023,34 +1023,21 @@
class LiteralExpression extends Expression {
final String template;
- final List<Expression> inputs;
-
- LiteralExpression(this.template) : inputs = const [];
-
- LiteralExpression.withData(this.template, this.inputs);
+ LiteralExpression(this.template);
T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralExpression(this);
R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
visitor.visitLiteralExpression(this, arg);
- void visitChildren<T>(NodeVisitor<T> visitor) {
- if (inputs != null) {
- for (Expression expr in inputs) expr.accept(visitor);
- }
- }
+ void visitChildren<T>(NodeVisitor<T> visitor) {}
- void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
- if (inputs != null) {
- for (Expression expr in inputs) expr.accept1(visitor, arg);
- }
- }
+ void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}
- LiteralExpression _clone() =>
- new LiteralExpression.withData(template, inputs);
+ LiteralExpression _clone() => LiteralExpression(template);
- // Code that uses JS must take care of operator precedences, and
- // put parenthesis if needed.
+ // Code that uses LiteralExpression must take care of operator precedences,
+ // and put parenthesis if needed.
int get precedenceLevel => PRIMARY;
}
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index 400dc42..0d04a21 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -1255,21 +1255,7 @@
@override
void visitLiteralExpression(LiteralExpression node) {
- String template = node.template;
- List<Expression> inputs = node.inputs;
-
- List<String> parts = template.split('#');
- int inputsLength = inputs == null ? 0 : inputs.length;
- if (parts.length != inputsLength + 1) {
- context.error('Wrong number of arguments for JS: $template');
- }
- // Code that uses JS must take care of operator precedences, and
- // put parenthesis if needed.
- out(parts[0]);
- for (int i = 0; i < inputsLength; i++) {
- visit(inputs[i]);
- out(parts[i + 1]);
- }
+ out(node.template);
}
@override
diff --git a/runtime/observatory/tests/service/dds_disconnects_existing_clients_test.dart b/runtime/observatory/tests/service/dds_disconnects_existing_clients_test.dart
new file mode 100644
index 0000000..584b1cc
--- /dev/null
+++ b/runtime/observatory/tests/service/dds_disconnects_existing_clients_test.dart
@@ -0,0 +1,61 @@
+// 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:async';
+
+import 'package:dds/dds.dart';
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+
+import 'test_helper.dart';
+
+final tests = <VMTest>[
+ (VM vm) async {
+ late DartDevelopmentService dds;
+ final waitForDDS = Completer<void>();
+ final serviceMessageCompleter = Completer<void>();
+
+ // The original VM service client is connected.
+ expect(vm.isConnected, true);
+
+ // A service event is sent to all existing clients when DDS connects before
+ // their connection is closed.
+ await vm.listenEventStream('Service', (ServiceEvent event) async {
+ // Wait for dds to be set before checking the server's URI.
+ await waitForDDS.future;
+ final message =
+ 'A Dart Developer Service instance has connected and this direct '
+ 'connection to the VM service will now be closed. Please reconnect to '
+ 'the Dart Development Service at ${dds.uri}.';
+ expect(event.kind, ServiceEvent.kDartDevelopmentServiceConnected);
+ expect(event.message, message);
+ expect(event.uri, dds.uri);
+ serviceMessageCompleter.complete();
+ });
+
+ // Start DDS, which should result in the original VM service client being
+ // disconnected from the VM service.
+ final remote = Uri.parse(vm.target.networkAddress);
+ dds = await DartDevelopmentService.startDartDevelopmentService(
+ remote.replace(
+ scheme: 'http',
+ pathSegments: remote.pathSegments.sublist(
+ 0,
+ remote.pathSegments.length - 1,
+ ),
+ ),
+ );
+ waitForDDS.complete();
+ expect(dds.isRunning, true);
+ await serviceMessageCompleter.future;
+ await vm.onDisconnect;
+ await dds.shutdown();
+ }
+];
+
+main(args) async => runVMTests(
+ args,
+ tests,
+ enableDds: false,
+ );
diff --git a/runtime/observatory_2/tests/service_2/dds_disconnects_existing_clients_test.dart b/runtime/observatory_2/tests/service_2/dds_disconnects_existing_clients_test.dart
new file mode 100644
index 0000000..a8b529e
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/dds_disconnects_existing_clients_test.dart
@@ -0,0 +1,61 @@
+// 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:async';
+
+import 'package:dds/dds.dart';
+import 'package:observatory_2/service_io.dart';
+import 'package:test/test.dart';
+
+import 'test_helper.dart';
+
+final tests = <VMTest>[
+ (VM vm) async {
+ DartDevelopmentService dds;
+ final waitForDDS = Completer<void>();
+ final serviceMessageCompleter = Completer<void>();
+
+ // The original VM service client is connected.
+ expect(vm.isConnected, true);
+
+ // A service event is sent to all existing clients when DDS connects before
+ // their connection is closed.
+ await vm.listenEventStream('Service', (ServiceEvent event) async {
+ // Wait for dds to be set before checking the server's URI.
+ await waitForDDS.future;
+ final message =
+ 'A Dart Developer Service instance has connected and this direct '
+ 'connection to the VM service will now be closed. Please reconnect to '
+ 'the Dart Development Service at ${dds.uri}.';
+ expect(event.kind, ServiceEvent.kDartDevelopmentServiceConnected);
+ expect(event.message, message);
+ expect(event.uri, dds.uri);
+ serviceMessageCompleter.complete();
+ });
+
+ // Start DDS, which should result in the original VM service client being
+ // disconnected from the VM service.
+ final remote = Uri.parse(vm.target.networkAddress);
+ dds = await DartDevelopmentService.startDartDevelopmentService(
+ remote.replace(
+ scheme: 'http',
+ pathSegments: remote.pathSegments.sublist(
+ 0,
+ remote.pathSegments.length - 1,
+ ),
+ ),
+ );
+ waitForDDS.complete();
+ expect(dds.isRunning, true);
+ await serviceMessageCompleter.future;
+ await vm.onDisconnect;
+ await dds.shutdown();
+ }
+];
+
+main(args) async => runVMTests(
+ args,
+ tests,
+ enableDds: false,
+ );
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index a220f97..dfa5bba 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -25216,6 +25216,19 @@
Function::Cast(member).ToLibNamePrefixedQualifiedCString(),
Function::KindToCString(Function::Cast(member).kind()))
: member.ToCString();
+ if (!FLAG_verify_entry_points) {
+ // Print a warning, but do not return an error.
+ char const* warning = OS::SCreate(
+ Thread::Current()->zone(),
+ "WARNING: '%s' is accessed through Dart C API without being marked as "
+ "an entry point; its tree-shaken signature cannot be verified.\n"
+ "WARNING: See "
+ "https://github.com/dart-lang/sdk/blob/master/runtime/docs/compiler/"
+ "aot/entry_point_pragma.md\n",
+ member_cstring);
+ OS::PrintErr("%s", warning);
+ return Error::null();
+ }
char const* error = OS::SCreate(
Thread::Current()->zone(),
"ERROR: It is illegal to access '%s' through Dart C API.\n"
diff --git a/sdk/lib/async/schedule_microtask.dart b/sdk/lib/async/schedule_microtask.dart
index 7e2e933..d01b483 100644
--- a/sdk/lib/async/schedule_microtask.dart
+++ b/sdk/lib/async/schedule_microtask.dart
@@ -132,6 +132,7 @@
* Learn how Dart handles the event queue and microtask queue, so you can write
* better asynchronous code with fewer surprises.
*/
+@pragma('vm:entry-point', 'call')
void scheduleMicrotask(void Function() callback) {
_Zone currentZone = Zone._current;
if (identical(_rootZone, currentZone)) {
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index f7f4a26..a3f7e8b 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -231,6 +231,28 @@
Uri? get ddsUri => _ddsUri;
Uri? _ddsUri;
+ void _sendDdsConnectedEvent(Client client, String uri) {
+ final message =
+ 'A Dart Developer Service instance has connected and this direct '
+ 'connection to the VM service will now be closed. Please reconnect to '
+ 'the Dart Development Service at $uri.';
+ final event = Response.json({
+ 'jsonrpc': '2.0',
+ 'method': 'streamNotify',
+ 'params': {
+ 'streamId': kServiceStream,
+ 'event': {
+ "type": "Event",
+ "kind": "DartDevelopmentServiceConnected",
+ "message": message,
+ "uri": uri,
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ }
+ }
+ });
+ client.post(event);
+ }
+
Future<String> _yieldControlToDDS(Message message) async {
final acceptNewWebSocketConnections =
VMServiceEmbedderHooks.acceptNewWebSocketConnections;
@@ -249,14 +271,16 @@
if (uri == null) {
return encodeMissingParamError(message, 'uri');
}
- // DDS can only take control if there is no other clients connected
- // directly to the VM service.
- if (clients.length > 1) {
- return encodeRpcError(message, kFeatureDisabled,
- details:
- 'Existing VM service clients prevent DDS from taking control.');
- }
acceptNewWebSocketConnections(false);
+ // Note: we call clients.toList() to avoid concurrent modification errors.
+ for (final client in clients.toList()) {
+ // This is the DDS client.
+ if (message.client == client) {
+ continue;
+ }
+ _sendDdsConnectedEvent(client, uri);
+ client.disconnect();
+ }
_ddsUri = Uri.parse(uri);
await VMServiceEmbedderHooks.ddsConnected!();
return encodeSuccess(message);
diff --git a/tools/VERSION b/tools/VERSION
index 2a0644f..ccecce5 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 215
+PRERELEASE 216
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/flutter/analyze_flutter_flutter.sh b/tools/bots/flutter/analyze_flutter_flutter.sh
index e639f93..adca5cb 100755
--- a/tools/bots/flutter/analyze_flutter_flutter.sh
+++ b/tools/bots/flutter/analyze_flutter_flutter.sh
@@ -32,4 +32,10 @@
bin/flutter update-packages
+# Analyze the flutter/flutter source code.
$dart --enable-asserts dev/bots/analyze.dart --dart-sdk $sdk
+
+# Test flutter's use of data-driven fixes.
+pushd packages/flutter/test_fixes
+../../../bin/dart fix --compare-to-golden
+popd