Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Unified Diff: pkg/docgen/lib/src/models/class.dart

Issue 242363004: pkg/docgen: moved model classes into minilibs (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/docgen/lib/src/models/class.dart
diff --git a/pkg/docgen/lib/src/models/class.dart b/pkg/docgen/lib/src/models/class.dart
new file mode 100644
index 0000000000000000000000000000000000000000..b58119cfb3b0ac0030e2cbc467f7d47a9e97e274
--- /dev/null
+++ b/pkg/docgen/lib/src/models/class.dart
@@ -0,0 +1,246 @@
+library docgen.models.class_indexable;
kevmoo 2014/04/18 17:03:18 Analyzer does not like a library sub-unit named 'c
Siggi Cherem (dart-lang) 2014/04/18 22:20:08 The name class_indexable is a bit strange. Some ot
kevmoo 2014/04/18 22:36:43 Done.
+
+import '../exports/dart2js_mirrors.dart' as dart2js_mirrors;
+import '../exports/mirrors_util.dart' as dart2js_util;
+import '../exports/source_mirrors.dart';
+
+import '../library_helpers.dart';
+
+import 'dummy_mirror.dart';
+import 'generic.dart';
+import 'indexable.dart';
+import 'library.dart';
+import 'method.dart';
+import 'model_helpers.dart';
+import 'owned_indexable.dart';
+import 'variable.dart';
+
+/// A class containing contents of a Dart class.
+class Class extends OwnedIndexable<dart2js_mirrors.Dart2JsInterfaceTypeMirror>
+ implements Comparable<Class> {
+
+ /// List of the names of interfaces that this class implements.
+ List<Class> interfaces = [];
+
+ /// Names of classes that extends or implements this class.
+ Set<Class> subclasses = new Set<Class>();
+
+ /// Top-level variables in the class.
+ Map<String, Variable> variables;
+
+ /// Inherited variables in the class.
+ final Map<String, Variable> inheritedVariables = {};
+
+ /// Methods in the class.
+ Map<String, Method> methods;
+
+ final Map<String, Method> inheritedMethods = new Map<String, Method>();
+
+ /// Generic infomation about the class.
+ final Map<String, Generic> generics;
+
+ Class superclass;
+ bool get isAbstract => mirror.isAbstract;
+
+ /// Make sure that we don't check for inherited comments more than once.
+ bool _commentsEnsured = false;
+
+ /// Returns the [Class] for the given [mirror] if it has already been created,
+ /// else creates it.
+ factory Class(ClassMirror mirror, Library owner) {
+ var clazz = getDocgenObject(mirror, owner);
+ if (clazz is DummyMirror) {
+ clazz = new Class._(mirror, owner);
+ }
+ return clazz;
+ }
+
+ /// Called when we are constructing a superclass or interface class, but it
+ /// is not known if it belongs to the same owner as the original class. In
+ /// this case, we create an object whose owner is what the original mirror
+ /// says it is.
+ factory Class._possiblyDifferentOwner(ClassMirror mirror,
+ Library originalOwner) {
+ if (mirror.owner is LibraryMirror) {
+ var realOwner = getDocgenObject(mirror.owner);
+ if (realOwner is Library) {
+ return new Class(mirror, realOwner);
+ } else {
+ return new Class(mirror, originalOwner);
+ }
+ } else {
+ return new Class(mirror, originalOwner);
+ }
+ }
+
+ Class._(ClassSourceMirror classMirror, Indexable owner)
+ : generics = createGenerics(classMirror),
+ super(classMirror, owner) {
+
+ // The reason we do this madness is the superclass and interface owners may
+ // not be this class's owner!! Example: BaseClient in http pkg.
+ var superinterfaces = classMirror.superinterfaces.map(
+ (interface) => new Class._possiblyDifferentOwner(interface, owner));
+ this.superclass = classMirror.superclass == null? null :
+ new Class._possiblyDifferentOwner(classMirror.superclass, owner);
+
+ interfaces = superinterfaces.toList();
+ variables = createVariables(
+ dart2js_util.variablesOf(classMirror.declarations), this);
+ methods = createMethods(classMirror.declarations.values.where(
+ (mirror) => mirror is MethodMirror), this);
+
+ // Tell superclass that you are a subclass, unless you are not
+ // visible or an intermediary mixin class.
+ if (!classMirror.isNameSynthetic && isVisible && superclass != null) {
+ superclass.addSubclass(this);
+ }
+
+ if (this.superclass != null) addInherited(superclass);
+ interfaces.forEach((interface) => addInherited(interface));
+ }
+
+ String _lookupInClassAndSuperclasses(String name) {
+ var lookupFunc = determineLookupFunc(name);
+ var classScope = this;
+ while (classScope != null) {
+ var classFunc = lookupFunc(classScope.mirror, name);
+ if (classFunc != null) {
+ return packagePrefix + getDocgenObject(classFunc, owner).docName;
+ }
+ classScope = classScope.superclass;
+ }
+ return null;
+ }
+
+ /// Look for the specified name starting with the current member, and
+ /// progressively working outward to the current library scope.
+ String findElementInScope(String name) {
+ var lookupFunc = determineLookupFunc(name);
+ var result = _lookupInClassAndSuperclasses(name);
+ if (result != null) {
+ return result;
+ }
+ result = owner.findElementInScope(name);
+ return result == null ? super.findElementInScope(name) : result;
+ }
+
+ String get typeName => 'class';
+
+ /// Add all inherited variables and methods from the provided superclass.
+ /// If [_includePrivate] is true, it also adds the variables and methods from
+ /// the superclass.
+ void addInherited(Class superclass) {
+ inheritedVariables.addAll(superclass.inheritedVariables);
+ inheritedVariables.addAll(_allButStatics(superclass.variables));
+ addInheritedMethod(superclass, this);
+ }
+
+ /** [newParent] refers to the actual class is currently using these methods.
+ * which may be different because with the mirror system, we only point to the
+ * original canonical superclasse's method.
+ */
+ void addInheritedMethod(Class parent, Class newParent) {
+ parent.inheritedMethods.forEach((name, method) {
+ if (!method.mirror.isConstructor) {
+ inheritedMethods[name] = new Method(method.mirror, newParent, method);
+ }
+ });
+ _allButStatics(parent.methods).forEach((name, method) {
+ if (!method.mirror.isConstructor) {
+ inheritedMethods[name] = new Method(method.mirror, newParent, method);
+ }
+ });
+ }
+
+ /// Remove statics from the map of inherited items before adding them.
+ Map _allButStatics(Map items) {
+ var result = {};
+ items.forEach((name, item) {
+ if (!item.isStatic) {
+ result[name] = item;
+ }
+ });
+ return result;
+ }
+
+ /// Add the subclass to the class.
+ ///
+ /// If [this] is private (or an intermediary mixin class), it will add the
+ /// subclass to the list of subclasses in the superclasses.
+ void addSubclass(Class subclass) {
+ if (docName == 'dart-core.Object') return;
+
+ if (!includePrivateMembers && isPrivate || mirror.isNameSynthetic) {
+ if (superclass != null) superclass.addSubclass(subclass);
+ interfaces.forEach((interface) {
+ interface.addSubclass(subclass);
+ });
+ } else {
+ subclasses.add(subclass);
+ }
+ }
+
+ /// Check if this [Class] is an error or exception.
+ bool isError() {
+ if (qualifiedName == 'dart-core.Error' ||
+ qualifiedName == 'dart-core.Exception')
+ return true;
+ for (var interface in interfaces) {
+ if (interface.isError()) return true;
+ }
+ if (superclass == null) return false;
+ return superclass.isError();
+ }
+
+ /// Makes sure that all methods with inherited equivalents have comments.
+ void ensureComments() {
+ if (_commentsEnsured) return;
+ _commentsEnsured = true;
+ if (superclass != null) superclass.ensureComments();
+ inheritedMethods.forEach((qualifiedName, inheritedMethod) {
+ var method = methods[qualifiedName];
+ if (method != null) {
+ // if we have overwritten this method in this class, we still provide
+ // the opportunity to inherit the comments.
+ method.ensureCommentFor(inheritedMethod);
+ }
+ });
+ // we need to populate the comments for all methods. so that the subclasses
+ // can get for their inherited versions the comments.
+ methods.forEach((qualifiedName, method) {
+ if (!method.mirror.isConstructor) method.ensureCommentFor(method);
+ });
+ }
+
+ /// If a class extends a private superclass, find the closest public
+ /// superclass of the private superclass.
+ String validSuperclass() {
+ if (superclass == null) return 'dart-core.Object';
+ if (superclass.isVisible) return superclass.qualifiedName;
+ return superclass.validSuperclass();
+ }
+
+ /// Generates a map describing the [Class] object.
+ Map toMap() => {
+ 'name': name,
+ 'qualifiedName': qualifiedName,
+ 'comment': comment,
+ 'isAbstract' : isAbstract,
+ 'superclass': validSuperclass(),
+ 'implements': interfaces.where((i) => i.isVisible)
+ .map((e) => e.qualifiedName).toList(),
+ 'subclass': (subclasses.toList()..sort())
+ .map((x) => x.qualifiedName).toList(),
+ 'variables': recurseMap(variables),
+ 'inheritedVariables': recurseMap(inheritedVariables),
+ 'methods': expandMethodMap(methods),
+ 'inheritedMethods': expandMethodMap(inheritedMethods),
+ 'annotations': annotations.map((a) => a.toMap()).toList(),
+ 'generics': recurseMap(generics)
+ };
+
+ int compareTo(Class other) => name.compareTo(other.name);
+
+ bool isValidMirror(DeclarationMirror mirror) => mirror is ClassMirror;
+}

Powered by Google App Engine
This is Rietveld 408576698