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

Side by Side Diff: pkg/kernel/test/verify_test.dart

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: Address Kevin's comments Created 3 years, 10 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 unified diff | Download patch
« no previous file with comments | « pkg/kernel/test/type_parser.dart ('k') | runtime/vm/kernel.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 import 'package:kernel/ast.dart'; 4 import 'package:kernel/ast.dart';
5 import 'package:kernel/text/ast_to_text.dart'; 5 import 'package:kernel/text/ast_to_text.dart';
6 import 'package:kernel/verifier.dart'; 6 import 'package:kernel/verifier.dart';
7 import 'package:test/test.dart'; 7 import 'package:test/test.dart';
8 8
9 /// Checks that the verifier correctly find errors in invalid programs. 9 /// Checks that the verifier correctly find errors in invalid programs.
10 /// 10 ///
11 /// The frontend should never generate invalid programs, so we have to test 11 /// The frontend should never generate invalid programs, so we have to test
12 /// these by manually constructing invalid ASTs. 12 /// these by manually constructing invalid ASTs.
13 /// 13 ///
14 /// We mostly test negative cases here, as we get plenty of positive cases by 14 /// We mostly test negative cases here, as we get plenty of positive cases by
15 /// compiling the Dart test suite with the verifier enabled. 15 /// compiling the Dart test suite with the verifier enabled.
16 main() { 16 main() {
17 positiveTest('Test harness has no errors', () { 17 positiveTest('Test harness has no errors', (TestHarness test) {
18 return new NullLiteral(); 18 return new NullLiteral();
19 }); 19 });
20 negativeTest('VariableGet out of scope', () { 20 negativeTest('VariableGet out of scope', (TestHarness test) {
21 return new VariableGet(makeVariable()); 21 return new VariableGet(test.makeVariable());
22 }); 22 });
23 negativeTest('VariableSet out of scope', () { 23 negativeTest('VariableSet out of scope', (TestHarness test) {
24 return new VariableSet(makeVariable(), new NullLiteral()); 24 return new VariableSet(test.makeVariable(), new NullLiteral());
25 }); 25 });
26 negativeTest('Variable block scope', () { 26 negativeTest('Variable block scope', (TestHarness test) {
27 VariableDeclaration variable = makeVariable(); 27 VariableDeclaration variable = test.makeVariable();
28 return new Block([ 28 return new Block([
29 new Block([variable]), 29 new Block([variable]),
30 new ReturnStatement(new VariableGet(variable)) 30 new ReturnStatement(new VariableGet(variable))
31 ]); 31 ]);
32 }); 32 });
33 negativeTest('Variable let scope', () { 33 negativeTest('Variable let scope', (TestHarness test) {
34 VariableDeclaration variable = makeVariable(); 34 VariableDeclaration variable = test.makeVariable();
35 return new LogicalExpression(new Let(variable, new VariableGet(variable)), 35 return new LogicalExpression(new Let(variable, new VariableGet(variable)),
36 '&&', new VariableGet(variable)); 36 '&&', new VariableGet(variable));
37 }); 37 });
38 negativeTest('Variable redeclared', () { 38 negativeTest('Variable redeclared', (TestHarness test) {
39 VariableDeclaration variable = makeVariable(); 39 VariableDeclaration variable = test.makeVariable();
40 return new Block([variable, variable]); 40 return new Block([variable, variable]);
41 }); 41 });
42 negativeTest('Member redeclared', () { 42 negativeTest('Member redeclared', (TestHarness test) {
43 Field field = new Field(new Name('field'), initializer: new NullLiteral()); 43 Field field = new Field(new Name('field'), initializer: new NullLiteral());
44 return new Class( 44 return new Class(
45 name: 'Test', 45 name: 'Test',
46 supertype: objectClass.asRawSupertype, 46 supertype: test.objectClass.asRawSupertype,
47 fields: [field, field]); 47 fields: [field, field]);
48 }); 48 });
49 negativeTest('Class redeclared', () { 49 negativeTest('Class redeclared', (TestHarness test) {
50 return otherClass; // Test harness also adds otherClass to program. 50 return test.otherClass; // Test harness also adds otherClass to program.
51 }); 51 });
52 negativeTest('Class type parameter redeclared', () { 52 negativeTest('Class type parameter redeclared', (TestHarness test) {
53 var parameter = makeTypeParameter(); 53 var parameter = test.makeTypeParameter();
54 return new Class( 54 return new Class(
55 name: 'Test', 55 name: 'Test',
56 supertype: objectClass.asRawSupertype, 56 supertype: test.objectClass.asRawSupertype,
57 typeParameters: [parameter, parameter]); 57 typeParameters: [parameter, parameter]);
58 }); 58 });
59 negativeTest('Member type parameter redeclared', () { 59 negativeTest('Member type parameter redeclared', (TestHarness test) {
60 var parameter = makeTypeParameter(); 60 var parameter = test.makeTypeParameter();
61 return new Procedure( 61 return new Procedure(
62 new Name('test'), 62 new Name('bar'),
63 ProcedureKind.Method, 63 ProcedureKind.Method,
64 new FunctionNode(new ReturnStatement(new NullLiteral()), 64 new FunctionNode(new ReturnStatement(new NullLiteral()),
65 typeParameters: [parameter, parameter])); 65 typeParameters: [parameter, parameter]));
66 }); 66 });
67 negativeTest('Type parameter out of scope', () { 67 negativeTest('Type parameter out of scope', (TestHarness test) {
68 var parameter = makeTypeParameter(); 68 var parameter = test.makeTypeParameter();
69 return new ListLiteral([], typeArgument: new TypeParameterType(parameter)); 69 return new ListLiteral([], typeArgument: new TypeParameterType(parameter));
70 }); 70 });
71 negativeTest('Class type parameter from another class', () { 71 negativeTest('Class type parameter from another class', (TestHarness test) {
72 return new TypeLiteral(new TypeParameterType(otherClass.typeParameters[0])); 72 return new TypeLiteral(
73 new TypeParameterType(test.otherClass.typeParameters[0]));
73 }); 74 });
74 negativeTest('Class type parameter in static method', () { 75 negativeTest('Class type parameter in static method', (TestHarness test) {
75 return new Procedure( 76 return new Procedure(
76 new Name('test'), 77 new Name('bar'),
77 ProcedureKind.Method, 78 ProcedureKind.Method,
78 new FunctionNode(new ReturnStatement( 79 new FunctionNode(new ReturnStatement(
79 new TypeLiteral(new TypeParameterType(classTypeParameter)))), 80 new TypeLiteral(new TypeParameterType(test.classTypeParameter)))),
80 isStatic: true); 81 isStatic: true);
81 }); 82 });
82 negativeTest('Class type parameter in static field', () { 83 negativeTest('Class type parameter in static field', (TestHarness test) {
83 return new Field(new Name('field'), 84 return new Field(new Name('field'),
84 initializer: new TypeLiteral(new TypeParameterType(classTypeParameter)), 85 initializer:
86 new TypeLiteral(new TypeParameterType(test.classTypeParameter)),
85 isStatic: true); 87 isStatic: true);
86 }); 88 });
87 negativeTest('Method type parameter out of scope', () { 89 negativeTest('Method type parameter out of scope', (TestHarness test) {
88 var parameter = makeTypeParameter(); 90 var parameter = test.makeTypeParameter();
89 return new Class( 91 return new Class(
90 name: 'Test', 92 name: 'Test',
91 supertype: objectClass.asRawSupertype, 93 supertype: test.objectClass.asRawSupertype,
92 procedures: [ 94 procedures: [
93 new Procedure( 95 new Procedure(
94 new Name('generic'), 96 new Name('generic'),
95 ProcedureKind.Method, 97 ProcedureKind.Method,
96 new FunctionNode(new EmptyStatement(), 98 new FunctionNode(new EmptyStatement(),
97 typeParameters: [parameter])), 99 typeParameters: [parameter])),
98 new Procedure( 100 new Procedure(
99 new Name('use'), 101 new Name('use'),
100 ProcedureKind.Method, 102 ProcedureKind.Method,
101 new FunctionNode(new ReturnStatement( 103 new FunctionNode(new ReturnStatement(
102 new TypeLiteral(new TypeParameterType(parameter))))) 104 new TypeLiteral(new TypeParameterType(parameter)))))
103 ]); 105 ]);
104 }); 106 });
105 negativeTest('Interface type arity too low', () { 107 negativeTest('Interface type arity too low', (TestHarness test) {
106 return new TypeLiteral(new InterfaceType(otherClass, [])); 108 return new TypeLiteral(new InterfaceType(test.otherClass, []));
107 }); 109 });
108 negativeTest('Interface type arity too high', () { 110 negativeTest('Interface type arity too high', (TestHarness test) {
109 return new TypeLiteral( 111 return new TypeLiteral(new InterfaceType(
110 new InterfaceType(otherClass, [new DynamicType(), new DynamicType()])); 112 test.otherClass, [new DynamicType(), new DynamicType()]));
111 }); 113 });
112 negativeTest('Dangling interface type', () { 114 negativeTest('Dangling interface type', (TestHarness test) {
113 return new TypeLiteral(new InterfaceType(new Class())); 115 var orphan = new Class();
116 return new TypeLiteral(new InterfaceType(orphan));
114 }); 117 });
115 negativeTest('Dangling field get', () { 118 negativeTest('Dangling field get', (TestHarness test) {
116 return new DirectPropertyGet(new NullLiteral(), new Field(new Name('foo'))); 119 var orphan = new Field(new Name('foo'));
120 return new DirectPropertyGet(new NullLiteral(), orphan);
117 }); 121 });
118 negativeTest('Missing block parent pointer', () { 122 negativeTest('Missing block parent pointer', (TestHarness test) {
119 var block = new Block([]); 123 var block = new Block([]);
120 block.statements.add(new ReturnStatement()); 124 block.statements.add(new ReturnStatement());
121 return block; 125 return block;
122 }); 126 });
123 negativeTest('Missing function parent pointer', () { 127 negativeTest('Missing function parent pointer', (TestHarness test) {
124 var procedure = new Procedure(new Name('test'), ProcedureKind.Method, null); 128 var procedure = new Procedure(new Name('bar'), ProcedureKind.Method, null);
125 procedure.function = new FunctionNode(new EmptyStatement()); 129 procedure.function = new FunctionNode(new EmptyStatement());
126 return procedure; 130 return procedure;
127 }); 131 });
128 negativeTest('StaticGet without target', () { 132 negativeTest('StaticGet without target', (TestHarness test) {
129 return new StaticGet(null); 133 return new StaticGet(null);
130 }); 134 });
131 negativeTest('StaticSet without target', () { 135 negativeTest('StaticSet without target', (TestHarness test) {
132 return new StaticSet(null, new NullLiteral()); 136 return new StaticSet(null, new NullLiteral());
133 }); 137 });
134 negativeTest('StaticInvocation without target', () { 138 negativeTest('StaticInvocation without target', (TestHarness test) {
135 return new StaticInvocation(null, new Arguments.empty()); 139 return new StaticInvocation(null, new Arguments.empty());
136 }); 140 });
137 positiveTest('Correct StaticInvocation', () { 141 positiveTest('Correct StaticInvocation', (TestHarness test) {
138 var method = new Procedure(new Name('test'), ProcedureKind.Method, null, 142 var method = new Procedure(
143 new Name('foo'),
144 ProcedureKind.Method,
145 new FunctionNode(new EmptyStatement(),
146 positionalParameters: [new VariableDeclaration('p')]),
139 isStatic: true); 147 isStatic: true);
140 method.function = new FunctionNode( 148 test.enclosingClass.addMember(method);
141 new ReturnStatement( 149 return new StaticInvocation(method, new Arguments([new NullLiteral()]));
142 new StaticInvocation(method, new Arguments([new NullLiteral()]))),
143 positionalParameters: [new VariableDeclaration('p')])..parent = method;
144 return new Class(
145 name: 'Test',
146 supertype: objectClass.asRawSupertype,
147 procedures: [method]);
148 }); 150 });
149 negativeTest('StaticInvocation with too many parameters', () { 151 negativeTest('StaticInvocation with too many parameters', (TestHarness test) {
150 var method = new Procedure(new Name('test'), ProcedureKind.Method, null, 152 var method = new Procedure(new Name('bar'), ProcedureKind.Method,
153 new FunctionNode(new EmptyStatement()),
151 isStatic: true); 154 isStatic: true);
152 method.function = new FunctionNode(new ReturnStatement( 155 test.enclosingClass.addMember(method);
153 new StaticInvocation(method, new Arguments([new NullLiteral()])))) 156 return new StaticInvocation(method, new Arguments([new NullLiteral()]));
154 ..parent = method;
155 return new Class(
156 name: 'Test',
157 supertype: objectClass.asRawSupertype,
158 procedures: [method]);
159 }); 157 });
160 negativeTest('StaticInvocation with too few parameters', () { 158 negativeTest('StaticInvocation with too few parameters', (TestHarness test) {
161 var method = new Procedure(new Name('test'), ProcedureKind.Method, null, 159 var method = new Procedure(
160 new Name('bar'),
161 ProcedureKind.Method,
162 new FunctionNode(new EmptyStatement(),
163 positionalParameters: [new VariableDeclaration('p')]),
162 isStatic: true); 164 isStatic: true);
163 method.function = new FunctionNode( 165 test.enclosingClass.addMember(method);
164 new ReturnStatement( 166 return new StaticInvocation(method, new Arguments.empty());
165 new StaticInvocation(method, new Arguments.empty())),
166 positionalParameters: [new VariableDeclaration('p')])..parent = method;
167 return new Class(
168 name: 'Test',
169 supertype: objectClass.asRawSupertype,
170 procedures: [method]);
171 }); 167 });
172 negativeTest('StaticInvocation with unmatched named parameter', () { 168 negativeTest('StaticInvocation with unmatched named parameter',
173 var method = new Procedure(new Name('test'), ProcedureKind.Method, null, 169 (TestHarness test) {
170 var method = new Procedure(new Name('bar'), ProcedureKind.Method,
171 new FunctionNode(new EmptyStatement()),
174 isStatic: true); 172 isStatic: true);
175 method.function = new FunctionNode(new ReturnStatement(new StaticInvocation( 173 test.enclosingClass.addMember(method);
174 return new StaticInvocation(
176 method, 175 method,
177 new Arguments([], 176 new Arguments([],
178 named: [new NamedExpression('p', new NullLiteral())])))) 177 named: [new NamedExpression('p', new NullLiteral())]));
179 ..parent = method; 178 });
180 return new Class( 179 negativeTest('StaticInvocation with missing type argument',
180 (TestHarness test) {
181 var method = new Procedure(
182 new Name('bar'),
183 ProcedureKind.Method,
184 new FunctionNode(new EmptyStatement(),
185 typeParameters: [test.makeTypeParameter()]),
186 isStatic: true);
187 test.enclosingClass.addMember(method);
188 return new StaticInvocation(method, new Arguments.empty());
189 });
190 negativeTest('ConstructorInvocation with missing type argument',
191 (TestHarness test) {
192 var class_ = new Class(
181 name: 'Test', 193 name: 'Test',
182 supertype: objectClass.asRawSupertype, 194 typeParameters: [test.makeTypeParameter()],
183 procedures: [method]); 195 supertype: test.objectClass.asRawSupertype);
184 }); 196 test.enclosingLibrary.addClass(class_);
185 negativeTest('StaticInvocation with missing type argument', () { 197 var constructor = new Constructor(new FunctionNode(new EmptyStatement()),
186 var method = new Procedure(new Name('test'), ProcedureKind.Method, null, 198 name: new Name('foo'));
187 isStatic: true); 199 test.enclosingClass.addMember(constructor);
188 method.function = new FunctionNode( 200 return new ConstructorInvocation(constructor, new Arguments.empty());
189 new ReturnStatement(
190 new StaticInvocation(method, new Arguments.empty())),
191 typeParameters: [makeTypeParameter()])..parent = method;
192 return new Class(
193 name: 'Test',
194 supertype: objectClass.asRawSupertype,
195 procedures: [method]);
196 });
197 negativeTest('ConstructorInvocation with missing type argument', () {
198 var constructor = new Constructor(null);
199 constructor.function = new FunctionNode(new ReturnStatement(
200 new ConstructorInvocation(constructor, new Arguments.empty())))
201 ..parent = constructor;
202 return new Class(
203 name: 'Test',
204 typeParameters: [makeTypeParameter()],
205 supertype: objectClass.asRawSupertype,
206 constructors: [constructor]);
207 }); 201 });
208 } 202 }
209 203
210 checkHasError(Program program) { 204 checkHasError(Program program) {
211 bool passed = false; 205 bool passed = false;
212 try { 206 try {
213 verifyProgram(program); 207 verifyProgram(program);
214 passed = true; 208 passed = true;
215 } catch (e) {} 209 } catch (e) {}
216 if (passed) { 210 if (passed) {
217 fail('Failed to reject invalid program:\n${programToString(program)}'); 211 fail('Failed to reject invalid program:\n${programToString(program)}');
218 } 212 }
219 } 213 }
220 214
221 Class objectClass = new Class(name: 'Object'); 215 class TestHarness {
216 Program program;
217 Class objectClass;
218 Library stubLibrary;
222 219
223 Library stubLibrary = new Library(Uri.parse('dart:core')) 220 TypeParameter classTypeParameter;
224 ..addClass(objectClass);
225 221
226 TypeParameter classTypeParameter = makeTypeParameter('T'); 222 Library enclosingLibrary;
223 Class enclosingClass;
224 Procedure enclosingMember;
227 225
228 Class otherClass = new Class( 226 Class otherClass;
229 name: 'OtherClass',
230 typeParameters: [makeTypeParameter('OtherT')],
231 supertype: objectClass.asRawSupertype);
232 227
233 Program makeProgram(TreeNode makeBody()) { 228 void addNode(TreeNode node) {
234 var node = makeBody(); 229 if (node is Expression) {
235 if (node is Expression) { 230 addExpression(node);
236 node = new ReturnStatement(node); 231 } else if (node is Statement) {
232 addStatement(node);
233 } else if (node is Member) {
234 addClassMember(node);
235 } else if (node is Class) {
236 addClass(node);
237 }
237 } 238 }
238 if (node is Statement) { 239
239 node = new FunctionNode(node); 240 void addExpression(Expression node) {
241 addStatement(new ReturnStatement(node));
240 } 242 }
241 if (node is FunctionNode) { 243
242 node = new Procedure(new Name('test'), ProcedureKind.Method, node); 244 void addStatement(Statement node) {
245 var function = enclosingMember.function;
246 function.body = node..parent = function;
243 } 247 }
244 if (node is Member) { 248
245 node = new Class( 249 void addClassMember(Member node) {
246 name: 'Test', 250 enclosingClass.addMember(node);
251 }
252
253 void addTopLevelMember(Member node) {
254 enclosingLibrary.addMember(node);
255 }
256
257 void addClass(Class node) {
258 enclosingLibrary.addClass(node);
259 }
260
261 VariableDeclaration makeVariable() => new VariableDeclaration(null);
262
263 TypeParameter makeTypeParameter([String name]) {
264 return new TypeParameter(name, new InterfaceType(objectClass));
265 }
266
267 TestHarness() {
268 setupProgram();
269 }
270
271 void setupProgram() {
272 program = new Program();
273 stubLibrary = new Library(Uri.parse('dart:core'));
274 program.libraries.add(stubLibrary..parent = program);
275 stubLibrary.name = 'dart.core';
276 objectClass = new Class(name: 'Object');
277 stubLibrary.addClass(objectClass);
278 enclosingLibrary = new Library(Uri.parse('file://test.dart'));
279 program.libraries.add(enclosingLibrary..parent = program);
280 enclosingLibrary.name = 'test_lib';
281 classTypeParameter = makeTypeParameter('T');
282 enclosingClass = new Class(
283 name: 'TestClass',
247 typeParameters: [classTypeParameter], 284 typeParameters: [classTypeParameter],
248 supertype: objectClass.asRawSupertype)..addMember(node); 285 supertype: objectClass.asRawSupertype);
286 enclosingLibrary.addClass(enclosingClass);
287 enclosingMember = new Procedure(new Name('test'), ProcedureKind.Method,
288 new FunctionNode(new EmptyStatement()));
289 enclosingClass.addMember(enclosingMember);
290 otherClass = new Class(
291 name: 'OtherClass',
292 typeParameters: [makeTypeParameter('OtherT')],
293 supertype: objectClass.asRawSupertype);
294 enclosingLibrary.addClass(otherClass);
249 } 295 }
250 if (node is Class) {
251 node =
252 new Library(Uri.parse('test.dart'), classes: <Class>[node, otherClass]);
253 }
254 if (node is Library) {
255 node = new Program(<Library>[node, stubLibrary]);
256 }
257 assert(node is Program);
258 return node;
259 } 296 }
260 297
261 negativeTest(String name, TreeNode makeBody()) { 298 negativeTest(String name, TreeNode makeTestCase(TestHarness test)) {
262 test(name, () { 299 test(name, () {
263 checkHasError(makeProgram(makeBody)); 300 var test = new TestHarness();
301 test.addNode(makeTestCase(test));
302 checkHasError(test.program);
264 }); 303 });
265 } 304 }
266 305
267 positiveTest(String name, TreeNode makeBody()) { 306 positiveTest(String name, TreeNode makeTestCase(TestHarness test)) {
268 test(name, () { 307 test(name, () {
269 verifyProgram(makeProgram(makeBody)); 308 var test = new TestHarness();
309 test.addNode(makeTestCase(test));
310 verifyProgram(test.program);
270 }); 311 });
271 } 312 }
272
273 VariableDeclaration makeVariable() => new VariableDeclaration(null);
274
275 TypeParameter makeTypeParameter([String name]) {
276 return new TypeParameter(name, new InterfaceType(objectClass));
277 }
OLDNEW
« no previous file with comments | « pkg/kernel/test/type_parser.dart ('k') | runtime/vm/kernel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698