| OLD | NEW |
| 1 #library("postProcess"); | 1 #library("prettyPrint"); |
| 2 | 2 |
| 3 #import("../../../frog/lib/node/node.dart"); | 3 #import("../../../frog/lib/node/node.dart"); |
| 4 #import("dart:json"); | 4 #import("dart:json"); |
| 5 | 5 #import("util.dart"); |
| 6 // TODO(jacobr): this file conflates pretty printing of the JSON database with | |
| 7 // filtering the database to select the best matches per file. | |
| 8 // Separate out the two tasks as quick and dirty coding is correct for pretty | |
| 9 // printing but more carefully documented code is required for the code | |
| 10 // filtering the database. | |
| 11 Map<String, List> database; | |
| 12 Map<String, Map> allProps; | |
| 13 Set<String> matchedTypes; | |
| 14 | 6 |
| 15 String orEmpty(String str) { | 7 String orEmpty(String str) { |
| 16 return str == null ? "" : str; | 8 return str == null ? "" : str; |
| 17 } | 9 } |
| 18 | 10 |
| 19 /** Returns whether the type has any member matching the specified name. */ | |
| 20 bool hasAny(String type, String prop) { | |
| 21 final data = allProps[type]; | |
| 22 return data['properties'].containsKey(prop) || | |
| 23 data['methods'].containsKey(prop) || | |
| 24 data['constants'].containsKey(prop); | |
| 25 } | |
| 26 | |
| 27 List<String> sortStringCollection(Collection<String> collection) { | 11 List<String> sortStringCollection(Collection<String> collection) { |
| 28 final out = <String>[]; | 12 final out = <String>[]; |
| 29 out.addAll(collection); | 13 out.addAll(collection); |
| 30 out.sort((String a, String b) => a.compareTo(b)); | 14 out.sort((String a, String b) => a.compareTo(b)); |
| 31 return out; | 15 return out; |
| 32 } | 16 } |
| 33 | 17 |
| 34 /** | |
| 35 * Return the members from an [entry] as Map of member names to member | |
| 36 * objects. | |
| 37 */ | |
| 38 Map getMembersMap(Map entry) { | |
| 39 List<Map> rawMembers = entry["members"]; | |
| 40 final members = {}; | |
| 41 for (final entry in rawMembers) { | |
| 42 members[entry['name']] = entry; | |
| 43 } | |
| 44 return members; | |
| 45 } | |
| 46 | |
| 47 int addMissing(StringBuffer sb, String type, Map members) { | 18 int addMissing(StringBuffer sb, String type, Map members) { |
| 48 int total = 0; | 19 int total = 0; |
| 49 /** | 20 /** |
| 50 * Add all missing members to the string output and return the number of | 21 * Add all missing members to the string output and return the number of |
| 51 * missing members. | 22 * missing members. |
| 52 */ | 23 */ |
| 53 void addMissingHelper(String propType) { | 24 void addMissingHelper(String propType) { |
| 54 Map expected = allProps[type][propType]; | 25 Map expected = allProps[type][propType]; |
| 55 if (expected != null) { | 26 if (expected != null) { |
| 56 for(final name in sortStringCollection(expected.getKeys())) { | 27 for(final name in sortStringCollection(expected.getKeys())) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 67 } | 38 } |
| 68 } | 39 } |
| 69 } | 40 } |
| 70 | 41 |
| 71 addMissingHelper('properties'); | 42 addMissingHelper('properties'); |
| 72 addMissingHelper('methods'); | 43 addMissingHelper('methods'); |
| 73 addMissingHelper('constants'); | 44 addMissingHelper('constants'); |
| 74 return total; | 45 return total; |
| 75 } | 46 } |
| 76 | 47 |
| 77 /** | |
| 78 * Score entries using similarity heuristics calculated from the observed and | |
| 79 * expected list of members. We could be much less naive and penalize spurious | |
| 80 * methods, prefer entries with class level comments, etc. This method is | |
| 81 * needed becase we extract entries for each of the top search results for | |
| 82 * each class name and rely on these scores to determine which entry was | |
| 83 * best. Typically all scores but one will be zero. Multiple pages have | |
| 84 * non-zero scores when MDN has multiple pages on the same class or pages on | |
| 85 * similar classes (e.g. HTMLElement and Element), or pages on Mozilla | |
| 86 * specific classes that are similar to DOM classes (Console). | |
| 87 */ | |
| 88 num scoreEntry(Map entry, String type) { | |
| 89 num score = 0; | |
| 90 // TODO(jacobr): consider removing skipped entries completely instead of | |
| 91 // just giving them lower scores. | |
| 92 if (!entry.containsKey('skipped')) { | |
| 93 score++; | |
| 94 } | |
| 95 if (entry.containsKey("members")) { | |
| 96 Map members = getMembersMap(entry); | |
| 97 for (String name in members.getKeys()) { | |
| 98 if (hasAny(type, name)) { | |
| 99 score++; | |
| 100 } | |
| 101 } | |
| 102 } | |
| 103 return score; | |
| 104 } | |
| 105 | |
| 106 /** | |
| 107 * Given a list of candidates for the documentation for a type, find the one | |
| 108 * that is the best. | |
| 109 */ | |
| 110 Map pickBestEntry(List entries, String type) { | |
| 111 num bestScore = -1; | |
| 112 Map bestEntry; | |
| 113 for (Map entry in entries) { | |
| 114 if (entry != null) { | |
| 115 num score = scoreEntry(entry, type); | |
| 116 if (score > bestScore) { | |
| 117 bestScore = score; | |
| 118 bestEntry = entry; | |
| 119 } | |
| 120 } | |
| 121 } | |
| 122 return bestEntry; | |
| 123 } | |
| 124 | |
| 125 void main() { | 48 void main() { |
| 126 // Database of code documentation. | 49 // Database of code documentation. |
| 127 database = JSON.parse(fs.readFileSync('output/database.json', 'utf8')); | 50 final Map<String, Map> database = JSON.parse(fs.readFileSync( |
| 128 // Database of expected property names for each type in WebKit. | 51 » 'output/database.filtered.json', 'utf8')); |
| 129 allProps = JSON.parse(fs.readFileSync('data/dartIdl.json', 'utf8')); | 52 |
| 130 // Types we have documentation for. | 53 // Types we have documentation for. |
| 131 matchedTypes = new Set<String>(); | 54 matchedTypes = new Set<String>(); |
| 132 int numMissingMethods = 0; | 55 int numMissingMethods = 0; |
| 133 int numFoundMethods = 0; | 56 int numFoundMethods = 0; |
| 134 int numExtraMethods = 0; | 57 int numExtraMethods = 0; |
| 135 int numGen = 0; | 58 int numGen = 0; |
| 136 int numSkipped = 0; | 59 int numSkipped = 0; |
| 137 final sbSkipped = new StringBuffer(); | 60 final sbSkipped = new StringBuffer(); |
| 138 final sbAllExamples = new StringBuffer(); | 61 final sbAllExamples = new StringBuffer(); |
| 139 final filteredDb = {}; | |
| 140 | 62 |
| 141 // Table rows for all obsolete members. | 63 // Table rows for all obsolete members. |
| 142 final sbObsolete = new StringBuffer(); | 64 final sbObsolete = new StringBuffer(); |
| 143 // Main documentation file. | 65 // Main documentation file. |
| 144 final sb = new StringBuffer(); | 66 final sb = new StringBuffer(); |
| 145 | 67 |
| 146 // TODO(jacobr): switch to using a real template system instead of string | 68 // TODO(jacobr): switch to using a real template system instead of string |
| 147 // interpolation combined with StringBuffers. | 69 // interpolation combined with StringBuffers. |
| 148 sb.add(""" | 70 sb.add(""" |
| 149 <html> | 71 <html> |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 } | 141 } |
| 220 </style> | 142 </style> |
| 221 <title>Doc Dump</title> | 143 <title>Doc Dump</title> |
| 222 </head> | 144 </head> |
| 223 <body> | 145 <body> |
| 224 <h1>Doc Dump</h1> | 146 <h1>Doc Dump</h1> |
| 225 <ul> | 147 <ul> |
| 226 <li><a href="#dart_summary">Summary</a></li> | 148 <li><a href="#dart_summary">Summary</a></li> |
| 227 </li> | 149 </li> |
| 228 """); | 150 """); |
| 229 | |
| 230 for (String type in sortStringCollection(database.getKeys())) { | 151 for (String type in sortStringCollection(database.getKeys())) { |
| 231 Map entry = pickBestEntry(database[type], type); | 152 » final entry = database[type]; |
| 232 filteredDb[type] = entry; | |
| 233 if (entry == null || entry.containsKey('skipped')) { | 153 if (entry == null || entry.containsKey('skipped')) { |
| 234 numSkipped++; | 154 numSkipped++; |
| 235 sbSkipped.add(""" | 155 sbSkipped.add(""" |
| 236 <li id="$type"> | 156 <li id="$type"> |
| 237 <a target="_blank" href="http://www.google.com/cse?cx=01719397256594783026
6%3Awpqsk6dy6ee&ie=UTF-8&q=$type"> | 157 <a target="_blank" href="http://www.google.com/cse?cx=01719397256594783026
6%3Awpqsk6dy6ee&ie=UTF-8&q=$type"> |
| 238 $type | 158 $type |
| 239 </a> | 159 </a> |
| 240 -- | 160 -- |
| 241 Title: ${entry == null ? "???" : entry["title"]} -- Issue: | 161 Title: ${entry == null ? "???" : entry["title"]} -- Issue: |
| 242 ${entry == null ? "???" : entry['cause']} | 162 ${entry == null ? "???" : entry['cause']} |
| (...skipping 14 matching lines...) Expand all Loading... |
| 257 sbMembers.add(""" | 177 sbMembers.add(""" |
| 258 <div class="members"> | 178 <div class="members"> |
| 259 <h3><span class="debug">[dart]</span> Members</h3> | 179 <h3><span class="debug">[dart]</span> Members</h3> |
| 260 <table> | 180 <table> |
| 261 <tbody> | 181 <tbody> |
| 262 <tr> | 182 <tr> |
| 263 <th>Name</th><th>Description</th><th>IDL</th><th>Status</th> | 183 <th>Name</th><th>Description</th><th>IDL</th><th>Status</th> |
| 264 </tr> | 184 </tr> |
| 265 """); | 185 """); |
| 266 for (String name in sortStringCollection(members.getKeys())) { | 186 for (String name in sortStringCollection(members.getKeys())) { |
| 267 » Map memberData = members[name]; | 187 Map memberData = members[name]; |
| 268 » bool unknown = !hasAny(type, name); | 188 bool unknown = !hasAny(type, name); |
| 269 » StringBuffer classes = new StringBuffer(); | 189 StringBuffer classes = new StringBuffer(); |
| 270 if (unknown) classes.add("unknown "); | 190 if (unknown) classes.add("unknown "); |
| 271 if (unknown) { | 191 if (unknown) { |
| 272 numExtraMethods++; | 192 numExtraMethods++; |
| 273 } else { | 193 } else { |
| 274 numFoundMethods++; | 194 numFoundMethods++; |
| 275 } | 195 } |
| 276 | 196 |
| 277 final sbMember = new StringBuffer(); | 197 final sbMember = new StringBuffer(); |
| 278 | 198 |
| 279 if (memberData.containsKey('url')) { | 199 if (memberData.containsKey('url')) { |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 <th>Description</th> | 416 <th>Description</th> |
| 497 <th>IDL</th> | 417 <th>IDL</th> |
| 498 <th>Status</th> | 418 <th>Status</th> |
| 499 </tr> | 419 </tr> |
| 500 $sbObsolete | 420 $sbObsolete |
| 501 </tbody> | 421 </tbody> |
| 502 </table> | 422 </table> |
| 503 </body> | 423 </body> |
| 504 </html> | 424 </html> |
| 505 """); | 425 """); |
| 506 | 426 } |
| 507 fs.writeFileSync("output/database.filtered.json", | |
| 508 JSON.stringify(filteredDb)); | |
| 509 } | |
| OLD | NEW |