Allow analyzer to fallback to getter documentation for setters
The analyzer server firsts looks for the setter's dartdoc, then the first parent setter's dartdoc, then the closest getter's dartdoc. Fixes #38963 Bug: https://github.com/dart-lang/sdk/issues/38963 Change-Id: I09f7ae0e5aa49d2536ebefd44dcfd3d6101bb0a6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148566 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Lasse R.H. Nielsen <lrn@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
f0450f3efc
commit
bf7e9d13d7
@@ -155,24 +155,46 @@ class DartUnitHoverComputer {
|
||||
// parameter for a field that does not exist.
|
||||
return null;
|
||||
}
|
||||
// The documentation of the element itself.
|
||||
if (element.documentationComment != null) {
|
||||
return dartdocInfo.processDartdoc(element.documentationComment);
|
||||
}
|
||||
// Look for documentation comments of overridden members.
|
||||
|
||||
Element documentedElement;
|
||||
Element documentedGetter;
|
||||
|
||||
// Look for documentation comments of overridden members
|
||||
var overridden = findOverriddenElements(element);
|
||||
for (var superElement in [
|
||||
for (var candidate in [
|
||||
element,
|
||||
...overridden.superElements,
|
||||
...overridden.interfaceElements
|
||||
]) {
|
||||
var rawDoc = superElement.documentationComment;
|
||||
if (rawDoc != null) {
|
||||
var interfaceClass = superElement.enclosingElement;
|
||||
return dartdocInfo.processDartdoc(rawDoc) +
|
||||
'\n\nCopied from `${interfaceClass.displayName}`.';
|
||||
if (candidate.documentationComment != null) {
|
||||
documentedElement = candidate;
|
||||
break;
|
||||
}
|
||||
if (documentedGetter == null &&
|
||||
candidate is PropertyAccessorElement &&
|
||||
candidate.isSetter) {
|
||||
var getter = candidate.correspondingGetter;
|
||||
if (getter != null && getter.documentationComment != null) {
|
||||
documentedGetter = getter;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
// Use documentation of a corresponding getter if setters don't have it
|
||||
documentedElement ??= documentedGetter;
|
||||
if (documentedElement == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var rawDoc = documentedElement.documentationComment;
|
||||
var result = dartdocInfo.processDartdoc(rawDoc);
|
||||
|
||||
var documentedElementClass = documentedElement.enclosingElement;
|
||||
if (documentedElementClass != element.enclosingElement) {
|
||||
result += '\n\nCopied from `${documentedElementClass.displayName}`.';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static DartType _getTypeOfDeclarationOrReference(Expression node) {
|
||||
|
||||
@@ -723,4 +723,108 @@ main() {
|
||||
expect(hover.elementKind, 'parameter');
|
||||
expect(hover.staticType, 'int');
|
||||
}
|
||||
|
||||
Future<void> test_setter_hasDocumentation() async {
|
||||
addTestFile('''
|
||||
class A {
|
||||
/// getting
|
||||
int get foo => 42;
|
||||
/// setting
|
||||
set foo(int x) {}
|
||||
}
|
||||
main(A a) {
|
||||
a.foo = 123;
|
||||
}
|
||||
''');
|
||||
var hover = await prepareHover('foo = ');
|
||||
expect(hover.containingClassDescription, 'A');
|
||||
expect(hover.dartdoc, '''setting''');
|
||||
expect(hover.elementDescription, 'void set foo(int x)');
|
||||
expect(hover.elementKind, 'setter');
|
||||
}
|
||||
|
||||
Future<void> test_setter_noDocumentation() async {
|
||||
addTestFile('''
|
||||
class A {
|
||||
/// getting
|
||||
int get foo => 42;
|
||||
set foo(int x) {}
|
||||
}
|
||||
main(A a) {
|
||||
a.foo = 123;
|
||||
}
|
||||
''');
|
||||
var hover = await prepareHover('foo = ');
|
||||
expect(hover.containingClassDescription, 'A');
|
||||
expect(hover.dartdoc, '''getting''');
|
||||
expect(hover.elementDescription, 'void set foo(int x)');
|
||||
expect(hover.elementKind, 'setter');
|
||||
}
|
||||
|
||||
Future<void> test_setter_super_hasDocumentation() async {
|
||||
addTestFile('''
|
||||
class A {
|
||||
/// pgetting
|
||||
int get foo => 42;
|
||||
/// psetting
|
||||
set foo(int x) {}
|
||||
}
|
||||
class B extends A {
|
||||
/// getting
|
||||
int get foo => 42;
|
||||
set foo(int x) {}
|
||||
}
|
||||
main(B b) {
|
||||
b.foo = 123;
|
||||
}
|
||||
''');
|
||||
var hover = await prepareHover('foo = ');
|
||||
expect(hover.containingClassDescription, 'B');
|
||||
expect(hover.dartdoc, '''psetting\n\nCopied from `A`.''');
|
||||
expect(hover.elementDescription, 'void set foo(int x)');
|
||||
expect(hover.elementKind, 'setter');
|
||||
}
|
||||
|
||||
Future<void> test_setter_super_noDocumentation() async {
|
||||
addTestFile('''
|
||||
class A {
|
||||
/// pgetting
|
||||
int get foo => 42;
|
||||
set foo(int x) {}
|
||||
}
|
||||
class B extends A {
|
||||
int get foo => 42;
|
||||
set foo(int x) {}
|
||||
}
|
||||
main(B b) {
|
||||
b.foo = 123;
|
||||
}
|
||||
''');
|
||||
var hover = await prepareHover('foo = ');
|
||||
expect(hover.containingClassDescription, 'B');
|
||||
expect(hover.dartdoc, '''pgetting\n\nCopied from `A`.''');
|
||||
expect(hover.elementDescription, 'void set foo(int x)');
|
||||
expect(hover.elementKind, 'setter');
|
||||
}
|
||||
|
||||
@failingTest
|
||||
Future<void> test_setter_super_noSetter() async {
|
||||
addTestFile('''
|
||||
class A {
|
||||
/// pgetting
|
||||
int get foo => 42;
|
||||
}
|
||||
class B extends A {
|
||||
set foo(int x) {}
|
||||
}
|
||||
main(B b) {
|
||||
b.foo = 123;
|
||||
}
|
||||
''');
|
||||
var hover = await prepareHover('foo = ');
|
||||
expect(hover.containingClassDescription, 'B');
|
||||
expect(hover.dartdoc, '''pgetting''');
|
||||
expect(hover.elementDescription, 'void set foo(int x)');
|
||||
expect(hover.elementKind, 'setter');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user