Skip to content

Commit 30183b4

Browse files
authored
Prevent crashes/corruption from inability to detect special objects in the right order. (#1729)
* dartfmt * Fix crash in angular, rearrange special object handling, and test angular doc builds * dartfmt * Pin to .69 until other changes go through * Pin appveyor too * Fix CI typos * Fix problem with embeddeders that don't provide Interceptor (mark it optional) * Fix Flutter analysis errors from forced-load Interceptor attempt * Check for null embedder sdk
1 parent 19134e5 commit 30183b4

13 files changed

+227
-88
lines changed

.travis.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
language: dart
22
sudo: false
33
dart:
4-
- "dev/raw/latest"
4+
- "dev/raw/2.0.0-dev.69.0"
55
env:
66
- DARTDOC_BOT=main
7-
# TODO(devoncarew): add angulardart support
8-
#- DARTDOC_BOT=angular
7+
- DARTDOC_BOT=packages
98
- DARTDOC_BOT=flutter
109
- DARTDOC_BOT=sdk-docs
1110
script: ./tool/travis.sh

analysis_options.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
analyzer:
2-
strong-mode: true
32
language:
4-
enableGenericMethods: true
53
enablePreviewDart2: true
64
enableSuperMixins: true
75
exclude:

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# BSD-style license that can be found in the LICENSE file.
44

55
install:
6-
- ps: wget https://storage.googleapis.com/dart-archive/channels/dev/raw/latest/sdk/dartsdk-windows-x64-release.zip -OutFile dart-sdk.zip
6+
- ps: wget https://storage.googleapis.com/dart-archive/channels/dev/raw/2.0.0-dev.69.0/sdk/dartsdk-windows-x64-release.zip -OutFile dart-sdk.zip
77
- cmd: echo "Unzipping dart-sdk..."
88
- cmd: 7z x dart-sdk.zip -o"C:\tools" -y > nul
99
- set PATH=%PATH%;C:\tools\dart-sdk\bin

lib/src/model.dart

Lines changed: 62 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import 'package:dartdoc/src/logging.dart';
4444
import 'package:dartdoc/src/markdown_processor.dart' show Documentation;
4545
import 'package:dartdoc/src/model_utils.dart';
4646
import 'package:dartdoc/src/package_meta.dart' show PackageMeta, FileContents;
47+
import 'package:dartdoc/src/special_elements.dart';
4748
import 'package:dartdoc/src/utils.dart';
4849
import 'package:dartdoc/src/warnings.dart';
4950
import 'package:front_end/src/byte_store/byte_store.dart';
@@ -180,18 +181,17 @@ abstract class Inheritable implements ModelElement {
180181
List<Class> get inheritance {
181182
List<Class> inheritance = [];
182183
inheritance.addAll((enclosingElement as Class).inheritanceChain);
184+
Class object = packageGraph.specialClasses[SpecialClass.object];
183185
if (!inheritance.contains(definingEnclosingElement) &&
184186
definingEnclosingElement != null) {
185-
assert(definingEnclosingElement == packageGraph.objectElement);
187+
assert(definingEnclosingElement == object);
186188
}
187189
// Unless the code explicitly extends dart-core's Object, we won't get
188190
// an entry here. So add it.
189-
if (inheritance.last != packageGraph.objectElement &&
190-
packageGraph.objectElement != null) {
191-
inheritance.add(packageGraph.objectElement);
191+
if (inheritance.last != object && object != null) {
192+
inheritance.add(object);
192193
}
193-
assert(
194-
inheritance.where((e) => e == packageGraph.objectElement).length == 1);
194+
assert(inheritance.where((e) => e == object).length == 1);
195195
return inheritance;
196196
}
197197
}
@@ -1629,7 +1629,7 @@ abstract class GetterSetterCombo implements ModelElement {
16291629
buffer.write('${getter.oneLineDoc}');
16301630
}
16311631
if (hasPublicSetter && setter.oneLineDoc.isNotEmpty) {
1632-
buffer.write('${getterSetterBothAvailable ? "": setter.oneLineDoc}');
1632+
buffer.write('${getterSetterBothAvailable ? "" : setter.oneLineDoc}');
16331633
}
16341634
_oneLineDoc = buffer.toString();
16351635
}
@@ -2587,21 +2587,6 @@ abstract class ModelElement extends Canonicalization
25872587
if (e is ClassElement) {
25882588
if (!e.isEnum) {
25892589
newModelElement = new Class(e, library, packageGraph);
2590-
if (newModelElement.name == 'Object' &&
2591-
newModelElement.library.name == 'dart:core') {
2592-
// We've found Object. This is an important object, so save it in the package.
2593-
assert(
2594-
newModelElement.library.packageGraph._objectElement == null);
2595-
newModelElement.library.packageGraph._objectElement =
2596-
newModelElement;
2597-
}
2598-
if (newModelElement.name == 'Interceptor' &&
2599-
newModelElement.library.name == 'dart:_interceptors') {
2600-
// We've found Interceptor. Another important object.
2601-
assert(!newModelElement.library.packageGraph._interceptorUsed);
2602-
newModelElement.library.packageGraph.interceptor =
2603-
newModelElement;
2604-
}
26052590
} else {
26062591
newModelElement = new Enum(e, library, packageGraph);
26072592
}
@@ -4017,8 +4002,19 @@ class PackageGraph {
40174002
// TODO(jcollins-g): This constructor is convoluted. Clean this up by
40184003
// building Libraries and adding them to Packages, then adding Packages
40194004
// to this graph.
4020-
PackageGraph(Iterable<LibraryElement> libraryElements, this.config,
4021-
this.packageMeta, this._packageWarningOptions, this.driver, this.sdk) {
4005+
4006+
/// Construct a package graph.
4007+
/// [libraryElements] - Libraries to be documented.
4008+
/// [specialLibraryElements] - Any libraries that may not be documented, but
4009+
/// contain required [SpecialClass]es.
4010+
PackageGraph(
4011+
Iterable<LibraryElement> libraryElements,
4012+
Iterable<LibraryElement> specialLibraryElements,
4013+
this.config,
4014+
this.packageMeta,
4015+
this._packageWarningOptions,
4016+
this.driver,
4017+
this.sdk) {
40224018
assert(_allConstructedModelElements.isEmpty);
40234019
assert(allLibraries.isEmpty);
40244020
_packageWarningCounter = new PackageWarningCounter(_packageWarningOptions);
@@ -4042,11 +4038,19 @@ class PackageGraph {
40424038
new Package.fromPackageMeta(packageMeta, this);
40434039
allLibrariesAdded = true;
40444040

4041+
// [findOrCreateLibraryFor] already adds to the proper structures.
4042+
specialLibraryElements.forEach((element) {
4043+
findOrCreateLibraryFor(element);
4044+
});
4045+
40454046
// Go through docs of every ModelElement in package to pre-build the macros
40464047
// index.
40474048
allLocalModelElements.forEach((m) => m.documentationLocal);
40484049
_macrosAdded = true;
40494050

4051+
// Scan all model elements to insure that interceptor and other special
4052+
// objects are found.
4053+
specialClasses = new SpecialClasses(this);
40504054
// After the allModelElements traversal to be sure that all packages
40514055
// are picked up.
40524056
documentedPackages.toList().forEach((package) {
@@ -4059,6 +4063,8 @@ class PackageGraph {
40594063
allImplementorsAdded = true;
40604064
}
40614065

4066+
SpecialClasses specialClasses;
4067+
40624068
/// It is safe to cache values derived from the _implementors table if this
40634069
/// is true.
40644070
bool allImplementorsAdded = false;
@@ -4497,31 +4503,6 @@ class PackageGraph {
44974503
return _localPublicLibraries;
44984504
}
44994505

4500-
// Written from ModelElement.from.
4501-
ModelElement _objectElement;
4502-
4503-
// Return the element for "Object".
4504-
ModelElement get objectElement {
4505-
assert(_objectElement != null);
4506-
return _objectElement;
4507-
}
4508-
4509-
// Don't let this be used for canonicalization before we find it.
4510-
bool _interceptorUsed = false;
4511-
Class _interceptor;
4512-
4513-
/// Return the element for "Interceptor", a Dart implementation class intended
4514-
/// to function the same as Object.
4515-
Class get interceptor {
4516-
_interceptorUsed = true;
4517-
return _interceptor;
4518-
}
4519-
4520-
set interceptor(Class newInterceptor) {
4521-
assert(_interceptorUsed == false);
4522-
_interceptor = newInterceptor;
4523-
}
4524-
45254506
// Return the set of [Class]es objects should inherit through if they
45264507
// show up in the inheritance chain. Do not call before interceptorElement is
45274508
// found. Add classes here if they are similar to Interceptor in that they
@@ -4531,7 +4512,7 @@ class PackageGraph {
45314512
Set<Class> get inheritThrough {
45324513
if (_inheritThrough == null) {
45334514
_inheritThrough = new Set();
4534-
_inheritThrough.add(interceptor);
4515+
_inheritThrough.add(specialClasses[SpecialClass.interceptor]);
45354516
}
45364517
return _inheritThrough;
45374518
}
@@ -4746,16 +4727,16 @@ class PackageGraph {
47464727
return foundLibrary;
47474728
}
47484729

4749-
List<ModelElement> _allModelElements;
4730+
List<ModelElement> _allLocalModelElements;
47504731
Iterable<ModelElement> get allLocalModelElements {
47514732
assert(allLibrariesAdded);
4752-
if (_allModelElements == null) {
4753-
_allModelElements = [];
4733+
if (_allLocalModelElements == null) {
4734+
_allLocalModelElements = [];
47544735
this.localLibraries.forEach((library) {
4755-
_allModelElements.addAll(library.allModelElements);
4736+
_allLocalModelElements.addAll(library.allModelElements);
47564737
});
47574738
}
4758-
return _allModelElements;
4739+
return _allLocalModelElements;
47594740
}
47604741

47614742
List<ModelElement> _allCanonicalModelElements;
@@ -5512,9 +5493,16 @@ class PackageBuilder {
55125493
if (packageMeta.needsPubGet) {
55135494
packageMeta.runPubGet();
55145495
}
5515-
Set<LibraryElement> libraries = await getLibraries(getFiles);
5516-
return new PackageGraph(libraries, config, config.topLevelPackageMeta,
5517-
getWarningOptions(), driver, sdk);
5496+
Set<LibraryElement> libraries = new Set();
5497+
Set<LibraryElement> specialLibraries = new Set();
5498+
DartSdk findSpecialsSdk = sdk;
5499+
if (embedderSdk != null && embedderSdk.urlMappings.isNotEmpty) {
5500+
findSpecialsSdk = embedderSdk;
5501+
}
5502+
await getLibraries(libraries, specialLibraries, getFiles,
5503+
specialLibraryFiles(findSpecialsSdk).toSet());
5504+
return new PackageGraph(libraries, specialLibraries, config,
5505+
config.topLevelPackageMeta, getWarningOptions(), driver, sdk);
55185506
}
55195507

55205508
DartSdk _sdk;
@@ -5711,7 +5699,8 @@ class PackageBuilder {
57115699
return metas;
57125700
}
57135701

5714-
Future<List<LibraryElement>> _parseLibraries(Set<String> files) async {
5702+
Future<List<LibraryElement>> _parseLibraries(Set<String> files,
5703+
{bool throwErrors = true}) async {
57155704
Set<LibraryElement> libraries = new Set();
57165705
Set<Source> originalSources;
57175706
Set<Source> sources = new Set<Source>();
@@ -5724,8 +5713,8 @@ class PackageBuilder {
57245713
driver.addFile(filename);
57255714
addedFiles.add(filename);
57265715
});
5727-
await Future
5728-
.wait(files.map((f) => processLibrary(f, libraries, sources)));
5716+
await Future.wait(
5717+
files.map((f) => processLibrary(f, libraries, sources)));
57295718

57305719
/// We don't care about upstream analysis errors, so save the first
57315720
/// source list.
@@ -5747,7 +5736,7 @@ class PackageBuilder {
57475736
}
57485737
} while (!lastPass.containsAll(current));
57495738

5750-
await logAnalysisErrors(originalSources);
5739+
if (throwErrors) await logAnalysisErrors(originalSources);
57515740
return libraries.toList();
57525741
}
57535742

@@ -5824,9 +5813,18 @@ class PackageBuilder {
58245813
return new Set.from(files.map((s) => new File(s).absolute.path));
58255814
}
58265815

5827-
Future<Set<LibraryElement>> getLibraries(Set<String> files) async {
5828-
Set<LibraryElement> libraries = new Set();
5816+
Future<void> getLibraries(
5817+
Set<LibraryElement> libraries,
5818+
Set<LibraryElement> specialLibraries,
5819+
Set<String> files,
5820+
Set<String> specialFiles) async {
58295821
libraries.addAll(await _parseLibraries(files));
5822+
5823+
/// Flutter doesn't seem to like being given the Interceptor library.
5824+
/// But it doesn't need it, either. So just skip reporting errors here.
5825+
specialLibraries.addAll(await _parseLibraries(
5826+
specialFiles.difference(files),
5827+
throwErrors: false));
58305828
if (config.include.isNotEmpty) {
58315829
Iterable knownLibraryNames = libraries.map((l) => l.name);
58325830
Set notFound = new Set.from(config.include)
@@ -5838,7 +5836,6 @@ class PackageBuilder {
58385836
}
58395837
libraries.removeWhere((lib) => !config.include.contains(lib.name));
58405838
}
5841-
return libraries;
58425839
}
58435840

58445841
/// If [dir] contains both a `lib` directory and a `pubspec.yaml` file treat

0 commit comments

Comments
 (0)