5f42d8c9b2
Co-authored-by: omegaleo <5655201+omegaleo@users.noreply.github.com>
261 lines
7.2 KiB
Markdown
261 lines
7.2 KiB
Markdown
# Do We Need IDE Plugins for DocumentationAttribute?
|
|
|
|
## The Question
|
|
|
|
Should we create plugins for Visual Studio and Rider to read `DocumentationAttribute` directly and display it in IDE tooltips?
|
|
|
|
## Quick Answer
|
|
|
|
**NO - Plugins are NOT necessary or recommended.** The standard .NET approach with triple-slash comments is better.
|
|
|
|
## Why Plugins Are Not The Right Solution
|
|
|
|
### 1. Complexity vs. Benefit
|
|
|
|
**Plugin Development Effort:**
|
|
- ✅ Visual Studio plugin: Complex, requires VSIX development
|
|
- ✅ Rider plugin: Requires Kotlin/Java, ReSharper SDK knowledge
|
|
- ✅ VS Code plugin: TypeScript/JavaScript, OmniSharp integration
|
|
- ❌ Maintenance burden: Updates for each IDE version
|
|
- ❌ Testing: Must test across multiple IDE versions
|
|
- ❌ Distribution: Users must install plugins manually
|
|
|
|
**Standard Approach:**
|
|
- ✅ Triple-slash comments: Built into language
|
|
- ✅ XML documentation: MSBuild native support
|
|
- ✅ Works everywhere: All IDEs, all tools
|
|
- ✅ Zero installation: Just works
|
|
- ✅ Zero maintenance: Standard .NET
|
|
|
|
### 2. Limited Adoption
|
|
|
|
**Plugin Reality:**
|
|
- Users must discover the plugin exists
|
|
- Users must manually install it
|
|
- Users must trust third-party plugin
|
|
- Users must update it regularly
|
|
- Many users won't bother
|
|
|
|
**Standard Approach:**
|
|
- Works for everyone immediately
|
|
- No installation needed
|
|
- No trust barrier
|
|
- Standard .NET practice
|
|
|
|
### 3. IDE Extension Points Limitations
|
|
|
|
#### Visual Studio
|
|
|
|
**Documentation Provider API:**
|
|
```csharp
|
|
// VS can extend Quick Info via IAsyncQuickInfoSourceProvider
|
|
// But this is complex and has limitations
|
|
```
|
|
|
|
**Limitations:**
|
|
- Only works in VS (not VS Code, not Rider)
|
|
- Requires COM interop or MEF
|
|
- Performance concerns
|
|
- Must handle all edge cases
|
|
- Complex debugging
|
|
|
|
#### JetBrains Rider
|
|
|
|
**PSI (Program Structure Interface):**
|
|
```kotlin
|
|
// Rider can extend documentation via QuickDoc providers
|
|
// Requires ReSharper SDK
|
|
```
|
|
|
|
**Limitations:**
|
|
- Kotlin/Java development
|
|
- Different from VS approach
|
|
- Must understand Rider's PSI
|
|
- Complex plugin architecture
|
|
|
|
#### VS Code
|
|
|
|
**Language Server Protocol:**
|
|
```typescript
|
|
// Must extend OmniSharp or create custom language server
|
|
```
|
|
|
|
**Limitations:**
|
|
- Requires LSP knowledge
|
|
- Different architecture again
|
|
- Must integrate with C# extension
|
|
|
|
### 4. The Standard Solution Works Better
|
|
|
|
**What We Have:**
|
|
```csharp
|
|
[Documentation("TryGetValue", "Tries to get the value...", null, "code example")]
|
|
/// <summary>
|
|
/// Tries to get the value from the NeoDictionary for the given key.
|
|
/// </summary>
|
|
/// <param name="key">The key to search for</param>
|
|
/// <param name="value">The value associated with the key, if found</param>
|
|
/// <returns>True if the key was found, false otherwise</returns>
|
|
public bool TryGetValue(TKey key, out TValue value)
|
|
```
|
|
|
|
**How It Works:**
|
|
|
|
1. **In IDE (Developer View):**
|
|
- Rider/VS reads `/// <summary>` from source
|
|
- Shows immediately in tooltips
|
|
- No plugin needed
|
|
|
|
2. **In XML (Consumer View):**
|
|
- XmlDocGenerator reads DocumentationAttribute
|
|
- Augments XML with examples, extended info
|
|
- Consumers get rich documentation
|
|
|
|
3. **Result:**
|
|
- ✅ Best of both worlds
|
|
- ✅ Zero plugins needed
|
|
- ✅ Standard .NET practice
|
|
|
|
## What DocumentationAttribute Provides
|
|
|
|
The attribute is still valuable for:
|
|
|
|
### 1. Code Examples
|
|
```csharp
|
|
[Documentation(..., codeExample: @"```csharp
|
|
var dict = new NeoDictionary<string, int>();
|
|
dict.Add(""key"", 42);
|
|
```")]
|
|
```
|
|
|
|
This goes into `<example>` in XML, which IDEs show in extended documentation.
|
|
|
|
### 2. Structured Metadata
|
|
```csharp
|
|
[Documentation(..., args: new[] {
|
|
"key: The unique identifier",
|
|
"value: The output value"
|
|
})]
|
|
```
|
|
|
|
XmlDocGenerator converts this to proper `<param>` tags.
|
|
|
|
### 3. Build-Time Generation
|
|
- Processes entire assembly
|
|
- Generates consistent documentation
|
|
- Can enforce patterns
|
|
- Single source of truth for metadata
|
|
|
|
## Alternative: Roslyn Analyzer
|
|
|
|
If we want IDE integration, a **Roslyn Analyzer** is better than a plugin:
|
|
|
|
### Benefits
|
|
|
|
✅ **Works in all IDEs** that support Roslyn (VS, Rider, VS Code)
|
|
✅ **No installation** - ships with NuGet package
|
|
✅ **Compile-time warnings** - enforces documentation standards
|
|
✅ **Code fixes** - can generate `///` from attributes
|
|
✅ **Standard approach** - many libraries do this
|
|
|
|
### Example
|
|
|
|
```csharp
|
|
// Analyzer detects missing /// when DocumentationAttribute exists
|
|
[Documentation("MyMethod", "Does something")]
|
|
public void MyMethod() { } // Warning: Add /// summary from Documentation attribute
|
|
|
|
// Code fix can generate:
|
|
[Documentation("MyMethod", "Does something")]
|
|
/// <summary>
|
|
/// Does something
|
|
/// </summary>
|
|
public void MyMethod() { }
|
|
```
|
|
|
|
### Implementation
|
|
|
|
```csharp
|
|
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
|
public class DocumentationAttributeAnalyzer : DiagnosticAnalyzer
|
|
{
|
|
// Detect: Has DocumentationAttribute but no /// summary
|
|
// Suggest: Add /// summary matching the attribute
|
|
}
|
|
|
|
[ExportCodeFixProvider]
|
|
public class DocumentationAttributeCodeFix : CodeFixProvider
|
|
{
|
|
// Generate /// <summary> from DocumentationAttribute
|
|
}
|
|
```
|
|
|
|
**Distribution:**
|
|
- Package with OmegaLeo.HelperLib.Documentation
|
|
- Automatically available to developers
|
|
- No separate installation
|
|
|
|
## Recommendation
|
|
|
|
### For Immediate Solution: Add Triple-Slash Comments ✅
|
|
|
|
```csharp
|
|
[Documentation("TryGetValue", "Tries to get the value...")]
|
|
/// <summary>
|
|
/// Tries to get the value from the NeoDictionary for the given key.
|
|
/// </summary>
|
|
public bool TryGetValue(TKey key, out TValue value)
|
|
```
|
|
|
|
**Why:**
|
|
- Works immediately
|
|
- Standard .NET practice
|
|
- Zero maintenance
|
|
- Universal compatibility
|
|
|
|
### For Future Enhancement: Roslyn Analyzer
|
|
|
|
Create an analyzer that:
|
|
1. Warns when `[Documentation]` exists without `///`
|
|
2. Provides code fix to generate `///` from attribute
|
|
3. Ships with NuGet package
|
|
4. Works in all IDEs
|
|
|
|
**Why:**
|
|
- Better than IDE plugins
|
|
- Works everywhere Roslyn works
|
|
- Standard extensibility model
|
|
- Low maintenance
|
|
|
|
### Do NOT Create IDE Plugins ❌
|
|
|
|
**Reasons:**
|
|
- Too complex for the benefit
|
|
- Limited adoption
|
|
- Maintenance burden
|
|
- Non-standard approach
|
|
- Triple-slash comments solve the problem
|
|
|
|
## Comparison Matrix
|
|
|
|
| Approach | IDE Support | Installation | Maintenance | Adoption | Recommendation |
|
|
|----------|-------------|--------------|-------------|----------|----------------|
|
|
| **Triple-slash `///`** | All IDEs | None | None | ✅ Universal | ✅ **USE THIS** |
|
|
| **XML Files** | All IDEs | None | Low | ✅ Standard | ✅ Already done |
|
|
| **Roslyn Analyzer** | VS, Rider, VS Code | Auto (NuGet) | Low | ✅ High | ⚠️ Future enhancement |
|
|
| **VS Plugin** | VS only | Manual | High | ❌ Low | ❌ **DON'T DO** |
|
|
| **Rider Plugin** | Rider only | Manual | High | ❌ Low | ❌ **DON'T DO** |
|
|
| **VS Code Plugin** | VS Code only | Manual | Medium | ❌ Low | ❌ **DON'T DO** |
|
|
|
|
## Conclusion
|
|
|
|
**No plugins needed.** The standard .NET approach works better:
|
|
|
|
1. ✅ Add `/// <summary>` comments to source code
|
|
2. ✅ Keep `[Documentation]` attributes for extended metadata
|
|
3. ✅ XmlDocGenerator augments XML with attribute content
|
|
4. ✅ Everyone sees documentation in their IDE
|
|
5. ✅ No installation or plugins required
|
|
|
|
If we want to enhance the developer experience, create a **Roslyn Analyzer** (not IDE plugins) that helps keep `///` and `[Documentation]` in sync.
|