mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:07:49 +00:00
More features handled in kernel impact.
BUG= R=het@google.com Review URL: https://codereview.chromium.org/2329403003 .
This commit is contained in:
parent
6e62b8af9a
commit
4eca725670
|
@ -2825,9 +2825,6 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
|||
new TypeUse.instantiation(backend.coreTypes.nullType));
|
||||
registerBackendImpact(transformed, impacts.nullLiteral);
|
||||
break;
|
||||
case Feature.INC_DEC_OPERATION:
|
||||
registerBackendImpact(transformed, impacts.incDecOperation);
|
||||
break;
|
||||
case Feature.LAZY_FIELD:
|
||||
registerBackendImpact(transformed, impacts.lazyField);
|
||||
break;
|
||||
|
|
|
@ -306,16 +306,6 @@ class BackendImpacts {
|
|||
return _constSymbol;
|
||||
}
|
||||
|
||||
BackendImpact _incDecOperation;
|
||||
|
||||
BackendImpact get incDecOperation {
|
||||
if (_incDecOperation == null) {
|
||||
_incDecOperation =
|
||||
_needsInt('Needed for the `+ 1` or `- 1` operation of ++/--.');
|
||||
}
|
||||
return _incDecOperation;
|
||||
}
|
||||
|
||||
/// Helper for registering that `int` is needed.
|
||||
BackendImpact _needsInt(String reason) {
|
||||
// TODO(johnniwinther): Register [reason] for use in dump-info.
|
||||
|
|
45
pkg/compiler/lib/src/kernel/kernel_debug.dart
Normal file
45
pkg/compiler/lib/src/kernel/kernel_debug.dart
Normal file
|
@ -0,0 +1,45 @@
|
|||
// 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.
|
||||
|
||||
/// Helper for debug Kernel nodes.
|
||||
|
||||
library kernel.debug;
|
||||
|
||||
import 'package:kernel/kernel.dart';
|
||||
import 'package:kernel/visitor.dart';
|
||||
|
||||
import '../util/util.dart' show Indentation, Tagging;
|
||||
|
||||
class DebugPrinter extends Visitor with Indentation, Tagging<Node> {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
void visitNodeWithChildren(Node node, String type, [Map params]) {
|
||||
openNode(node, type, params);
|
||||
node.visitChildren(this);
|
||||
closeNode();
|
||||
}
|
||||
|
||||
@override
|
||||
void defaultNode(Node node) {
|
||||
visitNodeWithChildren(node, '${node.runtimeType}');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitName(Name node) {
|
||||
openAndCloseNode(node, '${node.runtimeType}',
|
||||
{'name': node.name, 'library': node.library?.name});
|
||||
}
|
||||
|
||||
@override
|
||||
void visitIntLiteral(IntLiteral node) {
|
||||
openAndCloseNode(node, '${node.runtimeType}', {'value': '${node.value}'});
|
||||
}
|
||||
|
||||
/// Pretty-prints given node tree into string.
|
||||
static String prettyPrint(Node node) {
|
||||
var p = new DebugPrinter();
|
||||
node.accept(p);
|
||||
return p.sb.toString();
|
||||
}
|
||||
}
|
|
@ -3409,7 +3409,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
? new PrefixStructure(semantics, operator)
|
||||
: new PostfixStructure(semantics, operator);
|
||||
registry.registerSendStructure(node, sendStructure);
|
||||
registry.registerFeature(Feature.INC_DEC_OPERATION);
|
||||
registry.registerConstantLiteral(new IntConstantExpression(1));
|
||||
} else {
|
||||
Node rhs = node.arguments.head;
|
||||
visitExpression(rhs);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import 'package:kernel/ast.dart' as ir;
|
||||
|
||||
import '../common.dart';
|
||||
import '../common/names.dart';
|
||||
import '../compiler.dart';
|
||||
import '../constants/values.dart';
|
||||
import '../dart_types.dart';
|
||||
|
@ -91,20 +92,26 @@ class KernelAstAdapter {
|
|||
return new CallStructure(argumentCount, namedArguments);
|
||||
}
|
||||
|
||||
Name getName(ir.Name name) {
|
||||
return new Name(
|
||||
name.name, name.isPrivate ? getElement(name.library) : null);
|
||||
}
|
||||
|
||||
// TODO(het): Create the selector directly from the invocation
|
||||
Selector getSelector(ir.InvocationExpression invocation) {
|
||||
SelectorKind kind = Elements.isOperatorName(invocation.name.name)
|
||||
? SelectorKind.OPERATOR
|
||||
: SelectorKind.CALL;
|
||||
if (invocation.name.name == '[]' || invocation.name.name == '[]=') {
|
||||
kind = SelectorKind.INDEX;
|
||||
Name name = getName(invocation.name);
|
||||
SelectorKind kind;
|
||||
if (Elements.isOperatorName(invocation.name.name)) {
|
||||
if (name == Names.INDEX_NAME || name == Names.INDEX_SET_NAME) {
|
||||
kind = SelectorKind.INDEX;
|
||||
} else {
|
||||
kind = SelectorKind.OPERATOR;
|
||||
}
|
||||
} else {
|
||||
kind = SelectorKind.CALL;
|
||||
}
|
||||
|
||||
ir.Name irName = invocation.name;
|
||||
Name name = new Name(
|
||||
irName.name, irName.isPrivate ? getElement(irName.library) : null);
|
||||
CallStructure callStructure = getCallStructure(invocation.arguments);
|
||||
|
||||
return new Selector(kind, name, callStructure);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,11 @@ import '../dart_types.dart';
|
|||
import '../elements/elements.dart';
|
||||
import '../js_backend/backend.dart' show JavaScriptBackend;
|
||||
import '../kernel/kernel.dart';
|
||||
import '../kernel/kernel_debug.dart';
|
||||
import '../kernel/kernel_visitor.dart';
|
||||
import '../resolution/registry.dart' show ResolutionWorldImpactBuilder;
|
||||
import '../universe/feature.dart';
|
||||
import '../universe/selector.dart';
|
||||
import '../universe/use.dart';
|
||||
|
||||
import 'kernel_ast_adapter.dart';
|
||||
|
@ -211,8 +213,33 @@ class KernelImpactBuilder extends ir.Visitor {
|
|||
new DynamicUse(astAdapter.getSelector(invocation), null));
|
||||
}
|
||||
|
||||
@override
|
||||
void visitPropertyGet(ir.PropertyGet node) {
|
||||
node.receiver.accept(this);
|
||||
impactBuilder.registerDynamicUse(new DynamicUse(
|
||||
new Selector.getter(astAdapter.getName(node.name)), null));
|
||||
}
|
||||
|
||||
@override
|
||||
void visitPropertySet(ir.PropertySet node) {
|
||||
node.receiver.accept(this);
|
||||
node.value.accept(this);
|
||||
impactBuilder.registerDynamicUse(new DynamicUse(
|
||||
new Selector.setter(astAdapter.getName(node.name)), null));
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNot(ir.Not not) {
|
||||
not.operand.accept(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAssertStatement(ir.AssertStatement node) {
|
||||
impactBuilder.registerFeature(
|
||||
node.message != null ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT);
|
||||
node.visitChildren(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void defaultNode(ir.Node node) => node.visitChildren(this);
|
||||
}
|
||||
|
|
|
@ -43,9 +43,6 @@ enum Feature {
|
|||
/// A field without an initializer.
|
||||
FIELD_WITHOUT_INITIALIZER,
|
||||
|
||||
/// A ++/-- operation.
|
||||
INC_DEC_OPERATION,
|
||||
|
||||
/// A field whose initialization is not a constant.
|
||||
LAZY_FIELD,
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@ const Map<String, List/*<String|MessageKind>*/> WHITE_LIST = const {
|
|||
"Library 'package:async/async.dart' doesn't export a "
|
||||
"'ForkableStream' declaration.",
|
||||
],
|
||||
"/utils.dart": const [
|
||||
"Duplicated library name 'utils'.",
|
||||
],
|
||||
};
|
||||
|
||||
const List<String> SKIP_LIST = const <String>[
|
||||
|
|
|
@ -39,12 +39,25 @@ main() {
|
|||
testNonEmptyMapLiteral();
|
||||
testNot();
|
||||
testUnaryMinus();
|
||||
testConditional();
|
||||
testPostInc(null);
|
||||
testPostDec(null);
|
||||
testPreInc(null);
|
||||
testPreDec(null);
|
||||
testIfThen();
|
||||
testIfThenElse();
|
||||
testTopLevelInvoke();
|
||||
testTopLevelInvokeTyped();
|
||||
testTopLevelField();
|
||||
testTopLevelFieldTyped();
|
||||
testDynamicInvoke(null);
|
||||
testDynamicGet(null);
|
||||
testDynamicSet(null);
|
||||
testLocalWithInitializer();
|
||||
testInvokeIndex(null);
|
||||
testInvokeIndexSet(null);
|
||||
testAssert();
|
||||
testAssertWithMessage();
|
||||
}
|
||||
|
||||
testEmpty() {}
|
||||
|
@ -67,6 +80,11 @@ testEmptyMapLiteralConstant() => const {};
|
|||
testNonEmptyMapLiteral() => {0: true};
|
||||
testNot() => !false;
|
||||
testUnaryMinus() => -1;
|
||||
testConditional() => true ? 1 : '';
|
||||
testPostInc(o) => o++;
|
||||
testPostDec(o) => o--;
|
||||
testPreInc(o) => ++o;
|
||||
testPreDec(o) => --o;
|
||||
testIfThen() {
|
||||
if (false) return 42;
|
||||
return 1;
|
||||
|
@ -112,6 +130,30 @@ var topLevelField;
|
|||
testTopLevelField() => topLevelField;
|
||||
int topLevelFieldTyped;
|
||||
testTopLevelFieldTyped() => topLevelFieldTyped;
|
||||
testDynamicInvoke(o) {
|
||||
o.f1(0);
|
||||
o.f2(1);
|
||||
o.f3(2, 3);
|
||||
o.f4(4, 5, 6);
|
||||
o.f5(7);
|
||||
o.f6(8, b: 9);
|
||||
o.f7(10, c: 11);
|
||||
o.f8(12, b: 13, c: 14);
|
||||
o.f9(15, c: 16, b: 17);
|
||||
}
|
||||
testDynamicGet(o) => o.foo;
|
||||
testDynamicSet(o) => o.foo = 42;
|
||||
testLocalWithInitializer() {
|
||||
var l = 42;
|
||||
}
|
||||
testInvokeIndex(o) => o[42];
|
||||
testInvokeIndexSet(o) => o[42] = null;
|
||||
testAssert() {
|
||||
assert(true);
|
||||
}
|
||||
testAssertWithMessage() {
|
||||
assert(true, 'ok');
|
||||
}
|
||||
'''
|
||||
};
|
||||
|
||||
|
@ -122,11 +164,21 @@ main(List<String> args) {
|
|||
Compiler compiler = compilerFor(
|
||||
entryPoint: entryPoint,
|
||||
memorySourceFiles: SOURCE,
|
||||
options: [Flags.analyzeOnly, Flags.useKernel]);
|
||||
options:
|
||||
[Flags.analyzeAll, Flags.useKernel, Flags.enableAssertMessage]);
|
||||
compiler.resolution.retainCachesForTesting = true;
|
||||
await compiler.run(entryPoint);
|
||||
compiler.mainApp
|
||||
.forEachLocalMember((element) => checkElement(compiler, element));
|
||||
checkLibrary(compiler, compiler.mainApp);
|
||||
});
|
||||
}
|
||||
|
||||
void checkLibrary(Compiler compiler, LibraryElement library) {
|
||||
library.forEachLocalMember((AstElement element) {
|
||||
if (element.isClass) {
|
||||
// TODO(johnniwinther): Handle class members.
|
||||
} else {
|
||||
checkElement(compiler, element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue