Skip to content

Commit 8ff3d14

Browse files
authored
Enable strong mode in Dartdoc (#1611)
* First version of the strong mode change, before refactoring * Basic refactor eliminating multiple inheritance manager builds * dartfmt and test package rebuild * pubspec change * regen test package docs post merge
1 parent 39e4791 commit 8ff3d14

File tree

106 files changed

+2964
-123
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+2964
-123
lines changed

lib/src/model.dart

Lines changed: 48 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -698,115 +698,50 @@ class Class extends ModelElement
698698
}
699699

700700
List<Method> get inheritedMethods {
701-
if (_inheritedMethods != null) return _inheritedMethods;
702-
703-
Map<String, ExecutableElement> cmap =
704-
library.inheritanceManager.getMembersInheritedFromClasses(element);
705-
Map<String, ExecutableElement> imap =
706-
library.inheritanceManager.getMembersInheritedFromInterfaces(element);
707-
708-
// remove methods that exist on this class
709-
_methods.forEach((method) {
710-
cmap.remove(method.name);
711-
imap.remove(method.name);
712-
});
713-
714-
_inheritedMethods = [];
715-
List<ExecutableElement> values = [];
716-
Set<String> uniqueNames = new Set();
717-
718-
instanceProperties.forEach((f) {
719-
if (f.setter != null) uniqueNames.add(f.setter.element.name);
720-
if (f.getter != null) uniqueNames.add(f.getter.element.name);
721-
});
722-
723-
for (String key in cmap.keys) {
724-
// XXX: if we care about showing a hierarchy with our inherited methods,
725-
// then don't do this
726-
if (uniqueNames.contains(key)) continue;
727-
728-
uniqueNames.add(key);
729-
values.add(cmap[key]);
730-
}
731-
732-
for (String key in imap.keys) {
733-
// XXX: if we care about showing a hierarchy with our inherited methods,
734-
// then don't do this
735-
if (uniqueNames.contains(key)) continue;
736-
737-
uniqueNames.add(key);
738-
values.add(imap[key]);
739-
}
740-
741-
for (ExecutableElement value in values) {
742-
if (value != null &&
743-
value is MethodElement &&
744-
!value.isOperator &&
745-
value.enclosingElement != null) {
746-
Method m;
747-
m = new ModelElement.from(value, library, enclosingClass: this);
701+
if (_inheritedMethods == null) {
702+
_inheritedMethods = new List<Method>();
703+
Set<String> methodNames = _methods.map((m) => m.element.name).toSet();
704+
705+
Set<ExecutableElement> inheritedMethodElements =
706+
_inheritedElements.where((e) {
707+
return (e is MethodElement &&
708+
!e.isOperator &&
709+
e is! PropertyAccessorElement &&
710+
!methodNames.contains(e.name));
711+
}).toSet();
712+
713+
for (ExecutableElement e in inheritedMethodElements) {
714+
Method m = new ModelElement.from(e, library, enclosingClass: this);
748715
_inheritedMethods.add(m);
749716
_genPageMethods.add(m);
750717
}
718+
_inheritedMethods.sort(byName);
751719
}
752-
753-
_inheritedMethods.sort(byName);
754-
755720
return _inheritedMethods;
756721
}
757722

758723
Iterable get publicInheritedMethods => filterNonPublic(inheritedMethods);
759724

760725
bool get hasPublicInheritedMethods => publicInheritedMethods.isNotEmpty;
761726

762-
// TODO(jcollins-g): this is very copy-paste from inheritedMethods now that the
763-
// constructor is always [ModelElement.from]. Fix this.
764727
List<Operator> get inheritedOperators {
765-
if (_inheritedOperators != null) return _inheritedOperators;
766-
Map<String, ExecutableElement> cmap =
767-
library.inheritanceManager.getMembersInheritedFromClasses(element);
768-
Map<String, ExecutableElement> imap =
769-
library.inheritanceManager.getMembersInheritedFromInterfaces(element);
770-
operators.forEach((operator) {
771-
cmap.remove(operator.element.name);
772-
imap.remove(operator.element.name);
773-
});
774-
_inheritedOperators = [];
775-
Map<String, ExecutableElement> values = {};
776-
777-
bool _isInheritedOperator(ExecutableElement value) {
778-
if (value != null &&
779-
value is MethodElement &&
780-
!value.isPrivate &&
781-
value.isOperator &&
782-
value.enclosingElement != null) {
783-
return true;
728+
if (_inheritedOperators == null) {
729+
_inheritedOperators = [];
730+
Set<String> operatorNames = _operators.map((o) => o.element.name).toSet();
731+
732+
Set<ExecutableElement> inheritedOperatorElements =
733+
_inheritedElements.where((e) {
734+
return (e is MethodElement &&
735+
e.isOperator &&
736+
!operatorNames.contains(e.name));
737+
}).toSet();
738+
for (ExecutableElement e in inheritedOperatorElements) {
739+
Operator o = new ModelElement.from(e, library, enclosingClass: this);
740+
_inheritedOperators.add(o);
741+
_genPageOperators.add(o);
784742
}
785-
return false;
786-
}
787-
788-
for (String key in imap.keys) {
789-
ExecutableElement value = imap[key];
790-
if (_isInheritedOperator(value)) {
791-
values.putIfAbsent(value.name, () => value);
792-
}
793-
}
794-
795-
for (String key in cmap.keys) {
796-
ExecutableElement value = cmap[key];
797-
if (_isInheritedOperator(value)) {
798-
values.putIfAbsent(value.name, () => value);
799-
}
800-
}
801-
802-
for (ExecutableElement value in values.values) {
803-
Operator o = new ModelElement.from(value, library, enclosingClass: this);
804-
_inheritedOperators.add(o);
805-
_genPageOperators.add(o);
743+
_inheritedOperators.sort(byName);
806744
}
807-
808-
_inheritedOperators.sort(byName);
809-
810745
return _inheritedOperators;
811746
}
812747

@@ -994,22 +929,26 @@ class Class extends ModelElement
994929

995930
ElementType get supertype => _supertype;
996931

932+
List<ExecutableElement> __inheritedElements;
933+
List<ExecutableElement> get _inheritedElements {
934+
if (__inheritedElements == null) {
935+
__inheritedElements = [];
936+
Map<String, ExecutableElement> cmap =
937+
library.inheritanceManager.getMembersInheritedFromClasses(element);
938+
Map<String, ExecutableElement> imap =
939+
library.inheritanceManager.getMembersInheritedFromInterfaces(element);
940+
__inheritedElements.addAll(cmap.values);
941+
__inheritedElements
942+
.addAll(imap.values.where((e) => !cmap.containsKey(e.name)));
943+
}
944+
return __inheritedElements;
945+
}
946+
997947
List<Field> get allFields {
998948
if (_fields != null) return _fields;
999949
_fields = [];
1000-
Map<String, ExecutableElement> cmap =
1001-
library.inheritanceManager.getMembersInheritedFromClasses(element);
1002-
Map<String, ExecutableElement> imap =
1003-
library.inheritanceManager.getMembersInheritedFromInterfaces(element);
1004-
1005-
Set<PropertyAccessorElement> inheritedAccessors = new Set();
1006-
inheritedAccessors
1007-
.addAll(cmap.values.where((e) => e is PropertyAccessorElement));
1008-
1009-
// Interfaces are subordinate to members inherited from classes, so don't
1010-
// add this to our accessor set if we already have something inherited from classes.
1011-
inheritedAccessors.addAll(imap.values.where(
1012-
(e) => e is PropertyAccessorElement && !cmap.containsKey(e.name)));
950+
Set<PropertyAccessorElement> inheritedAccessors = new Set()
951+
..addAll(_inheritedElements.where((e) => e is PropertyAccessorElement));
1013952

1014953
// This structure keeps track of inherited accessors, allowing lookup
1015954
// by field name (stripping the '=' from setters).
@@ -5091,6 +5030,7 @@ class PackageBuilder {
50915030
PerformanceLog log = new PerformanceLog(null);
50925031
AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(log);
50935032
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
5033+
options.strongMode = true;
50945034
options.enableSuperMixins = true;
50955035

50965036
// TODO(jcollins-g): Make use of currently not existing API for managing

test/model_test.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ library dartdoc.model_test;
66

77
import 'dart:io';
88

9+
import 'package:analyzer/dart/element/element.dart';
910
import 'package:dartdoc/dartdoc.dart';
1011
import 'package:dartdoc/src/model.dart';
1112
import 'package:dartdoc/src/warnings.dart';
@@ -732,6 +733,15 @@ void main() {
732733
});
733734
});
734735

736+
group('Class edge cases', () {
737+
test('ExecutableElements from private classes and from public interfaces (#1561)', () {
738+
Class MIEEMixinWithOverride = fakeLibrary.publicClasses.firstWhere((c) => c.name == 'MIEEMixinWithOverride');
739+
Operator problematicOperator = MIEEMixinWithOverride.inheritedOperators.firstWhere((o) => o.name == 'operator []=');
740+
expect(problematicOperator.element.enclosingElement.name, equals('_MIEEPrivateOverride'));
741+
expect(problematicOperator.canonicalModelElement.enclosingElement.name, equals('MIEEMixinWithOverride'));
742+
});
743+
});
744+
735745
group('Class', () {
736746
List<Class> classes;
737747
Class Apple, B, Cat, Cool, Dog, F, Dep, SpecialList;

testing/test_package/lib/fake.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,4 +720,25 @@ class ReferringClass {
720720
bool notAMethodFromPrivateClass() {
721721
return false;
722722
}
723+
}
724+
725+
/// Test an edge case for cases where inherited ExecutableElements can come
726+
/// both from private classes and public interfaces. The test makes sure the
727+
/// class still takes precedence (#1561).
728+
abstract class MIEEMixinWithOverride<K, V> = MIEEBase<K, V> with _MIEEPrivateOverride<K, V>;
729+
730+
abstract class _MIEEPrivateOverride<K, V> implements MIEEThing<K, V> {
731+
void operator[]=(K key, V value) {
732+
throw new UnsupportedError("Never use this");
733+
}
734+
}
735+
736+
abstract class MIEEBase<K, V> extends MIEEMixin<K, V> {}
737+
738+
abstract class MIEEMixin<K, V> implements MIEEThing<K, V> {
739+
operator []=(K key, V value);
740+
}
741+
742+
abstract class MIEEThing<K, V> {
743+
void operator[]=(K key, V value);
723744
}

testing/test_package_docs/ex/Dog-class.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ <h2>Operators</h2>
375375
<dl class="callables">
376376
<dt id="operator ==" class="callable">
377377
<span class="name"><a href="ex/Dog/operator_equals.html">operator ==</a></span><span class="signature">(<wbr><span class="parameter" id="==-param-other"><span class="parameter-name">other</span></span>)
378-
<span class="returntype parameter">&#8594; dynamic</span>
378+
<span class="returntype parameter">&#8594; bool</span>
379379
</span>
380380
</dt>
381381
<dd>

testing/test_package_docs/ex/Dog/operator_equals.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ <h1>operator == method</h1>
9797
<li>@override</li>
9898
</ol>
9999
</div>
100-
<span class="returntype">dynamic</span>
100+
<span class="returntype">bool</span>
101101
<span class="name ">operator ==</span>
102102
(<wbr><span class="parameter" id="==-param-other"><span class="parameter-name">other</span></span>)
103103
</section>

testing/test_package_docs/ex/F-class.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ <h2>Operators</h2>
371371
<dl class="callables">
372372
<dt id="operator ==" class="callable inherited">
373373
<span class="name"><a href="ex/Dog/operator_equals.html">operator ==</a></span><span class="signature">(<wbr><span class="parameter" id="==-param-other"><span class="parameter-name">other</span></span>)
374-
<span class="returntype parameter">&#8594; dynamic</span>
374+
<span class="returntype parameter">&#8594; bool</span>
375375
</span>
376376
</dt>
377377
<dd class="inherited">

testing/test_package_docs/ex/Klass-class.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ <h2>Methods</h2>
200200
</dd>
201201
<dt id="toString" class="callable">
202202
<span class="name"><a href="ex/Klass/toString.html">toString</a></span><span class="signature">(<wbr>)
203-
<span class="returntype parameter">&#8594; dynamic</span>
203+
<span class="returntype parameter">&#8594; String</span>
204204
</span>
205205
</dt>
206206
<dd>

testing/test_package_docs/ex/Klass/toString.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ <h1>toString method</h1>
7474
<li>@override</li>
7575
</ol>
7676
</div>
77-
<span class="returntype">dynamic</span>
77+
<span class="returntype">String</span>
7878
<span class="name ">toString</span>
7979
(<wbr>)
8080
</section>

testing/test_package_docs/ex/ex-library.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ <h2>Constants</h2>
299299
</dd>
300300
<dt id="incorrectDocReference" class="constant">
301301
<span class="name "><a href="ex/incorrectDocReference-constant.html">incorrectDocReference</a></span>
302-
<span class="signature">&#8594; const dynamic</span>
302+
<span class="signature">&#8594; const String</span>
303303
</dt>
304304
<dd>
305305
This is the same name as a top-level const from the fake lib.
@@ -310,7 +310,7 @@ <h2>Constants</h2>
310310
</dd>
311311
<dt id="incorrectDocReferenceFromEx" class="constant">
312312
<span class="name "><a href="ex/incorrectDocReferenceFromEx-constant.html">incorrectDocReferenceFromEx</a></span>
313-
<span class="signature">&#8594; const dynamic</span>
313+
<span class="signature">&#8594; const String</span>
314314
</dt>
315315
<dd>
316316
This should <code>not work</code>.

testing/test_package_docs/fake/AClassUsingASuperMixin-class.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ <h5>fake library</h5>
6363
<li><a href="fake/InheritingClassTwo-class.html">InheritingClassTwo</a></li>
6464
<li><a href="fake/Interface-class.html">Interface</a></li>
6565
<li><a href="fake/LongFirstLine-class.html">LongFirstLine</a></li>
66+
<li><a href="fake/MIEEBase-class.html">MIEEBase</a></li>
67+
<li><a href="fake/MIEEMixin-class.html">MIEEMixin</a></li>
68+
<li><a href="fake/MIEEMixinWithOverride-class.html">MIEEMixinWithOverride</a></li>
69+
<li><a href="fake/MIEEThing-class.html">MIEEThing</a></li>
6670
<li><a href="fake/MixMeIn-class.html">MixMeIn</a></li>
6771
<li><a href="fake/NotAMixin-class.html">NotAMixin</a></li>
6872
<li><a href="fake/OperatorReferenceClass-class.html">OperatorReferenceClass</a></li>

testing/test_package_docs/fake/AClassWithFancyProperties-class.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ <h5>fake library</h5>
6363
<li><a href="fake/InheritingClassTwo-class.html">InheritingClassTwo</a></li>
6464
<li><a href="fake/Interface-class.html">Interface</a></li>
6565
<li><a href="fake/LongFirstLine-class.html">LongFirstLine</a></li>
66+
<li><a href="fake/MIEEBase-class.html">MIEEBase</a></li>
67+
<li><a href="fake/MIEEMixin-class.html">MIEEMixin</a></li>
68+
<li><a href="fake/MIEEMixinWithOverride-class.html">MIEEMixinWithOverride</a></li>
69+
<li><a href="fake/MIEEThing-class.html">MIEEThing</a></li>
6670
<li><a href="fake/MixMeIn-class.html">MixMeIn</a></li>
6771
<li><a href="fake/NotAMixin-class.html">NotAMixin</a></li>
6872
<li><a href="fake/OperatorReferenceClass-class.html">OperatorReferenceClass</a></li>

testing/test_package_docs/fake/AMixinCallingSuper-class.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ <h5>fake library</h5>
6363
<li><a href="fake/InheritingClassTwo-class.html">InheritingClassTwo</a></li>
6464
<li><a href="fake/Interface-class.html">Interface</a></li>
6565
<li><a href="fake/LongFirstLine-class.html">LongFirstLine</a></li>
66+
<li><a href="fake/MIEEBase-class.html">MIEEBase</a></li>
67+
<li><a href="fake/MIEEMixin-class.html">MIEEMixin</a></li>
68+
<li><a href="fake/MIEEMixinWithOverride-class.html">MIEEMixinWithOverride</a></li>
69+
<li><a href="fake/MIEEThing-class.html">MIEEThing</a></li>
6670
<li><a href="fake/MixMeIn-class.html">MixMeIn</a></li>
6771
<li><a href="fake/NotAMixin-class.html">NotAMixin</a></li>
6872
<li><a href="fake/OperatorReferenceClass-class.html">OperatorReferenceClass</a></li>

testing/test_package_docs/fake/Annotation-class.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ <h5>fake library</h5>
6363
<li><a href="fake/InheritingClassTwo-class.html">InheritingClassTwo</a></li>
6464
<li><a href="fake/Interface-class.html">Interface</a></li>
6565
<li><a href="fake/LongFirstLine-class.html">LongFirstLine</a></li>
66+
<li><a href="fake/MIEEBase-class.html">MIEEBase</a></li>
67+
<li><a href="fake/MIEEMixin-class.html">MIEEMixin</a></li>
68+
<li><a href="fake/MIEEMixinWithOverride-class.html">MIEEMixinWithOverride</a></li>
69+
<li><a href="fake/MIEEThing-class.html">MIEEThing</a></li>
6670
<li><a href="fake/MixMeIn-class.html">MixMeIn</a></li>
6771
<li><a href="fake/NotAMixin-class.html">NotAMixin</a></li>
6872
<li><a href="fake/OperatorReferenceClass-class.html">OperatorReferenceClass</a></li>

testing/test_package_docs/fake/AnotherInterface-class.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ <h5>fake library</h5>
6363
<li><a href="fake/InheritingClassTwo-class.html">InheritingClassTwo</a></li>
6464
<li><a href="fake/Interface-class.html">Interface</a></li>
6565
<li><a href="fake/LongFirstLine-class.html">LongFirstLine</a></li>
66+
<li><a href="fake/MIEEBase-class.html">MIEEBase</a></li>
67+
<li><a href="fake/MIEEMixin-class.html">MIEEMixin</a></li>
68+
<li><a href="fake/MIEEMixinWithOverride-class.html">MIEEMixinWithOverride</a></li>
69+
<li><a href="fake/MIEEThing-class.html">MIEEThing</a></li>
6670
<li><a href="fake/MixMeIn-class.html">MixMeIn</a></li>
6771
<li><a href="fake/NotAMixin-class.html">NotAMixin</a></li>
6872
<li><a href="fake/OperatorReferenceClass-class.html">OperatorReferenceClass</a></li>

testing/test_package_docs/fake/BaseForDocComments-class.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ <h5>fake library</h5>
6363
<li><a href="fake/InheritingClassTwo-class.html">InheritingClassTwo</a></li>
6464
<li><a href="fake/Interface-class.html">Interface</a></li>
6565
<li><a href="fake/LongFirstLine-class.html">LongFirstLine</a></li>
66+
<li><a href="fake/MIEEBase-class.html">MIEEBase</a></li>
67+
<li><a href="fake/MIEEMixin-class.html">MIEEMixin</a></li>
68+
<li><a href="fake/MIEEMixinWithOverride-class.html">MIEEMixinWithOverride</a></li>
69+
<li><a href="fake/MIEEThing-class.html">MIEEThing</a></li>
6670
<li><a href="fake/MixMeIn-class.html">MixMeIn</a></li>
6771
<li><a href="fake/NotAMixin-class.html">NotAMixin</a></li>
6872
<li><a href="fake/OperatorReferenceClass-class.html">OperatorReferenceClass</a></li>

testing/test_package_docs/fake/BaseThingy-class.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ <h5>fake library</h5>
6363
<li><a href="fake/InheritingClassTwo-class.html">InheritingClassTwo</a></li>
6464
<li><a href="fake/Interface-class.html">Interface</a></li>
6565
<li><a href="fake/LongFirstLine-class.html">LongFirstLine</a></li>
66+
<li><a href="fake/MIEEBase-class.html">MIEEBase</a></li>
67+
<li><a href="fake/MIEEMixin-class.html">MIEEMixin</a></li>
68+
<li><a href="fake/MIEEMixinWithOverride-class.html">MIEEMixinWithOverride</a></li>
69+
<li><a href="fake/MIEEThing-class.html">MIEEThing</a></li>
6670
<li><a href="fake/MixMeIn-class.html">MixMeIn</a></li>
6771
<li><a href="fake/NotAMixin-class.html">NotAMixin</a></li>
6872
<li><a href="fake/OperatorReferenceClass-class.html">OperatorReferenceClass</a></li>

testing/test_package_docs/fake/BaseThingy2-class.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ <h5>fake library</h5>
6363
<li><a href="fake/InheritingClassTwo-class.html">InheritingClassTwo</a></li>
6464
<li><a href="fake/Interface-class.html">Interface</a></li>
6565
<li><a href="fake/LongFirstLine-class.html">LongFirstLine</a></li>
66+
<li><a href="fake/MIEEBase-class.html">MIEEBase</a></li>
67+
<li><a href="fake/MIEEMixin-class.html">MIEEMixin</a></li>
68+
<li><a href="fake/MIEEMixinWithOverride-class.html">MIEEMixinWithOverride</a></li>
69+
<li><a href="fake/MIEEThing-class.html">MIEEThing</a></li>
6670
<li><a href="fake/MixMeIn-class.html">MixMeIn</a></li>
6771
<li><a href="fake/NotAMixin-class.html">NotAMixin</a></li>
6872
<li><a href="fake/OperatorReferenceClass-class.html">OperatorReferenceClass</a></li>

0 commit comments

Comments
 (0)