OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /// **docgen** is a tool for creating machine readable representations of Dart | 5 /// **docgen** is a tool for creating machine readable representations of Dart |
6 /// code metadata, including: classes, members, comments and annotations. | 6 /// code metadata, including: classes, members, comments and annotations. |
7 /// | 7 /// |
8 /// docgen is run on a `.dart` file or a directory containing `.dart` files. | 8 /// docgen is run on a `.dart` file or a directory containing `.dart` files. |
9 /// | 9 /// |
10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR] | 10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR] |
(...skipping 18 matching lines...) Expand all Loading... | |
29 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart' | 29 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart' |
30 as dart2js; | 30 as dart2js; |
31 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ; | 31 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ; |
32 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util. dart' | 32 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util. dart' |
33 as dart2js_util; | 33 as dart2js_util; |
34 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; | 34 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; |
35 import '../../../sdk/lib/_internal/libraries.dart'; | 35 import '../../../sdk/lib/_internal/libraries.dart'; |
36 | 36 |
37 var logger = new Logger('Docgen'); | 37 var logger = new Logger('Docgen'); |
38 | 38 |
39 var outputDirectory = 'docs'; | |
kustermann
2013/11/18 09:57:08
Why are some other global variables a few lines do
Alan Knight
2013/11/18 20:34:50
Made it private.
| |
40 | |
39 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] fooDir/barFile'; | 41 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] fooDir/barFile'; |
40 | 42 |
41 | 43 |
42 List<String> skippedAnnotations = const [ | 44 List<String> skippedAnnotations = const [ |
43 'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates', | 45 'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates', |
44 '_js_helper.Returns']; | 46 '_js_helper.Returns']; |
45 | 47 |
46 /// Set of libraries declared in the SDK, so libraries that can be accessed | 48 /// Set of libraries declared in the SDK, so libraries that can be accessed |
47 /// when running dart by default. | 49 /// when running dart by default. |
48 Iterable<LibraryMirror> _sdkLibraries; | 50 Iterable<LibraryMirror> _sdkLibraries; |
(...skipping 18 matching lines...) Expand all Loading... | |
67 /// Resolves reference links in doc comments. | 69 /// Resolves reference links in doc comments. |
68 markdown.Resolver linkResolver; | 70 markdown.Resolver linkResolver; |
69 | 71 |
70 /// Index of all indexable items. This also ensures that no class is | 72 /// Index of all indexable items. This also ensures that no class is |
71 /// created more than once. | 73 /// created more than once. |
72 Map<String, Indexable> entityMap = new Map<String, Indexable>(); | 74 Map<String, Indexable> entityMap = new Map<String, Indexable>(); |
73 | 75 |
74 /// This is set from the command line arguments flag --include-private | 76 /// This is set from the command line arguments flag --include-private |
75 bool _includePrivate = false; | 77 bool _includePrivate = false; |
76 | 78 |
79 /// Library names to explicitly exclude. | |
80 /// | |
81 /// Set from the command line option | |
82 /// --exclude-lib. | |
83 List<String> _excluded; | |
84 | |
77 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move | 85 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move |
78 // MDN-specific code to its own library that is imported into the default impl? | 86 // MDN-specific code to its own library that is imported into the default impl? |
79 /// Map of all the comments for dom elements from MDN. | 87 /// Map of all the comments for dom elements from MDN. |
80 Map _mdn; | 88 Map _mdn; |
81 | 89 |
82 /// Docgen constructor initializes the link resolver for markdown parsing. | 90 /// Docgen constructor initializes the link resolver for markdown parsing. |
83 /// Also initializes the command line arguments. | 91 /// Also initializes the command line arguments. |
84 /// | 92 /// |
85 /// [packageRoot] is the packages directory of the directory being analyzed. | 93 /// [packageRoot] is the packages directory of the directory being analyzed. |
86 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will | 94 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will |
87 /// also be documented. | 95 /// also be documented. |
88 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented. | 96 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented. |
89 /// This option is useful when only the SDK libraries are needed. | 97 /// This option is useful when only the SDK libraries are needed. |
90 /// | 98 /// |
91 /// Returned Future completes with true if document generation is successful. | 99 /// Returned Future completes with true if document generation is successful. |
92 Future<bool> docgen(List<String> files, {String packageRoot, | 100 Future<bool> docgen(List<String> files, {String packageRoot, |
93 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false, | 101 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false, |
94 bool parseSdk: false, bool append: false, String introduction: ''}) { | 102 bool parseSdk: false, bool append: false, String introduction: '', |
103 out: 'docs', List<String> excludeLibraries}) { | |
kustermann
2013/11/18 09:57:08
It's slightly strange that we have the default val
Alan Knight
2013/11/18 20:34:50
Yes. I can't default the parameter to a variable v
| |
104 _excluded = excludeLibraries; | |
95 _includePrivate = includePrivate; | 105 _includePrivate = includePrivate; |
106 outputDirectory = out; | |
96 if (!append) { | 107 if (!append) { |
97 var dir = new Directory('docs'); | 108 var dir = new Directory(outputDirectory); |
98 if (dir.existsSync()) dir.deleteSync(recursive: true); | 109 if (dir.existsSync()) dir.deleteSync(recursive: true); |
99 } | 110 } |
100 | 111 |
101 if (packageRoot == null && !parseSdk) { | 112 if (packageRoot == null && !parseSdk) { |
102 var type = FileSystemEntity.typeSync(files.first); | 113 var type = FileSystemEntity.typeSync(files.first); |
103 if (type == FileSystemEntityType.DIRECTORY) { | 114 if (type == FileSystemEntityType.DIRECTORY) { |
104 packageRoot = _findPackageRoot(files.first); | 115 packageRoot = _findPackageRoot(files.first); |
105 } else if (type == FileSystemEntityType.FILE) { | 116 } else if (type == FileSystemEntityType.FILE) { |
106 logger.warning('WARNING: No package root defined. If Docgen fails, try ' | 117 logger.warning('WARNING: No package root defined. If Docgen fails, try ' |
107 'again by setting the --package-root option.'); | 118 'again by setting the --package-root option.'); |
108 } | 119 } |
109 } | 120 } |
110 logger.info('Package Root: ${packageRoot}'); | 121 logger.info('Package Root: ${packageRoot}'); |
111 linkResolver = (name) => | 122 linkResolver = (name) => |
112 fixReference(name, _currentLibrary, _currentClass, _currentMember); | 123 fixReference(name, _currentLibrary, _currentClass, _currentMember); |
124 var requestedLibraries = !parseSdk ? _listLibraries(files) : _listSdk(); | |
113 | 125 |
114 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) | 126 return getMirrorSystem(requestedLibraries, packageRoot: packageRoot, |
127 parseSdk: parseSdk) | |
115 .then((MirrorSystem mirrorSystem) { | 128 .then((MirrorSystem mirrorSystem) { |
116 if (mirrorSystem.libraries.isEmpty) { | 129 if (mirrorSystem.libraries.isEmpty) { |
117 throw new StateError('No library mirrors were created.'); | 130 throw new StateError('No library mirrors were created.'); |
118 } | 131 } |
119 var librariesWeAskedFor = _listLibraries(files); | 132 var availableLibraries = mirrorSystem.libraries.values.where( |
120 var librariesWeGot = mirrorSystem.libraries.values.where( | |
121 (each) => each.uri.scheme == 'file'); | 133 (each) => each.uri.scheme == 'file'); |
122 _sdkLibraries = mirrorSystem.libraries.values.where( | 134 _sdkLibraries = mirrorSystem.libraries.values.where( |
123 (each) => each.uri.scheme == 'dart'); | 135 (each) => each.uri.scheme == 'dart'); |
124 _coreLibrary = _sdkLibraries.singleWhere((lib) => | 136 _coreLibrary = _sdkLibraries.singleWhere((lib) => |
125 lib.uri.toString().startsWith('dart:core')); | 137 lib.uri.toString().startsWith('dart:core')); |
126 var librariesWeGotByPath = new Map.fromIterables( | 138 var availableLibrariesByPath = new Map.fromIterables( |
127 librariesWeGot.map((each) => each.uri.toFilePath()), | 139 availableLibraries.map((each) => each.uri.toFilePath()), |
128 librariesWeGot); | 140 availableLibraries); |
129 var librariesToDocument = librariesWeAskedFor.map( | 141 var librariesToDocument = requestedLibraries.map( |
130 (each) => librariesWeGotByPath.putIfAbsent(each, | 142 (each) => availableLibrariesByPath.putIfAbsent(each, |
131 () => throw "Missing library $each")).toList(); | 143 () => throw "Missing library $each")).toList(); |
132 librariesToDocument.addAll((includeSdk || parseSdk) ? _sdkLibraries : []); | 144 librariesToDocument.addAll((includeSdk || parseSdk) ? _sdkLibraries : []); |
145 librariesToDocument.removeWhere((x) => _excluded.contains(x.simpleName)); | |
133 _documentLibraries(librariesToDocument, includeSdk: includeSdk, | 146 _documentLibraries(librariesToDocument, includeSdk: includeSdk, |
134 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, | 147 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, |
135 introduction: introduction); | 148 introduction: introduction); |
136 return true; | 149 return true; |
137 }); | 150 }); |
138 } | 151 } |
139 | 152 |
140 /// For a library's [mirror], determine the name of the package (if any) we | 153 /// For a library's [mirror], determine the name of the package (if any) we |
141 /// believe it came from (because of its file URI). | 154 /// believe it came from (because of its file URI). |
142 /// | 155 /// |
(...skipping 28 matching lines...) Expand all Loading... | |
171 if (readmes.isEmpty) return ''; | 184 if (readmes.isEmpty) return ''; |
172 // If there are multiples, pick the shortest name. | 185 // If there are multiples, pick the shortest name. |
173 readmes.sort((a, b) => a.length.compareTo(b.length)); | 186 readmes.sort((a, b) => a.length.compareTo(b.length)); |
174 var readme = readmes.first; | 187 var readme = readmes.first; |
175 var contents = markdown.markdownToHtml(readme | 188 var contents = markdown.markdownToHtml(readme |
176 .readAsStringSync(), linkResolver: linkResolver, | 189 .readAsStringSync(), linkResolver: linkResolver, |
177 inlineSyntaxes: markdownSyntaxes); | 190 inlineSyntaxes: markdownSyntaxes); |
178 return contents; | 191 return contents; |
179 } | 192 } |
180 | 193 |
181 | |
182 List<String> _listLibraries(List<String> args) { | 194 List<String> _listLibraries(List<String> args) { |
183 var libraries = new List<String>(); | 195 var libraries = new List<String>(); |
184 for (var arg in args) { | 196 for (var arg in args) { |
185 var type = FileSystemEntity.typeSync(arg); | 197 var type = FileSystemEntity.typeSync(arg); |
186 | 198 |
187 if (type == FileSystemEntityType.FILE) { | 199 if (type == FileSystemEntityType.FILE) { |
188 if (arg.endsWith('.dart')) { | 200 if (arg.endsWith('.dart')) { |
189 libraries.add(path.absolute(arg)); | 201 libraries.add(path.absolute(arg)); |
190 logger.info('Added to libraries: ${libraries.last}'); | 202 logger.info('Added to libraries: ${libraries.last}'); |
191 } | 203 } |
(...skipping 19 matching lines...) Expand all Loading... | |
211 // Only add the file if it does not contain 'part of' | 223 // Only add the file if it does not contain 'part of' |
212 // TODO(janicejl): Remove when Issue(12406) is resolved. | 224 // TODO(janicejl): Remove when Issue(12406) is resolved. |
213 var contents = new File(f).readAsStringSync(); | 225 var contents = new File(f).readAsStringSync(); |
214 if (!(contents.contains(new RegExp('\npart of ')) || | 226 if (!(contents.contains(new RegExp('\npart of ')) || |
215 contents.startsWith(new RegExp('part of ')))) { | 227 contents.startsWith(new RegExp('part of ')))) { |
216 libraries.add(f); | 228 libraries.add(f); |
217 logger.info('Added to libraries: $f'); | 229 logger.info('Added to libraries: $f'); |
218 } | 230 } |
219 } | 231 } |
220 }); | 232 }); |
221 return libraries; | 233 return libraries.map(path.absolute).map(path.normalize).toList(); |
222 } | 234 } |
223 | 235 |
224 String _findPackageRoot(String directory) { | 236 String _findPackageRoot(String directory) { |
225 var files = listDir(directory, recursive: true); | 237 var files = listDir(directory, recursive: true); |
226 // Return '' means that there was no pubspec.yaml and therefor no packageRoot. | 238 // Return '' means that there was no pubspec.yaml and therefor no packageRoot. |
227 String packageRoot = files.firstWhere((f) => | 239 String packageRoot = files.firstWhere((f) => |
228 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); | 240 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); |
229 if (packageRoot != '') { | 241 if (packageRoot != '') { |
230 packageRoot = path.join(path.dirname(packageRoot), 'packages'); | 242 packageRoot = path.join(path.dirname(packageRoot), 'packages'); |
231 } | 243 } |
(...skipping 15 matching lines...) Expand all Loading... | |
247 if (info.documented) { | 259 if (info.documented) { |
248 sdk.add('dart:$name'); | 260 sdk.add('dart:$name'); |
249 logger.info('Add to SDK: ${sdk.last}'); | 261 logger.info('Add to SDK: ${sdk.last}'); |
250 } | 262 } |
251 }); | 263 }); |
252 return sdk; | 264 return sdk; |
253 } | 265 } |
254 | 266 |
255 /// Analyzes set of libraries by getting a mirror system and triggers the | 267 /// Analyzes set of libraries by getting a mirror system and triggers the |
256 /// documentation of the libraries. | 268 /// documentation of the libraries. |
257 Future<MirrorSystem> getMirrorSystem(List<String> args, {String packageRoot, | 269 Future<MirrorSystem> getMirrorSystem(List<String> libraries, |
258 bool parseSdk: false}) { | 270 {String packageRoot, bool parseSdk: false}) { |
259 var libraries = !parseSdk ? _listLibraries(args) : _listSdk(); | |
260 if (libraries.isEmpty) throw new StateError('No Libraries.'); | 271 if (libraries.isEmpty) throw new StateError('No Libraries.'); |
261 // Finds the root of SDK library based off the location of docgen. | 272 // Finds the root of SDK library based off the location of docgen. |
262 | 273 |
263 var root = findRootDirectory(); | 274 var root = findRootDirectory(); |
264 var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk'))); | 275 var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk'))); |
265 logger.info('SDK Root: ${sdkRoot}'); | 276 logger.info('SDK Root: ${sdkRoot}'); |
266 return _analyzeLibraries(libraries, sdkRoot, packageRoot: packageRoot); | 277 return _analyzeLibraries(libraries, sdkRoot, packageRoot: packageRoot); |
267 } | 278 } |
268 | 279 |
269 String findRootDirectory() { | 280 String findRootDirectory() { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 // Everything is a subclass of Object, therefore empty the list to avoid a | 335 // Everything is a subclass of Object, therefore empty the list to avoid a |
325 // giant list of subclasses to be printed out. | 336 // giant list of subclasses to be printed out. |
326 if (includeSdk) (entityMap['dart-core.Object'] as Class).subclasses.clear(); | 337 if (includeSdk) (entityMap['dart-core.Object'] as Class).subclasses.clear(); |
327 | 338 |
328 var filteredEntities = entityMap.values.where(_isVisible); | 339 var filteredEntities = entityMap.values.where(_isVisible); |
329 | 340 |
330 // Outputs a JSON file with all libraries and their preview comments. | 341 // Outputs a JSON file with all libraries and their preview comments. |
331 // This will help the viewer know what libraries are available to read in. | 342 // This will help the viewer know what libraries are available to read in. |
332 var libraryMap; | 343 var libraryMap; |
333 if (append) { | 344 if (append) { |
334 var docsDir = listDir('docs'); | 345 var docsDir = listDir(outputDirectory); |
335 if (!docsDir.contains('docs/library_list.json')) { | 346 if (!docsDir.contains('$outputDirectory/library_list.json')) { |
336 throw new StateError('No library_list.json'); | 347 throw new StateError('No library_list.json'); |
337 } | 348 } |
338 libraryMap = | 349 libraryMap = |
339 JSON.decode(new File('docs/library_list.json').readAsStringSync()); | 350 JSON.decode(new File('$outputDirectory/library_list.json').readAsStringS ync()); |
340 libraryMap['libraries'].addAll(filteredEntities | 351 libraryMap['libraries'].addAll(filteredEntities |
341 .where((e) => e is Library) | 352 .where((e) => e is Library) |
342 .map((e) => e.previewMap)); | 353 .map((e) => e.previewMap)); |
343 if (introduction.isNotEmpty) { | 354 if (introduction.isNotEmpty) { |
344 var intro = libraryMap['introduction']; | 355 var intro = libraryMap['introduction']; |
345 if (intro.isNotEmpty) intro += '<br/><br/>'; | 356 if (intro.isNotEmpty) intro += '<br/><br/>'; |
346 intro += markdown.markdownToHtml( | 357 intro += markdown.markdownToHtml( |
347 new File(introduction).readAsStringSync(), | 358 new File(introduction).readAsStringSync(), |
348 linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes); | 359 linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes); |
349 libraryMap['introduction'] = intro; | 360 libraryMap['introduction'] = intro; |
(...skipping 20 matching lines...) Expand all Loading... | |
370 // Outputs all the qualified names documented with their type. | 381 // Outputs all the qualified names documented with their type. |
371 // This will help generate search results. | 382 // This will help generate search results. |
372 _writeToFile(filteredEntities.map((e) => | 383 _writeToFile(filteredEntities.map((e) => |
373 '${e.qualifiedName} ${e.typeName}').join('\n') + '\n', | 384 '${e.qualifiedName} ${e.typeName}').join('\n') + '\n', |
374 'index.txt', append: append); | 385 'index.txt', append: append); |
375 var index = new Map.fromIterables( | 386 var index = new Map.fromIterables( |
376 filteredEntities.map((e) => e.qualifiedName), | 387 filteredEntities.map((e) => e.qualifiedName), |
377 filteredEntities.map((e) => e.typeName)); | 388 filteredEntities.map((e) => e.typeName)); |
378 if (append) { | 389 if (append) { |
379 var previousIndex = | 390 var previousIndex = |
380 JSON.decode(new File('docs/index.json').readAsStringSync()); | 391 JSON.decode(new File('$outputDirectory/index.json').readAsStringSync()); |
381 index.addAll(previousIndex); | 392 index.addAll(previousIndex); |
382 } | 393 } |
383 _writeToFile(JSON.encode(index), 'index.json'); | 394 _writeToFile(JSON.encode(index), 'index.json'); |
384 } | 395 } |
385 | 396 |
386 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { | 397 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { |
387 _currentLibrary = library; | 398 _currentLibrary = library; |
388 var result = new Library(docName(library), _commentToHtml(library), | 399 var result = new Library(docName(library), _commentToHtml(library), |
389 _classes(library.classes), | 400 _classes(library.classes), |
390 _methods(library.functions), | 401 _methods(library.functions), |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
765 if (mirror is ClassMirror && !mirror.isTypedef) { | 776 if (mirror is ClassMirror && !mirror.isTypedef) { |
766 var innerList = []; | 777 var innerList = []; |
767 mirror.typeArguments.forEach((e) { | 778 mirror.typeArguments.forEach((e) { |
768 innerList.add(new Type(docName(e), _typeGenerics(e))); | 779 innerList.add(new Type(docName(e), _typeGenerics(e))); |
769 }); | 780 }); |
770 return innerList; | 781 return innerList; |
771 } | 782 } |
772 return []; | 783 return []; |
773 } | 784 } |
774 | 785 |
775 /// Writes text to a file in the 'docs' directory. | 786 /// Writes text to a file in the output directory. |
776 void _writeToFile(String text, String filename, {bool append: false}) { | 787 void _writeToFile(String text, String filename, {bool append: false}) { |
777 Directory dir = new Directory('docs'); | 788 if (text == null) return; |
789 Directory dir = new Directory(outputDirectory); | |
778 if (!dir.existsSync()) { | 790 if (!dir.existsSync()) { |
779 dir.createSync(); | 791 dir.createSync(); |
780 } | 792 } |
781 // We assume there's a single extra level of directory structure for packages. | 793 // We assume there's a single extra level of directory structure for packages. |
782 if (path.split(filename).length > 1) { | 794 if (path.split(filename).length > 1) { |
783 var subdir = new Directory(path.join('docs', path.dirname(filename))); | 795 var subdir = new Directory(path.join(outputDirectory, path.dirname(filename) )); |
784 if (!subdir.existsSync()) { | 796 if (!subdir.existsSync()) { |
785 subdir.createSync(); | 797 subdir.createSync(); |
786 } | 798 } |
787 } | 799 } |
788 | 800 File file = new File(path.join(outputDirectory, filename)); |
789 File file = new File('docs/$filename'); | |
790 if (!file.existsSync()) { | |
791 file.createSync(); | |
792 } | |
793 file.writeAsStringSync(text, mode: append ? FileMode.APPEND : FileMode.WRITE); | 801 file.writeAsStringSync(text, mode: append ? FileMode.APPEND : FileMode.WRITE); |
794 } | 802 } |
795 | 803 |
796 /// Transforms the map by calling toMap on each value in it. | 804 /// Transforms the map by calling toMap on each value in it. |
797 Map recurseMap(Map inputMap) { | 805 Map recurseMap(Map inputMap) { |
798 var outputMap = {}; | 806 var outputMap = {}; |
799 inputMap.forEach((key, value) { | 807 inputMap.forEach((key, value) { |
800 if (value is Map) { | 808 if (value is Map) { |
801 outputMap[key] = recurseMap(value); | 809 outputMap[key] = recurseMap(value); |
802 } else { | 810 } else { |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1396 /// Remove statics from the map of inherited items before adding them. | 1404 /// Remove statics from the map of inherited items before adding them. |
1397 Map _filterStatics(Map items) { | 1405 Map _filterStatics(Map items) { |
1398 var result = {}; | 1406 var result = {}; |
1399 items.forEach((name, item) { | 1407 items.forEach((name, item) { |
1400 if (!item.isStatic) { | 1408 if (!item.isStatic) { |
1401 result[name] = item; | 1409 result[name] = item; |
1402 } | 1410 } |
1403 }); | 1411 }); |
1404 return result; | 1412 return result; |
1405 } | 1413 } |
OLD | NEW |