-
-
Notifications
You must be signed in to change notification settings - Fork 184
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #592 from hadashiA/ku/incremental-source-generator
Support Incremental Source Generator
- Loading branch information
Showing
18 changed files
with
1,070 additions
and
123 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
using System; | ||
using System.Text; | ||
|
||
namespace VContainer.SourceGenerator | ||
{ | ||
public class CodeWriter | ||
{ | ||
readonly struct IndentScope : IDisposable | ||
{ | ||
readonly CodeWriter source; | ||
|
||
public IndentScope(CodeWriter source) | ||
{ | ||
this.source = source; | ||
source.IncreasaeIndent(); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
source.DecreaseIndent(); | ||
} | ||
} | ||
|
||
readonly struct BlockScope : IDisposable | ||
{ | ||
readonly CodeWriter source; | ||
|
||
public BlockScope(CodeWriter source, string? startLine = null) | ||
{ | ||
this.source = source; | ||
source.AppendLine(startLine); | ||
source.BeginBlock(); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
source.EndBlock(); | ||
} | ||
} | ||
|
||
readonly StringBuilder buffer = new(); | ||
int indentLevel; | ||
|
||
public void AppendLine(string value = "") | ||
{ | ||
if (string.IsNullOrEmpty(value)) | ||
{ | ||
buffer.AppendLine(); | ||
} | ||
else | ||
{ | ||
buffer.AppendLine($"{new string(' ', indentLevel * 4)} {value}"); | ||
} | ||
} | ||
|
||
public override string ToString() => buffer.ToString(); | ||
|
||
public IDisposable BeginIndentScope() => new IndentScope(this); | ||
public IDisposable BeginBlockScope(string? startLine = null) => new BlockScope(this, startLine); | ||
|
||
public void IncreasaeIndent() | ||
{ | ||
indentLevel++; | ||
} | ||
|
||
public void DecreaseIndent() | ||
{ | ||
if (indentLevel > 0) | ||
indentLevel--; | ||
} | ||
|
||
public void BeginBlock() | ||
{ | ||
AppendLine("{"); | ||
IncreasaeIndent(); | ||
} | ||
|
||
public void EndBlock() | ||
{ | ||
DecreaseIndent(); | ||
AppendLine("}"); | ||
} | ||
|
||
public void Clear() | ||
{ | ||
buffer.Clear(); | ||
indentLevel = 0; | ||
} | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
VContainer.SourceGenerator.Roslyn3/DiagnosticDescriptors.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace VContainer.SourceGenerator | ||
{ | ||
static class DiagnosticDescriptors | ||
{ | ||
const string Category = "VContainer.SourceGenerator.Roslyn3"; | ||
|
||
public static readonly DiagnosticDescriptor UnexpectedErrorDescriptor = new( | ||
id: "VCON0001", | ||
title: "Unexpected error during generation", | ||
messageFormat: "Unexpected error occurred during code generation: {0}", | ||
category: "Usage", | ||
defaultSeverity: DiagnosticSeverity.Error, | ||
isEnabledByDefault: true); | ||
|
||
public static readonly DiagnosticDescriptor AbstractNotAllow = new( | ||
id: "VCON0002", | ||
title: "Injectable type must not be abstract/interface", | ||
messageFormat: "The injectable type of '{0}' is abstract/interface. It is not allowed", | ||
category: Category, | ||
defaultSeverity: DiagnosticSeverity.Error, | ||
isEnabledByDefault: true); | ||
|
||
public static readonly DiagnosticDescriptor MultipleCtorAttributeNotSupported = new( | ||
id: "VCON0003", | ||
title: "[Inject] exists in multiple constructors", | ||
messageFormat: "Multiple [Inject] constructors exists in '{0}'", | ||
category: Category, | ||
defaultSeverity: DiagnosticSeverity.Error, | ||
isEnabledByDefault: true); | ||
|
||
public static readonly DiagnosticDescriptor MultipleInjectMethodNotSupported = new( | ||
id: "VCON0004", | ||
title: "[Inject] exists in multiple methods", | ||
messageFormat: "Multiple [Inject] methods exists in '{0}'", | ||
category: Category, | ||
defaultSeverity: DiagnosticSeverity.Error, | ||
isEnabledByDefault: true); | ||
|
||
public static readonly DiagnosticDescriptor NestedNotSupported = new( | ||
id: "VCON0005", | ||
title: "Nested type is not support to code generation.", | ||
messageFormat: "The injectable object '{0}' is a nested type. It cannot support code generation ", | ||
category: Category, | ||
defaultSeverity: DiagnosticSeverity.Warning, | ||
isEnabledByDefault: true); | ||
|
||
public static readonly DiagnosticDescriptor PrivateConstructorNotSupported = new( | ||
id: "VCON0006", | ||
title: "The private constructor is not supported to code generation.", | ||
messageFormat: "The injectable constructor of '{0}' is private. It cannot support source generator.", | ||
category: Category, | ||
defaultSeverity: DiagnosticSeverity.Warning, | ||
isEnabledByDefault: true); | ||
|
||
public static readonly DiagnosticDescriptor PrivateFieldNotSupported = new( | ||
id: "VCON0007", | ||
title: "The private [Inject] field is not supported to code generation.", | ||
messageFormat: "The [Inject] field '{0}' does not have accessible to set from the same dll. It cannot support to inject by the source generator.", | ||
category: Category, | ||
defaultSeverity: DiagnosticSeverity.Warning, | ||
isEnabledByDefault: true); | ||
|
||
public static readonly DiagnosticDescriptor PrivatePropertyNotSupported = new( | ||
id: "VCON0008", | ||
title: "The private [Inject] property is not supported to code generation", | ||
messageFormat: "The [Inject] '{0}' does not have accessible to set from the same dll. It cannot support to inject by the source generator.", | ||
category: Category, | ||
defaultSeverity: DiagnosticSeverity.Warning, | ||
isEnabledByDefault: true); | ||
|
||
public static readonly DiagnosticDescriptor PrivateMethodNotSupported = new( | ||
id: "VCON0009", | ||
title: "The private [Inject] method is not supported to code generation.", | ||
messageFormat: "The [Inject] '{0}' does not have accessible to call from the same dll. It cannot support inject by the source generator.", | ||
category: Category, | ||
defaultSeverity: DiagnosticSeverity.Warning, | ||
isEnabledByDefault: true); | ||
|
||
public static readonly DiagnosticDescriptor GenericsNotSupported = new( | ||
id: "VCON0010", | ||
title: "The [Inject] constructor or method that require generics argument is not supported to code generation.", | ||
messageFormat: "[Inject] '{0}' needs generic arguments. It cannot inject by the source generator.", | ||
category: Category, | ||
defaultSeverity: DiagnosticSeverity.Warning, | ||
isEnabledByDefault: true); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace VContainer.SourceGenerator | ||
{ | ||
public class ReferenceSymbols | ||
{ | ||
public static ReferenceSymbols? Create(Compilation compilation) | ||
{ | ||
var injectAttribute = compilation.GetTypeByMetadataName("VContainer.InjectAttribute"); | ||
if (injectAttribute is null) | ||
return null; | ||
|
||
return new ReferenceSymbols | ||
{ | ||
VContainerInjectAttribute = injectAttribute, | ||
VContainerInjectIgnoreAttribute = compilation.GetTypeByMetadataName("VContainer.InjectIgnoreAttribute")!, | ||
AttributeBase = compilation.GetTypeByMetadataName("System.Attribute")!, | ||
UnityEngineComponent = compilation.GetTypeByMetadataName("UnityEngine.Component"), | ||
}; | ||
} | ||
|
||
public INamedTypeSymbol VContainerInjectAttribute { get; private set; } = default!; | ||
public INamedTypeSymbol VContainerInjectIgnoreAttribute { get; private set; } = default!; | ||
public INamedTypeSymbol AttributeBase { get; private set; } = default!; | ||
public INamedTypeSymbol? UnityEngineComponent { get; private set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace VContainer.SourceGenerator | ||
{ | ||
public static class SymbolExtensions | ||
{ | ||
public static IEnumerable<ISymbol> GetAllMembers(this INamedTypeSymbol symbol, bool withoutOverride = true) | ||
{ | ||
// Iterate Parent -> Derived | ||
if (symbol.BaseType != null) | ||
{ | ||
foreach (var item in GetAllMembers(symbol.BaseType)) | ||
{ | ||
// override item already iterated in parent type | ||
if (!withoutOverride || !item.IsOverride) | ||
{ | ||
yield return item; | ||
} | ||
} | ||
} | ||
|
||
foreach (var item in symbol.GetMembers()) | ||
{ | ||
if (!withoutOverride || !item.IsOverride) | ||
{ | ||
yield return item; | ||
} | ||
} | ||
} | ||
|
||
public static bool ContainsAttribute(this ISymbol symbol, INamedTypeSymbol attribtue) | ||
{ | ||
return symbol.GetAttributes().Any(x => SymbolEqualityComparer.Default.Equals(x.AttributeClass, attribtue)); | ||
} | ||
|
||
public static IEnumerable<INamedTypeSymbol> GetAllBaseTypes(this INamedTypeSymbol symbol) | ||
{ | ||
var t = symbol.BaseType; | ||
while (t != null) | ||
{ | ||
yield return t; | ||
t = t.BaseType; | ||
} | ||
} | ||
|
||
public static bool CanBeCallFromInternal(this ISymbol symbol) | ||
{ | ||
return symbol.DeclaredAccessibility >= Accessibility.Internal; | ||
} | ||
|
||
public static string GetClassDeclarationName(this INamedTypeSymbol symbol) | ||
{ | ||
if (symbol.TypeArguments.Length == 0) | ||
{ | ||
return symbol.Name; | ||
} | ||
|
||
var sb = new StringBuilder(); | ||
|
||
sb.Append(symbol.Name); | ||
sb.Append('<'); | ||
|
||
var first = true; | ||
foreach (var typeArg in symbol.TypeArguments) | ||
{ | ||
if (!first) | ||
{ | ||
sb.Append(", "); | ||
} | ||
else | ||
{ | ||
first = false; | ||
} | ||
sb.Append(typeArg.Name); | ||
} | ||
|
||
sb.Append('>'); | ||
|
||
return sb.ToString(); | ||
} | ||
|
||
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) => DistinctBy(source, keySelector, null); | ||
|
||
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? comparer) | ||
{ | ||
return DistinctByIterator(source, keySelector, comparer); | ||
} | ||
|
||
static IEnumerable<TSource> DistinctByIterator<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? comparer) | ||
{ | ||
using IEnumerator<TSource> enumerator = source.GetEnumerator(); | ||
|
||
if (enumerator.MoveNext()) | ||
{ | ||
var set = new HashSet<TKey>(comparer); | ||
do | ||
{ | ||
TSource element = enumerator.Current; | ||
if (set.Add(keySelector(element))) | ||
{ | ||
yield return element; | ||
} | ||
} | ||
while (enumerator.MoveNext()); | ||
} | ||
} | ||
} | ||
} |
File renamed without changes.
Oops, something went wrong.
144f8bf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
vcontainer – ./
vcontainer.hadashikick.jp
vcontainer.vercel.app
vcontainer-git-master-hadashia.vercel.app
vcontainer-hadashia.vercel.app