Skip to content

Migrate markdown_processor and matching_link_result to NNBD #2835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 31 additions & 29 deletions lib/src/markdown_processor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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

/// Utility code to convert markdown comments to html.
library dartdoc.markdown_processor;

Expand Down Expand Up @@ -162,7 +160,7 @@ class _IterableBlockParser extends md.BlockParser {
/// Return false if the passed [referable] is an unnamed [Constructor],
/// or if it is shadowing another type of element, or is a parameter of
/// one of the above.
bool _rejectUnnamedAndShadowingConstructors(CommentReferable referable) {
bool _rejectUnnamedAndShadowingConstructors(CommentReferable? referable) {
if (referable is Constructor) {
if (referable.isUnnamedConstructor) return false;
if (referable.enclosingElement
Expand All @@ -175,11 +173,11 @@ bool _rejectUnnamedAndShadowingConstructors(CommentReferable referable) {

/// Return false unless the passed [referable] represents a callable object.
/// Allows constructors but does not require them.
bool _requireCallable(CommentReferable referable) =>
bool _requireCallable(CommentReferable? referable) =>
referable is ModelElement && referable.isCallable;

/// Return false unless the passed [referable] represents a constructor.
bool _requireConstructor(CommentReferable referable) =>
bool _requireConstructor(CommentReferable? referable) =>
referable is Constructor;

/// Implements _getMatchingLinkElement via [CommentReferable.referenceBy].
Expand All @@ -188,40 +186,42 @@ MatchingLinkResult _getMatchingLinkElementCommentReferable(
var commentReference =
warnable.commentRefs[codeRef] ?? ModelCommentReference.synthetic(codeRef);

bool Function(CommentReferable) filter;
bool Function(CommentReferable) allowTree;
late final bool Function(CommentReferable?) filter;
late final bool Function(CommentReferable?) allowTree;

// Constructor references are pretty ambiguous by nature since they can be
// declared with the same name as the class they are constructing, and even
// if they don't use field-formal parameters, sometimes have parameters
// named the same as members.
// Maybe clean this up with inspiration from constructor tear-off syntax?
if (commentReference.allowUnnamedConstructor) {
allowTree = (_) => true;
// Neither reject, nor require, a default constructor in the event
// the comment reference structure implies one. (We can not require it
// in case a library name is the same as a member class name and the class
// is the intended lookup). For example, [FooClass.FooClass] structurally
// "looks like" a default constructor, so we should allow it here.
filter = commentReference.hasCallableHint ? _requireCallable : null;
filter = commentReference.hasCallableHint ? _requireCallable : (_) => true;
} else if (commentReference.hasConstructorHint &&
commentReference.hasCallableHint) {
allowTree = (_) => true;
// This takes precedence over the callable hint if both are present --
// pick a constructor if and only constructor if we see `new`.
filter = _requireConstructor;
} else if (commentReference.hasCallableHint) {
allowTree = (_) => true;
// Trailing parens indicate we are looking for a callable.
filter = _requireCallable;
} else {
// Without hints, reject unnamed constructors and their parameters to force
// resolution to the class.
filter = _rejectUnnamedAndShadowingConstructors;

if (!commentReference.allowUnnamedConstructorParameter) {
allowTree = _rejectUnnamedAndShadowingConstructors;
} else {
allowTree = (_) => true;
}
// Without hints, reject unnamed constructors and their parameters to force
// resolution to the class.
filter = _rejectUnnamedAndShadowingConstructors;
}
allowTree ??= (_) => true;
filter ??= (_) => true;
var lookupResult = warnable.referenceBy(commentReference.referenceBy,
allowTree: allowTree, filter: filter);

Expand All @@ -239,7 +239,10 @@ md.Node _makeLinkNode(String codeRef, Warnable warnable) {
if (linkedElement is ModelElement && linkedElement.isDeprecated) {
anchor.attributes['class'] = 'deprecated';
}
anchor.attributes['href'] = linkedElement.href;
var href = linkedElement.href;
if (href != null) {
anchor.attributes['href'] = href;
}
return anchor;
}
// else this would be linkedElement.linkedName, but link bodies are slightly
Expand All @@ -250,9 +253,8 @@ md.Node _makeLinkNode(String codeRef, Warnable warnable) {
// current element.
warnable.warn(PackageWarning.unresolvedDocReference,
message: codeRef,
referredFrom: warnable.documentationIsLocal
? null
: warnable.documentationFrom);
referredFrom:
warnable.documentationIsLocal ? [] : warnable.documentationFrom);
}
}

Expand Down Expand Up @@ -328,8 +330,8 @@ Iterable<int> findFreeHangingGenericsPositions(String string) sync* {
}

class MarkdownDocument extends md.Document {
factory MarkdownDocument.withElementLinkResolver(Canonicalization element) {
md.Node /*?*/ linkResolver(String name, [String /*?*/ _]) {
factory MarkdownDocument.withElementLinkResolver(Warnable element) {
md.Node? linkResolver(String name, [String? _]) {
if (name.isEmpty) {
return null;
}
Expand All @@ -343,11 +345,11 @@ class MarkdownDocument extends md.Document {
}

MarkdownDocument(
{Iterable<md.BlockSyntax> blockSyntaxes,
Iterable<md.InlineSyntax> inlineSyntaxes,
md.ExtensionSet extensionSet,
md.Resolver linkResolver,
md.Resolver imageLinkResolver})
{Iterable<md.BlockSyntax>? blockSyntaxes,
Iterable<md.InlineSyntax>? inlineSyntaxes,
md.ExtensionSet? extensionSet,
md.Resolver? linkResolver,
md.Resolver? imageLinkResolver})
: super(
blockSyntaxes: blockSyntaxes,
inlineSyntaxes: inlineSyntaxes,
Expand All @@ -362,7 +364,7 @@ class MarkdownDocument extends md.Document {
String text, bool processFullText) {
var hasExtendedContent = false;
var lines = LineSplitter.split(text).toList();
md.Node firstNode;
md.Node? firstNode;
var nodes = <md.Node>[];
for (var node in _IterableBlockParser(lines, this).parseLinesGenerator()) {
if (firstNode != null) {
Expand All @@ -387,7 +389,7 @@ class MarkdownDocument extends md.Document {
nodes.insertAll(i, inlineNodes);
i += inlineNodes.length - 1;
} else if (node is md.Element && node.children != null) {
_parseInlineContent(node.children);
_parseInlineContent(node.children!);
}
}
}
Expand All @@ -407,7 +409,7 @@ class _InlineCodeSyntax extends md.InlineSyntax {

@override
bool onMatch(md.InlineParser parser, Match match) {
var element = md.Element.text('code', _htmlEscape.convert(match[1] /*!*/));
var element = md.Element.text('code', _htmlEscape.convert(match[1]!));
parser.addNode(element);
return true;
}
Expand All @@ -416,7 +418,7 @@ class _InlineCodeSyntax extends md.InlineSyntax {
class _AutolinkWithoutScheme extends md.AutolinkSyntax {
@override
bool onMatch(md.InlineParser parser, Match match) {
var url = match[1] /*!*/;
var url = match[1]!;
var text = _htmlEscape.convert(url).replaceFirst(_hideSchemes, '');
var anchor = md.Element.text('a', text);
anchor.attributes['href'] = url;
Expand Down
4 changes: 1 addition & 3 deletions lib/src/matching_link_result.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
// 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:dartdoc/src/model/comment_referable.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/quiver.dart';

class MatchingLinkResult {
final CommentReferable commentReferable;
final CommentReferable? commentReferable;
final bool warn;

MatchingLinkResult(this.commentReferable, {this.warn = true});
Expand Down
6 changes: 3 additions & 3 deletions lib/src/quiver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ Iterable<T> concat<T>(Iterable<Iterable<T>> iterables) =>
// From lib/src/core/hash.dart:

/// Generates a hash code for two objects.
int hash2(Object a, Object b) =>
int hash2(Object? a, Object? b) =>
_finish(_combine(_combine(0, a.hashCode), b.hashCode));

/// Generates a hash code for three objects.
int hash3(Object a, Object b, Object c) => _finish(
int hash3(Object? a, Object? b, Object? c) => _finish(
_combine(_combine(_combine(0, a.hashCode), b.hashCode), c.hashCode));

/// Generates a hash code for four objects.
int hash4(Object a, Object b, Object c, Object d) => _finish(_combine(
int hash4(Object? a, Object? b, Object? c, Object? d) => _finish(_combine(
_combine(_combine(_combine(0, a.hashCode), b.hashCode), c.hashCode),
d.hashCode));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ library constructor_tearoffs;

abstract class A {
final int number;

/// Even though this is abstract, dartdoc should still allow referring to
/// [A.new].
A.new(this.number);
Expand Down Expand Up @@ -59,11 +60,11 @@ typedef Fstring = F<String>;
typedef NotAClass = Function;

/// Mixins don't have constructors either, so disallow `M.new`.
mixin M<T> on C {
}
mixin M<T> on C {}

void func() {}
void funcTypeParams<T extends String, U extends num>(T something, U different) {}
void funcTypeParams<T extends String, U extends num>(
T something, U different) {}

const aFunc = func;
const aFuncParams = funcTypeParams;
Expand All @@ -78,4 +79,4 @@ const aTearOffDefaultConstructorArgs = F<String>.new;
const aTearOffDefaultConstructorTypedef = Fstring.new;

// TODO(jcollins-g): does not work @ analyzer 2.2
//const aTearOffDefaultConstructorArgsTypedef = Ft<String>.new;
//const aTearOffDefaultConstructorArgsTypedef = Ft<String>.new;