| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 /** | 5 /** |
| 6 * To generate docs for a library, run this script with the path to an | 6 * To generate docs for a library, run this script with the path to an |
| 7 * entrypoint .dart file, like: | 7 * entrypoint .dart file, like: |
| 8 * | 8 * |
| 9 * $ dart dartdoc.dart foo.dart | 9 * $ dart dartdoc.dart foo.dart |
| 10 * | 10 * |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 final List members = docMembersJson(library.declaredMembers); | 568 final List members = docMembersJson(library.declaredMembers); |
| 569 if (!members.isEmpty()) { | 569 if (!members.isEmpty()) { |
| 570 libraryInfo[MEMBERS] = members; | 570 libraryInfo[MEMBERS] = members; |
| 571 } | 571 } |
| 572 | 572 |
| 573 final types = []; | 573 final types = []; |
| 574 for (InterfaceMirror type in orderByName(library.types.getValues())) { | 574 for (InterfaceMirror type in orderByName(library.types.getValues())) { |
| 575 if (type.isPrivate) continue; | 575 if (type.isPrivate) continue; |
| 576 | 576 |
| 577 var typeInfo = {}; | 577 var typeInfo = {}; |
| 578 typeInfo[NAME] = type.simpleName; | 578 typeInfo[NAME] = type.displayName; |
| 579 if (type.isClass) { | 579 if (type.isClass) { |
| 580 typeInfo[KIND] = CLASS; | 580 typeInfo[KIND] = CLASS; |
| 581 } else if (type.isInterface) { | 581 } else if (type.isInterface) { |
| 582 typeInfo[KIND] = INTERFACE; | 582 typeInfo[KIND] = INTERFACE; |
| 583 } else { | 583 } else { |
| 584 assert(type.isTypedef); | 584 assert(type.isTypedef); |
| 585 typeInfo[KIND] = TYPEDEF; | 585 typeInfo[KIND] = TYPEDEF; |
| 586 } | 586 } |
| 587 final List typeMembers = docMembersJson(type.declaredMembers); | 587 final List typeMembers = docMembersJson(type.declaredMembers); |
| 588 if (!typeMembers.isEmpty()) { | 588 if (!typeMembers.isEmpty()) { |
| 589 typeInfo[MEMBERS] = typeMembers; | 589 typeInfo[MEMBERS] = typeMembers; |
| 590 } | 590 } |
| 591 | 591 |
| 592 if (!type.declaration.typeVariables.isEmpty()) { | 592 if (!type.declaration.typeVariables.isEmpty()) { |
| 593 final typeVariables = []; | 593 final typeVariables = []; |
| 594 for (final typeVariable in type.declaration.typeVariables) { | 594 for (final typeVariable in type.declaration.typeVariables) { |
| 595 typeVariables.add(typeVariable.simpleName); | 595 typeVariables.add(typeVariable.displayName); |
| 596 } | 596 } |
| 597 typeInfo[ARGS] = Strings.join(typeVariables, ', '); | 597 typeInfo[ARGS] = Strings.join(typeVariables, ', '); |
| 598 } | 598 } |
| 599 types.add(typeInfo); | 599 types.add(typeInfo); |
| 600 } | 600 } |
| 601 if (!types.isEmpty()) { | 601 if (!types.isEmpty()) { |
| 602 libraryInfo[TYPES] = types; | 602 libraryInfo[TYPES] = types; |
| 603 } | 603 } |
| 604 | 604 |
| 605 libraryList.add(libraryInfo); | 605 libraryList.add(libraryInfo); |
| 606 } | 606 } |
| 607 | 607 |
| 608 List docMembersJson(Map<Object,MemberMirror> memberMap) { | 608 List docMembersJson(Map<Object,MemberMirror> memberMap) { |
| 609 final members = []; | 609 final members = []; |
| 610 for (MemberMirror member in orderByName(memberMap.getValues())) { | 610 for (MemberMirror member in orderByName(memberMap.getValues())) { |
| 611 if (member.isPrivate) continue; | 611 if (member.isPrivate) continue; |
| 612 | 612 |
| 613 var memberInfo = {}; | 613 var memberInfo = {}; |
| 614 if (member.isField) { | 614 if (member.isField) { |
| 615 memberInfo[NAME] = member.simpleName; | |
| 616 memberInfo[KIND] = FIELD; | 615 memberInfo[KIND] = FIELD; |
| 617 } else { | 616 } else { |
| 618 MethodMirror method = member; | 617 MethodMirror method = member; |
| 619 if (method.isConstructor) { | 618 if (method.isConstructor) { |
| 620 if (method.constructorName != '') { | 619 memberInfo[KIND] = CONSTRUCTOR; |
| 621 memberInfo[NAME] = '${method.simpleName}.${method.constructorName}'; | |
| 622 memberInfo[KIND] = CONSTRUCTOR; | |
| 623 } else { | |
| 624 memberInfo[NAME] = member.simpleName; | |
| 625 memberInfo[KIND] = CONSTRUCTOR; | |
| 626 } | |
| 627 } else if (method.isOperator) { | |
| 628 memberInfo[NAME] = '${method.simpleName} ${method.operatorName}'; | |
| 629 memberInfo[KIND] = METHOD; | |
| 630 } else if (method.isSetter) { | 620 } else if (method.isSetter) { |
| 631 memberInfo[NAME] = member.simpleName; | |
| 632 memberInfo[KIND] = SETTER; | 621 memberInfo[KIND] = SETTER; |
| 633 } else if (method.isGetter) { | 622 } else if (method.isGetter) { |
| 634 memberInfo[NAME] = member.simpleName; | |
| 635 memberInfo[KIND] = GETTER; | 623 memberInfo[KIND] = GETTER; |
| 636 } else { | 624 } else { |
| 637 memberInfo[NAME] = member.simpleName; | |
| 638 memberInfo[KIND] = METHOD; | 625 memberInfo[KIND] = METHOD; |
| 639 } | 626 } |
| 640 if (method.parameters.isEmpty()) { | 627 if (method.parameters.isEmpty()) { |
| 641 memberInfo[NO_PARAMS] = true; | 628 memberInfo[NO_PARAMS] = true; |
| 642 } | 629 } |
| 643 } | 630 } |
| 631 memberInfo[NAME] = member.displayName; |
| 644 var anchor = memberAnchor(member); | 632 var anchor = memberAnchor(member); |
| 645 if (anchor != memberInfo[NAME]) { | 633 if (anchor != memberInfo[NAME]) { |
| 646 memberInfo[LINK_NAME] = anchor; | 634 memberInfo[LINK_NAME] = anchor; |
| 647 } | 635 } |
| 648 members.add(memberInfo); | 636 members.add(memberInfo); |
| 649 } | 637 } |
| 650 return members; | 638 return members; |
| 651 } | 639 } |
| 652 | 640 |
| 653 void docNavigation() { | 641 void docNavigation() { |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 917 typeSpan(supertypes[i]); | 905 typeSpan(supertypes[i]); |
| 918 write(' > '); | 906 write(' > '); |
| 919 } | 907 } |
| 920 | 908 |
| 921 // Write this class. | 909 // Write this class. |
| 922 typeSpan(type); | 910 typeSpan(type); |
| 923 writeln('</p>'); | 911 writeln('</p>'); |
| 924 } | 912 } |
| 925 | 913 |
| 926 listTypes(subtypes, 'Subclasses'); | 914 listTypes(subtypes, 'Subclasses'); |
| 927 listTypes(type.interfaces.getValues(), 'Implements'); | 915 listTypes(type.interfaces, 'Implements'); |
| 928 } else { | 916 } else { |
| 929 // Show the default class. | 917 // Show the default class. |
| 930 if (type.defaultType != null) { | 918 if (type.defaultType != null) { |
| 931 listTypes([type.defaultType], 'Default class'); | 919 listTypes([type.defaultType], 'Default class'); |
| 932 } | 920 } |
| 933 | 921 |
| 934 // List extended interfaces. | 922 // List extended interfaces. |
| 935 listTypes(type.interfaces.getValues(), 'Extends'); | 923 listTypes(type.interfaces, 'Extends'); |
| 936 | 924 |
| 937 // List subinterfaces and implementing classes. | 925 // List subinterfaces and implementing classes. |
| 938 final subinterfaces = []; | 926 final subinterfaces = []; |
| 939 final implementing = []; | 927 final implementing = []; |
| 940 | 928 |
| 941 for (final subtype in subtypes) { | 929 for (final subtype in subtypes) { |
| 942 if (subtype.isClass) { | 930 if (subtype.isClass) { |
| 943 implementing.add(subtype); | 931 implementing.add(subtype); |
| 944 } else { | 932 } else { |
| 945 subinterfaces.add(subtype); | 933 subinterfaces.add(subtype); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1066 if (method.isConstructor) { | 1054 if (method.isConstructor) { |
| 1067 if (method.isFactory) { | 1055 if (method.isFactory) { |
| 1068 write('factory '); | 1056 write('factory '); |
| 1069 } else { | 1057 } else { |
| 1070 write(method.isConst ? 'const ' : 'new '); | 1058 write(method.isConst ? 'const ' : 'new '); |
| 1071 } | 1059 } |
| 1072 } else if (method.isAbstract) { | 1060 } else if (method.isAbstract) { |
| 1073 write('abstract '); | 1061 write('abstract '); |
| 1074 } | 1062 } |
| 1075 | 1063 |
| 1076 if (method.constructorName == null) { | 1064 if (!method.isConstructor) { |
| 1077 annotateType(host, method.returnType); | 1065 annotateType(host, method.returnType); |
| 1078 } | 1066 } |
| 1079 | 1067 |
| 1080 var name = method.simpleName; | 1068 var name = method.displayName; |
| 1081 // Translate specially-named methods: getters, setters, operators. | 1069 // Translate specially-named methods: getters, setters, operators. |
| 1082 if (method.isGetter) { | 1070 if (method.isGetter) { |
| 1083 // Getter. | 1071 // Getter. |
| 1084 name = 'get $name'; | 1072 name = 'get $name'; |
| 1085 } else if (method.isSetter) { | 1073 } else if (method.isSetter) { |
| 1086 // Setter. | 1074 // Setter. |
| 1087 name = 'set $name'; | 1075 name = 'set $name'; |
| 1088 } else if (method.isOperator) { | |
| 1089 name = 'operator ${method.operatorName}'; | |
| 1090 } | 1076 } |
| 1091 | 1077 |
| 1092 write('<strong>$name</strong>'); | 1078 write('<strong>$name</strong>'); |
| 1093 | 1079 |
| 1094 // Named constructors. | |
| 1095 if (method.constructorName != null && method.constructorName != '') { | |
| 1096 write('.'); | |
| 1097 write(method.constructorName); | |
| 1098 } | |
| 1099 | |
| 1100 docParamList(host, method.parameters); | 1080 docParamList(host, method.parameters); |
| 1101 | 1081 |
| 1102 var prefix = host is LibraryMirror ? '' : '${typeName(host)}.'; | 1082 var prefix = host is LibraryMirror ? '' : '${typeName(host)}.'; |
| 1103 write(''' <a class="anchor-link" href="#${memberAnchor(method)}" | 1083 write(''' <a class="anchor-link" href="#${memberAnchor(method)}" |
| 1104 title="Permalink to $prefix$name">#</a>'''); | 1084 title="Permalink to $prefix$name">#</a>'''); |
| 1105 writeln('</h4>'); | 1085 writeln('</h4>'); |
| 1106 | 1086 |
| 1107 docCode(method.location, getMethodComment(method), showCode: showCode); | 1087 docCode(method.location, getMethodComment(method), showCode: showCode); |
| 1108 | 1088 |
| 1109 writeln('</div>'); | 1089 writeln('</div>'); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1262 } | 1242 } |
| 1263 | 1243 |
| 1264 /** Gets the URL for the documentation for [member]. */ | 1244 /** Gets the URL for the documentation for [member]. */ |
| 1265 String memberUrl(MemberMirror member) { | 1245 String memberUrl(MemberMirror member) { |
| 1266 String url = typeUrl(member.surroundingDeclaration); | 1246 String url = typeUrl(member.surroundingDeclaration); |
| 1267 return '$url#${memberAnchor(member)}'; | 1247 return '$url#${memberAnchor(member)}'; |
| 1268 } | 1248 } |
| 1269 | 1249 |
| 1270 /** Gets the anchor id for the document for [member]. */ | 1250 /** Gets the anchor id for the document for [member]. */ |
| 1271 String memberAnchor(MemberMirror member) { | 1251 String memberAnchor(MemberMirror member) { |
| 1272 if (member.isField) { | 1252 return member.simpleName; |
| 1273 return member.simpleName; | |
| 1274 } | |
| 1275 MethodMirror method = member; | |
| 1276 if (method.isConstructor) { | |
| 1277 if (method.constructorName == '') { | |
| 1278 return method.simpleName; | |
| 1279 } else { | |
| 1280 return '${method.simpleName}.${method.constructorName}'; | |
| 1281 } | |
| 1282 } else if (method.isOperator) { | |
| 1283 return '${method.simpleName} ${method.operatorName}'; | |
| 1284 } else if (method.isSetter) { | |
| 1285 return '${method.simpleName}='; | |
| 1286 } else { | |
| 1287 return method.simpleName; | |
| 1288 } | |
| 1289 } | 1253 } |
| 1290 | 1254 |
| 1291 /** | 1255 /** |
| 1292 * Creates a hyperlink. Handles turning the [href] into an appropriate | 1256 * Creates a hyperlink. Handles turning the [href] into an appropriate |
| 1293 * relative path from the current file. | 1257 * relative path from the current file. |
| 1294 */ | 1258 */ |
| 1295 String a(String href, String contents, [String css]) { | 1259 String a(String href, String contents, [String css]) { |
| 1296 // Mark outgoing external links, mainly so we can style them. | 1260 // Mark outgoing external links, mainly so we can style them. |
| 1297 final rel = isAbsolute(href) ? ' ref="external"' : ''; | 1261 final rel = isAbsolute(href) ? ' ref="external"' : ''; |
| 1298 final cssClass = css == null ? '' : ' class="$css"'; | 1262 final cssClass = css == null ? '' : ' class="$css"'; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1472 if (parameter.simpleName == name) { | 1436 if (parameter.simpleName == name) { |
| 1473 final element = new md.Element.text('span', name); | 1437 final element = new md.Element.text('span', name); |
| 1474 element.attributes['class'] = 'param'; | 1438 element.attributes['class'] = 'param'; |
| 1475 return element; | 1439 return element; |
| 1476 } | 1440 } |
| 1477 } | 1441 } |
| 1478 } | 1442 } |
| 1479 | 1443 |
| 1480 // See if it's another member of the current type. | 1444 // See if it's another member of the current type. |
| 1481 if (currentType != null) { | 1445 if (currentType != null) { |
| 1482 final foundMember = findMirror(currentType.declaredMembers, name); | 1446 final foundMember = currentType.declaredMembers[name]; |
| 1483 if (foundMember != null) { | 1447 if (foundMember != null) { |
| 1484 return makeLink(memberUrl(foundMember)); | 1448 return makeLink(memberUrl(foundMember)); |
| 1485 } | 1449 } |
| 1486 } | 1450 } |
| 1487 | 1451 |
| 1488 // See if it's another type or a member of another type in the current | 1452 // See if it's another type or a member of another type in the current |
| 1489 // library. | 1453 // library. |
| 1490 if (currentLibrary != null) { | 1454 if (currentLibrary != null) { |
| 1491 // See if it's a constructor | 1455 // See if it's a constructor |
| 1492 final constructorLink = (() { | 1456 final constructorLink = (() { |
| 1493 final match = | 1457 final match = |
| 1494 new RegExp(r'new ([\w$]+)(?:\.([\w$]+))?').firstMatch(name); | 1458 new RegExp(r'new ([\w$]+)(?:\.([\w$]+))?').firstMatch(name); |
| 1495 if (match == null) return; | 1459 if (match == null) return; |
| 1496 InterfaceMirror foundtype = findMirror(currentLibrary.types, match[1]); | 1460 String typeName = match[1]; |
| 1461 InterfaceMirror foundtype = currentLibrary.types[typeName]; |
| 1497 if (foundtype == null) return; | 1462 if (foundtype == null) return; |
| 1463 String constructorName = |
| 1464 match[2] == null ? typeName : '$typeName.${match[2]}'; |
| 1498 final constructor = | 1465 final constructor = |
| 1499 findMirror(foundtype.constructors, | 1466 foundtype.constructors[constructorName]; |
| 1500 match[2] == null ? '' : match[2]); | |
| 1501 if (constructor == null) return; | 1467 if (constructor == null) return; |
| 1502 return makeLink(memberUrl(constructor)); | 1468 return makeLink(memberUrl(constructor)); |
| 1503 })(); | 1469 })(); |
| 1504 if (constructorLink != null) return constructorLink; | 1470 if (constructorLink != null) return constructorLink; |
| 1505 | 1471 |
| 1506 // See if it's a member of another type | 1472 // See if it's a member of another type |
| 1507 final foreignMemberLink = (() { | 1473 final foreignMemberLink = (() { |
| 1508 final match = new RegExp(r'([\w$]+)\.([\w$]+)').firstMatch(name); | 1474 final match = new RegExp(r'([\w$]+)\.([\w$]+)').firstMatch(name); |
| 1509 if (match == null) return; | 1475 if (match == null) return; |
| 1510 InterfaceMirror foundtype = findMirror(currentLibrary.types, match[1]); | 1476 InterfaceMirror foundtype = currentLibrary.types[match[1]]; |
| 1511 if (foundtype == null) return; | 1477 if (foundtype == null) return; |
| 1512 MemberMirror foundMember = findMirror(foundtype.declaredMembers, match[2
]); | 1478 MemberMirror foundMember = foundtype.declaredMembers[match[2]]; |
| 1513 if (foundMember == null) return; | 1479 if (foundMember == null) return; |
| 1514 return makeLink(memberUrl(foundMember)); | 1480 return makeLink(memberUrl(foundMember)); |
| 1515 })(); | 1481 })(); |
| 1516 if (foreignMemberLink != null) return foreignMemberLink; | 1482 if (foreignMemberLink != null) return foreignMemberLink; |
| 1517 | 1483 |
| 1518 InterfaceMirror foundType = findMirror(currentLibrary.types, name); | 1484 InterfaceMirror foundType = currentLibrary.types[name]; |
| 1519 if (foundType != null) { | 1485 if (foundType != null) { |
| 1520 return makeLink(typeUrl(foundType)); | 1486 return makeLink(typeUrl(foundType)); |
| 1521 } | 1487 } |
| 1522 | 1488 |
| 1523 // See if it's a top-level member in the current library. | 1489 // See if it's a top-level member in the current library. |
| 1524 MemberMirror foundMember = findMirror(currentLibrary.declaredMembers, name
); | 1490 MemberMirror foundMember = currentLibrary.declaredMembers[name]; |
| 1525 if (foundMember != null) { | 1491 if (foundMember != null) { |
| 1526 return makeLink(memberUrl(foundMember)); | 1492 return makeLink(memberUrl(foundMember)); |
| 1527 } | 1493 } |
| 1528 } | 1494 } |
| 1529 | 1495 |
| 1530 // TODO(rnystrom): Should also consider: | 1496 // TODO(rnystrom): Should also consider: |
| 1531 // * Names imported by libraries this library imports. | 1497 // * Names imported by libraries this library imports. |
| 1532 // * Type parameters of the enclosing type. | 1498 // * Type parameters of the enclosing type. |
| 1533 | 1499 |
| 1534 return new md.Element.text('code', name); | 1500 return new md.Element.text('code', name); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1578 | 1544 |
| 1579 /** | 1545 /** |
| 1580 * Used to report an unexpected error in the DartDoc tool or the | 1546 * Used to report an unexpected error in the DartDoc tool or the |
| 1581 * underlying data | 1547 * underlying data |
| 1582 */ | 1548 */ |
| 1583 class InternalError { | 1549 class InternalError { |
| 1584 final String message; | 1550 final String message; |
| 1585 const InternalError(this.message); | 1551 const InternalError(this.message); |
| 1586 String toString() => "InternalError: '$message'"; | 1552 String toString() => "InternalError: '$message'"; |
| 1587 } | 1553 } |
| OLD | NEW |