Version 2.12.0-44.0.dev
Merge commit '94fa3c89c7caa7a9a6f476e151e2eea15f12bbb5' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index 23f68a1..d6a2a15 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
name: _fe_analyzer_shared
-version: 12.0.0
+version: 13.0.0
description: Logic that is shared between the front_end and analyzer packages.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/_fe_analyzer_shared
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index fb9d078..7ca094c 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -632,6 +632,7 @@
/// Return `true` if the new relevance computations should be used when
/// computing code completion suggestions.
+ // TODO: This flag is no longer used.
bool useNewRelevance = true;
/// The set of enabled features.
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 754fb57..642f895 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -275,10 +275,6 @@
/// A directory to analyze in order to train an analysis server snapshot.
static const String TRAIN_USING = 'train-using';
- /// A flag indicating that the new code completion relevance computation
- /// should be used to compute relevance scores.
- static const String USE_NEW_RELEVANCE = 'use-new-relevance';
-
/// The builder for attachments that should be included into crash reports.
CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder =
CrashReportingAttachmentsBuilder.empty;
@@ -317,7 +313,6 @@
analysisServerOptions.clientVersion = results[CLIENT_VERSION];
analysisServerOptions.cacheFolder = results[CACHE_FOLDER];
- analysisServerOptions.useNewRelevance = results[USE_NEW_RELEVANCE];
// Read in any per-SDK overrides specified in <sdk>/config/settings.json.
var sdkConfig = SdkConfiguration.readFromSdk();
@@ -719,14 +714,34 @@
CommandLineParser _createArgParser() {
var parser = CommandLineParser();
parser.addFlag(HELP_OPTION,
- help: 'print this help message without starting a server',
- abbr: 'h',
- defaultsTo: false,
- negatable: false);
+ abbr: 'h', negatable: false, help: 'Print this usage information.');
parser.addOption(CLIENT_ID,
- valueHelp: 'name', help: 'an identifier used to identify the client');
+ valueHelp: 'name', help: 'An identifier used to identify the client.');
parser.addOption(CLIENT_VERSION,
- valueHelp: 'version', help: 'the version of the client');
+ valueHelp: 'version', help: 'The version of the client.');
+
+ parser.addFlag(USE_LSP,
+ defaultsTo: false,
+ negatable: false,
+ help: 'Whether to use the Language Server Protocol (LSP).');
+
+ parser.addOption(SDK_OPTION,
+ valueHelp: 'path', help: 'The path to the Dart SDK.');
+ parser.addOption(CACHE_FOLDER,
+ valueHelp: 'path',
+ help: 'The path to the location to write cache data.');
+
+ parser.addOption(INSTRUMENTATION_LOG_FILE,
+ valueHelp: 'file path',
+ help: 'Write instrumentation data to the given file.');
+ parser.addOption(NEW_ANALYSIS_DRIVER_LOG,
+ valueHelp: 'path',
+ help: "Set a destination for the new analysis driver's log.");
+ parser.addOption(PORT_OPTION,
+ valueHelp: 'port',
+ help: 'The http diagnostic port to serve status and performance '
+ 'information.');
+
parser.addFlag(DISABLE_SERVER_EXCEPTION_HANDLING,
// TODO(jcollins-g): Pipeline option through and apply to all
// exception-nullifying runZoned() calls.
@@ -738,16 +753,12 @@
help: 'disable all completion features', defaultsTo: false, hide: true);
parser.addFlag(DISABLE_SERVER_FEATURE_SEARCH,
help: 'disable all search features', defaultsTo: false, hide: true);
- parser.addOption(INSTRUMENTATION_LOG_FILE,
- valueHelp: 'file path',
- help: 'write instrumentation data to the given file');
parser.addFlag(INTERNAL_PRINT_TO_CONSOLE,
help: 'enable sending `print` output to the console',
defaultsTo: false,
- negatable: false);
- parser.addOption(NEW_ANALYSIS_DRIVER_LOG,
- valueHelp: 'path',
- help: "set a destination for the new analysis driver's log");
+ negatable: false,
+ hide: true);
+
parser.addFlag(ANALYTICS_FLAG,
help: 'enable or disable sending analytics information to Google',
hide: !telemetry.SHOW_ANALYTICS_UI);
@@ -755,34 +766,17 @@
negatable: false,
help: 'suppress analytics for this session',
hide: !telemetry.SHOW_ANALYTICS_UI);
- parser.addOption(PORT_OPTION,
- valueHelp: 'port',
- help: 'the http diagnostic port on which the server provides'
- ' status and performance information');
- parser.addOption(SDK_OPTION,
- valueHelp: 'path', help: 'Path to the Dart sdk');
- parser.addOption(CACHE_FOLDER,
- valueHelp: 'path', help: 'Path to the location to write cache data');
- parser.addFlag(USE_LSP,
- defaultsTo: false,
- negatable: false,
- help: 'Whether to use the Language Server Protocol');
- parser.addFlag(ENABLE_COMPLETION_MODEL,
- help: 'Whether or not to turn on ML ranking for code completion');
- parser.addOption(COMPLETION_MODEL_FOLDER,
- valueHelp: 'path',
- help: 'Path to the location of a code completion model');
+
parser.addOption(TRAIN_USING,
valueHelp: 'path',
help: 'Pass in a directory to analyze for purposes of training an '
'analysis server snapshot.');
- //
- // Temporary flags.
- //
- parser.addFlag(USE_NEW_RELEVANCE,
- defaultsTo: true,
- help: 'Use the new relevance computation for code completion.');
+ parser.addFlag(ENABLE_COMPLETION_MODEL,
+ help: 'Whether or not to turn on ML ranking for code completion.');
+ parser.addOption(COMPLETION_MODEL_FOLDER,
+ valueHelp: 'path',
+ help: 'Path to the location of a code completion model.');
//
// Deprecated options - no longer read from.
@@ -800,6 +794,8 @@
parser.addFlag('preview-dart-2', hide: true);
// Removed 11/12/2020.
parser.addFlag('useAnalysisHighlight2', hide: true);
+ // Removed 11/13/2020.
+ parser.addFlag('use-new-relevance', hide: true);
// Removed 9/23/2020.
parser.addFlag('use-fasta-parser', hide: true);
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 d9d82b5..7ecd51e 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
@@ -4,6 +4,7 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
@@ -178,7 +179,11 @@
@override
Future<void> compute(ChangeBuilder builder) async {
- var changes = _transform.changes;
+ var changes = _transform.changesSelector
+ .getChanges(TemplateContext.forInvocation(node, utils));
+ if (changes == null) {
+ return;
+ }
var data = <Object>[];
for (var change in changes) {
var result = change.validate(this);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart
index 6fbcad4..1dc11da 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/add_type_parameter.dart
@@ -50,7 +50,7 @@
@override
_Data validate(DataDrivenFix fix) {
var node = fix.node;
- var context = TemplateContext(getInvocation(node), fix.utils);
+ var context = TemplateContext.forInvocation(node, fix.utils);
if (node is NamedType) {
// wrong_number_of_type_arguments
// wrong_number_of_type_arguments_constructor
@@ -101,7 +101,7 @@
void _applyToTypeArguments(
DartFileEditBuilder builder, DataDrivenFix fix, _TypeArgumentData data) {
- var context = TemplateContext(getInvocation(fix.node), fix.utils);
+ var context = TemplateContext.forInvocation(fix.node, fix.utils);
var typeArguments = data.typeArguments;
if (typeArguments == null) {
// Adding the first type argument.
@@ -130,7 +130,7 @@
void _applyToTypeParameters(
DartFileEditBuilder builder, DataDrivenFix fix, _TypeParameterData data) {
- var context = TemplateContext(getInvocation(fix.node), fix.utils);
+ var context = TemplateContext.forInvocation(fix.node, fix.utils);
void writeParameter(DartEditBuilder builder) {
builder.write(name);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/change.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/change.dart
index 39b5db6..f73f6ae 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/change.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/change.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
-import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
/// The behavior common to all of the changes used to construct a transform.
@@ -13,36 +12,6 @@
/// [validate] method.
void apply(DartFileEditBuilder builder, DataDrivenFix fix, D data);
- /// Return the invocation containing the given [node]. The invocation will be
- /// either an instance creation expression, function invocation, method
- /// invocation, or an extension override.
- AstNode getInvocation(AstNode node) {
- if (node is ArgumentList) {
- return node.parent;
- } else if (node is InstanceCreationExpression ||
- node is InvocationExpression) {
- return node;
- } else if (node is SimpleIdentifier) {
- var parent = node.parent;
- if (parent is ConstructorName) {
- var grandparent = parent.parent;
- if (grandparent is InstanceCreationExpression) {
- return grandparent;
- }
- } else if (parent is MethodInvocation && parent.methodName == node) {
- return parent;
- }
- } else if (node is TypeArgumentList) {
- var parent = node.parent;
- if (parent is InvocationExpression) {
- return parent;
- } else if (parent is ExtensionOverride) {
- return parent;
- }
- }
- return null;
- }
-
/// Validate that this change can be applied. Return the data to be passed to
/// [apply] if the change can be applied, or `null` if it can't be applied.
D validate(DataDrivenFix fix);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/changes_selector.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/changes_selector.dart
new file mode 100644
index 0000000..85f7b7e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/changes_selector.dart
@@ -0,0 +1,50 @@
+// 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.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart';
+
+/// An object that can select a single list of changes from among one or more
+/// possible lists.
+abstract class ChangesSelector {
+ /// Return the list of changes that should be applied based on the [context].
+ List<Change> getChanges(TemplateContext context);
+}
+
+/// A changes selector that uses boolean-valued conditions to select the list.
+class ConditionalChangesSelector implements ChangesSelector {
+ /// A table mapping the expressions to be evaluated to the changes that those
+ /// conditions select.
+ final Map<Expression, List<Change>> changeMap;
+
+ /// Initialize a newly created conditional changes selector with the changes
+ /// in the [changeMap].
+ ConditionalChangesSelector(this.changeMap);
+
+ @override
+ List<Change> getChanges(TemplateContext context) {
+ for (var entry in changeMap.entries) {
+ if (entry.key.evaluateIn(context)) {
+ return entry.value;
+ }
+ }
+ return null;
+ }
+}
+
+/// A changes selector that has a single, unconditional list of changes.
+class UnconditionalChangesSelector implements ChangesSelector {
+ /// The list of changes to be returned.
+ final List<Change> changes;
+
+ /// Initialize a newly created changes selector to return the given list of
+ /// [changes].
+ UnconditionalChangesSelector(this.changes);
+
+ @override
+ List<Change> getChanges(TemplateContext context) {
+ return changes;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_fragment_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_fragment_parser.dart
index 1e468e6..0050c6d8 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_fragment_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_fragment_parser.dart
@@ -275,7 +275,7 @@
/// <identifier> | <string>
Expression _parsePrimaryExpression() {
var token = currentToken;
- var kind = token.kind;
+ var kind = token?.kind;
if (kind == _TokenKind.identifier) {
advance();
var variableName = token.lexeme;
@@ -295,8 +295,23 @@
var value = lexeme.substring(1, lexeme.length - 1);
return LiteralString(value);
}
- errorReporter.reportErrorForOffset(TransformSetErrorCode.expectedPrimary,
- token.offset + delta, token.length);
+ int offset;
+ int length;
+ if (token == null) {
+ if (tokens.isNotEmpty) {
+ token = tokens[tokens.length - 1];
+ offset = token.offset + delta;
+ length = token.length;
+ } else {
+ offset = delta;
+ length = 0;
+ }
+ } else {
+ offset = token.offset + delta;
+ length = token.length;
+ }
+ errorReporter.reportErrorForOffset(
+ TransformSetErrorCode.expectedPrimary, offset, length);
return null;
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_template.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_template.dart
index b5936f4..07703a4 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_template.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/code_template.dart
@@ -65,8 +65,45 @@
/// The utilities used to help extract the code associated with various nodes.
final CorrectionUtils utils;
- /// Initialize a newly created variable support.
+ /// Initialize a newly created template context with the [node] and [utils].
TemplateContext(this.node, this.utils);
+
+ /// Initialize a newly created template context that uses the invocation
+ /// containing the [node] and the [utils].
+ factory TemplateContext.forInvocation(AstNode node, CorrectionUtils utils) =>
+ TemplateContext(_getInvocation(node), utils);
+
+ /// Return the invocation containing the given [node]. The invocation will be
+ /// either an instance creation expression, function invocation, method
+ /// invocation, or an extension override.
+ static AstNode _getInvocation(AstNode node) {
+ if (node is ArgumentList) {
+ return node.parent;
+ } else if (node is InstanceCreationExpression ||
+ node is InvocationExpression) {
+ return node;
+ } else if (node is SimpleIdentifier) {
+ var parent = node.parent;
+ if (parent is ConstructorName) {
+ var grandparent = parent.parent;
+ if (grandparent is InstanceCreationExpression) {
+ return grandparent;
+ }
+ } else if (parent is Label && parent.parent is NamedExpression) {
+ return parent.parent.parent.parent;
+ } else if (parent is MethodInvocation && parent.methodName == node) {
+ return parent;
+ }
+ } else if (node is TypeArgumentList) {
+ var parent = node.parent;
+ if (parent is InvocationExpression) {
+ return parent;
+ } else if (parent is ExtensionOverride) {
+ return parent;
+ }
+ }
+ return null;
+ }
}
/// Literal text within a template.
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/expression.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/expression.dart
index ef1e04c..96651b9 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/expression.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/expression.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:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/value_generator.dart';
/// A binary expression.
@@ -18,10 +19,35 @@
/// Initialize a newly created binary expression consisting of the
/// [leftOperand], [operator], and [rightOperand].
BinaryExpression(this.leftOperand, this.operator, this.rightOperand);
+
+ @override
+ Object evaluateIn(TemplateContext context) {
+ switch (operator) {
+ case Operator.and:
+ var left = leftOperand.evaluateIn(context);
+ var right = rightOperand.evaluateIn(context);
+ if (left is bool && right is bool) {
+ return left && right;
+ }
+ return null;
+ case Operator.equal:
+ var left = leftOperand.evaluateIn(context);
+ var right = rightOperand.evaluateIn(context);
+ return left == right;
+ case Operator.notEqual:
+ var left = leftOperand.evaluateIn(context);
+ var right = rightOperand.evaluateIn(context);
+ return left != right;
+ }
+ return null;
+ }
}
/// An expression.
-abstract class Expression {}
+abstract class Expression {
+ /// Return the result of evaluating this expression.
+ Object evaluateIn(TemplateContext context);
+}
/// A literal string.
class LiteralString extends Expression {
@@ -30,6 +56,11 @@
/// Initialize a newly created literal string to have the given [value].
LiteralString(this.value);
+
+ @override
+ String evaluateIn(TemplateContext context) {
+ return value;
+ }
}
/// An operator used in a binary expression.
@@ -47,4 +78,9 @@
/// Initialize a newly created variable reference to reference the variable
/// whose value is computed by the [generator].
VariableReference(this.generator);
+
+ @override
+ String evaluateIn(TemplateContext context) {
+ return generator.evaluateIn(context);
+ }
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
index 13b32f3..58eb217 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
@@ -66,6 +66,16 @@
SimpleIdentifier validate(DataDrivenFix fix) {
var node = fix.node;
if (node is SimpleIdentifier) {
+ var parent = node.parent;
+ if (parent is Label && parent.parent is NamedExpression) {
+ var invocation = parent.parent.parent.parent;
+ if (invocation is InstanceCreationExpression) {
+ invocation.constructorName.name;
+ } else if (invocation is MethodInvocation) {
+ return invocation.methodName;
+ }
+ return null;
+ }
return node;
} else if (node is ConstructorName) {
return node.name;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform.dart
index 2cda293..20d7ff4 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
import 'package:meta/meta.dart';
@@ -23,7 +23,7 @@
final ElementDescriptor element;
/// A list containing the changes to be applied to affect the transform.
- final List<Change> changes;
+ final ChangesSelector changesSelector;
/// Initialize a newly created transform to describe a transformation of the
/// [element].
@@ -32,7 +32,7 @@
this.date,
@required this.bulkApply,
@required this.element,
- @required this.changes});
+ @required this.changesSelector});
/// Return `true` if this transform can be applied to fix an issue related to
/// an element that matches the given [matcher]. The flag [applyingBulkFixes]
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 cb8540a..b0fb1de 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
@@ -4,10 +4,12 @@
import 'package:analysis_server/src/services/correction/fix/data_driven/add_type_parameter.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/code_fragment_parser.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/modify_parameters.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
@@ -53,6 +55,7 @@
static const String _fieldKey = 'field';
static const String _functionKey = 'function';
static const String _getterKey = 'getter';
+ static const String _ifKey = 'if';
static const String _inClassKey = 'inClass';
static const String _inEnumKey = 'inEnum';
static const String _inExtensionKey = 'inExtension';
@@ -64,6 +67,7 @@
static const String _nameKey = 'name';
static const String _newNameKey = 'newName';
static const String _oldNameKey = 'oldName';
+ static const String _oneOfKey = 'oneOf';
static const String _setterKey = 'setter';
static const String _statementsKey = 'statements';
static const String _styleKey = 'style';
@@ -474,6 +478,8 @@
CodeTemplateKind kind;
int templateOffset;
String template;
+ // TODO(brianwilkerson) Rework to use `_singleKey` to improve reporting
+ // (see _translateTransform for an example).
var expressionNode = node.valueAt(_expressionKey);
if (expressionNode != null) {
_reportUnsupportedKeys(node, const {_expressionKey, _variablesKey});
@@ -512,6 +518,47 @@
}
}
+ void _translateConditionalChange(YamlNode node, ErrorContext context,
+ Map<Expression, List<Change>> changeMap) {
+ if (node is YamlMap) {
+ _reportUnsupportedKeys(node, const {_ifKey, _changesKey});
+ var expressionNode = node.valueAt(_ifKey);
+ var expressionText = _translateString(
+ expressionNode, ErrorContext(key: _ifKey, parentNode: node));
+ var changes = _translateList(node.valueAt(_changesKey),
+ ErrorContext(key: _changesKey, parentNode: node), _translateChange);
+ if (_parameterModifications != null) {
+ if (changes != null) {
+ changes.add(ModifyParameters(modifications: _parameterModifications));
+ }
+ _parameterModifications = null;
+ }
+ if (expressionText != null && changes != null) {
+ var expression = CodeFragmentParser(errorReporter,
+ scope: transformVariableScope)
+ .parseCondition(expressionText, _offsetOfString(expressionNode));
+ if (expression != null) {
+ changeMap[expression] = changes;
+ }
+ }
+ } else {
+ return _reportInvalidValue(node, context, 'Map');
+ }
+ }
+
+ ChangesSelector _translateConditionalChanges(
+ YamlNode node, ErrorContext context) {
+ if (node is YamlList) {
+ var changeMap = <Expression, List<Change>>{};
+ for (var element in node.nodes) {
+ _translateConditionalChange(element, context, changeMap);
+ }
+ return ConditionalChangesSelector(changeMap);
+ } else {
+ return _reportInvalidValue(node, context, 'List');
+ }
+ }
+
/// Translate the [node] into a date. Return the resulting date, or `null`
/// if the [node] does not represent a valid date. If the [node] is not
/// valid, use the [context] to report the error.
@@ -810,6 +857,7 @@
_changesKey,
_dateKey,
_elementKey,
+ _oneOfKey,
_titleKey,
_variablesKey
});
@@ -826,23 +874,44 @@
transformVariableScope = _translateTemplateVariables(
node.valueAt(_variablesKey),
ErrorContext(key: _variablesKey, parentNode: node));
- var changes = _translateList(node.valueAt(_changesKey),
- ErrorContext(key: _changesKey, parentNode: node), _translateChange);
- transformVariableScope = VariableScope.empty;
- if (title == null || date == null || element == null || changes == null) {
+ ChangesSelector selector;
+ var key = _singleKey(
+ node, const [_changesKey, _oneOfKey], context.parentNode,
+ required: true);
+ if (key == _oneOfKey) {
+ selector = _translateConditionalChanges(node.valueAt(_oneOfKey),
+ ErrorContext(key: _oneOfKey, parentNode: node));
+ } else if (key == _changesKey) {
+ var changes = _translateList(node.valueAt(_changesKey),
+ ErrorContext(key: _changesKey, parentNode: node), _translateChange);
+ if (changes == null) {
+ // The error has already been reported.
+ _parameterModifications = null;
+ return null;
+ }
+ if (_parameterModifications != null) {
+ changes.add(ModifyParameters(modifications: _parameterModifications));
+ _parameterModifications = null;
+ }
+ selector = UnconditionalChangesSelector(changes);
+ } else {
// The error has already been reported.
return null;
}
- if (_parameterModifications != null) {
- changes.add(ModifyParameters(modifications: _parameterModifications));
- _parameterModifications = null;
+ transformVariableScope = VariableScope.empty;
+ if (title == null ||
+ date == null ||
+ element == null ||
+ selector == null) {
+ // The error has already been reported.
+ return null;
}
return Transform(
title: title,
date: date,
bulkApply: bulkApply,
element: element,
- changes: changes);
+ changesSelector: selector);
} else {
return _reportInvalidValue(node, context, 'Map');
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/value_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/value_generator.dart
index 659bb47..b59bac9 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/value_generator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/value_generator.dart
@@ -19,6 +19,23 @@
CodeFragment(this.accessors);
@override
+ String evaluateIn(TemplateContext context) {
+ Object target = context.node;
+ for (var accessor in accessors) {
+ target = accessor.getValue(target).result;
+ }
+ if (target is AstNode) {
+ return context.utils.getRangeText(range.node(target));
+ } else if (target is DartType) {
+ // TODO(brianwilkerson) If we end up needing it, figure out how to convert
+ // a type into valid code.
+ throw UnsupportedError('Unexpected result of ${target.runtimeType}');
+ } else {
+ throw UnsupportedError('Unexpected result of ${target.runtimeType}');
+ }
+ }
+
+ @override
bool validate(TemplateContext context) {
Object target = context.node;
for (var accessor in accessors) {
@@ -59,6 +76,11 @@
ImportedName(this.uris, this.name);
@override
+ String evaluateIn(TemplateContext context) {
+ return name;
+ }
+
+ @override
bool validate(TemplateContext context) {
// TODO(brianwilkerson) Validate that the import can be added.
return true;
@@ -72,6 +94,10 @@
/// An object used to generate the value of a template variable.
abstract class ValueGenerator {
+ /// Return the value generated by this generator, using the [context] to
+ /// access needed information that isn't already known to this generator.
+ String evaluateIn(TemplateContext context);
+
/// Use the [context] to validate that this generator will be able to generate
/// a value.
bool validate(TemplateContext context);
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 342dc7c..947a966 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -644,6 +644,48 @@
LIBRARY my_lib''');
}
+ Future<void> test_path_inExtension_named() async {
+ addTestFile('''
+class A {
+ void foo() {}
+}
+
+extension E on A {
+ void bar() {
+ foo();
+ }
+}
+''');
+ await findElementReferences('foo() {}', false);
+ assertHasResult(SearchResultKind.INVOCATION, 'foo();');
+ expect(getPathString(result.path), '''
+METHOD bar
+EXTENSION E
+COMPILATION_UNIT test.dart
+LIBRARY''');
+ }
+
+ Future<void> test_path_inExtension_unnamed() async {
+ addTestFile('''
+class A {
+ void foo() {}
+}
+
+extension on A {
+ void bar() {
+ foo();
+ }
+}
+''');
+ await findElementReferences('foo() {}', false);
+ assertHasResult(SearchResultKind.INVOCATION, 'foo();');
+ expect(getPathString(result.path), '''
+METHOD bar
+EXTENSION
+COMPILATION_UNIT test.dart
+LIBRARY''');
+ }
+
@failingTest
Future<void> test_path_inFunction() async {
// The path does not contain the first expected element.
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 6b81786..5ed784f 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
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/fix/data_driven/add_type_parameter.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/transform.dart';
@@ -484,12 +485,12 @@
kind: ElementKindUtilities.fromName(_kind),
components: components ?? ['C', 'm']),
bulkApply: false,
- changes: [
+ changesSelector: UnconditionalChangesSelector([
AddTypeParameter(
index: index,
name: 'T',
extendedType:
extendedType == null ? null : codeTemplate(extendedType),
argumentValue: codeTemplate('String')),
- ]);
+ ]));
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/expected_primary_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/expected_primary_test.dart
new file mode 100644
index 0000000..38c7e43
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/expected_primary_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../transform_set_parser_test_support.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExpectedPrimaryTest);
+ });
+}
+
+@reflectiveTest
+class ExpectedPrimaryTest extends AbstractTransformSetParserTest {
+ void test_integer() {
+ assertErrors('''
+version: 1
+transforms:
+ - title: 'Remove nullOk'
+ date: 2020-11-04
+ element:
+ uris: [ 'test.dart' ]
+ method: 'm'
+ inClass: 'C'
+ oneOf:
+ - if: "'x' =="
+ changes: []
+''', [
+ error(TransformSetErrorCode.expectedPrimary, 177, 2),
+ ]);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart
index 1237ba0..c4a2e75 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart
@@ -199,20 +199,6 @@
]);
}
- void test_transform_changes() {
- assertErrors('''
-version: 1
-transforms:
-- title: ''
- date: 2020-09-14
- element:
- uris: ['test.dart']
- function: 'f'
-''', [
- error(TransformSetErrorCode.missingKey, 25, 82),
- ]);
- }
-
void test_transform_date() {
assertErrors('''
version: 1
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_one_of_multiple_keys_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_one_of_multiple_keys_test.dart
index 255767b..c5bba1e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_one_of_multiple_keys_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_one_of_multiple_keys_test.dart
@@ -79,4 +79,18 @@
error(TransformSetErrorCode.missingOneOfMultipleKeys, 124, 22),
]);
}
+
+ void test_transform() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+''', [
+ error(TransformSetErrorCode.missingOneOfMultipleKeys, 0, 107),
+ ]);
+ }
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
index 651508b..64265e6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
@@ -5,6 +5,7 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'conflicting_key_test.dart' as conflicting_key;
+import 'expected_primary_test.dart' as expected_primary;
import 'invalid_character_test.dart' as invalid_character;
import 'invalid_key_test.dart' as invalid_key;
import 'invalid_parameter_style_test.dart' as invalid_parameter_style;
@@ -16,6 +17,7 @@
import 'missing_token_test.dart' as missing_token;
import 'missing_uri_test.dart' as missing_uri;
import 'undefined_variable_test.dart' as undefined_variable;
+import 'unexpected_token_test.dart' as unexpected_token;
import 'unknown_accessor_test.dart' as unknown_accessor;
import 'unsupported_key_test.dart' as unsupported_key;
import 'unsupported_version_test.dart' as unsupported_version;
@@ -25,6 +27,7 @@
void main() {
defineReflectiveSuite(() {
conflicting_key.main();
+ expected_primary.main();
invalid_character.main();
invalid_key.main();
invalid_parameter_style.main();
@@ -36,6 +39,7 @@
missing_token.main();
missing_uri.main();
undefined_variable.main();
+ unexpected_token.main();
unknown_accessor.main();
unsupported_key.main();
unsupported_version.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unexpected_token_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unexpected_token_test.dart
new file mode 100644
index 0000000..9f6213c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unexpected_token_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../transform_set_parser_test_support.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UnexpectedTokenTest);
+ });
+}
+
+@reflectiveTest
+class UnexpectedTokenTest extends AbstractTransformSetParserTest {
+ void test_integer() {
+ assertErrors('''
+version: 1
+transforms:
+ - title: 'Remove nullOk'
+ date: 2020-11-04
+ element:
+ uris: [ 'test.dart' ]
+ method: 'm'
+ inClass: 'C'
+ oneOf:
+ - if: "'x' == 'y' 'z'"
+ changes: []
+''', [
+ error(TransformSetErrorCode.unexpectedToken, 184, 3),
+ ]);
+ }
+}
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 2e53eb1..ee53183 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
@@ -599,6 +599,150 @@
''');
}
+ Future<void> test_material_Scaffold_of_matchFirstCase() async {
+ setPackageContent('''
+class Scaffold {
+ static ScaffoldState of(BuildContext context) => ScaffoldState();
+ static ScaffoldState maybeOf(BuildContext context) => ScaffoldState();
+}
+class ScaffoldState {}
+class BuildContext {}
+''');
+ addPackageDataFile('''
+version: 1
+transforms:
+ - title: 'Remove nullOk'
+ date: 2020-11-04
+ element:
+ uris: ['$importUri']
+ method: 'of'
+ inClass: 'Scaffold'
+ oneOf:
+ - if: "nullOk == 'true'"
+ changes:
+ - kind: 'rename'
+ newName: 'maybeOf'
+ - kind: 'removeParameter'
+ name: 'nullOk'
+ - if: "nullOk == 'false'"
+ changes:
+ - kind: 'removeParameter'
+ name: 'nullOk'
+ variables:
+ nullOk:
+ kind: 'fragment'
+ value: 'arguments[nullOk]'
+''');
+ await resolveTestCode('''
+import '$importUri';
+
+void f(BuildContext context, bool b) {
+ Scaffold.of(context, nullOk: true);
+}
+''');
+ await assertHasFix('''
+import '$importUri';
+
+void f(BuildContext context, bool b) {
+ Scaffold.maybeOf(context);
+}
+''');
+ }
+
+ Future<void> test_material_Scaffold_of_matchNoCases() async {
+ setPackageContent('''
+class Scaffold {
+ static ScaffoldState of(BuildContext context) => ScaffoldState();
+ static ScaffoldState maybeOf(BuildContext context) => ScaffoldState();
+}
+class ScaffoldState {}
+class BuildContext {}
+''');
+ addPackageDataFile('''
+version: 1
+transforms:
+ - title: 'Remove nullOk'
+ date: 2020-11-04
+ element:
+ uris: ['$importUri']
+ method: 'of'
+ inClass: 'Scaffold'
+ oneOf:
+ - if: "nullOk == 'true'"
+ changes:
+ - kind: 'rename'
+ newName: 'maybeOf'
+ - kind: 'removeParameter'
+ name: 'nullOk'
+ - if: "nullOk == 'false'"
+ changes:
+ - kind: 'removeParameter'
+ name: 'nullOk'
+ variables:
+ nullOk:
+ kind: 'fragment'
+ value: 'arguments[nullOk]'
+''');
+ await resolveTestCode('''
+import '$importUri';
+
+void f(BuildContext context, bool b) {
+ Scaffold.of(context, nullOk: b);
+}
+''');
+ await assertNoFix();
+ }
+
+ Future<void> test_material_Scaffold_of_matchSecondCase() async {
+ setPackageContent('''
+class Scaffold {
+ static ScaffoldState of(BuildContext context) => ScaffoldState();
+ static ScaffoldState maybeOf(BuildContext context) => ScaffoldState();
+}
+class ScaffoldState {}
+class BuildContext {}
+''');
+ addPackageDataFile('''
+version: 1
+transforms:
+ - title: 'Remove nullOk'
+ date: 2020-11-04
+ element:
+ uris: ['$importUri']
+ method: 'of'
+ inClass: 'Scaffold'
+ oneOf:
+ - if: "nullOk == 'true'"
+ changes:
+ - kind: 'rename'
+ newName: 'maybeOf'
+ - kind: 'removeParameter'
+ name: 'nullOk'
+ - if: "nullOk == 'false'"
+ changes:
+ - kind: 'removeParameter'
+ name: 'nullOk'
+ variables:
+ nullOk:
+ kind: 'fragment'
+ value: 'arguments[nullOk]'
+''');
+ await resolveTestCode('''
+import '$importUri';
+
+void f(BuildContext context, bool b) {
+ Scaffold.of(context, nullOk: false);
+}
+''');
+ await assertHasFix('''
+import '$importUri';
+
+void f(BuildContext context, bool b) {
+ Scaffold.of(context);
+}
+''');
+ }
+
Future<void>
test_material_Scaffold_resizeToAvoidBottomPadding_deprecated() async {
setPackageContent('''
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 028cda4..30f1bce 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
@@ -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:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/modify_parameters.dart';
@@ -946,8 +947,8 @@
kind: ElementKindUtilities.fromName(_kind),
components: originalComponents),
bulkApply: false,
- changes: [
+ changesSelector: UnconditionalChangesSelector([
ModifyParameters(modifications: modifications),
if (newName != null) Rename(newName: newName),
- ]);
+ ]));
}
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 eca3df1..f892cd6 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
@@ -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:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/rename_parameter.dart';
@@ -335,7 +336,7 @@
kind: ElementKindUtilities.fromName(_kind),
components: components),
bulkApply: false,
- changes: [
+ changesSelector: UnconditionalChangesSelector([
RenameParameter(newName: newName, oldName: oldName),
- ]);
+ ]));
}
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 2578b5b..2edc72d 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
@@ -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:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
@@ -1231,13 +1232,13 @@
String get _kind;
Transform _rename(List<String> components, String newName) => Transform(
- title: 'title',
- element: ElementDescriptor(
- libraryUris: [Uri.parse(importUri)],
- kind: ElementKindUtilities.fromName(_kind),
- components: components),
- bulkApply: false,
- changes: [
- Rename(newName: newName),
- ]);
+ title: 'title',
+ element: ElementDescriptor(
+ libraryUris: [Uri.parse(importUri)],
+ kind: ElementKindUtilities.fromName(_kind),
+ components: components),
+ bulkApply: false,
+ changesSelector: UnconditionalChangesSelector([
+ Rename(newName: newName),
+ ]));
}
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 b4c29ff..f0e84ad 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
@@ -4,8 +4,11 @@
import 'package:analysis_server/src/services/correction/fix/data_driven/accessor.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/add_type_parameter.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/modify_parameters.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
@@ -53,8 +56,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Add');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as ModifyParameters;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as ModifyParameters;
var modifications = change.modifications;
expect(modifications, hasLength(1));
var modification = modifications[0] as AddParameter;
@@ -88,8 +92,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Add');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as ModifyParameters;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as ModifyParameters;
var modifications = change.modifications;
expect(modifications, hasLength(1));
var modification = modifications[0] as AddParameter;
@@ -124,8 +129,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Add');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as ModifyParameters;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as ModifyParameters;
var modifications = change.modifications;
expect(modifications, hasLength(1));
var modification = modifications[0] as AddParameter;
@@ -165,8 +171,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Add');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as ModifyParameters;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as ModifyParameters;
var modifications = change.modifications;
expect(modifications, hasLength(1));
var modification = modifications[0] as AddParameter;
@@ -209,8 +216,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Add');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as ModifyParameters;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as ModifyParameters;
var modifications = change.modifications;
expect(modifications, hasLength(1));
var modification = modifications[0] as AddParameter;
@@ -256,8 +264,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Add');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as AddTypeParameter;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as AddTypeParameter;
expect(change.index, 0);
expect(change.name, 'T');
var components = change.argumentValue.components;
@@ -292,8 +301,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Add');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as AddTypeParameter;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as AddTypeParameter;
expect(change.index, 0);
expect(change.name, 'T');
expect(change.extendedType, null);
@@ -332,8 +342,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Add');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as AddTypeParameter;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as AddTypeParameter;
expect(change.index, 0);
expect(change.name, 'T');
@@ -375,8 +386,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Add');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as AddTypeParameter;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as AddTypeParameter;
expect(change.index, 0);
expect(change.name, 'T');
@@ -408,7 +420,7 @@
var transform = transforms[0];
expect(transform.title, 'Rename g');
expect(transform.bulkApply, false);
- expect(transform.changes, isEmpty);
+ expect(_changes(transform), isEmpty);
}
void test_correctOffsetForPlainStrings() {
@@ -453,7 +465,7 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Rename g');
- expect(transform.changes, isEmpty);
+ expect(_changes(transform), isEmpty);
}
void test_element_getter_inMixin() {
@@ -472,7 +484,7 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Rename g');
- expect(transform.changes, isEmpty);
+ expect(_changes(transform), isEmpty);
}
void test_element_getter_topLevel() {
@@ -490,7 +502,7 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Rename g');
- expect(transform.changes, isEmpty);
+ expect(_changes(transform), isEmpty);
}
void test_element_method_inClass() {
@@ -509,7 +521,7 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Rename m');
- expect(transform.changes, isEmpty);
+ expect(_changes(transform), isEmpty);
}
void test_element_variable() {
@@ -527,7 +539,7 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Rename v');
- expect(transform.changes, isEmpty);
+ expect(_changes(transform), isEmpty);
}
void test_incomplete() {
@@ -568,8 +580,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Remove');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as ModifyParameters;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as ModifyParameters;
var modifications = change.modifications;
expect(modifications, hasLength(1));
var modification = modifications[0] as RemoveParameter;
@@ -594,8 +607,9 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Remove');
- expect(transform.changes, hasLength(1));
- var change = transform.changes[0] as ModifyParameters;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var change = changes[0] as ModifyParameters;
var modifications = change.modifications;
expect(modifications, hasLength(1));
var modification = modifications[0] as RemoveParameter;
@@ -621,8 +635,42 @@
expect(transforms, hasLength(1));
var transform = transforms[0];
expect(transform.title, 'Rename A');
- expect(transform.changes, hasLength(1));
- var rename = transform.changes[0] as Rename;
+ var changes = _changes(transform);
+ expect(changes, hasLength(1));
+ var rename = changes[0] as Rename;
+ expect(rename.newName, 'B');
+ }
+
+ void test_rename_oneOf() {
+ parse('''
+version: 1
+transforms:
+- title: 'Rename A'
+ date: 2020-08-21
+ element:
+ uris:
+ - 'test.dart'
+ class: 'A'
+ oneOf:
+ - if: "'a' == 'b'"
+ changes:
+ - kind: 'rename'
+ newName: 'B'
+''');
+ var transforms = _transforms('A');
+ expect(transforms, hasLength(1));
+ var transform = transforms[0];
+ expect(transform.title, 'Rename A');
+ var selector = transform.changesSelector as ConditionalChangesSelector;
+ var changeMap = selector.changeMap;
+ expect(changeMap, hasLength(1));
+ var condition = changeMap.keys.first as BinaryExpression;
+ expect((condition.leftOperand as LiteralString).value, 'a');
+ expect(condition.operator, Operator.equal);
+ expect((condition.rightOperand as LiteralString).value, 'b');
+ var changes = changeMap[condition];
+ expect(changes, hasLength(1));
+ var rename = changes[0] as Rename;
expect(rename.newName, 'B');
}
@@ -630,6 +678,11 @@
Accessor _accessor(TemplateComponent component) =>
((component as TemplateVariable).generator as CodeFragment).accessors[0];
+ /// Assuming that the [transform] has a single list of changes associated with
+ /// it, return the list of changes.
+ List<Change> _changes(Transform transform) =>
+ (transform.changesSelector as UnconditionalChangesSelector).changes;
+
ElementMatcher _matcher(String name) =>
ElementMatcher(importedUris: uris, name: name);
diff --git a/pkg/analyzer/lib/src/context/packages.dart b/pkg/analyzer/lib/src/context/packages.dart
index 5ef1a56..087680f 100644
--- a/pkg/analyzer/lib/src/context/packages.dart
+++ b/pkg/analyzer/lib/src/context/packages.dart
@@ -6,8 +6,8 @@
import 'package:analyzer/src/context/package_config_json.dart';
import 'package:analyzer/src/util/uri.dart';
import 'package:meta/meta.dart';
-// ignore: deprecated_member_use
-import 'package:package_config/packages_file.dart' as dot_packages;
+import 'package:package_config/src/packages_file.dart'
+ as package_config_packages_file;
import 'package:pub_semver/pub_semver.dart';
/// Find [Packages] starting from the given [start] resource.
@@ -45,18 +45,24 @@
Packages parseDotPackagesFile(ResourceProvider provider, File file) {
var uri = file.toUri();
var content = file.readAsBytesSync();
- var uriMap = dot_packages.parse(content, uri);
+ // TODO(srawlins): Replacing these two imports with public imports currently
+ // requires a sweeping breaking change, from synchronous code to asynchronous,
+ // including in our public APIs. When synchronous public APIs become
+ // available, use those.
+ // See https://github.com/dart-lang/package_config/issues/95.
+ var packageConfig = package_config_packages_file.parse(
+ content, uri, (Object error) => throw error);
var map = <String, Package>{};
- for (var name in uriMap.keys) {
- var libUri = uriMap[name];
+ for (var package in packageConfig.packages) {
+ var libUri = package.packageUriRoot;
var libPath = fileUriToNormalizedPath(
provider.pathContext,
libUri,
);
var libFolder = provider.getFolder(libPath);
- map[name] = Package(
- name: name,
+ map[package.name] = Package(
+ name: package.name,
rootFolder: libFolder,
libFolder: libFolder,
languageVersion: null,
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 74cdd53..feb9a23 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2921,7 +2921,7 @@
@override
bool get isPrivate {
- String name = displayName;
+ var name = this.name;
if (name == null) {
return true;
}
@@ -3947,7 +3947,7 @@
}
@override
- String get displayName => name;
+ String get displayName => name ?? '';
@override
String get documentationComment {
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index f097d37..c34d83f 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -7,7 +7,7 @@
sdk: '>=2.7.0 <3.0.0'
dependencies:
- _fe_analyzer_shared: ^12.0.0
+ _fe_analyzer_shared: ^13.0.0
args: ^1.0.0
cli_util: '>=0.1.4 <0.3.0'
collection: ^1.10.1
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index a3cfc3c..f55891d 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -23,10 +23,10 @@
/// The return type separator: →
abstract class AbstractResynthesizeTest with ResourceProviderMixin {
DeclaredVariables declaredVariables = DeclaredVariables();
- SourceFactory sourceFactory;
- MockSdk sdk;
+ /*late final*/ SourceFactory sourceFactory;
+ /*late final*/ MockSdk sdk;
- String testFile;
+ /*late final*/ String testFile;
Source testSource;
Set<Source> otherLibrarySources = <Source>{};
@@ -12258,7 +12258,7 @@
/// Mixin containing helper methods for testing summary resynthesis. Intended
/// to be applied to a class implementing [ResynthesizeTestStrategy].
mixin ResynthesizeTestHelpers implements ResynthesizeTestStrategy {
- Future<LibraryElementImpl> checkLibrary(String text,
+ Future<LibraryElementImpl /*!*/ > checkLibrary(String text,
{bool allowErrors = false, bool dumpSummaries = false}) async {
throw 42;
// Source source = addTestSource(text);
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index e1a5601..b9bf27d 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -2688,7 +2688,7 @@
String path = convertPath('/test/lib/test.dart');
newFile(path, content: text);
UnitElementResult result = await driver.getUnitElement(path);
- return result.element.library;
+ return result.element.library /*!*/;
}
}
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 0269dd30..e9527d9 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -447,7 +447,6 @@
}
/// Returns the canonical name to refer to the Dart library.
- @protected
js_ast.Identifier emitLibraryName(Library library) {
// Avoid adding the dart:_runtime to _imports when our runtime unit tests
// import it explicitly. It will always be implicitly imported.
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 371f472..9571c2a 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -105,6 +105,14 @@
FunctionNode _currentFunction;
+ /// Whether the current function needs to insert parameter checks.
+ ///
+ /// Used to avoid adding checks for formal parameters inside a synthetic
+ /// function that is generated during expression compilation in the
+ /// incremental compiler, since those checks would already be done in
+ /// the original code.
+ bool _checkParameters = true;
+
/// Whether we are currently generating code for the body of a `JS()` call.
bool _isInForeignJS = false;
@@ -353,8 +361,9 @@
// Add assert locations
_uriMap.forEach((location, id) {
- moduleItems.insert(_constTableInsertionIndex,
- js.statement('var # = #;', [id, js.escapedString(location)]));
+ var value = location == null ? 'null' : js.escapedString(location);
+ moduleItems.insert(
+ _constTableInsertionIndex, js.statement('var # = #;', [id, value]));
});
moduleItems.addAll(afterClassDefItems);
@@ -2982,6 +2991,12 @@
_staticTypeContext.enterLibrary(_currentLibrary);
_currentClass = cls;
+ // Do not add formal parameter checks for the top-level synthetic function
+ // generated for expression evaluation, as those parameters are a set of
+ // variables from the current scope, and should alredy be checked in the
+ // original code.
+ _checkParameters = false;
+
// Emit function with additional information, such as types that are used
// in the expression. Note that typeTable can be null if this function is
// called from the expression compilation service, since we currently do
@@ -3341,13 +3356,16 @@
// The check on `p.type` is per:
// https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion
var condition = js.call('# == null', [jsParam]);
+ // Offsets are not available for compiler-generated variables
+ // Get the best available location even if the offset is missing.
+ // https://github.com/dart-lang/sdk/issues/34942
var location = p.location;
var check = js.statement(' if (#) #.nullFailed(#, #, #, #);', [
condition,
runtimeModule,
- _cacheUri(location.file.toString()),
- js.number(location.line),
- js.number(location.column),
+ _cacheUri(location?.file?.toString()),
+ js.number(location?.line ?? -1),
+ js.number(location?.column ?? -1),
js.escapedString('${p.name}'),
]);
body.add(check);
@@ -3356,7 +3374,9 @@
for (var p in f.positionalParameters) {
var jsParam = _emitVariableDef(p);
- initParameter(p, jsParam);
+ if (_checkParameters) {
+ initParameter(p, jsParam);
+ }
}
for (var p in f.namedParameters) {
// Parameters will be passed using their real names, not the (possibly
@@ -3383,8 +3403,18 @@
paramName,
]));
}
- initParameter(p, jsParam);
+ if (_checkParameters) {
+ initParameter(p, jsParam);
+ }
}
+
+ // '_checkParametes = false' is only needed once, while processing formal
+ // parameters of the synthetic function from expression evalaluation - it
+ // will be called from emitFunctionIncremental, which is a top-level API
+ // for expression compilation.
+ // Here we either are done with processing those formals, or compiling
+ // something else (in which case _checkParameters is already true).
+ _checkParameters = true;
return body;
}
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
index 9d8b566..92cca7c 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
@@ -12,6 +12,7 @@
import 'package:_fe_analyzer_shared/src/messages/codes.dart' show Message, Code;
import 'package:dev_compiler/dev_compiler.dart';
+import 'package:dev_compiler/src/compiler/js_names.dart' as js_ast;
import 'package:dev_compiler/src/js_ast/js_ast.dart' as js_ast;
import 'package:dev_compiler/src/kernel/compiler.dart';
@@ -253,8 +254,16 @@
}
}
+/// Collect private fields and libraries used in expression.
+///
+/// Used during expression evaluation to find symbols
+/// for private fields. The symbols are used in the ddc
+/// compilation of the expression, are not always avalable
+/// in the JavaScript scope, so we need to redefine them.
+///
+/// See [_addSymbolDefinitions]
class PrivateFieldsVisitor extends Visitor<void> {
- final Map<String, String> privateFields = {};
+ final Map<String, Library> privateFields = {};
@override
void defaultNode(Node node) {
@@ -263,33 +272,31 @@
@override
void visitFieldReference(Field node) {
- if (node.name.isPrivate) {
- var library = node.enclosingLibrary?.importUri;
- privateFields[node.name.text] = library?.toString();
+ if (node.name.isPrivate && !node.isStatic) {
+ privateFields[node.name.text] = node.enclosingLibrary;
}
}
@override
void visitField(Field node) {
- if (node.name.isPrivate) {
- var library = node.enclosingLibrary?.importUri;
- privateFields[node.name.text] = library?.toString();
+ if (node.name.isPrivate && !node.isStatic) {
+ privateFields[node.name.text] = node.enclosingLibrary;
}
}
@override
void visitPropertyGet(PropertyGet node) {
- if (node.name.isPrivate) {
- var library = node.interfaceTarget?.enclosingLibrary?.importUri;
- privateFields[node.name.text] = library?.toString();
+ var member = node.interfaceTarget;
+ if (node.name.isPrivate && member != null && member.isInstanceMember) {
+ privateFields[node.name.text] = node.interfaceTarget?.enclosingLibrary;
}
}
@override
void visitPropertySet(PropertySet node) {
- if (node.name.isPrivate) {
- var library = node.interfaceTarget?.enclosingLibrary?.importUri;
- privateFields[node.name.text] = library?.toString();
+ var member = node.interfaceTarget;
+ if (node.name.isPrivate && member != null && member.isInstanceMember) {
+ privateFields[node.name.text] = node.interfaceTarget?.enclosingLibrary;
}
}
}
@@ -329,31 +336,18 @@
/// Values listed in [jsFrameValues] are substituted for their names in the
/// [expression].
///
- /// Ensures that all [jsModules] are loaded and accessible inside the
- /// expression.
- ///
/// Returns expression compiled to JavaScript or null on error.
- /// Errors are reported using onDiagnostic function
- /// [moduleName] is of the form 'packages/hello_world_main.dart'
+ /// Errors are reported using onDiagnostic function.
+ ///
/// [jsFrameValues] is a map from js variable name to its primitive value
/// or another variable name, for example
/// { 'x': '1', 'y': 'y', 'o': 'null' }
- /// [jsModules] is a map from variable name to the module name, where
- /// variable name is the name originally used in JavaScript to contain the
- /// module object, for example:
- /// { 'dart':'dart_sdk', 'main': 'packages/hello_world_main.dart' }
- Future<String> compileExpressionToJs(
- String libraryUri,
- int line,
- int column,
- Map<String, String> jsModules,
- Map<String, String> jsScope,
- String moduleName,
- String expression) async {
+ Future<String> compileExpressionToJs(String libraryUri, int line, int column,
+ Map<String, String> jsScope, String expression) async {
try {
// 1. find dart scope where debugger is paused
- _log('Compiling expression in $moduleName:\n$expression');
+ _log('Compiling expression \n$expression');
var dartScope = await _findScopeAt(Uri.parse(libraryUri), line, column);
if (dartScope == null) {
@@ -382,11 +376,10 @@
// 3. compile dart expression to JS
- var jsExpression = await _compileExpression(
- dartScope, jsModules, moduleName, expression);
+ var jsExpression = await _compileExpression(dartScope, expression);
if (jsExpression == null) {
- _log('Failed to compile expression in $moduleName:\n$expression');
+ _log('Failed to compile expression: \n$expression');
return null;
}
@@ -472,19 +465,9 @@
/// Return a JS function that returns the evaluated results when called.
///
- /// [scope] current dart scope information
- /// [modules] map from module variable names to module names in JavaScript
- /// code. For example,
- /// { 'dart':'dart_sdk', 'main': 'packages/hello_world_main.dart' }
- /// [currentModule] current js module name.
- /// For example, in library package:hello_world/main.dart:
- /// 'packages/hello_world/main.dart'
+ /// [scope] current dart scope information.
/// [expression] expression to compile in given [scope].
- Future<String> _compileExpression(
- DartScope scope,
- Map<String, String> modules,
- String currentModule,
- String expression) async {
+ Future<String> _compileExpression(DartScope scope, String expression) async {
var procedure = await _compiler.compileExpression(
expression,
scope.definitions,
@@ -513,7 +496,7 @@
_log('Generated JavaScript for expression');
- var jsFunModified = _addSymbolDefinitions(procedure, jsFun, scope, modules);
+ var jsFunModified = _addSymbolDefinitions(procedure, jsFun, scope);
_log('Added symbol definitions to JavaScript');
@@ -531,85 +514,48 @@
/// Add symbol definitions for all symbols in compiled expression
///
+ /// Example:
+ ///
+ /// compilation of this._field from library 'main'
+ ///
+ /// Symbol definition:
+ ///
+ /// let _f = dart.privateName(main, "_f");
+ ///
+ /// Expression generated by ddc:
+ ///
+ /// this[_f]
+ ///
/// TODO: this is a temporary workaround to make JavaScript produced
/// by the ProgramCompiler self-contained.
/// Issue: https://github.com/dart-lang/sdk/issues/41480
- js_ast.Fun _addSymbolDefinitions(Procedure procedure, js_ast.Fun jsFun,
- DartScope scope, Map<String, String> modules) {
+ js_ast.Fun _addSymbolDefinitions(
+ Procedure procedure, js_ast.Fun jsFun, DartScope scope) {
// get private fields accessed by the evaluated expression
var fieldsCollector = PrivateFieldsVisitor();
procedure.accept(fieldsCollector);
var privateFields = fieldsCollector.privateFields;
- // collect libraries where private fields are defined
- var currentLibraries = <String, String>{};
- var currentModules = <String, String>{};
- for (var variable in modules.keys) {
- var module = modules[variable];
- for (var field in privateFields.keys) {
- var library = privateFields[field];
- if (library != null) {
- var libraryVariable =
- library.replaceAll('.dart', '').replaceAll('/', '__');
- if (libraryVariable.endsWith(variable)) {
- if (currentLibraries[field] != null) {
- onDiagnostic(_createInternalError(
- scope.library.importUri,
- 0,
- 0,
- 'ExpressionCompiler: $field defined in more than one library: '
- '${currentLibraries[field]}, $variable'));
- return null;
- }
- currentLibraries[field] = variable;
- currentModules[variable] = module;
- }
- }
- }
- }
+ // collect library names where private symbols are defined
+ var libraryForField = privateFields.map((field, library) =>
+ MapEntry(field, _kernel2jsCompiler.emitLibraryName(library).name));
var body = js_ast.Block([
- // require modules used in evaluated expression
- ...currentModules.keys.map((String variable) =>
- _createRequireModuleStatement(
- currentModules[variable], variable, variable)),
// re-create private field accessors
- ...currentLibraries.keys
- .map((String k) => _createPrivateField(k, currentLibraries[k])),
+ ...libraryForField.keys.map(
+ (String field) => _createPrivateField(field, libraryForField[field])),
// statements generated by the FE
...jsFun.body.statements
]);
-
return js_ast.Fun(jsFun.params, body);
}
- /// Creates a library symbol definition
- ///
- /// example:
- /// let dart = require('dart_sdk').dart;
- js_ast.Statement _createRequireModuleStatement(
- String moduleName, String moduleVariable, String fieldName) {
- var variableName = moduleVariable.replaceFirst('.dart', '');
- var rhs = js_ast.PropertyAccess.field(
- js_ast.Call(js_ast.Identifier('require'),
- [js_ast.LiteralExpression('\'$moduleName\'')]),
- '$fieldName');
-
- return rhs.toVariableDeclaration(js_ast.Identifier('$variableName'));
- }
-
/// Creates a private symbol definition
///
/// example:
/// let _f = dart.privateName(main, "_f");
js_ast.Statement _createPrivateField(String field, String library) {
- var libraryName = library.replaceFirst('.dart', '');
- var rhs = js_ast.Call(
- js_ast.PropertyAccess.field(js_ast.Identifier('dart'), 'privateName'), [
- js_ast.LiteralExpression(libraryName),
- js_ast.LiteralExpression('"$field"')
- ]);
-
- return rhs.toVariableDeclaration(js_ast.Identifier('$field'));
+ return js_ast.js.statement('let # = dart.privateName(#, #)',
+ [field, library, js_ast.js.string(field)]);
}
}
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
index 9e77102..fbd7ba6 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
@@ -108,8 +108,13 @@
final CompilerOptions _compilerOptions;
final Component _sdkComponent;
- ExpressionCompilerWorker._(this._processedOptions, this._compilerOptions,
- this._sdkComponent, this.requestStream, this.sendResponse);
+ ExpressionCompilerWorker._(
+ this._processedOptions,
+ this._compilerOptions,
+ this._sdkComponent,
+ this.requestStream,
+ this.sendResponse,
+ );
static Future<ExpressionCompilerWorker> createFromArgs(
List<String> args, {
@@ -243,8 +248,6 @@
/// Handles a `CompileExpression` request.
Future<Map<String, dynamic>> _compileExpression(
CompileExpressionRequest request) async {
- _processedOptions.ticker.logMs('Compiling expression to JavaScript');
-
var libraryUri = Uri.parse(request.libraryUri);
if (libraryUri.scheme == 'dart') {
// compiling expressions inside the SDK currently fails because
@@ -259,7 +262,8 @@
throw ArgumentError(
'Unable to find library `$libraryUri`, it must be loaded first.');
}
-
+ _processedOptions.ticker.logMs(
+ 'Compiling expression to JavaScript in module ${request.moduleName}');
var component = _sdkComponent;
if (libraryUri.scheme != 'dart') {
@@ -297,7 +301,13 @@
finalComponent,
incrementalCompiler.getClassHierarchy(),
SharedCompilerOptions(
- sourceMap: true, summarizeApi: false, moduleName: request.moduleName),
+ sourceMap: true,
+ summarizeApi: false,
+ moduleName: request.moduleName,
+ // Disable asserts due to failures to load source and
+ // locations on kernel loaded from dill files in DDC.
+ // https://github.com/dart-lang/sdk/issues/43986
+ enableAsserts: false),
_componentForLibrary,
_componentModuleNames,
coreTypes: incrementalCompiler.getCoreTypes(),
@@ -318,9 +328,7 @@
request.libraryUri,
request.line,
request.column,
- request.jsModules,
request.jsScope,
- request.moduleName,
request.expression);
_processedOptions.ticker.logMs('Compiled expression to JavaScript');
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
index ff0b230..48eb3ed 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
@@ -8,12 +8,13 @@
import 'package:cli_util/cli_util.dart';
import 'package:dev_compiler/dev_compiler.dart';
+import 'package:dev_compiler/src/compiler/module_builder.dart';
import 'package:front_end/src/api_unstable/ddc.dart';
import 'package:front_end/src/api_prototype/compiler_options.dart'
show CompilerOptions;
import 'package:front_end/src/compute_platform_binaries_location.dart';
import 'package:front_end/src/fasta/incremental_serializer.dart';
-import 'package:kernel/ast.dart' show Component;
+import 'package:kernel/ast.dart' show Component, Library;
import 'package:kernel/target/targets.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
@@ -97,7 +98,7 @@
final Uri importUri;
Module(this.importUri, this.fileUri)
- : name = importUri.pathSegments.last.replaceAll('.dart', ''),
+ : name = libraryUriToJsIdentifier(importUri),
path = importUri.scheme == 'package'
? 'packages/${importUri.path}'
: importUri.path;
@@ -124,20 +125,31 @@
Future<TestCompilationResult> compile(
{Uri input,
+ Uri packages,
int line,
int column,
Map<String, String> scope,
String expression}) async {
// initialize incremental compiler and create component
+ setup.options.packagesFileUri = packages;
var compiler = DevelopmentIncrementalCompiler(setup.options, input);
var component = await compiler.computeDelta();
+ component.computeCanonicalNames();
// initialize ddc
var classHierarchy = compiler.getClassHierarchy();
var compilerOptions = SharedCompilerOptions(replCompile: true);
var coreTypes = compiler.getCoreTypes();
- var kernel2jsCompiler = ProgramCompiler(
- component, classHierarchy, compilerOptions, const {}, const {},
+
+ final importToSummary = Map<Library, Component>.identity();
+ final summaryToModule = Map<Component, String>.identity();
+ for (var lib in component.libraries) {
+ importToSummary[lib] = component;
+ }
+ summaryToModule[component] = 'foo.dart';
+
+ var kernel2jsCompiler = ProgramCompiler(component, classHierarchy,
+ compilerOptions, importToSummary, summaryToModule,
coreTypes: coreTypes);
kernel2jsCompiler.emitModule(component);
@@ -152,19 +164,13 @@
// collect all module names and paths
var moduleInfo = _collectModules(component);
-
- var modules =
- moduleInfo.map((k, v) => MapEntry<String, String>(v.name, v.path));
- modules['dart'] = 'dart_sdk';
- modules['core'] = 'dart_sdk';
-
var module = moduleInfo[input];
setup.errors.clear();
// compile
var jsExpression = await evaluator.compileExpressionToJs(
- module.package, line, column, modules, scope, module.name, expression);
+ module.package, line, column, scope, expression);
if (setup.errors.isNotEmpty) {
jsExpression = setup.errors.toString().replaceAll(
@@ -193,6 +199,7 @@
Directory tempDir;
final String source;
Uri input;
+ Uri packages;
File file;
int line;
@@ -204,6 +211,21 @@
input = tempDir.uri.resolve('foo.dart');
file = File.fromUri(input)..createSync();
file.writeAsStringSync(source);
+
+ packages = tempDir.uri.resolve('package_config.json');
+ file = File.fromUri(packages)..createSync();
+ file.writeAsStringSync('''
+ {
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "./",
+ "packageUri": "./"
+ }
+ ]
+ }
+ ''');
}
void delete() {
@@ -217,6 +239,7 @@
String expectedResult}) async {
var result = await TestCompiler(options).compile(
input: input,
+ packages: packages,
line: line,
column: 1,
scope: scope,
@@ -233,7 +256,9 @@
}
String _normalize(String text) {
- return text.replaceAll(RegExp('\'.*foo.dart\''), '\'foo.dart\'');
+ return text
+ .replaceAll(RegExp('\'.*foo.dart\''), '\'foo.dart\'')
+ .replaceAll(RegExp('\".*foo.dart\"'), '\'foo.dart\'');
}
Matcher _matches(String text) {
@@ -541,8 +566,6 @@
expression: 'x + _staticField',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
- let _staticField = dart.privateName(foo, "_staticField");
return dart.notNull(x) + dart.notNull(foo.C._staticField);
}.bind(this)(
1
@@ -569,7 +592,6 @@
expression: 'x + _field',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
let _field = dart.privateName(foo, "_field");
return dart.notNull(x) + dart.notNull(this[_field]);
}.bind(this)(
@@ -636,7 +658,6 @@
expression: '_field = 2',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
let _field = dart.privateName(foo, "_field");
return this[_field] = 2;
}.bind(this)(
@@ -664,8 +685,6 @@
expression: '_staticField = 2',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
- let _staticField = dart.privateName(foo, "_staticField");
return foo.C._staticField = 2;
}.bind(this)(
1
@@ -755,8 +774,6 @@
expression: 'x + _staticField',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
- let _staticField = dart.privateName(foo, "_staticField");
return dart.notNull(x) + dart.notNull(foo.C._staticField);
}.bind(this)(
1
@@ -783,7 +800,6 @@
expression: 'x + _field',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
let _field = dart.privateName(foo, "_field");
return dart.notNull(x) + dart.notNull(this[_field]);
}.bind(this)(
@@ -798,7 +814,6 @@
expression: '_field = 2',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
let _field = dart.privateName(foo, "_field");
return this[_field] = 2;
}.bind(this)(
@@ -826,8 +841,6 @@
expression: '_staticField = 2',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
- let _staticField = dart.privateName(foo, "_staticField");
return foo.C._staticField = 2;
}.bind(this)(
1
@@ -1014,7 +1027,6 @@
expression: 'C(1,3)._field',
expectedResult: '''
(function(x, c) {
- let foo = require('foo.dart').foo;
let _field = dart.privateName(foo, "_field");
return new foo.C.new(1, 3)[_field];
}(
@@ -1065,7 +1077,6 @@
expression: 'c._field',
expectedResult: '''
(function(x, c) {
- let foo = require('foo.dart').foo;
let _field = dart.privateName(foo, "_field");
return c[_field];
}(
@@ -1123,7 +1134,6 @@
expression: 'c._field = 2',
expectedResult: '''
(function(x, c) {
- let foo = require('foo.dart').foo;
let _field = dart.privateName(foo, "_field");
return c[_field] = 2;
}(
@@ -1512,8 +1522,6 @@
expression: 'x + _staticField',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
- let _staticField = dart.privateName(foo, "_staticField");
return dart.notNull(x) + dart.notNull(foo.C._staticField);
}.bind(this)(
1
@@ -1540,7 +1548,6 @@
expression: 'x + _field',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
let _field = dart.privateName(foo, "_field");
return dart.notNull(x) + dart.notNull(this[_field]);
}.bind(this)(
@@ -1607,7 +1614,6 @@
expression: '_field = 2',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
let _field = dart.privateName(foo, "_field");
return this[_field] = 2;
}.bind(this)(
@@ -1635,8 +1641,6 @@
expression: '_staticField = 2',
expectedResult: '''
(function(x) {
- let foo = require('foo.dart').foo;
- let _staticField = dart.privateName(foo, "_staticField");
return foo.C._staticField = 2;
}.bind(this)(
1
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart
index 1735621..68357f8 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart
@@ -393,158 +393,6 @@
]));
});
});
-
- group('Expression compiler worker (google3 simulation) - ', () {
- ExpressionCompilerWorker worker;
- Future workerDone;
- StreamController<Map<String, dynamic>> requestController;
- StreamController<Map<String, dynamic>> responseController;
- Directory tempDir;
- TestProjectConfiguration config;
- List inputs;
-
- setUpAll(() async {
- tempDir = Directory.systemTemp.createTempSync('foo bar');
- config = TestProjectConfiguration(tempDir);
-
- // simulate google3
- config.createTestProject();
- var kernelGenerator = BazelKernelWorkerGenerator(config);
- await kernelGenerator.generate();
-
- inputs = [
- {
- 'path': config.mainModule.fullDillPath.path,
- 'moduleName': config.mainModule.moduleName
- },
- ];
- });
-
- tearDownAll(() async {
- tempDir.deleteSync(recursive: true);
- });
-
- setUp(() async {
- var fileSystem = MultiRootFileSystem(
- 'org-dartlang-app', [tempDir.uri], StandardFileSystem.instance);
-
- requestController = StreamController<Map<String, dynamic>>();
- responseController = StreamController<Map<String, dynamic>>();
- worker = await ExpressionCompilerWorker.create(
- librariesSpecificationUri: config.librariesPath,
- packagesFile: null,
- sdkSummary: config.sdkSummaryPath,
- fileSystem: fileSystem,
- requestStream: requestController.stream,
- sendResponse: responseController.add,
- verbose: verbose,
- );
- workerDone = worker.start();
- });
-
- tearDown(() async {
- unawaited(requestController.close());
- await workerDone;
- unawaited(responseController.close());
- });
-
- test('can load dependencies and compile expressions in sdk', () async {
- requestController.add({
- 'command': 'UpdateDeps',
- 'inputs': inputs,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'other',
- 'line': 107,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {'other': 'other'},
- 'libraryUri': 'dart:collection',
- 'moduleName': 'dart_sdk',
- });
-
- expect(
- responseController.stream,
- emitsInOrder([
- equals({
- 'succeeded': true,
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'compiledProcedure': contains('return other;'),
- })
- ]));
- }, skip: 'Evaluating expressions in SDK is not supported yet');
-
- test('can load dependencies and compile expressions in a library',
- () async {
- requestController.add({
- 'command': 'UpdateDeps',
- 'inputs': inputs,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'formal',
- 'line': 5,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {'formal': 'formal'},
- 'libraryUri': config.testModule.libraryUri,
- 'moduleName': config.mainModule.moduleName,
- });
-
- expect(
- responseController.stream,
- emitsInOrder([
- equals({
- 'succeeded': true,
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'compiledProcedure': contains('return formal;'),
- })
- ]));
- });
-
- test('can load dependencies and compile expressions in main', () async {
- requestController.add({
- 'command': 'UpdateDeps',
- 'inputs': inputs,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'count',
- 'line': 8,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {'count': 'count'},
- 'libraryUri': config.mainModule.libraryUri,
- 'moduleName': config.mainModule.moduleName,
- });
-
- expect(
- responseController.stream,
- emitsInOrder([
- equals({
- 'succeeded': true,
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'compiledProcedure': contains('return count;'),
- })
- ]));
- });
- }, skip: 'bazel kernel worker does not support full kernel generation yet');
}
/// Uses DDC to generate kernel from the test code
@@ -641,47 +489,6 @@
}
}
-/// Uses bazel kernel worker to generate kernel from test code
-/// in order to simulate google3 environment
-/// TODO: split into 3 modules
-class BazelKernelWorkerGenerator {
- TestProjectConfiguration config;
-
- BazelKernelWorkerGenerator(this.config);
-
- Future<void> generate() async {
- var dart = Platform.resolvedExecutable;
- var kernelWorker =
- p.join(p.dirname(dart), 'snapshots', 'kernel_worker.dart.snapshot');
-
- var args = [
- kernelWorker,
- '--target',
- 'ddc',
- '--output',
- config.mainModule.fullDillPath.path,
- '--dart-sdk-summary',
- config.sdkSummaryPath.path,
- '--exclude-non-sources',
- '--source',
- config.mainModule.libraryUri,
- '--source',
- config.testModule.libraryUri,
- '--source',
- config.testModule2.libraryUri,
- '--multi-root',
- '${config.root}',
- '--multi-root-scheme',
- 'org-dartlang-app',
- '--packages-file',
- '.packages',
- '--verbose'
- ];
-
- return await runProcess(dart, args, config.rootPath);
- }
-}
-
Future<int> runProcess(
String command, List<String> args, String workingDirectory) async {
if (verbose) {
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 658e1d0..e132a2d 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -944,7 +944,8 @@
{bool isCovariant}) {
assert(isCovariant != null);
VariableDeclaration parameter = new VariableDeclaration(null)
- ..isCovariant = isCovariant;
+ ..isCovariant = isCovariant
+ ..fileOffset = fileOffset;
return new Procedure(
null,
ProcedureKind.Setter,
@@ -1537,7 +1538,8 @@
if (!isFinal) {
VariableDeclaration parameter =
new VariableDeclaration("#externalFieldValue")
- ..isCovariant = isCovariant;
+ ..isCovariant = isCovariant
+ ..fileOffset = charOffset;
_setter = new Procedure(
null,
ProcedureKind.Setter,
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 906d131..a354e88 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -1792,6 +1792,7 @@
templateIncrementalCompilerIllegalParameter.withArguments(name),
// TODO: pass variable declarations instead of
// parameter names for proper location detection.
+ // https://github.com/dart-lang/sdk/issues/44158
-1,
-1,
libraryUri);
@@ -1849,11 +1850,16 @@
MemoryFileSystem fs = hfs.memory;
fs.entityForUri(debugExprUri).writeAsStringSync(expression);
+ // TODO: pass variable declarations instead of
+ // parameter names for proper location detection.
+ // https://github.com/dart-lang/sdk/issues/44158
FunctionNode parameters = new FunctionNode(null,
typeParameters: typeDefinitions,
positionalParameters: definitions.keys
.map((name) =>
- new VariableDeclarationImpl(name, 0, type: definitions[name]))
+ new VariableDeclarationImpl(name, 0, type: definitions[name])
+ ..fileOffset =
+ cls?.fileOffset ?? libraryBuilder.library.fileOffset)
.toList());
debugLibrary.build(userCode.loader.coreLibrary, modifyTarget: false);
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 4d9b5ae..4867d3e 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -824,7 +824,8 @@
final String boundaryKey = Uuid().generateV4();
_outputStream.writeln('result $boundaryKey');
- _processedOptions.ticker.logMs('Compiling expression to JavaScript');
+ _processedOptions.ticker
+ .logMs('Compiling expression to JavaScript in $moduleName');
var kernel2jsCompiler = _bundler.compilers[moduleName];
Component component = _generator.lastKnownGoodComponent;
@@ -832,7 +833,7 @@
_processedOptions.ticker.logMs('Computed component');
- var evaluator = new ExpressionCompiler(
+ var expressionCompiler = new ExpressionCompiler(
_compilerOptions,
errors,
_generator.generator,
@@ -840,8 +841,8 @@
component,
);
- var procedure = await evaluator.compileExpressionToJs(libraryUri, line,
- column, jsModules, jsFrameValues, moduleName, expression);
+ var procedure = await expressionCompiler.compileExpressionToJs(
+ libraryUri, line, column, jsFrameValues, expression);
var result = errors.length > 0 ? errors[0] : procedure;
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 4e0f338..50283d3 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -294,9 +294,6 @@
}
*len = static_cast<intptr_t>(file_len);
*data = reinterpret_cast<uint8_t*>(malloc(*len));
- if (*data == NULL) {
- OUT_OF_MEMORY();
- }
if (!file_stream->ReadFully(*data, *len)) {
free(*data);
*data = NULL;
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 755ef82..f0aa87a 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -312,9 +312,6 @@
}
*p_bytes = reinterpret_cast<uint8_t*>(malloc(size));
- if (*p_bytes == nullptr) {
- OUT_OF_MEMORY();
- }
uint8_t* p = *p_bytes;
KernelIRNode* node = head;
while (node != nullptr) {
diff --git a/runtime/bin/gzip.cc b/runtime/bin/gzip.cc
index 5494537..c80396c 100644
--- a/runtime/bin/gzip.cc
+++ b/runtime/bin/gzip.cc
@@ -4,6 +4,7 @@
#include "bin/gzip.h"
+#include "platform/allocation.h"
#include "platform/assert.h"
#include "platform/globals.h"
#include "zlib/zlib.h"
diff --git a/runtime/bin/utils_win.h b/runtime/bin/utils_win.h
index 0e4fae9..3d4cfe3 100644
--- a/runtime/bin/utils_win.h
+++ b/runtime/bin/utils_win.h
@@ -9,6 +9,8 @@
#include "platform/utils.h"
+#include "platform/allocation.h"
+
#define MAX_LONG_PATH 32767
namespace dart {
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 247adc3..d16d3d6 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -720,7 +720,7 @@
}
}
- uint8_t* data = reinterpret_cast<uint8_t*>(malloc(total_bytes));
+ uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(total_bytes));
if (data == nullptr) {
const Instance& exception =
Instance::Handle(thread->isolate()->object_store()->out_of_memory());
diff --git a/runtime/platform/allocation.cc b/runtime/platform/allocation.cc
new file mode 100644
index 0000000..6f8ae01
--- /dev/null
+++ b/runtime/platform/allocation.cc
@@ -0,0 +1,27 @@
+// 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.
+
+#include "platform/allocation.h"
+
+#include "platform/assert.h"
+
+namespace dart {
+
+void* malloc(size_t size) {
+ void* result = ::malloc(size);
+ if (result == nullptr) {
+ OUT_OF_MEMORY();
+ }
+ return result;
+}
+
+void* realloc(void* ptr, size_t size) {
+ void* result = ::realloc(ptr, size);
+ if (result == nullptr) {
+ OUT_OF_MEMORY();
+ }
+ return result;
+}
+
+} // namespace dart
diff --git a/runtime/platform/allocation.h b/runtime/platform/allocation.h
index e2d7ded..4458f55 100644
--- a/runtime/platform/allocation.h
+++ b/runtime/platform/allocation.h
@@ -62,6 +62,9 @@
#endif
};
+void* malloc(size_t size);
+void* realloc(void* ptr, size_t size);
+
} // namespace dart
#endif // RUNTIME_PLATFORM_ALLOCATION_H_
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 1796c33..ab51780 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -374,12 +374,6 @@
#error Unknown architecture.
#endif
-#if defined(ARCH_IS_32_BIT) || defined(IS_SIMARM_X64)
-#define TARGET_ARCH_IS_32_BIT 1
-#elif defined(ARCH_IS_64_BIT)
-#define TARGET_ARCH_IS_64_BIT 1
-#endif
-
#if !defined(TARGET_OS_ANDROID) && !defined(TARGET_OS_FUCHSIA) && \
!defined(TARGET_OS_MACOS_IOS) && !defined(TARGET_OS_LINUX) && \
!defined(TARGET_OS_MACOS) && !defined(TARGET_OS_WINDOWS)
diff --git a/runtime/platform/growable_array.h b/runtime/platform/growable_array.h
index 20d5f1f..9c906f6 100644
--- a/runtime/platform/growable_array.h
+++ b/runtime/platform/growable_array.h
@@ -240,12 +240,12 @@
public:
template <class T>
static inline T* Alloc(intptr_t len) {
- return reinterpret_cast<T*>(malloc(len * sizeof(T)));
+ return reinterpret_cast<T*>(dart::malloc(len * sizeof(T)));
}
template <class T>
static inline T* Realloc(T* old_array, intptr_t old_len, intptr_t new_len) {
- return reinterpret_cast<T*>(realloc(old_array, new_len * sizeof(T)));
+ return reinterpret_cast<T*>(dart::realloc(old_array, new_len * sizeof(T)));
}
template <class T>
diff --git a/runtime/platform/platform_sources.gni b/runtime/platform/platform_sources.gni
index 02f23fb..bef56fe 100644
--- a/runtime/platform/platform_sources.gni
+++ b/runtime/platform/platform_sources.gni
@@ -6,6 +6,7 @@
# components.
platform_sources = [
"address_sanitizer.h",
+ "allocation.cc",
"allocation.h",
"assert.cc",
"assert.h",
diff --git a/runtime/platform/text_buffer.cc b/runtime/platform/text_buffer.cc
index 5d08892..104fe76 100644
--- a/runtime/platform/text_buffer.cc
+++ b/runtime/platform/text_buffer.cc
@@ -114,9 +114,6 @@
TextBuffer::TextBuffer(intptr_t buf_size) {
ASSERT(buf_size > 0);
buffer_ = reinterpret_cast<char*>(malloc(buf_size));
- if (buffer_ == nullptr) {
- OUT_OF_MEMORY();
- }
capacity_ = buf_size;
Clear();
}
@@ -139,9 +136,6 @@
if (remaining <= len) {
intptr_t new_size = capacity_ + Utils::Maximum(capacity_, len + 1);
char* new_buf = reinterpret_cast<char*>(realloc(buffer_, new_size));
- if (new_buf == nullptr) {
- OUT_OF_MEMORY();
- }
buffer_ = new_buf;
capacity_ = new_size;
}
diff --git a/runtime/platform/utils.cc b/runtime/platform/utils.cc
index 6314265..dc10160 100644
--- a/runtime/platform/utils.cc
+++ b/runtime/platform/utils.cc
@@ -4,6 +4,8 @@
#include "platform/utils.h"
+#include "platform/allocation.h"
+
namespace dart {
// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
diff --git a/runtime/platform/utils_macos.cc b/runtime/platform/utils_macos.cc
index f0ccf53f..a801746 100644
--- a/runtime/platform/utils_macos.cc
+++ b/runtime/platform/utils_macos.cc
@@ -25,9 +25,6 @@
len = n;
}
char* result = reinterpret_cast<char*>(malloc(len + 1));
- if (result == NULL) {
- return NULL;
- }
result[len] = '\0';
return reinterpret_cast<char*>(memmove(result, s, len));
#else // !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || ...
diff --git a/runtime/platform/utils_win.cc b/runtime/platform/utils_win.cc
index 6cfe4e0..7ba2ec8 100644
--- a/runtime/platform/utils_win.cc
+++ b/runtime/platform/utils_win.cc
@@ -6,6 +6,7 @@
#if defined(HOST_OS_WINDOWS)
#include <io.h> // NOLINT
+#include "platform/allocation.h"
#include "platform/utils.h"
namespace dart {
@@ -19,9 +20,6 @@
len = n;
}
char* result = reinterpret_cast<char*>(malloc(len + 1));
- if (result == NULL) {
- return NULL;
- }
result[len] = '\0';
return reinterpret_cast<char*>(memmove(result, s, len));
}
diff --git a/runtime/vm/base64.cc b/runtime/vm/base64.cc
index ec003ae..54e1ddc 100644
--- a/runtime/vm/base64.cc
+++ b/runtime/vm/base64.cc
@@ -4,6 +4,7 @@
#include "vm/base64.h"
+#include "platform/allocation.h"
#include "vm/os.h"
namespace dart {
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index a1ca4cd..cf5a69a 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -270,7 +270,6 @@
intptr_t kernel_buffer_size = file->Length();
uint8_t* kernel_buffer =
reinterpret_cast<uint8_t*>(malloc(kernel_buffer_size));
- EXPECT(kernel_buffer != NULL);
bool read_fully = file->ReadFully(kernel_buffer, kernel_buffer_size);
EXPECT(read_fully);
Dart_Handle result =
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 8068db1..529040e 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -7,6 +7,7 @@
#include <memory>
+#include "platform/allocation.h"
#include "platform/assert.h"
#include "platform/atomic.h"
#include "platform/utils.h"
diff --git a/runtime/vm/code_observers.cc b/runtime/vm/code_observers.cc
index 7d50a23..8590013 100644
--- a/runtime/vm/code_observers.cc
+++ b/runtime/vm/code_observers.cc
@@ -43,9 +43,6 @@
observers_length_++;
observers_ = reinterpret_cast<CodeObserver**>(
realloc(observers_, sizeof(observer) * observers_length_));
- if (observers_ == NULL) {
- FATAL("failed to grow code observers array");
- }
observers_[observers_length_ - 1] = observer;
}
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index d371645..6debb13 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -842,11 +842,11 @@
if (forward_list_length_ == 0) {
forward_list_length_ = 4;
intptr_t new_size = forward_list_length_ * sizeof(object);
- new_list = ::malloc(new_size);
+ new_list = dart::malloc(new_size);
} else {
forward_list_length_ *= 2;
intptr_t new_size = (forward_list_length_ * sizeof(object));
- new_list = ::realloc(forward_list_, new_size);
+ new_list = dart::realloc(forward_list_, new_size);
}
ASSERT(new_list != NULL);
forward_list_ = reinterpret_cast<Dart_CObject**>(new_list);
@@ -1039,7 +1039,7 @@
WriteSmi(len);
if (type == Utf8::kLatin1) {
uint8_t* latin1_str =
- reinterpret_cast<uint8_t*>(::malloc(len * sizeof(uint8_t)));
+ reinterpret_cast<uint8_t*>(dart::malloc(len * sizeof(uint8_t)));
bool success =
Utf8::DecodeToLatin1(utf8_str, utf8_len, latin1_str, len);
ASSERT(success);
@@ -1049,7 +1049,7 @@
::free(latin1_str);
} else {
uint16_t* utf16_str =
- reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t)));
+ reinterpret_cast<uint16_t*>(dart::malloc(len * sizeof(uint16_t)));
bool success = Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len);
ASSERT(success);
for (intptr_t i = 0; i < len; i++) {
diff --git a/runtime/vm/malloc_hooks_arm.cc b/runtime/vm/malloc_hooks_arm.cc
index e344434..7e857e5 100644
--- a/runtime/vm/malloc_hooks_arm.cc
+++ b/runtime/vm/malloc_hooks_arm.cc
@@ -10,7 +10,7 @@
namespace dart {
-const intptr_t kSkipCount = 4;
+const intptr_t kSkipCount = 5;
} // namespace dart
diff --git a/runtime/vm/malloc_hooks_arm64.cc b/runtime/vm/malloc_hooks_arm64.cc
index d063748..e50ea0b 100644
--- a/runtime/vm/malloc_hooks_arm64.cc
+++ b/runtime/vm/malloc_hooks_arm64.cc
@@ -10,7 +10,7 @@
namespace dart {
-const intptr_t kSkipCount = 4;
+const intptr_t kSkipCount = 5;
} // namespace dart
diff --git a/runtime/vm/malloc_hooks_ia32.cc b/runtime/vm/malloc_hooks_ia32.cc
index b056456..2b7a371 100644
--- a/runtime/vm/malloc_hooks_ia32.cc
+++ b/runtime/vm/malloc_hooks_ia32.cc
@@ -11,9 +11,9 @@
namespace dart {
#if defined(DEBUG)
-const intptr_t kSkipCount = 5;
+const intptr_t kSkipCount = 6;
#elif !(defined(PRODUCT) || defined(DEBUG))
-const intptr_t kSkipCount = 4;
+const intptr_t kSkipCount = 5;
#endif
} // namespace dart
diff --git a/runtime/vm/malloc_hooks_x64.cc b/runtime/vm/malloc_hooks_x64.cc
index 25e2283..2ec564b 100644
--- a/runtime/vm/malloc_hooks_x64.cc
+++ b/runtime/vm/malloc_hooks_x64.cc
@@ -11,9 +11,9 @@
namespace dart {
#if defined(DEBUG)
-const intptr_t kSkipCount = 5;
+const intptr_t kSkipCount = 6;
#elif !(defined(PRODUCT) || defined(DEBUG))
-const intptr_t kSkipCount = 4;
+const intptr_t kSkipCount = 5;
#endif
} // namespace dart
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 4b011d9..1b7f6ba 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -1461,9 +1461,6 @@
writer->Write<ObjectPtr>(length_);
uint8_t* data = reinterpret_cast<uint8_t*>(this->data());
void* passed_data = malloc(bytes);
- if (passed_data == NULL) {
- OUT_OF_MEMORY();
- }
memmove(passed_data, data, bytes);
static_cast<MessageWriter*>(writer)->finalizable_data()->Put(
bytes,
@@ -1546,9 +1543,6 @@
writer->Write<ObjectPtr>(length_);
uint8_t* data = reinterpret_cast<uint8_t*>(data_);
void* passed_data = malloc(bytes);
- if (passed_data == NULL) {
- OUT_OF_MEMORY();
- }
memmove(passed_data, data, bytes);
static_cast<MessageWriter*>(writer)->finalizable_data()->Put(
bytes,
diff --git a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
index 2b66dfc..02ec093 100644
--- a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
+++ b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
@@ -739,7 +739,7 @@
@Native('Float32Array')
class NativeFloat32List extends NativeTypedArrayOfDouble
implements Float32List {
- factory NativeFloat32List(int length) => _create1(_checkLength(length));
+ factory NativeFloat32List(int length) => _createLength(_checkLength(length));
factory NativeFloat32List.fromList(List<double> elements) =>
_create1(_ensureNativeList(elements));
@@ -760,6 +760,11 @@
return _create1(source);
}
+ static NativeFloat32List _createLength(int arg) => JS(
+ 'returns:NativeFloat32List;effects:none;depends:none;new:true',
+ 'new Float32Array(#)',
+ arg);
+
static NativeFloat32List _create1(arg) =>
JS('NativeFloat32List', 'new Float32Array(#)', arg);
@@ -773,7 +778,7 @@
@Native('Float64Array')
class NativeFloat64List extends NativeTypedArrayOfDouble
implements Float64List {
- factory NativeFloat64List(int length) => _create1(_checkLength(length));
+ factory NativeFloat64List(int length) => _createLength(_checkLength(length));
factory NativeFloat64List.fromList(List<double> elements) =>
_create1(_ensureNativeList(elements));
@@ -794,6 +799,11 @@
return _create1(source);
}
+ static NativeFloat64List _createLength(int arg) => JS(
+ 'returns:NativeFloat64List;effects:none;depends:none;new:true',
+ 'new Float64Array(#)',
+ arg);
+
static NativeFloat64List _create1(arg) =>
JS('NativeFloat64List', 'new Float64Array(#)', arg);
@@ -806,7 +816,7 @@
@Native('Int16Array')
class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
- factory NativeInt16List(int length) => _create1(_checkLength(length));
+ factory NativeInt16List(int length) => _createLength(_checkLength(length));
factory NativeInt16List.fromList(List<int> elements) =>
_create1(_ensureNativeList(elements));
@@ -832,6 +842,11 @@
return _create1(source);
}
+ static NativeInt16List _createLength(int arg) => JS(
+ 'returns:NativeInt16List;effects:none;depends:none;new:true',
+ 'new Int16Array(#)',
+ arg);
+
static NativeInt16List _create1(arg) =>
JS('NativeInt16List', 'new Int16Array(#)', arg);
@@ -844,7 +859,7 @@
@Native('Int32Array')
class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
- factory NativeInt32List(int length) => _create1(_checkLength(length));
+ factory NativeInt32List(int length) => _createLength(_checkLength(length));
factory NativeInt32List.fromList(List<int> elements) =>
_create1(_ensureNativeList(elements));
@@ -870,6 +885,11 @@
return _create1(source);
}
+ static NativeInt32List _createLength(int arg) => JS(
+ 'returns:NativeInt32List;effects:none;depends:none;new:true',
+ 'new Int32Array(#)',
+ arg);
+
static NativeInt32List _create1(arg) =>
JS('NativeInt32List', 'new Int32Array(#)', arg);
@@ -882,7 +902,7 @@
@Native('Int8Array')
class NativeInt8List extends NativeTypedArrayOfInt implements Int8List {
- factory NativeInt8List(int length) => _create1(_checkLength(length));
+ factory NativeInt8List(int length) => _createLength(_checkLength(length));
factory NativeInt8List.fromList(List<int> elements) =>
_create1(_ensureNativeList(elements));
@@ -908,6 +928,11 @@
return _create1(source);
}
+ static NativeInt8List _createLength(int arg) => JS(
+ 'returns:NativeInt8List;effects:none;depends:none;new:true',
+ 'new Int8Array(#)',
+ arg);
+
static NativeInt8List _create1(arg) =>
JS('NativeInt8List', 'new Int8Array(#)', arg);
@@ -920,7 +945,7 @@
@Native('Uint16Array')
class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
- factory NativeUint16List(int length) => _create1(_checkLength(length));
+ factory NativeUint16List(int length) => _createLength(_checkLength(length));
factory NativeUint16List.fromList(List<int> list) =>
_create1(_ensureNativeList(list));
@@ -946,6 +971,11 @@
return _create1(source);
}
+ static NativeUint16List _createLength(int arg) => JS(
+ 'returns:NativeUint16List;effects:none;depends:none;new:true',
+ 'new Uint16Array(#)',
+ arg);
+
static NativeUint16List _create1(arg) =>
JS('NativeUint16List', 'new Uint16Array(#)', arg);
@@ -958,7 +988,7 @@
@Native('Uint32Array')
class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
- factory NativeUint32List(int length) => _create1(_checkLength(length));
+ factory NativeUint32List(int length) => _createLength(_checkLength(length));
factory NativeUint32List.fromList(List<int> elements) =>
_create1(_ensureNativeList(elements));
@@ -984,6 +1014,11 @@
return _create1(source);
}
+ static NativeUint32List _createLength(int arg) => JS(
+ 'returns:NativeUint32List;effects:none;depends:none;new:true',
+ 'new Uint32Array(#)',
+ arg);
+
static NativeUint32List _create1(arg) =>
JS('NativeUint32List', 'new Uint32Array(#)', arg);
@@ -997,7 +1032,8 @@
@Native('Uint8ClampedArray,CanvasPixelArray')
class NativeUint8ClampedList extends NativeTypedArrayOfInt
implements Uint8ClampedList {
- factory NativeUint8ClampedList(int length) => _create1(_checkLength(length));
+ factory NativeUint8ClampedList(int length) =>
+ _createLength(_checkLength(length));
factory NativeUint8ClampedList.fromList(List<int> elements) =>
_create1(_ensureNativeList(elements));
@@ -1026,6 +1062,11 @@
return _create1(source);
}
+ static NativeUint8ClampedList _createLength(int arg) => JS(
+ 'returns:NativeUint8ClampedList;effects:none;depends:none;new:true',
+ 'new Uint8ClampedArray(#)',
+ arg);
+
static NativeUint8ClampedList _create1(arg) =>
JS('NativeUint8ClampedList', 'new Uint8ClampedArray(#)', arg);
@@ -1046,7 +1087,7 @@
// dispatch record for Uint8List.
@Native('Uint8Array,!nonleaf')
class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List {
- factory NativeUint8List(int length) => _create1(_checkLength(length));
+ factory NativeUint8List(int length) => _createLength(_checkLength(length));
factory NativeUint8List.fromList(List<int> elements) =>
_create1(_ensureNativeList(elements));
@@ -1074,6 +1115,11 @@
return _create1(source);
}
+ static NativeUint8List _createLength(int arg) => JS(
+ 'returns:NativeUint8List;effects:none;depends:none;new:true',
+ 'new Uint8Array(#)',
+ arg);
+
static NativeUint8List _create1(arg) =>
JS('NativeUint8List', 'new Uint8Array(#)', arg);
diff --git a/tools/VERSION b/tools/VERSION
index f245b05..c026b79e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 43
+PRERELEASE 44
PRERELEASE_PATCH 0
\ No newline at end of file