Skip to content

Add PrefixElement linkage to analyzer scope lookups #2672

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 2 commits into from
Jun 10, 2021
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
6 changes: 6 additions & 0 deletions lib/src/markdown_processor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,12 @@ MatchingLinkResult _getMatchingLinkElementCommentReferable(
var lookupResult =
warnable.referenceBy(commentReference.referenceBy, filter: filter);

// TODO(jcollins-g): Referring to packages or other non-[ModelElement]s
// might be needed here. Determine if that's the case.
if (!(lookupResult is ModelElement)) {
lookupResult = null;
}

// TODO(jcollins-g): Consider prioritizing analyzer resolution before custom.
return MatchingLinkResult(lookupResult);
}
Expand Down
11 changes: 3 additions & 8 deletions lib/src/model/comment_referable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,12 @@ mixin CommentReferable implements Nameable {
/// Looks up references by [scope], skipping over results that do not match
/// the given filter.
///
/// Override if [Scope.lookup] may return a [PrefixElement] or other elements
/// not corresponding to a [CommentReferable], but you still want to have
/// an implementation of [scope].
/// Override if [Scope.lookup] may return elements not corresponding to a
/// [CommentReferable], but you still want to have an implementation of
/// [scope].
CommentReferable lookupViaScope(ReferenceChildrenLookup referenceLookup,
bool Function(CommentReferable) filter) {
var resultElement = scope.lookupPreferGetter(referenceLookup.lookup);
if (resultElement is PrefixElement) {
assert(false,
'PrefixElement detected, override [lookupViaScope] in subclass');
return null;
}
if (resultElement == null) return null;
var result = ModelElement.fromElement(resultElement, packageGraph);
if (result is Accessor) {
Expand Down
4 changes: 4 additions & 0 deletions lib/src/model/model_element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import 'package:dartdoc/src/model/comment_referable.dart';
import 'package:dartdoc/src/model/feature.dart';
import 'package:dartdoc/src/model/feature_set.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/model/prefix.dart';
import 'package:dartdoc/src/model_utils.dart' as utils;
import 'package:dartdoc/src/render/model_element_renderer.dart';
import 'package:dartdoc/src/render/parameter_renderer.dart';
Expand Down Expand Up @@ -286,6 +287,9 @@ abstract class ModelElement extends Canonicalization
if (e is LibraryElement) {
return Library(e, packageGraph);
}
if (e is PrefixElement) {
return Prefix(e, library, packageGraph);
}
if (e is ClassElement) {
if (e.isMixin) {
return Mixin(e, library, packageGraph);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/model/parameter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Parameter extends ModelElement implements EnclosedElement {

@override
String get filePath {
throw StateError('filePath not implemented for parameters');
throw UnimplementedError('Parameters have no generated files in dartdoc');
}

@override
Expand Down
49 changes: 49 additions & 0 deletions lib/src/model/prefix.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// 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.

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/scope.dart';
import 'package:dartdoc/src/model/comment_referable.dart';
import 'package:dartdoc/src/model/library.dart';

import '../../dartdoc.dart';

/// Represents a [PrefixElement] for dartdoc.
///
/// Like [Parameter], it doesn't have doc pages, but participates in lookups.
class Prefix extends ModelElement implements EnclosedElement {
/// [library] is the library the prefix is defined in, not the [Library]
/// referred to by the [PrefixElement].
Prefix(PrefixElement element, Library library, PackageGraph packageGraph)
: super(element, library, packageGraph);

@override
// TODO(jcollins-g): consider allowing bare prefixes to link to a library doc?
bool get isCanonical => false;

@override
Scope get scope => element.scope;

@override
PrefixElement get element => super.element;

@override
ModelElement get enclosingElement => library;

@override
String get filePath =>
throw UnimplementedError('prefixes have no generated files in dartdoc');

@override
String get href => null;

@override
String get kind => 'prefix';

@override
Map<String, CommentReferable> get referenceChildren => {};

@override
Iterable<CommentReferable> get referenceParents => [library];
}
3 changes: 1 addition & 2 deletions test/end2end/model_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2264,8 +2264,7 @@ void main() {
equals(MatchingLinkResult(incorrectDocReferenceFromEx)));

// A prefixed constant in another library.
// TODO(jcollins-g): prefixed namespace lookups are not yet implemented with new lookup code.
expect(originalLookup(doAwesomeStuff, 'css.theOnlyThingInTheLibrary'),
expect(bothLookup(doAwesomeStuff, 'css.theOnlyThingInTheLibrary'),
equals(MatchingLinkResult(theOnlyThingInTheLibrary)));

// A name that exists in this package but is not imported.
Expand Down