| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /// **docgen** is a tool for creating machine readable representations of Dart | 5 /// **docgen** is a tool for creating machine readable representations of Dart |
| 6 /// code metadata, including: classes, members, comments and annotations. | 6 /// code metadata, including: classes, members, comments and annotations. |
| 7 /// | 7 /// |
| 8 /// docgen is run on a `.dart` file or a directory containing `.dart` files. | 8 /// docgen is run on a `.dart` file or a directory containing `.dart` files. |
| 9 /// | 9 /// |
| 10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR] | 10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR] |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; | 502 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; |
| 503 if (mdnType['srcUrl'] == null) return ''; | 503 if (mdnType['srcUrl'] == null) return ''; |
| 504 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); | 504 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); |
| 505 } | 505 } |
| 506 | 506 |
| 507 String _htmlMdn(String content, String url) { | 507 String _htmlMdn(String content, String url) { |
| 508 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' | 508 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' |
| 509 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; | 509 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; |
| 510 } | 510 } |
| 511 | 511 |
| 512 /// Look for the specified name starting with the current member, and |
| 513 /// progressively working outward to the current library scope. |
| 514 String findElementInScope(String name, LibraryMirror currentLibrary, |
| 515 ClassMirror currentClass, MemberMirror currentMember) { |
| 516 var memberScope = currentMember == null ? |
| 517 null : currentMember.lookupInScope(name); |
| 518 if (memberScope != null) { |
| 519 return docName(memberScope); |
| 520 } else { |
| 521 var classScope = currentClass == null ? |
| 522 null : currentClass.lookupInScope(name); |
| 523 if (classScope != null) { |
| 524 return docName(classScope); |
| 525 } else { |
| 526 var libraryScope = currentLibrary == null ? |
| 527 null : currentLibrary.lookupInScope(name); |
| 528 if (libraryScope != null) { |
| 529 return docName(libraryScope); |
| 530 } |
| 531 } |
| 532 } |
| 533 return null; |
| 534 } |
| 535 |
| 536 // HTML escaped version of '<' character. |
| 537 final _LESS_THAN = '<'; |
| 538 |
| 539 /// Chunk the provided name into individual parts to be resolved. We take a |
| 540 /// simplistic approach to chunking, though, we break at " ", ",", "<" |
| 541 /// and ">". All other characters are grouped into the name to be resolved. |
| 542 /// As a result, these characters will all be treated as part of the item to be |
| 543 /// resolved (aka the * is interpreted literally as a *, not as an indicator for |
| 544 /// bold <em>. |
| 545 List<String> _tokenizeComplexReference(String name) { |
| 546 var tokens = []; |
| 547 var append = false; |
| 548 var index = 0; |
| 549 while(index < name.length) { |
| 550 if (name.indexOf(_LESS_THAN, index) == index) { |
| 551 tokens.add(_LESS_THAN); |
| 552 append = false; |
| 553 index += _LESS_THAN.length; |
| 554 } else if (name[index] == ' ' || name[index] == ',' || |
| 555 name[index] == '>') { |
| 556 tokens.add(name[index]); |
| 557 append = false; |
| 558 index++; |
| 559 } else { |
| 560 if (append) { |
| 561 tokens[tokens.length - 1] = tokens.last + name[index]; |
| 562 } else { |
| 563 tokens.add(name[index]); |
| 564 append = true; |
| 565 } |
| 566 index++; |
| 567 } |
| 568 } |
| 569 return tokens; |
| 570 } |
| 571 |
| 572 /// This is a more complex reference. Try to break up if its of the form A<B> |
| 573 /// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"), |
| 574 /// or of the form A<B>. Note: unlike other the other markdown-style links, all |
| 575 /// text inside the square brackets is treated as part of the link (aka the * is |
| 576 /// interpreted literally as a *, not as a indicator for bold <em>. |
| 577 /// |
| 578 /// Example: [foo<_bar_>] will produce |
| 579 /// <a>resolvedFoo</a><<a>resolved_bar_</a>> rather than an italicized |
| 580 /// version of resolvedBar. |
| 581 markdown.Node _fixComplexReference(String name, LibraryMirror currentLibrary, |
| 582 ClassMirror currentClass, MemberMirror currentMember) { |
| 583 // Parse into multiple elements we can try to resolve. |
| 584 var tokens = _tokenizeComplexReference(name); |
| 585 |
| 586 // Produce an html representation of our elements. Group unresolved and plain |
| 587 // text are grouped into "link" elements so they display as code. |
| 588 final textElements = [' ', ',', '>', _LESS_THAN]; |
| 589 var accumulatedHtml = ''; |
| 590 |
| 591 for (var token in tokens) { |
| 592 bool added = false; |
| 593 if (!textElements.contains(token)) { |
| 594 String elementName = findElementInScope(token, currentLibrary, |
| 595 currentClass, currentMember); |
| 596 if (elementName != null) { |
| 597 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text( |
| 598 'a', elementName)]); |
| 599 added = true; |
| 600 } |
| 601 } |
| 602 if (!added) { |
| 603 accumulatedHtml += token; |
| 604 } |
| 605 } |
| 606 return new markdown.Text(accumulatedHtml); |
| 607 } |
| 608 |
| 512 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. | 609 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 513 markdown.Node fixReference(String name, LibraryMirror currentLibrary, | 610 markdown.Node fixReference(String name, LibraryMirror currentLibrary, |
| 514 ClassMirror currentClass, MemberMirror currentMember) { | 611 ClassMirror currentClass, MemberMirror currentMember) { |
| 515 var reference; | 612 // Attempt the look up the whole name up in the scope. |
| 516 var memberScope = currentMember == null ? | 613 String elementName = |
| 517 null : currentMember.lookupInScope(name); | 614 findElementInScope(name, currentLibrary, currentClass, currentMember); |
| 518 if (memberScope != null) { | 615 if (elementName != null) { |
| 519 reference = docName(memberScope); | 616 return new markdown.Element.text('a', elementName); |
| 520 } else { | |
| 521 var classScope = currentClass == null ? | |
| 522 null : currentClass.lookupInScope(name); | |
| 523 if (classScope != null) { | |
| 524 reference = docName(classScope); | |
| 525 } else { | |
| 526 var libraryScope = currentLibrary == null ? | |
| 527 null : currentLibrary.lookupInScope(name); | |
| 528 reference = libraryScope != null ? docName(libraryScope) : name; | |
| 529 } | |
| 530 } | 617 } |
| 531 return new markdown.Element.text('a', reference); | 618 return _fixComplexReference(name, currentLibrary, currentClass, currentMember)
; |
| 532 } | 619 } |
| 533 | 620 |
| 534 /// Returns a map of [Variable] objects constructed from [mirrorMap]. | 621 /// Returns a map of [Variable] objects constructed from [mirrorMap]. |
| 535 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { | 622 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { |
| 536 var data = {}; | 623 var data = {}; |
| 537 // TODO(janicejl): When map to map feature is created, replace the below with | 624 // TODO(janicejl): When map to map feature is created, replace the below with |
| 538 // a filter. Issue(#9590). | 625 // a filter. Issue(#9590). |
| 539 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { | 626 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { |
| 540 _currentMember = mirror; | 627 _currentMember = mirror; |
| 541 if (_includePrivate || !_isHidden(mirror)) { | 628 if (_includePrivate || !_isHidden(mirror)) { |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1238 String docName(DeclarationMirror m) { | 1325 String docName(DeclarationMirror m) { |
| 1239 if (m is LibraryMirror) { | 1326 if (m is LibraryMirror) { |
| 1240 return (m as LibraryMirror).qualifiedName.replaceAll('.','-'); | 1327 return (m as LibraryMirror).qualifiedName.replaceAll('.','-'); |
| 1241 } | 1328 } |
| 1242 var owner = m.owner; | 1329 var owner = m.owner; |
| 1243 if (owner == null) return m.qualifiedName; | 1330 if (owner == null) return m.qualifiedName; |
| 1244 // For the unnamed constructor we just return the class name. | 1331 // For the unnamed constructor we just return the class name. |
| 1245 if (m.simpleName == '') return docName(owner); | 1332 if (m.simpleName == '') return docName(owner); |
| 1246 return docName(owner) + '.' + m.simpleName; | 1333 return docName(owner) + '.' + m.simpleName; |
| 1247 } | 1334 } |
| OLD | NEW |