Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit f0587c0

Browse files
author
John Messerly
committed
remove SemanticNode
we didn't really need it after Siggi's reporting changes and introducing Conversion (and it's trivial to check the "dynamic" bit in codegen) [email protected] Review URL: https://chromereviews.googleplex.com/131277013
1 parent 88dabce commit f0587c0

File tree

4 files changed

+27
-59
lines changed

4 files changed

+27
-59
lines changed

lib/src/checker/checker.dart

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ CheckerResults checkProgram(Uri fileUri, TypeResolver resolver,
1919
// Invoke the checker on the entry point.
2020
TypeProvider provider = resolver.context.typeProvider;
2121
var rules = new RestrictedRules(provider, reporter);
22-
final visitor = new ProgramChecker(
23-
resolver, rules, fileUri, checkSdk, reporter);
22+
final visitor =
23+
new ProgramChecker(resolver, rules, fileUri, checkSdk, reporter);
2424
visitor.check();
2525
return new CheckerResults(visitor.libraries, rules, visitor.failure);
2626
}
@@ -209,14 +209,12 @@ class ProgramChecker extends RecursiveAstVisitor {
209209

210210
void checkFunctionApplication(
211211
Expression node, Expression f, ArgumentList list) {
212-
DartType type = _rules.getStaticType(f);
213-
if (type.isDynamic || type.isDartCoreFunction || type is! FunctionType) {
212+
if (_rules.isDynamicCall(f)) {
214213
// TODO(vsm): For a function object, we should still be able to derive a
215214
// function type from it.
216215
_recordDynamicInvoke(node);
217216
} else {
218-
assert(type is FunctionType);
219-
checkArgumentList(list, type);
217+
checkArgumentList(list, _rules.getStaticType(f));
220218
}
221219
}
222220

@@ -286,10 +284,7 @@ class ProgramChecker extends RecursiveAstVisitor {
286284
}
287285

288286
visitPropertyAccess(PropertyAccess node) {
289-
final target = node.realTarget;
290-
DartType receiverType = _rules.getStaticType(target);
291-
assert(receiverType != null);
292-
if (receiverType.isDynamic || receiverType.isDartCoreFunction) {
287+
if (_rules.isDynamicGet(node.realTarget)) {
293288
_recordDynamicInvoke(node);
294289
}
295290
node.visitChildren(this);
@@ -299,12 +294,8 @@ class ProgramChecker extends RecursiveAstVisitor {
299294
final target = node.prefix;
300295
// Check if the prefix is a library - PrefixElement denotes a library
301296
// access.
302-
if (target.staticElement is! PrefixElement) {
303-
DartType receiverType = _rules.getStaticType(target);
304-
assert(receiverType != null);
305-
if (receiverType.isDynamic || receiverType.isDartCoreFunction) {
306-
_recordDynamicInvoke(node);
307-
}
297+
if (target.staticElement is! PrefixElement && _rules.isDynamicGet(target)) {
298+
_recordDynamicInvoke(node);
308299
}
309300
node.visitChildren(this);
310301
}
@@ -354,22 +345,8 @@ class ProgramChecker extends RecursiveAstVisitor {
354345
return expr;
355346
}
356347

357-
SemanticNode _getSemanticNode(AstNode astNode) {
358-
if (astNode == null) return null;
359-
360-
final semanticNode = _current.nodeInfo[astNode];
361-
if (semanticNode == null) {
362-
return _current.nodeInfo[astNode] = new SemanticNode(astNode);
363-
}
364-
return semanticNode;
365-
}
366-
367348
void _recordDynamicInvoke(AstNode node) {
368-
final info = new DynamicInvoke(_rules, node);
369-
final semanticNode = _getSemanticNode(node);
370-
assert(semanticNode.dynamicInvoke == null);
371-
semanticNode.dynamicInvoke = info;
372-
_reporter.log(info);
349+
_reporter.log(new DynamicInvoke(_rules, node));
373350
}
374351

375352
void _recordMessage(StaticInfo info) {

lib/src/checker/rules.dart

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ abstract class TypeRules {
2929
DartType getStaticType(Expression expr) => expr.staticType;
3030

3131
DartType elementType(Element e);
32+
33+
/// Returns `true` if the expression is a dynamic property access or prefixed
34+
/// identifier.
35+
bool isDynamicGet(Expression expr) {
36+
var t = getStaticType(expr);
37+
// TODO(jmesserly): we should not allow all property gets on `Function`
38+
return t.isDynamic || t.isDartCoreFunction;
39+
}
40+
41+
/// Returns `true` if the expression is a dynamic function call or method
42+
/// invocation.
43+
bool isDynamicCall(Expression call) {
44+
var t = getStaticType(call);
45+
// TODO(jmesserly): fix handling of types with `call` methods. These are not
46+
// FunctionType, but they also aren't dynamic calls.
47+
return t.isDynamic || t.isDartCoreFunction || t is! FunctionType;
48+
}
3249
}
3350

3451
class DartRules extends TypeRules {
@@ -63,9 +80,6 @@ class RestrictedRules extends TypeRules {
6380
DartType getStaticType(Expression expr) {
6481
var type = expr.staticType;
6582
if (type != null) return type;
66-
67-
var node = currentLibraryInfo.nodeInfo
68-
.putIfAbsent(expr, () => new SemanticNode(expr));
6983
_reporter.log(new MissingTypeError(expr));
7084
return provider.dynamicType;
7185
}

lib/src/codegen/js_codegen.dart

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ var $name = (function (_super) {
425425

426426
@override
427427
void visitMethodInvocation(MethodInvocation node) {
428-
if (_isDynamic(node)) {
428+
if (rules.isDynamicCall(node.methodName)) {
429429
_unimplemented(node);
430430
return;
431431
}
@@ -693,7 +693,7 @@ var $name = (function (_super) {
693693

694694
/// Shared code for [PrefixedIdentifier] and [PropertyAccess].
695695
void _visitGet(Expression target, SimpleIdentifier name) {
696-
if (_isDynamic(target.parent)) {
696+
if (rules.isDynamicGet(target)) {
697697
out.write('dart_runtime.dload(');
698698
target.accept(this);
699699
out.write(', "');
@@ -813,13 +813,6 @@ var $name = (function (_super) {
813813
id.accept(this);
814814
}
815815

816-
// TODO(jmesserly): is there a cleaner way to track this dynamic bit?
817-
// Ideally we could just look at the resolved information on the AstNode.
818-
bool _isDynamic(AstNode node) {
819-
final info = libraryInfo.nodeInfo[node];
820-
return info != null && info.dynamicInvoke != null;
821-
}
822-
823816
/// Safely visit the given node, with an optional prefix or suffix.
824817
void _visitNode(AstNode node, {String prefix: '', String suffix: ''}) {
825818
if (node == null) return;

lib/src/info.dart

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ class LibraryInfo {
3030
/// Corresponding analyzer element.
3131
final LibraryElement library;
3232

33-
/// Information on each node that belongs to this library (includes nodes in
34-
/// the declaring unit and in parts).
35-
Map<AstNode, SemanticNode> nodeInfo = <AstNode, SemanticNode>{};
36-
3733
LibraryInfo(this.library) {
3834
name = library.name;
3935
if (name != null && library.name != '') return;
@@ -45,18 +41,6 @@ class LibraryInfo {
4541
}
4642
}
4743

48-
/// Semantic information about a node.
49-
// TODO(jmesserly): this structure is very incomplete.
50-
class SemanticNode {
51-
/// The syntax tree node this info is attached to.
52-
final AstNode node;
53-
54-
/// If this operation is dynamically dispatched, this will be set.
55-
DynamicInvoke dynamicInvoke;
56-
57-
SemanticNode(this.node);
58-
}
59-
6044
// The abstract type of coercions mapping one type to another.
6145
// This class also exposes static builder functions which
6246
// check for errors and reduce redundant coercions to the identity.

0 commit comments

Comments
 (0)