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

Side by Side Diff: pkg/kernel/lib/binary/ast_to_binary.dart

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: Address 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 library kernel.ast_to_binary; 4 library kernel.ast_to_binary;
5 5
6 import '../ast.dart'; 6 import '../ast.dart';
7 import '../import_table.dart'; 7 import '../import_table.dart';
8 import 'tag.dart'; 8 import 'tag.dart';
9 import 'dart:convert'; 9 import 'dart:convert';
10 import 'dart:typed_data'; 10 import 'dart:typed_data';
11 import 'dart:collection'; 11 import 'dart:collection';
12 12
13 /// Writes to a binary file. 13 /// Writes to a binary file.
14 /// 14 ///
15 /// A [BinaryPrinter] can be used to write one file and must then be 15 /// A [BinaryPrinter] can be used to write one file and must then be
16 /// discarded. 16 /// discarded.
17 class BinaryPrinter extends Visitor { 17 class BinaryPrinter extends Visitor {
18 ImportTable _importTable;
19
20 VariableIndexer _variableIndexer; 18 VariableIndexer _variableIndexer;
21 LabelIndexer _labelIndexer; 19 LabelIndexer _labelIndexer;
22 SwitchCaseIndexer _switchCaseIndexer; 20 SwitchCaseIndexer _switchCaseIndexer;
23 final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer(); 21 final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer();
24 final GlobalIndexer _globalIndexer;
25 final StringIndexer _stringIndexer = new StringIndexer(); 22 final StringIndexer _stringIndexer = new StringIndexer();
26 final StringIndexer _sourceUriIndexer = new StringIndexer(); 23 final StringIndexer _sourceUriIndexer = new StringIndexer();
27 24
28 final BufferedSink _sink; 25 final BufferedSink _sink;
29 26
30 /// Create a printer that writes to the given [sink]. 27 /// Create a printer that writes to the given [sink].
31 /// 28 ///
32 /// The BinaryPrinter will use its own buffer, so the [sink] does not need 29 /// The BinaryPrinter will use its own buffer, so the [sink] does not need
33 /// one. 30 /// one.
34 /// 31 ///
35 /// If multiple binaries are to be written based on the same IR, a shared 32 /// If multiple binaries are to be written based on the same IR, a shared
36 /// [globalIndexer] may be passed in to avoid rebuilding the same indices 33 /// [globalIndexer] may be passed in to avoid rebuilding the same indices
37 /// in every printer. 34 /// in every printer.
38 BinaryPrinter(Sink<List<int>> sink, {GlobalIndexer globalIndexer}) 35 BinaryPrinter(Sink<List<int>> sink) : _sink = new BufferedSink(sink);
39 : _sink = new BufferedSink(sink),
40 _globalIndexer = globalIndexer ?? new GlobalIndexer();
41 36
42 void _flush() { 37 void _flush() {
43 _sink.flushAndDestroy(); 38 _sink.flushAndDestroy();
44 } 39 }
45 40
46 void writeByte(int byte) { 41 void writeByte(int byte) {
47 _sink.addByte(byte); 42 _sink.addByte(byte);
48 } 43 }
49 44
50 void writeBytes(List<int> bytes) { 45 void writeBytes(List<int> bytes) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 if (node == null) { 120 if (node == null) {
126 writeByte(Tag.Nothing); 121 writeByte(Tag.Nothing);
127 } else { 122 } else {
128 writeByte(Tag.Something); 123 writeByte(Tag.Something);
129 writeClassReference(node.baseClass, allowNull: true); 124 writeClassReference(node.baseClass, allowNull: true);
130 writeByte(node.baseClassKind.index); 125 writeByte(node.baseClassKind.index);
131 writeByte(node.valueBits); 126 writeByte(node.valueBits);
132 } 127 }
133 } 128 }
134 129
130 void writeLinkTable(Program program) {
131 List<CanonicalName> list = <CanonicalName>[];
132 void visitCanonicalName(CanonicalName node) {
133 node.index = list.length;
134 list.add(node);
135 node.children.forEach(visitCanonicalName);
136 }
137
138 for (var library in program.libraries) {
139 visitCanonicalName(library.canonicalName);
140 }
141 writeList(list, writeCanonicalNameEntry);
142 }
143
144 void writeCanonicalNameEntry(CanonicalName node) {
145 var parent = node.parent;
146 if (parent.isRoot) {
147 writeByte(0);
148 } else {
149 writeUInt30(parent.index + 1);
150 }
151 writeStringReference(node.name);
152 }
153
135 void writeProgramFile(Program program) { 154 void writeProgramFile(Program program) {
136 writeMagicWord(Tag.ProgramFile); 155 writeMagicWord(Tag.ProgramFile);
137 _importTable = new ProgramImportTable(program); 156 _stringIndexer.scanProgram(program);
138 _stringIndexer.build(program);
139 writeStringTable(_stringIndexer); 157 writeStringTable(_stringIndexer);
140 writeUriToSource(program); 158 writeUriToSource(program);
159 writeLinkTable(program);
141 writeList(program.libraries, writeNode); 160 writeList(program.libraries, writeNode);
142 writeMemberReference(program.mainMethod, allowNull: true); 161 writeMemberReference(program.mainMethod, allowNull: true);
143 _flush(); 162 _flush();
144 } 163 }
145 164
146 void writeUriToSource(Program program) { 165 void writeUriToSource(Program program) {
147 program.uriToSource.keys.forEach((uri) { 166 program.uriToSource.keys.forEach((uri) {
148 _sourceUriIndexer.put(uri); 167 _sourceUriIndexer.put(uri);
149 }); 168 });
150 writeStringTable(_sourceUriIndexer); 169 writeStringTable(_sourceUriIndexer);
151 for (int i = 0; i < _sourceUriIndexer.entries.length; i++) { 170 for (int i = 0; i < _sourceUriIndexer.entries.length; i++) {
152 String uri = _sourceUriIndexer.entries[i].value; 171 String uri = _sourceUriIndexer.entries[i].value;
153 Source source = program.uriToSource[uri] ?? new Source([], ''); 172 Source source = program.uriToSource[uri] ?? new Source([], '');
154 String sourceCode = source.source; 173 String sourceCode = source.source;
155 writeStringTableEntry(sourceCode); 174 writeStringTableEntry(sourceCode);
156 List<int> lineStarts = source.lineStarts; 175 List<int> lineStarts = source.lineStarts;
157 writeUInt30(lineStarts.length); 176 writeUInt30(lineStarts.length);
158 int previousLineStart = 0; 177 int previousLineStart = 0;
159 lineStarts.forEach((lineStart) { 178 lineStarts.forEach((lineStart) {
160 writeUInt30(lineStart - previousLineStart); 179 writeUInt30(lineStart - previousLineStart);
161 previousLineStart = lineStart; 180 previousLineStart = lineStart;
162 }); 181 });
163 } 182 }
164 } 183 }
165 184
166 void writeLibraryImportTable(LibraryImportTable imports) { 185 void writeCanonicalNameReference(CanonicalName name) {
167 writeList(imports.importPaths, writeStringReference); 186 if (name == null) {
187 writeByte(0);
188 } else {
189 writeUInt30(name.index + 1);
190 }
168 } 191 }
169 192
170 void writeLibraryReference(Library node) { 193 void writeLibraryReference(Library node) {
171 int index = _importTable.getImportIndex(node); 194 writeCanonicalNameReference(node.canonicalName);
172 if (index == -1) {
173 throw 'Missing import for library: ${node.importUri}';
174 }
175 writeUInt30(index);
176 }
177
178 void writeClassIndex(Class node) {
179 writeUInt30(_globalIndexer[node]);
180 }
181
182 void writeClassReference(Class node, {bool allowNull: false}) {
183 if (node == null) {
184 if (allowNull) {
185 writeByte(Tag.NullReference);
186 } else {
187 throw 'Expected a class reference to be valid but was `null`.';
188 }
189 } else {
190 node.acceptReference(this);
191 }
192 }
193
194 void writeMemberReference(Member node, {bool allowNull: false}) {
195 if (node == null) {
196 if (allowNull) {
197 writeByte(Tag.NullReference);
198 } else {
199 throw 'Expected a member reference to be valid but was `null`.';
200 }
201 } else {
202 node.acceptReference(this);
203 }
204 } 195 }
205 196
206 writeOffset(TreeNode node, int offset) { 197 writeOffset(TreeNode node, int offset) {
207 // TODO(jensj): Delta-encoding. 198 // TODO(jensj): Delta-encoding.
208 // File offset ranges from -1 and up, 199 // File offset ranges from -1 and up,
209 // but is here saved as unsigned (thus the +1) 200 // but is here saved as unsigned (thus the +1)
210 writeUInt30(offset + 1); 201 writeUInt30(offset + 1);
211 } 202 }
212 203
213 void visitClassReference(Class node) { 204 void writeClassReference(Class class_, {bool allowNull: false}) {
214 var library = node.enclosingLibrary; 205 if (class_ == null && !allowNull) {
215 writeByte(node.isMixinApplication 206 throw 'Expected a class reference to be valid but was `null`.';
216 ? Tag.MixinClassReference 207 }
217 : Tag.NormalClassReference); 208 writeCanonicalNameReference(getCanonicalNameOfClass(class_));
218 writeLibraryReference(library);
219 writeClassIndex(node);
220 } 209 }
221 210
222 void visitFieldReference(Field node) { 211 void writeMemberReference(Member member, {bool allowNull: false}) {
223 if (node.enclosingClass != null) { 212 if (member == null && !allowNull) {
224 writeByte(Tag.ClassFieldReference); 213 throw 'Expected a member reference to be valid but was `null`.';
225 Class classNode = node.enclosingClass;
226 writeClassReference(classNode);
227 writeUInt30(_globalIndexer[node]);
228 } else {
229 writeByte(Tag.LibraryFieldReference);
230 writeLibraryReference(node.enclosingLibrary);
231 writeUInt30(_globalIndexer[node]);
232 } 214 }
233 } 215 writeCanonicalNameReference(getCanonicalNameOfMember(member));
234
235 void visitConstructorReference(Constructor node) {
236 writeByte(Tag.ClassConstructorReference);
237 writeClassReference(node.enclosingClass);
238 writeUInt30(_globalIndexer[node]);
239 }
240
241 void visitProcedureReference(Procedure node) {
242 if (node.enclosingClass != null) {
243 writeByte(Tag.ClassProcedureReference);
244 Class classNode = node.enclosingClass;
245 writeClassReference(classNode);
246 writeUInt30(_globalIndexer[node]);
247 } else {
248 writeByte(Tag.LibraryProcedureReference);
249 writeLibraryReference(node.enclosingLibrary);
250 writeUInt30(_globalIndexer[node]);
251 }
252 } 216 }
253 217
254 void writeName(Name node) { 218 void writeName(Name node) {
255 writeStringReference(node.name); 219 writeStringReference(node.name);
256 // TODO: Consider a more compressed format for private names within the 220 // TODO: Consider a more compressed format for private names within the
257 // enclosing library. 221 // enclosing library.
258 if (node.isPrivate) { 222 if (node.isPrivate) {
259 writeLibraryReference(node.library); 223 writeLibraryReference(node.library);
260 } 224 }
261 } 225 }
262 226
263 bool insideExternalLibrary = false; 227 bool insideExternalLibrary = false;
264 228
265 visitLibrary(Library node) { 229 visitLibrary(Library node) {
266 insideExternalLibrary = node.isExternal; 230 insideExternalLibrary = node.isExternal;
267 writeByte(insideExternalLibrary ? 1 : 0); 231 writeByte(insideExternalLibrary ? 1 : 0);
232 writeCanonicalNameReference(getCanonicalNameOfLibrary(node));
268 writeStringReference(node.name ?? ''); 233 writeStringReference(node.name ?? '');
269 writeStringReference('${node.importUri}');
270 // TODO(jensj): We save (almost) the same URI twice. 234 // TODO(jensj): We save (almost) the same URI twice.
271 writeUriReference(node.fileUri ?? ''); 235 writeUriReference(node.fileUri ?? '');
272 writeNodeList(node.classes); 236 writeNodeList(node.classes);
273 writeNodeList(node.fields); 237 writeNodeList(node.fields);
274 writeNodeList(node.procedures); 238 writeNodeList(node.procedures);
275 } 239 }
276 240
277 void writeAnnotation(Expression annotation) { 241 void writeAnnotation(Expression annotation) {
278 _variableIndexer ??= new VariableIndexer(); 242 _variableIndexer ??= new VariableIndexer();
279 writeNode(annotation); 243 writeNode(annotation);
280 } 244 }
281 245
282 void writeAnnotationList(List<Expression> annotations) { 246 void writeAnnotationList(List<Expression> annotations) {
283 writeList(annotations, writeAnnotation); 247 writeList(annotations, writeAnnotation);
284 } 248 }
285 249
286 visitClass(Class node) { 250 visitClass(Class node) {
287 int flags = node.isAbstract ? 1 : 0; 251 int flags = node.isAbstract ? 1 : 0;
288 if (node.level == ClassLevel.Type) { 252 if (node.level == ClassLevel.Type) {
289 flags |= 0x2; 253 flags |= 0x2;
290 } 254 }
291 if (node.isMixinApplication) { 255 if (node.canonicalName == null) {
292 writeByte(Tag.MixinClass); 256 throw 'Missing canonical name for $node';
293 writeOffset(node, node.fileOffset);
294 writeByte(flags);
295 writeStringReference(node.name ?? '');
296 writeUriReference(node.fileUri ?? '');
297 writeAnnotationList(node.annotations);
298 _typeParameterIndexer.enter(node.typeParameters);
299 writeNodeList(node.typeParameters);
300 writeNode(node.supertype);
301 writeNode(node.mixedInType);
302 writeNodeList(node.implementedTypes);
303 writeNodeList(node.constructors);
304 _typeParameterIndexer.exit(node.typeParameters);
305 } else {
306 writeByte(Tag.NormalClass);
307 writeOffset(node, node.fileOffset);
308 writeByte(flags);
309 writeStringReference(node.name ?? '');
310 writeUriReference(node.fileUri ?? '');
311 writeAnnotationList(node.annotations);
312 _typeParameterIndexer.enter(node.typeParameters);
313 writeNodeList(node.typeParameters);
314 writeOptionalNode(node.supertype);
315 writeNodeList(node.implementedTypes);
316 writeNodeList(node.fields);
317 writeNodeList(node.constructors);
318 writeNodeList(node.procedures);
319 _typeParameterIndexer.exit(node.typeParameters);
320 } 257 }
258 writeByte(Tag.Class);
259 writeCanonicalNameReference(getCanonicalNameOfClass(node));
260 writeOffset(node, node.fileOffset);
261 writeByte(flags);
262 writeStringReference(node.name ?? '');
263 writeUriReference(node.fileUri ?? '');
264 writeAnnotationList(node.annotations);
265 _typeParameterIndexer.enter(node.typeParameters);
266 writeNodeList(node.typeParameters);
267 writeOptionalNode(node.supertype);
268 writeOptionalNode(node.mixedInType);
269 writeNodeList(node.implementedTypes);
270 writeNodeList(node.fields);
271 writeNodeList(node.constructors);
272 writeNodeList(node.procedures);
273 _typeParameterIndexer.exit(node.typeParameters);
321 } 274 }
322 275
323 static final Name _emptyName = new Name(''); 276 static final Name _emptyName = new Name('');
324 277
325 visitConstructor(Constructor node) { 278 visitConstructor(Constructor node) {
279 if (node.canonicalName == null) {
280 throw 'Missing canonical name for $node';
281 }
326 _variableIndexer = new VariableIndexer(); 282 _variableIndexer = new VariableIndexer();
327 writeByte(Tag.Constructor); 283 writeByte(Tag.Constructor);
284 writeCanonicalNameReference(getCanonicalNameOfMember(node));
328 writeOffset(node, node.fileOffset); 285 writeOffset(node, node.fileOffset);
329 writeOffset(node, node.fileEndOffset); 286 writeOffset(node, node.fileEndOffset);
330 writeByte(node.flags); 287 writeByte(node.flags);
331 writeName(node.name ?? _emptyName); 288 writeName(node.name ?? _emptyName);
332 writeAnnotationList(node.annotations); 289 writeAnnotationList(node.annotations);
333 assert(node.function.typeParameters.isEmpty); 290 assert(node.function.typeParameters.isEmpty);
334 writeNode(node.function); 291 writeNode(node.function);
335 // Parameters are in scope in the initializers. 292 // Parameters are in scope in the initializers.
336 _variableIndexer.restoreScope(node.function.positionalParameters.length + 293 _variableIndexer.restoreScope(node.function.positionalParameters.length +
337 node.function.namedParameters.length); 294 node.function.namedParameters.length);
338 writeNodeList(node.initializers); 295 writeNodeList(node.initializers);
339 _variableIndexer = null; 296 _variableIndexer = null;
340 } 297 }
341 298
342 visitProcedure(Procedure node) { 299 visitProcedure(Procedure node) {
300 if (node.canonicalName == null) {
301 throw 'Missing canonical name for $node';
302 }
343 _variableIndexer = new VariableIndexer(); 303 _variableIndexer = new VariableIndexer();
344 writeByte(Tag.Procedure); 304 writeByte(Tag.Procedure);
305 writeCanonicalNameReference(getCanonicalNameOfMember(node));
345 writeOffset(node, node.fileOffset); 306 writeOffset(node, node.fileOffset);
346 writeOffset(node, node.fileEndOffset); 307 writeOffset(node, node.fileEndOffset);
347 writeByte(node.kind.index); 308 writeByte(node.kind.index);
348 writeByte(node.flags); 309 writeByte(node.flags);
349 writeName(node.name ?? ''); 310 writeName(node.name ?? '');
350 writeUriReference(node.fileUri ?? ''); 311 writeUriReference(node.fileUri ?? '');
351 writeAnnotationList(node.annotations); 312 writeAnnotationList(node.annotations);
352 writeOptionalNode(node.function); 313 writeOptionalNode(node.function);
353 _variableIndexer = null; 314 _variableIndexer = null;
354 } 315 }
355 316
356 visitField(Field node) { 317 visitField(Field node) {
318 if (node.canonicalName == null) {
319 throw 'Missing canonical name for $node';
320 }
357 _variableIndexer = new VariableIndexer(); 321 _variableIndexer = new VariableIndexer();
358 writeByte(Tag.Field); 322 writeByte(Tag.Field);
323 writeCanonicalNameReference(getCanonicalNameOfMember(node));
359 writeOffset(node, node.fileOffset); 324 writeOffset(node, node.fileOffset);
360 writeOffset(node, node.fileEndOffset); 325 writeOffset(node, node.fileEndOffset);
361 writeByte(node.flags); 326 writeByte(node.flags);
362 writeName(node.name ?? ''); 327 writeName(node.name ?? '');
363 writeUriReference(node.fileUri ?? ''); 328 writeUriReference(node.fileUri ?? '');
364 writeAnnotationList(node.annotations); 329 writeAnnotationList(node.annotations);
365 writeNode(node.type); 330 writeNode(node.type);
366 writeOptionalInferredValue(node.inferredValue); 331 writeOptionalInferredValue(node.inferredValue);
367 writeOptionalNode(node.initializer); 332 writeOptionalNode(node.initializer);
368 _variableIndexer = null; 333 _variableIndexer = null;
369 } 334 }
370 335
371 visitInvalidInitializer(InvalidInitializer node) { 336 visitInvalidInitializer(InvalidInitializer node) {
372 writeByte(Tag.InvalidInitializer); 337 writeByte(Tag.InvalidInitializer);
373 } 338 }
374 339
375 visitFieldInitializer(FieldInitializer node) { 340 visitFieldInitializer(FieldInitializer node) {
376 writeByte(Tag.FieldInitializer); 341 writeByte(Tag.FieldInitializer);
377 writeMemberReference(node.field); 342 writeCanonicalNameReference(node.fieldName);
378 writeNode(node.value); 343 writeNode(node.value);
379 } 344 }
380 345
381 visitSuperInitializer(SuperInitializer node) { 346 visitSuperInitializer(SuperInitializer node) {
382 writeByte(Tag.SuperInitializer); 347 writeByte(Tag.SuperInitializer);
383 writeMemberReference(node.target); 348 writeCanonicalNameReference(node.targetName);
384 writeNode(node.arguments); 349 writeNode(node.arguments);
385 } 350 }
386 351
387 visitRedirectingInitializer(RedirectingInitializer node) { 352 visitRedirectingInitializer(RedirectingInitializer node) {
388 writeByte(Tag.RedirectingInitializer); 353 writeByte(Tag.RedirectingInitializer);
389 writeMemberReference(node.target); 354 writeCanonicalNameReference(node.targetName);
390 writeNode(node.arguments); 355 writeNode(node.arguments);
391 } 356 }
392 357
393 visitLocalInitializer(LocalInitializer node) { 358 visitLocalInitializer(LocalInitializer node) {
394 writeByte(Tag.LocalInitializer); 359 writeByte(Tag.LocalInitializer);
395 writeVariableDeclaration(node.variable); 360 writeVariableDeclaration(node.variable);
396 } 361 }
397 362
398 visitFunctionNode(FunctionNode node) { 363 visitFunctionNode(FunctionNode node) {
399 assert(_variableIndexer != null); 364 assert(_variableIndexer != null);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 writeUInt30(_variableIndexer[node.variable]); 419 writeUInt30(_variableIndexer[node.variable]);
455 writeNode(node.value); 420 writeNode(node.value);
456 } 421 }
457 } 422 }
458 423
459 visitPropertyGet(PropertyGet node) { 424 visitPropertyGet(PropertyGet node) {
460 writeByte(Tag.PropertyGet); 425 writeByte(Tag.PropertyGet);
461 writeOffset(node, node.fileOffset); 426 writeOffset(node, node.fileOffset);
462 writeNode(node.receiver); 427 writeNode(node.receiver);
463 writeName(node.name); 428 writeName(node.name);
464 writeMemberReference(node.interfaceTarget, allowNull: true); 429 writeCanonicalNameReference(node.interfaceTargetName);
465 } 430 }
466 431
467 visitPropertySet(PropertySet node) { 432 visitPropertySet(PropertySet node) {
468 writeByte(Tag.PropertySet); 433 writeByte(Tag.PropertySet);
469 writeOffset(node, node.fileOffset); 434 writeOffset(node, node.fileOffset);
470 writeNode(node.receiver); 435 writeNode(node.receiver);
471 writeName(node.name); 436 writeName(node.name);
472 writeNode(node.value); 437 writeNode(node.value);
473 writeMemberReference(node.interfaceTarget, allowNull: true); 438 writeCanonicalNameReference(node.interfaceTargetName);
474 } 439 }
475 440
476 visitSuperPropertyGet(SuperPropertyGet node) { 441 visitSuperPropertyGet(SuperPropertyGet node) {
477 writeByte(Tag.SuperPropertyGet); 442 writeByte(Tag.SuperPropertyGet);
478 writeName(node.name); 443 writeName(node.name);
479 writeMemberReference(node.interfaceTarget, allowNull: true); 444 writeCanonicalNameReference(node.interfaceTargetName);
480 } 445 }
481 446
482 visitSuperPropertySet(SuperPropertySet node) { 447 visitSuperPropertySet(SuperPropertySet node) {
483 writeByte(Tag.SuperPropertySet); 448 writeByte(Tag.SuperPropertySet);
484 writeName(node.name); 449 writeName(node.name);
485 writeNode(node.value); 450 writeNode(node.value);
486 writeMemberReference(node.interfaceTarget, allowNull: true); 451 writeCanonicalNameReference(node.interfaceTargetName);
487 } 452 }
488 453
489 visitDirectPropertyGet(DirectPropertyGet node) { 454 visitDirectPropertyGet(DirectPropertyGet node) {
490 writeByte(Tag.DirectPropertyGet); 455 writeByte(Tag.DirectPropertyGet);
491 writeNode(node.receiver); 456 writeNode(node.receiver);
492 writeMemberReference(node.target); 457 writeCanonicalNameReference(node.targetName);
493 } 458 }
494 459
495 visitDirectPropertySet(DirectPropertySet node) { 460 visitDirectPropertySet(DirectPropertySet node) {
496 writeByte(Tag.DirectPropertySet); 461 writeByte(Tag.DirectPropertySet);
497 writeNode(node.receiver); 462 writeNode(node.receiver);
498 writeMemberReference(node.target); 463 writeCanonicalNameReference(node.targetName);
499 writeNode(node.value); 464 writeNode(node.value);
500 } 465 }
501 466
502 visitStaticGet(StaticGet node) { 467 visitStaticGet(StaticGet node) {
503 writeByte(Tag.StaticGet); 468 writeByte(Tag.StaticGet);
504 writeOffset(node, node.fileOffset); 469 writeOffset(node, node.fileOffset);
505 writeMemberReference(node.target); 470 writeCanonicalNameReference(node.targetName);
506 } 471 }
507 472
508 visitStaticSet(StaticSet node) { 473 visitStaticSet(StaticSet node) {
509 writeByte(Tag.StaticSet); 474 writeByte(Tag.StaticSet);
510 writeMemberReference(node.target); 475 writeCanonicalNameReference(node.targetName);
511 writeNode(node.value); 476 writeNode(node.value);
512 } 477 }
513 478
514 visitMethodInvocation(MethodInvocation node) { 479 visitMethodInvocation(MethodInvocation node) {
515 writeByte(Tag.MethodInvocation); 480 writeByte(Tag.MethodInvocation);
516 writeOffset(node, node.fileOffset); 481 writeOffset(node, node.fileOffset);
517 writeNode(node.receiver); 482 writeNode(node.receiver);
518 writeName(node.name); 483 writeName(node.name);
519 writeNode(node.arguments); 484 writeNode(node.arguments);
520 writeMemberReference(node.interfaceTarget, allowNull: true); 485 writeCanonicalNameReference(node.interfaceTargetName);
521 } 486 }
522 487
523 visitSuperMethodInvocation(SuperMethodInvocation node) { 488 visitSuperMethodInvocation(SuperMethodInvocation node) {
524 writeByte(Tag.SuperMethodInvocation); 489 writeByte(Tag.SuperMethodInvocation);
525 writeOffset(node, node.fileOffset); 490 writeOffset(node, node.fileOffset);
526 writeName(node.name); 491 writeName(node.name);
527 writeNode(node.arguments); 492 writeNode(node.arguments);
528 writeMemberReference(node.interfaceTarget, allowNull: true); 493 writeCanonicalNameReference(node.interfaceTargetName);
529 } 494 }
530 495
531 visitDirectMethodInvocation(DirectMethodInvocation node) { 496 visitDirectMethodInvocation(DirectMethodInvocation node) {
532 writeByte(Tag.DirectMethodInvocation); 497 writeByte(Tag.DirectMethodInvocation);
533 writeNode(node.receiver); 498 writeNode(node.receiver);
534 writeMemberReference(node.target); 499 writeCanonicalNameReference(node.targetName);
535 writeNode(node.arguments); 500 writeNode(node.arguments);
536 } 501 }
537 502
538 visitStaticInvocation(StaticInvocation node) { 503 visitStaticInvocation(StaticInvocation node) {
539 writeByte(node.isConst ? Tag.ConstStaticInvocation : Tag.StaticInvocation); 504 writeByte(node.isConst ? Tag.ConstStaticInvocation : Tag.StaticInvocation);
540 writeOffset(node, node.fileOffset); 505 writeOffset(node, node.fileOffset);
541 writeMemberReference(node.target); 506 writeCanonicalNameReference(node.targetName);
542 writeNode(node.arguments); 507 writeNode(node.arguments);
543 } 508 }
544 509
545 visitConstructorInvocation(ConstructorInvocation node) { 510 visitConstructorInvocation(ConstructorInvocation node) {
546 writeByte(node.isConst 511 writeByte(node.isConst
547 ? Tag.ConstConstructorInvocation 512 ? Tag.ConstConstructorInvocation
548 : Tag.ConstructorInvocation); 513 : Tag.ConstructorInvocation);
549 writeOffset(node, node.fileOffset); 514 writeOffset(node, node.fileOffset);
550 writeMemberReference(node.target); 515 writeCanonicalNameReference(node.targetName);
551 writeNode(node.arguments); 516 writeNode(node.arguments);
552 } 517 }
553 518
554 visitArguments(Arguments node) { 519 visitArguments(Arguments node) {
555 writeNodeList(node.types); 520 writeNodeList(node.types);
556 writeNodeList(node.positional); 521 writeNodeList(node.positional);
557 writeNodeList(node.named); 522 writeNodeList(node.named);
558 } 523 }
559 524
560 visitNamedExpression(NamedExpression node) { 525 visitNamedExpression(NamedExpression node) {
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 writeByte(Tag.DynamicType); 865 writeByte(Tag.DynamicType);
901 } 866 }
902 867
903 visitVoidType(VoidType node) { 868 visitVoidType(VoidType node) {
904 writeByte(Tag.VoidType); 869 writeByte(Tag.VoidType);
905 } 870 }
906 871
907 visitInterfaceType(InterfaceType node) { 872 visitInterfaceType(InterfaceType node) {
908 if (node.typeArguments.isEmpty) { 873 if (node.typeArguments.isEmpty) {
909 writeByte(Tag.SimpleInterfaceType); 874 writeByte(Tag.SimpleInterfaceType);
910 writeClassReference(node.classNode); 875 writeCanonicalNameReference(node.className);
911 } else { 876 } else {
912 writeByte(Tag.InterfaceType); 877 writeByte(Tag.InterfaceType);
913 writeClassReference(node.classNode); 878 writeCanonicalNameReference(node.className);
914 writeNodeList(node.typeArguments); 879 writeNodeList(node.typeArguments);
915 } 880 }
916 } 881 }
917 882
918 visitSupertype(Supertype node) { 883 visitSupertype(Supertype node) {
919 if (node.typeArguments.isEmpty) { 884 if (node.typeArguments.isEmpty) {
920 writeByte(Tag.SimpleInterfaceType); 885 writeByte(Tag.SimpleInterfaceType);
921 writeClassReference(node.classNode); 886 writeCanonicalNameReference(node.className);
922 } else { 887 } else {
923 writeByte(Tag.InterfaceType); 888 writeByte(Tag.InterfaceType);
924 writeClassReference(node.classNode); 889 writeCanonicalNameReference(node.className);
925 writeNodeList(node.typeArguments); 890 writeNodeList(node.typeArguments);
926 } 891 }
927 } 892 }
928 893
929 visitFunctionType(FunctionType node) { 894 visitFunctionType(FunctionType node) {
930 if (node.requiredParameterCount == node.positionalParameters.length && 895 if (node.requiredParameterCount == node.positionalParameters.length &&
931 node.typeParameters.isEmpty && 896 node.typeParameters.isEmpty &&
932 node.namedParameters.isEmpty) { 897 node.namedParameters.isEmpty) {
933 writeByte(Tag.SimpleFunctionType); 898 writeByte(Tag.SimpleFunctionType);
934 writeNodeList(node.positionalParameters); 899 writeNodeList(node.positionalParameters);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 class StringIndexer extends RecursiveVisitor<Null> { 1018 class StringIndexer extends RecursiveVisitor<Null> {
1054 final List<StringTableEntry> entries = <StringTableEntry>[]; 1019 final List<StringTableEntry> entries = <StringTableEntry>[];
1055 final LinkedHashMap<String, int> index = new LinkedHashMap<String, int>(); 1020 final LinkedHashMap<String, int> index = new LinkedHashMap<String, int>();
1056 1021
1057 StringIndexer() { 1022 StringIndexer() {
1058 put(''); 1023 put('');
1059 } 1024 }
1060 1025
1061 int get numberOfStrings => index.length; 1026 int get numberOfStrings => index.length;
1062 1027
1063 void build(Node node) { 1028 void scanProgram(Node node) {
1064 node.accept(this); 1029 node.accept(this);
1065 entries.sort(); 1030 entries.sort();
1066 for (int i = 0; i < entries.length; ++i) { 1031 for (int i = 0; i < entries.length; ++i) {
1067 index[entries[i].value] = i; 1032 index[entries[i].value] = i;
1068 } 1033 }
1069 } 1034 }
1070 1035
1036 void visitCanonicalName(CanonicalName name) {
1037 put(name.name);
1038 name.children.forEach(visitCanonicalName);
1039 }
1040
1071 void put(String string) { 1041 void put(String string) {
1072 int i = index.putIfAbsent(string, () { 1042 int i = index.putIfAbsent(string, () {
1073 entries.add(new StringTableEntry(string)); 1043 entries.add(new StringTableEntry(string));
1074 return index.length; 1044 return index.length;
1075 }); 1045 });
1076 ++entries[i].frequency; 1046 ++entries[i].frequency;
1077 } 1047 }
1078 1048
1079 void putOptional(String string) { 1049 void putOptional(String string) {
1080 if (string != null) { 1050 if (string != null) {
1081 put(string); 1051 put(string);
1082 } 1052 }
1083 } 1053 }
1084 1054
1085 int operator [](String string) => index[string]; 1055 int operator [](String string) => index[string];
1086 1056
1087 void addLibraryImports(LibraryImportTable imports) { 1057 void addLibraryImports(LibraryImportTable imports) {
1088 imports.importPaths.forEach(put); 1058 imports.importPaths.forEach(put);
1089 } 1059 }
1090 1060
1091 visitName(Name node) { 1061 visitName(Name node) {
1092 put(node.name); 1062 put(node.name);
1093 } 1063 }
1094 1064
1095 visitLibrary(Library node) { 1065 visitLibrary(Library node) {
1066 visitCanonicalName(node.canonicalName);
1096 putOptional(node.name); 1067 putOptional(node.name);
1097 put('${node.importUri}'); 1068 put('${node.importUri}');
1098 node.visitChildren(this); 1069 node.visitChildren(this);
1099 } 1070 }
1100 1071
1101 visitClass(Class node) { 1072 visitClass(Class node) {
1102 putOptional(node.name); 1073 putOptional(node.name);
1103 node.visitChildren(this); 1074 node.visitChildren(this);
1104 } 1075 }
1105 1076
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 void flush() { 1212 void flush() {
1242 _sink.add(_buffer.sublist(0, length)); 1213 _sink.add(_buffer.sublist(0, length));
1243 _buffer = new Uint8List(SIZE); 1214 _buffer = new Uint8List(SIZE);
1244 length = 0; 1215 length = 0;
1245 } 1216 }
1246 1217
1247 void flushAndDestroy() { 1218 void flushAndDestroy() {
1248 _sink.add(_buffer.sublist(0, length)); 1219 _sink.add(_buffer.sublist(0, length));
1249 } 1220 }
1250 } 1221 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698