OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 |
5 library trydart.poi; | 5 library trydart.poi; |
6 | 6 |
7 import 'dart:async' show | 7 import 'dart:async' show |
8 Completer, | 8 Completer, |
9 Future, | 9 Future, |
10 Stream; | 10 Stream; |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 | 302 |
303 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) => true; | 303 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) => true; |
304 | 304 |
305 void processWorkItem(void f(WorkItem work), WorkItem work) { | 305 void processWorkItem(void f(WorkItem work), WorkItem work) { |
306 if (work.element.library.canonicalUri == script) { | 306 if (work.element.library.canonicalUri == script) { |
307 f(work); | 307 f(work); |
308 } | 308 } |
309 } | 309 } |
310 } | 310 } |
311 | 311 |
312 class ScopeInformationVisitor extends ElementVisitor/* <void> */ { | 312 class ScopeInformationVisitor extends ElementVisitor/* <void> */ { |
Johnni Winther
2014/07/18 10:33:07
Comments are generally needed in the class.
ahe
2014/08/12 13:53:47
Good idea. I've added documentation and comments.
| |
313 // TODO(ahe): Include function parameters and local variables. | 313 // TODO(ahe): Include function parameters and local variables. |
314 | 314 |
315 final Element element; | 315 final Element currentElement; |
316 final int position; | 316 final int position; |
317 final StringBuffer buffer = new StringBuffer(); | 317 final StringBuffer buffer = new StringBuffer(); |
318 int indentationLevel = 0; | 318 int indentationLevel = 0; |
319 ClassElement currentClass; | |
319 | 320 |
320 ScopeInformationVisitor(this.element, this.position); | 321 ScopeInformationVisitor(this.currentElement, this.position); |
321 | 322 |
322 String get indentation => ' ' * indentationLevel; | 323 String get indentation => ' ' * indentationLevel; |
323 | 324 |
324 StringBuffer get indented => buffer..write(indentation); | 325 StringBuffer get indented => buffer..write(indentation); |
325 | 326 |
326 void visitElement(Element e) { | 327 void visitElement(Element e) { |
327 serialize(e, omitEnclosing: false); | 328 serialize(e, omitEnclosing: false); |
328 } | 329 } |
329 | 330 |
330 void visitLibraryElement(LibraryElement e) { | 331 void visitLibraryElement(LibraryElement e) { |
331 bool isFirst = true; | 332 bool isFirst = true; |
333 forEach(Element member) { | |
334 if (!isFirst) { | |
335 buffer.write(','); | |
336 } | |
337 buffer.write('\n'); | |
338 indented; | |
339 serialize(member); | |
340 isFirst = false; | |
341 } | |
332 serialize( | 342 serialize( |
333 e, omitEnclosing: true, | 343 e, omitEnclosing: currentClass == null, |
334 name: e.getLibraryName(), | 344 name: e.getLibraryName(), |
345 serializeEnclosing: () { | |
346 isFirst = true; | |
347 buffer.write('{\n'); | |
348 indentationLevel++; | |
349 indented.write('"kind": "imports",\n'); | |
350 indented.write('"members": ['); | |
351 indentationLevel++; | |
352 e.importScope.importScope.values.forEach(forEach); | |
353 indentationLevel--; | |
354 buffer.write('\n'); | |
355 indented.write('],\n'); | |
356 indented.write('"enclosing": '); | |
357 serializeClassSide( | |
358 currentClass.superclass, isStatic: false, includeSuper: true); | |
359 buffer.write('\n'); | |
360 indentationLevel--; | |
361 indented.write('}'); | |
362 }, | |
335 serializeMembers: () { | 363 serializeMembers: () { |
336 // TODO(ahe): Include imported elements in libraries. | 364 isFirst = true; |
337 e.forEachLocalMember((Element member) { | 365 e.localScope.values.forEach(forEach); |
338 if (!isFirst) { | |
339 buffer.write(','); | |
340 } | |
341 buffer.write('\n'); | |
342 indented; | |
343 serialize(member); | |
344 isFirst = false; | |
345 }); | |
346 }); | 366 }); |
347 } | 367 } |
348 | 368 |
369 void visitClassElement(ClassElement e) { | |
370 currentClass = e; | |
371 serializeClassSide(e, isStatic: true); | |
372 } | |
373 | |
374 void serializeClassSide( | |
375 ClassElement e, | |
376 {bool isStatic: false, | |
377 bool omitEnclosing: false, | |
378 bool includeSuper: false}) { | |
379 bool isFirst = true; | |
380 String name = e.name; | |
381 var serializeEnclosing; | |
382 if (isStatic) { | |
383 serializeEnclosing = () { | |
384 serializeClassSide(e, isStatic: false, omitEnclosing: omitEnclosing); | |
385 }; | |
386 } else { | |
387 name = "this($name)"; | |
388 } | |
389 if (includeSuper) { | |
390 assert(!omitEnclosing && !isStatic); | |
391 if (e.superclass == null) { | |
392 omitEnclosing = true; | |
393 } else { | |
394 serializeEnclosing = () { | |
395 serializeClassSide( | |
396 e.superclass, isStatic: false, omitEnclosing: false, | |
397 includeSuper: true); | |
398 }; | |
399 } | |
400 } | |
401 serialize( | |
402 e, omitEnclosing: omitEnclosing, serializeEnclosing: serializeEnclosing, | |
403 name: name, serializeMembers: () { | |
404 // TODO(ahe): Include inherited members in classes. | |
405 e.forEachLocalMember((Element member) { | |
406 if (member.isStatic != isStatic) return; | |
407 if (!isFirst) { | |
408 buffer.write(','); | |
409 } | |
410 buffer.write('\n'); | |
411 indented; | |
412 serialize(member); | |
413 isFirst = false; | |
414 }); | |
415 }); | |
416 } | |
417 | |
349 void visitScopeContainerElement(ScopeContainerElement e) { | 418 void visitScopeContainerElement(ScopeContainerElement e) { |
350 bool isFirst = true; | 419 bool isFirst = true; |
351 serialize(e, omitEnclosing: false, serializeMembers: () { | 420 serialize(e, omitEnclosing: false, serializeMembers: () { |
352 // TODO(ahe): Include inherited members in classes. | 421 // TODO(ahe): Include inherited members in classes. |
353 e.forEachLocalMember((Element member) { | 422 e.forEachLocalMember((Element member) { |
354 if (!isFirst) { | 423 if (!isFirst) { |
355 buffer.write(','); | 424 buffer.write(','); |
356 } | 425 } |
357 buffer.write('\n'); | 426 buffer.write('\n'); |
358 indented; | 427 indented; |
359 serialize(member); | 428 serialize(member); |
360 isFirst = false; | 429 isFirst = false; |
361 }); | 430 }); |
362 }); | 431 }); |
363 } | 432 } |
364 | 433 |
365 void visitCompilationUnitElement(CompilationUnitElement e) { | 434 void visitCompilationUnitElement(CompilationUnitElement e) { |
366 e.enclosingElement.accept(this); | 435 e.enclosingElement.accept(this); |
367 } | 436 } |
368 | 437 |
369 void serialize( | 438 void serialize( |
370 Element element, | 439 Element element, |
371 {bool omitEnclosing: true, | 440 {bool omitEnclosing: true, |
372 void serializeMembers(), | 441 void serializeMembers(), |
442 void serializeEnclosing(), | |
373 String name}) { | 443 String name}) { |
374 DartType type; | 444 DartType type; |
375 int category = element.kind.category; | 445 int category = element.kind.category; |
376 if (category == ElementCategory.FUNCTION || | 446 if (category == ElementCategory.FUNCTION || |
377 category == ElementCategory.VARIABLE || | 447 category == ElementCategory.VARIABLE || |
378 element.isConstructor) { | 448 element.isConstructor) { |
379 type = element.computeType(cachedCompiler); | 449 type = element.computeType(cachedCompiler); |
380 } | 450 } |
381 if (name == null) { | 451 if (name == null) { |
382 name = element.name; | 452 name = element.name; |
383 } | 453 } |
384 buffer.write('{\n'); | 454 buffer.write('{\n'); |
385 indentationLevel++; | 455 indentationLevel++; |
386 indented | 456 if (name != '') { |
387 ..write('"name": "') | 457 indented |
388 ..write(name) | 458 ..write('"name": "') |
389 ..write('",\n'); | 459 ..write(name) |
460 ..write('",\n'); | |
461 } | |
390 indented | 462 indented |
391 ..write('"kind": "') | 463 ..write('"kind": "') |
392 ..write(element.kind) | 464 ..write(element.kind) |
393 ..write('"'); | 465 ..write('"'); |
394 if (type != null) { | 466 if (type != null) { |
395 buffer.write(',\n'); | 467 buffer.write(',\n'); |
396 indented | 468 indented |
397 ..write('"type": "') | 469 ..write('"type": "') |
398 ..write(type) | 470 ..write(type) |
399 ..write('"'); | 471 ..write('"'); |
400 } | 472 } |
401 if (serializeMembers != null) { | 473 if (serializeMembers != null) { |
402 buffer.write(',\n'); | 474 buffer.write(',\n'); |
403 indented.write('"members": ['); | 475 indented.write('"members": ['); |
404 indentationLevel++; | 476 indentationLevel++; |
405 serializeMembers(); | 477 serializeMembers(); |
406 indentationLevel--; | 478 indentationLevel--; |
407 buffer.write('\n'); | 479 buffer.write('\n'); |
408 indented.write(']'); | 480 indented.write(']'); |
409 } | 481 } |
410 if (!omitEnclosing) { | 482 if (!omitEnclosing) { |
411 buffer.write(',\n'); | 483 buffer.write(',\n'); |
412 indented.write('"enclosing": '); | 484 indented.write('"enclosing": '); |
413 element.enclosingElement.accept(this); | 485 if (serializeEnclosing != null) { |
486 serializeEnclosing(); | |
487 } else { | |
488 element.enclosingElement.accept(this); | |
489 } | |
414 } | 490 } |
415 indentationLevel--; | 491 indentationLevel--; |
416 buffer.write('\n'); | 492 buffer.write('\n'); |
417 indented.write('}'); | 493 indented.write('}'); |
418 } | 494 } |
419 } | 495 } |
OLD | NEW |