You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .github/copilot-instructions.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -48,14 +48,16 @@ When setting environment variables for SDK tools (e.g. `sdkmanager`, `avdmanager
48
48
-**Process arguments**: use `ProcessUtils.CreateProcessStartInfo()` and pass arguments as separate strings instead of building a single arguments string yourself. `ProcessUtils` will use `ProcessStartInfo.ArgumentList` when available and fall back to `Arguments` on `netstandard2.0`.
49
49
-**Use `FileUtil`**: file operations like extraction, downloads, checksum verification, and path checks belong in `FileUtil.cs`. Don't duplicate file helpers in domain classes.
50
50
-**Concise XML docs**: omit `<summary>` tags for self-explanatory methods. Only add doc comments when the behavior is non-obvious. Avoid restating the method name.
51
-
-**`netstandard2.0` awareness**: many modern .NET APIs are unavailable or have fewer overloads on `netstandard2.0`. When unsure about API availability, search mslearn to check documentation for the target framework.
51
+
-**`netstandard2.0` awareness**: many modern .NET APIs are unavailable or have fewer overloads on `netstandard2.0`. When unsure about API availability, search mslearn to check documentation for the target framework. UTF-8 literals (`"text"u8`) unavailable on `netstandard2.0` — use `static readonly byte[]` with `Encoding.ASCII.GetBytes()`.
52
+
-**Reuse buffers**: use `ArrayPool<byte>.Shared.Rent()`/`Return()` with `try/finally` for temporary buffers (see `DownloadUtils.cs`). For fixed-size repeated reads, prefer a reusable `readonly byte[]` field. No `stackalloc` across `await` boundaries.
52
53
-**Format your code**: always match the existing file indentation (tabs, not spaces — see `.editorconfig`). Only format code you add or modify; never reformat existing lines.
53
54
-**No whitespace-only diffs**: before committing, run `git diff --stat` and verify only files with intentional code changes appear. If a file shows as fully rewritten (all lines removed and re-added) you have introduced line-ending or trailing-whitespace changes — revert that file with `git checkout -- <file>` and re-apply only your code change. Never commit whitespace-only or line-ending-only changes.
54
55
-**File-scoped namespaces**: all new files should use file-scoped namespaces (`namespace Foo;` instead of `namespace Foo { ... }`).
55
56
-**Static `HttpClient`**: `HttpClient` instances must be `static` to avoid socket exhaustion. See [HttpClient guidelines](https://learn.microsoft.com/dotnet/fundamentals/networking/http/httpclient-guidelines#recommended-use). Do not create per-instance `HttpClient` fields or dispose them in `IDisposable`.
56
57
-[Mono Coding Guidelines](http://www.mono-project.com/community/contributing/coding-guidelines/): tabs, K&R braces, `PascalCase` public members.
57
58
-**No null-forgiving operator (`!`)**: do not use the null-forgiving operator after null checks. Instead, use C# property patterns (e.g. `if (value is { Length: > 0 } v)`) which give the compiler proper non-null flow analysis on all target frameworks including `netstandard2.0`.
58
59
-**Prefer switch expressions**: use C# switch expressions over switch statements for simple value mappings (e.g. `return state switch { "x" => A, _ => B };`). Use switch statements only when the body has side effects or complex logic.
60
+
-**Document thread-safety**: when a class reuses mutable state (buffers, caches) assuming single-caller semantics, add `<remarks>This class is not thread-safe.</remarks>`.
59
61
- Nullable enabled in `AndroidSdk`. `NullableAttributes.cs` excluded on `net10.0+`.
60
62
- Strong-named via `product.snk`. In the AndroidSdk project, tests use `InternalsVisibleTo` with full public key (`Properties/AssemblyInfo.cs`).
61
63
- Assembly names support `$(VendorPrefix)`/`$(VendorSuffix)` for branding forks.
For each changed file, read the **full source file** (not just the diff) to understand surrounding invariants, call patterns, and data flow. If the change modifies a public/internal API or utility, search for callers. Check whether sibling types need the same fix.
39
39
40
+
**Prefer existing repo patterns.** Before suggesting new infrastructure, grep for established patterns (`ArrayPool`, `ObjectPool`, `MemoryStreamPool`, `ProcessUtils`) and follow those.
41
+
40
42
**Form an independent assessment** of what the change does and what problems it has *before* reading the PR description.
Copy file name to clipboardExpand all lines: .github/skills/android-tools-reviewer/references/review-rules.md
+7-2Lines changed: 7 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ Framework. Every API call must work on both targets.
13
13
| Check | What to look for |
14
14
|-------|-----------------|
15
15
|**netstandard2.0 API surface**| Methods/overloads that only exist on net5+. Common traps: `HttpContent.ReadAsStringAsync(CancellationToken)`, `ProcessStartInfo.ArgumentList`, `Environment.IsPrivilegedProcess`, `ArrayPool<T>` (needs `System.Buffers` package on ns2.0). When unsure, check MS Learn docs. |
16
-
|**C# language features**|`init` accessors, `required` keyword, file-scoped types, raw string literals — may need polyfills or `#if` guards. |
16
+
|**C# language features**|`init`, `required`, file-scoped types, raw string literals may need polyfills or `#if` guards. `"text"u8` is not `netstandard2.0`-compatible — use `static readonly byte[]`. |
17
17
|**Conditional compilation**| New API usage should be behind `#if NET5_0_OR_GREATER` (or similar) with a fallback for netstandard2.0. |
18
18
19
19
**Postmortem refs:**#3, #4, #30
@@ -39,7 +39,7 @@ Framework. Every API call must work on both targets.
39
39
|-------|-----------------|
40
40
|**HttpClient must be static**|`HttpClient` instances should be `static readonly` fields, not per-instance. Creating/disposing `HttpClient` leads to socket exhaustion via `TIME_WAIT` accumulation. See [Microsoft guidelines](https://learn.microsoft.com/dotnet/fundamentals/networking/http/httpclient-guidelines). |
41
41
|**No HttpClient injection (YAGNI)**| Don't add `HttpClient` constructor parameters "for testability" unless a caller actually needs it today. The AI tends to over-engineer this. |
42
-
|**ArrayPool for large buffers**| Buffers ≥ 1KB (especially 80KB+ download buffers) should use `ArrayPool<byte>.Shared.Rent()` with `try/finally` return. Large allocations go to the LOH and are expensive to GC. |
42
+
|**ArrayPool for large buffers**| Buffers ≥ 1KB should use `ArrayPool<byte>.Shared.Rent()` with `try/finally` return — see §8 Performance for hot-path details. |
43
43
|**IDisposable**| Classes that own unmanaged resources or expensive managed resources must implement `IDisposable` with a dispose guard (`ThrowIfDisposed`). |
44
44
45
45
**Postmortem refs:**#6, #7, #13
@@ -83,6 +83,7 @@ Framework. Every API call must work on both targets.
83
83
|**File-scoped namespaces**| New files should use `namespace Foo;` (not `namespace Foo { ... }`). Don't reformat existing files. |
84
84
|**No #region directives**|`#region` hides code and makes reviews harder. Remove them. This also applies to banner/section-separator comments (e.g., `// --- Device Tests ---`) — they serve the same purpose as `#region` and signal the file should be split instead. |
85
85
|**Use `record` for data types**| Immutable data-carrier types (progress, version info, license info) should be `record` types. They get value equality, `ToString()`, and deconstruction for free. |
86
+
|**Document thread-safety invariants**| When a class reuses buffers, caches, or mutable state assuming single-caller semantics, add `<remarks>This class is not thread-safe.</remarks>` to the type. Callers need to know if external synchronization is required. |
86
87
|**Remove unused code**| Dead methods, speculative helpers, and code "for later" should be removed. Ship only what's needed. |
87
88
|**No commented-out code**| Commented-out code should be deleted — Git has history. |
88
89
|**Reduce indentation with early returns**| Invert conditions with `continue` or early `return` to reduce nesting. `foreach (var x in items ?? Array.Empty<T>())` eliminates null-check nesting. |
@@ -109,6 +110,10 @@ Framework. Every API call must work on both targets.
109
110
110
111
| Check | What to look for |
111
112
|-------|-----------------|
113
+
|**Reuse hot-path buffers**| Pool repeated `byte[]` allocations with `ArrayPool<byte>.Shared` (see `DownloadUtils.cs`). For fixed-size repeated reads, use a `readonly byte[]` instance field. Document non-thread-safety in `<remarks>`. |
114
+
|**No string intermediates in protocols**| Avoid `int.ToString("x4")`/`int.TryParse()` for hex. Use direct `byte[]` bitwise helpers. |
115
+
|**No `stackalloc` in async I/O**|`stackalloc` prohibited across `await`. Use ArrayPool or instance buffers. |
116
+
|**Reuse loop helpers**| If a loop creates resettable helpers (e.g., `TcpClient`), reuse one instance via `Reconnect()`/`Reset()` instead of `new` per iteration. |
112
117
|**XmlReader over LINQ XML**| For forward-only XML parsing (manifests, config files), use `XmlReader` — it's streaming and allocation-free. `XElement`/`XDocument` builds a full DOM tree. |
113
118
|**p/invoke over process spawn**| For single syscalls like `chmod`, use `[DllImport("libc")]` instead of spawning a child process. Process creation is orders of magnitude more expensive. |
114
119
|**Avoid intermediate collections**| Don't create two lists and `AddRange()` one to the other. Build a single list, or use LINQ to chain. |
0 commit comments