Port inference tests, #5 of 5

Change-Id: I384056289dfa99991aa42fbe0baadedc6c208b6f
Reviewed-on: https://dart-review.googlesource.com/34586
Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Johnni Winther 2018-01-17 10:19:53 +00:00
parent 0f70f94992
commit 94fc11388a
23 changed files with 1102 additions and 1562 deletions

View file

@ -115,7 +115,7 @@ abstract class InferrerEngine<T> {
void setDefaultTypeOfParameter(Local parameter, TypeInformation type,
{bool isInstanceMember});
Iterable<MemberEntity> getCallersOf(MemberEntity element);
Iterable<MemberEntity> getCallersOfForTesting(MemberEntity element);
// TODO(johnniwinther): Make this private again.
GlobalTypeInferenceElementData<T> dataOfMember(MemberEntity element);
@ -250,6 +250,8 @@ abstract class InferrerEngine<T> {
}
abstract class InferrerEngineImpl<T> extends InferrerEngine<T> {
static bool retainDataForTesting = false;
final Map<Local, TypeInformation> defaultTypeOfParameter =
new Map<Local, TypeInformation>();
final WorkQueue workQueue = new WorkQueue();
@ -1094,7 +1096,11 @@ abstract class InferrerEngineImpl<T> extends InferrerEngine<T> {
}
void clear() {
void cleanup(TypeInformation info) => info.cleanup();
void cleanup(TypeInformation info) {
if (!retainDataForTesting) {
info.cleanup();
}
}
types.allocatedCalls.forEach(cleanup);
types.allocatedCalls.clear();
@ -1119,9 +1125,9 @@ abstract class InferrerEngineImpl<T> extends InferrerEngine<T> {
types.allocatedLists.values.forEach(cleanup);
}
Iterable<MemberEntity> getCallersOf(MemberEntity element) {
Iterable<MemberEntity> getCallersOfForTesting(MemberEntity element) {
MemberTypeInformation info = types.getInferredTypeOfMember(element);
return info.callers;
return info.callersForTesting;
}
TypeInformation typeOfMemberWithSelector(

View file

@ -140,12 +140,12 @@ abstract class TypeGraphInferrer<T> implements TypesInferrer<T> {
return result;
}
Iterable<MemberEntity> getCallersOf(MemberEntity element) {
Iterable<MemberEntity> getCallersOfForTesting(MemberEntity element) {
if (_disableTypeInference) {
throw new UnsupportedError(
"Cannot query the type inferrer when type inference is disabled.");
}
return inferrer.getCallersOf(element);
return inferrer.getCallersOfForTesting(element);
}
bool isMemberCalledOnce(MemberEntity element) {

View file

@ -429,13 +429,8 @@ abstract class MemberTypeInformation extends ElementTypeInformation
}
}
Iterable<MemberEntity> get callers {
// TODO(sra): This is called only from an unused API and a test. If it
// becomes used, [cleanup] will need to copy `_caller.keys`.
// `simple_inferrer_callers_test.dart` ensures that cleanup has not
// happened.
return _callers.keys;
Iterable<MemberEntity> get callersForTesting {
return _callers?.keys;
}
bool isCalledOnce() {

View file

@ -254,7 +254,7 @@ usedByTests() {
closedWorld.getClassHierarchyNode(null);
closedWorld.getClassSet(null);
closedWorld.haveAnyCommonSubtypes(null, null);
typeGraphInferrer.getCallersOf(null);
typeGraphInferrer.getCallersOfForTesting(null);
dart_types.Types.sorted(null);
new dart_types.Types(null).copy(null);
}

View file

@ -542,6 +542,12 @@ Spannable computeSpannable(
if (id is NodeId) {
return new SourceSpan(mainUri, id.value, id.value + 1);
} else if (id is ElementId) {
String memberName = id.memberName;
bool isSetter = false;
if (memberName != '[]=' && memberName.endsWith('=')) {
isSetter = true;
memberName = memberName.substring(0, memberName.length - 1);
}
LibraryEntity library = elementEnvironment.lookupLibrary(mainUri);
if (id.className != null) {
ClassEntity cls =
@ -549,23 +555,22 @@ Spannable computeSpannable(
if (cls == null) {
throw new ArgumentError("No class '${id.className}' in $mainUri.");
}
MemberEntity member =
elementEnvironment.lookupClassMember(cls, id.memberName);
MemberEntity member = elementEnvironment
.lookupClassMember(cls, memberName, setter: isSetter);
if (member == null) {
ConstructorEntity constructor =
elementEnvironment.lookupConstructor(cls, id.memberName);
elementEnvironment.lookupConstructor(cls, memberName);
if (constructor == null) {
throw new ArgumentError(
"No class member '${id.memberName}' in $cls.");
throw new ArgumentError("No class member '${memberName}' in $cls.");
}
return constructor;
}
return member;
} else {
MemberEntity member =
elementEnvironment.lookupLibraryMember(library, id.memberName);
MemberEntity member = elementEnvironment
.lookupLibraryMember(library, memberName, setter: isSetter);
if (member == null) {
throw new ArgumentError("No member '${id.memberName}' in $mainUri.");
throw new ArgumentError("No member '${memberName}' in $mainUri.");
}
return member;
}

View file

@ -8,37 +8,40 @@ import 'dart:io';
import 'package:args/args.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/filenames.dart';
import 'package:compiler/src/inferrer/inferrer_engine.dart';
import 'package:compiler/src/io/source_file.dart';
import 'package:compiler/src/source_file_provider.dart';
import '../kernel/test_helpers.dart';
import 'id_equivalence_helper.dart';
show(List<String> args, ComputeMemberDataFunction computeAstData,
ComputeMemberDataFunction computeKernelData) async {
ArgParser createArgParser() {
ArgParser argParser = new ArgParser(allowTrailingOptions: true);
argParser.addFlag('verbose', negatable: true, defaultsTo: false);
argParser.addFlag('colors', negatable: true);
argParser.addFlag('all', negatable: false, defaultsTo: false);
argParser.addFlag('use-kernel', negatable: false, defaultsTo: false);
ArgResults argResults = argParser.parse(args);
return argParser;
}
show(ArgResults argResults, ComputeMemberDataFunction computeAstData,
ComputeMemberDataFunction computeKernelData) async {
if (argResults.wasParsed('colors')) {
useColors = argResults['colors'];
}
bool verbose = argResults['verbose'];
bool useKernel = argResults['use-kernel'];
InferrerEngineImpl.useSorterForTesting = true;
String file = argResults.rest.first;
Uri entryPoint = Uri.base.resolve(nativeToUriPath(file));
List<String> show;
if (argResults.rest.length > 1) {
if (argResults['all']) {
show = null;
} else if (argResults.rest.length > 1) {
show = argResults.rest.skip(1).toList();
} else {
show = [entryPoint.pathSegments.last];
}
List<String> options = <String>[];
List<String> options = <String>[stopAfterTypeInference];
if (useKernel) {
options.add(Flags.useKernel);
}

View file

@ -1,297 +0,0 @@
// Copyright (c) 2013, 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.
/// TODO(johnniwinther): Port this test to use the equivalence framework.
/// Currently it only works with the mock compiler.
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/types/masks.dart';
import 'package:expect/expect.dart';
import 'type_mask_test_helper.dart';
import '../compiler_helper.dart';
void compileAndFind(String code, String className, String memberName,
bool disableInlining, check(compiler, element)) {
Uri uri = new Uri(scheme: 'source');
var compiler = mockCompilerFor(code, uri, disableInlining: disableInlining);
asyncTest(() => compiler.run(uri).then((_) {
ClassElement cls = findElement(compiler, className);
var member = cls.lookupLocalMember(memberName);
return check(compiler, member);
}));
}
const String TEST_1 = r"""
class A {
x(p) => p;
}
main() { new A().x("s"); }
""";
const String TEST_2 = r"""
class A {
x(p) => p;
}
main() { new A().x(1); }
""";
const String TEST_3 = r"""
class A {
x(p) => x(p - 1);
}
main() { new A().x(1); }
""";
const String TEST_4 = r"""
class A {
x(p) => x(p - 1);
}
main() { new A().x(1.5); }
""";
const String TEST_5 = r"""
class A {
x(p) => p;
}
main() {
new A().x(1);
new A().x(1.5);
}
""";
const String TEST_6 = r"""
class A {
x(p) => p;
}
main() {
new A().x(1.5);
new A().x(1);
}
""";
const String TEST_7a = r"""
class A {
x(p) => x("x");
}
main() {
new A().x(1);
}
""";
const String TEST_7b = r"""
class A {
x(p) => x("x");
}
main() {
new A().x({});
}
""";
const String TEST_8 = r"""
class A {
x(p1, p2, p3) => x(p1, "x", {});
}
main() {
new A().x(1, 2, 3);
}
""";
const String TEST_9 = r"""
class A {
x(p1, p2) => x(p1, p2);
}
main() {
new A().x(1, 2);
}
""";
const String TEST_10 = r"""
class A {
x(p1, p2) => x(p1, p2);
}
void f(p) {
p.x("x", "y");
}
main() {
f(null);
new A().x(1, 2);
}
""";
const String TEST_11 = r"""
class A {
x(p1, p2) => x(1, 2);
}
main() {
new A().x("x", "y");
}
""";
const String TEST_12 = r"""
class A {
x(p1, [p2 = 1]) => 1;
}
main() {
new A().x("x", 1);
new A().x("x");
}
""";
const String TEST_13 = r"""
class A {
x(p) => 1;
}
f(p) => p.x(2.2);
main() {
new A().x(1);
f(new A());
}
""";
const String TEST_14 = r"""
class A {
x(p1, [p2 = "s"]) => 1;
}
main() {
new A().x(1);
}
""";
const String TEST_15 = r"""
class A {
x(p1, [p2 = true]) => 1;
}
f(p) => p.a("x");
main() {
new A().x("x");
new A().x("x", false);
f(null);
}
""";
const String TEST_16 = r"""
class A {
x(p1, [p2 = 1, p3 = "s"]) => 1;
}
main() {
new A().x(1);
new A().x(1, 2);
new A().x(1, 2, "x");
new A().x(1, p2: 2);
new A().x(1, p3: "x");
new A().x(1, p3: "x", p2: 2);
new A().x(1, p2: 2, p3: "x");
}
""";
const String TEST_17 = r"""
class A {
x(p1, [p2 = 1, p3 = "s"]) => 1;
}
main() {
new A().x(1, true, 1.1);
new A().x(1, false, 2.2);
new A().x(1, p3: 3.3, p2: true);
new A().x(1, p2: false, p3: 4.4);
}
""";
const String TEST_18 = r"""
class A {
x(p1, p2) => x(p1, p2);
}
class B extends A {
}
main() {
new B().x("a", "b");
new A().x(1, 2);
}
""";
typedef List<TypeMask> TestCallback(CommonMasks masks);
void doTest(String test, bool enableInlining, TestCallback f) {
compileAndFind(test, 'A', 'x', enableInlining, (compiler, element) {
var inferrer = compiler.globalInference.typesInferrerInternal;
var closedWorld = inferrer.closedWorld;
var expectedTypes = f(closedWorld.commonMasks);
var signature = element.functionSignature;
int index = 0;
signature.forEachParameter((Element element) {
Expect.equals(expectedTypes[index++],
simplify(inferrer.getTypeOfParameter(element), closedWorld), test);
});
Expect.equals(index, expectedTypes.length);
});
}
void runTest(String test, TestCallback f) {
doTest(test, false, f);
doTest(test, true, f);
}
void test() {
runTest(TEST_1, (commonMasks) => [commonMasks.stringType]);
runTest(TEST_2, (commonMasks) => [commonMasks.uint31Type]);
runTest(TEST_3, (commonMasks) => [commonMasks.intType]);
runTest(TEST_4, (commonMasks) => [commonMasks.numType]);
runTest(TEST_5, (commonMasks) => [commonMasks.numType]);
runTest(TEST_6, (commonMasks) => [commonMasks.numType]);
runTest(TEST_7a, (commonMasks) => [commonMasks.interceptorType]);
runTest(TEST_7b, (commonMasks) => [commonMasks.dynamicType.nonNullable()]);
runTest(
TEST_8,
(commonMasks) => [
commonMasks.uint31Type,
commonMasks.interceptorType,
commonMasks.dynamicType.nonNullable()
]);
runTest(TEST_9,
(commonMasks) => [commonMasks.uint31Type, commonMasks.uint31Type]);
runTest(TEST_10,
(commonMasks) => [commonMasks.uint31Type, commonMasks.uint31Type]);
runTest(
TEST_11,
(commonMasks) =>
[commonMasks.interceptorType, commonMasks.interceptorType]);
runTest(TEST_12,
(commonMasks) => [commonMasks.stringType, commonMasks.uint31Type]);
runTest(TEST_13, (commonMasks) => [commonMasks.numType]);
runTest(TEST_14,
(commonMasks) => [commonMasks.uint31Type, commonMasks.stringType]);
runTest(
TEST_15, (commonMasks) => [commonMasks.stringType, commonMasks.boolType]);
runTest(
TEST_16,
(commonMasks) => [
commonMasks.uint31Type,
commonMasks.uint31Type,
commonMasks.stringType
]);
runTest(
TEST_17,
(commonMasks) => [
commonMasks.uint31Type,
commonMasks.boolType,
commonMasks.doubleType
]);
runTest(
TEST_18,
(commonMasks) =>
[commonMasks.interceptorType, commonMasks.interceptorType]);
}
void main() {
test();
}

View file

@ -0,0 +1,20 @@
// Copyright (c) 2018, 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.
/*element: B.:[main]*/
class A {
/*element: A.field:[main]*/
var field;
}
/*element: A.:[main]*/
class B {
/*element: B.field:[main]*/
var field;
}
main() {
new A().field;
new B().field;
}

View file

@ -0,0 +1,145 @@
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:io';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/closure.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/inferrer/inferrer_engine.dart';
import 'package:compiler/src/inferrer/type_graph_inferrer.dart';
import 'package:compiler/src/kernel/element_map.dart';
import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
import 'package:compiler/src/tree/nodes.dart' as ast;
import 'package:kernel/ast.dart' as ir;
import '../equivalence/id_equivalence.dart';
import '../equivalence/id_equivalence_helper.dart';
main(List<String> args) {
InferrerEngineImpl.retainDataForTesting = true;
asyncTest(() async {
Directory dataDir =
new Directory.fromUri(Platform.script.resolve('callers'));
await checkTests(dataDir, computeMemberAstCallers, computeMemberIrCallers,
args: args, options: [stopAfterTypeInference]);
});
}
/// Compute callers data for [_member] as a [MemberElement].
///
/// Fills [actualMap] with the data.
void computeMemberAstCallers(
Compiler compiler, MemberEntity _member, Map<Id, ActualData> actualMap,
{bool verbose: false}) {
MemberElement member = _member;
ResolvedAst resolvedAst = member.resolvedAst;
compiler.reporter.withCurrentElement(member.implementation, () {
new CallersAstComputer(compiler.reporter, actualMap, resolvedAst,
compiler.globalInference.typesInferrerInternal)
.run();
});
}
abstract class ComputeValueMixin<T> {
TypeGraphInferrer get inferrer;
String getMemberValue(MemberEntity member) {
Iterable<MemberEntity> callers = inferrer.getCallersOfForTesting(member);
if (callers != null) {
List<String> names = callers.map((MemberEntity member) {
StringBuffer sb = new StringBuffer();
if (member.enclosingClass != null) {
sb.write(member.enclosingClass.name);
sb.write('.');
}
sb.write(member.name);
if (member.isSetter) {
sb.write('=');
}
return sb.toString();
}).toList()
..sort();
return '[${names.join(',')}]';
}
return null;
}
}
/// AST visitor for computing side effects data for a member.
class CallersAstComputer extends AstDataExtractor
with ComputeValueMixin<ast.Node> {
final TypeGraphInferrer inferrer;
CallersAstComputer(DiagnosticReporter reporter, Map<Id, ActualData> actualMap,
ResolvedAst resolvedAst, this.inferrer)
: super(reporter, actualMap, resolvedAst);
@override
String computeElementValue(Id id, AstElement element) {
if (element.isParameter) {
return null;
} else if (element.isLocal && element.isFunction) {
LocalFunctionElement localFunction = element;
return getMemberValue(localFunction.callMethod);
} else {
MemberElement member = element.declaration;
return getMemberValue(member);
}
}
@override
String computeNodeValue(Id id, ast.Node node, [AstElement element]) {
if (element != null && element.isLocal && element.isFunction) {
return computeElementValue(id, element);
}
return null;
}
}
/// Compute callers data for [member] from kernel based inference.
///
/// Fills [actualMap] with the data.
void computeMemberIrCallers(
Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
{bool verbose: false}) {
KernelBackendStrategy backendStrategy = compiler.backendStrategy;
KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
MemberDefinition definition = elementMap.getMemberDefinition(member);
new CallersIrComputer(
compiler.reporter,
actualMap,
elementMap,
compiler.globalInference.typesInferrerInternal,
backendStrategy.closureDataLookup as ClosureDataLookup<ir.Node>)
.run(definition.node);
}
/// AST visitor for computing side effects data for a member.
class CallersIrComputer extends IrDataExtractor
with ComputeValueMixin<ir.Node> {
final TypeGraphInferrer inferrer;
final KernelToElementMapForBuilding _elementMap;
final ClosureDataLookup<ir.Node> _closureDataLookup;
CallersIrComputer(DiagnosticReporter reporter, Map<Id, ActualData> actualMap,
this._elementMap, this.inferrer, this._closureDataLookup)
: super(reporter, actualMap);
@override
String computeMemberValue(Id id, ir.Member node) {
return getMemberValue(_elementMap.getMember(node));
}
@override
String computeNodeValue(Id id, ir.TreeNode node) {
if (node is ir.FunctionExpression || node is ir.FunctionDeclaration) {
ClosureRepresentationInfo info = _closureDataLookup.getClosureInfo(node);
return getMemberValue(info.callMethod);
}
return null;
}
}

View file

@ -1,90 +0,0 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// TODO(johnniwinther): Port this test to use the equivalence framework.
import 'dart:async';
import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import '../compiler_helper.dart';
Future compileAndFind(String code, String name, check(compiler, element)) {
Uri uri = new Uri(scheme: 'source');
var compiler = mockCompilerFor(code, uri);
return compiler.run(uri).then((_) {
var element = findElement(compiler, name);
check(compiler, element);
});
}
void checkPrintType(String expression, checkType(closedWorld, type)) {
asyncTest(() => compileAndFind('main() { print($expression); }', 'print',
(compiler, printElement) {
var parameter = printElement.functionSignature.requiredParameters.first;
checkType(compiler.resolutionWorldBuilder.closedWorldForTesting,
_typeOf(compiler, parameter));
}));
asyncTest(() =>
compileAndFind('main() { var x = print; print($expression); }', 'print',
(compiler, printElement) {
var parameter = printElement.functionSignature.requiredParameters.first;
checkType(compiler.resolutionWorldBuilder.closedWorldForTesting,
_typeOf(compiler, parameter));
}));
asyncTest(() => compileAndFind(
'main() { print($expression); print($expression); }', 'print',
(compiler, printElement) {
var parameter = printElement.functionSignature.requiredParameters.first;
checkType(compiler.resolutionWorldBuilder.closedWorldForTesting,
_typeOf(compiler, parameter));
}));
}
void testBasicTypes() {
checkPrintType('true', (closedWorld, type) {
if (type.isForwarding) type = type.forwardTo;
Expect.identical(closedWorld.commonMasks.boolType, type);
});
checkPrintType('1.5', (closedWorld, type) {
Expect.identical(closedWorld.commonMasks.doubleType, type);
});
checkPrintType('1', (closedWorld, type) {
Expect.identical(closedWorld.commonMasks.uint31Type, type);
});
checkPrintType('[]', (closedWorld, type) {
if (type.isForwarding) type = type.forwardTo;
Expect.identical(closedWorld.commonMasks.growableListType, type);
});
checkPrintType('null', (closedWorld, type) {
Expect.identical(closedWorld.commonMasks.nullType, type);
});
checkPrintType('"foo"', (closedWorld, type) {
Expect.isTrue(
closedWorld.commonMasks.stringType.containsOnlyString(closedWorld));
});
}
void testOptionalParameters() {
compileAndFind('fisk(a, [b, c]) {} main() { fisk(1); }', 'fisk',
(compiler, fiskElement) {
var firstParameter = fiskElement.functionSignature.requiredParameters[0];
var secondParameter = fiskElement.functionSignature.optionalParameters[0];
var thirdParameter = fiskElement.functionSignature.optionalParameters[1];
var commonMasks =
compiler.resolutionWorldBuilder.closedWorldForTesting.commonMasks;
Expect.identical(commonMasks.uint31Type, _typeOf(compiler, firstParameter));
Expect.identical(commonMasks.nullType, _typeOf(compiler, secondParameter));
Expect.identical(commonMasks.nullType, _typeOf(compiler, thirdParameter));
});
}
void main() {
testBasicTypes();
testOptionalParameters();
}
_typeOf(compiler, parameter) =>
compiler.globalInference.results.resultOfParameter(parameter).type;

View file

@ -0,0 +1,309 @@
// Copyright (c) 2018, 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.
/*element: main:[null]*/
main() {
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test8();
test9();
test10();
test11();
test12();
test13();
test14();
test15();
test16();
test17();
test18();
test19();
}
/*element: A1.:[exact=A1]*/
class A1 {
/*element: A1.x1:Value([exact=JSString], value: "s")*/
x1(
/*Value([exact=JSString], value: "s")*/ p) =>
p;
}
/*element: test1:[null]*/
test1() {
new A1(). /*invoke: [exact=A1]*/ x1("s");
}
/*element: A2.:[exact=A2]*/
class A2 {
/*element: A2.x2:[exact=JSUInt31]*/
x2(/*[exact=JSUInt31]*/ p) => p;
}
/*element: test2:[null]*/
test2() {
new A2(). /*invoke: [exact=A2]*/ x2(1);
}
/*element: A3.:[exact=A3]*/
class A3 {
/*element: A3.x3:[empty]*/
x3(/*[subclass=JSInt]*/ p) => /*invoke: [exact=A3]*/ x3(
p /*invoke: [subclass=JSInt]*/ - 1);
}
/*element: test3:[null]*/
test3() {
new A3(). /*invoke: [exact=A3]*/ x3(1);
}
/*element: A4.:[exact=A4]*/
class A4 {
/*element: A4.x4:[empty]*/
x4(/*[subclass=JSNumber]*/ p) => /*invoke: [exact=A4]*/ x4(
p /*invoke: [subclass=JSNumber]*/ - 1);
}
/*element: test4:[null]*/
test4() {
new A4(). /*invoke: [exact=A4]*/ x4(1.5);
}
/*element: A5.:[exact=A5]*/
class A5 {
/*element: A5.x5:Union([exact=JSDouble], [exact=JSUInt31])*/
x5(
/*Union([exact=JSDouble], [exact=JSUInt31])*/ p) =>
p;
}
/*element: test5:[null]*/
test5() {
new A5(). /*invoke: [exact=A5]*/ x5(1);
new A5(). /*invoke: [exact=A5]*/ x5(1.5);
}
/*element: A6.:[exact=A6]*/
class A6 {
/*element: A6.x6:Union([exact=JSDouble], [exact=JSUInt31])*/
x6(
/*Union([exact=JSDouble], [exact=JSUInt31])*/ p) =>
p;
}
/*element: test6:[null]*/
test6() {
new A6(). /*invoke: [exact=A6]*/ x6(1.5);
new A6(). /*invoke: [exact=A6]*/ x6(1);
}
/*element: A7.:[exact=A7]*/
class A7 {
/*element: A7.x7:[empty]*/
x7(
/*Union([exact=JSString], [exact=JSUInt31])*/ p) => /*invoke: [exact=A7]*/ x7("x");
}
/*element: test7:[null]*/
test7() {
new A7(). /*invoke: [exact=A7]*/ x7(1);
}
/*element: A8.:[exact=A8]*/
class A8 {
/*element: A8.x8:[empty]*/
x8(
/*Union([exact=JSString], [subclass=JsLinkedHashMap])*/ p) =>
/*invoke: [exact=A8]*/ x8("x");
}
/*element: test8:[null]*/
test8() {
new A8(). /*invoke: [exact=A8]*/ x8({});
}
/*element: A9.:[exact=A9]*/
class A9 {
/*element: A9.x9:[empty]*/ x9(
/*[exact=JSUInt31]*/ p1,
/*Union([exact=JSString], [exact=JSUInt31])*/ p2,
/*Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/ p3) =>
/*invoke: [exact=A9]*/ x9(p1, "x", {});
}
/*element: test9:[null]*/
test9() {
new A9(). /*invoke: [exact=A9]*/ x9(1, 2, 3);
}
/*element: A10.:[exact=A10]*/
class A10 {
/*element: A10.x10:[empty]*/ x10(
/*[exact=JSUInt31]*/ p1,
/*[exact=JSUInt31]*/ p2) => /*invoke: [exact=A10]*/ x10(p1, p2);
}
/*element: test10:[null]*/
test10() {
new A10(). /*invoke: [exact=A10]*/ x10(1, 2);
}
/*element: A11.:[exact=A11]*/
class A11 {
/*element: A11.x11:[empty]*/
x11(
/*[exact=JSUInt31]*/ p1,
/*[exact=JSUInt31]*/ p2) => /*invoke: [exact=A11]*/ x11(p1, p2);
}
/*element: f11:[null]*/
void f11(/*[null]*/ p) {
p. /*invoke: [null]*/ x11("x", "y");
}
/*element: test11:[null]*/
test11() {
f11(null);
new A11(). /*invoke: [exact=A11]*/ x11(1, 2);
}
/*element: A12.:[exact=A12]*/
class A12 {
/*element: A12.x12:[empty]*/
x12(
/*Union([exact=JSString], [exact=JSUInt31])*/ p1,
/*Union([exact=JSString], [exact=JSUInt31])*/ p2) =>
/*invoke: [exact=A12]*/ x12(1, 2);
}
/*element: test12:[null]*/
test12() {
new A12(). /*invoke: [exact=A12]*/ x12("x", "y");
}
/*element: A13.:[exact=A13]*/
class A13 {
/*element: A13.x13:[exact=JSUInt31]*/
x13(
/*Value([exact=JSString], value: "x")*/ p1,
[/*[exact=JSUInt31]*/ p2 = 1]) =>
1;
}
/*element: test13:[null]*/
test13() {
new A13(). /*invoke: [exact=A13]*/ x13("x", 1);
new A13(). /*invoke: [exact=A13]*/ x13("x");
}
/*element: A14.:[exact=A14]*/
class A14 {
/*element: A14.x14:[exact=JSUInt31]*/
x14(
/*Union([exact=JSDouble], [exact=JSUInt31])*/ p) =>
1;
}
/*element: f14:[exact=JSUInt31]*/
f14(/*[exact=A14]*/ p) => p. /*invoke: [exact=A14]*/ x14(2.2);
/*element: test14:[null]*/
test14() {
new A14(). /*invoke: [exact=A14]*/ x14(1);
f14(new A14());
}
/*element: A15.:[exact=A15]*/
class A15 {
/*element: A15.x15:[exact=JSUInt31]*/
x15(/*[exact=JSUInt31]*/ p1,
[/*Value([exact=JSString], value: "s")*/ p2 = "s"]) =>
1;
}
/*element: test15:[null]*/
test15() {
new A15(). /*invoke: [exact=A15]*/ x15(1);
}
/*element: A16.:[exact=A16]*/
class A16 {
/*element: A16.x16:[exact=JSUInt31]*/
x16(
/*Value([exact=JSString], value: "x")*/ p1,
[/*[exact=JSBool]*/ p2 = true]) =>
1;
}
/*element: f16:[empty]*/
f16(/*[null]*/ p) => p. /*invoke: [null]*/ a("x");
/*element: test16:[null]*/
test16() {
new A16(). /*invoke: [exact=A16]*/ x16("x");
new A16(). /*invoke: [exact=A16]*/ x16("x", false);
f16(null);
}
/*element: A17.:[exact=A17]*/
class A17 {
/*element: A17.x17:[exact=JSUInt31]*/
x17(/*[exact=JSUInt31]*/ p1,
[/*[exact=JSUInt31]*/ p2 = 1, /*[exact=JSString]*/ p3 = "s"]) =>
1;
}
/*element: test17:[null]*/
test17() {
new A17(). /*invoke: [exact=A17]*/ x17(1);
new A17(). /*invoke: [exact=A17]*/ x17(1, 2);
new A17(). /*invoke: [exact=A17]*/ x17(1, 2, "x");
// ignore: undefined_named_parameter
new A17(). /*invoke: [exact=A17]*/ x17(1, p2: 2);
// ignore: undefined_named_parameter
new A17(). /*invoke: [exact=A17]*/ x17(1, p3: "x");
// ignore: undefined_named_parameter
new A17(). /*invoke: [exact=A17]*/ x17(1, p3: "x", p2: 2);
// ignore: undefined_named_parameter
new A17(). /*invoke: [exact=A17]*/ x17(1, p2: 2, p3: "x");
}
/*element: A18.:[exact=A18]*/
class A18 {
/*element: A18.x18:[exact=JSUInt31]*/
x18(/*[exact=JSUInt31]*/ p1,
[/*[exact=JSBool]*/ p2 = 1, /*[exact=JSDouble]*/ p3 = "s"]) =>
1;
}
/*element: test18:[null]*/
test18() {
new A18(). /*invoke: [exact=A18]*/ x18(1, true, 1.1);
new A18(). /*invoke: [exact=A18]*/ x18(1, false, 2.2);
// ignore: undefined_named_parameter
new A18(). /*invoke: [exact=A18]*/ x18(1, p3: 3.3, p2: true);
// ignore: undefined_named_parameter
new A18(). /*invoke: [exact=A18]*/ x18(1, p2: false, p3: 4.4);
}
/*element: A19.:[exact=A19]*/
class A19 {
/*element: A19.x19:[empty]*/
x19(
/*Union([exact=JSString], [exact=JSUInt31])*/ p1,
/*Union([exact=JSString], [exact=JSUInt31])*/ p2) =>
/*invoke: [subclass=A19]*/ x19(p1, p2);
}
/*element: B19.:[exact=B19]*/
class B19 extends A19 {}
/*element: test19:[null]*/
test19() {
new B19(). /*invoke: [exact=B19]*/ x19("a", "b");
new A19(). /*invoke: [exact=A19]*/ x19(1, 2);
}

View file

@ -0,0 +1,196 @@
// Copyright (c) 2018, 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.
/*element: main:[null]*/
main() {
test1();
test2();
test3();
test4();
test5();
}
/*element: dictionaryA1:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
var dictionaryA1 = {'string': "aString", 'int': 42, 'double': 21.5, 'list': []};
/*element: dictionaryB1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
var dictionaryB1 = {'string': "aString", 'int': 42, 'double': 21.5, 'list': []};
/*element: otherDict1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {stringTwo: Value([exact=JSString], value: "anotherString"), intTwo: [exact=JSUInt31]})*/
var otherDict1 = {'stringTwo': "anotherString", 'intTwo': 84};
/*element: int1:[exact=JSUInt31]*/
var int1 = 0;
/*element: anotherInt1:[exact=JSUInt31]*/
var anotherInt1 = 0;
/*element: nullOrInt1:[null|exact=JSUInt31]*/
var nullOrInt1 = 0;
/*element: dynamic1:[null|subclass=Object]*/
var dynamic1 = 0;
/*element: test1:[null]*/
test1() {
dictionaryA1
. /*invoke: Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
addAll(otherDict1);
dictionaryB1
. /*invoke: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
addAll({'stringTwo': "anotherString", 'intTwo': 84});
int1 = dictionaryB1
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
['int'];
anotherInt1 = otherDict1
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {stringTwo: Value([exact=JSString], value: "anotherString"), intTwo: [exact=JSUInt31]})*/
['intTwo'];
dynamic1 = dictionaryA1
/*Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/ [
'int'];
nullOrInt1 = dictionaryB1
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
['intTwo'];
}
/*element: dictionaryA2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
var dictionaryA2 = {'string': "aString", 'int': 42, 'double': 21.5, 'list': []};
/*element: dictionaryB2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), intTwo: [exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
var dictionaryB2 = {'string': "aString", 'intTwo': 42, 'list': []};
/*element: nullOrInt2:[null|exact=JSUInt31]*/
var nullOrInt2 = 0;
/*element: aString2:[exact=JSString]*/
var aString2 = "";
/*element: doubleOrNull2:[null|exact=JSDouble]*/
var doubleOrNull2 = 22.2;
/*element: test2:[null]*/
test2() {
var union = dictionaryA2
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
['foo']
? dictionaryA2
: dictionaryB2;
nullOrInt2 = union
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {int: [null|exact=JSUInt31], double: [null|exact=JSDouble], string: Value([exact=JSString], value: "aString"), intTwo: [null|exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
['intTwo'];
aString2 = union
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {int: [null|exact=JSUInt31], double: [null|exact=JSDouble], string: Value([exact=JSString], value: "aString"), intTwo: [null|exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
['string'];
doubleOrNull2 = union
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {int: [null|exact=JSUInt31], double: [null|exact=JSDouble], string: Value([exact=JSString], value: "aString"), intTwo: [null|exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
['double'];
}
/*element: dictionary3:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
var dictionary3 = {'string': "aString", 'int': 42, 'double': 21.5, 'list': []};
/*element: keyD3:Value([exact=JSString], value: "double")*/
var keyD3 = 'double';
/*element: keyI3:Value([exact=JSString], value: "int")*/
var keyI3 = 'int';
/*element: keyN3:Value([exact=JSString], value: "notFoundInMap")*/
var keyN3 = 'notFoundInMap';
/*element: knownDouble3:[exact=JSDouble]*/
var knownDouble3 = 42.2;
/*element: intOrNull3:[null|exact=JSUInt31]*/
var intOrNull3 = dictionary3
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
[keyI3];
/*element: justNull3:[null]*/
var justNull3 = dictionary3
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
[keyN3];
/*element: test3:[null]*/
test3() {
knownDouble3 = dictionary3
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
[keyD3];
// ignore: unused_local_variable
var x = [intOrNull3, justNull3];
}
class A4 {
/*element: A4.:[exact=A4]*/
A4();
/*element: A4.foo4:[exact=JSUInt31]*/
foo4(
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ value) {
return value /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ [
'anInt'];
}
}
class B4 {
/*element: B4.:[exact=B4]*/
B4();
/*element: B4.foo4:[exact=JSUInt31]*/
foo4(
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ value) {
return 0;
}
}
/*element: test4:[null]*/
test4() {
var dictionary = {'anInt': 42, 'aString': "theString"};
var it;
if ([true, false]
/*Container([exact=JSExtendableArray], element: [exact=JSBool], length: 2)*/
[0]) {
it = new A4();
} else {
it = new B4();
}
print(it. /*invoke: Union([exact=A4], [exact=B4])*/ foo4(
dictionary) /*invoke: [exact=JSUInt31]*/ +
2);
}
/*element: dict5:Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
var dict5 = makeMap5([1, 2]);
/*element: notInt5:[null|subclass=Object]*/
var notInt5 = 0;
/*element: alsoNotInt5:[null|subclass=Object]*/
var alsoNotInt5 = 0;
/*element: makeMap5:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
makeMap5(
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 2)*/ values) {
return {
'moo': values
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 2)*/
[0],
'boo': values
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 2)*/
[1]
};
}
/*element: test5:[null]*/
test5() {
dict5
/*update: Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
['goo'] = 42;
var closure =
/*Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
() => dict5;
notInt5 = closure()['boo'];
alsoNotInt5 = dict5
/*Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
['goo'];
print("$notInt5 and $alsoNotInt5.");
}

View file

@ -0,0 +1,189 @@
// Copyright (c) 2018, 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.
/*element: main:[null]*/
main() {
test1();
test2();
test3();
test4();
test5();
test6();
}
/*element: aDouble1:[null|exact=JSDouble]*/
double aDouble1 = 42.5;
/*element: aList1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
List aList1 = [42];
/*element: consume1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
consume1(
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
x;
/*element: test1:[null]*/
test1() {
var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4};
theMap
/*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSDouble], map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: [null|exact=JSDouble]})*/
['d'] = 5.5;
/*iterator: [exact=LinkedHashMapKeyIterable]*/
/*current: [exact=LinkedHashMapKeyIterator]*/
/*moveNext: [exact=LinkedHashMapKeyIterator]*/
for (var key in theMap.
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSDouble], map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: [null|exact=JSDouble]})*/
keys) {
aDouble1 = theMap
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSDouble], map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: [null|exact=JSDouble]})*/
[key];
}
// We have to reference it somewhere, so that it always gets resolved.
consume1(aList1);
}
/*element: aDouble2:[null|exact=JSDouble]*/
double aDouble2 = 42.5;
/*element: aList2:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
List aList2 = [42];
/*element: consume2:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
consume2(
/*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
x;
/*element: test2:[null]*/
test2() {
dynamic theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4};
theMap
/*update: Map([subclass=JsLinkedHashMap], key: Union([exact=JSExtendableArray], [exact=JSString]), value: [null|exact=JSDouble])*/
[aList2] = 5.5;
/*iterator: [exact=LinkedHashMapKeyIterable]*/
/*current: [exact=LinkedHashMapKeyIterator]*/
/*moveNext: [exact=LinkedHashMapKeyIterator]*/
for (var key in theMap.
/*Map([subclass=JsLinkedHashMap], key: Union([exact=JSExtendableArray], [exact=JSString]), value: [null|exact=JSDouble])*/
keys) {
aDouble2 = theMap
/*Map([subclass=JsLinkedHashMap], key: Union([exact=JSExtendableArray], [exact=JSString]), value: [null|exact=JSDouble])*/
[key];
}
// We have to reference it somewhere, so that it always gets resolved.
consume2(aList2);
}
/*element: aDouble3:Union([exact=JSDouble], [null|exact=JSExtendableArray])*/
double aDouble3 = 42.5;
/*element: aList3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
List aList3 = [42];
/*element: consume3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
consume3(
/*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
x;
/*element: test3:[null]*/
test3() {
dynamic theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4};
theMap
/*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [null|exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
['d'] = aList3;
/*iterator: [exact=LinkedHashMapKeyIterable]*/
/*current: [exact=LinkedHashMapKeyIterator]*/
/*moveNext: [exact=LinkedHashMapKeyIterator]*/
for (var key in theMap.
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [null|exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
keys) {
aDouble3 = theMap
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [null|exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
[key];
}
// We have to reference it somewhere, so that it always gets resolved.
consume3(aList3);
}
/*element: aDouble4:[null|exact=JSDouble]*/
double aDouble4 = 42.5;
/*element: aList4:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
List aList4 = [42];
/*element: consume4:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
consume4(
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
x;
/*element: test4:[null]*/
test4() {
var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4, 'd': 5.5};
/*iterator: [exact=LinkedHashMapKeyIterable]*/
/*current: [exact=LinkedHashMapKeyIterator]*/
/*moveNext: [exact=LinkedHashMapKeyIterator]*/
for (var key in theMap.
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSDouble], map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: [exact=JSDouble]})*/
keys) {
aDouble4 = theMap
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSDouble], map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: [exact=JSDouble]})*/
[key];
}
// We have to reference it somewhere, so that it always gets resolved.
consume4(aList4);
}
/*element: aDouble5:[null|exact=JSDouble]*/
double aDouble5 = 42.5;
/*element: aList5:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
List aList5 = [42];
/*element: consume5:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
consume5(
/*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
x;
/*element: test5:[null]*/
test5() {
var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4, aList5: 5.5};
/*iterator: [exact=LinkedHashMapKeyIterable]*/
/*current: [exact=LinkedHashMapKeyIterator]*/
/*moveNext: [exact=LinkedHashMapKeyIterator]*/
for (var key in theMap.
/*Map([subclass=JsLinkedHashMap], key: Union([exact=JSExtendableArray], [exact=JSString]), value: [null|exact=JSDouble])*/
keys) {
aDouble5 = theMap
/*Map([subclass=JsLinkedHashMap], key: Union([exact=JSExtendableArray], [exact=JSString]), value: [null|exact=JSDouble])*/
[key];
}
// We have to reference it somewhere, so that it always gets resolved.
consume5(aList5);
}
/*element: aDouble6:Union([null|exact=JSDouble], [null|exact=JSExtendableArray])*/
double aDouble6 = 42.5;
/*element: aList6:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
List aList6 = [42];
/*element: consume6:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
consume6(
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
x;
/*element: test6:[null]*/
test6() {
var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4, 'd': aList6};
/*iterator: [exact=LinkedHashMapKeyIterable]*/
/*current: [exact=LinkedHashMapKeyIterator]*/
/*moveNext: [exact=LinkedHashMapKeyIterator]*/
for (var key in theMap.
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [null|exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
keys) {
aDouble6 = theMap
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([null|exact=JSDouble], [null|exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
[key];
}
// We have to reference it somewhere, so that it always gets resolved.
consume6(aList6);
}

View file

@ -1,173 +0,0 @@
// Copyright (c) 2014, 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.
/// TODO(johnniwinther): Port this test to use the equivalence framework.
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:expect/expect.dart';
import '../memory_compiler.dart';
var SOURCES = const {
'AddAll.dart': """
var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5,
'list': []};
var dictionaryB = {'string': "aString", 'int': 42, 'double': 21.5,
'list': []};
var otherDict = {'stringTwo' : "anotherString", 'intTwo' : 84};
var int = 0;
var anotherInt = 0;
var nullOrInt = 0;
var dynamic = 0;
main() {
dictionaryA.addAll(otherDict);
dictionaryB.addAll({'stringTwo' : "anotherString", 'intTwo' : 84});
int = dictionaryB['int'];
anotherInt = otherDict['intTwo'];
dynamic = dictionaryA['int'];
nullOrInt = dictionaryB['intTwo'];
}
""",
'Union.dart': """
var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5,
'list': []};
var dictionaryB = {'string': "aString", 'intTwo': 42, 'list': []};
var nullOrInt = 0;
var aString = "";
var doubleOrNull = 22.2;
var key = "string";
main() {
var union = dictionaryA['foo'] ? dictionaryA : dictionaryB;
nullOrInt = union['intTwo'];
aString = union['string'];
doubleOrNull = union['double'];
}
""",
'ValueType.dart': """
var dictionary = {'string': "aString", 'int': 42, 'double': 21.5, 'list': []};
var keyD = 'double';
var keyI = 'int';
var keyN = 'notFoundInMap';
var knownDouble = 42.2;
var intOrNull = dictionary[keyI];
var justNull = dictionary[keyN];
main() {
knownDouble = dictionary[keyD];
var x = [intOrNull, justNull];
}
""",
'Propagation.dart': """
class A {
A();
foo(value) {
return value['anInt'];
}
}
class B {
B();
foo(value) {
return 0;
}
}
main() {
var dictionary = {'anInt': 42, 'aString': "theString"};
var it;
if ([true, false][0]) {
it = new A();
} else {
it = new B();
}
print(it.foo(dictionary) + 2);
}
""",
'Bailout.dart': """
var dict = makeMap([1,2]);
var notInt = 0;
var alsoNotInt = 0;
makeMap(values) {
return {'moo': values[0], 'boo': values[1]};
}
main () {
dict['goo'] = 42;
var closure = () => dict;
notInt = closure()['boo'];
alsoNotInt = dict['goo'];
print("\$notInt and \$alsoNotInt.");
}
"""
};
void main() {
asyncTest(() async {
print('--test from ast---------------------------------------------------');
await runTests(useKernel: false);
print('--test from kernel------------------------------------------------');
await runTests(useKernel: true);
});
}
runTests({bool useKernel}) async {
await compileAndTest("AddAll.dart", (types, getType, closedWorld) {
Expect.equals(getType('int'), types.uint31Type);
Expect.equals(getType('anotherInt'), types.uint31Type);
Expect.equals(getType('dynamic'), types.dynamicType);
Expect.equals(getType('nullOrInt'), types.uint31Type.nullable());
}, useKernel: useKernel);
await compileAndTest("Union.dart", (types, getType, closedWorld) {
Expect.equals(getType('nullOrInt'), types.uint31Type.nullable());
Expect.isTrue(getType('aString').containsOnlyString(closedWorld));
Expect.equals(getType('doubleOrNull'), types.doubleType.nullable());
}, useKernel: useKernel);
await compileAndTest("ValueType.dart", (types, getType, closedWorld) {
Expect.equals(getType('knownDouble'), types.doubleType);
Expect.equals(getType('intOrNull'), types.uint31Type.nullable());
Expect.equals(getType('justNull'), types.nullType);
}, useKernel: useKernel);
await compileAndTest("Propagation.dart", (code) {
Expect.isFalse(code.contains("J.\$add\$ns"));
}, createCode: true, useKernel: useKernel);
await compileAndTest("Bailout.dart", (types, getType, closedWorld) {
Expect.equals(getType('notInt'), types.dynamicType);
Expect.equals(getType('alsoNotInt'), types.dynamicType);
Expect.isFalse(getType('dict').isDictionary);
}, useKernel: useKernel);
}
compileAndTest(source, checker,
{bool createCode: false, bool useKernel}) async {
CompilationResult result = await runCompiler(
entryPoint: Uri.parse('memory:' + source),
memorySourceFiles: SOURCES,
beforeRun: (compiler) {
compiler.stopAfterTypeInference = !createCode;
},
options: useKernel ? [Flags.useKernel] : []);
var compiler = result.compiler;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
var closedWorld = typesInferrer.closedWorld;
var elementEnvironment = closedWorld.elementEnvironment;
var commonMasks = closedWorld.commonMasks;
getType(String name) {
var element = elementEnvironment.lookupLibraryMember(
elementEnvironment.mainLibrary, name);
Expect.isNotNull(element, "No class '$name' found.");
return typesInferrer.getTypeOfMember(element);
}
if (!createCode) {
checker(commonMasks, getType, closedWorld);
} else {
var element = elementEnvironment.mainFunction;
var code = compiler.backend.getGeneratedCode(element);
checker(code);
}
}

View file

@ -1,689 +0,0 @@
// Copyright (c) 2013, 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.
/// TODO(johnniwinther): Port this test to use the equivalence framework.
/// Currently it only works with the mock compiler.
import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/types/types.dart' show TypeMask;
import 'package:compiler/src/world.dart' show ClosedWorld;
import 'type_mask_test_helper.dart';
import '../compiler_helper.dart';
void compileAndFind(String code, String className, String memberName,
bool disableInlining, check(compiler, element)) {
Uri uri = new Uri(scheme: 'source');
var compiler = mockCompilerFor(code, uri, disableInlining: disableInlining);
asyncTest(() => compiler.run(uri).then((_) {
dynamic cls = findElement(compiler, className);
var member = cls.lookupMember(memberName);
check(compiler, member);
}));
}
const String TEST_1 = r"""
class A {
int f;
}
main() { new A(); }
""";
const String TEST_2 = r"""
class A {
int f1;
int f2 = 1;
}
main() { new A(); }
""";
const String TEST_3 = r"""
class A {
int f1;
int f2;
A() : f1 = 1;
}
main() { new A().f2 = 2; }
""";
const String TEST_4 = r"""
class A {
int f1;
int f2;
A() : f1 = 1;
}
main() {
A a = new A();
a.f1 = "a";
a.f2 = "a";
}
""";
const String TEST_5 = r"""
class A {
int f1 = 1;
int f2 = 1;
A(x) {
f1 = "1";
if (x) {
f2 = "1";
} else {
f2 = "2";
}
}
}
main() {
new A(true);
new A(false);
}
""";
const String TEST_6 = r"""
class A {
int f1 = 1;
int f2 = 1;
A(x) {
f1 = "1";
if (x) {
f2 = "1";
} else {
f2 = "2";
}
if (x) {
f2 = new List();
} else {
f2 = new List();
}
}
}
main() {
new A(true);
new A(false);
}
""";
const String TEST_7 = r"""
class A {
int f1 = 1;
int f2 = 1;
A(x) {
f1 = "1";
if (x) {
f2 = "1";
} else {
f2 = "2";
}
if (x) {
f1 = new List();
f2 = new List();
} else {
f2 = new List();
}
}
}
main() {
new A(true);
new A(false);
}
""";
const String TEST_8 = r"""
class A {
int f;
A(x) {
if (x) {
f = "1";
} else {
}
}
}
main() {
new A(true);
new A(false);
}
""";
const String TEST_9 = r"""
class A {
int f;
A(x) {
if (x) {
} else {
f = "1";
}
}
}
main() {
new A(true);
new A(false);
}
""";
const String TEST_10 = r"""
class A {
int f;
A() {
f = 1;
}
m() => f + 1;
}
void f(x) { x.f = "2"; }
main() {
A a;
f(a);
a = new A();
a.m();
}
""";
const String TEST_11 = r"""
class S {
int fs = 1;
ms() { fs = 1; }
}
class A extends S {
m() { ms(); }
}
main() {
A a = new A();
a.m();
}
""";
const String TEST_12 = r"""
class S {
int fs = 1;
S() { fs = "2"; }
}
class A extends S {
}
main() {
A a = new A();
}
""";
const String TEST_13 = r"""
class S {
int fs;
S() { fs = 1; }
}
class A extends S {
A() { fs = 1; }
}
main() {
A a = new A();
}
""";
const String TEST_14 = r"""
class A {
var f;
A() { f = 1; }
A.other() { f = 2; }
}
main() {
A a = new A();
a = new A.other();
}
""";
const String TEST_15 = r"""
class A {
var f;
A() { f = "1"; }
A.other() { f = new List(); }
}
main() {
A a = new A();
a = new A.other();
}
""";
const String TEST_16 = r"""
class A {
var f;
A() { f = "1"; }
A.other() : f = 1 { }
}
main() {
A a = new A();
a = new A.other();
}
""";
const String TEST_17 = r"""
g([p]) => p.f = 1;
class A {
var f;
A(x) {
var a;
if (x) {
a = this;
} else {
a = g;
}
a(this);
}
}
main() {
new A(true);
new A(false);
}
""";
const String TEST_18 = r"""
class A {
var f1;
var f2;
var f3;
A(x) {
f1 = 1;
var a;
if (x) {
f2 = "1";
a = this;
} else {
a = 1;
f2 = "1";
}
f3 = a;
}
}
main() {
new A(true);
new A(false);
}
""";
const String TEST_19 = r"""
class A {
var f1;
var f2;
var f3;
A(x) {
f1 = 1;
var a;
if (x) {
f2 = "1";
a = this;
} else {
a = 1;
f2 = "1";
}
f3 = a;
a();
}
}
main() {
new A(true);
new A(false);
}
""";
const String TEST_20 = r"""
class A {
var f;
A() {
for (f in this) {
}
}
get iterator => this;
get current => 42;
bool moveNext() => false;
}
main() {
new A();
}
""";
const String TEST_21 = r"""
class A {
var f;
A() {
for (var i in this) {
}
f = 42;
}
get iterator => null;
}
main() {
new A();
}
""";
const String TEST_22 = r"""
class A {
var f1;
var f2;
var f3;
A() {
f1 = 42;
f2 = f1 == null ? 42 : f3 == null ? 41: 43;
f3 = 'foo';
}
}
main() {
new A();
}
""";
const String TEST_23 = r"""
class A {
var f1 = 42;
var f2 = 42;
var f3 = 42;
var f4 = 42;
A() {
// Test string interpolation.
'${f1 = null}';
// Test string juxtaposition.
''
'${f2 = null}';
// Test list literal.
[f3 = null];
// Test map literal.
var c = {'foo': f4 = null };
}
}
main() {
new A();
}
""";
const String TEST_24 = r"""
class A {
var f1 = 42;
var f2 = 42;
var f3 = 42;
final f4;
var f5;
var f6 = null;
A() : f4 = 42 {
f1++;
f2 += 42;
var f6 = 'foo';
this.f6 = f6;
}
A.foo(other) : f3 = other.f3, f4 = other.f4, f5 = other.bar();
operator+(other) => 'foo';
bar() => 42.5;
}
class B extends A {
bar() => 42;
}
main() {
new A();
new A.foo(new A());
new A.foo(new B());
}
""";
const String TEST_25 = r"""
class A {
var f1 = 42;
}
class B {
var f1 = '42';
}
main() {
new B();
new A().f1 = new A().f1;
}
""";
const String TEST_26 = r"""
class A {
var f1 = 42;
}
class B {
var f1 = 54;
}
main() {
new A().f1 = [new B(), new A()][0].f1 + 42;
}
""";
const String TEST_27 = r"""
class A {
var f1;
var f2;
A() {
this.f1 = 42;
this.f2 = 42;
}
}
class B extends A {
set f2(value) {}
}
main() {
new A();
new B();
}
""";
const String TEST_28 = r"""
class A {
var f1;
var f2;
A(x) {
this.f1 = x;
if (x == 0) return;
this.f2 = x;
}
}
main() {
new A(0);
new A(1);
}
""";
const String TEST_29 = r"""
class A {
var f1;
var f2;
A(x) {
this.f1 = x;
if (x == 0) {
} else {
return;
}
this.f2 = x;
}
}
main() {
new A(0);
new A(1);
}
""";
const String TEST_30 = r"""
class A {
var f1;
var f2;
var f3;
A(x) {
this.f1 = x;
if (x == 0) {
this.f2 = 1;
} else {
this.f2 = x;
return;
}
this.f3 = x;
}
}
main() {
new A(0);
new A(1);
}
""";
typedef TypeMask TestCallback(ClosedWorld closedWorld);
void doTest(
String test, bool disableInlining, Map<String, TestCallback> fields) {
fields.forEach((String name, TestCallback f) {
compileAndFind(test, 'A', name, disableInlining, (compiler, field) {
var inferrer = compiler.globalInference.typesInferrerInternal;
var closedWorld = inferrer.closedWorld;
TypeMask type = f(closedWorld);
TypeMask inferredType =
simplify(inferrer.getTypeOfMember(field), closedWorld);
Expect.equals(type, inferredType, '$name of:\n$test');
});
});
}
void runTest(String test, Map<String, TestCallback> fields) {
doTest(test, false, fields);
doTest(test, true, fields);
}
void test() {
runTest(TEST_1, <String, TestCallback>{
'f': (closedWorld) => closedWorld.commonMasks.nullType
});
runTest(TEST_2, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.nullType,
'f2': (closedWorld) => closedWorld.commonMasks.uint31Type
});
runTest(TEST_3, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f2': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_4, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.interceptorType,
'f2': (closedWorld) => closedWorld.commonMasks.stringType.nullable()
});
// TODO(ngeoffray): We should try to infer that the initialization
// code at the declaration site of the fields does not matter.
runTest(TEST_5, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.interceptorType,
'f2': (closedWorld) => closedWorld.commonMasks.interceptorType,
});
runTest(TEST_6, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.interceptorType,
'f2': (closedWorld) => closedWorld.commonMasks.interceptorType,
});
runTest(TEST_7, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.interceptorType,
'f2': (closedWorld) => closedWorld.commonMasks.interceptorType,
});
runTest(TEST_8, <String, TestCallback>{
'f': (closedWorld) => closedWorld.commonMasks.stringType.nullable()
});
runTest(TEST_9, <String, TestCallback>{
'f': (closedWorld) => closedWorld.commonMasks.stringType.nullable()
});
runTest(TEST_10, <String, TestCallback>{
'f': (closedWorld) => closedWorld.commonMasks.uint31Type
});
runTest(TEST_11, <String, TestCallback>{
'fs': (closedWorld) => closedWorld.commonMasks.uint31Type
});
// TODO(ngeoffray): We should try to infer that the initialization
// code at the declaration site of the fields does not matter.
runTest(TEST_12, <String, TestCallback>{
'fs': (closedWorld) => closedWorld.commonMasks.interceptorType
});
runTest(TEST_13, <String, TestCallback>{
'fs': (closedWorld) => closedWorld.commonMasks.uint31Type
});
runTest(TEST_14, <String, TestCallback>{
'f': (closedWorld) => closedWorld.commonMasks.uint31Type
});
runTest(TEST_15, <String, TestCallback>{
'f': (closedWorld) {
ClassElement cls = closedWorld.commonElements.jsIndexableClass;
return new TypeMask.nonNullSubtype(cls, closedWorld);
}
});
runTest(TEST_16, <String, TestCallback>{
'f': (closedWorld) => closedWorld.commonMasks.interceptorType
});
runTest(TEST_17, <String, TestCallback>{
'f': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_18, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f2': (closedWorld) => closedWorld.commonMasks.stringType,
'f3': (closedWorld) => closedWorld.commonMasks.dynamicType
});
runTest(TEST_19, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f2': (closedWorld) => closedWorld.commonMasks.stringType,
'f3': (closedWorld) => closedWorld.commonMasks.dynamicType
});
runTest(TEST_20, <String, TestCallback>{
'f': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_21, <String, TestCallback>{
'f': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_22, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f2': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f3': (closedWorld) => closedWorld.commonMasks.stringType.nullable()
});
runTest(TEST_23, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable(),
'f2': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable(),
'f3': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable(),
'f4': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_24, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.positiveIntType,
'f2': (closedWorld) => closedWorld.commonMasks.positiveIntType,
'f3': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f4': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f5': (closedWorld) => closedWorld.commonMasks.numType.nullable(),
'f6': (closedWorld) => closedWorld.commonMasks.stringType.nullable()
});
runTest(TEST_25, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.uint31Type
});
runTest(TEST_26, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.positiveIntType
});
runTest(TEST_27, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f2': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_28, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f2': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_29, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f2': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_30, <String, TestCallback>{
'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f2': (closedWorld) => closedWorld.commonMasks.uint31Type,
'f3': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
}
void main() {
test();
}

View file

@ -2,7 +2,8 @@
// 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.
/// TODO(johnniwinther): Currently this only works with the mock compiler.
/// TODO(johnniwinther): Move this to the codegen folder. Currently this only
/// works with the mock compiler.
import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";

View file

@ -2,7 +2,8 @@
// 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.
/// TODO(johnniwinther): Currently this only works with the mock compiler.
/// TODO(johnniwinther): Move this to the codegen folder. Currently this only
/// works with the mock compiler.
import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";

View file

@ -5,12 +5,13 @@
/// TODO(johnniwinther): Port this test to use the equivalence framework.
/// Currently it only works with the mock compiler.
import 'package:expect/expect.dart';
import "package:async_helper/async_helper.dart";
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/types/types.dart' show ContainerTypeMask, TypeMask;
import 'package:compiler/src/commandline_options.dart';
import 'package:expect/expect.dart';
import 'type_mask_test_helper.dart';
import '../compiler_helper.dart';
import '../memory_compiler.dart';
String generateTest(String listAllocation) {
return """
@ -189,58 +190,76 @@ main() {
}
void main() {
doTest('[]', nullify: false); // Test literal list.
doTest('new List()', nullify: false); // Test growable list.
doTest('new List(1)', nullify: true); // Test fixed list.
doTest('new List.filled(1, 0)', nullify: false); // Test List.filled.
doTest('new List.filled(1, null)', nullify: true); // Test List.filled.
runTest({bool useKernel}) async {
// Test literal list.
await doTest('[]', nullify: false, useKernel: useKernel);
// Test growable list.
await doTest('new List()', nullify: false, useKernel: useKernel);
// Test fixed list.
await doTest('new List(1)', nullify: true, useKernel: useKernel);
// Test List.filled.
await doTest('new List.filled(1, 0)', nullify: false, useKernel: useKernel);
// Test List.filled.
await doTest('new List.filled(1, null)',
nullify: true, useKernel: useKernel);
}
asyncTest(() async {
print('--test from ast---------------------------------------------------');
await runTest(useKernel: false);
print('--test from kernel------------------------------------------------');
await runTest(useKernel: true);
});
}
void doTest(String allocation, {bool nullify}) {
Uri uri = new Uri(scheme: 'source');
var compiler = mockCompilerFor(generateTest(allocation), uri,
expectedErrors: 0, expectedWarnings: 1);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
var closedWorld = typesInferrer.closedWorld;
var commonMasks = closedWorld.commonMasks;
doTest(String allocation, {bool nullify, bool useKernel}) async {
String source = generateTest(allocation);
var result = await runCompiler(
memorySourceFiles: {'main.dart': source},
options: useKernel ? [Flags.useKernel] : []);
Expect.isTrue(result.isSuccess);
var compiler = result.compiler;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
var closedWorld = typesInferrer.closedWorld;
var commonMasks = closedWorld.commonMasks;
checkType(String name, type) {
MemberElement element = findElement(compiler, name);
ContainerTypeMask mask = typesInferrer.getTypeOfMember(element);
if (nullify) type = type.nullable();
Expect.equals(type, simplify(mask.elementType, closedWorld), name);
}
checkType(String name, type) {
var element = findMember(closedWorld, name);
ContainerTypeMask mask = typesInferrer.getTypeOfMember(element);
if (nullify) type = type.nullable();
Expect.equals(type, simplify(mask.elementType, closedWorld), name);
}
checkType('listInField', commonMasks.numType);
checkType('listPassedToMethod', commonMasks.numType);
checkType('listReturnedFromMethod', commonMasks.numType);
checkType('listUsedWithCascade', commonMasks.numType);
checkType('listUsedInClosure', commonMasks.numType);
checkType('listPassedToSelector', commonMasks.numType);
checkType('listReturnedFromSelector', commonMasks.numType);
checkType('listUsedWithAddAndInsert', commonMasks.numType);
checkType('listUsedWithConstraint', commonMasks.positiveIntType);
checkType('listEscapingFromSetter', commonMasks.numType);
checkType('listUsedInLocal', commonMasks.numType);
checkType('listEscapingInSetterValue', commonMasks.numType);
checkType('listEscapingInIndex', commonMasks.numType);
checkType('listEscapingInIndexSet', commonMasks.uint31Type);
checkType('listEscapingTwiceInIndexSet', commonMasks.numType);
checkType('listSetInNonFinalField', commonMasks.numType);
checkType('listWithChangedLength', commonMasks.uint31Type.nullable());
checkType('listInField', commonMasks.numType);
checkType('listPassedToMethod', commonMasks.numType);
checkType('listReturnedFromMethod', commonMasks.numType);
checkType('listUsedWithCascade', commonMasks.numType);
checkType('listUsedInClosure', commonMasks.numType);
checkType('listPassedToSelector', commonMasks.numType);
checkType('listReturnedFromSelector', commonMasks.numType);
checkType('listUsedWithAddAndInsert', commonMasks.numType);
checkType('listUsedWithConstraint', commonMasks.positiveIntType);
checkType('listEscapingFromSetter', commonMasks.numType);
checkType('listUsedInLocal', commonMasks.numType);
checkType('listEscapingInSetterValue', commonMasks.numType);
checkType('listEscapingInIndex', commonMasks.numType);
checkType('listEscapingInIndexSet', commonMasks.uint31Type);
// TODO(johnniwinther): Since Iterable.iterableToString is part of the closed
// world we find the `dynamicType` instead of `numType`.
checkType('listEscapingTwiceInIndexSet', commonMasks.dynamicType);
checkType('listSetInNonFinalField', commonMasks.numType);
checkType('listWithChangedLength', commonMasks.uint31Type.nullable());
checkType('listPassedToClosure', commonMasks.dynamicType);
checkType('listReturnedFromClosure', commonMasks.dynamicType);
checkType('listUsedWithNonOkSelector', commonMasks.dynamicType);
checkType('listPassedAsOptionalParameter', commonMasks.numType);
checkType('listPassedAsNamedParameter', commonMasks.numType);
checkType('listStoredInList', commonMasks.uint31Type);
checkType('listStoredInListButEscapes', commonMasks.dynamicType);
checkType('listPassedToClosure', commonMasks.dynamicType);
checkType('listReturnedFromClosure', commonMasks.dynamicType);
checkType('listUsedWithNonOkSelector', commonMasks.dynamicType);
checkType('listPassedAsOptionalParameter', commonMasks.numType);
checkType('listPassedAsNamedParameter', commonMasks.numType);
checkType('listStoredInList', commonMasks.uint31Type);
checkType('listStoredInListButEscapes', commonMasks.dynamicType);
if (!allocation.contains('filled')) {
checkType('listUnset', new TypeMask.nonNullEmpty());
checkType('listOnlySetWithConstraint', new TypeMask.nonNullEmpty());
}
}));
if (!allocation.contains('filled')) {
checkType('listUnset', new TypeMask.nonNullEmpty());
checkType('listOnlySetWithConstraint', new TypeMask.nonNullEmpty());
}
}

View file

@ -1,80 +0,0 @@
// Copyright (c) 2014, 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.
/// TODO(johnniwinther): Port this test to use the equivalence framework.
/// Currently it only works with the mock compiler.
import 'package:expect/expect.dart';
import "package:async_helper/async_helper.dart";
import 'package:compiler/src/types/types.dart' show ContainerTypeMask, TypeMask;
import '../compiler_helper.dart';
String generateTest(String key, String value, bool initial) {
return """
double aDouble = 42.5;
List aList = [42];
consume(x) => x;
main() {
""" +
(initial
? """
var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4, $key: $value};
"""
: """
var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4};
theMap[$key] = $value;
""") +
"""
for (var key in theMap.keys) {
aDouble = theMap[key];
}
// We have to reference it somewhere, so that it always gets resolved.
consume(aList);
}
""";
}
void main() {
// Test using keys without the list floating in
doTest();
// Test using keys with the list floating in as key
doTest(key: "aList", bail: true);
// Test using keys with the list floating in as value
doTest(value: "aList");
// And the above where we add the list as part of the map literal.
doTest(initial: true);
doTest(key: "aList", bail: true, initial: true);
doTest(value: "aList", initial: true);
}
void doTest(
{String key: "'d'",
String value: "5.5",
bool bail: false,
bool initial: false}) {
Uri uri = new Uri(scheme: 'source');
var compiler = mockCompilerFor(generateTest(key, value, initial), uri,
expectedErrors: 0, expectedWarnings: 0);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
var commonMasks = typesInferrer.closedWorld.commonMasks;
MemberElement aDouble = findElement(compiler, 'aDouble');
var aDoubleType = typesInferrer.getTypeOfMember(aDouble);
MemberElement aList = findElement(compiler, 'aList');
var aListType = typesInferrer.getTypeOfMember(aList);
Expect.equals(aDoubleType, commonMasks.doubleType);
Expect.isTrue(aListType is ContainerTypeMask);
ContainerTypeMask container = aListType;
TypeMask elementType = container.elementType;
if (bail) {
Expect.equals(elementType, commonMasks.dynamicType);
} else {
Expect.equals(elementType, commonMasks.uint31Type);
}
}));
}

View file

@ -5,12 +5,17 @@
/// TODO(johnniwinther): Port this test to use the equivalence framework.
/// Currently it only works with the mock compiler.
import 'package:expect/expect.dart';
import "package:async_helper/async_helper.dart";
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/inferrer/type_graph_inferrer.dart';
import 'package:compiler/src/types/types.dart' show MapTypeMask, TypeMask;
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import 'type_mask_test_helper.dart';
import '../compiler_helper.dart';
import '../memory_compiler.dart';
String generateTest(String mapAllocation) {
return """
@ -119,6 +124,8 @@ takeNamed({map}) {
}
main() {
anInt++;
mapReturnedFromMethod[aKey] = anInt;
bar()[aKey] = aDouble;
@ -202,90 +209,103 @@ main() {
}
void main() {
// Test empty literal map
doTest('{}');
// Test preset map of <String,uint32>
doTest('{presetKey : anInt}', "presetKey", "anInt");
// Test preset map of <Double,uint32>
doTest('{aDouble : anInt}', "aDouble", "anInt");
runTests({bool useKernel}) async {
// Test empty literal map
await doTest('{}', useKernel: useKernel);
// Test preset map of <String,uint32>
await doTest('{presetKey : anInt}',
keyElementName: "presetKey",
valueElementName: "anInt",
useKernel: useKernel);
// Test preset map of <Double,uint32>
await doTest('{aDouble : anInt}',
keyElementName: "aDouble",
valueElementName: "anInt",
useKernel: useKernel);
}
asyncTest(() async {
print('--test from ast---------------------------------------------------');
await runTests(useKernel: false);
print('--test from kernel------------------------------------------------');
await runTests(useKernel: true);
});
}
void doTest(String allocation,
[String keyElementName, String valueElementName]) {
Uri uri = new Uri(scheme: 'source');
var compiler = mockCompilerFor(generateTest(allocation), uri,
expectedErrors: 0, expectedWarnings: 1);
asyncTest(() => compiler.run(uri).then((_) {
var keyType, valueType;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
var closedWorld = typesInferrer.closedWorld;
var commonMasks = closedWorld.commonMasks;
var emptyType = new TypeMask.nonNullEmpty();
MemberElement aKey = findElement(compiler, 'aKey');
var aKeyType = typesInferrer.getTypeOfMember(aKey);
if (keyElementName != null) {
MemberElement keyElement = findElement(compiler, keyElementName);
keyType = typesInferrer.getTypeOfMember(keyElement);
}
if (valueElementName != null) {
MemberElement valueElement = findElement(compiler, valueElementName);
valueType = typesInferrer.getTypeOfMember(valueElement);
}
if (keyType == null) keyType = emptyType;
if (valueType == null) valueType = emptyType;
doTest(String allocation,
{String keyElementName, String valueElementName, bool useKernel}) async {
String source = generateTest(allocation);
var result = await runCompiler(
memorySourceFiles: {'main.dart': source},
options: useKernel ? [Flags.useKernel] : []);
Expect.isTrue(result.isSuccess);
Compiler compiler = result.compiler;
TypeMask keyType, valueType;
TypeGraphInferrer typesInferrer =
compiler.globalInference.typesInferrerInternal;
ClosedWorld closedWorld = typesInferrer.closedWorld;
CommonMasks commonMasks = closedWorld.commonMasks;
TypeMask emptyType = new TypeMask.nonNullEmpty();
MemberEntity aKey = findMember(closedWorld, 'aKey');
TypeMask aKeyType = typesInferrer.getTypeOfMember(aKey);
if (keyElementName != null) {
MemberEntity keyElement = findMember(closedWorld, keyElementName);
keyType = typesInferrer.getTypeOfMember(keyElement);
}
if (valueElementName != null) {
MemberEntity valueElement = findMember(closedWorld, valueElementName);
valueType = typesInferrer.getTypeOfMember(valueElement);
}
if (keyType == null) keyType = emptyType;
if (valueType == null) valueType = emptyType;
checkType(String name, keyType, valueType) {
MemberElement element = findElement(compiler, name);
MapTypeMask mask = typesInferrer.getTypeOfMember(element);
Expect.equals(keyType, simplify(mask.keyType, closedWorld), name);
Expect.equals(valueType, simplify(mask.valueType, closedWorld), name);
}
checkType(String name, keyType, valueType) {
MemberEntity element = findMember(closedWorld, name);
MapTypeMask mask = typesInferrer.getTypeOfMember(element);
Expect.equals(keyType, simplify(mask.keyType, closedWorld), name);
Expect.equals(valueType, simplify(mask.valueType, closedWorld), name);
}
K(TypeMask other) =>
simplify(keyType.union(other, closedWorld), closedWorld);
V(TypeMask other) =>
simplify(valueType.union(other, closedWorld), closedWorld)
.nullable();
K(TypeMask other) => simplify(keyType.union(other, closedWorld), closedWorld);
V(TypeMask other) =>
simplify(valueType.union(other, closedWorld), closedWorld).nullable();
checkType('mapInField', K(aKeyType), V(commonMasks.numType));
checkType('mapPassedToMethod', K(aKeyType), V(commonMasks.numType));
checkType('mapReturnedFromMethod', K(aKeyType), V(commonMasks.numType));
checkType('mapUsedWithCascade', K(aKeyType), V(commonMasks.numType));
checkType('mapUsedInClosure', K(aKeyType), V(commonMasks.numType));
checkType('mapPassedToSelector', K(aKeyType), V(commonMasks.numType));
checkType(
'mapReturnedFromSelector', K(aKeyType), V(commonMasks.numType));
checkType(
'mapUsedWithConstraint', K(aKeyType), V(commonMasks.uint31Type));
checkType('mapEscapingFromSetter', K(aKeyType), V(commonMasks.numType));
checkType('mapUsedInLocal', K(aKeyType), V(commonMasks.numType));
checkType(
'mapEscapingInSetterValue', K(aKeyType), V(commonMasks.numType));
checkType('mapEscapingInIndex', K(aKeyType), V(commonMasks.numType));
checkType(
'mapEscapingInIndexSet', K(aKeyType), V(commonMasks.uint31Type));
checkType(
'mapEscapingTwiceInIndexSet', K(aKeyType), V(commonMasks.numType));
checkType('mapSetInNonFinalField', K(aKeyType), V(commonMasks.numType));
checkType('mapInField', K(aKeyType), V(commonMasks.numType));
checkType('mapPassedToMethod', K(aKeyType), V(commonMasks.numType));
checkType('mapReturnedFromMethod', K(aKeyType), V(commonMasks.numType));
checkType('mapUsedWithCascade', K(aKeyType), V(commonMasks.numType));
checkType('mapUsedInClosure', K(aKeyType), V(commonMasks.numType));
checkType('mapPassedToSelector', K(aKeyType), V(commonMasks.numType));
checkType('mapReturnedFromSelector', K(aKeyType), V(commonMasks.numType));
checkType(
'mapUsedWithConstraint', K(aKeyType), V(commonMasks.positiveIntType));
checkType('mapEscapingFromSetter', K(aKeyType), V(commonMasks.numType));
checkType('mapUsedInLocal', K(aKeyType), V(commonMasks.numType));
checkType('mapEscapingInSetterValue', K(aKeyType), V(commonMasks.numType));
checkType('mapEscapingInIndex', K(aKeyType), V(commonMasks.numType));
checkType(
'mapEscapingInIndexSet', K(aKeyType), V(commonMasks.positiveIntType));
// TODO(johnniwinther): Reenable this when we don't bail out due to
// (benign) JS calls.
//checkType('mapEscapingTwiceInIndexSet', K(aKeyType), V(commonMasks.numType));
checkType('mapSetInNonFinalField', K(aKeyType), V(commonMasks.numType));
checkType('mapPassedToClosure', K(commonMasks.dynamicType),
V(commonMasks.dynamicType));
checkType('mapReturnedFromClosure', K(commonMasks.dynamicType),
V(commonMasks.dynamicType));
checkType('mapUsedWithNonOkSelector', K(commonMasks.dynamicType),
V(commonMasks.dynamicType));
checkType('mapPassedAsOptionalParameter', K(aKeyType),
V(commonMasks.numType));
checkType(
'mapPassedAsNamedParameter', K(aKeyType), V(commonMasks.numType));
checkType('mapStoredInList', K(aKeyType), V(commonMasks.uint31Type));
checkType('mapStoredInListButEscapes', K(commonMasks.dynamicType),
V(commonMasks.dynamicType));
checkType('mapStoredInMap', K(aKeyType), V(commonMasks.uint31Type));
checkType('mapStoredInMapButEscapes', K(commonMasks.dynamicType),
V(commonMasks.dynamicType));
checkType('mapPassedToClosure', K(commonMasks.dynamicType),
V(commonMasks.dynamicType));
checkType('mapReturnedFromClosure', K(commonMasks.dynamicType),
V(commonMasks.dynamicType));
checkType('mapUsedWithNonOkSelector', K(commonMasks.dynamicType),
V(commonMasks.dynamicType));
checkType(
'mapPassedAsOptionalParameter', K(aKeyType), V(commonMasks.numType));
checkType('mapPassedAsNamedParameter', K(aKeyType), V(commonMasks.numType));
checkType('mapStoredInList', K(aKeyType), V(commonMasks.uint31Type));
checkType('mapStoredInListButEscapes', K(commonMasks.dynamicType),
V(commonMasks.dynamicType));
checkType('mapStoredInMap', K(aKeyType), V(commonMasks.uint31Type));
checkType('mapStoredInMapButEscapes', K(commonMasks.dynamicType),
V(commonMasks.dynamicType));
checkType('mapUnset', K(emptyType), V(emptyType));
checkType('mapOnlySetWithConstraint', K(aKeyType), V(emptyType));
}));
checkType('mapUnset', K(emptyType), V(emptyType));
checkType('mapOnlySetWithConstraint', K(aKeyType), V(emptyType));
}

View file

@ -4,9 +4,35 @@
/// Helper program that shows the inferrer data on a dart program.
import 'package:args/args.dart';
import 'package:compiler/src/inferrer/inferrer_engine.dart';
import '../equivalence/id_equivalence_helper.dart';
import '../equivalence/show_helper.dart';
import 'inference_test_helper.dart';
import 'side_effects_test.dart';
import 'callers_test.dart';
main(List<String> args) async {
await show(args, computeMemberAstTypeMasks, computeMemberIrTypeMasks);
ArgParser argParser = createArgParser();
argParser.addFlag('inference', defaultsTo: true);
argParser.addFlag('side-effects', defaultsTo: false);
argParser.addFlag('callers', defaultsTo: false);
ArgResults results = argParser.parse(args);
ComputeMemberDataFunction astFunction;
ComputeMemberDataFunction kernelFunction;
if (results['side-effects']) {
astFunction = computeMemberAstSideEffects;
kernelFunction = computeMemberIrSideEffects;
}
if (results['callers']) {
InferrerEngineImpl.retainDataForTesting = true;
astFunction = computeMemberAstCallers;
kernelFunction = computeMemberIrCallers;
} else {
InferrerEngineImpl.useSorterForTesting = true;
astFunction = computeMemberAstTypeMasks;
kernelFunction = computeMemberIrTypeMasks;
}
await show(results, astFunction, kernelFunction);
}

View file

@ -1,67 +0,0 @@
// Copyright (c) 2013, 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.
/// TODO(johnniwinther): Port this test to use the equivalence framework.
// Test that computation of callers of an element works when two
// elements of the same name are being invoked in the same method.
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/inferrer/type_graph_inferrer.dart';
import 'package:compiler/src/world.dart' show ClosedWorld, ClosedWorldRefiner;
import '../compiler_helper.dart';
const String TEST = """
class A {
var field;
}
class B {
var field;
}
main() {
new A().field;
new B().field;
}
""";
// Create our own type inferrer to avoid clearing out the internal
// data structures.
class MyInferrer extends AstTypeGraphInferrer {
MyInferrer(compiler, closedWorld, closedWorldRefiner)
: super(compiler, closedWorld, closedWorldRefiner);
clear() {}
}
void main() {
Uri uri = new Uri(scheme: 'source');
var compiler = mockCompilerFor(TEST, uri, analyzeOnly: true);
asyncTest(() => compiler.run(uri).then((_) {
ElementEnvironment elementEnvironment =
compiler.frontendStrategy.elementEnvironment;
ClosedWorldRefiner closedWorldRefiner =
compiler.closeResolution(elementEnvironment.mainFunction);
ClosedWorld closedWorld =
compiler.resolutionWorldBuilder.closedWorldForTesting;
var inferrer =
new MyInferrer(compiler, closedWorld, closedWorldRefiner);
compiler.globalInference.typesInferrerInternal = inferrer;
compiler.globalInference.runGlobalTypeInference(
closedWorld.elementEnvironment.mainFunction,
closedWorld,
closedWorldRefiner);
var mainElement = findElement(compiler, 'main');
dynamic classA = findElement(compiler, 'A');
var fieldA = classA.lookupLocalMember('field');
dynamic classB = findElement(compiler, 'B');
var fieldB = classB.lookupLocalMember('field');
Expect.isTrue(inferrer.getCallersOf(fieldA).contains(mainElement));
Expect.isTrue(inferrer.getCallersOf(fieldB).contains(mainElement));
}));
}

View file

@ -10,5 +10,6 @@ import 'inlining_test.dart';
main(List<String> args) async {
JavaScriptBackend.cacheCodegenImpactForTesting = true;
await show(args, computeMemberAstInlinings, computeMemberIrInlinings);
await show(createArgParser().parse(args), computeMemberAstInlinings,
computeMemberIrInlinings);
}