Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Unified Diff: tests/compiler/dart2js/semantic_visitor_test.dart

Issue 1043723002: Handle NewExpression in SemanticSendVisitor. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased+fix modely.dart Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/resolved_visitor.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/compiler/dart2js/semantic_visitor_test.dart
diff --git a/tests/compiler/dart2js/semantic_visitor_test.dart b/tests/compiler/dart2js/semantic_visitor_test.dart
index e96120d2a7d32119f00d013440ca67b2a69aeef4..cdacd2c0781fc48a0776af853d350a5d64c64216 100644
--- a/tests/compiler/dart2js/semantic_visitor_test.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test.dart
@@ -4,6 +4,7 @@
library dart2js.semantics_visitor_test;
+import 'dart:async';
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/constants/expressions.dart';
@@ -34,6 +35,11 @@ class Visit {
final setter;
final constant;
final selector;
+ final parameters;
+ final body;
+ final target;
+ final targetType;
+ final initializers;
const Visit(this.method,
{this.element,
@@ -50,7 +56,12 @@ class Visit {
this.getter,
this.setter,
this.constant,
- this.selector});
+ this.selector,
+ this.parameters,
+ this.body,
+ this.target,
+ this.targetType,
+ this.initializers});
int get hashCode => toString().hashCode;
@@ -104,6 +115,21 @@ class Visit {
if (selector != null) {
sb.write(',selector=$selector');
}
+ if (parameters != null) {
+ sb.write(',parameters=$parameters');
+ }
+ if (body != null) {
+ sb.write(',body=$body');
+ }
+ if (target != null) {
+ sb.write(',target=$target');
+ }
+ if (targetType != null) {
+ sb.write(',targetType=$targetType');
+ }
+ if (initializers != null) {
+ sb.write(',initializers=$initializers');
+ }
return sb.toString();
}
}
@@ -113,15 +139,15 @@ class Test {
final String code;
final /*Visit | List<Visit>*/ expectedVisits;
final String cls;
+ final String method;
const Test(this.code, this.expectedVisits)
- : cls = null, codeByPrefix = null;
- const Test.clazz(this.code, this.expectedVisits)
- : cls = 'C', codeByPrefix = null;
+ : cls = null, method = 'm', codeByPrefix = null;
+ const Test.clazz(this.code, this.expectedVisits,
+ {this.cls: 'C', this.method: 'm'})
+ : codeByPrefix = null;
const Test.prefix(this.codeByPrefix, this.code, this.expectedVisits)
- : cls = null;
-
- String get method => 'm';
+ : cls = null, method = 'm';
String toString() {
StringBuffer sb = new StringBuffer();
@@ -135,7 +161,8 @@ class Test {
}
}
-const List<Test> TESTS = const [
+const Map<String, List<Test>> SEND_TESTS = const {
+ 'Parameters': const [
// Parameters
const Test('m(o) => o;',
const Visit(VisitKind.VISIT_PARAMETER_GET,
@@ -149,7 +176,8 @@ const List<Test> TESTS = const [
element: 'parameter(m#o)',
arguments: '(null,42)',
selector: 'Selector(call, call, arity=2)')),
-
+ ],
+ 'Local variables': const [
// Local variables
const Test('m() { var o; return o; }',
const Visit(VisitKind.VISIT_LOCAL_VARIABLE_GET,
@@ -163,7 +191,8 @@ const List<Test> TESTS = const [
element: 'variable(m#o)',
arguments: '(null,42)',
selector: 'Selector(call, call, arity=2)')),
-
+ ],
+ 'Local functions': const [
// Local functions
const Test('m() { o(a, b) {}; return o; }',
const Visit(VisitKind.VISIT_LOCAL_FUNCTION_GET,
@@ -173,7 +202,8 @@ const List<Test> TESTS = const [
element: 'function(m#o)',
arguments: '(null,42)',
selector: 'Selector(call, call, arity=2)')),
-
+ ],
+ 'Static fields': const [
// Static fields
const Test(
'''
@@ -285,7 +315,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
element: 'field(C#o)',
arguments: '(null,42)')),
-
+ ],
+ 'Static properties': const [
// Static properties
const Test(
'''
@@ -399,7 +430,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
element: 'getter(C#o)',
arguments: '(null,42)')),
-
+ ],
+ 'Static functions': const [
// Static functions
const Test(
'''
@@ -473,7 +505,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
element: 'function(C#o)',
arguments: '(null,42)')),
-
+ ],
+ 'Top level fields': const [
// Top level fields
const Test(
'''
@@ -521,7 +554,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
element: 'field(o)',
arguments: '(null,42)')),
-
+ ],
+ 'Top level properties': const [
// Top level properties
const Test(
'''
@@ -571,7 +605,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,
element: 'getter(o)',
arguments: '(null,42)')),
-
+ ],
+ 'Top level functions': const [
// Top level functions
const Test(
'''
@@ -596,23 +631,37 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,
element: 'function(o)',
arguments: '(null,42)')),
-
+ ],
+ 'Dynamic properties': const [
// Dynamic properties
const Test('m(o) => o.foo;',
- const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
- receiver: 'o',
- name: 'foo')),
+ const [
+ const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
+ receiver: 'o',
+ name: 'foo'),
+ const Visit(VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#o)'),
+ ]),
const Test('m(o) { o.foo = 42; }',
- const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,
- receiver: 'o',
- name: 'foo',
- rhs: '42')),
+ const [
+ const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,
+ receiver: 'o',
+ name: 'foo',
+ rhs: '42'),
+ const Visit(VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#o)'),
+ ]),
const Test('m(o) { o.foo(null, 42); }',
- const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,
- receiver: 'o',
- name: 'foo',
- arguments: '(null,42)')),
-
+ const [
+ const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,
+ receiver: 'o',
+ name: 'foo',
+ arguments: '(null,42)'),
+ const Visit(VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#o)'),
+ ]),
+ ],
+ 'This access': const [
// This access
const Test.clazz(
'''
@@ -630,7 +679,8 @@ const List<Test> TESTS = const [
''',
const Visit(VisitKind.VISIT_THIS_INVOKE,
arguments: '(null,42)')),
-
+ ],
+ 'This properties': const [
// This properties
const Test.clazz(
'''
@@ -728,7 +778,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,
name: 'foo',
arguments: '(null,42)')),
-
+ ],
+ 'Super fields': const [
// Super fields
const Test.clazz(
'''
@@ -765,7 +816,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_SUPER_FIELD_INVOKE,
element: 'field(B#o)',
arguments: '(null,42)')),
-
+ ],
+ 'Super properties': const [
// Super properties
const Test.clazz(
'''
@@ -802,7 +854,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,
element: 'getter(B#o)',
arguments: '(null,42)')),
-
+ ],
+ 'Super methods': const [
// Super methods
const Test.clazz(
'''
@@ -827,13 +880,15 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_SUPER_METHOD_INVOKE,
element: 'function(B#o)',
arguments: '(null,42)')),
-
+ ],
+ 'Expression invoke': const [
// Expression invoke
const Test('m() => (a, b){}(null, 42);',
const Visit(VisitKind.VISIT_EXPRESSION_INVOKE,
receiver: '(a,b){}',
arguments: '(null,42)')),
-
+ ],
+ 'Class type literals': const [
// Class type literals
const Test(
'''
@@ -850,7 +905,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
constant: 'C',
arguments: '(null,42)')),
-
+ ],
+ 'Typedef type literals': const [
// Typedef type literals
const Test(
'''
@@ -867,7 +923,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
constant: 'F',
arguments: '(null,42)')),
-
+ ],
+ 'Type variable type literals': const [
// Type variable type literals
const Test.clazz(
'''
@@ -887,6 +944,8 @@ const List<Test> TESTS = const [
element: 'type_variable(C#T)',
arguments: '(null,42)')),
+ ],
+ 'Dynamic type literals': const [
// Dynamic type literals
const Test(
'''
@@ -903,28 +962,32 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
constant: 'dynamic',
arguments: '(null,42)')),*/
-
+ ],
+ 'Assert': const [
// Assert
const Test(
'''
m() { assert(false); }
''',
const Visit(VisitKind.VISIT_ASSERT, expression: 'false')),
-
+ ],
+ 'Logical and': const [
// Logical and
const Test(
'''
m() => true && false;
''',
const Visit(VisitKind.VISIT_LOGICAL_AND, left: 'true', right: 'false')),
-
+ ],
+ 'Logical or': const [
// Logical or
const Test(
'''
m() => true || false;
''',
const Visit(VisitKind.VISIT_LOGICAL_OR, left: 'true', right: 'false')),
-
+ ],
+ 'Is test': const [
// Is test
const Test(
'''
@@ -932,7 +995,8 @@ const List<Test> TESTS = const [
m() => 0 is C;
''',
const Visit(VisitKind.VISIT_IS, expression: '0', type: 'C')),
-
+ ],
+ 'Is not test': const [
// Is not test
const Test(
'''
@@ -940,15 +1004,17 @@ const List<Test> TESTS = const [
m() => 0 is! C;
''',
const Visit(VisitKind.VISIT_IS_NOT, expression: '0', type: 'C')),
-
- // Is test
+ ],
+ 'As test': const [
+ // As test
const Test(
'''
class C {}
m() => 0 as C;
''',
const Visit(VisitKind.VISIT_AS, expression: '0', type: 'C')),
-
+ ],
+ 'Binary operators': const [
// Binary operators
const Test(
'''
@@ -1053,6 +1119,8 @@ const List<Test> TESTS = const [
element: 'function(B#+)',
operator: '+',
right: '42')),
+ ],
+ 'Index': const [
// Index
const Test(
'''
@@ -1114,7 +1182,8 @@ const List<Test> TESTS = const [
setter: 'function(B#[]=)',
index: '42',
operator: '--')),
-
+ ],
+ 'Equals': const [
// Equals
const Test(
'''
@@ -1134,7 +1203,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_SUPER_EQUALS,
element: 'function(B#==)',
right: '42')),
-
+ ],
+ 'Not equals': const [
// Not equals
const Test(
'''
@@ -1155,7 +1225,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,
element: 'function(B#==)',
right: '42')),*/
-
+ ],
+ 'Unary expression': const [
// Unary expression
const Test(
'''
@@ -1196,7 +1267,8 @@ const List<Test> TESTS = const [
m() => !0;
''',
const Visit(VisitKind.VISIT_NOT, expression: '0')),
-
+ ],
+ 'Index set': const [
// Index set
const Test(
'''
@@ -1215,7 +1287,8 @@ const List<Test> TESTS = const [
''',
const Visit(VisitKind.VISIT_SUPER_INDEX_SET,
element: 'function(B#[]=)', index: '1', rhs: '2')),
-
+ ],
+ 'Compound assignment': const [
// Compound assignment
const Test(
'''
@@ -1533,7 +1606,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
getter: 'field(B#a)', setter: 'field(A#a)',
operator: '+=', rhs: '42')),*/
-
+ ],
+ 'Compound index assignment': const [
// Compound index assignment
const Test(
'''
@@ -1555,7 +1629,8 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_SUPER_COMPOUND_INDEX_SET,
getter: 'function(B#[])', setter: 'function(B#[]=)',
index: '1', operator: '+=', rhs: '42')),*/
-
+ ],
+ 'Prefix expression': const [
// Prefix expression
const Test(
'''
@@ -1777,8 +1852,9 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,
getter: 'field(A#a)', setter: 'setter(B#a)',
operator: '++')),
-
- // Prefix expression
+ ],
+ 'Postfix expression': const [
+ // Postfix expression
const Test(
'''
m(a) => a.b--;
@@ -1999,79 +2075,266 @@ const List<Test> TESTS = const [
const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,
getter: 'field(A#a)', setter: 'setter(B#a)',
operator: '++')),
+ ],
+ 'Constructor invocations': const [
+ const Test(
+ '''
+ class Class {
+ const Class(a, b);
+ }
+ m() => const Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,
+ constant: 'const Class(true, 42)')),
+ const Test(
+ '''
+ class Class {}
+ m() => new Class();
+ ''',
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Class#)',
+ arguments: '()',
+ type: 'Class',
+ selector: 'Selector(call, , arity=0)')),
+ const Test(
+ '''
+ class Class {
+ Class(a, b);
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'Selector(call, , arity=2)')),
+ const Test(
+ '''
+ class Class {
+ Class.named(a, b);
+ }
+ m() => new Class.named(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Class#named)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'Selector(call, named, arity=2)')),
+ const Test(
+ '''
+ class Class {
+ Class(a, b) : this._(a, b);
+ Class._(a, b);
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'Selector(call, , arity=2)')),
+ const Test(
+ '''
+ class Class {
+ factory Class(a, b) => new Class._(a, b);
+ Class._(a, b);
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'Selector(call, , arity=2)')),
+ const Test(
+ '''
+ class Class<T> {
+ factory Class(a, b) = Class<int>.a;
+ factory Class.a(a, b) = Class<Class<T>>.b;
+ Class.b(a, b);
+ }
+ m() => new Class<double>(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class<double>',
+ target: 'generative_constructor(Class#b)',
+ targetType: 'Class<Class<int>>',
+ selector: 'Selector(call, , arity=2)')),
+ const Test(
+ '''
+ class Class {
+ Class(a, b);
+ }
+ m() => new Class.unresolved(true, 42);
+ ''',
+ const Visit(
+ VisitKind.ERROR_UNRESOLVED_CONSTRUCTOR_INVOKE,
+ arguments: '(true,42)')),
+ const Test(
+ '''
+ m() => new Unresolved(true, 42);
+ ''',
+ const Visit(
+ // TODO(johnniwinther): Update this to
+ // `VisitKind.ERROR_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE`.
+ VisitKind.ERROR_UNRESOLVED_CONSTRUCTOR_INVOKE,
+ arguments: '(true,42)')),
+ const Test(
+ '''
+ abstract class AbstractClass {}
+ m() => new AbstractClass();
+ ''',
+ const Visit(
+ VisitKind.ERROR_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(AbstractClass#)',
+ type: 'AbstractClass',
+ arguments: '()',
+ selector: 'Selector(call, , arity=0)')),
+ const Test(
+ '''
+ class Class {
+ factory Class(a, b) = Unresolved;
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(
+ VisitKind.ERROR_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'Selector(call, , arity=2)')),
+ const Test(
+ '''
+ class Class {
+ factory Class(a, b) = Class.named;
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(
+ VisitKind.ERROR_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'Selector(call, , arity=2)')),
+ const Test(
+ '''
+ class Class {
+ factory Class(a, b) = Class.named;
+ factory Class.named(a, b) = Class.unresolved;
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(
+ VisitKind.ERROR_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'Selector(call, , arity=2)')),
+ const Test(
+ '''
+ abstract class AbstractClass {
+ AbstractClass(a, b);
+ }
+ class Class {
+ factory Class(a, b) = AbstractClass;
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(
+ VisitKind.ERROR_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'Selector(call, , arity=2)')),
+ ],
+};
+
+main(List<String> arguments) {
+ asyncTest(() => Future.forEach([
+ () {
+ return test(
+ arguments,
+ SEND_TESTS,
+ (elements) => new SemanticSendTestVisitor(elements));
+ },
+ ], (f) => f()));
+}
-];
-
-main() {
+Future test(List<String> arguments,
+ Map<String, List<Test>> TESTS,
+ SemanticTestVisitor createVisitor(TreeElements elements)) {
Map<String, String> sourceFiles = {};
Map<String, Test> testMap = {};
StringBuffer mainSource = new StringBuffer();
int index = 0;
- TESTS.forEach((Test test) {
- StringBuffer testSource = new StringBuffer();
- if (test.codeByPrefix != null) {
- String prefixFilename = 'pre$index.dart';
- sourceFiles[prefixFilename] = test.codeByPrefix;
- testSource.writeln("import '$prefixFilename' as p;");
- }
-
- String filename = 'lib$index.dart';
- testSource.writeln(test.code);
- sourceFiles[filename] = testSource.toString();
- mainSource.writeln("import '$filename';");
- testMap[filename] = test;
- index++;
+ TESTS.forEach((String group, List<Test> tests) {
+ if (arguments.isNotEmpty && !arguments.contains(group)) return;
+
+ tests.forEach((Test test) {
+ StringBuffer testSource = new StringBuffer();
+ if (test.codeByPrefix != null) {
+ String prefixFilename = 'pre$index.dart';
+ sourceFiles[prefixFilename] = test.codeByPrefix;
+ testSource.writeln("import '$prefixFilename' as p;");
+ }
+
+ String filename = 'lib$index.dart';
+ testSource.writeln(test.code);
+ sourceFiles[filename] = testSource.toString();
+ mainSource.writeln("import '$filename';");
+ testMap[filename] = test;
+ index++;
+ });
});
mainSource.writeln("main() {}");
sourceFiles['main.dart'] = mainSource.toString();
- asyncTest(() {
- Compiler compiler = compilerFor(sourceFiles,
- options: ['--analyze-all', '--analyze-only']);
- return compiler.run(Uri.parse('memory:main.dart')).then((_) {
- testMap.forEach((String filename, Test test) {
- LibraryElement library = compiler.libraryLoader.lookupLibrary(
- Uri.parse('memory:$filename'));
- var expectedVisits = test.expectedVisits;
- if (expectedVisits is! List) {
- expectedVisits = [expectedVisits];
- }
- AstElement element;
- String cls = test.cls;
- String method = test.method;
- if (cls == null) {
- element = library.find(method);
- } else {
- ClassElement classElement = library.find(cls);
- Expect.isNotNull(classElement,
- "Class '$cls' not found in:\n"
- "${library.compilationUnit.script.text}");
- element = classElement.localLookup(method);
- }
- Expect.isNotNull(element, "Element '$method' not found in:\n"
- "${library.compilationUnit.script.text}");
- ResolvedAst resolvedAst = element.resolvedAst;
- SemanticTestVisitor visitor =
- new SemanticTestVisitor(resolvedAst.elements);
- try {
- compiler.withCurrentElement(resolvedAst.element, () {
- //print(resolvedAst.node.toDebugString());
- resolvedAst.node.accept(visitor);
- });
- } catch (e, s) {
- Expect.fail("$e:\n$s\nIn test:\n"
- "${library.compilationUnit.script.text}");
- }
- Expect.listEquals(expectedVisits, visitor.visits,
- "In test:\n"
- "${library.compilationUnit.script.text}");
- });
+ Compiler compiler = compilerFor(sourceFiles,
+ options: ['--analyze-all', '--analyze-only']);
+ return compiler.run(Uri.parse('memory:main.dart')).then((_) {
+ testMap.forEach((String filename, Test test) {
+ LibraryElement library = compiler.libraryLoader.lookupLibrary(
+ Uri.parse('memory:$filename'));
+ var expectedVisits = test.expectedVisits;
+ if (expectedVisits is! List) {
+ expectedVisits = [expectedVisits];
+ }
+ AstElement element;
+ String cls = test.cls;
+ String method = test.method;
+ if (cls == null) {
+ element = library.find(method);
+ } else {
+ ClassElement classElement = library.find(cls);
+ Expect.isNotNull(classElement,
+ "Class '$cls' not found in:\n"
+ "${library.compilationUnit.script.text}");
+ element = classElement.localLookup(method);
+ }
+ Expect.isNotNull(element, "Element '$method' not found in:\n"
+ "${library.compilationUnit.script.text}");
+ ResolvedAst resolvedAst = element.resolvedAst;
+ SemanticTestVisitor visitor = createVisitor(resolvedAst.elements);
+ try {
+ compiler.withCurrentElement(resolvedAst.element, () {
+ //print(resolvedAst.node.toDebugString());
+ resolvedAst.node.accept(visitor);
+ });
+ } catch (e, s) {
+ Expect.fail("$e:\n$s\nIn test:\n"
+ "${library.compilationUnit.script.text}");
+ }
+ Expect.listEquals(expectedVisits, visitor.visits,
+ "In test:\n"
+ "${library.compilationUnit.script.text}");
});
});
}
-class SemanticTestVisitor extends SemanticVisitor with SemanticSendVisitor {
+abstract class SemanticTestVisitor extends TraversalVisitor {
List<Visit> visits = <Visit>[];
SemanticTestVisitor(TreeElements elements) : super(elements);
@@ -2081,13 +2344,11 @@ class SemanticTestVisitor extends SemanticVisitor with SemanticSendVisitor {
internalError(Spannable spannable, String message) {
throw new SpannableAssertionFailure(spannable, message);
}
+}
- SemanticSendVisitor get sendVisitor => this;
+class SemanticSendTestVisitor extends SemanticTestVisitor {
- @override
- visitNode(Node node) {
- node.visitChildren(this);
- }
+ SemanticSendTestVisitor(TreeElements elements) : super(elements);
@override
visitAs(
@@ -2222,6 +2483,7 @@ class SemanticTestVisitor extends SemanticVisitor with SemanticSendVisitor {
arg) {
visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
receiver: receiver, name: selector.name));
+ apply(receiver, arg);
}
@override
@@ -2233,6 +2495,7 @@ class SemanticTestVisitor extends SemanticVisitor with SemanticSendVisitor {
arg) {
visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,
receiver: receiver, name: selector.name, arguments: arguments));
+ apply(receiver, arg);
apply(arguments, arg);
}
@@ -2245,6 +2508,7 @@ class SemanticTestVisitor extends SemanticVisitor with SemanticSendVisitor {
arg) {
visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,
receiver: receiver, name: selector.name, rhs: rhs));
+ apply(receiver, arg);
}
@override
@@ -4015,6 +4279,151 @@ class SemanticTestVisitor extends SemanticVisitor with SemanticSendVisitor {
index: index, operator: operator));
apply(index, arg);
}
+
+ @override
+ errorUnresolvedClassConstructorInvoke(
+ NewExpression node,
+ Element constructor,
+ MalformedType type,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ // TODO(johnniwinther): Test [type] and [selector].
+ visits.add(new Visit(
+ VisitKind.ERROR_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
+ arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ errorUnresolvedConstructorInvoke(
+ NewExpression node,
+ Element constructor,
+ DartType type,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ // TODO(johnniwinther): Test [type] and [selector].
+ visits.add(new Visit(
+ VisitKind.ERROR_UNRESOLVED_CONSTRUCTOR_INVOKE,
+ arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitConstConstructorInvoke(
+ NewExpression node,
+ ConstructedConstantExpression constant,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,
+ constant: constant.getText()));
+ }
+
+ @override
+ visitFactoryConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ arguments: arguments,
+ selector: selector));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitGenerativeConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ arguments: arguments,
+ selector: selector));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitRedirectingFactoryConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ ConstructorElement effectiveTarget,
+ InterfaceType effectiveTargetType,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ target: effectiveTarget,
+ targetType: effectiveTargetType,
+ arguments: arguments,
+ selector: selector));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitRedirectingGenerativeConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ arguments: arguments,
+ selector: selector));
+ apply(arguments, arg);
+ }
+
+ @override
+ errorAbstractClassConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.ERROR_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ arguments: arguments,
+ selector: selector));
+ apply(arguments, arg);
+ }
+
+ @override
+ errorUnresolvedRedirectingFactoryConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.ERROR_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ arguments: arguments,
+ selector: selector));
+ apply(arguments, arg);
+ }
}
enum VisitKind {
@@ -4174,5 +4583,16 @@ enum VisitKind {
VISIT_IS_NOT,
VISIT_AS,
+ VISIT_CONST_CONSTRUCTOR_INVOKE,
+ VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+ VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
+ VISIT_FACTORY_CONSTRUCTOR_INVOKE,
+ VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+
+ ERROR_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
+ ERROR_UNRESOLVED_CONSTRUCTOR_INVOKE,
+ ERROR_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
+ ERROR_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+
// TODO(johnniwinther): Add tests for error cases.
}
« no previous file with comments | « pkg/compiler/lib/src/resolved_visitor.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698