-
-
Notifications
You must be signed in to change notification settings - Fork 267
Replace ISourceGenerator with IIncrementalGenerator (#11302) #12271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| namespace Bit.BlazorUI.SourceGenerators.AutoInject; | ||
|
|
||
| internal readonly record struct AutoInjectMember(string Name, string TypeDisplay, bool IsField, bool IsNullable); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,67 +1,51 @@ | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Text; | ||
| using Bit.SourceGenerators; | ||
| using Microsoft.CodeAnalysis; | ||
|
|
||
| namespace Bit.BlazorUI.SourceGenerators.AutoInject; | ||
|
|
||
| public static class AutoInjectRazorComponentHandler | ||
| internal static class AutoInjectRazorComponentHandler | ||
| { | ||
| public static string? Generate(INamedTypeSymbol? classSymbol, IReadOnlyCollection<ISymbol> eligibleMembers) | ||
| public static string? Generate( | ||
| string classNamespace, | ||
| string classNameForCode, | ||
| IReadOnlyCollection<AutoInjectMember> directMembers) | ||
| { | ||
| if (classSymbol is null) | ||
| { | ||
| return null; | ||
| } | ||
|
|
||
| if (AutoInjectHelper.IsContainingSymbolEqualToContainingNamespace(classSymbol) is false) | ||
| { | ||
| return null; | ||
| } | ||
|
|
||
| string classNamespace = classSymbol.ContainingNamespace.ToDisplayString(); | ||
|
|
||
| IReadOnlyCollection<ISymbol> sortedMembers = eligibleMembers.OrderBy(o => o.Name).ToList(); | ||
|
|
||
| string source = $@" | ||
| using Microsoft.AspNetCore.Components; | ||
| using System.ComponentModel; | ||
|
|
||
| namespace {classNamespace} | ||
| {{ | ||
| public partial class {AutoInjectHelper.GenerateClassName(classSymbol)} | ||
| public partial class {classNameForCode} | ||
| {{ | ||
| {GenerateInjectableProperties(sortedMembers)} | ||
| {GenerateInjectableProperties(directMembers)} | ||
| }} | ||
| }}"; | ||
| return source; | ||
| } | ||
|
|
||
| private static string GenerateInjectableProperties(IReadOnlyCollection<ISymbol> eligibleMembers) | ||
| private static string GenerateInjectableProperties(IReadOnlyCollection<AutoInjectMember> members) | ||
| { | ||
| StringBuilder stringBuilder = new StringBuilder(); | ||
|
|
||
| foreach (ISymbol member in eligibleMembers) | ||
| foreach (var member in members) | ||
| { | ||
| if (member is IFieldSymbol fieldSymbol) | ||
| stringBuilder.Append(GenerateProperty(fieldSymbol.Type, fieldSymbol.Name)); | ||
|
|
||
| if (member is IPropertySymbol propertySymbol) | ||
| stringBuilder.Append(GenerateProperty(propertySymbol.Type, propertySymbol.Name)); | ||
| stringBuilder.Append(GenerateProperty(member.TypeDisplay, member.Name)); | ||
| } | ||
|
|
||
| return stringBuilder.ToString(); | ||
| } | ||
|
|
||
| private static string GenerateProperty(ITypeSymbol @type, string name) | ||
| private static string GenerateProperty(string typeDisplay, string name) | ||
| { | ||
| return $@" | ||
| [global::System.CodeDom.Compiler.GeneratedCode(""Bit.SourceGenerators"",""{BitSourceGeneratorUtil.GetPackageVersion()}"")] | ||
| [global::System.Diagnostics.DebuggerNonUserCode] | ||
| [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] | ||
| {"\t\t"}[Inject] | ||
| {"\t\t"}[EditorBrowsable(EditorBrowsableState.Never)] | ||
| {"\t\t"}private {@type} ____{AutoInjectHelper.FormatMemberName(name)} {{ get => {name}; set => {name} = value; }}"; | ||
| {"\t\t"}private {typeDisplay} ____{AutoInjectHelper.FormatMemberName(name)} {{ get => {name}; set => {name} = value; }}"; | ||
| } | ||
|
Comment on lines
+40
to
49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Look for any AutoInject usage on fields (vs properties) to confirm the field path is exercised.
rg -nP '\[AutoInject\]\s*(?:private|protected|internal|public|readonly|static|\s)*\s+\w+[\w\.<>?,\s]*\s+_?\w+\s*;' --type=cs -g '!**/AutoInject/**'
echo '---'
# And confirm TypeDisplay format used in the generator.
rg -nP 'ToDisplayString\(' --type=cs -g 'src/**/AutoInject/AutoInjectSourceGenerator.cs'Repository: bitfoundation/bitplatform Length of output: 6227 🏁 Script executed: #!/bin/bash
# 1. Check for tests covering AutoInject on fields
echo "=== Tests covering AutoInject on fields ==="
fd -e 'cs' -path '**/*Test*' -o -path '**/*test*' | xargs rg -l '\[AutoInject\]' 2>/dev/null | head -20
echo ""
echo "=== AutoInjectRazorComponentHandler property generation ==="
# Check how the property is generated and if it handles type qualification
rg -A5 'private static string GenerateProperty' 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/AutoInjectRazorComponentHandler.cs'
echo ""
echo "=== Check how typeDisplay is used in the handler ==="
# See if typeDisplay is directly used in the template
rg -B5 -A10 'GenerateProperty' 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/AutoInjectRazorComponentHandler.cs' | head -40Repository: bitfoundation/bitplatform Length of output: 3435 🏁 Script executed: #!/bin/bash
# 2. Verify if default ToDisplayString() causes type qualification issues
echo "=== Check if TypeDisplay needs full qualification ==="
rg -B2 -A2 'AutoInjectMember.*TypeDisplay' 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/'
echo ""
echo "=== Look for actual usage patterns in generated properties ==="
# Check if there are example generated outputs or documentation
fd -e 'md' -o -e 'txt' | xargs rg -l 'AutoInject' 2>/dev/null | head -5Repository: bitfoundation/bitplatform Length of output: 1112 🏁 Script executed: #!/bin/bash
# Look for unit tests for AutoInject specifically
echo "=== Unit tests for AutoInject ==="
find . -path '**/*Test*' -o -path '**/*test*' | xargs grep -l 'AutoInject' 2>/dev/null | grep -i test
echo ""
echo "=== Check AutoInjectSourceGenerator for how it creates TypeDisplay ==="
# Show the exact lines where ToDisplayString is called for fields
sed -n '95,110p' 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/AutoInjectSourceGenerator.cs'
echo ""
echo "=== Check if there's handling for types that need fully qualified names ==="
rg -i 'FullyQualified|MinimallyQualified|SymbolDisplayFormat' 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/'
echo ""
echo "=== Check actual field usage with [AutoInject] ==="
# Find a real example and see what happens
rg -A3 '\[AutoInject\]\s*private\s+\w+' 'src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Controllers/FileUploadController.cs'Repository: bitfoundation/bitplatform Length of output: 1636 🏁 Script executed: #!/bin/bash
# Check if there's any generated code that shows actual output
echo "=== Look for integration tests or sample outputs ==="
fd 'AutoInject' -e 'txt' -o -e 'g.cs' 2>/dev/null | head -10
echo ""
echo "=== Check handler files to see if they handle type qualification ==="
cat 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/AutoInjectRazorComponentHandler.cs' | wc -l
echo ""
echo "=== Full AutoInjectRazorComponentHandler.cs to understand context ==="
cat 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/AutoInjectRazorComponentHandler.cs'Repository: bitfoundation/bitplatform Length of output: 1826 🏁 Script executed: #!/bin/bash
# Check if AppSettings is in scope for the FileUploadController
echo "=== Check AppSettings location and namespace ==="
rg -B5 'AppSettings' 'src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Controllers/FileUploadController.cs'
echo ""
echo "=== Check if there are actual compilation tests ==="
# Look for test files that verify generated code compiles
find . -path '*Test*' -name '*.cs' -type f | xargs grep -l 'AutoInject' 2>/dev/null | head -5
echo ""
echo "=== Check AutoInjectNormalClassHandler to see if it has different handling ==="
rg -A20 'private static string GenerateProperty' 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/AutoInjectNormalClassHandler.cs' | head -25Repository: bitfoundation/bitplatform Length of output: 520 🏁 Script executed: #!/bin/bash
# Check if there are any issues reported or TODOs in the AutoInject code
echo "=== Look for FIXMEs, TODOs, or issue comments ==="
rg -i 'todo|fixme|issue|bug|hack' 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/'
echo ""
echo "=== Check if default ToDisplayString actually causes problems by looking at type names used ==="
# Check what types are typically used with [AutoInject]
rg '\[AutoInject\]\s*private\s+(\w+(?:<[^>]+>)?)\s+' -o --replace '$1' | sort | uniq | head -20Repository: bitfoundation/bitplatform Length of output: 2561 🏁 Script executed: #!/bin/bash
# Check what namespaces are in the original files that use [AutoInject]
echo "=== Check using statements in FileUploadController ==="
head -20 'src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Controllers/FileUploadController.cs'
echo ""
echo "=== Check what namespace AppSettings is in ==="
rg -B5 'class AppSettings' 'src/BlazorUI/Demo/' | head -20
echo ""
echo "=== Verify the generated partial class structure ==="
# Check if there are actual generated files we can examine
find . -name '*.g.cs' -path '*AutoInject*' 2>/dev/null | head -5
echo ""
echo "=== Check if the generated files have all necessary usings ==="
# Look for how other generators handle this
rg -B3 -A10 'namespace.*{' 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/AutoInjectNormalClassHandler.cs'Repository: bitfoundation/bitplatform Length of output: 1275 🏁 Script executed: #!/bin/bash
# Check if the concern about missing usings in generated file is valid
echo "=== Look at a complete handler to see if usings are injected ==="
cat 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/AutoInjectNormalClassHandler.cs'Repository: bitfoundation/bitplatform Length of output: 3403 🏁 Script executed: #!/bin/bash
# Check if AutoInjectHelper.FormatMemberName properly handles leading underscores
echo "=== Check FormatMemberName implementation ==="
rg -A10 'FormatMemberName' 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/AutoInjectHelper.cs'
echo ""
echo "=== Verify the generated property compiles for field with underscore ==="
# Look for any actual generated code output or documentation
find . -name '*g.cs' | xargs rg -l 'private.*___' 2>/dev/null | head -3Repository: bitfoundation/bitplatform Length of output: 593 🏁 Script executed: #!/bin/bash
# Final check: does the generated RazorComponentHandler include needed usings?
echo "=== Check if generated code from RazorComponentHandler includes type usings ==="
# The template shows it adds System.ComponentModel and Microsoft.AspNetCore.Components
# but we need to check if it handles user-defined types
echo "Generated template from RazorComponentHandler:"
sed -n '11,28p' 'src/BlazorUI/Bit.BlazorUI.SourceGenerators/AutoInject/AutoInjectRazorComponentHandler.cs'
echo ""
echo "=== Check if similar types work without explicit using (same namespace) ==="
rg 'AppSettings' 'src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/' -B2 -A2 | head -15Repository: bitfoundation/bitplatform Length of output: 2052 Type qualification risk in generated properties — confirm cross-namespace types don't silently fail. The generated property correctly handles field-to-property proxying (e.g.,
🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.