6
6
library dartdoc;
7
7
8
8
import 'dart:async' ;
9
+ import 'dart:convert' ;
9
10
import 'dart:io' ;
10
11
11
12
import 'package:analyzer/dart/element/element.dart' show LibraryElement;
@@ -214,45 +215,61 @@ class DartDoc {
214
215
return new DartDocResults (packageMeta, package, outputDir);
215
216
}
216
217
217
- void _warn (Package package, PackageWarning kind, String p, String origin,
218
- {String source}) {
218
+ /// Warn on file paths.
219
+ void _warn (Package package, PackageWarning kind, String warnOn, String origin,
220
+ {String referredFrom}) {
219
221
// Ordinarily this would go in [Package.warn], but we don't actually know what
220
222
// ModelElement to warn on yet.
221
- Locatable referenceElement;
222
- Set <Locatable > referenceElements;
223
+ Locatable referredFromElement;
224
+ Locatable warnOnElement;
225
+ Set <Locatable > referredFromElements;
226
+ Set <Locatable > warnOnElements;
223
227
224
228
// Make all paths relative to origin.
225
- if (path.isWithin (origin, p )) {
226
- p = path.relative (p , from: origin);
229
+ if (path.isWithin (origin, warnOn )) {
230
+ warnOn = path.relative (warnOn , from: origin);
227
231
}
228
- if (source != null ) {
229
- if (path.isWithin (origin, source )) {
230
- source = path.relative (source , from: origin);
232
+ if (referredFrom != null ) {
233
+ if (path.isWithin (origin, referredFrom )) {
234
+ referredFrom = path.relative (referredFrom , from: origin);
231
235
}
232
236
// Source paths are always relative.
233
- referenceElements = package.allHrefs[source];
234
- } else {
235
- referenceElements = package.allHrefs[p];
237
+ referredFromElements = _hrefs[referredFrom];
238
+ }
239
+ warnOnElements = _hrefs[warnOn];
240
+
241
+ if (referredFromElements != null ) {
242
+ if (referredFromElements.any ((e) => e.isCanonical)) {
243
+ referredFromElement =
244
+ referredFromElements.firstWhere ((e) => e.isCanonical);
245
+ } else {
246
+ // If we don't have a canonical element, just pick one.
247
+ referredFromElement =
248
+ referredFromElements.isEmpty ? null : referredFromElements.first;
249
+ }
236
250
}
237
- if (referenceElements != null ) {
238
- if (referenceElements .any ((e) => e.isCanonical)) {
239
- referenceElement = referenceElements .firstWhere ((e) => e.isCanonical);
251
+ if (warnOnElements != null ) {
252
+ if (warnOnElements .any ((e) => e.isCanonical)) {
253
+ warnOnElement = warnOnElements .firstWhere ((e) => e.isCanonical);
240
254
} else {
241
255
// If we don't have a canonical element, just pick one.
242
- referenceElement =
243
- referenceElements.isEmpty ? null : referenceElements.first;
256
+ warnOnElement = warnOnElements.isEmpty ? null : warnOnElements.first;
244
257
}
245
258
}
246
- if (referenceElement == null && source == 'index.html' )
247
- referenceElement = package;
248
- package.warnOnElement (referenceElement, kind, message: p);
259
+
260
+ if (referredFromElement == null && referredFrom == 'index.html' )
261
+ referredFromElement = package;
262
+ String message = warnOn;
263
+ if (referredFrom == 'index.json' ) message = '$warnOn (from index.json)' ;
264
+ package.warnOnElement (warnOnElement, kind,
265
+ message: message, referredFrom: referredFromElement);
249
266
}
250
267
251
268
void _doOrphanCheck (Package package, String origin, Set <String > visited) {
252
269
String normalOrigin = path.normalize (origin);
253
270
String staticAssets = path.joinAll ([normalOrigin, 'static-assets' , '' ]);
254
271
String indexJson = path.joinAll ([normalOrigin, 'index.json' ]);
255
- bool foundIndex = false ;
272
+ bool foundIndexJson = false ;
256
273
for (FileSystemEntity f
257
274
in new Directory (normalOrigin).listSync (recursive: true )) {
258
275
var fullPath = path.normalize (f.path);
@@ -263,7 +280,7 @@ class DartDoc {
263
280
continue ;
264
281
}
265
282
if (fullPath == indexJson) {
266
- foundIndex = true ;
283
+ foundIndexJson = true ;
267
284
_onCheckProgress.add (fullPath);
268
285
continue ;
269
286
}
@@ -277,7 +294,7 @@ class DartDoc {
277
294
_onCheckProgress.add (fullPath);
278
295
}
279
296
280
- if (! foundIndex ) {
297
+ if (! foundIndexJson ) {
281
298
_warn (package, PackageWarning .brokenLink, indexJson, normalOrigin);
282
299
_onCheckProgress.add (indexJson);
283
300
}
@@ -305,6 +322,42 @@ class DartDoc {
305
322
return new Tuple2 (stringLinks, baseHref);
306
323
}
307
324
325
+ void _doSearchIndexCheck (
326
+ Package package, String origin, Set <String > visited) {
327
+ String fullPath = path.joinAll ([origin, 'index.json' ]);
328
+ String indexPath = path.joinAll ([origin, 'index.html' ]);
329
+ File file = new File ("$fullPath " );
330
+ if (! file.existsSync ()) {
331
+ return null ;
332
+ }
333
+ JsonDecoder decoder = new JsonDecoder ();
334
+ List jsonData = decoder.convert (file.readAsStringSync ());
335
+
336
+ Set <String > found = new Set ();
337
+ found.add (fullPath);
338
+ // The package index isn't supposed to be in the search, so suppress the
339
+ // warning.
340
+ found.add (indexPath);
341
+ for (Map <String , String > entry in jsonData) {
342
+ if (entry.containsKey ('href' )) {
343
+ String entryPath = path.joinAll ([origin, entry['href' ]]);
344
+ if (! visited.contains (entryPath)) {
345
+ _warn (package, PackageWarning .brokenLink, entryPath,
346
+ path.normalize (origin),
347
+ referredFrom: fullPath);
348
+ }
349
+ found.add (entryPath);
350
+ }
351
+ }
352
+ // Missing from search index
353
+ Set <String > missing_from_search = visited.difference (found);
354
+ for (String s in missing_from_search) {
355
+ _warn (package, PackageWarning .missingFromSearchIndex, s,
356
+ path.normalize (origin),
357
+ referredFrom: fullPath);
358
+ }
359
+ }
360
+
308
361
void _doCheck (
309
362
Package package, String origin, Set <String > visited, String pathToCheck,
310
363
[String source, String fullPath]) {
@@ -313,15 +366,15 @@ class DartDoc {
313
366
fullPath = path.normalize (fullPath);
314
367
}
315
368
316
- visited.add (fullPath);
317
369
Tuple2 stringLinksAndHref = _getStringLinksAndHref (fullPath);
318
370
if (stringLinksAndHref == null ) {
319
371
_warn (package, PackageWarning .brokenLink, pathToCheck,
320
372
path.normalize (origin),
321
- source : source);
373
+ referredFrom : source);
322
374
_onCheckProgress.add (pathToCheck);
323
375
return null ;
324
376
}
377
+ visited.add (fullPath);
325
378
Iterable <String > stringLinks = stringLinksAndHref.item1;
326
379
String baseHref = stringLinksAndHref.item2;
327
380
@@ -355,10 +408,10 @@ class DartDoc {
355
408
356
409
final Set <String > visited = new Set ();
357
410
final String start = 'index.html' ;
358
- visited.add (start);
359
411
stdout.write ('\n validating docs...' );
360
412
_doCheck (package, origin, visited, start);
361
413
_doOrphanCheck (package, origin, visited);
414
+ _doSearchIndexCheck (package, origin, visited);
362
415
}
363
416
364
417
List <LibraryElement > _parseLibraries (
0 commit comments