Version 2.13.0-141.0.dev
Merge commit '2472db0031116e76df8d300a5c8b3c2646d54ada' into 'dev'
diff --git a/DEPS b/DEPS
index 318184f..442c05e 100644
--- a/DEPS
+++ b/DEPS
@@ -113,7 +113,7 @@
"http_retry_rev": "845771af7bb5ab38ab740ce4a31f3b0c7680302b",
"http_rev": "d5c678cd63c3e9c1d779a09acfa95b7e3af84665",
"http_throttle_tag" : "1.0.2",
- "icu_rev" : "79326efe26e5440f530963704c3c0ff965b3a4ac",
+ "icu_rev" : "81d656878ec611cb0b42d52c82e9dae93920d9ba",
"idl_parser_rev": "5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
"intl_tag": "0.17.0-nullsafety",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index e6e7c2d..32821ea2 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -518,7 +518,6 @@
default_warning_flags += [
"-Wno-deprecated-declarations", # crashpad
"-Wno-ignored-pragma-optimize", # icu, double-conversion
- "-Wno-implicit-int-float-conversion", # icu
"-Wno-macro-redefined",
"-Wno-microsoft-cast",
"-Wno-microsoft-unqualified-friend",
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index 9d64fc8..c0066ca 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
name: _fe_analyzer_shared
-version: 17.0.0
+version: 18.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/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 9a2ca7e..d44c693 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,6 +1,8 @@
-## 1.2.0-dev
+## 1.2.0
* Deprecated all setters in API of AST. Use `parseString()` instead.
* `AnalysisSession.getErrors()` does not return `null`, check its `state`.
+* Support for `aliasElement` and `aliasArguments` for aliases of
+ `InterfaceType`s and `TypeParameterType`s.
## 1.1.0
* Deprecated `TypeProvider.futureType2()`, `iterableType2()`, etc.
diff --git a/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart b/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
index e74356b..e043a3f 100644
--- a/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
@@ -14,10 +14,14 @@
static const _key = 'BodyInferenceContext';
final TypeSystemImpl _typeSystem;
- final bool _isAsynchronous;
- final bool _isGenerator;
+ final bool isAsynchronous;
+ final bool isGenerator;
- /// The context type, computed from the imposed return type schema.
+ /// The imposed return type, from the typing context.
+ /// Might be `null` if an empty typing context.
+ final DartType? imposedType;
+
+ /// The context type, computed from [imposedType].
/// Might be `null` if an empty typing context.
final DartType? contextType;
@@ -35,6 +39,7 @@
typeSystem: typeSystem,
isAsynchronous: node.isAsynchronous,
isGenerator: node.isGenerator,
+ imposedType: imposedType,
contextType: contextType,
);
node.setProperty(_key, bodyContext);
@@ -44,12 +49,13 @@
BodyInferenceContext._({
required TypeSystemImpl typeSystem,
- required bool isAsynchronous,
- required bool isGenerator,
+ required this.isAsynchronous,
+ required this.isGenerator,
+ required this.imposedType,
required this.contextType,
- }) : _typeSystem = typeSystem,
- _isAsynchronous = isAsynchronous,
- _isGenerator = isGenerator;
+ }) : _typeSystem = typeSystem;
+
+ bool get isSynchronous => !isAsynchronous;
TypeProvider get _typeProvider => _typeSystem.typeProvider;
@@ -58,7 +64,7 @@
_returnTypes.add(_typeProvider.nullType);
} else {
var type = expression.typeOrThrow;
- if (_isAsynchronous) {
+ if (isAsynchronous) {
type = _typeSystem.flatten(type);
}
_returnTypes.add(type);
@@ -73,8 +79,8 @@
return;
}
- if (_isGenerator) {
- var requiredClass = _isAsynchronous
+ if (isGenerator) {
+ var requiredClass = isAsynchronous
? _typeProvider.streamElement
: _typeProvider.iterableElement;
var type = _argumentOf(expressionType, requiredClass);
@@ -93,14 +99,14 @@
var clampedReturnedType = _clampToContextType(actualReturnedType);
- if (_isGenerator) {
- if (_isAsynchronous) {
+ if (isGenerator) {
+ if (isAsynchronous) {
return _typeProvider.streamType(clampedReturnedType);
} else {
return _typeProvider.iterableType(clampedReturnedType);
}
} else {
- if (_isAsynchronous) {
+ if (isAsynchronous) {
return _typeProvider.futureType(
_typeSystem.flatten(clampedReturnedType),
);
@@ -122,7 +128,7 @@
// `FutureOr<void>`, let `S` be `void`.
if (_typeSystem.isNonNullableByDefault) {
if (R.isVoid ||
- _isAsynchronous &&
+ isAsynchronous &&
R is InterfaceType &&
R.isDartAsyncFutureOr &&
R.typeArguments[0].isVoid) {
@@ -142,7 +148,7 @@
DartType _computeActualReturnedType({
required bool endOfBlockIsReachable,
}) {
- if (_isGenerator) {
+ if (isGenerator) {
if (_returnTypes.isEmpty) {
return DynamicTypeImpl.instance;
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
index 24ce9b9..6617ab2 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
@@ -43,7 +43,7 @@
return;
}
- var receiverType = function.staticType;
+ var receiverType = function.typeOrThrow;
if (receiverType is InterfaceType) {
// Note: in this circumstance it's not necessary to call
// `_nullableDereferenceVerifier.expression` because
@@ -53,6 +53,11 @@
return;
}
+ if (_checkForUseOfVoidResult(function, receiverType)) {
+ _unresolved(node, DynamicTypeImpl.instance);
+ return;
+ }
+
_nullableDereferenceVerifier.expression(function,
errorCode: CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE);
@@ -62,6 +67,8 @@
}
if (identical(receiverType, NeverTypeImpl.instance)) {
+ _errorReporter.reportErrorForNode(
+ HintCode.RECEIVER_OF_TYPE_NEVER, function);
_unresolved(node, NeverTypeImpl.instance);
return;
}
@@ -69,6 +76,30 @@
_unresolved(node, DynamicTypeImpl.instance);
}
+ /// Check for situations where the result of a method or function is used,
+ /// when it returns 'void'. Or, in rare cases, when other types of expressions
+ /// are void, such as identifiers.
+ ///
+ /// See [StaticWarningCode.USE_OF_VOID_RESULT].
+ ///
+ /// TODO(scheglov) this is duplicate
+ bool _checkForUseOfVoidResult(Expression expression, DartType type) {
+ if (!identical(type, VoidTypeImpl.instance)) {
+ return false;
+ }
+
+ if (expression is MethodInvocation) {
+ SimpleIdentifier methodName = expression.methodName;
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.USE_OF_VOID_RESULT, methodName, []);
+ } else {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.USE_OF_VOID_RESULT, expression, []);
+ }
+
+ return true;
+ }
+
void _resolve(FunctionExpressionInvocationImpl node, FunctionType rawType) {
_inferenceHelper.resolveFunctionExpressionInvocation(
node: node,
@@ -130,7 +161,22 @@
);
var callElement = result.getter;
- if (callElement == null || callElement.kind != ElementKind.METHOD) {
+ if (callElement == null) {
+ if (result.needsGetterError) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
+ function,
+ );
+ }
+ _unresolved(node, DynamicTypeImpl.instance);
+ return;
+ }
+
+ if (callElement.kind != ElementKind.METHOD) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
+ function,
+ );
_unresolved(node, DynamicTypeImpl.instance);
return;
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
index c241eb0..4238870 100644
--- a/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
@@ -3,13 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/resolver/body_inference_context.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -21,8 +21,6 @@
required ResolverVisitor resolver,
}) : _resolver = resolver;
- ExecutableElement get _enclosingFunction => _resolver.enclosingFunction!;
-
ErrorReporter get _errorReporter => _resolver.errorReporter;
TypeProvider get _typeProvider => _resolver.typeProvider;
@@ -30,8 +28,9 @@
TypeSystemImpl get _typeSystem => _resolver.typeSystem;
void resolve(YieldStatement node) {
- if (_enclosingFunction.isGenerator) {
- _resolve_generator(node);
+ var bodyContext = _resolver.inferenceContext.bodyContext;
+ if (bodyContext != null && bodyContext.isGenerator) {
+ _resolve_generator(bodyContext, node);
} else {
_resolve_notGenerator(node);
}
@@ -69,26 +68,30 @@
/// return type of a generator function.
///
/// This method should only be called in generator functions.
- void _checkForYieldOfInvalidType(YieldStatement node, bool isYieldEach) {
- var declaredReturnType = _enclosingFunction.returnType;
-
+ void _checkForYieldOfInvalidType(
+ BodyInferenceContext bodyContext,
+ YieldStatement node,
+ bool isYieldEach,
+ ) {
var expression = node.expression;
var expressionType = expression.typeOrThrow;
DartType impliedReturnType;
if (isYieldEach) {
impliedReturnType = expressionType;
- } else if (_enclosingFunction.isSynchronous) {
+ } else if (bodyContext.isSynchronous) {
impliedReturnType = _typeProvider.iterableType(expressionType);
} else {
impliedReturnType = _typeProvider.streamType(expressionType);
}
- if (!_typeSystem.isAssignableTo(impliedReturnType, declaredReturnType)) {
+ var imposedReturnType = bodyContext.imposedType;
+ if (imposedReturnType != null &&
+ !_typeSystem.isAssignableTo(impliedReturnType, imposedReturnType)) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
expression,
- [impliedReturnType, declaredReturnType],
+ [impliedReturnType, imposedReturnType],
);
return;
}
@@ -98,7 +101,7 @@
// also check that the implied return type is assignable to generic
// Iterable/Stream.
DartType requiredReturnType;
- if (_enclosingFunction.isSynchronous) {
+ if (bodyContext.isSynchronous) {
requiredReturnType = _typeProvider.iterableDynamicType;
} else {
requiredReturnType = _typeProvider.streamDynamicType;
@@ -114,21 +117,11 @@
}
}
- void _computeElementType(YieldStatement node) {
- var elementType = _resolver.inferenceContext.bodyContext?.contextType;
- if (elementType != null) {
- var contextType = elementType;
- if (node.star != null) {
- contextType = _enclosingFunction.isSynchronous
- ? _typeProvider.iterableType(elementType)
- : _typeProvider.streamType(elementType);
- }
- InferenceContext.setType(node.expression, contextType);
- }
- }
-
- void _resolve_generator(YieldStatement node) {
- _computeElementType(node);
+ void _resolve_generator(
+ BodyInferenceContext bodyContext,
+ YieldStatement node,
+ ) {
+ _setContextType(bodyContext, node);
node.expression.accept(_resolver);
@@ -138,9 +131,9 @@
.UNCHECKED_USE_OF_NULLABLE_VALUE_IN_YIELD_EACH);
}
- _resolver.inferenceContext.bodyContext?.addYield(node);
+ bodyContext.addYield(node);
- _checkForYieldOfInvalidType(node, node.star != null);
+ _checkForYieldOfInvalidType(bodyContext, node, node.star != null);
_checkForUseOfVoidResult(node.expression);
}
@@ -156,4 +149,20 @@
_checkForUseOfVoidResult(node.expression);
}
+
+ void _setContextType(
+ BodyInferenceContext bodyContext,
+ YieldStatement node,
+ ) {
+ var elementType = bodyContext.contextType;
+ if (elementType != null) {
+ var contextType = elementType;
+ if (node.star != null) {
+ contextType = bodyContext.isSynchronous
+ ? _typeProvider.iterableType(elementType)
+ : _typeProvider.streamType(elementType);
+ }
+ InferenceContext.setType(node.expression, contextType);
+ }
+ }
}
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 071f068..11f7424 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -765,14 +765,7 @@
}
DartType expressionType = functionExpression.typeOrThrow;
- if (!_checkForUseOfVoidResult(functionExpression) &&
- !_checkForUseOfNever(functionExpression) &&
- node.staticElement == null &&
- !_isFunctionType(expressionType)) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
- functionExpression);
- } else if (expressionType is FunctionType) {
+ if (expressionType is FunctionType) {
_typeArgumentsVerifier.checkFunctionExpressionInvocation(node);
}
_requiredParametersVerifier.visitFunctionExpressionInvocation(node);
@@ -4502,24 +4495,6 @@
}
}
- /// While in general Never is a sort of placehold type that should be usable
- /// anywhere, we explicitly bar it from some dubious syntactic locations such
- /// as calling a method on Never, which in practice would look something like
- /// `(throw x).toString()` which is clearly something between a mistake and
- /// dead code.
- ///
- /// See [StaticWarningCode.RECEIVER_OF_TYPE_NEVER].
- bool _checkForUseOfNever(Expression expression) {
- if (!identical(expression.staticType, NeverTypeImpl.instance)) {
- return false;
- }
-
- _errorReporter.reportErrorForNode(
- HintCode.RECEIVER_OF_TYPE_NEVER, expression);
-
- return true;
- }
-
/// Check for situations where the result of a method or function is used,
/// when it returns 'void'. Or, in rare cases, when other types of expressions
/// are void, such as identifiers.
@@ -5220,19 +5195,6 @@
return false;
}
- bool _isFunctionType(DartType type) {
- if (type.isDynamic || type.isDartCoreNull) {
- return true;
- } else if (type is FunctionType || type.isDartCoreFunction) {
- return true;
- } else if (type is InterfaceType) {
- var callMethod =
- type.lookUpMethod2(FunctionElement.CALL_METHOD_NAME, _currentLibrary);
- return callMethod != null;
- }
- return false;
- }
-
/// Return `true` if the given [identifier] is in a location where it is
/// allowed to resolve to a static member of a supertype.
bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed(
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index a6d0a3d..5be43d5 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 1.2.0-dev
+version: 1.2.0
description: This package provides a library that performs static analysis of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -7,7 +7,7 @@
sdk: '>=2.12.0-0 <3.0.0'
dependencies:
- _fe_analyzer_shared: ^17.0.0
+ _fe_analyzer_shared: ^18.0.0
cli_util: ^0.3.0
collection: ^1.15.0
convert: ^3.0.0
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index b1bc073..237b1d8 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -1155,9 +1155,6 @@
c.foo();
}
''', [
- if (typeToStringWithNullability)
- error(
- CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE, 61, 5),
error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 61, 5),
]);
@@ -1179,9 +1176,6 @@
foo();
}
''', [
- if (typeToStringWithNullability)
- error(
- CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE, 23, 3),
error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 23, 3),
]);
@@ -1203,9 +1197,6 @@
foo()();
}
''', [
- if (typeToStringWithNullability)
- error(
- CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE, 26, 5),
error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 26, 3),
]);
assertMethodInvocation(
@@ -1223,9 +1214,6 @@
foo();
}
''', [
- if (typeToStringWithNullability)
- error(
- CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE, 22, 3),
error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 22, 3),
]);
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
index eb82661..424912e 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
@@ -30,7 +30,6 @@
int f(A a) => a();
''', [
error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS, 110, 1),
- error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 110, 1),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/invocation_of_non_function_expression_test.dart b/pkg/analyzer/test/src/diagnostics/invocation_of_non_function_expression_test.dart
index 1a329c0..77ac7e9 100644
--- a/pkg/analyzer/test/src/diagnostics/invocation_of_non_function_expression_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invocation_of_non_function_expression_test.dart
@@ -15,13 +15,35 @@
@reflectiveTest
class InvocationOfNonFunctionExpressionTest extends PubPackageResolutionTest {
- test_invocationOfNonFunctionExpression_literal() async {
+ test_literal_int() async {
await assertErrorsInCode(r'''
-f() {
+void f() {
3(5);
}
''', [
- error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 8, 1),
+ error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 13, 1),
+ ]);
+ }
+
+ test_literal_null() async {
+ await assertErrorsInCode(r'''
+// @dart = 2.9
+void f() {
+ null();
+}
+''', [
+ error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 28, 4),
+ ]);
+ }
+
+ test_type_Null() async {
+ await assertErrorsInCode(r'''
+// @dart = 2.9
+void f(Null a) {
+ a();
+}
+''', [
+ error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 34, 1),
]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
index 7ca7f8d..cd56869 100644
--- a/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
@@ -832,6 +832,17 @@
]);
}
+ test_invoke_dynamicFunctionType_nullable2() async {
+ await assertErrorsInCode(r'''
+void f<F extends Function>(List<F?> funcList) {
+ funcList[0]();
+}
+''', [
+ error(
+ CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE, 50, 11),
+ ]);
+ }
+
test_invoke_nonNullable() async {
await assertNoErrorsInCode(r'''
m() {
diff --git a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
index a107230..a5453bd 100644
--- a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
@@ -86,6 +86,19 @@
]);
}
+ test_none_asyncStar_int_to_streamString_functionExpression() async {
+ await assertErrorsInCode('''
+void f() {
+ // ignore:unused_local_variable
+ Stream<String> Function() v = () async* {
+ yield 1;
+ };
+}
+''', [
+ error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 99, 1),
+ ]);
+ }
+
test_none_asyncStar_int_to_untyped() async {
await assertNoErrorsInCode('''
f() async* {
@@ -152,6 +165,19 @@
]);
}
+ test_none_syncStar_int_to_iterableString_functionExpression() async {
+ await assertErrorsInCode('''
+void f() {
+ // ignore:unused_local_variable
+ Iterable<String> Function() v = () sync* {
+ yield 1;
+ };
+}
+''', [
+ error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 100, 1),
+ ]);
+ }
+
test_none_syncStar_int_to_stream() async {
await assertErrorsInCode('''
Stream<int> f() sync* {
diff --git a/pkg/dev_compiler/lib/src/compiler/module_builder.dart b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
index 04b15cc..922b17f 100644
--- a/pkg/dev_compiler/lib/src/compiler/module_builder.dart
+++ b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
@@ -109,6 +109,9 @@
Fun transformFunctionModuleFormat(
List<ModuleItem> items, Fun function, ModuleFormat format) {
switch (format) {
+ case ModuleFormat.ddc:
+ // Legacy format always generates output compatible with single file mode.
+ return DdcModuleBuilder().buildFunctionWithImports(items, function);
case ModuleFormat.amd:
return AmdModuleBuilder().buildFunctionWithImports(items, function);
default:
@@ -174,55 +177,113 @@
/// Generates modules for with our DDC `dart_library.js` loading mechanism.
// TODO(jmesserly): remove this and replace with something that interoperates.
class DdcModuleBuilder extends _ModuleBuilder {
- Program build(Program module) {
- // Collect imports/exports/statements.
- visitProgram(module);
+ /// Build a module variable definition for [import].
+ ///
+ /// Used to load modules referenced in the expression during expression
+ /// evaluation.
+ static Statement buildLoadModule(
+ Identifier moduleVar, ImportDeclaration import) =>
+ js.statement(
+ 'const # = dart_library.import(#);', [moduleVar, import.from]);
- // Build import parameters.
- var exportsVar = TemporaryId('exports');
- var parameters = <TemporaryId>[exportsVar];
- var importNames = <Expression>[];
- var importStatements = <Statement>[];
- for (var import in imports) {
- importNames.add(import.from);
- // TODO(jmesserly): we could use destructuring here.
- var moduleVar =
- TemporaryId(pathToJSIdentifier(import.from.valueWithoutQuotes));
- parameters.add(moduleVar);
- for (var importName in import.namedImports) {
- assert(!importName
- .isStar); // import * not supported in ddc format modules.
- var asName = importName.asName ?? importName.name;
- var fromName = importName.name.name;
- // Load non-SDK modules on demand (i.e., deferred).
- if (import.from.valueWithoutQuotes != dartSdkModule) {
- importStatements.add(js.statement(
- 'let # = dart_library.defer(#, #, function (mod, lib) {'
- ' # = mod;'
- ' # = lib;'
- '});',
- [asName, moduleVar, js.string(fromName), moduleVar, asName]));
- } else {
- importStatements.add(js.statement(
- 'const # = #.#', [asName, moduleVar, importName.name.name]));
- }
+ /// Build library variable definitions for all libraries from [import].
+ static List<Statement> buildImports(
+ Identifier moduleVar, ImportDeclaration import, bool deferModules) {
+ var items = <Statement>[];
+
+ for (var importName in import.namedImports) {
+ // import * is not emitted by the compiler, so we don't handle it here.
+ assert(!importName.isStar);
+ var asName = importName.asName ?? importName.name;
+ var fromName = importName.name.name;
+ // Load non-SDK modules on demand (i.e., deferred).
+ if (deferModules && import.from.valueWithoutQuotes != dartSdkModule) {
+ items.add(js.statement(
+ 'let # = dart_library.defer(#, #, function (mod, lib) {'
+ ' # = mod;'
+ ' # = lib;'
+ '});',
+ [asName, moduleVar, js.string(fromName), moduleVar, asName]));
+ } else {
+ items.add(js.statement('const # = #.#', [asName, moduleVar, fromName]));
}
}
- statements.insertAll(0, importStatements);
+ return items;
+ }
+
+ /// Build statements for [exports].
+ static List<Statement> buildExports(
+ Identifier exportsVar, List<ExportDeclaration> exports) {
+ var items = <Statement>[];
if (exports.isNotEmpty) {
- statements.add(js.comment('Exports:'));
+ items.add(js.comment('Exports:'));
// TODO(jmesserly): make these immutable in JS?
for (var export in exports) {
var names = export.exportedNames;
assert(names != null); // export * not supported in ddc modules.
for (var name in names) {
var alias = name.asName ?? name.name;
- statements.add(
+ items.add(
js.statement('#.# = #;', [exportsVar, alias.name, name.name]));
}
}
}
+ return items;
+ }
+
+ /// Build function body with all necessary imports included.
+ ///
+ /// Used for the top level synthetic function generated during expression
+ /// compilation, in order to include all the context needed for evaluation
+ /// inside it.
+ ///
+ /// Returns a new function that combines all statements from tranformed
+ /// imports from [items] and the body of the [function].
+ Fun buildFunctionWithImports(List<ModuleItem> items, Fun function) {
+ clear();
+ visitModuleItems(items);
+
+ var moduleImports = _collectModuleImports(imports);
+ var importStatements = <Statement>[];
+
+ for (var p in moduleImports) {
+ var moduleVar = p.key;
+ var import = p.value;
+ importStatements.add(buildLoadModule(moduleVar, import));
+ importStatements.addAll(buildImports(moduleVar, import, false));
+ }
+
+ return Fun(
+ function.params,
+ Block([...importStatements, ...statements, ...function.body.statements]),
+ );
+ }
+
+ Program build(Program module) {
+ // Collect imports/exports/statements.
+ visitProgram(module);
+
+ var exportsVar = TemporaryId('exports');
+ var parameters = <Identifier>[exportsVar];
+ var importNames = <Expression>[];
+
+ var moduleImports = _collectModuleImports(imports);
+ var importStatements = <Statement>[];
+
+ for (var p in moduleImports) {
+ var moduleVar = p.key;
+ var import = p.value;
+ importNames.add(import.from);
+ parameters.add(moduleVar);
+ importStatements.addAll(buildImports(moduleVar, import, true));
+ }
+
+ // Prepend import statetements.
+ statements.insertAll(0, importStatements);
+
+ // Append export statements.
+ statements.addAll(buildExports(exportsVar, exports));
var resultModule = NamedFunction(
loadFunctionIdentifier(module.name),
@@ -293,6 +354,9 @@
AmdModuleBuilder();
/// Build a module variable definition for [import].
+ ///
+ /// Used to load modules referenced in the expression during expression
+ /// evaluation.
static Statement buildLoadModule(
Identifier moduleVar, ImportDeclaration import) =>
js.statement('const # = require(#);', [moduleVar, import.from]);
@@ -312,20 +376,6 @@
return items;
}
- /// Group libraries from [imports] by modules.
- static Map<Identifier, ImportDeclaration> _collectModuleImports(
- List<ImportDeclaration> imports) {
- var result = <Identifier, ImportDeclaration>{};
- for (var import in imports) {
- // TODO(jmesserly): we could use destructuring once Atom supports it.
- var moduleVar =
- TemporaryId(pathToJSIdentifier(import.from.valueWithoutQuotes));
-
- result[moduleVar] = import;
- }
- return result;
- }
-
/// Build statements for [exports].
static List<Statement> buildExports(List<ExportDeclaration> exports) {
var items = <Statement>[];
@@ -349,7 +399,7 @@
/// Build function body with all necessary imports included.
///
- /// Used for the top level syntetic function generated during expression
+ /// Used for the top level synthetic function generated during expression
/// compilation, in order to include all the context needed for evaluation
/// inside it.
///
@@ -362,10 +412,12 @@
var moduleImports = _collectModuleImports(imports);
var importStatements = <Statement>[];
- moduleImports.forEach((moduleVar, import) {
+ for (var p in moduleImports) {
+ var moduleVar = p.key;
+ var import = p.value;
importStatements.add(buildLoadModule(moduleVar, import));
importStatements.addAll(buildImports(moduleVar, import));
- });
+ }
return Fun(
function.params,
@@ -379,14 +431,16 @@
var moduleImports = _collectModuleImports(imports);
var importStatements = <Statement>[];
+ var fnParams = <Identifier>[];
+ var dependencies = <LiteralString>[];
- var fnParams = moduleImports.keys.toList();
- var dependencies =
- moduleImports.values.map((import) => import.from).toList();
-
- moduleImports.forEach((moduleVar, import) {
+ for (var p in moduleImports) {
+ var moduleVar = p.key;
+ var import = p.value;
+ fnParams.add(moduleVar);
+ dependencies.add(import.from);
importStatements.addAll(buildImports(moduleVar, import));
- });
+ }
// Prepend import statetements.
statements.insertAll(0, importStatements);
@@ -444,3 +498,17 @@
// Replacement string for path separators (i.e., '/', '\', '..').
final encodedSeparator = '__';
+
+/// Group libraries from [imports] by modules.
+List<MapEntry<Identifier, ImportDeclaration>> _collectModuleImports(
+ List<ImportDeclaration> imports) {
+ var result = <MapEntry<Identifier, ImportDeclaration>>[];
+ for (var import in imports) {
+ // TODO(jmesserly): we could use destructuring once Atom supports it.
+ var moduleVar =
+ TemporaryId(pathToJSIdentifier(import.from.valueWithoutQuotes));
+
+ result.add(MapEntry<Identifier, ImportDeclaration>(moduleVar, import));
+ }
+ return result;
+}
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 bfec31c..993d2aa 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
@@ -89,6 +89,17 @@
errors.addAll(m.plainTextFormatted);
};
}
+
+ String get loadModule {
+ switch (moduleFormat) {
+ case ModuleFormat.amd:
+ return 'require';
+ case ModuleFormat.ddc:
+ return 'dart_library.import';
+ default:
+ throw UnsupportedError('Module format: $moduleFormat');
+ }
+ }
}
/// Convenience class describing JavaScript module
@@ -122,7 +133,7 @@
@override
String toString() =>
- 'Name: $name, File: $file, Package: $package, path: $path';
+ 'Name: \$name, File: \$file, Package: \$package, path: \$path';
}
class TestCompilationResult {
@@ -156,7 +167,8 @@
var compilerOptions = SharedCompilerOptions(
replCompile: true,
moduleName: moduleName,
- soundNullSafety: setup.soundNullSafety);
+ soundNullSafety: setup.soundNullSafety,
+ moduleFormats: [setup.moduleFormat]);
var coreTypes = compiler.getCoreTypes();
final importToSummary = Map<Library, Component>.identity();
@@ -176,7 +188,7 @@
allowKeywordsInProperties: true, allowSingleLineIfStatements: true);
var printer = SimpleJavaScriptPrintingContext();
- var tree = transformModuleFormat(ModuleFormat.amd, moduleTree);
+ var tree = transformModuleFormat(setup.moduleFormat, moduleTree);
tree.accept(Printer(opts, printer, localNamer: TemporaryNamer(tree)));
var printed = printer.getText();
debugPrint(printed);
@@ -311,105 +323,185 @@
}
void main() {
- group('Unsound null safety:', () {
- var options = SetupCompilerOptions(soundNullSafety: false);
+ for (var moduleFormat in [ModuleFormat.amd, ModuleFormat.ddc]) {
+ group('Module format: $moduleFormat', () {
+ group('Unsound null safety:', () {
+ var options = SetupCompilerOptions(
+ soundNullSafety: false, moduleFormat: moduleFormat);
- group('Expression compiler extension symbols tests', () {
- var source = '''
- ${options.dartLangComment}
-
- main() {
- List<int> list = {};
- list.add(0);
- /* evaluation placeholder */
- }
- ''';
-
- TestDriver driver;
-
- setUp(() {
- driver = TestDriver(options, source);
- });
-
- tearDown(() {
- driver.delete();
- });
-
- test('extension symbol used in original compilation', () async {
- await driver.check(
- scope: <String, String>{'list': 'list'},
- expression: 'list.add(1)',
- expectedResult: r'''
- (function(list) {
- const dart_sdk = require('dart_sdk');
- const dartx = dart_sdk.dartx;
- var $add = dartx.add;
- var S = {$add: dartx.add};
- return list[$add](1);
- }(
- list
- ))
- ''');
- });
-
- test('extension symbol used only in expression compilation', () async {
- await driver.check(
- scope: <String, String>{'list': 'list'},
- expression: 'list.first',
- expectedResult: r'''
- (function(list) {
- const dart_sdk = require('dart_sdk');
- const dartx = dart_sdk.dartx;
- var S = {$first: dartx.first};
- return list[S.$first];
- }(
- list
- ))
- ''');
- });
- });
-
- group('Expression compiler scope collection tests', () {
- var source = '''
- ${options.dartLangComment}
-
- class C {
- C(int this.field);
-
- int methodFieldAccess(int x) {
- var inScope = 1;
- {
- var innerInScope = global + staticField + field;
- /* evaluation placeholder */
- print(innerInScope);
- var innerNotInScope = 2;
- }
- var notInScope = 3;
+ group('Expression compiler import tests', () {
+ var source = '''
+ ${options.dartLangComment}
+ import 'dart:io' show Directory;
+ import 'dart:io' as p;
+ import 'dart:convert' as p;
+
+ main() {
+ print(Directory.systemTemp);
+ print(p.Directory.systemTemp);
+ print(p.utf.decoder);
}
- static int staticField = 0;
- int field;
- }
+ void foo() {
+ /* evaluation placeholder */
+ }
+ ''';
- int global = 42;
- main() => 0;
- ''';
+ TestDriver driver;
- TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- setUp(() {
- driver = TestDriver(options, source);
- });
+ tearDown(() {
+ driver.delete();
+ });
- tearDown(() {
- driver.delete();
- });
+ test('expression referencing unnamed import', () async {
+ await driver.check(
+ scope: <String, String>{},
+ expression: 'Directory.systemTemp',
+ expectedResult: '''
+ (function() {
+ const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+ const io = dart_sdk.io;
+ return io.Directory.systemTemp;
+ }(
+
+ ))
+ ''');
+ });
- test('local in scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'inScope',
- expectedResult: '''
+ test('expression referencing named import', () async {
+ await driver.check(
+ scope: <String, String>{},
+ expression: 'p.Directory.systemTemp',
+ expectedResult: '''
+ (function() {
+ const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+ const io = dart_sdk.io;
+ return io.Directory.systemTemp;
+ }(
+
+ ))
+ ''');
+ });
+
+ test(
+ 'expression referencing another library with the same named import',
+ () async {
+ await driver.check(
+ scope: <String, String>{},
+ expression: 'p.utf8.decoder',
+ expectedResult: '''
+ (function() {
+ const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+ const convert = dart_sdk.convert;
+ return convert.utf8.decoder;
+ }(
+
+ ))
+ ''');
+ });
+ });
+
+ group('Expression compiler extension symbols tests', () {
+ var source = '''
+ ${options.dartLangComment}
+
+ main() {
+ List<int> list = {};
+ list.add(0);
+ /* evaluation placeholder */
+ }
+ ''';
+
+ TestDriver driver;
+
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
+
+ tearDown(() {
+ driver.delete();
+ });
+
+ test('extension symbol used in original compilation', () async {
+ await driver.check(
+ scope: <String, String>{'list': 'list'},
+ expression: 'list.add(1)',
+ expectedResult: '''
+ (function(list) {
+ const dart_sdk = ${options.loadModule}('dart_sdk');
+ const dartx = dart_sdk.dartx;
+ var \$add = dartx.add;
+ var S = {\$add: dartx.add};
+ return list[\$add](1);
+ }(
+ list
+ ))
+ ''');
+ });
+
+ test('extension symbol used only in expression compilation',
+ () async {
+ await driver.check(
+ scope: <String, String>{'list': 'list'},
+ expression: 'list.first',
+ expectedResult: '''
+ (function(list) {
+ const dart_sdk = ${options.loadModule}('dart_sdk');
+ const dartx = dart_sdk.dartx;
+ var S = {\$first: dartx.first};
+ return list[S.\$first];
+ }(
+ list
+ ))
+ ''');
+ });
+ });
+
+ group('Expression compiler scope collection tests', () {
+ var source = '''
+ ${options.dartLangComment}
+
+ class C {
+ C(int this.field);
+
+ int methodFieldAccess(int x) {
+ var inScope = 1;
+ {
+ var innerInScope = global + staticField + field;
+ /* evaluation placeholder */
+ print(innerInScope);
+ var innerNotInScope = 2;
+ }
+ var notInScope = 3;
+ }
+
+ static int staticField = 0;
+ int field;
+ }
+
+ int global = 42;
+ main() => 0;
+ ''';
+
+ TestDriver driver;
+
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
+
+ tearDown(() {
+ driver.delete();
+ });
+
+ test('local in scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'inScope',
+ expectedResult: '''
(function(inScope, innerInScope) {
return inScope;
}.bind(this)(
@@ -417,13 +509,13 @@
0
))
''');
- });
+ });
- test('local in inner scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'innerInScope',
- expectedResult: '''
+ test('local in inner scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'innerInScope',
+ expectedResult: '''
(function(inScope, innerInScope) {
return innerInScope;
}.bind(this)(
@@ -431,45 +523,45 @@
0
))
''');
- });
+ });
- test('global in scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'global',
- expectedResult: r'''
+ test('global in scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'global',
+ expectedResult: '''
(function(inScope, innerInScope) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.global;
}.bind(this)(
1,
0
))
''');
- });
+ });
- test('static field in scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'staticField',
- expectedResult: r'''
+ test('static field in scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'staticField',
+ expectedResult: '''
(function(inScope, innerInScope) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField;
}.bind(this)(
1,
0
))
''');
- });
+ });
- test('field in scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'field',
- expectedResult: '''
+ test('field in scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'field',
+ expectedResult: '''
(function(inScope, innerInScope) {
return this.field;
}.bind(this)(
@@ -477,137 +569,137 @@
0
))
''');
- });
+ });
- test('local not in scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'notInScope',
- expectedError:
- "Error: The getter 'notInScope' isn't defined for the class 'C'.");
- });
+ test('local not in scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'notInScope',
+ expectedError:
+ "Error: The getter 'notInScope' isn't defined for the class 'C'.");
+ });
- test('local not in inner scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'innerNotInScope',
- expectedError:
- "Error: The getter 'innerNotInScope' isn't defined for the class 'C'.");
- });
- });
+ test('local not in inner scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'innerNotInScope',
+ expectedError:
+ "Error: The getter 'innerNotInScope' isn't defined for the class 'C'.");
+ });
+ });
- group('Expression compiler tests in extension method:', () {
- var source = '''
- ${options.dartLangComment}
- extension NumberParsing on String {
- int parseInt() {
- var ret = int.parse(this);
- /* evaluation placeholder */
- return ret;
+ group('Expression compiler tests in extension method:', () {
+ var source = '''
+ ${options.dartLangComment}
+ extension NumberParsing on String {
+ int parseInt() {
+ var ret = int.parse(this);
+ /* evaluation placeholder */
+ return ret;
+ }
}
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
+ TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'ret': '1234'},
- expression: 'typo',
- expectedError: "Error: Getter not found: 'typo'");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'ret': '1234'},
+ expression: 'typo',
+ expectedError: "Error: Getter not found: 'typo'");
+ });
- test('local (trimmed scope)', () async {
- // Test that current expression evaluation works in extension methods.
- //
- // Note: the actual scope is {#this, ret}, but #this is effectively
- // removed in the expression compilator because it does not exist
- // in JavaScript code.
- // See (full scope) tests for what will the evaluation will look like
- // when the mapping from dart symbols to JavaScipt symbols is added.
- await driver.check(
- scope: <String, String>{'ret': '1234'},
- expression: 'ret',
- expectedResult: '''
+ test('local (trimmed scope)', () async {
+ // Test that current expression evaluation works in extension methods.
+ //
+ // Note: the actual scope is {#this, ret}, but #this is effectively
+ // removed in the expression compilator because it does not exist
+ // in JavaScript code.
+ // See (full scope) tests for what will the evaluation will look like
+ // when the mapping from dart symbols to JavaScipt symbols is added.
+ await driver.check(
+ scope: <String, String>{'ret': '1234'},
+ expression: 'ret',
+ expectedResult: '''
(function(ret) {
return ret;
}(
1234
))
''');
- });
+ });
- test('local (full scope)', () async {
- // Test evalution in extension methods in the future when the mapping
- // from kernel symbols to dartdevc symbols is added.
- //
- // Note: this currently fails due to
- // - incremental compiler not allowing #this as a parameter name
- await driver.check(
- scope: <String, String>{'ret': '1234', '#this': 'this'},
- expression: 'ret',
- expectedError:
- "Illegal parameter name '#this' found during expression compilation.");
- });
+ test('local (full scope)', () async {
+ // Test evalution in extension methods in the future when the mapping
+ // from kernel symbols to dartdevc symbols is added.
+ //
+ // Note: this currently fails due to
+ // - incremental compiler not allowing #this as a parameter name
+ await driver.check(
+ scope: <String, String>{'ret': '1234', '#this': 'this'},
+ expression: 'ret',
+ expectedError:
+ "Illegal parameter name '#this' found during expression compilation.");
+ });
- test('this (full scope)', () async {
- // Test evalution in extension methods in the future when the mapping
- // from kernel symbols to dartdevc symbols is added.
- //
- // Note: this currently fails due to
- // - incremental compiler not allowing #this as a parameter name
- // - incremental compiler not mapping 'this' from user input to '#this'
- await driver.check(
- scope: <String, String>{'ret': '1234', '#this': 'this'},
- expression: 'this',
- expectedError:
- "Illegal parameter name '#this' found during expression compilation.");
- });
- });
+ test('this (full scope)', () async {
+ // Test evalution in extension methods in the future when the mapping
+ // from kernel symbols to dartdevc symbols is added.
+ //
+ // Note: this currently fails due to
+ // - incremental compiler not allowing #this as a parameter name
+ // - incremental compiler not mapping 'this' from user input to '#this'
+ await driver.check(
+ scope: <String, String>{'ret': '1234', '#this': 'this'},
+ expression: 'this',
+ expectedError:
+ "Illegal parameter name '#this' found during expression compilation.");
+ });
+ });
- group('Expression compiler tests in static function:', () {
- var source = '''
- ${options.dartLangComment}
- int foo(int x, {int y}) {
- int z = 0;
- /* evaluation placeholder */
- return x + y + z;
- }
+ group('Expression compiler tests in static function:', () {
+ var source = '''
+ ${options.dartLangComment}
+ int foo(int x, {int y}) {
+ int z = 0;
+ /* evaluation placeholder */
+ return x + y + z;
+ }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
+ TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
- expression: 'typo',
- expectedError: "Getter not found: \'typo\'");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+ expression: 'typo',
+ expectedError: "Getter not found: \'typo\'");
+ });
- test('local', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
- expression: 'x',
- expectedResult: '''
+ test('local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+ expression: 'x',
+ expectedResult: '''
(function(x, y, z) {
return x;
}(
@@ -616,13 +708,13 @@
3
))
''');
- });
+ });
- test('formal', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
- expression: 'y',
- expectedResult: '''
+ test('formal', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+ expression: 'y',
+ expectedResult: '''
(function(x, y, z) {
return y;
}(
@@ -631,13 +723,13 @@
3
))
''');
- });
+ });
- test('named formal', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
- expression: 'z',
- expectedResult: '''
+ test('named formal', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+ expression: 'z',
+ expectedResult: '''
(function(x, y, z) {
return z;
}(
@@ -646,18 +738,18 @@
3
))
''');
- });
+ });
- test('function', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
- expression: 'main',
- expectedResult: r'''
+ test('function', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+ expression: 'main',
+ expectedResult: '''
(function(x, y, z) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
var T = {
VoidTodynamic: () => (T.VoidTodynamic = dart.constFn(dart.fnType(dart.dynamic, [])))()
};
@@ -675,587 +767,590 @@
3
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in method:', () {
- var source = '''
- ${options.dartLangComment}
- extension NumberParsing on String {
- int parseInt() {
- return int.parse(this);
- }
- }
-
- int global = 42;
-
- class C {
- C(int this.field, int this._field);
-
- static int staticField = 0;
- static int _staticField = 1;
-
- int _field;
- int field;
-
- int methodFieldAccess(int x) {
- /* evaluation placeholder */
- return x + _field + _staticField;
+ group('Expression compiler tests in method:', () {
+ var source = '''
+ ${options.dartLangComment}
+ extension NumberParsing on String {
+ int parseInt() {
+ return int.parse(this);
+ }
}
- Future<int> asyncMethod(int x) async {
- return x;
+ int global = 42;
+
+ class C {
+ C(int this.field, int this._field);
+
+ static int staticField = 0;
+ static int _staticField = 1;
+
+ int _field;
+ int field;
+
+ int methodFieldAccess(int x) {
+ /* evaluation placeholder */
+ return x + _field + _staticField;
+ }
+
+ Future<int> asyncMethod(int x) async {
+ return x;
+ }
}
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
+ TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'typo',
- expectedError: "The getter 'typo' isn't defined for the class 'C'");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'typo',
+ expectedError:
+ "The getter 'typo' isn't defined for the class 'C'");
+ });
- test('local', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x',
- expectedResult: '''
+ test('local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x',
+ expectedResult: '''
(function(x) {
return x;
}.bind(this)(
1
))
''');
- });
+ });
- test('this', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'this',
- expectedResult: '''
+ test('this', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'this',
+ expectedResult: '''
(function(x) {
return this;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using locals', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + 1',
- expectedResult: '''
+ test('expression using locals', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + 1',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.notNull(x) + 1;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + staticField',
- expectedResult: r'''
+ test('expression using static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + staticField',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return dart.notNull(x) + dart.notNull(foo.C.staticField);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _staticField',
- expectedResult: r'''
+ test('expression using private static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _staticField',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return dart.notNull(x) + dart.notNull(foo.C._staticField);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + field',
- expectedResult: '''
+ test('expression using fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + field',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.notNull(x) + dart.notNull(this.field);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _field',
- expectedResult: r'''
+ test('expression using private fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _field',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return dart.notNull(x) + dart.notNull(this[S._field$1]);
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return dart.notNull(x) + dart.notNull(this[S._field\$1]);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using globals', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + global',
- expectedResult: r'''
+ test('expression using globals', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + global',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return dart.notNull(x) + dart.notNull(foo.global);
}.bind(this)(
1
))
''');
- });
+ });
- test('method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'methodFieldAccess(2)',
- expectedResult: '''
+ test('method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'methodFieldAccess(2)',
+ expectedResult: '''
(function(x) {
return this.methodFieldAccess(2);
}.bind(this)(
1
))
''');
- });
+ });
- test('async method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'asyncMethod(2)',
- expectedResult: '''
+ test('async method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'asyncMethod(2)',
+ expectedResult: '''
(function(x) {
return this.asyncMethod(2);
}.bind(this)(
1
))
''');
- });
+ });
- test('extension method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '"1234".parseInt()',
- expectedResult: r'''
+ test('extension method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '"1234".parseInt()',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo['NumberParsing|parseInt']("1234");
}.bind(this)(
1
))
''');
- });
+ });
- test('private field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_field = 2',
- expectedResult: r'''
+ test('private field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_field = 2',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return this[S._field$1] = 2;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return this[S._field\$1] = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'field = 2',
- expectedResult: '''
+ test('field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'field = 2',
+ expectedResult: '''
(function(x) {
return this.field = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('private static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_staticField = 2',
- expectedResult: r'''
+ test('private static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C._staticField = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'staticField = 2',
- expectedResult: r'''
+ test('static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField = 2;
}.bind(this)(
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in method with no field access:', () {
- var source = '''
- ${options.dartLangComment}
- extension NumberParsing on String {
- int parseInt() {
- return int.parse(this);
- }
- }
-
- int global = 42;
-
- class C {
- C(int this.field, int this._field);
-
- static int staticField = 0;
- static int _staticField = 1;
-
- int _field;
- int field;
-
- int methodNoFieldAccess(int x) {
- /* evaluation placeholder */
- return x;
+ group('Expression compiler tests in method with no field access:', () {
+ var source = '''
+ ${options.dartLangComment}
+ extension NumberParsing on String {
+ int parseInt() {
+ return int.parse(this);
+ }
}
- Future<int> asyncMethod(int x) async {
- return x;
+ int global = 42;
+
+ class C {
+ C(int this.field, int this._field);
+
+ static int staticField = 0;
+ static int _staticField = 1;
+
+ int _field;
+ int field;
+
+ int methodNoFieldAccess(int x) {
+ /* evaluation placeholder */
+ return x;
+ }
+
+ Future<int> asyncMethod(int x) async {
+ return x;
+ }
}
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'typo',
- expectedError: "The getter 'typo' isn't defined for the class 'C'");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'typo',
+ expectedError:
+ "The getter 'typo' isn't defined for the class 'C'");
+ });
- test('expression using static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + staticField',
- expectedResult: r'''
+ test('expression using static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + staticField',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return dart.notNull(x) + dart.notNull(foo.C.staticField);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _staticField',
- expectedResult: r'''
+ test('expression using private static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _staticField',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return dart.notNull(x) + dart.notNull(foo.C._staticField);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + field',
- expectedResult: '''
+ test('expression using fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + field',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.notNull(x) + dart.notNull(this.field);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _field',
- expectedResult: r'''
+ test('expression using private fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _field',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return dart.notNull(x) + dart.notNull(this[S._field$1]);
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return dart.notNull(x) + dart.notNull(this[S._field\$1]);
}.bind(this)(
1
))
''');
- });
+ });
- test('private field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_field = 2',
- expectedResult: r'''
+ test('private field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_field = 2',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return this[S._field$1] = 2;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return this[S._field\$1] = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'field = 2',
- expectedResult: '''
+ test('field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'field = 2',
+ expectedResult: '''
(function(x) {
return this.field = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('private static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_staticField = 2',
- expectedResult: r'''
+ test('private static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C._staticField = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'staticField = 2',
- expectedResult: r'''
+ test('static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField = 2;
}.bind(this)(
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in async method:', () {
- var source = '''
- ${options.dartLangComment}
- class C {
- C(int this.field, int this._field);
+ group('Expression compiler tests in async method:', () {
+ var source = '''
+ ${options.dartLangComment}
+ class C {
+ C(int this.field, int this._field);
- int _field;
- int field;
+ int _field;
+ int field;
- Future<int> asyncMethod(int x) async {
- /* evaluation placeholder */
- return x;
+ Future<int> asyncMethod(int x) async {
+ /* evaluation placeholder */
+ return x;
+ }
}
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'typo',
- expectedError: "The getter 'typo' isn't defined for the class 'C'");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'typo',
+ expectedError:
+ "The getter 'typo' isn't defined for the class 'C'");
+ });
- test('local', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x',
- expectedResult: '''
+ test('local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x',
+ expectedResult: '''
(function(x) {
return x;
}.bind(this)(
1
))
''');
- });
+ });
- test('this', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'this',
- expectedResult: '''
+ test('this', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'this',
+ expectedResult: '''
(function(x) {
return this;
}.bind(this)(
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in global function:', () {
- var source = '''
- ${options.dartLangComment}
- extension NumberParsing on String {
- int parseInt() {
- return int.parse(this);
- }
- }
-
- int global = 42;
-
- class C {
- C(int this.field, int this._field);
-
- static int staticField = 0;
- static int _staticField = 1;
-
- int _field;
- int field;
-
- int methodFieldAccess(int x) {
- return (x + _field + _staticField);
- }
- int methodFieldAccess(int x) {
- return (x)
+ group('Expression compiler tests in global function:', () {
+ var source = '''
+ ${options.dartLangComment}
+ extension NumberParsing on String {
+ int parseInt() {
+ return int.parse(this);
+ }
}
- Future<int> asyncMethod(int x) async {
- return x;
+ int global = 42;
+
+ class C {
+ C(int this.field, int this._field);
+
+ static int staticField = 0;
+ static int _staticField = 1;
+
+ int _field;
+ int field;
+
+ int methodFieldAccess(int x) {
+ return (x + _field + _staticField);
+ }
+ int methodFieldAccess(int x) {
+ return (x)
+ }
+
+ Future<int> asyncMethod(int x) async {
+ return x;
+ }
}
- }
- int main() {
- int x = 15;
- var c = C(1, 2);
- /* evaluation placeholder */
- return 0;
- }
- ''';
+ int main() {
+ int x = 15;
+ var c = C(1, 2);
+ /* evaluation placeholder */
+ return 0;
+ }
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'typo',
- expectedError: "Getter not found: 'typo'.");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'typo',
+ expectedError: "Getter not found: 'typo'.");
+ });
- test('local with primitive type', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'x',
- expectedResult: '''
+ test('local with primitive type', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'x',
+ expectedResult: '''
(function(x, c) {
return x;
}(
@@ -1263,13 +1358,13 @@
null
))
''');
- });
+ });
- test('local object', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c',
- expectedResult: '''
+ test('local object', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c',
+ expectedResult: '''
(function(x, c) {
return c;
}(
@@ -1277,71 +1372,71 @@
null
))
''');
- });
+ });
- test('create new object', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C(1,3)',
- expectedResult: r'''
+ test('create new object', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C(1,3)',
+ expectedResult: '''
(function(x, c) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return new foo.C.new(1, 3);
}(
1,
null
))
''');
- });
+ });
- test('access field of new object', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C(1,3)._field',
- expectedResult: r'''
+ test('access field of new object', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C(1,3)._field',
+ expectedResult: '''
(function(x, c) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return new foo.C.new(1, 3)[S._field$1];
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return new foo.C.new(1, 3)[S._field\$1];
}(
1,
null
))
''');
- });
+ });
- test('access static field', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C.staticField',
- expectedResult: r'''
+ test('access static field', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C.staticField',
+ expectedResult: '''
(function(x, c) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField;
}(
1,
null
))
''');
- });
+ });
- test('expression using private static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C._staticField',
- expectedError: "Error: Getter not found: '_staticField'.");
- });
+ test('expression using private static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C._staticField',
+ expectedError: "Error: Getter not found: '_staticField'.");
+ });
- test('access field', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c.field',
- expectedResult: '''
+ test('access field', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c.field',
+ expectedResult: '''
(function(x, c) {
return c.field;
}(
@@ -1349,32 +1444,32 @@
null
))
''');
- });
+ });
- test('access private field', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c._field',
- expectedResult: r'''
+ test('access private field', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c._field',
+ expectedResult: '''
(function(x, c) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return c[S._field$1];
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return c[S._field\$1];
}(
1,
null
))
''');
- });
+ });
- test('method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c.methodFieldAccess(2)',
- expectedResult: '''
+ test('method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c.methodFieldAccess(2)',
+ expectedResult: '''
(function(x, c) {
return c.methodFieldAccess(2);
}(
@@ -1382,13 +1477,13 @@
null
))
''');
- });
+ });
- test('async method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c.asyncMethod(2)',
- expectedResult: '''
+ test('async method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c.asyncMethod(2)',
+ expectedResult: '''
(function(x, c) {
return c.asyncMethod(2);
}(
@@ -1396,48 +1491,48 @@
null
))
''');
- });
+ });
- test('extension method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: '"1234".parseInt()',
- expectedResult: r'''
+ test('extension method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: '"1234".parseInt()',
+ expectedResult: '''
(function(x, c) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo['NumberParsing|parseInt']("1234");
}(
1,
null
))
''');
- });
+ });
- test('private field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c._field = 2',
- expectedResult: r'''
+ test('private field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c._field = 2',
+ expectedResult: '''
(function(x, c) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return c[S._field$1] = 2;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return c[S._field\$1] = 2;
}(
1,
null
))
''');
- });
+ });
- test('field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c.field = 2',
- expectedResult: '''
+ test('field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c.field = 2',
+ expectedResult: '''
(function(x, c) {
return c.field = 2;
}(
@@ -1445,38 +1540,38 @@
null
))
''');
- });
+ });
- test('private static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C._staticField = 2',
- expectedError: "Setter not found: '_staticField'.");
- });
+ test('private static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C._staticField = 2',
+ expectedError: "Setter not found: '_staticField'.");
+ });
- test('static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C.staticField = 2',
- expectedResult: r'''
+ test('static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C.staticField = 2',
+ expectedResult: '''
(function(x, c) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField = 2;
}(
1,
null
))
''');
- });
+ });
- test('call global function from core library', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'print(x)',
- expectedResult: '''
+ test('call global function from core library', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'print(x)',
+ expectedResult: '''
(function(x, c) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const core = dart_sdk.core;
return core.print(x);
}(
@@ -1484,54 +1579,61 @@
null
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in closures:', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- int x = 15;
- var c = C(1, 2);
+ group('Expression compiler tests in closures:', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ int x = 15;
+ var c = C(1, 2);
- var outerClosure = (int y) {
- var closureCaptureInner = (int z) {
- /* evaluation placeholder */
- print('\$y+\$z');
- };
- closureCaptureInner(0);
- };
+ var outerClosure = (int y) {
+ var closureCaptureInner = (int z) {
+ /* evaluation placeholder */
+ print('\$y+\$z');
+ };
+ closureCaptureInner(0);
+ };
- outerClosure(3);
- return 0;
- }
+ outerClosure(3);
+ return 0;
+ }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
- expression: 'typo',
- expectedError: "Getter not found: 'typo'.");
- });
+ test('compilation error', () async {
+ await driver.check(scope: <String, String>{
+ 'x': '1',
+ 'c': 'null',
+ 'y': '3',
+ 'z': '0'
+ }, expression: 'typo', expectedError: "Getter not found: 'typo'.");
+ });
- test('expression using uncaptured variables', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
- expression: r"'$x+$y+$z'",
- expectedResult: '''
+ test('expression using uncaptured variables', () async {
+ await driver.check(
+ scope: <String, String>{
+ 'x': '1',
+ 'c': 'null',
+ 'y': '3',
+ 'z': '0'
+ },
+ expression: "'\$x+\$y+\$z'",
+ expectedResult: '''
(function(x, c, y, z) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.str(x) + "+" + dart.str(y) + "+" + dart.str(z);
}(
@@ -1541,15 +1643,20 @@
0
))
''');
- });
+ });
- test('expression using captured variables', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
- expression: r"'$y+$z'",
- expectedResult: '''
+ test('expression using captured variables', () async {
+ await driver.check(
+ scope: <String, String>{
+ 'x': '1',
+ 'c': 'null',
+ 'y': '3',
+ 'z': '0'
+ },
+ expression: "'\$y+\$z'",
+ expectedResult: '''
(function(x, c, y, z) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.str(y) + "+" + dart.str(z);
}(
@@ -1559,83 +1666,83 @@
0
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in method with no type use:', () {
- var source = '''
+ group('Expression compiler tests in method with no type use:', () {
+ var source = '''
${options.dartLangComment}
- abstract class Key {
- const factory Key(String value) = ValueKey;
- const Key.empty();
- }
+ abstract class Key {
+ const factory Key(String value) = ValueKey;
+ const Key.empty();
+ }
- abstract class LocalKey extends Key {
- const LocalKey() : super.empty();
- }
+ abstract class LocalKey extends Key {
+ const LocalKey() : super.empty();
+ }
- class ValueKey implements LocalKey {
- const ValueKey(this.value);
- final String value;
- }
+ class ValueKey implements LocalKey {
+ const ValueKey(this.value);
+ final String value;
+ }
- class MyClass {
- const MyClass(this._t);
- final int _t;
- }
+ class MyClass {
+ const MyClass(this._t);
+ final int _t;
+ }
- int bar(int p){
- return p;
- }
- int baz(String t){
- return t;
- }
- void main() {
- var k = Key('t');
- MyClass c = MyClass(0);
- int p = 1;
- const t = 1;
+ int bar(int p){
+ return p;
+ }
+ int baz(String t){
+ return t;
+ }
+ void main() {
+ var k = Key('t');
+ MyClass c = MyClass(0);
+ int p = 1;
+ const t = 1;
- /* evaluation placeholder */
- print('\$c, \$k, \$t');
- }
- ''';
+ /* evaluation placeholder */
+ print('\$c, \$k, \$t');
+ }
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('call function not using type', () async {
- await driver.check(
- scope: <String, String>{'p': '1'},
- expression: 'bar(p)',
- expectedResult: r'''
+ test('call function not using type', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: 'bar(p)',
+ expectedResult: '''
(function(p) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.bar(p);
}(
1
))
''');
- });
+ });
- test('call function using type', () async {
- await driver.check(
- scope: <String, String>{'p': '0'},
- expression: 'baz(p as String)',
- expectedResult: r'''
+ test('call function using type', () async {
+ await driver.check(
+ scope: <String, String>{'p': '0'},
+ expression: 'baz(p as String)',
+ expectedResult: '''
(function(p) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const core = dart_sdk.core;
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
var T = {
StringL: () => (T.StringL = dart.constFn(dart.legacy(core.String)))()
};
@@ -1644,18 +1751,18 @@
0
))
''');
- });
+ });
- test('evaluate new const expression', () async {
- await driver.check(
- scope: <String, String>{'p': '1'},
- expression: 'const MyClass(1)',
- expectedResult: r'''
+ test('evaluate new const expression', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: 'const MyClass(1)',
+ expectedResult: '''
(function(p) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
var S = {MyClass__t: dart.privateName(foo, "MyClass._t")};
const CT = Object.create(null);
dart.defineLazy(CT, {
@@ -1672,47 +1779,47 @@
1
))
''');
- });
+ });
- test('evaluate optimized const expression', () async {
- await driver.check(
- scope: <String, String>{},
- expression: 't',
- expectedResult: '''
+ test('evaluate optimized const expression', () async {
+ await driver.check(
+ scope: <String, String>{},
+ expression: 't',
+ expectedResult: '''
(function() {
return 1;
}(
))
''');
- },
- skip: 'Cannot compile constants optimized away by the frontend. '
- 'Issue: https://github.com/dart-lang/sdk/issues/41999');
+ },
+ skip: 'Cannot compile constants optimized away by the frontend. '
+ 'Issue: https://github.com/dart-lang/sdk/issues/41999');
- test('evaluate factory constructor call', () async {
- await driver.check(
- scope: <String, String>{'p': '1'},
- expression: "Key('t')",
- expectedResult: r'''
+ test('evaluate factory constructor call', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: "Key('t')",
+ expectedResult: '''
(function(p) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return new foo.ValueKey.new("t");
}(
1
))
''');
- });
+ });
- test('evaluate const factory constructor call', () async {
- await driver.check(
- scope: <String, String>{'p': '1'},
- expression: "const Key('t')",
- expectedResult: r'''
+ test('evaluate const factory constructor call', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: "const Key('t')",
+ expectedResult: '''
(function(p) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
var S = {ValueKey_value: dart.privateName(foo, "ValueKey.value")};
const CT = Object.create(null);
dart.defineLazy(CT, {
@@ -1729,321 +1836,322 @@
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in constructor:', () {
- var source = '''
- ${options.dartLangComment}
- extension NumberParsing on String {
- int parseInt() {
- return int.parse(this);
- }
- }
-
- int global = 42;
-
- class C {
- C(int this.field, int this._field) {
- int x = 1;
- /* evaluation placeholder */
- print(this.field);
+ group('Expression compiler tests in constructor:', () {
+ var source = '''
+ ${options.dartLangComment}
+ extension NumberParsing on String {
+ int parseInt() {
+ return int.parse(this);
+ }
}
- static int staticField = 0;
- static int _staticField = 1;
+ int global = 42;
- int _field;
- int field;
+ class C {
+ C(int this.field, int this._field) {
+ int x = 1;
+ /* evaluation placeholder */
+ print(this.field);
+ }
- int methodFieldAccess(int t) {
- return t + _field + _staticField;
+ static int staticField = 0;
+ static int _staticField = 1;
+
+ int _field;
+ int field;
+
+ int methodFieldAccess(int t) {
+ return t + _field + _staticField;
+ }
+
+ Future<int> asyncMethod(int t) async {
+ return t;
+ }
}
- Future<int> asyncMethod(int t) async {
- return t;
- }
- }
+ main() => 0;
+ ''';
- main() => 0;
- ''';
+ TestDriver driver;
- TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- setUp(() {
- driver = TestDriver(options, source);
- });
+ tearDown(() {
+ driver.delete();
+ });
- tearDown(() {
- driver.delete();
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'typo',
+ expectedError:
+ "The getter 'typo' isn't defined for the class 'C'");
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'typo',
- expectedError: "The getter 'typo' isn't defined for the class 'C'");
- });
-
- test('local', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x',
- expectedResult: '''
+ test('local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x',
+ expectedResult: '''
(function(x) {
return x;
}.bind(this)(
1
))
''');
- });
+ });
- test('this', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'this',
- expectedResult: '''
+ test('this', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'this',
+ expectedResult: '''
(function(x) {
return this;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using locals', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + 1',
- expectedResult: '''
+ test('expression using locals', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + 1',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.notNull(x) + 1;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + staticField',
- expectedResult: r'''
+ test('expression using static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + staticField',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return dart.notNull(x) + dart.notNull(foo.C.staticField);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _staticField',
- expectedResult: r'''
+ test('expression using private static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _staticField',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return dart.notNull(x) + dart.notNull(foo.C._staticField);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + field',
- expectedResult: '''
+ test('expression using fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + field',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.notNull(x) + dart.notNull(this.field);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _field',
- expectedResult: r'''
+ test('expression using private fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _field',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return dart.notNull(x) + dart.notNull(this[S._field$1]);
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return dart.notNull(x) + dart.notNull(this[S._field\$1]);
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using globals', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + global',
- expectedResult: r'''
+ test('expression using globals', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + global',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return dart.notNull(x) + dart.notNull(foo.global);
}.bind(this)(
1
))
''');
- });
+ });
- test('method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'methodFieldAccess(2)',
- expectedResult: '''
+ test('method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'methodFieldAccess(2)',
+ expectedResult: '''
(function(x) {
return this.methodFieldAccess(2);
}.bind(this)(
1
))
''');
- });
+ });
- test('async method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'asyncMethod(2)',
- expectedResult: '''
+ test('async method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'asyncMethod(2)',
+ expectedResult: '''
(function(x) {
return this.asyncMethod(2);
}.bind(this)(
1
))
''');
- });
+ });
- test('extension method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '"1234".parseInt()',
- expectedResult: r'''
+ test('extension method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '"1234".parseInt()',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo['NumberParsing|parseInt']("1234");
}.bind(this)(
1
))
''');
- });
+ });
- test('private field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_field = 2',
- expectedResult: r'''
+ test('private field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_field = 2',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return this[S._field$1] = 2;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return this[S._field\$1] = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'field = 2',
- expectedResult: '''
+ test('field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'field = 2',
+ expectedResult: '''
(function(x) {
return this.field = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('private static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_staticField = 2',
- expectedResult: r'''
+ test('private static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C._staticField = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'staticField = 2',
- expectedResult: r'''
+ test('static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField = 2;
}.bind(this)(
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in simple loops:', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- int x = 15;
- var c = C(1, 2);
+ group('Expression compiler tests in simple loops:', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ int x = 15;
+ var c = C(1, 2);
- for(int i = 0; i < 10; i++) {
- /* evaluation placeholder */
- print('\$i+\$x');
- };
- return 0;
- }
+ for(int i = 0; i < 10; i++) {
+ /* evaluation placeholder */
+ print('\$i+\$x');
+ };
+ return 0;
+ }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('expression using local', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
- expression: 'x',
- expectedResult: '''
+ test('expression using local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
+ expression: 'x',
+ expectedResult: '''
(function(x, c, i) {
return x;
}(
@@ -2052,13 +2160,13 @@
0
))
''');
- });
+ });
- test('expression using loop variable', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
- expression: 'i',
- expectedResult: '''
+ test('expression using loop variable', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
+ expression: 'i',
+ expectedResult: '''
(function(x, c, i) {
return i;
}(
@@ -2067,39 +2175,39 @@
0
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in iterator loops:', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- var l = <String>['1', '2', '3'];
+ group('Expression compiler tests in iterator loops:', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ var l = <String>['1', '2', '3'];
- for(var e in l) {
- /* evaluation placeholder */
- print(e);
- };
- return 0;
- }
+ for(var e in l) {
+ /* evaluation placeholder */
+ print(e);
+ };
+ return 0;
+ }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('expression loop variable', () async {
- await driver.check(
- scope: <String, String>{'l': 'null', 'e': '1'},
- expression: 'e',
- expectedResult: '''
+ test('expression loop variable', () async {
+ await driver.check(
+ scope: <String, String>{'l': 'null', 'e': '1'},
+ expression: 'e',
+ expectedResult: '''
(function(l, e) {
return e;
}(
@@ -2107,44 +2215,44 @@
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in conditional (then):', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- int x = 1;
- var c = C(1, 2);
+ group('Expression compiler tests in conditional (then):', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ int x = 1;
+ var c = C(1, 2);
- if (x == 14) {
- int y = 3;
- /* evaluation placeholder */
- print('\$y+\$x');
- } else {
- int z = 3;
- print('\$z+\$x');
+ if (x == 14) {
+ int y = 3;
+ /* evaluation placeholder */
+ print('\$y+\$x');
+ } else {
+ int z = 3;
+ print('\$z+\$x');
+ }
+ return 0;
}
- return 0;
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('expression using local', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
- expression: 'y',
- expectedResult: '''
+ test('expression using local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
+ expression: 'y',
+ expectedResult: '''
(function(x, c, y) {
return y;
}(
@@ -2153,51 +2261,51 @@
3
))
''');
- });
+ });
- test('expression using local out of scope', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
- expression: 'z',
- expectedError: "Error: Getter not found: 'z'");
- });
- });
+ test('expression using local out of scope', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
+ expression: 'z',
+ expectedError: "Error: Getter not found: 'z'");
+ });
+ });
- group('Expression compiler tests in conditional (else):', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- int x = 1;
- var c = C(1, 2);
+ group('Expression compiler tests in conditional (else):', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ int x = 1;
+ var c = C(1, 2);
- if (x == 14) {
- int y = 3;
- print('\$y+\$x');
- } else {
- int z = 3;
- /* evaluation placeholder */
- print('\$z+\$x');
+ if (x == 14) {
+ int y = 3;
+ print('\$y+\$x');
+ } else {
+ int z = 3;
+ /* evaluation placeholder */
+ print('\$z+\$x');
+ }
+ return 0;
}
- return 0;
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('expression using local', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
- expression: 'z',
- expectedResult: '''
+ test('expression using local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
+ expression: 'z',
+ expectedResult: '''
(function(x, c, z) {
return z;
}(
@@ -2206,51 +2314,51 @@
3
))
''');
- });
+ });
- test('expression using local out of scope', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
- expression: 'y',
- expectedError: "Error: Getter not found: 'y'");
- });
- });
+ test('expression using local out of scope', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
+ expression: 'y',
+ expectedError: "Error: Getter not found: 'y'");
+ });
+ });
- group('Expression compiler tests after conditionals:', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- int x = 1;
- var c = C(1, 2);
+ group('Expression compiler tests after conditionals:', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ int x = 1;
+ var c = C(1, 2);
- if (x == 14) {
- int y = 3;
- print('\$y+\$x');
- } else {
- int z = 3;
- print('\$z+\$x');
- }
- /* evaluation placeholder */
- return 0;
- }
+ if (x == 14) {
+ int y = 3;
+ print('\$y+\$x');
+ } else {
+ int z = 3;
+ print('\$z+\$x');
+ }
+ /* evaluation placeholder */
+ return 0;
+ }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('expression using local', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'x',
- expectedResult: '''
+ test('expression using local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'x',
+ expectedResult: '''
(function(x, c) {
return x;
}(
@@ -2258,53 +2366,55 @@
null
))
''');
- });
+ });
- test('expression using local out of scope', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'z',
- expectedError: "Error: Getter not found: 'z'");
- });
- });
+ test('expression using local out of scope', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'z',
+ expectedError: "Error: Getter not found: 'z'");
+ });
+ });
- group('Expression compiler tests for interactions with module containers:',
- () {
- var source = '''
- ${options.dartLangComment}
- class A {
- const A();
- }
- class B {
- const B();
- }
- void foo() {
- const a = A();
- var check = a is int;
- /* evaluation placeholder */
- return;
- }
+ group(
+ 'Expression compiler tests for interactions with module containers:',
+ () {
+ var source = '''
+ ${options.dartLangComment}
+ class A {
+ const A();
+ }
+ class B {
+ const B();
+ }
+ void foo() {
+ const a = A();
+ var check = a is int;
+ /* evaluation placeholder */
+ return;
+ }
- void main() => foo();
- ''';
+ void main() => foo();
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('evaluation that non-destructively appends to the type container',
- () async {
- await driver.check(
- scope: <String, String>{'a': 'null', 'check': 'null'},
- expression: 'a is String',
- expectedResult: r'''
+ test(
+ 'evaluation that non-destructively appends to the type container',
+ () async {
+ await driver.check(
+ scope: <String, String>{'a': 'null', 'check': 'null'},
+ expression: 'a is String',
+ expectedResult: '''
(function(a, check) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const core = dart_sdk.core;
const dart = dart_sdk.dart;
var T = {
@@ -2316,15 +2426,15 @@
null
))
''');
- });
+ });
- test('evaluation that reuses the type container', () async {
- await driver.check(
- scope: <String, String>{'a': 'null', 'check': 'null'},
- expression: 'a is int',
- expectedResult: r'''
+ test('evaluation that reuses the type container', () async {
+ await driver.check(
+ scope: <String, String>{'a': 'null', 'check': 'null'},
+ expression: 'a is int',
+ expectedResult: '''
(function(a, check) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const core = dart_sdk.core;
const dart = dart_sdk.dart;
var T = {
@@ -2336,20 +2446,20 @@
null
))
''');
- });
+ });
- test(
- 'evaluation that non-destructively appends to the constant container',
- () async {
- await driver.check(
- scope: <String, String>{'a': 'null', 'check': 'null'},
- expression: 'const B()',
- expectedResult: r'''
+ test(
+ 'evaluation that non-destructively appends to the constant container',
+ () async {
+ await driver.check(
+ scope: <String, String>{'a': 'null', 'check': 'null'},
+ expression: 'const B()',
+ expectedResult: '''
(function(a, check) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
const CT = Object.create(null);
dart.defineLazy(CT, {
get C0() {
@@ -2365,20 +2475,20 @@
null
))
''');
- });
+ });
- test(
- 'evaluation that reuses the constant container and canonicalizes properly',
- () async {
- await driver.check(
- scope: <String, String>{'a': 'null', 'check': 'null'},
- expression: 'a == const A()',
- expectedResult: r'''
+ test(
+ 'evaluation that reuses the constant container and canonicalizes properly',
+ () async {
+ await driver.check(
+ scope: <String, String>{'a': 'null', 'check': 'null'},
+ expression: 'a == const A()',
+ expectedResult: '''
(function(a, check) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
const CT = Object.create(null);
dart.defineLazy(CT, {
get C0() {
@@ -2394,42 +2504,42 @@
null
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in generic method:', () {
- var source = '''
- ${options.dartLangComment}
- class A {
- void generic<TType, KType>(TType a, KType b) {
- /* evaluation placeholder */
- print(a);
- print(b);
+ group('Expression compiler tests in generic method:', () {
+ var source = '''
+ ${options.dartLangComment}
+ class A {
+ void generic<TType, KType>(TType a, KType b) {
+ /* evaluation placeholder */
+ print(a);
+ print(b);
+ }
}
- }
- void main() => generic<int, String>(0, 'hi');
- ''';
+ void main() => generic<int, String>(0, 'hi');
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('evaluate formals', () async {
- await driver.check(
- scope: <String, String>{
- 'TType': 'TType',
- 'KType': 'KType',
- 'a': 'a',
- 'b': 'b'
- },
- expression: 'a',
- expectedResult: '''
+ test('evaluate formals', () async {
+ await driver.check(
+ scope: <String, String>{
+ 'TType': 'TType',
+ 'KType': 'KType',
+ 'a': 'a',
+ 'b': 'b'
+ },
+ expression: 'a',
+ expectedResult: '''
(function(TType, KType, a, b) {
return a;
}.bind(this)(
@@ -2439,20 +2549,20 @@
b
))
''');
- });
+ });
- test('evaluate type parameters', () async {
- await driver.check(
- scope: <String, String>{
- 'TType': 'TType',
- 'KType': 'KType',
- 'a': 'a',
- 'b': 'b'
- },
- expression: 'TType',
- expectedResult: '''
+ test('evaluate type parameters', () async {
+ await driver.check(
+ scope: <String, String>{
+ 'TType': 'TType',
+ 'KType': 'KType',
+ 'a': 'a',
+ 'b': 'b'
+ },
+ expression: 'TType',
+ expectedResult: '''
(function(TType, KType, a, b) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.wrapType(dart.legacy(TType));
}.bind(this)(
@@ -2462,156 +2572,237 @@
b
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests using extension symbols', () {
- var source = '''
- ${options.dartLangComment}
- void bar() {
- /* evaluation placeholder */
- }
+ group('Expression compiler tests using extension symbols', () {
+ var source = '''
+ ${options.dartLangComment}
+ void bar() {
+ /* evaluation placeholder */
+ }
- void main() => bar();
- ''';
+ void main() => bar();
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('map access', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression:
- '(Map<String, String> params) { return params["index"]; }({})',
- expectedResult: r'''
+ test('map access', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression:
+ '(Map<String, String> params) { return params["index"]; }({})',
+ expectedResult: '''
(function() {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const core = dart_sdk.core;
const _js_helper = dart_sdk._js_helper;
const dart = dart_sdk.dart;
const dartx = dart_sdk.dartx;
var T = {
StringL: () => (T.StringL = dart.constFn(dart.legacy(core.String)))(),
- MapOfStringL$StringL: () => (T.MapOfStringL$StringL = dart.constFn(core.Map$(T.StringL(), T.StringL())))(),
- MapLOfStringL$StringL: () => (T.MapLOfStringL$StringL = dart.constFn(dart.legacy(T.MapOfStringL$StringL())))(),
- MapLOfStringL$StringLToStringL: () => (T.MapLOfStringL$StringLToStringL = dart.constFn(dart.fnType(T.StringL(), [T.MapLOfStringL$StringL()])))(),
- IdentityMapOfStringL$StringL: () => (T.IdentityMapOfStringL$StringL = dart.constFn(_js_helper.IdentityMap$(T.StringL(), T.StringL())))()
+ MapOfStringL\$StringL: () => (T.MapOfStringL\$StringL = dart.constFn(core.Map\$(T.StringL(), T.StringL())))(),
+ MapLOfStringL\$StringL: () => (T.MapLOfStringL\$StringL = dart.constFn(dart.legacy(T.MapOfStringL\$StringL())))(),
+ MapLOfStringL\$StringLToStringL: () => (T.MapLOfStringL\$StringLToStringL = dart.constFn(dart.fnType(T.StringL(), [T.MapLOfStringL\$StringL()])))(),
+ IdentityMapOfStringL\$StringL: () => (T.IdentityMapOfStringL\$StringL = dart.constFn(_js_helper.IdentityMap\$(T.StringL(), T.StringL())))()
};
- var S = {$_get: dartx._get};
- return dart.fn(params => params[S.$_get]("index"), T.MapLOfStringL$StringLToStringL())(new (T.IdentityMapOfStringL$StringL()).new());
+ var S = {\$_get: dartx._get};
+ return dart.fn(params => params[S.\$_get]("index"), T.MapLOfStringL\$StringLToStringL())(new (T.IdentityMapOfStringL\$StringL()).new());
}(
))
''');
+ });
+ });
});
});
- });
+ }
- group('Sound null safety:', () {
- var options = SetupCompilerOptions(soundNullSafety: true);
+ for (var moduleFormat in [ModuleFormat.amd, ModuleFormat.ddc]) {
+ group('Module format: $moduleFormat', () {
+ group('Sound null safety:', () {
+ var options = SetupCompilerOptions(soundNullSafety: true);
- group('Expression compiler extension symbols tests', () {
- var source = '''
- ${options.dartLangComment}
-
- main() {
- List<int> list = {};
- list.add(0);
- /* evaluation placeholder */
- }
- ''';
-
- TestDriver driver;
-
- setUp(() {
- driver = TestDriver(options, source);
- });
-
- tearDown(() {
- driver.delete();
- });
-
- test('extension symbol used in original compilation', () async {
- await driver.check(
- scope: <String, String>{'list': 'list'},
- expression: 'list.add(1)',
- expectedResult: r'''
- (function(list) {
- const dart_sdk = require('dart_sdk');
- const dartx = dart_sdk.dartx;
- var $add = dartx.add;
- var S = {$add: dartx.add};
- return list[$add](1);
- }(
- list
- ))
- ''');
- });
-
- test('extension symbol used only in expression compilation', () async {
- await driver.check(
- scope: <String, String>{'list': 'list'},
- expression: 'list.first',
- expectedResult: r'''
- (function(list) {
- const dart_sdk = require('dart_sdk');
- const dartx = dart_sdk.dartx;
- var S = {$first: dartx.first};
- return list[S.$first];
- }(
- list
- ))
- ''');
- });
- });
-
- group('Expression compiler scope collection tests', () {
- var source = '''
- ${options.dartLangComment}
-
- class C {
- C(int this.field);
-
- int methodFieldAccess(int x) {
- var inScope = 1;
- {
- var innerInScope = global + staticField + field;
- /* evaluation placeholder */
- print(innerInScope);
- var innerNotInScope = 2;
- }
- var notInScope = 3;
+ group('Expression compiler import tests', () {
+ var source = '''
+ ${options.dartLangComment}
+ import 'dart:io' show Directory;
+ import 'dart:io' as p;
+ import 'dart:convert' as p;
+
+ main() {
+ print(Directory.systemTemp);
+ print(p.Directory.systemTemp);
+ print(p.utf.decoder);
}
- static int staticField = 0;
- int field;
- }
+ void foo() {
+ /* evaluation placeholder */
+ }
+ ''';
- int global = 42;
- main() => 0;
- ''';
+ TestDriver driver;
- TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- setUp(() {
- driver = TestDriver(options, source);
- });
+ tearDown(() {
+ driver.delete();
+ });
- tearDown(() {
- driver.delete();
- });
+ test('expression referencing unnamed import', () async {
+ await driver.check(
+ scope: <String, String>{},
+ expression: 'Directory.systemTemp',
+ expectedResult: '''
+ (function() {
+ const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+ const io = dart_sdk.io;
+ return io.Directory.systemTemp;
+ }(
+
+ ))
+ ''');
+ });
- test('local in scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'inScope',
- expectedResult: '''
+ test('expression referencing named import', () async {
+ await driver.check(
+ scope: <String, String>{},
+ expression: 'p.Directory.systemTemp',
+ expectedResult: '''
+ (function() {
+ const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+ const io = dart_sdk.io;
+ return io.Directory.systemTemp;
+ }(
+
+ ))
+ ''');
+ });
+
+ test(
+ 'expression referencing another library with the same named import',
+ () async {
+ await driver.check(
+ scope: <String, String>{},
+ expression: 'p.utf8.decoder',
+ expectedResult: '''
+ (function() {
+ const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+ const convert = dart_sdk.convert;
+ return convert.utf8.decoder;
+ }(
+
+ ))
+ ''');
+ });
+ });
+
+ group('Expression compiler extension symbols tests', () {
+ var source = '''
+ ${options.dartLangComment}
+
+ main() {
+ List<int> list = {};
+ list.add(0);
+ /* evaluation placeholder */
+ }
+ ''';
+
+ TestDriver driver;
+
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
+
+ tearDown(() {
+ driver.delete();
+ });
+
+ test('extension symbol used in original compilation', () async {
+ await driver.check(
+ scope: <String, String>{'list': 'list'},
+ expression: 'list.add(1)',
+ expectedResult: '''
+ (function(list) {
+ const dart_sdk = ${options.loadModule}('dart_sdk');
+ const dartx = dart_sdk.dartx;
+ var \$add = dartx.add;
+ var S = {\$add: dartx.add};
+ return list[\$add](1);
+ }(
+ list
+ ))
+ ''');
+ });
+
+ test('extension symbol used only in expression compilation',
+ () async {
+ await driver.check(
+ scope: <String, String>{'list': 'list'},
+ expression: 'list.first',
+ expectedResult: '''
+ (function(list) {
+ const dart_sdk = ${options.loadModule}('dart_sdk');
+ const dartx = dart_sdk.dartx;
+ var S = {\$first: dartx.first};
+ return list[S.\$first];
+ }(
+ list
+ ))
+ ''');
+ });
+ });
+
+ group('Expression compiler scope collection tests', () {
+ var source = '''
+ ${options.dartLangComment}
+
+ class C {
+ C(int this.field);
+
+ int methodFieldAccess(int x) {
+ var inScope = 1;
+ {
+ var innerInScope = global + staticField + field;
+ /* evaluation placeholder */
+ print(innerInScope);
+ var innerNotInScope = 2;
+ }
+ var notInScope = 3;
+ }
+
+ static int staticField = 0;
+ int field;
+ }
+
+ int global = 42;
+ main() => 0;
+ ''';
+
+ TestDriver driver;
+
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
+
+ tearDown(() {
+ driver.delete();
+ });
+
+ test('local in scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'inScope',
+ expectedResult: '''
(function(inScope, innerInScope) {
return inScope;
}.bind(this)(
@@ -2619,13 +2810,13 @@
0
))
''');
- });
+ });
- test('local in inner scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'innerInScope',
- expectedResult: '''
+ test('local in inner scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'innerInScope',
+ expectedResult: '''
(function(inScope, innerInScope) {
return innerInScope;
}.bind(this)(
@@ -2633,45 +2824,45 @@
0
))
''');
- });
+ });
- test('global in scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'global',
- expectedResult: r'''
+ test('global in scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'global',
+ expectedResult: '''
(function(inScope, innerInScope) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.global;
}.bind(this)(
1,
0
))
''');
- });
+ });
- test('static field in scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'staticField',
- expectedResult: r'''
+ test('static field in scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'staticField',
+ expectedResult: '''
(function(inScope, innerInScope) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField;
}.bind(this)(
1,
0
))
''');
- });
+ });
- test('field in scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'field',
- expectedResult: '''
+ test('field in scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'field',
+ expectedResult: '''
(function(inScope, innerInScope) {
return this.field;
}.bind(this)(
@@ -2679,137 +2870,137 @@
0
))
''');
- });
+ });
- test('local not in scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'notInScope',
- expectedError:
- "Error: The getter 'notInScope' isn't defined for the class 'C'.");
- });
+ test('local not in scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'notInScope',
+ expectedError:
+ "Error: The getter 'notInScope' isn't defined for the class 'C'.");
+ });
- test('local not in inner scope', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression: 'innerNotInScope',
- expectedError:
- "Error: The getter 'innerNotInScope' isn't defined for the class 'C'.");
- });
- });
+ test('local not in inner scope', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression: 'innerNotInScope',
+ expectedError:
+ "Error: The getter 'innerNotInScope' isn't defined for the class 'C'.");
+ });
+ });
- group('Expression compiler tests in extension method:', () {
- var source = '''
- ${options.dartLangComment}
- extension NumberParsing on String {
- int parseInt() {
- var ret = int.parse(this);
- /* evaluation placeholder */
- return ret;
+ group('Expression compiler tests in extension method:', () {
+ var source = '''
+ ${options.dartLangComment}
+ extension NumberParsing on String {
+ int parseInt() {
+ var ret = int.parse(this);
+ /* evaluation placeholder */
+ return ret;
+ }
}
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
+ TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'ret': '1234'},
- expression: 'typo',
- expectedError: "Error: Getter not found: 'typo'");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'ret': '1234'},
+ expression: 'typo',
+ expectedError: "Error: Getter not found: 'typo'");
+ });
- test('local (trimmed scope)', () async {
- // Test that current expression evaluation works in extension methods.
- //
- // Note: the actual scope is {#this, ret}, but #this is effectively
- // removed in the expression compilator because it does not exist
- // in JavaScript code.
- // See (full scope) tests for what will the evaluation will look like
- // when the mapping from dart symbols to JavaScipt symbols is added.
- await driver.check(
- scope: <String, String>{'ret': '1234'},
- expression: 'ret',
- expectedResult: '''
+ test('local (trimmed scope)', () async {
+ // Test that current expression evaluation works in extension methods.
+ //
+ // Note: the actual scope is {#this, ret}, but #this is effectively
+ // removed in the expression compilator because it does not exist
+ // in JavaScript code.
+ // See (full scope) tests for what will the evaluation will look like
+ // when the mapping from dart symbols to JavaScipt symbols is added.
+ await driver.check(
+ scope: <String, String>{'ret': '1234'},
+ expression: 'ret',
+ expectedResult: '''
(function(ret) {
return ret;
}(
1234
))
''');
- });
+ });
- test('local (full scope)', () async {
- // Test evalution in extension methods in the future when the mapping
- // from kernel symbols to dartdevc symbols is added.
- //
- // Note: this currently fails due to
- // - incremental compiler not allowing #this as a parameter name
- await driver.check(
- scope: <String, String>{'ret': '1234', '#this': 'this'},
- expression: 'ret',
- expectedError:
- "Illegal parameter name '#this' found during expression compilation.");
- });
+ test('local (full scope)', () async {
+ // Test evalution in extension methods in the future when the mapping
+ // from kernel symbols to dartdevc symbols is added.
+ //
+ // Note: this currently fails due to
+ // - incremental compiler not allowing #this as a parameter name
+ await driver.check(
+ scope: <String, String>{'ret': '1234', '#this': 'this'},
+ expression: 'ret',
+ expectedError:
+ "Illegal parameter name '#this' found during expression compilation.");
+ });
- test('this (full scope)', () async {
- // Test evalution in extension methods in the future when the mapping
- // from kernel symbols to dartdevc symbols is added.
- //
- // Note: this currently fails due to
- // - incremental compiler not allowing #this as a parameter name
- // - incremental compiler not mapping 'this' from user input to '#this'
- await driver.check(
- scope: <String, String>{'ret': '1234', '#this': 'this'},
- expression: 'this',
- expectedError:
- "Illegal parameter name '#this' found during expression compilation.");
- });
- });
+ test('this (full scope)', () async {
+ // Test evalution in extension methods in the future when the mapping
+ // from kernel symbols to dartdevc symbols is added.
+ //
+ // Note: this currently fails due to
+ // - incremental compiler not allowing #this as a parameter name
+ // - incremental compiler not mapping 'this' from user input to '#this'
+ await driver.check(
+ scope: <String, String>{'ret': '1234', '#this': 'this'},
+ expression: 'this',
+ expectedError:
+ "Illegal parameter name '#this' found during expression compilation.");
+ });
+ });
- group('Expression compiler tests in static function:', () {
- var source = '''
- ${options.dartLangComment}
- int foo(int x, {int y}) {
- int z = 0;
- /* evaluation placeholder */
- return x + y + z;
- }
+ group('Expression compiler tests in static function:', () {
+ var source = '''
+ ${options.dartLangComment}
+ int foo(int x, {int y}) {
+ int z = 0;
+ /* evaluation placeholder */
+ return x + y + z;
+ }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
+ TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
- expression: 'typo',
- expectedError: "Getter not found: \'typo\'");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+ expression: 'typo',
+ expectedError: "Getter not found: \'typo\'");
+ });
- test('local', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
- expression: 'x',
- expectedResult: '''
+ test('local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+ expression: 'x',
+ expectedResult: '''
(function(x, y, z) {
return x;
}(
@@ -2818,13 +3009,13 @@
3
))
''');
- });
+ });
- test('formal', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
- expression: 'y',
- expectedResult: '''
+ test('formal', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+ expression: 'y',
+ expectedResult: '''
(function(x, y, z) {
return y;
}(
@@ -2833,13 +3024,13 @@
3
))
''');
- });
+ });
- test('named formal', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
- expression: 'z',
- expectedResult: '''
+ test('named formal', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+ expression: 'z',
+ expectedResult: '''
(function(x, y, z) {
return z;
}(
@@ -2848,18 +3039,18 @@
3
))
''');
- });
+ });
- test('function', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
- expression: 'main',
- expectedResult: r'''
+ test('function', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
+ expression: 'main',
+ expectedResult: '''
(function(x, y, z) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
var T = {
VoidTodynamic: () => (T.VoidTodynamic = dart.constFn(dart.fnType(dart.dynamic, [])))()
};
@@ -2877,571 +3068,574 @@
3
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in method:', () {
- var source = '''
- ${options.dartLangComment}
- extension NumberParsing on String {
- int parseInt() {
- return int.parse(this);
- }
- }
-
- int global = 42;
-
- class C {
- C(int this.field, int this._field);
-
- static int staticField = 0;
- static int _staticField = 1;
-
- int _field;
- int field;
-
- int methodFieldAccess(int x) {
- /* evaluation placeholder */
- return x + _field + _staticField;
+ group('Expression compiler tests in method:', () {
+ var source = '''
+ ${options.dartLangComment}
+ extension NumberParsing on String {
+ int parseInt() {
+ return int.parse(this);
+ }
}
- Future<int> asyncMethod(int x) async {
- return x;
+ int global = 42;
+
+ class C {
+ C(int this.field, int this._field);
+
+ static int staticField = 0;
+ static int _staticField = 1;
+
+ int _field;
+ int field;
+
+ int methodFieldAccess(int x) {
+ /* evaluation placeholder */
+ return x + _field + _staticField;
+ }
+
+ Future<int> asyncMethod(int x) async {
+ return x;
+ }
}
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
+ TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'typo',
- expectedError: "The getter 'typo' isn't defined for the class 'C'");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'typo',
+ expectedError:
+ "The getter 'typo' isn't defined for the class 'C'");
+ });
- test('local', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x',
- expectedResult: '''
+ test('local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x',
+ expectedResult: '''
(function(x) {
return x;
}.bind(this)(
1
))
''');
- });
+ });
- test('this', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'this',
- expectedResult: '''
+ test('this', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'this',
+ expectedResult: '''
(function(x) {
return this;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using locals', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + 1',
- expectedResult: '''
+ test('expression using locals', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + 1',
+ expectedResult: '''
(function(x) {
return x + 1;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + staticField',
- expectedResult: r'''
+ test('expression using static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + staticField',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return x + foo.C.staticField;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _staticField',
- expectedResult: r'''
+ test('expression using private static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _staticField',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return x + foo.C._staticField;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + field',
- expectedResult: '''
+ test('expression using fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + field',
+ expectedResult: '''
(function(x) {
return x + this.field;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _field',
- expectedResult: r'''
+ test('expression using private fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _field',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return x + this[S._field$1];
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return x + this[S._field\$1];
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using globals', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + global',
- expectedResult: r'''
+ test('expression using globals', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + global',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return x + foo.global;
}.bind(this)(
1
))
''');
- });
+ });
- test('method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'methodFieldAccess(2)',
- expectedResult: '''
+ test('method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'methodFieldAccess(2)',
+ expectedResult: '''
(function(x) {
return this.methodFieldAccess(2);
}.bind(this)(
1
))
''');
- });
+ });
- test('async method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'asyncMethod(2)',
- expectedResult: '''
+ test('async method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'asyncMethod(2)',
+ expectedResult: '''
(function(x) {
return this.asyncMethod(2);
}.bind(this)(
1
))
''');
- });
+ });
- test('extension method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '"1234".parseInt()',
- expectedResult: r'''
+ test('extension method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '"1234".parseInt()',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo['NumberParsing|parseInt']("1234");
}.bind(this)(
1
))
''');
- });
+ });
- test('private field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_field = 2',
- expectedResult: r'''
+ test('private field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_field = 2',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return this[S._field$1] = 2;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return this[S._field\$1] = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'field = 2',
- expectedResult: '''
+ test('field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'field = 2',
+ expectedResult: '''
(function(x) {
return this.field = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('private static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_staticField = 2',
- expectedResult: r'''
+ test('private static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C._staticField = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'staticField = 2',
- expectedResult: r'''
+ test('static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField = 2;
}.bind(this)(
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in method with no field access:', () {
- var source = '''
- ${options.dartLangComment}
- extension NumberParsing on String {
- int parseInt() {
- return int.parse(this);
- }
- }
-
- int global = 42;
-
- class C {
- C(int this.field, int this._field);
-
- static int staticField = 0;
- static int _staticField = 1;
-
- int _field;
- int field;
-
- int methodNoFieldAccess(int x) {
- /* evaluation placeholder */
- return x;
+ group('Expression compiler tests in method with no field access:', () {
+ var source = '''
+ ${options.dartLangComment}
+ extension NumberParsing on String {
+ int parseInt() {
+ return int.parse(this);
+ }
}
- Future<int> asyncMethod(int x) async {
- return x;
+ int global = 42;
+
+ class C {
+ C(int this.field, int this._field);
+
+ static int staticField = 0;
+ static int _staticField = 1;
+
+ int _field;
+ int field;
+
+ int methodNoFieldAccess(int x) {
+ /* evaluation placeholder */
+ return x;
+ }
+
+ Future<int> asyncMethod(int x) async {
+ return x;
+ }
}
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'typo',
- expectedError: "The getter 'typo' isn't defined for the class 'C'");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'typo',
+ expectedError:
+ "The getter 'typo' isn't defined for the class 'C'");
+ });
- test('expression using static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + staticField',
- expectedResult: r'''
+ test('expression using static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + staticField',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return x + foo.C.staticField;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _staticField',
- expectedResult: r'''
+ test('expression using private static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _staticField',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return x + foo.C._staticField;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + field',
- expectedResult: '''
+ test('expression using fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + field',
+ expectedResult: '''
(function(x) {
return x + this.field;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _field',
- expectedResult: r'''
+ test('expression using private fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _field',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return x + this[S._field$1];
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return x + this[S._field\$1];
}.bind(this)(
1
))
''');
- });
+ });
- test('private field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_field = 2',
- expectedResult: r'''
+ test('private field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_field = 2',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return this[S._field$1] = 2;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return this[S._field\$1] = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'field = 2',
- expectedResult: '''
+ test('field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'field = 2',
+ expectedResult: '''
(function(x) {
return this.field = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('private static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_staticField = 2',
- expectedResult: r'''
+ test('private static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C._staticField = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'staticField = 2',
- expectedResult: r'''
+ test('static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField = 2;
}.bind(this)(
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in async method:', () {
- var source = '''
- ${options.dartLangComment}
- class C {
- C(int this.field, int this._field);
+ group('Expression compiler tests in async method:', () {
+ var source = '''
+ ${options.dartLangComment}
+ class C {
+ C(int this.field, int this._field);
- int _field;
- int field;
+ int _field;
+ int field;
- Future<int> asyncMethod(int x) async {
- /* evaluation placeholder */
- return x;
+ Future<int> asyncMethod(int x) async {
+ /* evaluation placeholder */
+ return x;
+ }
}
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'typo',
- expectedError: "The getter 'typo' isn't defined for the class 'C'");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'typo',
+ expectedError:
+ "The getter 'typo' isn't defined for the class 'C'");
+ });
- test('local', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x',
- expectedResult: '''
+ test('local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x',
+ expectedResult: '''
(function(x) {
return x;
}.bind(this)(
1
))
''');
- });
+ });
- test('this', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'this',
- expectedResult: '''
+ test('this', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'this',
+ expectedResult: '''
(function(x) {
return this;
}.bind(this)(
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in global function:', () {
- var source = '''
- ${options.dartLangComment}
- extension NumberParsing on String {
- int parseInt() {
- return int.parse(this);
- }
- }
-
- int global = 42;
-
- class C {
- C(int this.field, int this._field);
-
- static int staticField = 0;
- static int _staticField = 1;
-
- int _field;
- int field;
-
- int methodFieldAccess(int x) {
- return (x + _field + _staticField);
- }
- int methodFieldAccess(int x) {
- return (x)
+ group('Expression compiler tests in global function:', () {
+ var source = '''
+ ${options.dartLangComment}
+ extension NumberParsing on String {
+ int parseInt() {
+ return int.parse(this);
+ }
}
- Future<int> asyncMethod(int x) async {
- return x;
+ int global = 42;
+
+ class C {
+ C(int this.field, int this._field);
+
+ static int staticField = 0;
+ static int _staticField = 1;
+
+ int _field;
+ int field;
+
+ int methodFieldAccess(int x) {
+ return (x + _field + _staticField);
+ }
+ int methodFieldAccess(int x) {
+ return (x)
+ }
+
+ Future<int> asyncMethod(int x) async {
+ return x;
+ }
}
- }
- int main() {
- int x = 15;
- var c = C(1, 2);
- /* evaluation placeholder */
- return 0;
- }
- ''';
+ int main() {
+ int x = 15;
+ var c = C(1, 2);
+ /* evaluation placeholder */
+ return 0;
+ }
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'typo',
- expectedError: "Getter not found: 'typo'.");
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'typo',
+ expectedError: "Getter not found: 'typo'.");
+ });
- test('local with primitive type', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'x',
- expectedResult: '''
+ test('local with primitive type', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'x',
+ expectedResult: '''
(function(x, c) {
return x;
}(
@@ -3449,13 +3643,13 @@
null
))
''');
- });
+ });
- test('local object', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c',
- expectedResult: '''
+ test('local object', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c',
+ expectedResult: '''
(function(x, c) {
return c;
}(
@@ -3463,71 +3657,71 @@
null
))
''');
- });
+ });
- test('create new object', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C(1,3)',
- expectedResult: r'''
+ test('create new object', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C(1,3)',
+ expectedResult: '''
(function(x, c) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return new foo.C.new(1, 3);
}(
1,
null
))
''');
- });
+ });
- test('access field of new object', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C(1,3)._field',
- expectedResult: r'''
+ test('access field of new object', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C(1,3)._field',
+ expectedResult: '''
(function(x, c) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return new foo.C.new(1, 3)[S._field$1];
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return new foo.C.new(1, 3)[S._field\$1];
}(
1,
null
))
''');
- });
+ });
- test('access static field', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C.staticField',
- expectedResult: r'''
+ test('access static field', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C.staticField',
+ expectedResult: '''
(function(x, c) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField;
}(
1,
null
))
''');
- });
+ });
- test('expression using private static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C._staticField',
- expectedError: "Error: Getter not found: '_staticField'.");
- });
+ test('expression using private static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C._staticField',
+ expectedError: "Error: Getter not found: '_staticField'.");
+ });
- test('access field', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c.field',
- expectedResult: '''
+ test('access field', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c.field',
+ expectedResult: '''
(function(x, c) {
return c.field;
}(
@@ -3535,32 +3729,32 @@
null
))
''');
- });
+ });
- test('access private field', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c._field',
- expectedResult: r'''
+ test('access private field', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c._field',
+ expectedResult: '''
(function(x, c) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return c[S._field$1];
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return c[S._field\$1];
}(
1,
null
))
''');
- });
+ });
- test('method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c.methodFieldAccess(2)',
- expectedResult: '''
+ test('method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c.methodFieldAccess(2)',
+ expectedResult: '''
(function(x, c) {
return c.methodFieldAccess(2);
}(
@@ -3568,13 +3762,13 @@
null
))
''');
- });
+ });
- test('async method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c.asyncMethod(2)',
- expectedResult: '''
+ test('async method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c.asyncMethod(2)',
+ expectedResult: '''
(function(x, c) {
return c.asyncMethod(2);
}(
@@ -3582,48 +3776,48 @@
null
))
''');
- });
+ });
- test('extension method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: '"1234".parseInt()',
- expectedResult: r'''
+ test('extension method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: '"1234".parseInt()',
+ expectedResult: '''
(function(x, c) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo['NumberParsing|parseInt']("1234");
}(
1,
null
))
''');
- });
+ });
- test('private field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c._field = 2',
- expectedResult: r'''
+ test('private field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c._field = 2',
+ expectedResult: '''
(function(x, c) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return c[S._field$1] = 2;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return c[S._field\$1] = 2;
}(
1,
null
))
''');
- });
+ });
- test('field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'c.field = 2',
- expectedResult: '''
+ test('field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'c.field = 2',
+ expectedResult: '''
(function(x, c) {
return c.field = 2;
}(
@@ -3631,38 +3825,38 @@
null
))
''');
- });
+ });
- test('private static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C._staticField = 2',
- expectedError: "Setter not found: '_staticField'.");
- });
+ test('private static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C._staticField = 2',
+ expectedError: "Setter not found: '_staticField'.");
+ });
- test('static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'C.staticField = 2',
- expectedResult: r'''
+ test('static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'C.staticField = 2',
+ expectedResult: '''
(function(x, c) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField = 2;
}(
1,
null
))
''');
- });
+ });
- test('call global function from core library', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'print(x)',
- expectedResult: '''
+ test('call global function from core library', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'print(x)',
+ expectedResult: '''
(function(x, c) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const core = dart_sdk.core;
return core.print(x);
}(
@@ -3670,54 +3864,61 @@
null
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in closures:', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- int x = 15;
- var c = C(1, 2);
+ group('Expression compiler tests in closures:', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ int x = 15;
+ var c = C(1, 2);
- var outerClosure = (int y) {
- var closureCaptureInner = (int z) {
- /* evaluation placeholder */
- print('\$y+\$z');
- };
- closureCaptureInner(0);
- };
+ var outerClosure = (int y) {
+ var closureCaptureInner = (int z) {
+ /* evaluation placeholder */
+ print('\$y+\$z');
+ };
+ closureCaptureInner(0);
+ };
- outerClosure(3);
- return 0;
- }
+ outerClosure(3);
+ return 0;
+ }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
- expression: 'typo',
- expectedError: "Getter not found: 'typo'.");
- });
+ test('compilation error', () async {
+ await driver.check(scope: <String, String>{
+ 'x': '1',
+ 'c': 'null',
+ 'y': '3',
+ 'z': '0'
+ }, expression: 'typo', expectedError: "Getter not found: 'typo'.");
+ });
- test('expression using uncaptured variables', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
- expression: r"'$x+$y+$z'",
- expectedResult: '''
+ test('expression using uncaptured variables', () async {
+ await driver.check(
+ scope: <String, String>{
+ 'x': '1',
+ 'c': 'null',
+ 'y': '3',
+ 'z': '0'
+ },
+ expression: "'\$x+\$y+\$z'",
+ expectedResult: '''
(function(x, c, y, z) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.str(x) + "+" + dart.str(y) + "+" + dart.str(z);
}(
@@ -3727,15 +3928,20 @@
0
))
''');
- });
+ });
- test('expression using captured variables', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'y': '3', 'z': '0'},
- expression: r"'$y+$z'",
- expectedResult: '''
+ test('expression using captured variables', () async {
+ await driver.check(
+ scope: <String, String>{
+ 'x': '1',
+ 'c': 'null',
+ 'y': '3',
+ 'z': '0'
+ },
+ expression: "'\$y+\$z'",
+ expectedResult: '''
(function(x, c, y, z) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.str(y) + "+" + dart.str(z);
}(
@@ -3745,99 +3951,99 @@
0
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in method with no type use:', () {
- var source = '''
- ${options.dartLangComment}
- abstract class Key {
- const factory Key(String value) = ValueKey;
- const Key.empty();
- }
+ group('Expression compiler tests in method with no type use:', () {
+ var source = '''
+ ${options.dartLangComment}
+ abstract class Key {
+ const factory Key(String value) = ValueKey;
+ const Key.empty();
+ }
- abstract class LocalKey extends Key {
- const LocalKey() : super.empty();
- }
+ abstract class LocalKey extends Key {
+ const LocalKey() : super.empty();
+ }
- class ValueKey implements LocalKey {
- const ValueKey(this.value);
- final String value;
- }
+ class ValueKey implements LocalKey {
+ const ValueKey(this.value);
+ final String value;
+ }
- class MyClass {
- const MyClass(this._t);
- final int _t;
- }
+ class MyClass {
+ const MyClass(this._t);
+ final int _t;
+ }
- int bar(int p){
- return p;
- }
- int baz(String t){
- return t;
- }
- void main() {
- var k = Key('t');
- MyClass c = MyClass(0);
- int p = 1;
- const t = 1;
+ int bar(int p){
+ return p;
+ }
+ int baz(String t){
+ return t;
+ }
+ void main() {
+ var k = Key('t');
+ MyClass c = MyClass(0);
+ int p = 1;
+ const t = 1;
- /* evaluation placeholder */
- print('\$c, \$k, \$t');
- }
- ''';
+ /* evaluation placeholder */
+ print('\$c, \$k, \$t');
+ }
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('call function not using type', () async {
- await driver.check(
- scope: <String, String>{'p': '1'},
- expression: 'bar(p)',
- expectedResult: r'''
+ test('call function not using type', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: 'bar(p)',
+ expectedResult: '''
(function(p) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.bar(p);
}(
1
))
''');
- });
+ });
- test('call function using type', () async {
- await driver.check(
- scope: <String, String>{'p': '0'},
- expression: 'baz(p as String)',
- expectedResult: r'''
+ test('call function using type', () async {
+ await driver.check(
+ scope: <String, String>{'p': '0'},
+ expression: 'baz(p as String)',
+ expectedResult: '''
(function(p) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const core = dart_sdk.core;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.baz(core.String.as(p));
}(
0
))
''');
- });
+ });
- test('evaluate new const expression', () async {
- await driver.check(
- scope: <String, String>{'p': '1'},
- expression: 'const MyClass(1)',
- expectedResult: r'''
+ test('evaluate new const expression', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: 'const MyClass(1)',
+ expectedResult: '''
(function(p) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
var S = {MyClass__t: dart.privateName(foo, "MyClass._t")};
const CT = Object.create(null);
dart.defineLazy(CT, {
@@ -3854,47 +4060,47 @@
1
))
''');
- });
+ });
- test('evaluate optimized const expression', () async {
- await driver.check(
- scope: <String, String>{},
- expression: 't',
- expectedResult: '''
+ test('evaluate optimized const expression', () async {
+ await driver.check(
+ scope: <String, String>{},
+ expression: 't',
+ expectedResult: '''
(function() {
return 1;
}(
))
''');
- },
- skip: 'Cannot compile constants optimized away by the frontend. '
- 'Issue: https://github.com/dart-lang/sdk/issues/41999');
+ },
+ skip: 'Cannot compile constants optimized away by the frontend. '
+ 'Issue: https://github.com/dart-lang/sdk/issues/41999');
- test('evaluate factory constructor call', () async {
- await driver.check(
- scope: <String, String>{'p': '1'},
- expression: "Key('t')",
- expectedResult: r'''
+ test('evaluate factory constructor call', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: "Key('t')",
+ expectedResult: '''
(function(p) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return new foo.ValueKey.new("t");
}(
1
))
''');
- });
+ });
- test('evaluate const factory constructor call', () async {
- await driver.check(
- scope: <String, String>{'p': '1'},
- expression: "const Key('t')",
- expectedResult: r'''
+ test('evaluate const factory constructor call', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: "const Key('t')",
+ expectedResult: '''
(function(p) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
var S = {ValueKey_value: dart.privateName(foo, "ValueKey.value")};
const CT = Object.create(null);
dart.defineLazy(CT, {
@@ -3911,311 +4117,312 @@
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in constructor:', () {
- var source = '''
- ${options.dartLangComment}
- extension NumberParsing on String {
- int parseInt() {
- return int.parse(this);
- }
- }
-
- int global = 42;
-
- class C {
- C(int this.field, int this._field) {
- int x = 1;
- /* evaluation placeholder */
- print(this.field);
+ group('Expression compiler tests in constructor:', () {
+ var source = '''
+ ${options.dartLangComment}
+ extension NumberParsing on String {
+ int parseInt() {
+ return int.parse(this);
+ }
}
- static int staticField = 0;
- static int _staticField = 1;
+ int global = 42;
- int _field;
- int field;
+ class C {
+ C(int this.field, int this._field) {
+ int x = 1;
+ /* evaluation placeholder */
+ print(this.field);
+ }
- int methodFieldAccess(int t) {
- return t + _field + _staticField;
+ static int staticField = 0;
+ static int _staticField = 1;
+
+ int _field;
+ int field;
+
+ int methodFieldAccess(int t) {
+ return t + _field + _staticField;
+ }
+
+ Future<int> asyncMethod(int t) async {
+ return t;
+ }
}
- Future<int> asyncMethod(int t) async {
- return t;
- }
- }
+ main() => 0;
+ ''';
- main() => 0;
- ''';
+ TestDriver driver;
- TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- setUp(() {
- driver = TestDriver(options, source);
- });
+ tearDown(() {
+ driver.delete();
+ });
- tearDown(() {
- driver.delete();
- });
+ test('compilation error', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'typo',
+ expectedError:
+ "The getter 'typo' isn't defined for the class 'C'");
+ });
- test('compilation error', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'typo',
- expectedError: "The getter 'typo' isn't defined for the class 'C'");
- });
-
- test('local', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x',
- expectedResult: '''
+ test('local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x',
+ expectedResult: '''
(function(x) {
return x;
}.bind(this)(
1
))
''');
- });
+ });
- test('this', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'this',
- expectedResult: '''
+ test('this', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'this',
+ expectedResult: '''
(function(x) {
return this;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using locals', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + 1',
- expectedResult: '''
+ test('expression using locals', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + 1',
+ expectedResult: '''
(function(x) {
return x + 1;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + staticField',
- expectedResult: r'''
+ test('expression using static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + staticField',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return x + foo.C.staticField;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private static fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _staticField',
- expectedResult: r'''
+ test('expression using private static fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _staticField',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return x + foo.C._staticField;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + field',
- expectedResult: '''
+ test('expression using fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + field',
+ expectedResult: '''
(function(x) {
return x + this.field;
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using private fields', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + _field',
- expectedResult: r'''
+ test('expression using private fields', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + _field',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return x + this[S._field$1];
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return x + this[S._field\$1];
}.bind(this)(
1
))
''');
- });
+ });
- test('expression using globals', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'x + global',
- expectedResult: r'''
+ test('expression using globals', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'x + global',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return x + foo.global;
}.bind(this)(
1
))
''');
- });
+ });
- test('method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'methodFieldAccess(2)',
- expectedResult: '''
+ test('method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'methodFieldAccess(2)',
+ expectedResult: '''
(function(x) {
return this.methodFieldAccess(2);
}.bind(this)(
1
))
''');
- });
+ });
- test('async method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'asyncMethod(2)',
- expectedResult: '''
+ test('async method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'asyncMethod(2)',
+ expectedResult: '''
(function(x) {
return this.asyncMethod(2);
}.bind(this)(
1
))
''');
- });
+ });
- test('extension method call', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '"1234".parseInt()',
- expectedResult: r'''
+ test('extension method call', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '"1234".parseInt()',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo['NumberParsing|parseInt']("1234");
}.bind(this)(
1
))
''');
- });
+ });
- test('private field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_field = 2',
- expectedResult: r'''
+ test('private field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_field = 2',
+ expectedResult: '''
(function(x) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
- var S = {_field$1: dart.privateName(foo, "_field")};
- return this[S._field$1] = 2;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
+ var S = {_field\$1: dart.privateName(foo, "_field")};
+ return this[S._field\$1] = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'field = 2',
- expectedResult: '''
+ test('field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'field = 2',
+ expectedResult: '''
(function(x) {
return this.field = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('private static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: '_staticField = 2',
- expectedResult: r'''
+ test('private static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: '_staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C._staticField = 2;
}.bind(this)(
1
))
''');
- });
+ });
- test('static field modification', () async {
- await driver.check(
- scope: <String, String>{'x': '1'},
- expression: 'staticField = 2',
- expectedResult: r'''
+ test('static field modification', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1'},
+ expression: 'staticField = 2',
+ expectedResult: '''
(function(x) {
- const foo$46dart = require('foo.dart');
- const foo = foo$46dart.foo;
+ const foo\$46dart = ${options.loadModule}('foo.dart');
+ const foo = foo\$46dart.foo;
return foo.C.staticField = 2;
}.bind(this)(
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in loops:', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- int x = 15;
- var c = C(1, 2);
+ group('Expression compiler tests in loops:', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ int x = 15;
+ var c = C(1, 2);
- for(int i = 0; i < 10; i++) {
- /* evaluation placeholder */
- print('\$i+\$x');
- };
- return 0;
- }
+ for(int i = 0; i < 10; i++) {
+ /* evaluation placeholder */
+ print('\$i+\$x');
+ };
+ return 0;
+ }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('expression using local', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
- expression: 'x',
- expectedResult: '''
+ test('expression using local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
+ expression: 'x',
+ expectedResult: '''
(function(x, c, i) {
return x;
}(
@@ -4224,13 +4431,13 @@
0
))
''');
- });
+ });
- test('expression using loop variable', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
- expression: 'i',
- expectedResult: '''
+ test('expression using loop variable', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'i': '0'},
+ expression: 'i',
+ expectedResult: '''
(function(x, c, i) {
return i;
}(
@@ -4239,39 +4446,39 @@
0
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in iterator loops:', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- var l = <String>['1', '2', '3'];
+ group('Expression compiler tests in iterator loops:', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ var l = <String>['1', '2', '3'];
- for(var e in l) {
- /* evaluation placeholder */
- print(e);
- };
- return 0;
- }
+ for(var e in l) {
+ /* evaluation placeholder */
+ print(e);
+ };
+ return 0;
+ }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('expression loop variable', () async {
- await driver.check(
- scope: <String, String>{'l': 'null', 'e': '1'},
- expression: 'e',
- expectedResult: '''
+ test('expression loop variable', () async {
+ await driver.check(
+ scope: <String, String>{'l': 'null', 'e': '1'},
+ expression: 'e',
+ expectedResult: '''
(function(l, e) {
return e;
}(
@@ -4279,44 +4486,44 @@
1
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests in conditional (then):', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- int x = 1;
- var c = C(1, 2);
+ group('Expression compiler tests in conditional (then):', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ int x = 1;
+ var c = C(1, 2);
- if (x == 14) {
- int y = 3;
- /* evaluation placeholder */
- print('\$y+\$x');
- } else {
- int z = 3;
- print('\$z+\$x');
+ if (x == 14) {
+ int y = 3;
+ /* evaluation placeholder */
+ print('\$y+\$x');
+ } else {
+ int z = 3;
+ print('\$z+\$x');
+ }
+ return 0;
}
- return 0;
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('expression using local', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
- expression: 'y',
- expectedResult: '''
+ test('expression using local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
+ expression: 'y',
+ expectedResult: '''
(function(x, c, y) {
return y;
}(
@@ -4325,51 +4532,51 @@
3
))
''');
- });
+ });
- test('expression using local out of scope', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
- expression: 'z',
- expectedError: "Error: Getter not found: 'z'");
- });
- });
+ test('expression using local out of scope', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'y': '3'},
+ expression: 'z',
+ expectedError: "Error: Getter not found: 'z'");
+ });
+ });
- group('Expression compiler tests in conditional (else):', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- int x = 1;
- var c = C(1, 2);
+ group('Expression compiler tests in conditional (else):', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ int x = 1;
+ var c = C(1, 2);
- if (x == 14) {
- int y = 3;
- print('\$y+\$x');
- } else {
- int z = 3;
- /* evaluation placeholder */
- print('\$z+\$x');
+ if (x == 14) {
+ int y = 3;
+ print('\$y+\$x');
+ } else {
+ int z = 3;
+ /* evaluation placeholder */
+ print('\$z+\$x');
+ }
+ return 0;
}
- return 0;
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('expression using local', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
- expression: 'z',
- expectedResult: '''
+ test('expression using local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
+ expression: 'z',
+ expectedResult: '''
(function(x, c, z) {
return z;
}(
@@ -4378,51 +4585,51 @@
3
))
''');
- });
+ });
- test('expression using local out of scope', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
- expression: 'y',
- expectedError: "Error: Getter not found: 'y'");
- });
- });
+ test('expression using local out of scope', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null', 'z': '3'},
+ expression: 'y',
+ expectedError: "Error: Getter not found: 'y'");
+ });
+ });
- group('Expression compiler tests after conditionals:', () {
- var source = '''
- ${options.dartLangComment}
- int globalFunction() {
- int x = 1;
- var c = C(1, 2);
+ group('Expression compiler tests after conditionals:', () {
+ var source = '''
+ ${options.dartLangComment}
+ int globalFunction() {
+ int x = 1;
+ var c = C(1, 2);
- if (x == 14) {
- int y = 3;
- print('\$y+\$x');
- } else {
- int z = 3;
- print('\$z+\$x');
+ if (x == 14) {
+ int y = 3;
+ print('\$y+\$x');
+ } else {
+ int z = 3;
+ print('\$z+\$x');
+ }
+ /* evaluation placeholder */
+ return 0;
}
- /* evaluation placeholder */
- return 0;
- }
- main() => 0;
- ''';
+ main() => 0;
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('expression using local', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'x',
- expectedResult: '''
+ test('expression using local', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'x',
+ expectedResult: '''
(function(x, c) {
return x;
}(
@@ -4430,49 +4637,49 @@
null
))
''');
- });
+ });
- test('expression using local out of scope', () async {
- await driver.check(
- scope: <String, String>{'x': '1', 'c': 'null'},
- expression: 'z',
- expectedError: "Error: Getter not found: 'z'");
- });
- });
+ test('expression using local out of scope', () async {
+ await driver.check(
+ scope: <String, String>{'x': '1', 'c': 'null'},
+ expression: 'z',
+ expectedError: "Error: Getter not found: 'z'");
+ });
+ });
- group('Expression compiler tests in generic method:', () {
- var source = '''
- ${options.dartLangComment}
- class A {
- void generic<TType, KType>(TType a, KType b) {
- /* evaluation placeholder */
- print(a);
- print(b);
+ group('Expression compiler tests in generic method:', () {
+ var source = '''
+ ${options.dartLangComment}
+ class A {
+ void generic<TType, KType>(TType a, KType b) {
+ /* evaluation placeholder */
+ print(a);
+ print(b);
+ }
}
- }
- void main() => generic<int, String>(0, 'hi');
- ''';
+ void main() => generic<int, String>(0, 'hi');
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('evaluate formals', () async {
- await driver.check(
- scope: <String, String>{
- 'TType': 'TType',
- 'KType': 'KType',
- 'a': 'a',
- 'b': 'b'
- },
- expression: 'a',
- expectedResult: '''
+ test('evaluate formals', () async {
+ await driver.check(
+ scope: <String, String>{
+ 'TType': 'TType',
+ 'KType': 'KType',
+ 'a': 'a',
+ 'b': 'b'
+ },
+ expression: 'a',
+ expectedResult: '''
(function(TType, KType, a, b) {
return a;
}.bind(this)(
@@ -4482,20 +4689,20 @@
b
))
''');
- });
+ });
- test('evaluate type parameters', () async {
- await driver.check(
- scope: <String, String>{
- 'TType': 'TType',
- 'KType': 'KType',
- 'a': 'a',
- 'b': 'b'
- },
- expression: 'TType',
- expectedResult: '''
+ test('evaluate type parameters', () async {
+ await driver.check(
+ scope: <String, String>{
+ 'TType': 'TType',
+ 'KType': 'KType',
+ 'a': 'a',
+ 'b': 'b'
+ },
+ expression: 'TType',
+ expectedResult: '''
(function(TType, KType, a, b) {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const dart = dart_sdk.dart;
return dart.wrapType(TType);
}.bind(this)(
@@ -4505,53 +4712,55 @@
b
))
''');
- });
- });
+ });
+ });
- group('Expression compiler tests using extension symbols', () {
- var source = '''
- ${options.dartLangComment}
- void bar() {
- /* evaluation placeholder */
- }
+ group('Expression compiler tests using extension symbols', () {
+ var source = '''
+ ${options.dartLangComment}
+ void bar() {
+ /* evaluation placeholder */
+ }
- void main() => bar();
- ''';
+ void main() => bar();
+ ''';
- TestDriver driver;
- setUp(() {
- driver = TestDriver(options, source);
- });
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
- tearDown(() {
- driver.delete();
- });
+ tearDown(() {
+ driver.delete();
+ });
- test('map access', () async {
- await driver.check(
- scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
- expression:
- '(Map<String, String> params) { return params["index"]; }({})',
- expectedResult: r'''
+ test('map access', () async {
+ await driver.check(
+ scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+ expression:
+ '(Map<String, String> params) { return params["index"]; }({})',
+ expectedResult: '''
(function() {
- const dart_sdk = require('dart_sdk');
+ const dart_sdk = ${options.loadModule}('dart_sdk');
const core = dart_sdk.core;
const _js_helper = dart_sdk._js_helper;
const dart = dart_sdk.dart;
const dartx = dart_sdk.dartx;
var T = {
StringN: () => (T.StringN = dart.constFn(dart.nullable(core.String)))(),
- MapOfString$String: () => (T.MapOfString$String = dart.constFn(core.Map$(core.String, core.String)))(),
- MapOfString$StringToStringN: () => (T.MapOfString$StringToStringN = dart.constFn(dart.fnType(T.StringN(), [T.MapOfString$String()])))(),
- IdentityMapOfString$String: () => (T.IdentityMapOfString$String = dart.constFn(_js_helper.IdentityMap$(core.String, core.String)))()
+ MapOfString\$String: () => (T.MapOfString\$String = dart.constFn(core.Map\$(core.String, core.String)))(),
+ MapOfString\$StringToStringN: () => (T.MapOfString\$StringToStringN = dart.constFn(dart.fnType(T.StringN(), [T.MapOfString\$String()])))(),
+ IdentityMapOfString\$String: () => (T.IdentityMapOfString\$String = dart.constFn(_js_helper.IdentityMap\$(core.String, core.String)))()
};
- var S = {$_get: dartx._get};
- return dart.fn(params => params[S.$_get]("index"), T.MapOfString$StringToStringN())(new (T.IdentityMapOfString$String()).new());
+ var S = {\$_get: dartx._get};
+ return dart.fn(params => params[S.\$_get]("index"), T.MapOfString\$StringToStringN())(new (T.IdentityMapOfString\$String()).new());
}(
))
''');
+ });
+ });
});
});
- });
+ }
}
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 e964f5f..b784e96 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
@@ -47,8 +47,10 @@
final Directory rootDirectory;
final String outputDir = 'out';
final bool soundNullSafety;
+ final String moduleFormat;
- TestProjectConfiguration(this.rootDirectory, this.soundNullSafety);
+ TestProjectConfiguration(
+ this.rootDirectory, this.soundNullSafety, this.moduleFormat);
ModuleConfiguration get mainModule => ModuleConfiguration(
root: root,
@@ -210,486 +212,486 @@
}
void main() async {
- for (var soundNullSafety in [true, false]) {
- group('${soundNullSafety ? "sound" : "unsound"} null safety -', () {
- for (var summarySupport in [true, false]) {
- group('${summarySupport ? "" : "no "}debugger summary support -', () {
- group('expression compiler worker', () {
- ExpressionCompilerWorker worker;
- Future workerDone;
- StreamController<Map<String, dynamic>> requestController;
- StreamController<Map<String, dynamic>> responseController;
- Directory tempDir;
- TestProjectConfiguration config;
- List inputs;
+ for (var moduleFormat in ['amd', 'ddc']) {
+ group('$moduleFormat module format -', () {
+ for (var soundNullSafety in [true, false]) {
+ group('${soundNullSafety ? "sound" : "unsound"} null safety -', () {
+ for (var summarySupport in [true, false]) {
+ group('${summarySupport ? "" : "no "}debugger summary support -',
+ () {
+ group('expression compiler worker', () {
+ 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, soundNullSafety);
+ setUpAll(() async {
+ tempDir = Directory.systemTemp.createTempSync('foo bar');
+ config = TestProjectConfiguration(
+ tempDir, soundNullSafety, moduleFormat);
- // simulate webdev
- config.createTestProject();
- var kernelGenerator = DDCKernelGenerator(config);
- await kernelGenerator.generate();
+ // simulate webdev
+ config.createTestProject();
+ var kernelGenerator = DDCKernelGenerator(config);
+ await kernelGenerator.generate();
- inputs = [
- {
- 'path': config.mainModule.fullDillPath.path,
- if (summarySupport)
- 'summaryPath': config.mainModule.summaryDillPath.path,
- 'moduleName': config.mainModule.moduleName
- },
- {
- 'path': config.testModule.fullDillPath.path,
- if (summarySupport)
- 'summaryPath': config.testModule.summaryDillPath.path,
- 'moduleName': config.testModule.moduleName
- },
- {
- 'path': config.testModule2.fullDillPath.path,
- if (summarySupport)
- 'summaryPath': config.testModule2.summaryDillPath.path,
- 'moduleName': config.testModule2.moduleName
- },
- {
- 'path': config.testModule3.fullDillPath.path,
- if (summarySupport)
- 'summaryPath': config.testModule3.summaryDillPath.path,
- 'moduleName': config.testModule3.moduleName
- },
- ];
+ inputs = [
+ {
+ 'path': config.mainModule.fullDillPath.path,
+ if (summarySupport)
+ 'summaryPath': config.mainModule.summaryDillPath.path,
+ 'moduleName': config.mainModule.moduleName
+ },
+ {
+ 'path': config.testModule.fullDillPath.path,
+ if (summarySupport)
+ 'summaryPath': config.testModule.summaryDillPath.path,
+ 'moduleName': config.testModule.moduleName
+ },
+ {
+ 'path': config.testModule2.fullDillPath.path,
+ if (summarySupport)
+ 'summaryPath': config.testModule2.summaryDillPath.path,
+ 'moduleName': config.testModule2.moduleName
+ },
+ {
+ 'path': config.testModule3.fullDillPath.path,
+ if (summarySupport)
+ 'summaryPath': config.testModule3.summaryDillPath.path,
+ 'moduleName': config.testModule3.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,
+ // We should be able to load everything from dill and not
+ // require source parsing. Webdev and google3 integration
+ // currently rely on that. Make the test fail on source
+ // reading by not providing a packages file.
+ packagesFile: null,
+ sdkSummary: config.sdkSummaryPath,
+ fileSystem: fileSystem,
+ requestStream: requestController.stream,
+ sendResponse: responseController.add,
+ soundNullSafety: soundNullSafety,
+ verbose: verbose,
+ );
+ workerDone = worker.start();
+ });
+
+ tearDown(() async {
+ unawaited(requestController.close());
+ await workerDone;
+ unawaited(responseController.close());
+ });
+
+ test('can 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,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains('return other;'),
+ })
+ ]));
+ }, skip: 'Evaluating expressions in SDK is not supported yet');
+
+ test('can 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.testModule.moduleName,
+ });
+
+ expect(
+ responseController.stream,
+ emitsInOrder([
+ equals({
+ 'succeeded': true,
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains('return formal;'),
+ })
+ ]));
+ });
+
+ test('can compile expressions in main', () async {
+ requestController.add({
+ 'command': 'UpdateDeps',
+ 'inputs': inputs,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'count',
+ 'line': 9,
+ '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,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains('return count;'),
+ })
+ ]));
+ });
+
+ test('can compile expressions in main (extension method)',
+ () async {
+ requestController.add({
+ 'command': 'UpdateDeps',
+ 'inputs': inputs,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'ret',
+ 'line': 19,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {'ret': 'ret'},
+ 'libraryUri': config.mainModule.libraryUri,
+ 'moduleName': config.mainModule.moduleName,
+ });
+
+ expect(
+ responseController.stream,
+ emitsInOrder([
+ equals({
+ 'succeeded': true,
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains('return ret;'),
+ })
+ ]));
+ });
+
+ test('can compile transitive expressions in main', () async {
+ requestController.add({
+ 'command': 'UpdateDeps',
+ 'inputs': inputs,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'B().c().getNumber()',
+ 'line': 9,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {},
+ 'libraryUri': config.mainModule.libraryUri,
+ 'moduleName': config.mainModule.moduleName,
+ });
+
+ expect(
+ responseController.stream,
+ emitsInOrder([
+ equals({
+ 'succeeded': true,
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains(
+ 'new test_library.B.new().c().getNumber()'),
+ })
+ ]));
+ });
+
+ test('can compile series of expressions in various libraries',
+ () async {
+ requestController.add({
+ 'command': 'UpdateDeps',
+ 'inputs': inputs,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'B().c().getNumber()',
+ 'line': 8,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {},
+ 'libraryUri': config.mainModule.libraryUri,
+ 'moduleName': config.mainModule.moduleName,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'formal',
+ 'line': 5,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {'formal': 'formal'},
+ 'libraryUri': config.testModule.libraryUri,
+ 'moduleName': config.testModule.moduleName,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'formal',
+ 'line': 3,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {'formal': 'formal'},
+ 'libraryUri': config.testModule2.libraryUri,
+ 'moduleName': config.testModule2.moduleName,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'formal',
+ 'line': 3,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {'formal': 'formal'},
+ 'libraryUri': config.testModule3.libraryUri,
+ 'moduleName': config.testModule3.moduleName,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'B().printNumber()',
+ 'line': 9,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {},
+ 'libraryUri': config.mainModule.libraryUri,
+ 'moduleName': config.mainModule.moduleName,
+ });
+
+ expect(
+ responseController.stream,
+ emitsInOrder([
+ equals({
+ 'succeeded': true,
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains(
+ 'new test_library.B.new().c().getNumber()'),
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains('return formal;'),
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains('return formal;'),
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains('return formal;'),
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure':
+ contains('test_library.B.new().printNumber()'),
+ })
+ ]));
+ });
+
+ test('can compile after dependency update', () async {
+ requestController.add({
+ 'command': 'UpdateDeps',
+ 'inputs': inputs,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'B().c().getNumber()',
+ 'line': 8,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {},
+ 'libraryUri': config.mainModule.libraryUri,
+ 'moduleName': config.mainModule.moduleName,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'formal',
+ 'line': 5,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {'formal': 'formal'},
+ 'libraryUri': config.testModule.libraryUri,
+ 'moduleName': config.testModule.moduleName,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'B().printNumber()',
+ 'line': 9,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {},
+ 'libraryUri': config.mainModule.libraryUri,
+ 'moduleName': config.mainModule.moduleName,
+ });
+
+ requestController.add({
+ 'command': 'UpdateDeps',
+ 'inputs': inputs,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'B().c().getNumber()',
+ 'line': 8,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {},
+ 'libraryUri': config.mainModule.libraryUri,
+ 'moduleName': config.mainModule.moduleName,
+ });
+
+ requestController.add({
+ 'command': 'CompileExpression',
+ 'expression': 'formal',
+ 'line': 3,
+ 'column': 1,
+ 'jsModules': {},
+ 'jsScope': {'formal': 'formal'},
+ 'libraryUri': config.testModule3.libraryUri,
+ 'moduleName': config.testModule3.moduleName,
+ });
+
+ expect(
+ responseController.stream,
+ emitsInOrder([
+ equals({
+ 'succeeded': true,
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains(
+ 'new test_library.B.new().c().getNumber()'),
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains('return formal;'),
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure':
+ contains('test_library.B.new().printNumber()'),
+ }),
+ equals({
+ 'succeeded': true,
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains(
+ 'new test_library.B.new().c().getNumber()'),
+ }),
+ equals({
+ 'succeeded': true,
+ 'errors': isEmpty,
+ 'warnings': isEmpty,
+ 'infos': isEmpty,
+ 'compiledProcedure': contains('return formal;'),
+ }),
+ ]));
+ });
+ });
});
-
- 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,
- // We should be able to load everything from dill and not require
- // source parsing. Webdev and google3 integration currently rely on
- // that. Make the test fail on source reading by not providing a
- // packages file.
- packagesFile: null,
- sdkSummary: config.sdkSummaryPath,
- fileSystem: fileSystem,
- requestStream: requestController.stream,
- sendResponse: responseController.add,
- soundNullSafety: soundNullSafety,
- 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,
- 'infos': 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.testModule.moduleName,
- });
-
- expect(
- responseController.stream,
- emitsInOrder([
- equals({
- 'succeeded': true,
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': 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': 9,
- '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,
- 'infos': isEmpty,
- 'compiledProcedure': contains('return count;'),
- })
- ]));
- });
-
- test(
- 'can load dependencies and compile expressions in main (extension method)',
- () async {
- requestController.add({
- 'command': 'UpdateDeps',
- 'inputs': inputs,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'ret',
- 'line': 19,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {'ret': 'ret'},
- 'libraryUri': config.mainModule.libraryUri,
- 'moduleName': config.mainModule.moduleName,
- });
-
- expect(
- responseController.stream,
- emitsInOrder([
- equals({
- 'succeeded': true,
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure': contains('return ret;'),
- })
- ]));
- });
-
- test(
- 'can load dependencies and compile transitive expressions in main',
- () async {
- requestController.add({
- 'command': 'UpdateDeps',
- 'inputs': inputs,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'B().c().getNumber()',
- 'line': 9,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {},
- 'libraryUri': config.mainModule.libraryUri,
- 'moduleName': config.mainModule.moduleName,
- });
-
- expect(
- responseController.stream,
- emitsInOrder([
- equals({
- 'succeeded': true,
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure': contains(
- 'return new test_library.B.new().c().getNumber()'),
- })
- ]));
- });
-
- test('can compile series of expressions in various libraries',
- () async {
- requestController.add({
- 'command': 'UpdateDeps',
- 'inputs': inputs,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'B().c().getNumber()',
- 'line': 8,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {},
- 'libraryUri': config.mainModule.libraryUri,
- 'moduleName': config.mainModule.moduleName,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'formal',
- 'line': 5,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {'formal': 'formal'},
- 'libraryUri': config.testModule.libraryUri,
- 'moduleName': config.testModule.moduleName,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'formal',
- 'line': 3,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {'formal': 'formal'},
- 'libraryUri': config.testModule2.libraryUri,
- 'moduleName': config.testModule2.moduleName,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'formal',
- 'line': 3,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {'formal': 'formal'},
- 'libraryUri': config.testModule3.libraryUri,
- 'moduleName': config.testModule3.moduleName,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'B().printNumber()',
- 'line': 9,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {},
- 'libraryUri': config.mainModule.libraryUri,
- 'moduleName': config.mainModule.moduleName,
- });
-
- expect(
- responseController.stream,
- emitsInOrder([
- equals({
- 'succeeded': true,
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure':
- contains('new test_library.B.new().c().getNumber()'),
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure': contains('return formal;'),
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure': contains('return formal;'),
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure': contains('return formal;'),
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure':
- contains('test_library.B.new().printNumber()'),
- })
- ]));
- });
-
- test('can compile after dependency update', () async {
- requestController.add({
- 'command': 'UpdateDeps',
- 'inputs': inputs,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'B().c().getNumber()',
- 'line': 8,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {},
- 'libraryUri': config.mainModule.libraryUri,
- 'moduleName': config.mainModule.moduleName,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'formal',
- 'line': 5,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {'formal': 'formal'},
- 'libraryUri': config.testModule.libraryUri,
- 'moduleName': config.testModule.moduleName,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'B().printNumber()',
- 'line': 9,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {},
- 'libraryUri': config.mainModule.libraryUri,
- 'moduleName': config.mainModule.moduleName,
- });
-
- requestController.add({
- 'command': 'UpdateDeps',
- 'inputs': inputs,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'B().c().getNumber()',
- 'line': 8,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {},
- 'libraryUri': config.mainModule.libraryUri,
- 'moduleName': config.mainModule.moduleName,
- });
-
- requestController.add({
- 'command': 'CompileExpression',
- 'expression': 'formal',
- 'line': 3,
- 'column': 1,
- 'jsModules': {},
- 'jsScope': {'formal': 'formal'},
- 'libraryUri': config.testModule3.libraryUri,
- 'moduleName': config.testModule3.moduleName,
- });
-
- expect(
- responseController.stream,
- emitsInOrder([
- equals({
- 'succeeded': true,
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure':
- contains('new test_library.B.new().c().getNumber()'),
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure': contains('return formal;'),
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure':
- contains('test_library.B.new().printNumber()'),
- }),
- equals({
- 'succeeded': true,
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure':
- contains('new test_library.B.new().c().getNumber()'),
- }),
- equals({
- 'succeeded': true,
- 'errors': isEmpty,
- 'warnings': isEmpty,
- 'infos': isEmpty,
- 'compiledProcedure': contains('return formal;'),
- }),
- ]));
- });
- });
+ }
});
}
});
@@ -727,7 +729,10 @@
'org-dartlang-app',
'--packages',
config.packagesPath.path,
- config.soundNullSafety ? '--sound-null-safety' : '--no-sound-null-safety'
+ if (config.soundNullSafety) '--sound-null-safety',
+ if (!config.soundNullSafety) '--no-sound-null-safety',
+ '--modules',
+ '${config.moduleFormat}',
];
var exitCode = await runProcess(dart, args, config.rootPath);
@@ -753,6 +758,9 @@
'--packages',
config.packagesPath.path,
if (config.soundNullSafety) '--sound-null-safety',
+ if (!config.soundNullSafety) '--no-sound-null-safety',
+ '--modules',
+ '${config.moduleFormat}',
];
exitCode = await runProcess(dart, args, config.rootPath);
@@ -780,6 +788,9 @@
'--packages',
config.packagesPath.path,
if (config.soundNullSafety) '--sound-null-safety',
+ if (!config.soundNullSafety) '--no-sound-null-safety',
+ '--modules',
+ '${config.moduleFormat}',
];
exitCode = await runProcess(dart, args, config.rootPath);
@@ -809,6 +820,9 @@
'--packages',
config.packagesPath.toFilePath(),
if (config.soundNullSafety) '--sound-null-safety',
+ if (!config.soundNullSafety) '--no-sound-null-safety',
+ '--modules',
+ '${config.moduleFormat}',
];
return await runProcess(dart, args, config.rootPath);
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 45d05d8..c8a530d 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -1636,14 +1636,13 @@
/// ---- Implementation of [EntryPointsListener] interface. ----
@override
- void addDirectFieldAccess(Field field, Type value) {
+ void addFieldUsedInConstant(Field field, Type instance, Type value) {
+ assert(!field.isStatic);
final fieldValue = getFieldValue(field);
- if (field.isStatic) {
- fieldValue.setValue(value, this, /*receiver_type=*/ null);
- } else {
- final receiver = new ConeType(hierarchyCache.getTFClass(field.parent));
- fieldValue.setValue(value, this, receiver);
- }
+ fieldValue.setValue(value, this, instance);
+ // Make sure the field is retained as removing fields used in constants
+ // may affect identity of the constants.
+ fieldValue.isGetterUsed = true;
}
@override
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 2a67d18..7375c51 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -21,7 +21,7 @@
void addRawCall(Selector selector);
/// Sets the type of the given field.
- void addDirectFieldAccess(Field field, Type value);
+ void addFieldUsedInConstant(Field field, Type instance, Type value);
/// Add instantiation of the given class.
ConcreteType addAllocatedClass(Class c);
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 1756791..34c375b 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -2415,8 +2415,8 @@
final resultClass = summaryCollector._entryPointsListener
.addAllocatedClass(constant.classNode);
constant.fieldValues.forEach((Reference fieldReference, Constant value) {
- summaryCollector._entryPointsListener
- .addDirectFieldAccess(fieldReference.asField, typeFor(value));
+ summaryCollector._entryPointsListener.addFieldUsedInConstant(
+ fieldReference.asField, resultClass, typeFor(value));
});
return new ConcreteType(resultClass.cls, null, constant);
}
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index a046634..cad4936 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -44,7 +44,7 @@
void addRawCall(Selector selector) {}
@override
- void addDirectFieldAccess(Field field, Type value) {}
+ void addFieldUsedInConstant(Field field, Type instance, Type value) {}
@override
ConcreteType addAllocatedClass(Class c) {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart
new file mode 100644
index 0000000..76c439a
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+ final int targetPlatform;
+ const A(this.targetPlatform);
+
+ static const BAR = A(1);
+}
+
+class X implements A {
+ int get targetPlatform => 2;
+}
+
+A a = X();
+
+void main() {
+ print(a.targetPlatform);
+ print(A.BAR);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart.expect
new file mode 100644
index 0000000..ad855f7
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart.expect
@@ -0,0 +1,19 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/ {
+[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] [@vm.unboxing-info.metadata=()->i] final field core::int* targetPlatform;
+}
+class X extends core::Object implements self::A {
+ synthetic constructor •() → self::X*
+ : super core::Object::•()
+ ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] [@vm.unboxing-info.metadata=()->i] get targetPlatform() → core::int*
+ return 2;
+}
+[@vm.inferred-type.metadata=#lib::X?]static field self::A* a = new self::X::•();
+static method main() → void {
+ core::print([@vm.direct-call.metadata=#lib::X.targetPlatform??] [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] [@vm.inferred-type.metadata=#lib::X?] self::a.{self::A::targetPlatform});
+ core::print(#C2);
+}
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index dd07c76..5a09268 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -347,6 +347,7 @@
VirtualMemory::~VirtualMemory() {
#if defined(DART_COMPRESSED_POINTERS)
if (VirtualMemoryCompressedHeap::Contains(reserved_.pointer())) {
+ madvise(reserved_.pointer(), reserved_.size(), MADV_DONTNEED);
VirtualMemoryCompressedHeap::Free(reserved_.pointer(), reserved_.size());
return;
}
diff --git a/tools/VERSION b/tools/VERSION
index faca9a1..d053d5c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 13
PATCH 0
-PRERELEASE 140
+PRERELEASE 141
PRERELEASE_PATCH 0
\ No newline at end of file