Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,11 @@ dotnet add package BLite
### 2. Basic Usage

```csharp
using BLite.Bson; // ObjectId
using BLite.Core; // DocumentDbContext
using BLite.Core.Collections; // DocumentCollection<TId, T>, UpsertResult<T>
using BLite.Core.Query; // async LINQ extensions (ToListAsync, ...)

// 1. Define your Entities
public class User
{
Expand Down
4 changes: 2 additions & 2 deletions src/BLite.SourceGenerators/EntityAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static EntityInfo Analyze(INamedTypeSymbol entityType, SemanticModel sema
var entityInfo = new EntityInfo
{
Name = entityType.Name,
Namespace = entityType.ContainingNamespace.ToDisplayString(),
Namespace = SyntaxHelper.GetNamespaceOrEmpty(entityType),
FullTypeName = SyntaxHelper.GetFullName(entityType),
CollectionName = entityType.Name.ToLowerInvariant() + BLiteConventions.DefaultCollectionNameSuffix
};
Expand Down Expand Up @@ -342,7 +342,7 @@ private static void AnalyzeNestedTypesRecursive(
var nestedInfo = new NestedTypeInfo
{
Name = simpleName,
Namespace = nestedTypeSymbol.ContainingNamespace.ToDisplayString(),
Namespace = SyntaxHelper.GetNamespaceOrEmpty(nestedTypeSymbol),
FullTypeName = fullTypeName,
Depth = currentDepth
};
Expand Down
12 changes: 12 additions & 0 deletions src/BLite.SourceGenerators/Helpers/SyntaxHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ public static string GetFullName(INamedTypeSymbol symbol)
.Replace("global::", "");
}

/// <summary>
/// Returns the containing namespace's display string, or an empty string when the
/// symbol lives in the global namespace. <see cref="INamespaceSymbol.ToDisplayString()"/>
/// returns the literal text "&lt;global namespace&gt;" for global types, which produces
/// invalid source and invalid generator hint names if used directly.
/// </summary>
public static string GetNamespaceOrEmpty(ISymbol symbol)
{
var ns = symbol.ContainingNamespace;
return ns is { IsGlobalNamespace: false } ? ns.ToDisplayString() : string.Empty;
}

public static string GetTypeName(ITypeSymbol type)
{
if (type is INamedTypeSymbol namedType &&
Expand Down
28 changes: 21 additions & 7 deletions src/BLite.SourceGenerators/MapperGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
sb.AppendLine();

// Use safeName (Context + Filename) to avoid collisions
var mapperNamespace = $"{dbContext.Namespace}.{safeName}_Mappers";
var mapperNamespace = string.IsNullOrEmpty(dbContext.Namespace)
? $"{safeName}_Mappers"
: $"{dbContext.Namespace}.{safeName}_Mappers";
sb.AppendLine($"namespace {mapperNamespace}");
sb.AppendLine($"{{");

Expand Down Expand Up @@ -169,8 +171,14 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
// Partial DbContext for InitializeCollections (Only for top-level partial classes)
if (!dbContext.IsNested && dbContext.IsPartial)
{
sb.AppendLine($"namespace {dbContext.Namespace}");
sb.AppendLine($"{{");
// Global-namespace DbContexts (e.g. declared in a top-level Program.cs)
// emit the partial class without a namespace wrapper.
var wrapNamespace = !string.IsNullOrEmpty(dbContext.Namespace);
if (wrapNamespace)
{
sb.AppendLine($"namespace {dbContext.Namespace}");
sb.AppendLine($"{{");
}
sb.AppendLine($" public partial class {dbContext.ClassName}");
sb.AppendLine($" {{");
sb.AppendLine($" protected override void InitializeCollections()");
Expand Down Expand Up @@ -289,10 +297,16 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
}

sb.AppendLine($" }}");
sb.AppendLine($"}}");
if (wrapNamespace)
{
sb.AppendLine($"}}");
}
}

spc.AddSource($"{dbContext.Namespace}.{safeName}.Mappers.g.cs", sb.ToString());

var hintName = string.IsNullOrEmpty(dbContext.Namespace)
? $"{safeName}.Mappers.g.cs"
: $"{dbContext.Namespace}.{safeName}.Mappers.g.cs";
spc.AddSource(hintName, sb.ToString());
});

// ── Filter pipeline: emit exactly one {Entity}Filter per unique entity type ──
Expand Down Expand Up @@ -808,7 +822,7 @@ private static string EscapeString(string s)
var info = new DbContextInfo
{
ClassName = classSymbol.Name,
Namespace = classSymbol.ContainingNamespace.ToDisplayString(),
Namespace = SyntaxHelper.GetNamespaceOrEmpty(classSymbol),
FilePath = classDecl.SyntaxTree.FilePath,
IsNested = classSymbol.ContainingType != null,
IsPartial = classDecl.Modifiers.Any(m => m.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.PartialKeyword)),
Expand Down