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

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

Issue 2999033002: Mark top-level error field as static. (Closed)
Patch Set: Remove unused import. Created 3 years, 3 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/lib/verifier.dart ('k') | no next file » | 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
4 import 'package:kernel/ast.dart'; 5 import 'package:kernel/ast.dart';
5 import 'package:kernel/text/ast_to_text.dart'; 6 import 'package:kernel/text/ast_to_text.dart';
6 import 'package:kernel/verifier.dart'; 7 import 'package:kernel/verifier.dart';
7 import 'package:test/test.dart'; 8 import 'package:test/test.dart';
8 9
10 const String varRegexp = "#t[0-9]+";
11
12 const String tvarRegexp = "#T[0-9]+";
13
9 /// Checks that the verifier correctly find errors in invalid programs. 14 /// Checks that the verifier correctly find errors in invalid programs.
10 /// 15 ///
11 /// The frontend should never generate invalid programs, so we have to test 16 /// The frontend should never generate invalid programs, so we have to test
12 /// these by manually constructing invalid ASTs. 17 /// these by manually constructing invalid ASTs.
13 /// 18 ///
14 /// We mostly test negative cases here, as we get plenty of positive cases by 19 /// We mostly test negative cases here, as we get plenty of positive cases by
15 /// compiling the Dart test suite with the verifier enabled. 20 /// compiling the Dart test suite with the verifier enabled.
16 main() { 21 main() {
17 positiveTest('Test harness has no errors', (TestHarness test) { 22 positiveTest('Test harness has no errors', (TestHarness test) {
18 return new NullLiteral(); 23 return new NullLiteral();
19 }); 24 });
20 negativeTest('VariableGet out of scope', (TestHarness test) { 25 negativeTest('VariableGet out of scope',
26 matches("Variable '$varRegexp' used out of scope\\."),
27 (TestHarness test) {
21 return new VariableGet(test.makeVariable()); 28 return new VariableGet(test.makeVariable());
22 }); 29 });
23 negativeTest('VariableSet out of scope', (TestHarness test) { 30 negativeTest('VariableSet out of scope',
31 matches("Variable '$varRegexp' used out of scope\\."),
32 (TestHarness test) {
24 return new VariableSet(test.makeVariable(), new NullLiteral()); 33 return new VariableSet(test.makeVariable(), new NullLiteral());
25 }); 34 });
26 negativeTest('Variable block scope', (TestHarness test) { 35 negativeTest('Variable block scope',
36 matches("Variable '$varRegexp' used out of scope\\."),
37 (TestHarness test) {
27 VariableDeclaration variable = test.makeVariable(); 38 VariableDeclaration variable = test.makeVariable();
28 return new Block([ 39 return new Block([
29 new Block([variable]), 40 new Block([variable]),
30 new ReturnStatement(new VariableGet(variable)) 41 new ReturnStatement(new VariableGet(variable))
31 ]); 42 ]);
32 }); 43 });
33 negativeTest('Variable let scope', (TestHarness test) { 44 negativeTest('Variable let scope',
45 matches("Variable '$varRegexp' used out of scope\\."),
46 (TestHarness test) {
34 VariableDeclaration variable = test.makeVariable(); 47 VariableDeclaration variable = test.makeVariable();
35 return new LogicalExpression(new Let(variable, new VariableGet(variable)), 48 return new LogicalExpression(new Let(variable, new VariableGet(variable)),
36 '&&', new VariableGet(variable)); 49 '&&', new VariableGet(variable));
37 }); 50 });
38 negativeTest('Variable redeclared', (TestHarness test) { 51 negativeTest('Variable redeclared',
52 matches("Variable '$varRegexp' declared more than once\\."),
53 (TestHarness test) {
39 VariableDeclaration variable = test.makeVariable(); 54 VariableDeclaration variable = test.makeVariable();
40 return new Block([variable, variable]); 55 return new Block([variable, variable]);
41 }); 56 });
42 negativeTest('Member redeclared', (TestHarness test) { 57 negativeTest('Member redeclared',
58 "Member 'test_lib::Test::field' has been declared more than once.",
59 (TestHarness test) {
43 Field field = new Field(new Name('field'), initializer: new NullLiteral()); 60 Field field = new Field(new Name('field'), initializer: new NullLiteral());
44 return new Class( 61 return new Class(
45 name: 'Test', 62 name: 'Test',
46 supertype: test.objectClass.asRawSupertype, 63 supertype: test.objectClass.asRawSupertype,
47 fields: [field, field]); 64 fields: [field, field]);
48 }); 65 });
49 negativeTest('Class redeclared', (TestHarness test) { 66 negativeTest('Class redeclared',
67 "Class 'test_lib::OtherClass' declared more than once.",
68 (TestHarness test) {
50 return test.otherClass; // Test harness also adds otherClass to program. 69 return test.otherClass; // Test harness also adds otherClass to program.
51 }); 70 });
52 negativeTest('Class type parameter redeclared', (TestHarness test) { 71 negativeTest('Class type parameter redeclared',
72 matches("Type parameter 'test_lib::Test::$tvarRegexp' redeclared\\."),
73 (TestHarness test) {
53 var parameter = test.makeTypeParameter(); 74 var parameter = test.makeTypeParameter();
54 return new Class( 75 return new Class(
55 name: 'Test', 76 name: 'Test',
56 supertype: test.objectClass.asRawSupertype, 77 supertype: test.objectClass.asRawSupertype,
57 typeParameters: [parameter, parameter]); 78 typeParameters: [parameter, parameter]);
58 }); 79 });
59 negativeTest('Member type parameter redeclared', (TestHarness test) { 80 negativeTest('Member type parameter redeclared',
81 matches("Type parameter '$tvarRegexp' redeclared\\."),
82 (TestHarness test) {
60 var parameter = test.makeTypeParameter(); 83 var parameter = test.makeTypeParameter();
61 return new Procedure( 84 return new Procedure(
62 new Name('bar'), 85 new Name('bar'),
63 ProcedureKind.Method, 86 ProcedureKind.Method,
64 new FunctionNode(new ReturnStatement(new NullLiteral()), 87 new FunctionNode(new ReturnStatement(new NullLiteral()),
65 typeParameters: [parameter, parameter])); 88 typeParameters: [parameter, parameter]));
66 }); 89 });
67 negativeTest('Type parameter out of scope', (TestHarness test) { 90 negativeTest(
91 'Type parameter out of scope',
92 matches("Type parameter '$tvarRegexp' referenced out of scope,"
93 " parent is: 'null'\\."), (TestHarness test) {
68 var parameter = test.makeTypeParameter(); 94 var parameter = test.makeTypeParameter();
69 return new ListLiteral([], typeArgument: new TypeParameterType(parameter)); 95 return new ListLiteral([], typeArgument: new TypeParameterType(parameter));
70 }); 96 });
71 negativeTest('Class type parameter from another class', (TestHarness test) { 97 negativeTest(
98 'Class type parameter from another class',
99 "Type parameter 'test_lib::OtherClass::OtherT' referenced out of scope,"
100 " parent is: 'test_lib::OtherClass'.", (TestHarness test) {
72 return new TypeLiteral( 101 return new TypeLiteral(
73 new TypeParameterType(test.otherClass.typeParameters[0])); 102 new TypeParameterType(test.otherClass.typeParameters[0]));
74 }); 103 });
75 negativeTest('Class type parameter in static method', (TestHarness test) { 104 negativeTest(
105 'Class type parameter in static method',
106 "Type parameter 'test_lib::TestClass::T' referenced from static context,"
107 " parent is 'test_lib::TestClass'.", (TestHarness test) {
76 return new Procedure( 108 return new Procedure(
77 new Name('bar'), 109 new Name('bar'),
78 ProcedureKind.Method, 110 ProcedureKind.Method,
79 new FunctionNode(new ReturnStatement( 111 new FunctionNode(new ReturnStatement(
80 new TypeLiteral(new TypeParameterType(test.classTypeParameter)))), 112 new TypeLiteral(new TypeParameterType(test.classTypeParameter)))),
81 isStatic: true); 113 isStatic: true);
82 }); 114 });
83 negativeTest('Class type parameter in static field', (TestHarness test) { 115 negativeTest(
116 'Class type parameter in static field',
117 "Type parameter 'test_lib::TestClass::T' referenced from static context,"
118 " parent is 'test_lib::TestClass'.", (TestHarness test) {
84 return new Field(new Name('field'), 119 return new Field(new Name('field'),
85 initializer: 120 initializer:
86 new TypeLiteral(new TypeParameterType(test.classTypeParameter)), 121 new TypeLiteral(new TypeParameterType(test.classTypeParameter)),
87 isStatic: true); 122 isStatic: true);
88 }); 123 });
89 negativeTest('Method type parameter out of scope', (TestHarness test) { 124 negativeTest(
125 'Method type parameter out of scope',
126 matches("Type parameter '$tvarRegexp' referenced out of scope,"
127 " parent is: '<FunctionNode>'\\."), (TestHarness test) {
90 var parameter = test.makeTypeParameter(); 128 var parameter = test.makeTypeParameter();
91 return new Class( 129 return new Class(
92 name: 'Test', 130 name: 'Test',
93 supertype: test.objectClass.asRawSupertype, 131 supertype: test.objectClass.asRawSupertype,
94 procedures: [ 132 procedures: [
95 new Procedure( 133 new Procedure(
96 new Name('generic'), 134 new Name('generic'),
97 ProcedureKind.Method, 135 ProcedureKind.Method,
98 new FunctionNode(new EmptyStatement(), 136 new FunctionNode(new EmptyStatement(),
99 typeParameters: [parameter])), 137 typeParameters: [parameter])),
100 new Procedure( 138 new Procedure(
101 new Name('use'), 139 new Name('use'),
102 ProcedureKind.Method, 140 ProcedureKind.Method,
103 new FunctionNode(new ReturnStatement( 141 new FunctionNode(new ReturnStatement(
104 new TypeLiteral(new TypeParameterType(parameter))))) 142 new TypeLiteral(new TypeParameterType(parameter)))))
105 ]); 143 ]);
106 }); 144 });
107 negativeTest('Interface type arity too low', (TestHarness test) { 145 negativeTest(
146 'Interface type arity too low',
147 "Type test_lib::OtherClass provides 0 type arguments"
148 " but the class declares 1 parameters.", (TestHarness test) {
108 return new TypeLiteral(new InterfaceType(test.otherClass, [])); 149 return new TypeLiteral(new InterfaceType(test.otherClass, []));
109 }); 150 });
110 negativeTest('Interface type arity too high', (TestHarness test) { 151 negativeTest(
152 'Interface type arity too high',
153 "Type test_lib::OtherClass<dynamic, dynamic> provides 2 type arguments"
154 " but the class declares 1 parameters.", (TestHarness test) {
111 return new TypeLiteral(new InterfaceType( 155 return new TypeLiteral(new InterfaceType(
112 test.otherClass, [new DynamicType(), new DynamicType()])); 156 test.otherClass, [new DynamicType(), new DynamicType()]));
113 }); 157 });
114 negativeTest('Dangling interface type', (TestHarness test) { 158 negativeTest(
159 'Dangling interface type',
160 matches("Dangling reference to 'null::#class[0-9]+',"
161 " parent is: 'null'\\."), (TestHarness test) {
115 var orphan = new Class(); 162 var orphan = new Class();
116 return new TypeLiteral(new InterfaceType(orphan)); 163 return new TypeLiteral(new InterfaceType(orphan));
117 }); 164 });
118 negativeTest('Dangling field get', (TestHarness test) { 165 negativeTest('Dangling field get',
166 "Dangling reference to 'null::foo', parent is: 'null'.",
167 (TestHarness test) {
119 var orphan = new Field(new Name('foo')); 168 var orphan = new Field(new Name('foo'));
120 return new DirectPropertyGet(new NullLiteral(), orphan); 169 return new DirectPropertyGet(new NullLiteral(), orphan);
121 }); 170 });
122 negativeTest('Missing block parent pointer', (TestHarness test) { 171 negativeTest(
172 'Missing block parent pointer',
173 "Incorrect parent pointer on ReturnStatement:"
174 " expected 'Block', but found: 'Null'.", (TestHarness test) {
123 var block = new Block([]); 175 var block = new Block([]);
124 block.statements.add(new ReturnStatement()); 176 block.statements.add(new ReturnStatement());
125 return block; 177 return block;
126 }); 178 });
127 negativeTest('Missing function parent pointer', (TestHarness test) { 179 negativeTest(
180 'Missing function parent pointer',
181 "Incorrect parent pointer on FunctionNode:"
182 " expected 'Procedure', but found: 'Null'.", (TestHarness test) {
128 var procedure = new Procedure(new Name('bar'), ProcedureKind.Method, null); 183 var procedure = new Procedure(new Name('bar'), ProcedureKind.Method, null);
129 procedure.function = new FunctionNode(new EmptyStatement()); 184 procedure.function = new FunctionNode(new EmptyStatement());
130 return procedure; 185 return procedure;
131 }); 186 });
132 negativeTest('StaticGet without target', (TestHarness test) { 187 negativeTest('StaticGet without target', "StaticGet without target.",
188 (TestHarness test) {
133 return new StaticGet(null); 189 return new StaticGet(null);
134 }); 190 });
135 negativeTest('StaticSet without target', (TestHarness test) { 191 negativeTest('StaticSet without target', "StaticSet without target.",
192 (TestHarness test) {
136 return new StaticSet(null, new NullLiteral()); 193 return new StaticSet(null, new NullLiteral());
137 }); 194 });
138 negativeTest('StaticInvocation without target', (TestHarness test) { 195 negativeTest(
196 'StaticInvocation without target', "StaticInvocation without target.",
197 (TestHarness test) {
139 return new StaticInvocation(null, new Arguments.empty()); 198 return new StaticInvocation(null, new Arguments.empty());
140 }); 199 });
141 positiveTest('Correct StaticInvocation', (TestHarness test) { 200 positiveTest('Correct StaticInvocation', (TestHarness test) {
142 var method = new Procedure( 201 var method = new Procedure(
143 new Name('foo'), 202 new Name('foo'),
144 ProcedureKind.Method, 203 ProcedureKind.Method,
145 new FunctionNode(new EmptyStatement(), 204 new FunctionNode(new EmptyStatement(),
146 positionalParameters: [new VariableDeclaration('p')]), 205 positionalParameters: [new VariableDeclaration('p')]),
147 isStatic: true); 206 isStatic: true);
148 test.enclosingClass.addMember(method); 207 test.enclosingClass.addMember(method);
149 return new StaticInvocation(method, new Arguments([new NullLiteral()])); 208 return new StaticInvocation(method, new Arguments([new NullLiteral()]));
150 }); 209 });
151 negativeTest('StaticInvocation with too many parameters', (TestHarness test) { 210 negativeTest(
211 'StaticInvocation with too many parameters',
212 "StaticInvocation with incompatible arguments for"
213 " 'test_lib::TestClass::bar'.", (TestHarness test) {
152 var method = new Procedure(new Name('bar'), ProcedureKind.Method, 214 var method = new Procedure(new Name('bar'), ProcedureKind.Method,
153 new FunctionNode(new EmptyStatement()), 215 new FunctionNode(new EmptyStatement()),
154 isStatic: true); 216 isStatic: true);
155 test.enclosingClass.addMember(method); 217 test.enclosingClass.addMember(method);
156 return new StaticInvocation(method, new Arguments([new NullLiteral()])); 218 return new StaticInvocation(method, new Arguments([new NullLiteral()]));
157 }); 219 });
158 negativeTest('StaticInvocation with too few parameters', (TestHarness test) { 220 negativeTest(
221 'StaticInvocation with too few parameters',
222 "StaticInvocation with incompatible arguments for"
223 " 'test_lib::TestClass::bar'.", (TestHarness test) {
159 var method = new Procedure( 224 var method = new Procedure(
160 new Name('bar'), 225 new Name('bar'),
161 ProcedureKind.Method, 226 ProcedureKind.Method,
162 new FunctionNode(new EmptyStatement(), 227 new FunctionNode(new EmptyStatement(),
163 positionalParameters: [new VariableDeclaration('p')]), 228 positionalParameters: [new VariableDeclaration('p')]),
164 isStatic: true); 229 isStatic: true);
165 test.enclosingClass.addMember(method); 230 test.enclosingClass.addMember(method);
166 return new StaticInvocation(method, new Arguments.empty()); 231 return new StaticInvocation(method, new Arguments.empty());
167 }); 232 });
168 negativeTest('StaticInvocation with unmatched named parameter', 233 negativeTest(
169 (TestHarness test) { 234 'StaticInvocation with unmatched named parameter',
235 "StaticInvocation with incompatible arguments for"
236 " 'test_lib::TestClass::bar'.", (TestHarness test) {
170 var method = new Procedure(new Name('bar'), ProcedureKind.Method, 237 var method = new Procedure(new Name('bar'), ProcedureKind.Method,
171 new FunctionNode(new EmptyStatement()), 238 new FunctionNode(new EmptyStatement()),
172 isStatic: true); 239 isStatic: true);
173 test.enclosingClass.addMember(method); 240 test.enclosingClass.addMember(method);
174 return new StaticInvocation( 241 return new StaticInvocation(
175 method, 242 method,
176 new Arguments([], 243 new Arguments([],
177 named: [new NamedExpression('p', new NullLiteral())])); 244 named: [new NamedExpression('p', new NullLiteral())]));
178 }); 245 });
179 negativeTest('StaticInvocation with missing type argument', 246 negativeTest(
180 (TestHarness test) { 247 'StaticInvocation with missing type argument',
248 "StaticInvocation with wrong number of type arguments for"
249 " 'test_lib::TestClass::bar'.", (TestHarness test) {
181 var method = new Procedure( 250 var method = new Procedure(
182 new Name('bar'), 251 new Name('bar'),
183 ProcedureKind.Method, 252 ProcedureKind.Method,
184 new FunctionNode(new EmptyStatement(), 253 new FunctionNode(new EmptyStatement(),
185 typeParameters: [test.makeTypeParameter()]), 254 typeParameters: [test.makeTypeParameter()]),
186 isStatic: true); 255 isStatic: true);
187 test.enclosingClass.addMember(method); 256 test.enclosingClass.addMember(method);
188 return new StaticInvocation(method, new Arguments.empty()); 257 return new StaticInvocation(method, new Arguments.empty());
189 }); 258 });
190 negativeTest('ConstructorInvocation with missing type argument', 259 negativeTest(
191 (TestHarness test) { 260 'ConstructorInvocation with missing type argument',
261 "ConstructorInvocation with wrong number of type arguments for"
262 " 'test_lib::TestClass::foo'.", (TestHarness test) {
192 var class_ = new Class( 263 var class_ = new Class(
193 name: 'Test', 264 name: 'Test',
194 typeParameters: [test.makeTypeParameter()], 265 typeParameters: [test.makeTypeParameter()],
195 supertype: test.objectClass.asRawSupertype); 266 supertype: test.objectClass.asRawSupertype);
196 test.enclosingLibrary.addClass(class_); 267 test.enclosingLibrary.addClass(class_);
197 var constructor = new Constructor(new FunctionNode(new EmptyStatement()), 268 var constructor = new Constructor(new FunctionNode(new EmptyStatement()),
198 name: new Name('foo')); 269 name: new Name('foo'));
199 test.enclosingClass.addMember(constructor); 270 test.enclosingClass.addMember(constructor);
200 return new ConstructorInvocation(constructor, new Arguments.empty()); 271 return new ConstructorInvocation(constructor, new Arguments.empty());
201 }); 272 });
(...skipping 19 matching lines...) Expand all
221 var foo = new Typedef('Foo', null); 292 var foo = new Typedef('Foo', null);
222 var bar = new Typedef('Bar', null); 293 var bar = new Typedef('Bar', null);
223 foo.type = new InterfaceType(test.otherClass, [new TypedefType(bar)]); 294 foo.type = new InterfaceType(test.otherClass, [new TypedefType(bar)]);
224 bar.type = test.otherClass.rawType; 295 bar.type = test.otherClass.rawType;
225 test.enclosingLibrary.addTypedef(foo); 296 test.enclosingLibrary.addTypedef(foo);
226 test.enclosingLibrary.addTypedef(bar); 297 test.enclosingLibrary.addTypedef(bar);
227 }); 298 });
228 positiveTest('Valid typedef type in field', (TestHarness test) { 299 positiveTest('Valid typedef type in field', (TestHarness test) {
229 var typedef_ = new Typedef( 300 var typedef_ = new Typedef(
230 'Foo', new FunctionType([test.otherClass.rawType], const VoidType())); 301 'Foo', new FunctionType([test.otherClass.rawType], const VoidType()));
231 var field = new Field(new Name('field'), type: new TypedefType(typedef_)); 302 var field = new Field(new Name('field'),
303 type: new TypedefType(typedef_), isStatic: true);
232 test.enclosingLibrary.addTypedef(typedef_); 304 test.enclosingLibrary.addTypedef(typedef_);
233 test.enclosingLibrary.addMember(field); 305 test.enclosingLibrary.addMember(field);
234 }); 306 });
235 negativeTest('Invalid typedef Foo = Foo', (TestHarness test) { 307 negativeTest(
308 'Invalid typedef Foo = Foo',
309 "The typedef 'typedef Foo = test_lib::Foo;\n'"
310 " refers to itself", (TestHarness test) {
236 var typedef_ = new Typedef('Foo', null); 311 var typedef_ = new Typedef('Foo', null);
237 typedef_.type = new TypedefType(typedef_); 312 typedef_.type = new TypedefType(typedef_);
238 test.enclosingLibrary.addTypedef(typedef_); 313 test.enclosingLibrary.addTypedef(typedef_);
239 }); 314 });
240 negativeTest('Invalid typedef Foo = `(Foo) => void`', (TestHarness test) { 315 negativeTest(
316 'Invalid typedef Foo = `(Foo) => void`',
317 "The typedef 'typedef Foo = (test_lib::Foo) → void;\n'"
318 " refers to itself", (TestHarness test) {
241 var typedef_ = new Typedef('Foo', null); 319 var typedef_ = new Typedef('Foo', null);
242 typedef_.type = 320 typedef_.type =
243 new FunctionType([new TypedefType(typedef_)], const VoidType()); 321 new FunctionType([new TypedefType(typedef_)], const VoidType());
244 test.enclosingLibrary.addTypedef(typedef_); 322 test.enclosingLibrary.addTypedef(typedef_);
245 }); 323 });
246 negativeTest('Invalid typedef Foo = `() => Foo`', (TestHarness test) { 324 negativeTest(
325 'Invalid typedef Foo = `() => Foo`',
326 "The typedef 'typedef Foo = () → test_lib::Foo;\n'"
327 " refers to itself", (TestHarness test) {
247 var typedef_ = new Typedef('Foo', null); 328 var typedef_ = new Typedef('Foo', null);
248 typedef_.type = new FunctionType([], new TypedefType(typedef_)); 329 typedef_.type = new FunctionType([], new TypedefType(typedef_));
249 test.enclosingLibrary.addTypedef(typedef_); 330 test.enclosingLibrary.addTypedef(typedef_);
250 }); 331 });
251 negativeTest('Invalid typedef Foo = C<Foo>', (TestHarness test) { 332 negativeTest(
333 'Invalid typedef Foo = C<Foo>',
334 "The typedef 'typedef Foo = test_lib::OtherClass<test_lib::Foo>;\n'"
335 " refers to itself", (TestHarness test) {
252 var typedef_ = new Typedef('Foo', null); 336 var typedef_ = new Typedef('Foo', null);
253 typedef_.type = 337 typedef_.type =
254 new InterfaceType(test.otherClass, [new TypedefType(typedef_)]); 338 new InterfaceType(test.otherClass, [new TypedefType(typedef_)]);
255 test.enclosingLibrary.addTypedef(typedef_); 339 test.enclosingLibrary.addTypedef(typedef_);
256 }); 340 });
257 negativeTest('Invalid typedefs Foo = Bar, Bar = Foo', (TestHarness test) { 341 negativeTest(
342 'Invalid typedefs Foo = Bar, Bar = Foo',
343 "The typedef 'typedef Foo = test_lib::Bar;\n'"
344 " refers to itself", (TestHarness test) {
258 var foo = new Typedef('Foo', null); 345 var foo = new Typedef('Foo', null);
259 var bar = new Typedef('Bar', null); 346 var bar = new Typedef('Bar', null);
260 foo.type = new TypedefType(bar); 347 foo.type = new TypedefType(bar);
261 bar.type = new TypedefType(foo); 348 bar.type = new TypedefType(foo);
262 test.enclosingLibrary.addTypedef(foo); 349 test.enclosingLibrary.addTypedef(foo);
263 test.enclosingLibrary.addTypedef(bar); 350 test.enclosingLibrary.addTypedef(bar);
264 }); 351 });
265 negativeTest('Invalid typedefs Foo = Bar, Bar = C<Foo>', (TestHarness test) { 352 negativeTest(
353 'Invalid typedefs Foo = Bar, Bar = C<Foo>',
354 "The typedef 'typedef Foo = test_lib::Bar;\n'"
355 " refers to itself", (TestHarness test) {
266 var foo = new Typedef('Foo', null); 356 var foo = new Typedef('Foo', null);
267 var bar = new Typedef('Bar', null); 357 var bar = new Typedef('Bar', null);
268 foo.type = new TypedefType(bar); 358 foo.type = new TypedefType(bar);
269 bar.type = new InterfaceType(test.otherClass, [new TypedefType(foo)]); 359 bar.type = new InterfaceType(test.otherClass, [new TypedefType(foo)]);
270 test.enclosingLibrary.addTypedef(foo); 360 test.enclosingLibrary.addTypedef(foo);
271 test.enclosingLibrary.addTypedef(bar); 361 test.enclosingLibrary.addTypedef(bar);
272 }); 362 });
273 negativeTest('Invalid typedefs Foo = C<Bar>, Bar = C<Foo>', 363 negativeTest(
274 (TestHarness test) { 364 'Invalid typedefs Foo = C<Bar>, Bar = C<Foo>',
365 "The typedef 'typedef Foo = test_lib::OtherClass<test_lib::Bar>;\n'"
366 " refers to itself", (TestHarness test) {
275 var foo = new Typedef('Foo', null); 367 var foo = new Typedef('Foo', null);
276 var bar = new Typedef('Bar', null); 368 var bar = new Typedef('Bar', null);
277 foo.type = new InterfaceType(test.otherClass, [new TypedefType(bar)]); 369 foo.type = new InterfaceType(test.otherClass, [new TypedefType(bar)]);
278 bar.type = new InterfaceType(test.otherClass, [new TypedefType(foo)]); 370 bar.type = new InterfaceType(test.otherClass, [new TypedefType(foo)]);
279 test.enclosingLibrary.addTypedef(foo); 371 test.enclosingLibrary.addTypedef(foo);
280 test.enclosingLibrary.addTypedef(bar); 372 test.enclosingLibrary.addTypedef(bar);
281 }); 373 });
282 positiveTest('Valid long typedefs C20 = C19 = ... = C1 = C0 = dynamic', 374 positiveTest('Valid long typedefs C20 = C19 = ... = C1 = C0 = dynamic',
283 (TestHarness test) { 375 (TestHarness test) {
284 var typedef_ = new Typedef('C0', const DynamicType()); 376 var typedef_ = new Typedef('C0', const DynamicType());
285 test.enclosingLibrary.addTypedef(typedef_); 377 test.enclosingLibrary.addTypedef(typedef_);
286 for (int i = 1; i < 20; ++i) { 378 for (int i = 1; i < 20; ++i) {
287 typedef_ = new Typedef('C$i', new TypedefType(typedef_)); 379 typedef_ = new Typedef('C$i', new TypedefType(typedef_));
288 test.enclosingLibrary.addTypedef(typedef_); 380 test.enclosingLibrary.addTypedef(typedef_);
289 } 381 }
290 }); 382 });
291 negativeTest('Invalid long typedefs C20 = C19 = ... = C1 = C0 = C20', 383 negativeTest(
292 (TestHarness test) { 384 'Invalid long typedefs C20 = C19 = ... = C1 = C0 = C20',
385 "The typedef 'typedef C0 = test_lib::C19;\n'"
386 " refers to itself", (TestHarness test) {
293 var typedef_ = new Typedef('C0', null); 387 var typedef_ = new Typedef('C0', null);
294 test.enclosingLibrary.addTypedef(typedef_); 388 test.enclosingLibrary.addTypedef(typedef_);
295 var first = typedef_; 389 var first = typedef_;
296 for (int i = 1; i < 20; ++i) { 390 for (int i = 1; i < 20; ++i) {
297 typedef_ = new Typedef('C$i', new TypedefType(typedef_)); 391 typedef_ = new Typedef('C$i', new TypedefType(typedef_));
298 test.enclosingLibrary.addTypedef(typedef_); 392 test.enclosingLibrary.addTypedef(typedef_);
299 } 393 }
300 first.type = new TypedefType(typedef_); 394 first.type = new TypedefType(typedef_);
301 }); 395 });
302 positiveTest('Valid typedef Foo<T extends C> = C<T>', (TestHarness test) { 396 positiveTest('Valid typedef Foo<T extends C> = C<T>', (TestHarness test) {
(...skipping 18 matching lines...) Expand all
321 var foo = 415 var foo =
322 new Typedef('Foo', const DynamicType(), typeParameters: [fooParam]); 416 new Typedef('Foo', const DynamicType(), typeParameters: [fooParam]);
323 var barParam = new TypeParameter('T', null); 417 var barParam = new TypeParameter('T', null);
324 barParam.bound = new TypedefType(foo, [new TypeParameterType(barParam)]); 418 barParam.bound = new TypedefType(foo, [new TypeParameterType(barParam)]);
325 var bar = new Typedef('Bar', 419 var bar = new Typedef('Bar',
326 new InterfaceType(test.otherClass, [new TypeParameterType(barParam)]), 420 new InterfaceType(test.otherClass, [new TypeParameterType(barParam)]),
327 typeParameters: [barParam]); 421 typeParameters: [barParam]);
328 test.enclosingLibrary.addTypedef(foo); 422 test.enclosingLibrary.addTypedef(foo);
329 test.enclosingLibrary.addTypedef(bar); 423 test.enclosingLibrary.addTypedef(bar);
330 }); 424 });
331 negativeTest('Invalid typedefs Foo<T extends Bar<T>>, Bar<T extends Foo<T>>', 425 negativeTest(
332 (TestHarness test) { 426 'Invalid typedefs Foo<T extends Bar<T>>, Bar<T extends Foo<T>>',
427 "The typedef 'typedef Foo<T extends test_lib::Bar<T>> = dynamic;\n'"
428 " refers to itself", (TestHarness test) {
333 var fooParam = test.makeTypeParameter('T'); 429 var fooParam = test.makeTypeParameter('T');
334 var foo = 430 var foo =
335 new Typedef('Foo', const DynamicType(), typeParameters: [fooParam]); 431 new Typedef('Foo', const DynamicType(), typeParameters: [fooParam]);
336 var barParam = new TypeParameter('T', null); 432 var barParam = new TypeParameter('T', null);
337 barParam.bound = new TypedefType(foo, [new TypeParameterType(barParam)]); 433 barParam.bound = new TypedefType(foo, [new TypeParameterType(barParam)]);
338 var bar = new Typedef('Bar', 434 var bar = new Typedef('Bar',
339 new InterfaceType(test.otherClass, [new TypeParameterType(barParam)]), 435 new InterfaceType(test.otherClass, [new TypeParameterType(barParam)]),
340 typeParameters: [barParam]); 436 typeParameters: [barParam]);
341 fooParam.bound = new TypedefType(bar, [new TypeParameterType(fooParam)]); 437 fooParam.bound = new TypedefType(bar, [new TypeParameterType(fooParam)]);
342 test.enclosingLibrary.addTypedef(foo); 438 test.enclosingLibrary.addTypedef(foo);
343 test.enclosingLibrary.addTypedef(bar); 439 test.enclosingLibrary.addTypedef(bar);
344 }); 440 });
345 negativeTest('Invalid typedef Foo<T extends Foo<dynamic> = C<T>', 441 negativeTest(
346 (TestHarness test) { 442 'Invalid typedef Foo<T extends Foo<dynamic> = C<T>',
443 "The typedef 'typedef Foo<T extends test_lib::Foo<dynamic>> = "
444 "test_lib::OtherClass<T>;\n'"
445 " refers to itself", (TestHarness test) {
347 var param = new TypeParameter('T', null); 446 var param = new TypeParameter('T', null);
348 var foo = new Typedef('Foo', 447 var foo = new Typedef('Foo',
349 new InterfaceType(test.otherClass, [new TypeParameterType(param)]), 448 new InterfaceType(test.otherClass, [new TypeParameterType(param)]),
350 typeParameters: [param]); 449 typeParameters: [param]);
351 param.bound = new TypedefType(foo, [const DynamicType()]); 450 param.bound = new TypedefType(foo, [const DynamicType()]);
352 test.enclosingLibrary.addTypedef(foo); 451 test.enclosingLibrary.addTypedef(foo);
353 }); 452 });
354 negativeTest('Typedef arity error', (TestHarness test) { 453 negativeTest(
454 'Typedef arity error',
455 "The typedef type test_lib::Foo provides 0 type arguments"
456 " but the typedef declares 1 parameters.", (TestHarness test) {
355 var param = test.makeTypeParameter('T'); 457 var param = test.makeTypeParameter('T');
356 var foo = 458 var foo =
357 new Typedef('Foo', test.otherClass.rawType, typeParameters: [param]); 459 new Typedef('Foo', test.otherClass.rawType, typeParameters: [param]);
358 var field = new Field(new Name('field'), type: new TypedefType(foo, [])); 460 var field = new Field(new Name('field'),
461 type: new TypedefType(foo, []), isStatic: true);
359 test.enclosingLibrary.addTypedef(foo); 462 test.enclosingLibrary.addTypedef(foo);
360 test.enclosingLibrary.addMember(field); 463 test.enclosingLibrary.addMember(field);
361 }); 464 });
362 negativeTest('Dangling typedef reference', (TestHarness test) { 465 negativeTest(
466 'Dangling typedef reference',
467 "Dangling reference to 'typedef Foo = test_lib::OtherClass<dynamic>;\n'"
468 ", parent is: 'null'", (TestHarness test) {
363 var foo = new Typedef('Foo', test.otherClass.rawType, typeParameters: []); 469 var foo = new Typedef('Foo', test.otherClass.rawType, typeParameters: []);
364 var field = new Field(new Name('field'), type: new TypedefType(foo, [])); 470 var field = new Field(new Name('field'),
471 type: new TypedefType(foo, []), isStatic: true);
472 test.enclosingLibrary.addMember(field);
473 });
474 negativeTest('Non-static top-level field',
475 "The top-level field 'field' should be static", (TestHarness test) {
476 var field = new Field(new Name('field'));
365 test.enclosingLibrary.addMember(field); 477 test.enclosingLibrary.addMember(field);
366 }); 478 });
367 } 479 }
368 480
369 checkHasError(Program program) { 481 checkHasError(Program program, Matcher matcher) {
370 bool passed = false;
371 try { 482 try {
372 verifyProgram(program); 483 verifyProgram(program);
373 passed = true; 484 } on VerificationError catch (e) {
374 } catch (e) {} 485 expect(e.details, matcher);
375 if (passed) { 486 return;
376 fail('Failed to reject invalid program:\n${programToString(program)}');
377 } 487 }
488 fail('Failed to reject invalid program:\n${programToString(program)}');
378 } 489 }
379 490
380 class TestHarness { 491 class TestHarness {
381 Program program; 492 Program program;
382 Class objectClass; 493 Class objectClass;
383 Library stubLibrary; 494 Library stubLibrary;
384 495
385 TypeParameter classTypeParameter; 496 TypeParameter classTypeParameter;
386 497
387 Library enclosingLibrary; 498 Library enclosingLibrary;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 new FunctionNode(new EmptyStatement())); 564 new FunctionNode(new EmptyStatement()));
454 enclosingClass.addMember(enclosingMember); 565 enclosingClass.addMember(enclosingMember);
455 otherClass = new Class( 566 otherClass = new Class(
456 name: 'OtherClass', 567 name: 'OtherClass',
457 typeParameters: [makeTypeParameter('OtherT')], 568 typeParameters: [makeTypeParameter('OtherT')],
458 supertype: objectClass.asRawSupertype); 569 supertype: objectClass.asRawSupertype);
459 enclosingLibrary.addClass(otherClass); 570 enclosingLibrary.addClass(otherClass);
460 } 571 }
461 } 572 }
462 573
463 negativeTest(String name, TreeNode makeTestCase(TestHarness test)) { 574 negativeTest(String name, matcher, TreeNode makeTestCase(TestHarness test)) {
575 if (matcher is String) {
576 matcher = equals(matcher);
577 }
464 test(name, () { 578 test(name, () {
465 var test = new TestHarness(); 579 var test = new TestHarness();
466 test.addNode(makeTestCase(test)); 580 test.addNode(makeTestCase(test));
467 checkHasError(test.program); 581 checkHasError(test.program, matcher);
468 }); 582 });
469 } 583 }
470 584
471 positiveTest(String name, TreeNode makeTestCase(TestHarness test)) { 585 positiveTest(String name, TreeNode makeTestCase(TestHarness test)) {
472 test(name, () { 586 test(name, () {
473 var test = new TestHarness(); 587 var test = new TestHarness();
474 test.addNode(makeTestCase(test)); 588 test.addNode(makeTestCase(test));
475 verifyProgram(test.program); 589 verifyProgram(test.program);
476 }); 590 });
477 } 591 }
OLDNEW
« no previous file with comments | « pkg/kernel/lib/verifier.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698