Skip to content

Commit 9263f70

Browse files
authored
Initial nnbd implementation and cleanup (#2069)
1 parent 4995e7e commit 9263f70

11 files changed

+137
-74
lines changed

analysis_options.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
include: package:pedantic/analysis_options.1.8.0.yaml
22

33
analyzer:
4-
# enable for analysis on test package sources.
5-
enable-experiment:
6-
- extension-methods
74
exclude:
85
- 'doc/**'
96
- 'lib/src/third_party/pkg/**'

lib/src/model/field.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'package:analyzer/dart/element/element.dart';
66
import 'package:analyzer/src/dart/element/element.dart';
7+
import 'package:dartdoc/src/element_type.dart';
78
import 'package:dartdoc/src/model/model.dart';
89

910
class Field extends ModelElement
@@ -184,6 +185,9 @@ class Field extends ModelElement
184185
}
185186
}
186187

188+
@override
189+
CallableElementType get modelType => super.modelType;
190+
187191
@override
188192
Inheritable get overriddenElement => null;
189193
}

lib/src/model/package_builder.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ class PackageBuilder {
152152
AnalysisOptionsImpl options = AnalysisOptionsImpl();
153153

154154
// TODO(jcollins-g): pass in an ExperimentStatus instead?
155-
options.enabledExperiments = config.enableExperiment
156-
..add('extension-methods');
155+
options.enabledExperiments = config.enableExperiment;
157156

158157
// TODO(jcollins-g): Make use of currently not existing API for managing
159158
// many AnalysisDrivers

pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ author: Dart Team <[email protected]>
55
description: A documentation generator for Dart.
66
homepage: https://github.com/dart-lang/dartdoc
77
environment:
8-
sdk: '>=2.2.0 <3.0.0'
8+
sdk: '>=2.6.0 <3.0.0'
99

1010
dependencies:
11-
analyzer: ^0.39.0
11+
analyzer: ^0.39.1
1212
args: '>=1.5.0 <2.0.0'
1313
collection: ^1.2.0
1414
crypto: ^2.0.6

test/dartdoc_test.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,9 @@ void main() {
258258
expect(p.name, 'test_package');
259259
expect(p.hasDocumentationFile, isTrue);
260260
// Total number of public libraries in test_package.
261-
expect(packageGraph.defaultPackage.publicLibraries, hasLength(16));
261+
// +2 since we are not manually excluding anything.
262+
expect(packageGraph.defaultPackage.publicLibraries,
263+
hasLength(kTestPackagePublicLibraries + 2));
262264
expect(packageGraph.localPackages.length, equals(1));
263265
});
264266

@@ -313,8 +315,8 @@ void main() {
313315
PackageGraph p = results.packageGraph;
314316
expect(p.defaultPackage.name, 'test_package');
315317
expect(p.defaultPackage.hasDocumentationFile, isTrue);
316-
expect(p.libraries, hasLength(1));
317-
expect(p.libraries.map((lib) => lib.name), contains('fake'));
318+
expect(p.localPublicLibraries, hasLength(1));
319+
expect(p.localPublicLibraries.map((lib) => lib.name), contains('fake'));
318320
});
319321

320322
test('generate docs excluding a single library', () async {
@@ -327,7 +329,10 @@ void main() {
327329
PackageGraph p = results.packageGraph;
328330
expect(p.defaultPackage.name, 'test_package');
329331
expect(p.defaultPackage.hasDocumentationFile, isTrue);
330-
expect(p.localPublicLibraries, hasLength(15));
332+
// Plus 1 here because we're excluding only two libraries (the specified
333+
// one and the <nodoc> 'excluded' library) instead of three.
334+
expect(
335+
p.localPublicLibraries, hasLength(kTestPackagePublicLibraries + 1));
331336
expect(p.localPublicLibraries.map((lib) => lib.name).contains('fake'),
332337
isFalse);
333338
});

test/model_special_cases_test.dart

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -29,49 +29,26 @@ void main() {
2929
// Experimental features not yet enabled by default. Move tests out of this block
3030
// when the feature is enabled by default.
3131
group('Experiments', () {
32-
Library main;
33-
TopLevelVariable aComplexSet,
34-
inferredTypeSet,
35-
specifiedSet,
36-
untypedMap,
37-
typedSet;
38-
32+
Library lateFinalWithoutInitializer;
3933
setUpAll(() async {
40-
main = (await utils.testPackageGraphExperiments)
34+
lateFinalWithoutInitializer = (await utils.testPackageGraphExperiments)
4135
.libraries
42-
.firstWhere((lib) => lib.name == 'main');
43-
aComplexSet = main.constants.firstWhere((v) => v.name == 'aComplexSet');
44-
inferredTypeSet =
45-
main.constants.firstWhere((v) => v.name == 'inferredTypeSet');
46-
specifiedSet = main.constants.firstWhere((v) => v.name == 'specifiedSet');
47-
untypedMap = main.constants.firstWhere((v) => v.name == 'untypedMap');
48-
typedSet = main.constants.firstWhere((v) => v.name == 'typedSet');
49-
});
50-
51-
test('Set literals test', () {
52-
expect(aComplexSet.modelType.name, equals('Set'));
53-
expect(aComplexSet.modelType.typeArguments.map((a) => a.name).toList(),
54-
equals(['AClassContainingLiterals']));
55-
expect(aComplexSet.constantValue,
56-
equals('const {const AClassContainingLiterals(3, 5)}'));
57-
expect(inferredTypeSet.modelType.name, equals('Set'));
58-
expect(
59-
inferredTypeSet.modelType.typeArguments.map((a) => a.name).toList(),
60-
equals(['num']));
61-
expect(inferredTypeSet.constantValue, equals('const {1, 2.5, 3}'));
62-
expect(specifiedSet.modelType.name, equals('Set'));
63-
expect(specifiedSet.modelType.typeArguments.map((a) => a.name).toList(),
64-
equals(['int']));
65-
expect(specifiedSet.constantValue, equals('const {}'));
66-
expect(untypedMap.modelType.name, equals('Map'));
67-
expect(untypedMap.modelType.typeArguments.map((a) => a.name).toList(),
68-
equals(['dynamic', 'dynamic']));
69-
expect(untypedMap.constantValue, equals('const {}'));
70-
expect(typedSet.modelType.name, equals('Set'));
71-
expect(typedSet.modelType.typeArguments.map((a) => a.name).toList(),
72-
equals(['String']));
73-
expect(typedSet.constantValue,
74-
matches(RegExp(r'const &lt;String&gt;\s?{}')));
36+
.firstWhere((lib) => lib.name == 'late_final_without_initializer');
37+
});
38+
39+
test('Late finals test', () {
40+
Class c = lateFinalWithoutInitializer.allClasses
41+
.firstWhere((c) => c.name == 'C');
42+
Field a = c.allFields.firstWhere((f) => f.name == 'a');
43+
Field b = c.allFields.firstWhere((f) => f.name == 'b');
44+
Field cField = c.allFields.firstWhere((f) => f.name == 'cField');
45+
Field dField = c.allFields.firstWhere((f) => f.name == 'dField');
46+
// If nnbd isn't enabled, fields named 'late' come back from the analyzer.
47+
expect(c.allFields.any((f) => f.name == 'late'), isFalse);
48+
expect(a.modelType.returnType.name, equals('dynamic'));
49+
expect(b.modelType.returnType.name, equals('int'));
50+
expect(cField.modelType.returnType.name, equals('dynamic'));
51+
expect(dField.modelType.returnType.name, equals('double'));
7552
});
7653
});
7754

test/model_test.dart

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,55 @@ void main() {
7676
packageGraph.libraries.firstWhere((lib) => lib.name == 'base_class');
7777
});
7878

79+
group('Set Literals', () {
80+
Library set_literals;
81+
TopLevelVariable aComplexSet,
82+
inferredTypeSet,
83+
specifiedSet,
84+
untypedMap,
85+
typedSet;
86+
87+
setUpAll(() async {
88+
set_literals = packageGraph.libraries
89+
.firstWhere((lib) => lib.name == 'set_literals');
90+
aComplexSet =
91+
set_literals.constants.firstWhere((v) => v.name == 'aComplexSet');
92+
inferredTypeSet =
93+
set_literals.constants.firstWhere((v) => v.name == 'inferredTypeSet');
94+
specifiedSet =
95+
set_literals.constants.firstWhere((v) => v.name == 'specifiedSet');
96+
untypedMap =
97+
set_literals.constants.firstWhere((v) => v.name == 'untypedMap');
98+
typedSet = set_literals.constants.firstWhere((v) => v.name == 'typedSet');
99+
});
100+
101+
test('Set literals test', () {
102+
expect(aComplexSet.modelType.name, equals('Set'));
103+
expect(aComplexSet.modelType.typeArguments.map((a) => a.name).toList(),
104+
equals(['AClassContainingLiterals']));
105+
expect(aComplexSet.constantValue,
106+
equals('const {const AClassContainingLiterals(3, 5)}'));
107+
expect(inferredTypeSet.modelType.name, equals('Set'));
108+
expect(
109+
inferredTypeSet.modelType.typeArguments.map((a) => a.name).toList(),
110+
equals(['num']));
111+
expect(inferredTypeSet.constantValue, equals('const {1, 2.5, 3}'));
112+
expect(specifiedSet.modelType.name, equals('Set'));
113+
expect(specifiedSet.modelType.typeArguments.map((a) => a.name).toList(),
114+
equals(['int']));
115+
expect(specifiedSet.constantValue, equals('const {}'));
116+
expect(untypedMap.modelType.name, equals('Map'));
117+
expect(untypedMap.modelType.typeArguments.map((a) => a.name).toList(),
118+
equals(['dynamic', 'dynamic']));
119+
expect(untypedMap.constantValue, equals('const {}'));
120+
expect(typedSet.modelType.name, equals('Set'));
121+
expect(typedSet.modelType.typeArguments.map((a) => a.name).toList(),
122+
equals(['String']));
123+
expect(typedSet.constantValue,
124+
matches(RegExp(r'const &lt;String&gt;\s?{}')));
125+
});
126+
});
127+
79128
group('Tools', () {
80129
Class toolUser;
81130
Class _NonCanonicalToolUser, CanonicalToolUser, PrivateLibraryToolUser;
@@ -291,10 +340,6 @@ void main() {
291340
]));
292341
expect(packageCategories.map((c) => c.libraries.length).toList(),
293342
orderedEquals([0, 2, 3, 1, 0, 0]));
294-
expect(
295-
packageGraph
296-
.localPackages.first.defaultCategory.publicLibraries.length,
297-
equals(9));
298343
});
299344

300345
test('Verify libraries with multiple categories show up in multiple places',
@@ -313,7 +358,8 @@ void main() {
313358
expect(
314359
packageGraph
315360
.localPackages.first.defaultCategory.publicLibraries.length,
316-
equals(9));
361+
// Only 5 libraries have categories, the rest belong in default.
362+
equals(utils.kTestPackagePublicLibraries - 5));
317363
});
318364
});
319365

@@ -383,7 +429,8 @@ void main() {
383429
});
384430

385431
test('libraries', () {
386-
expect(packageGraph.localPublicLibraries, hasLength(14));
432+
expect(packageGraph.localPublicLibraries,
433+
hasLength(utils.kTestPackagePublicLibraries));
387434
expect(interceptorsLib.isPublic, isFalse);
388435
});
389436

@@ -398,7 +445,8 @@ void main() {
398445

399446
Package package = packageGraph.localPackages.first;
400447
expect(package.name, 'test_package');
401-
expect(package.publicLibraries, hasLength(14));
448+
expect(package.publicLibraries,
449+
hasLength(utils.kTestPackagePublicLibraries));
402450
});
403451

404452
test('is documented in library', () {
@@ -710,11 +758,12 @@ void main() {
710758
EnumField enumValue2;
711759

712760
setUpAll(() {
713-
enumWithAnimation = exLibrary.enums.firstWhere((c) => c.name == 'EnumWithAnimation');
714-
enumValue1 = enumWithAnimation.constants
715-
.firstWhere((m) => m.name == 'value1');
716-
enumValue2 = enumWithAnimation.constants
717-
.firstWhere((m) => m.name == 'value2');
761+
enumWithAnimation =
762+
exLibrary.enums.firstWhere((c) => c.name == 'EnumWithAnimation');
763+
enumValue1 =
764+
enumWithAnimation.constants.firstWhere((m) => m.name == 'value1');
765+
enumValue2 =
766+
enumWithAnimation.constants.firstWhere((m) => m.name == 'value2');
718767
dog = exLibrary.classes.firstWhere((c) => c.name == 'Dog');
719768
withAnimation =
720769
dog.allInstanceMethods.firstWhere((m) => m.name == 'withAnimation');
@@ -775,12 +824,18 @@ void main() {
775824
contains('<video id="outOfOrder"'));
776825
});
777826
test("Enum field animation identifiers are unique.", () {
778-
expect(enumValue1.documentationAsHtml, contains('<video id="animation_1"'));
779-
expect(enumValue1.documentationAsHtml, contains('<video id="animation_2"'));
780-
expect(enumValue2.documentationAsHtml, isNot(contains('<video id="animation_1"')));
781-
expect(enumValue2.documentationAsHtml, isNot(contains('<video id="animation_2"')));
782-
expect(enumValue2.documentationAsHtml, contains('<video id="animation_3"'));
783-
expect(enumValue2.documentationAsHtml, contains('<video id="animation_4"'));
827+
expect(
828+
enumValue1.documentationAsHtml, contains('<video id="animation_1"'));
829+
expect(
830+
enumValue1.documentationAsHtml, contains('<video id="animation_2"'));
831+
expect(enumValue2.documentationAsHtml,
832+
isNot(contains('<video id="animation_1"')));
833+
expect(enumValue2.documentationAsHtml,
834+
isNot(contains('<video id="animation_2"')));
835+
expect(
836+
enumValue2.documentationAsHtml, contains('<video id="animation_3"'));
837+
expect(
838+
enumValue2.documentationAsHtml, contains('<video id="animation_4"'));
784839
});
785840
});
786841

test/src/utils.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ import 'package:dartdoc/src/model/model.dart';
1515
import 'package:dartdoc/src/package_meta.dart';
1616
import 'package:path/path.dart' as path;
1717

18+
/// The number of public libraries in testing/test_package, minus 2 for
19+
/// the excluded libraries listed in the initializers for _testPackageGraphMemo
20+
/// and minus 1 for the <nodoc> tag in the 'excluded' library.
21+
const int kTestPackagePublicLibraries = 15;
22+
1823
final RegExp quotables = RegExp(r'[ "\r\n\$]');
1924
final RegExp observatoryPortRegexp =
2025
RegExp(r'^Observatory listening on http://.*:(\d+)');
@@ -23,15 +28,14 @@ Directory sdkDir = defaultSdkDir;
2328
PackageMeta sdkPackageMeta = PackageMeta.fromDir(sdkDir);
2429

2530
final _testPackageGraphMemo = AsyncMemoizer<PackageGraph>();
26-
Future<PackageGraph> get testPackageGraph =>
27-
_testPackageGraphMemo.runOnce(() => bootBasicPackage(
28-
'testing/test_package', ['css', 'code_in_comments', 'excluded']));
31+
Future<PackageGraph> get testPackageGraph => _testPackageGraphMemo.runOnce(() =>
32+
bootBasicPackage('testing/test_package', ['css', 'code_in_comments']));
2933

3034
final _testPackageGraphExperimentsMemo = AsyncMemoizer<PackageGraph>();
3135
Future<PackageGraph> get testPackageGraphExperiments =>
3236
_testPackageGraphExperimentsMemo.runOnce(() => bootBasicPackage(
3337
'testing/test_package_experiments', [],
34-
additionalArguments: ['--enable-experiment', 'set-literals']));
38+
additionalArguments: ['--enable-experiment', 'non-nullable']));
3539

3640
final _testPackageGraphGinormousMemo = AsyncMemoizer<PackageGraph>();
3741
Future<PackageGraph> get testPackageGraphGinormous =>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
analyzer:
2+
# enable for analysis on test package sources.
3+
enable-experiment:
4+
- non-nullable
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
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.
4+
5+
import 'dart:math';
6+
7+
class C {
8+
late final a;
9+
late final b = 0;
10+
late final cField;
11+
late final double dField;
12+
13+
C(double param) {
14+
cField = param * 3.14;
15+
dField = param * 8.854 * pow(10, -12);
16+
}
17+
}
18+

0 commit comments

Comments
 (0)