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

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

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: Address more 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
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 test.enclosingLibrary.canonicalName.getChild('foo').bindTo(orphan);
117 return new TypeLiteral(new InterfaceType(orphan));
114 }); 118 });
115 negativeTest('Dangling field get', () { 119 negativeTest('Dangling field get', (TestHarness test) {
116 return new DirectPropertyGet(new NullLiteral(), new Field(new Name('foo'))); 120 var orphan = new Field(new Name('foo'));
121 test.enclosingLibrary.canonicalName.getChild('foo').bindTo(orphan);
122 return new DirectPropertyGet(new NullLiteral(), orphan);
117 }); 123 });
118 negativeTest('Missing block parent pointer', () { 124 negativeTest('Missing block parent pointer', (TestHarness test) {
119 var block = new Block([]); 125 var block = new Block([]);
120 block.statements.add(new ReturnStatement()); 126 block.statements.add(new ReturnStatement());
121 return block; 127 return block;
122 }); 128 });
123 negativeTest('Missing function parent pointer', () { 129 negativeTest('Missing function parent pointer', (TestHarness test) {
124 var procedure = new Procedure(new Name('test'), ProcedureKind.Method, null); 130 var procedure = new Procedure(new Name('bar'), ProcedureKind.Method, null);
125 procedure.function = new FunctionNode(new EmptyStatement()); 131 procedure.function = new FunctionNode(new EmptyStatement());
126 return procedure; 132 return procedure;
127 }); 133 });
128 negativeTest('StaticGet without target', () { 134 negativeTest('StaticGet without target', (TestHarness test) {
129 return new StaticGet(null); 135 return new StaticGet(null);
130 }); 136 });
131 negativeTest('StaticSet without target', () { 137 negativeTest('StaticSet without target', (TestHarness test) {
132 return new StaticSet(null, new NullLiteral()); 138 return new StaticSet(null, new NullLiteral());
133 }); 139 });
134 negativeTest('StaticInvocation without target', () { 140 negativeTest('StaticInvocation without target', (TestHarness test) {
135 return new StaticInvocation(null, new Arguments.empty()); 141 return new StaticInvocation(null, new Arguments.empty());
136 }); 142 });
137 positiveTest('Correct StaticInvocation', () { 143 positiveTest('Correct StaticInvocation', (TestHarness test) {
138 var method = new Procedure(new Name('test'), ProcedureKind.Method, null, 144 var method = new Procedure(
145 new Name('foo'),
146 ProcedureKind.Method,
147 new FunctionNode(new EmptyStatement(),
148 positionalParameters: [new VariableDeclaration('p')]),
139 isStatic: true); 149 isStatic: true);
140 method.function = new FunctionNode( 150 test.enclosingClass.addMember(method);
141 new ReturnStatement( 151 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 }); 152 });
149 negativeTest('StaticInvocation with too many parameters', () { 153 negativeTest('StaticInvocation with too many parameters', (TestHarness test) {
150 var method = new Procedure(new Name('test'), ProcedureKind.Method, null, 154 var method = new Procedure(new Name('bar'), ProcedureKind.Method,
155 new FunctionNode(new EmptyStatement()),
151 isStatic: true); 156 isStatic: true);
152 method.function = new FunctionNode(new ReturnStatement( 157 test.enclosingClass.addMember(method);
153 new StaticInvocation(method, new Arguments([new NullLiteral()])))) 158 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 }); 159 });
160 negativeTest('StaticInvocation with too few parameters', () { 160 negativeTest('StaticInvocation with too few parameters', (TestHarness test) {
161 var method = new Procedure(new Name('test'), ProcedureKind.Method, null, 161 var method = new Procedure(
162 new Name('bar'),
163 ProcedureKind.Method,
164 new FunctionNode(new EmptyStatement(),
165 positionalParameters: [new VariableDeclaration('p')]),
162 isStatic: true); 166 isStatic: true);
163 method.function = new FunctionNode( 167 test.enclosingClass.addMember(method);
164 new ReturnStatement( 168 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 }); 169 });
172 negativeTest('StaticInvocation with unmatched named parameter', () { 170 negativeTest('StaticInvocation with unmatched named parameter',
173 var method = new Procedure(new Name('test'), ProcedureKind.Method, null, 171 (TestHarness test) {
172 var method = new Procedure(new Name('bar'), ProcedureKind.Method,
173 new FunctionNode(new EmptyStatement()),
174 isStatic: true); 174 isStatic: true);
175 method.function = new FunctionNode(new ReturnStatement(new StaticInvocation( 175 test.enclosingClass.addMember(method);
176 return new StaticInvocation(
176 method, 177 method,
177 new Arguments([], 178 new Arguments([],
178 named: [new NamedExpression('p', new NullLiteral())])))) 179 named: [new NamedExpression('p', new NullLiteral())]));
179 ..parent = method; 180 });
180 return new Class( 181 negativeTest('StaticInvocation with missing type argument',
182 (TestHarness test) {
183 var method = new Procedure(
184 new Name('bar'),
185 ProcedureKind.Method,
186 new FunctionNode(new EmptyStatement(),
187 typeParameters: [test.makeTypeParameter()]),
188 isStatic: true);
189 test.enclosingClass.addMember(method);
190 return new StaticInvocation(method, new Arguments.empty());
191 });
192 negativeTest('ConstructorInvocation with missing type argument',
193 (TestHarness test) {
194 var class_ = new Class(
181 name: 'Test', 195 name: 'Test',
182 supertype: objectClass.asRawSupertype, 196 typeParameters: [test.makeTypeParameter()],
183 procedures: [method]); 197 supertype: test.objectClass.asRawSupertype);
184 }); 198 test.enclosingLibrary.addClass(class_);
185 negativeTest('StaticInvocation with missing type argument', () { 199 var constructor = new Constructor(new FunctionNode(new EmptyStatement()),
186 var method = new Procedure(new Name('test'), ProcedureKind.Method, null, 200 name: new Name('foo'));
187 isStatic: true); 201 test.enclosingClass.addMember(constructor);
188 method.function = new FunctionNode( 202 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 }); 203 });
208 } 204 }
209 205
210 checkHasError(Program program) { 206 checkHasError(Program program) {
211 bool passed = false; 207 bool passed = false;
212 try { 208 try {
213 verifyProgram(program); 209 verifyProgram(program);
214 passed = true; 210 passed = true;
215 } catch (e) {} 211 } catch (e) {}
216 if (passed) { 212 if (passed) {
217 fail('Failed to reject invalid program:\n${programToString(program)}'); 213 fail('Failed to reject invalid program:\n${programToString(program)}');
218 } 214 }
219 } 215 }
220 216
221 Class objectClass = new Class(name: 'Object'); 217 class TestHarness {
218 Program program;
219 Class objectClass;
220 Library stubLibrary;
222 221
223 Library stubLibrary = new Library(Uri.parse('dart:core')) 222 TypeParameter classTypeParameter;
224 ..addClass(objectClass);
225 223
226 TypeParameter classTypeParameter = makeTypeParameter('T'); 224 Library enclosingLibrary;
225 Class enclosingClass;
226 Procedure enclosingMember;
227 227
228 Class otherClass = new Class( 228 Class otherClass;
229 name: 'OtherClass',
230 typeParameters: [makeTypeParameter('OtherT')],
231 supertype: objectClass.asRawSupertype);
232 229
233 Program makeProgram(TreeNode makeBody()) { 230 void addNode(TreeNode node) {
234 var node = makeBody(); 231 if (node is Expression) {
235 if (node is Expression) { 232 addExpression(node);
236 node = new ReturnStatement(node); 233 } else if (node is Statement) {
234 addStatement(node);
235 } else if (node is Member) {
236 addClassMember(node);
237 } else if (node is Class) {
238 addClass(node);
239 }
237 } 240 }
238 if (node is Statement) { 241
239 node = new FunctionNode(node); 242 void addExpression(Expression node) {
243 addStatement(new ReturnStatement(node));
240 } 244 }
241 if (node is FunctionNode) { 245
242 node = new Procedure(new Name('test'), ProcedureKind.Method, node); 246 void addStatement(Statement node) {
247 var function = enclosingMember.function;
248 function.body = node..parent = function;
243 } 249 }
244 if (node is Member) { 250
245 node = new Class( 251 void addClassMember(Member node) {
246 name: 'Test', 252 enclosingClass.addMember(node);
253 }
254
255 void addTopLevelMember(Member node) {
256 enclosingLibrary.addMember(node);
257 }
258
259 void addClass(Class node) {
260 enclosingLibrary.addClass(node);
261 }
262
263 VariableDeclaration makeVariable() => new VariableDeclaration(null);
264
265 TypeParameter makeTypeParameter([String name]) {
266 return new TypeParameter(name, new InterfaceType(objectClass));
267 }
268
269 TestHarness() {
270 setupProgram();
271 }
272
273 void setupProgram() {
274 program = new Program();
275 stubLibrary = program.getLibraryReference(Uri.parse('dart:core'));
276 stubLibrary.name = 'dart.core';
277 objectClass = new Class(name: 'Object');
278 stubLibrary.addClass(objectClass);
279 enclosingLibrary =
280 program.getLibraryReference(Uri.parse('file://test.dart'));
281 enclosingLibrary.name = 'test_lib';
282 classTypeParameter = makeTypeParameter('T');
283 enclosingClass = new Class(
284 name: 'TestClass',
247 typeParameters: [classTypeParameter], 285 typeParameters: [classTypeParameter],
248 supertype: objectClass.asRawSupertype)..addMember(node); 286 supertype: objectClass.asRawSupertype);
287 enclosingLibrary.addClass(enclosingClass);
288 enclosingMember = new Procedure(new Name('test'), ProcedureKind.Method,
289 new FunctionNode(new EmptyStatement()));
290 enclosingClass.addMember(enclosingMember);
291 otherClass = new Class(
292 name: 'OtherClass',
293 typeParameters: [makeTypeParameter('OtherT')],
294 supertype: objectClass.asRawSupertype);
295 enclosingLibrary.addClass(otherClass);
249 } 296 }
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 } 297 }
260 298
261 negativeTest(String name, TreeNode makeBody()) { 299 negativeTest(String name, TreeNode makeTestCase(TestHarness test)) {
262 test(name, () { 300 test(name, () {
263 checkHasError(makeProgram(makeBody)); 301 var test = new TestHarness();
302 test.addNode(makeTestCase(test));
303 checkHasError(test.program);
264 }); 304 });
265 } 305 }
266 306
267 positiveTest(String name, TreeNode makeBody()) { 307 positiveTest(String name, TreeNode makeTestCase(TestHarness test)) {
268 test(name, () { 308 test(name, () {
269 verifyProgram(makeProgram(makeBody)); 309 var test = new TestHarness();
310 test.addNode(makeTestCase(test));
311 verifyProgram(test.program);
270 }); 312 });
271 } 313 }
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') | runtime/vm/kernel.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698