Files
sdk/pkg/kernel/lib/transformations/closure/mock.dart
T
Asger Feldthaus 8bfc4b47c0 Implement canonical name scheme in kernel.
This adds a class CanonicalName that can represent a library, class,
or member.  All references now go through a Reference object, which is
linked to both the AST node and its CanonicalName, so either can be
created first.

dartk now accepts multiple input files:
- If multiple dart files are given, they are all compiled.
- If multiple binaries are given, they are linked together.
Mixed dart and binary input is not supported by dartk.

dartk now has a flag --include-sdk which includes the entire SDK in
the output.  This is so the SDK can be compiled alone and then linked.

Example of compiling separately and then linking:
  dartk foo.dart -o foo.dill
  dartk main.dart -o main.dill
  dartk --include-sdk -o sdk.dill
  dartk main.dill foo.dill sdk.dill --target=vm --link -o program.dill

dartk still has incredibly slow cold start due to the analyzer loading
the dart sdk, so this does not actually speed things up at the moment.

BUG=
R=ahe@google.com, kmillikin@google.com, kustermann@google.com, sigmund@google.com

Review-Url: https://codereview.chromium.org/2665723002 .
2017-02-23 14:12:10 +01:00

197 lines
6.5 KiB
Dart

// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library kernel.transformations.closure.mock;
import '../../ast.dart'
show
Arguments,
Block,
Class,
Constructor,
ConstructorInvocation,
DartType,
DynamicType,
EmptyStatement,
Expression,
ExpressionStatement,
Field,
FieldInitializer,
FunctionNode,
Initializer,
IntLiteral,
Library,
MethodInvocation,
Name,
NullLiteral,
Procedure,
ProcedureKind,
Program,
PropertyGet,
ReturnStatement,
Source,
Statement,
StaticInvocation,
Supertype,
VariableDeclaration,
VariableGet;
import '../../core_types.dart' show CoreTypes;
import '../../frontend/accessors.dart'
show
Accessor,
IndexAccessor,
PropertyAccessor,
ThisPropertyAccessor,
VariableAccessor;
/// Extend the program with this mock:
///
/// class Context {
/// final List list;
/// var parent;
/// Context(int i) : list = new List(i);
/// operator[] (int i) => list[i];
/// operator[]= (int i, value) {
/// list[i] = value;
/// }
/// Context copy() {
/// Context c = new Context(list.length);
/// c.parent = parent;
/// c.list.setRange(0, list.length, list);
/// return c;
/// }
/// }
///
/// Returns the mock.
Class mockUpContext(CoreTypes coreTypes, Program program) {
String fileUri = "dart:mock";
/// final List list;
Field listField = new Field(new Name("list"),
type: coreTypes.listClass.rawType, isFinal: true, fileUri: fileUri);
Accessor listFieldAccessor =
new ThisPropertyAccessor(listField.name, listField, null);
/// var parent;
Field parentField = new Field(new Name("parent"), fileUri: fileUri);
Accessor parentFieldAccessor =
new ThisPropertyAccessor(parentField.name, parentField, parentField);
List<Field> fields = <Field>[listField, parentField];
/// Context(int i) : list = new List(i);
VariableDeclaration iParameter = new VariableDeclaration("i",
type: coreTypes.intClass.rawType, isFinal: true);
// TODO(karlklose): use the default factory when it is exposed again.
Procedure listConstructor = coreTypes.listClass.procedures
.firstWhere((Procedure p) => p.name.name == 'filled');
Constructor constructor = new Constructor(
new FunctionNode(new EmptyStatement(),
positionalParameters: <VariableDeclaration>[iParameter]),
name: new Name(""),
initializers: <Initializer>[
new FieldInitializer(
listField,
new StaticInvocation(
listConstructor,
new Arguments(<Expression>[
new VariableAccessor(iParameter).buildSimpleRead(),
new NullLiteral(),
], types: <DartType>[
const DynamicType()
])))
]);
/// operator[] (int i) => list[i];
iParameter = new VariableDeclaration("i",
type: coreTypes.intClass.rawType, isFinal: true);
Accessor accessor = IndexAccessor.make(listFieldAccessor.buildSimpleRead(),
new VariableAccessor(iParameter).buildSimpleRead(), null, null);
Procedure indexGet = new Procedure(
new Name("[]"),
ProcedureKind.Operator,
new FunctionNode(new ReturnStatement(accessor.buildSimpleRead()),
positionalParameters: <VariableDeclaration>[iParameter]),
fileUri: fileUri);
/// operator[]= (int i, value) {
/// list[i] = value;
/// }
iParameter = new VariableDeclaration("i",
type: coreTypes.intClass.rawType, isFinal: true);
VariableDeclaration valueParameter =
new VariableDeclaration("value", isFinal: true);
accessor = IndexAccessor.make(listFieldAccessor.buildSimpleRead(),
new VariableAccessor(iParameter).buildSimpleRead(), null, null);
Expression expression = accessor.buildAssignment(
new VariableAccessor(valueParameter).buildSimpleRead(),
voidContext: true);
Procedure indexSet = new Procedure(
new Name("[]="),
ProcedureKind.Operator,
new FunctionNode(new ExpressionStatement(expression),
positionalParameters: <VariableDeclaration>[
iParameter,
valueParameter
]),
fileUri: fileUri);
/// Context copy() {
/// Context c = new Context(list.length);
/// c.parent = parent;
/// c.list.setRange(0, list.length, list);
/// return c;
/// }
VariableDeclaration c = new VariableDeclaration("c",
initializer: new ConstructorInvocation(
constructor,
new Arguments(<Expression>[
new PropertyGet(
listFieldAccessor.buildSimpleRead(), new Name("length"))
])));
Accessor accessCParent = PropertyAccessor.make(
new VariableGet(c), parentField.name, parentField, parentField);
Accessor accessCList = PropertyAccessor.make(
new VariableGet(c), listField.name, listField, null);
List<Statement> statements = <Statement>[
c,
new ExpressionStatement(accessCParent.buildAssignment(
parentFieldAccessor.buildSimpleRead(),
voidContext: true)),
new ExpressionStatement(new MethodInvocation(
accessCList.buildSimpleRead(),
new Name("setRange"),
new Arguments(<Expression>[
new IntLiteral(0),
new PropertyGet(
listFieldAccessor.buildSimpleRead(), new Name("length")),
listFieldAccessor.buildSimpleRead()
]))),
new ReturnStatement(new VariableGet(c))
];
Procedure copy = new Procedure(new Name("copy"), ProcedureKind.Method,
new FunctionNode(new Block(statements)),
fileUri: fileUri);
List<Procedure> procedures = <Procedure>[indexGet, indexSet, copy];
Class contextClass = new Class(
name: "Context",
supertype: new Supertype(coreTypes.objectClass, const <DartType>[]),
constructors: [constructor],
fields: fields,
procedures: procedures,
fileUri: fileUri);
Library mock = new Library(Uri.parse(fileUri),
name: "mock", classes: [contextClass])..fileUri = fileUri;
program.libraries.add(mock);
mock.parent = program;
program.uriToSource[mock.fileUri] = new Source(<int>[0], "");
return contextClass;
}