Skip to content

Prevent crashes/corruption from inability to detect special objects in the right order. #1729

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
language: dart
sudo: false
dart:
- "dev/raw/latest"
- "dev/raw/2.0.0-dev.69.0"
env:
- DARTDOC_BOT=main
# TODO(devoncarew): add angulardart support
#- DARTDOC_BOT=angular
- DARTDOC_BOT=packages
- DARTDOC_BOT=flutter
- DARTDOC_BOT=sdk-docs
script: ./tool/travis.sh
Expand Down
2 changes: 0 additions & 2 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
analyzer:
strong-mode: true
language:
enableGenericMethods: true
enablePreviewDart2: true
enableSuperMixins: true
exclude:
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# BSD-style license that can be found in the LICENSE file.

install:
- ps: wget https://storage.googleapis.com/dart-archive/channels/dev/raw/latest/sdk/dartsdk-windows-x64-release.zip -OutFile dart-sdk.zip
- 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
- cmd: echo "Unzipping dart-sdk..."
- cmd: 7z x dart-sdk.zip -o"C:\tools" -y > nul
- set PATH=%PATH%;C:\tools\dart-sdk\bin
Expand Down
127 changes: 62 additions & 65 deletions lib/src/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import 'package:dartdoc/src/logging.dart';
import 'package:dartdoc/src/markdown_processor.dart' show Documentation;
import 'package:dartdoc/src/model_utils.dart';
import 'package:dartdoc/src/package_meta.dart' show PackageMeta, FileContents;
import 'package:dartdoc/src/special_elements.dart';
import 'package:dartdoc/src/utils.dart';
import 'package:dartdoc/src/warnings.dart';
import 'package:front_end/src/byte_store/byte_store.dart';
Expand Down Expand Up @@ -180,18 +181,17 @@ abstract class Inheritable implements ModelElement {
List<Class> get inheritance {
List<Class> inheritance = [];
inheritance.addAll((enclosingElement as Class).inheritanceChain);
Class object = packageGraph.specialClasses[SpecialClass.object];
if (!inheritance.contains(definingEnclosingElement) &&
definingEnclosingElement != null) {
assert(definingEnclosingElement == packageGraph.objectElement);
assert(definingEnclosingElement == object);
}
// Unless the code explicitly extends dart-core's Object, we won't get
// an entry here. So add it.
if (inheritance.last != packageGraph.objectElement &&
packageGraph.objectElement != null) {
inheritance.add(packageGraph.objectElement);
if (inheritance.last != object && object != null) {
inheritance.add(object);
}
assert(
inheritance.where((e) => e == packageGraph.objectElement).length == 1);
assert(inheritance.where((e) => e == object).length == 1);
return inheritance;
}
}
Expand Down Expand Up @@ -1629,7 +1629,7 @@ abstract class GetterSetterCombo implements ModelElement {
buffer.write('${getter.oneLineDoc}');
}
if (hasPublicSetter && setter.oneLineDoc.isNotEmpty) {
buffer.write('${getterSetterBothAvailable ? "": setter.oneLineDoc}');
buffer.write('${getterSetterBothAvailable ? "" : setter.oneLineDoc}');
}
_oneLineDoc = buffer.toString();
}
Expand Down Expand Up @@ -2587,21 +2587,6 @@ abstract class ModelElement extends Canonicalization
if (e is ClassElement) {
if (!e.isEnum) {
newModelElement = new Class(e, library, packageGraph);
if (newModelElement.name == 'Object' &&
newModelElement.library.name == 'dart:core') {
// We've found Object. This is an important object, so save it in the package.
assert(
newModelElement.library.packageGraph._objectElement == null);
newModelElement.library.packageGraph._objectElement =
newModelElement;
}
if (newModelElement.name == 'Interceptor' &&
newModelElement.library.name == 'dart:_interceptors') {
// We've found Interceptor. Another important object.
assert(!newModelElement.library.packageGraph._interceptorUsed);
newModelElement.library.packageGraph.interceptor =
newModelElement;
}
} else {
newModelElement = new Enum(e, library, packageGraph);
}
Expand Down Expand Up @@ -4017,8 +4002,19 @@ class PackageGraph {
// TODO(jcollins-g): This constructor is convoluted. Clean this up by
// building Libraries and adding them to Packages, then adding Packages
// to this graph.
PackageGraph(Iterable<LibraryElement> libraryElements, this.config,
this.packageMeta, this._packageWarningOptions, this.driver, this.sdk) {

/// Construct a package graph.
/// [libraryElements] - Libraries to be documented.
/// [specialLibraryElements] - Any libraries that may not be documented, but
/// contain required [SpecialClass]es.
PackageGraph(
Iterable<LibraryElement> libraryElements,
Iterable<LibraryElement> specialLibraryElements,
this.config,
this.packageMeta,
this._packageWarningOptions,
this.driver,
this.sdk) {
assert(_allConstructedModelElements.isEmpty);
assert(allLibraries.isEmpty);
_packageWarningCounter = new PackageWarningCounter(_packageWarningOptions);
Expand All @@ -4042,11 +4038,19 @@ class PackageGraph {
new Package.fromPackageMeta(packageMeta, this);
allLibrariesAdded = true;

// [findOrCreateLibraryFor] already adds to the proper structures.
specialLibraryElements.forEach((element) {
findOrCreateLibraryFor(element);
});

// Go through docs of every ModelElement in package to pre-build the macros
// index.
allLocalModelElements.forEach((m) => m.documentationLocal);
_macrosAdded = true;

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

SpecialClasses specialClasses;

/// It is safe to cache values derived from the _implementors table if this
/// is true.
bool allImplementorsAdded = false;
Expand Down Expand Up @@ -4497,31 +4503,6 @@ class PackageGraph {
return _localPublicLibraries;
}

// Written from ModelElement.from.
ModelElement _objectElement;

// Return the element for "Object".
ModelElement get objectElement {
assert(_objectElement != null);
return _objectElement;
}

// Don't let this be used for canonicalization before we find it.
bool _interceptorUsed = false;
Class _interceptor;

/// Return the element for "Interceptor", a Dart implementation class intended
/// to function the same as Object.
Class get interceptor {
_interceptorUsed = true;
return _interceptor;
}

set interceptor(Class newInterceptor) {
assert(_interceptorUsed == false);
_interceptor = newInterceptor;
}

// Return the set of [Class]es objects should inherit through if they
// show up in the inheritance chain. Do not call before interceptorElement is
// found. Add classes here if they are similar to Interceptor in that they
Expand All @@ -4531,7 +4512,7 @@ class PackageGraph {
Set<Class> get inheritThrough {
if (_inheritThrough == null) {
_inheritThrough = new Set();
_inheritThrough.add(interceptor);
_inheritThrough.add(specialClasses[SpecialClass.interceptor]);
}
return _inheritThrough;
}
Expand Down Expand Up @@ -4746,16 +4727,16 @@ class PackageGraph {
return foundLibrary;
}

List<ModelElement> _allModelElements;
List<ModelElement> _allLocalModelElements;
Iterable<ModelElement> get allLocalModelElements {
assert(allLibrariesAdded);
if (_allModelElements == null) {
_allModelElements = [];
if (_allLocalModelElements == null) {
_allLocalModelElements = [];
this.localLibraries.forEach((library) {
_allModelElements.addAll(library.allModelElements);
_allLocalModelElements.addAll(library.allModelElements);
});
}
return _allModelElements;
return _allLocalModelElements;
}

List<ModelElement> _allCanonicalModelElements;
Expand Down Expand Up @@ -5512,9 +5493,16 @@ class PackageBuilder {
if (packageMeta.needsPubGet) {
packageMeta.runPubGet();
}
Set<LibraryElement> libraries = await getLibraries(getFiles);
return new PackageGraph(libraries, config, config.topLevelPackageMeta,
getWarningOptions(), driver, sdk);
Set<LibraryElement> libraries = new Set();
Set<LibraryElement> specialLibraries = new Set();
DartSdk findSpecialsSdk = sdk;
if (embedderSdk != null && embedderSdk.urlMappings.isNotEmpty) {
findSpecialsSdk = embedderSdk;
}
await getLibraries(libraries, specialLibraries, getFiles,
specialLibraryFiles(findSpecialsSdk).toSet());
return new PackageGraph(libraries, specialLibraries, config,
config.topLevelPackageMeta, getWarningOptions(), driver, sdk);
}

DartSdk _sdk;
Expand Down Expand Up @@ -5711,7 +5699,8 @@ class PackageBuilder {
return metas;
}

Future<List<LibraryElement>> _parseLibraries(Set<String> files) async {
Future<List<LibraryElement>> _parseLibraries(Set<String> files,
{bool throwErrors = true}) async {
Set<LibraryElement> libraries = new Set();
Set<Source> originalSources;
Set<Source> sources = new Set<Source>();
Expand All @@ -5724,8 +5713,8 @@ class PackageBuilder {
driver.addFile(filename);
addedFiles.add(filename);
});
await Future
.wait(files.map((f) => processLibrary(f, libraries, sources)));
await Future.wait(
files.map((f) => processLibrary(f, libraries, sources)));

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

await logAnalysisErrors(originalSources);
if (throwErrors) await logAnalysisErrors(originalSources);
return libraries.toList();
}

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

Future<Set<LibraryElement>> getLibraries(Set<String> files) async {
Set<LibraryElement> libraries = new Set();
Future<void> getLibraries(
Set<LibraryElement> libraries,
Set<LibraryElement> specialLibraries,
Set<String> files,
Set<String> specialFiles) async {
libraries.addAll(await _parseLibraries(files));

/// Flutter doesn't seem to like being given the Interceptor library.
/// But it doesn't need it, either. So just skip reporting errors here.
specialLibraries.addAll(await _parseLibraries(
specialFiles.difference(files),
throwErrors: false));
if (config.include.isNotEmpty) {
Iterable knownLibraryNames = libraries.map((l) => l.name);
Set notFound = new Set.from(config.include)
Expand All @@ -5838,7 +5836,6 @@ class PackageBuilder {
}
libraries.removeWhere((lib) => !config.include.contains(lib.name));
}
return libraries;
}

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