From 7359ea27a3df30ea8a56b0eda9ecfde4e46cf8a0 Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Tue, 5 Oct 2021 14:12:42 -0700 Subject: [PATCH 1/3] migrate category --- lib/src/model/category.dart | 54 ++++++++++++++----------------------- lib/src/warnings.dart | 8 +++--- 2 files changed, 24 insertions(+), 38 deletions(-) diff --git a/lib/src/model/category.dart b/lib/src/model/category.dart index 807cde1fca..d4a07f2adb 100644 --- a/lib/src/model/category.dart +++ b/lib/src/model/category.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// @dart=2.9 - import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:dartdoc/src/comment_references/model_comment_reference.dart'; @@ -86,14 +84,13 @@ class Category extends Nameable } @override - // TODO(jcollins-g): make [Category] a [Warnable]? - Warnable get enclosingElement => null; + Warnable? get enclosingElement => null; @override - Element get element => null; + Element? get element => null; @override - String get name => categoryDefinition?.displayName ?? _name; + String get name => categoryDefinition.displayName; @override String get sortKey => _name; @@ -108,7 +105,8 @@ class Category extends Nameable PackageGraph get packageGraph => package.packageGraph; @override - Library get canonicalLibrary => null; + Library get canonicalLibrary => + throw UnimplementedError('Categories can not have associated libraries.'); @override List get documentationFrom => [this]; @@ -116,14 +114,9 @@ class Category extends Nameable @override DocumentLocation get documentedWhere => package.documentedWhere; - bool _isDocumented; - @override - bool get isDocumented { - _isDocumented ??= documentedWhere != DocumentLocation.missing && - documentationFile != null; - return _isDocumented; - } + late final bool isDocumented = + documentedWhere != DocumentLocation.missing && documentationFile != null; @override String get fullyQualifiedName => name; @@ -133,41 +126,34 @@ class Category extends Nameable String get filePath => 'topics/$name-topic.$_fileType'; @override - String get href => isCanonical ? '${package.baseHref}$filePath' : null; + String? get href => isCanonical ? '${package.baseHref}$filePath' : null; String get categoryLabel => _categoryRenderer.renderCategoryLabel(this); String get linkedName => _categoryRenderer.renderLinkedName(this); - int _categoryIndex; - /// The position in the container order for this category. - int get categoryIndex { - _categoryIndex ??= package.categories.indexOf(this); - return _categoryIndex; - } + late final int categoryIndex = package.categories.indexOf(this); - CategoryDefinition get categoryDefinition => - config.categories.categoryDefinitions[sortKey]; + late final CategoryDefinition categoryDefinition = + config.categories.categoryDefinitions[sortKey] ?? + CategoryDefinition(_name, null, null); @override - bool get isCanonical => categoryDefinition != null; + bool get isCanonical => + config.categories.categoryDefinitions.containsKey(sortKey); @override String get kind => 'Topic'; - File _documentationFile; - @override - File get documentationFile { - if (_documentationFile == null) { - if (categoryDefinition?.documentationMarkdown != null) { - _documentationFile = _config.resourceProvider - .getFile(categoryDefinition.documentationMarkdown); - } + late final File? documentationFile = () { + var documentationMarkdown = categoryDefinition.documentationMarkdown; + if (documentationMarkdown != null) { + return _config.resourceProvider.getFile(documentationMarkdown); } - return _documentationFile; - } + return null; + }(); @override Iterable get classes => _classes; diff --git a/lib/src/warnings.dart b/lib/src/warnings.dart index 85b1a3318a..24eed7429b 100644 --- a/lib/src/warnings.dart +++ b/lib/src/warnings.dart @@ -283,9 +283,9 @@ const Map packageWarningDefinitions = /// with an analyzer [element]. mixin Warnable implements Canonicalization, CommentReferable { @override - Element get element; + Element? get element; - Warnable get enclosingElement; + Warnable? get enclosingElement; Package get package; @@ -449,7 +449,7 @@ class PackageWarningOptions { } class PackageWarningCounter { - final Map>> _countedWarnings = {}; + final Map>> _countedWarnings = {}; final _items = []; final _displayedWarningCounts = {}; final PackageGraph packageGraph; @@ -466,7 +466,7 @@ class PackageWarningCounter { /// An unmodifiable map view of all counted warnings related by their element, /// warning type, and message. - UnmodifiableMapView>> + UnmodifiableMapView>> get countedWarnings => UnmodifiableMapView(_countedWarnings); PackageWarningCounter(this.packageGraph); From a357fa6439835881cec3413ad7567f17c4816af8 Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Tue, 5 Oct 2021 15:21:22 -0700 Subject: [PATCH 2/3] Migrate model_comment_reference and the parser --- .../model_comment_reference.dart | 39 +++++++++---------- lib/src/comment_references/parser.dart | 38 ++++++++---------- 2 files changed, 35 insertions(+), 42 deletions(-) diff --git a/lib/src/comment_references/model_comment_reference.dart b/lib/src/comment_references/model_comment_reference.dart index dce0a95741..346ea997f7 100644 --- a/lib/src/comment_references/model_comment_reference.dart +++ b/lib/src/comment_references/model_comment_reference.dart @@ -3,8 +3,6 @@ // BSD-style license that can be found in the LICENSE file. // -// @dart=2.9 - import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/file_system/file_system.dart'; @@ -19,7 +17,7 @@ abstract class ModelCommentReference { bool get hasConstructorHint; bool get hasCallableHint; List get referenceBy; - Element get staticElement; + Element? get staticElement; /// Construct a [ModelCommentReference] using the analyzer AST. factory ModelCommentReference( @@ -35,45 +33,47 @@ abstract class ModelCommentReference { /// information needed for Dartdoc. Drops link to the [CommentReference] /// and [ResourceProvider] after construction. class _ModelCommentReferenceImpl implements ModelCommentReference { - bool _allowUnnamedConstructor; - void _initAllowCache() { var referencePieces = parsed.whereType().toList(); _allowUnnamedConstructor = false; _allowUnnamedConstructorParameter = false; if (referencePieces.length >= 2) { - IdentifierNode nodeLast; - for (var f in referencePieces) { - if (f.text == nodeLast?.text) { - if (identical(referencePieces.last, f)) { + for (var i = 0; i <= referencePieces.length - 2; i++) { + if (referencePieces[i].text == referencePieces[i + 1].text) { + if (i + 2 == referencePieces.length) { + // This looks like an old-style reference to an unnamed + // constructor, e.g. [lib_name.C.C]. _allowUnnamedConstructor = true; } else { + // This could be a reference to a parameter or type parameter of + // an unnamed/new-declared constructor. _allowUnnamedConstructorParameter = true; } } - nodeLast = f; - } - if (referencePieces.last.text == 'new') { - _allowUnnamedConstructor = true; } } + // e.g. [C.new], which may be the unnamed constructor + if (referencePieces.isNotEmpty && referencePieces.last.text == 'new') { + _allowUnnamedConstructor = true; + } } + bool? _allowUnnamedConstructor; @override bool get allowUnnamedConstructor { if (_allowUnnamedConstructor == null) { _initAllowCache(); } - return _allowUnnamedConstructor; + return _allowUnnamedConstructor!; } - bool _allowUnnamedConstructorParameter; + bool? _allowUnnamedConstructorParameter; @override bool get allowUnnamedConstructorParameter { if (_allowUnnamedConstructorParameter == null) { _initAllowCache(); } - return _allowUnnamedConstructorParameter; + return _allowUnnamedConstructorParameter!; } @override @@ -96,7 +96,7 @@ class _ModelCommentReferenceImpl implements ModelCommentReference { .toList(growable: false); @override - final Element staticElement; + final Element? staticElement; _ModelCommentReferenceImpl( CommentReference ref, ResourceProvider resourceProvider) @@ -120,7 +120,6 @@ class _ModelCommentReferenceImpl implements ModelCommentReference { .substring(ref.offset - token.offset, ref.end - token.offset); } - List _parsed; - List get parsed => - _parsed ??= CommentReferenceParser(codeRef).parse(); + late final List parsed = + CommentReferenceParser(codeRef).parse(); } diff --git a/lib/src/comment_references/parser.dart b/lib/src/comment_references/parser.dart index 8a17681aff..5e1eb1e41d 100644 --- a/lib/src/comment_references/parser.dart +++ b/lib/src/comment_references/parser.dart @@ -3,8 +3,6 @@ // BSD-style license that can be found in the LICENSE file. // -// @dart=2.9 - import 'package:charcode/charcode.dart'; import 'package:meta/meta.dart'; @@ -52,7 +50,7 @@ class StringTrie { var matchChar = toMatch.codeUnitAt(index); if (children.containsKey(matchChar)) { lastValid = valid ? index : lastValid; - return children[matchChar].match(toMatch, index + 1, lastValid); + return children[matchChar]!.match(toMatch, index + 1, lastValid); } return valid ? index : lastValid; } @@ -61,22 +59,19 @@ class StringTrie { var currentTrie = this; for (var i in toAdd.codeUnits) { currentTrie.children.putIfAbsent(i, () => StringTrie()); - currentTrie = currentTrie.children[i]; + currentTrie = currentTrie.children[i]!; } currentTrie.valid = true; } } -StringTrie _operatorParseTrie; -StringTrie get operatorParseTrie { - if (_operatorParseTrie == null) { - _operatorParseTrie = StringTrie(); - for (var name in operatorNames.keys) { - _operatorParseTrie.addWord(name); - } +late final StringTrie operatorParseTrie = () { + var _operatorParseTrie = StringTrie(); + for (var name in operatorNames.keys) { + _operatorParseTrie.addWord(name); } return _operatorParseTrie; -} +}(); /// A parser for comment references. // TODO(jcollins-g): align with [CommentReference] from analyzer AST. @@ -114,7 +109,7 @@ class CommentReferenceParser { return []; } if (prefixResult.type == _PrefixResultType.parsedConstructorHint) { - children.add(prefixResult.node); + children.add(prefixResult.node!); } // [_PrefixResultType.junk] and [_PrefixResultType.missing] we can skip. @@ -130,7 +125,7 @@ class CommentReferenceParser { break; } else if (identifierResult.type == _IdentifierResultType.parsedIdentifier) { - children.add(identifierResult.node); + children.add(identifierResult.node!); var typeVariablesResult = _parseTypeVariables(); if (typeVariablesResult.type == _TypeVariablesResultType.endOfFile) { break; @@ -140,7 +135,7 @@ class CommentReferenceParser { ; } else if (typeVariablesResult.type == _TypeVariablesResultType.parsedTypeVariables) { - children.add(typeVariablesResult.node); + children.add(typeVariablesResult.node!); } } if (_atEnd || _thisChar != $dot) { @@ -155,7 +150,7 @@ class CommentReferenceParser { // Invalid trailing junk; reject the reference. return []; } else if (suffixResult.type == _SuffixResultType.parsedCallableHint) { - children.add(suffixResult.node); + children.add(suffixResult.node!); } // [_SuffixResultType.junk] or [_SuffixResultType.missing] we can skip. @@ -210,7 +205,7 @@ class CommentReferenceParser { /// Advances the index forward to the end of the operator if one is /// present and returns the operator's name. Otherwise, leaves _index /// unchanged and returns null. - String _tryParseOperator() { + String? _tryParseOperator() { var tryIndex = _index; if (tryIndex + _operatorKeyword.length < codeRef.length && codeRef.substring(tryIndex, tryIndex + _operatorKeyword.length) == @@ -319,7 +314,6 @@ class CommentReferenceParser { bool _tryMatchLiteral(String characters, {bool acceptTrailingWhitespace = true, bool requireTrailingNonidentifier = false}) { - assert(acceptTrailingWhitespace != null); if (characters.length + _index > _referenceLength) return false; int startIndex; for (startIndex = _index; @@ -389,7 +383,7 @@ enum _PrefixResultType { class _PrefixParseResult { final _PrefixResultType type; - final CommentReferenceNode node; + final CommentReferenceNode? node; const _PrefixParseResult._(this.type, this.node); @@ -417,7 +411,7 @@ enum _IdentifierResultType { class _IdentifierParseResult { final _IdentifierResultType type; - final IdentifierNode node; + final IdentifierNode? node; const _IdentifierParseResult._(this.type, this.node); @@ -441,7 +435,7 @@ enum _TypeVariablesResultType { class _TypeVariablesParseResult { final _TypeVariablesResultType type; - final TypeVariablesNode node; + final TypeVariablesNode? node; const _TypeVariablesParseResult._(this.type, this.node); @@ -468,7 +462,7 @@ enum _SuffixResultType { class _SuffixParseResult { final _SuffixResultType type; - final CommentReferenceNode node; + final CommentReferenceNode? node; const _SuffixParseResult._(this.type, this.node); From fa5a6d044c986f42f94f5c05b6ffe01565df6e56 Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Fri, 8 Oct 2021 14:34:10 -0700 Subject: [PATCH 3/3] Fix test failure --- lib/src/comment_references/model_comment_reference.dart | 8 ++++---- test/end2end/model_special_cases_test.dart | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/src/comment_references/model_comment_reference.dart b/lib/src/comment_references/model_comment_reference.dart index 346ea997f7..dd37b972be 100644 --- a/lib/src/comment_references/model_comment_reference.dart +++ b/lib/src/comment_references/model_comment_reference.dart @@ -51,10 +51,10 @@ class _ModelCommentReferenceImpl implements ModelCommentReference { } } } - } - // e.g. [C.new], which may be the unnamed constructor - if (referencePieces.isNotEmpty && referencePieces.last.text == 'new') { - _allowUnnamedConstructor = true; + // e.g. [C.new], which may be the unnamed constructor + if (referencePieces.isNotEmpty && referencePieces.last.text == 'new') { + _allowUnnamedConstructor = true; + } } } diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index 89666d4972..d334ee0f08 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -311,6 +311,7 @@ void main() { expect(injectSimpleHtml.documentationAsHtml, contains('
[HtmlInjection]
')); }); + test('can inject HTML from tool', () { var envLine = RegExp(r'^Env: \{', multiLine: true); expect(envLine.allMatches(injectHtmlFromTool.documentation).length,