Skip to content

Commit c03e00d

Browse files
committed
Improve documentation comments and add examples.
1 parent 0d8400f commit c03e00d

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

GEMINI.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Development Charter
2+
3+
## General Instructions
4+
5+
- When generating new Dart code, strictly follow the style conventions defined in [Effective Dart](https://dart.dev/effective-dart).
6+
- Systematically prefer using `const` constructors and literals whenever possible to optimize runtime performance.
7+
8+
## Comments, Documentation and Examples
9+
10+
- Use triple-slash (`///`) doc comments for all public members.
11+
- Use square brackets (`[Name]`) to link to other members within doc comments. Use markdown sparingly.
12+
- Start with a concise, single-sentence summary. If more detail is required, follow with a blank line and a deeper explanation (e.g., edge cases, parameters, error handling, ...).
13+
- Include code examples for non-trivial public APIs. Ensure examples are well-formatted, accurate, and relevant. Veryify that examples compile and produce the advertised output.
14+
15+
## Coding Style and Conventions
16+
17+
### Naming
18+
19+
- File names must use snake-case (e.g., `recipe_card.dart`).
20+
- Class names, enums, and extensions must use upper camel-case (e.g., `RecipeCard`).
21+
- Private class members, variables, and functions (visible only within the file) must be prefixed with an underscore `_`.
22+
23+
### Imports
24+
25+
- Adhere to the `directives_ordering` linter rule: `dart:` imports first, then `package:` imports, then relative imports.
26+
- Within `lib/`, prefer relative imports (e.g., `import 'src/utils.dart';`) over package imports.
27+
28+
### Code Quality
29+
30+
- The code must be free of linter warnings (run `dart analyze` and `dart fix --apply`).
31+
- The code must be auto-formatted (run `dart format .`).
32+
- Embrace strict **null safety**. Avoid using the non-null assertion operator (`!`) unless you can prove adherence to a loop invariant or similar logical guarantee that the compiler cannot infer.
33+
34+
## Logic and Patterns
35+
36+
### Asynchrony
37+
38+
- Prefer `async` / `await` syntax over chaining `Future.then`, `Future.catchError`, etc., for better readability.
39+
- Always return `Future<void>` instead of `void` for asynchronous functions (unless it's an event handler where `void` is required).
40+
41+
### Error Handling
42+
43+
- Throw specific exceptions (e.g., `ArgumentError`, `StateError`, `FormatException`) rather than generic `Exception` strings.
44+
- Catch specific exceptions. Avoid generic `catch (e)` unless you are logging the error or rethrowing it.
45+
46+
## Architecture
47+
48+
- Keep the root `lib/` directory clean. It should primarily contain the public API exports.
49+
- Place implementation details in `lib/src/`. Users of the package should not import files from `lib/src/` directly.
50+
- Avoid introducing new external dependencies in `pubspec.yaml` unless absolutely necessary and no alternative exists in the SDK. If required, justify the addition to the user.
51+
52+
## Testing
53+
54+
- All new code must be accompanied by unit tests in the `test/` folder.
55+
- Structure the tests following the same folder structure as the code under test (e.g., `lib/src/foo/bar.dart` -> `test/foo/bar_test.dart`).
56+
- Use `expect` with literal values or matchers to assert the expected behavior (e.g., `expect(result, 'expected')`, `expect(list, isEmpty)`).
57+
- Group tests by functionality using `group('description', () { ... })`. Avoid declaring a single top-level group in a file.

lib/src/core/token.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ class Token<R> {
5656
int get hashCode => value.hashCode + start.hashCode + stop.hashCode;
5757

5858
/// Combines multiple tokens into a single token with the list of its values.
59+
///
60+
/// ```dart
61+
/// final t1 = Token('a', 'abc', 0, 1);
62+
/// final t2 = Token('b', 'abc', 1, 2);
63+
/// final t3 = Token.join([t1, t2]);
64+
///
65+
/// print(t3.value); // ['a', 'b']
66+
/// print(t3.start); // 0
67+
/// print(t3.stop); // 2
68+
/// ```
5969
static Token<List<T>> join<T>(Iterable<Token<T>> token) {
6070
final iterator = token.iterator;
6171
if (!iterator.moveNext()) {
@@ -85,6 +95,12 @@ class Token<R> {
8595
static final _newlineParser = newline();
8696

8797
/// Converts the [position] index in a [buffer] to a line and column tuple.
98+
///
99+
/// ```dart
100+
/// const buffer = 'a\nb';
101+
/// print(Token.lineAndColumnOf(buffer, 0)); // [1, 1]
102+
/// print(Token.lineAndColumnOf(buffer, 2)); // [2, 1]
103+
/// ```
88104
static List<int> lineAndColumnOf(String buffer, int position) {
89105
var line = 1, offset = 0;
90106
for (final token in newlineParser().token().allMatches(buffer)) {
@@ -99,6 +115,12 @@ class Token<R> {
99115

100116
/// Returns a human readable string representing the [position] index in a
101117
/// [buffer].
118+
///
119+
/// ```dart
120+
/// const buffer = 'a\nb';
121+
/// print(Token.positionString(buffer, 0)); // 1:1
122+
/// print(Token.positionString(buffer, 2)); // 2:1
123+
/// ```
102124
static String positionString(String buffer, int position) {
103125
final lineAndColumn = lineAndColumnOf(buffer, position);
104126
return '${lineAndColumn[0]}:${lineAndColumn[1]}';

0 commit comments

Comments
 (0)