문서 주석 참조(Doc comment references)

문서 주석 참조(Doc comment references)

///로 시작하는 문서 주석 안에서 대괄호([...])로 감싸면 코드의 다양한 식별자를 참조할 수 있어요. 이렇게 하면 IDE가 이름 완성이나 이동 기능을 제공하고, dart doc으로 만든 API 문서에서도 해당 요소의 문서 페이지로 연결돼요. 문서 주석 참조를 잘 활용하면 바로가기와 자동 수정이 모두 살아나요.

출처: Documentation comment references

본문

문서 주석은 다양한 식별자를 참조할 수 있어요. ///로 시작하는 문서 주석에서 함수나 클래스 같은 요소는 그 이름을 대괄호([...])로 감싸 참조하면 돼요. 몇 가지 예를 볼게요.

/// Returns a [String].
String f() => 'Hello';

/// Wraps [object] with [Future.value].
Future<T> g<T>(T object) => Future.value(object);

이 문서 주석들은 String 클래스, object 매개변수, 그리고 Future.value 생성자를 참조하고 있어요.

참조의 장점들

문서 주석 참조로 코드 요소를 가리키면 여러 가지 이점이 있어요.

에디터 지원

문서 주석 참조는 몇 가지 IDE 기능을 켜 줘요.

  • 코드 완성(Code completion): 대괄호 안에서 요소 이름을 코드 완성으로 채울 수 있어요.
  • 이름 바꾸기 리팩터링(Rename refactoring): IDE 명령으로 요소 이름을 바꾸면, 문서 주석 안의 참조를 포함해 그 요소를 쓰는 곳을 함께 다시 써 줘요.
  • 참조 찾기(Find references): IDE가 요소의 "참조"를 나열할 때 문서 주석 안의 참조도 포함해요.
  • 정의로 이동(Go to definition): IDE는 문서 주석 참조 위치에서도 정의로 이동 기능을 제공해요.

💡 comment_references 린트 규칙을 쓰면 문서 주석 참조가 유효한지 확인해 줘서, 오타나 잘못된 사용을 막을 수 있어요. 참조를 유효하게 유지해야 위 IDE 기능들이 모든 참조에서 동작해요.

API 문서

dart doc으로 생성한 API 문서에서, 문서 주석 참조는 가능하면 참조하는 요소의 문서 페이지로 연결돼요. 만약 그 요소에 문서 페이지가 없다면(예: 함수 매개변수, 타입 매개변수, private 클래스), 링크는 만들어지지 않아요.

무엇을 참조할 수 있나요

대부분의 라이브러리 멤버는 문서 주석에서 참조할 수 있어요. 클래스, 상수, enum, named extension, extension type, 함수, mixin, 타입 별칭이 모두 해당돼요. 여기에는 scope 안의 모든 라이브러리 멤버가 포함되는데, 로컬에 선언됐거나, import 됐거나, doc import로 가져온 것이 모두 포함돼요. import prefix와 함께 가져온 라이브러리 멤버는 그 prefix로 참조할 수 있어요. 예를 들면:

import 'dart:math' as math;

/// [List] is in scope.
/// So is [math.max].
int x = 7;

클래스, enum, extension, extension type, mixin의 대부분 멤버도 참조할 수 있어요. scope 밖에 있는 멤버를 참조할 땐 그 컨테이너의 이름으로 한정(prefix)해 줘야 해요. 예를 들어 Future 클래스의 wait static 메서드는 문서 주석에서 [Future.wait]로 참조할 수 있어요. 인스턴스 멤버도 마찬가지예요. List 클래스의 add 메서드와 length 속성은 [List.add], [List.length]로 참조할 수 있어요. 컨테이너 멤버가 scope 안에 있을 때는(예: 인스턴스 메서드의 문서 주석) 한정하는 컨테이너 이름 없이 참조할 수 있어요.

abstract class MyList<E> implements List<E> {
  /// Refer to [add] and [contains], which is declared on [Iterable].
  void myMethod() {}
}

이름 없는 생성자(unnamed constructor)는 그 이름 없는 생성자의 tear-off처럼 new 이름으로 참조할 수 있어요. 예를 들어 [DateTime.new]는 이름 없는 DateTime 생성자에 대한 참조예요.

함수의 매개변수와 함수 타입의 매개변수는 scope 안에 있을 때만 문서 주석에서 참조할 수 있어요. 그래서 그 매개변수의 함수에 대한 문서 주석이나, 그 매개변수를 감싸는 함수 타입에 대한 타입 별칭 안에서만 참조할 수 있어요.

타입 매개변수는 scope 안에 있을 때만 문서 주석에서 참조할 수 있어요. 그래서 메서드, 최상위 함수, 타입 별칭의 타입 매개변수는 그 요소의 문서 주석 안에서만 참조할 수 있고, 클래스, enum, extension, extension type, mixin의 타입 매개변수는 그 요소 또는 그 멤버 중 하나의 문서 주석 안에서만 참조할 수 있어요.

클래스, enum, extension type, mixin을 별칭하는 타입 별칭의 문서 주석은, 별칭된 타입의 멤버를 마치 scope 안에 있는 것처럼 참조해서는 안 돼요.

Doc imports

Dart는 @docImport 문서 태그를 지원해요. 이 태그로 실제 import 없이도 문서 주석에서 외부 요소를 참조할 수 있게 해 줘요. 이 태그는 library 지시어 위의 문서 주석 안에 지정할 수 있어요. 예를 들면:

/// @docImport 'dart:async';
library;

/// Doc comments can now reference elements like
/// [Future] and [Future.value] from `dart:async`,
/// even if the library is not imported with an actual import.
class Foo {}

Doc import는 일반 Dart import와 같은 URI 스타일을 지원해요. dart:package: 스킴은 물론 상대 경로도 포함돼요. 다만 deferred(지연)로 쓰거나, as, show, hide로 구성할 수는 없어요.

📌 버전 참고: doc import 지원은 Dart 3.8에서 도입됐어요.

더 알아보기