Skip to content

Commit

Permalink
fix: shorten type names in generated code
Browse files Browse the repository at this point in the history
Full type names tend to cause trouble in generated code. Now, all type names except those that start with "UIComponents." are shortened as much as possible, taking the current namespace and nested types into account.
  • Loading branch information
jonisavo committed Nov 20, 2022
1 parent 6437399 commit 03917ef
Show file tree
Hide file tree
Showing 19 changed files with 200 additions and 38 deletions.
2 changes: 1 addition & 1 deletion Assets/UIComponents.Tests/QueryAttributeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public IEnumerator Should_Log_Errors_If_Query_Yields_No_Results()
Assert.That(component.buttons.Count, Is.EqualTo(0));

_mockLogger.Received().LogError("Query (label): No instances of UnityEngine.UIElements.Label found", component);
_mockLogger.Received().LogError("Query (components): No instances of Tests.QueryAttributeTests.ComponentWithQueryAttribute found", component);
_mockLogger.Received().LogError("Query (components): No instances of UIComponents.Tests.QueryAttributeTests.ComponentWithQueryAttribute found", component);
_mockLogger.Received().LogError("Query (buttons): No instances of UnityEngine.UIElements.Button found", component);
}
}
Expand Down
Binary file modified Assets/UIComponents/Roslyn/UIComponents.Roslyn.Generation.dll
Binary file not shown.
Binary file modified Assets/UIComponents/Roslyn/UIComponents.Roslyn.Generation.pdb
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,29 @@ public partial class UIComponentWithNoOwnDependencies : UIComponent {}
return GeneratorTester.Verify<DependencyAugmentGenerator>(source);
}

[Fact]
public Task It_Handles_Multiple_Namespaces()
{
var firstSource = @"
namespace MyLibrary.Core.Services
{
public interface IService {}
public class Service : IService {}
}
";
var secondSource = @"
using UIComponents;
using MyLibrary.Core.Services;
namespace MyLibrary.GUI.Components
{
[Dependency(typeof(IService), provide: typeof(Service)]
public class MyGUIComponent : UIComponent {}
}
";
return GeneratorTester.Verify<DependencyAugmentGenerator>(firstSource, secondSource);
}

[Fact]
public Task It_Does_Not_Generate_When_Not_Inheriting_Consumer_Interface()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ private partial class NestedProvideComponent : UIComponent
[Provide]
public Dependencies.IDependency Dependency;
[Provide(CastFrom = typeof(IDependency))]
[Provide(CastFrom = typeof(Dependencies.IDependency))]
public Dependencies.Dependency ConcreteDependency;
[Provide]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,81 @@ public void Returns_Null_If_Member_Is_Not_Field_Or_Property()
Assert.Null(memberType);
}
}

public class GetTypeNameForNamespace
{
[Fact]
public void Returns_The_Type_Name_With_Shared_Portions_Removed()
{
var twoPartTypeSymbol = Substitute.For<ITypeSymbol>();
twoPartTypeSymbol
.ToDisplayString()
.Returns("MyLibrary.Service");

var fivePartTypeSymbol = Substitute.For<ITypeSymbol>();
fivePartTypeSymbol
.ToDisplayString()
.Returns("MyLibrary.Services.Area.Internal.Helper");

var twoPartName =
RoslynUtilities.GetTypeNameForNamespace(twoPartTypeSymbol, "MyLibrary");

Assert.Equal("Service", twoPartName);

var fivePartName =
RoslynUtilities.GetTypeNameForNamespace(fivePartTypeSymbol, "MyLibrary.Services.Area");

Assert.Equal("Internal.Helper", fivePartName);
}

[Fact]
public void Returns_Type_Name_If_It_Has_One_Part()
{
var onePartTypeSymbol = Substitute.For<ITypeSymbol>();
onePartTypeSymbol
.ToDisplayString()
.Returns("MyService");

var onePartName =
RoslynUtilities.GetTypeNameForNamespace(onePartTypeSymbol, "MyService");

Assert.Equal("MyService", onePartName);
}

[Fact]
public void Returns_Type_Name_If_There_Is_No_Match()
{
var typeSymbol = Substitute.For<ITypeSymbol>();
typeSymbol
.ToDisplayString()
.Returns("MyLibrary.Services.MyService");
var typeSymbolWithoutGlobal = Substitute.For<ITypeSymbol>();
typeSymbolWithoutGlobal
.ToDisplayString()
.Returns("MyLibrary.Services.MyService");

var newTypeName =
RoslynUtilities.GetTypeNameForNamespace(typeSymbol, "OtherLibrary.Services");
var newTypeNameWithoutGlobal =
RoslynUtilities.GetTypeNameForNamespace(typeSymbolWithoutGlobal, "OtherLibrary.Services");

Assert.Equal("MyLibrary.Services.MyService", newTypeName);
Assert.Equal("MyLibrary.Services.MyService", newTypeNameWithoutGlobal);
}

[Fact]
public void Returns_Type_Name_If_It_Belongs_In_UIComponents()
{
var typeSymbol = Substitute.For<ITypeSymbol>();
typeSymbol
.ToDisplayString()
.Returns("UIComponents.Addressables.AddressableAssetResolver");

var newTypeName =
RoslynUtilities.GetTypeNameForNamespace(typeSymbol, "UIComponents.Samples.Addressables.Stuff");

Assert.Equal("UIComponents.Addressables.AddressableAssetResolver", newTypeName);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public partial class SecondConsumerClass
};

[GeneratedCode("UIComponents.Roslyn.Generation", "1.0.0-alpha.3")]
public IEnumerable<IDependency> GetDependencies()
public override IEnumerable<IDependency> GetDependencies()
{
return UIC_Dependencies;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public partial class SecondConsumerClass
};

[GeneratedCode("UIComponents.Roslyn.Generation", "1.0.0-alpha.3")]
public IEnumerable<IDependency> GetDependencies()
public override IEnumerable<IDependency> GetDependencies()
{
return UIC_Dependencies;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//HintName: MyGUIComponent.Dependencies.g.cs
// <auto-generated>
// This file has been generated automatically by UIComponents.Roslyn.
// Do not attempt to modify it. Any changes will be overridden during compilation.
// </auto-generated>

using System.Collections.Generic;
using UIComponents.DependencyInjection;
using System.CodeDom.Compiler;
using UnityEngine.UIElements;

namespace MyLibrary.GUI.Components
{
public partial class MyGUIComponent
{
[GeneratedCode("UIComponents.Roslyn.Generation", "1.0.0-alpha.3")]
private static readonly IDependency[] UIC_Dependencies = new IDependency[] {
UIComponents.DependencyInjection.Dependency.SingletonFor<UIComponents.IAssetResolver, UIComponents.ResourcesAssetResolver>(),
UIComponents.DependencyInjection.Dependency.SingletonFor<UIComponents.ILogger, UIComponents.DebugLogger>(),
UIComponents.DependencyInjection.Dependency.SingletonFor<Core.Services.IService, Core.Services.Service>()
};

[GeneratedCode("UIComponents.Roslyn.Generation", "1.0.0-alpha.3")]
public override IEnumerable<IDependency> GetDependencies()
{
return UIC_Dependencies;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ private void UIC_SetProvideField<TField, TCastFrom>(ref TField value, string fie
protected override void UIC_PopulateProvideFields()
{
UIC_SetProvideField<Dependencies.IDependency, Dependencies.IDependency>(ref Dependency, "Dependency");
UIC_SetProvideField<Dependencies.Dependency, IDependency>(ref ConcreteDependency, "ConcreteDependency");
UIC_SetProvideField<Components.ParentClass.IOtherDependency, Components.ParentClass.IOtherDependency>(ref OtherDependency, "OtherDependency");
UIC_SetProvideField<Dependencies.Dependency, Dependencies.IDependency>(ref ConcreteDependency, "ConcreteDependency");
UIC_SetProvideField<IOtherDependency, IOtherDependency>(ref OtherDependency, "OtherDependency");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//HintName: Parent.PTwo.PThree.PFour.SecondNestedComponent.Query.g.cs
//HintName: Parent.PTwo.PThree.PFour.SecondNestedComponent.Query.g.cs
// <auto-generated>
// This file has been generated automatically by UIComponents.Roslyn.
// Do not attempt to modify it. Any changes will be overridden during compilation.
Expand All @@ -22,10 +22,10 @@ private partial class SecondNestedComponent
protected override void UIC_PopulateQueryFields()
{
// component
var UIC_componentList = new List<Parent.PTwo.PThree.PFour.FirstNestedComponent>();
this.Query<Parent.PTwo.PThree.PFour.FirstNestedComponent>(null, (string) null).ToList(UIC_componentList);
var UIC_componentList = new List<FirstNestedComponent>();
this.Query<FirstNestedComponent>(null, (string) null).ToList(UIC_componentList);
if (UIC_componentList.Count == 0)
Logger.LogError("Query (component): No instances of Parent.PTwo.PThree.PFour.FirstNestedComponent found", this);
Logger.LogError("Query (component): No instances of FirstNestedComponent found", this);
if (UIC_componentList.Count > 0)
component = UIC_componentList[0];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public struct AugmentGenerationContext

public string GetTypeName(ITypeSymbol type)
{
return RoslynUtilities.GetTypeNameWithoutRootNamespace(type, CurrentTypeNamespace);
var typeName = CurrentTypeSymbol.ToDisplayString();
return RoslynUtilities.GetTypeNameForNamespace(type, typeName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ protected override void GenerateSource(AugmentGenerationContext context, StringB
for (var i = 0; i < _dependencyDescriptions.Count; i++)
{
var dependency = _dependencyDescriptions[i];
stringBuilder.AppendWithPadding(dependency.ToConstructorCallString(), 2);
stringBuilder.AppendWithPadding(dependency.ToConstructorCallString(context), 2);
if (i != _dependencyDescriptions.Count - 1)
stringBuilder.Append(",");
stringBuilder.AppendLine();
Expand All @@ -123,7 +123,11 @@ protected override void GenerateSource(AugmentGenerationContext context, StringB

stringBuilder.AppendWithPadding("public ");

if (RoslynUtilities.HasBaseType(context.CurrentTypeSymbol, _uiComponentSymbol))
var currentTypeHasInterface = context.CurrentTypeSymbol.Interfaces
.Where((interfaceType) => interfaceType.Equals(_dependencyConsumerInterfaceSymbol, SymbolEqualityComparer.Default))
.Any();

if (!currentTypeHasInterface)
stringBuilder.Append("override ");

stringBuilder.AppendLine(@"IEnumerable<IDependency> GetDependencies()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public DependencyDescription(
ScopeAsInt = scopeAsInt;
}

public string ToConstructorCallString()
public string ToConstructorCallString(AugmentGenerationContext context)
{
var stringBuilder = new StringBuilder();
stringBuilder.Append("UIComponents.DependencyInjection.Dependency.");
Expand All @@ -34,9 +34,9 @@ public string ToConstructorCallString()
stringBuilder.Append("TransientFor<");

stringBuilder
.Append(DependencyType.ToDisplayString())
.Append(context.GetTypeName(DependencyType))
.Append(", ")
.Append(ImplementationType.ToDisplayString())
.Append(context.GetTypeName(ImplementationType))
.Append(">()");

return stringBuilder.ToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,12 @@ protected override void GenerateSource(AugmentGenerationContext context, StringB

foreach (var provideDescription in _provideDescriptions)
{
var typeName =
RoslynUtilities.GetTypeNameWithoutRootNamespace(provideDescription.Field.Type, context.CurrentTypeNamespace);
var typeName = context.GetTypeName(provideDescription.Field.Type);
stringBuilder
.AppendWithPadding("UIC_SetProvideField<", 2)
.Append(typeName)
.Append(", ")
.Append(provideDescription.GetCastFromTypeName(context.CurrentTypeNamespace))
.Append(provideDescription.GetCastFromTypeName(context))
.Append(">(ref ")
.Append(provideDescription.Field.Name)
.Append(", ")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.CodeAnalysis;
using System;
using UIComponents.Roslyn.Generation.Utilities;

namespace UIComponents.Roslyn.Generation.Generators.DependencyInjection
Expand All @@ -15,12 +14,12 @@ public ProvideDescription(IFieldSymbol field, INamedTypeSymbol castFromType)
CastFromType = castFromType;
}

public string GetCastFromTypeName(string nameSpace)
public string GetCastFromTypeName(AugmentGenerationContext context)
{
if (CastFromType != null)
return RoslynUtilities.GetTypeNameWithoutRootNamespace(CastFromType, nameSpace);
return context.GetTypeName(CastFromType);

return RoslynUtilities.GetTypeNameWithoutRootNamespace(Field.Type, nameSpace);
return context.GetTypeName(Field.Type);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ protected override void BuildUsingStatements(StringBuilder stringBuilder)
base.BuildUsingStatements(stringBuilder);
}

private void GenerateEffectArrayInitialization(StringBuilder stringBuilder)
private void GenerateEffectArrayInitialization(AugmentGenerationContext context, StringBuilder stringBuilder)
{
stringBuilder
.AppendPadding()
Expand All @@ -66,7 +66,7 @@ private void GenerateEffectArrayInitialization(StringBuilder stringBuilder)

stringBuilder
.AppendWithPadding("new ", 3)
.Append(effect.EffectTypeSymbol.ToDisplayString())
.Append(context.GetTypeName(effect.EffectTypeSymbol))
.Append(effect.CallString);

if (i != _effectDescriptions.Count - 1)
Expand All @@ -90,7 +90,7 @@ protected override void GenerateSource(AugmentGenerationContext context, StringB
.AppendLine("private static UIComponentEffectAttribute[] UIC_EffectAttributes;")
.AppendLine();

GenerateEffectArrayInitialization(stringBuilder);
GenerateEffectArrayInitialization(context, stringBuilder);

stringBuilder.AppendLine($@"
{Constants.GeneratedCodeAttribute}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,25 @@ protected override bool ShouldGenerateSource(AugmentGenerationContext context)
if (!base.ShouldGenerateSource(context))
return false;

if (_queryAttributeSymbol == null)
return false;

_queryDescriptions.Clear();
GetQueryDescriptions(context, _queryDescriptions);

return _queryAttributeSymbol != null && _queryDescriptions.Count > 0;
return _queryDescriptions.Count > 0;
}

private void GenerateQueryAssignment(QueryDescription queryDescription, StringBuilder stringBuilder)
private void GenerateQueryAssignment(
QueryDescription queryDescription,
AugmentGenerationContext context,
StringBuilder stringBuilder)
{
var memberSymbol = queryDescription.MemberSymbol;
var memberType = RoslynUtilities.GetMemberType(memberSymbol);

var namespaceString = memberSymbol.ContainingNamespace.ToDisplayString();
var concreteMemberType = RoslynUtilities.GetConcreteType(memberType);
var concreteMemberTypeName = RoslynUtilities.GetTypeNameWithoutRootNamespace(concreteMemberType, namespaceString);
var concreteMemberTypeName = context.GetTypeName(concreteMemberType);

stringBuilder.AppendLineWithPadding($"// {memberSymbol.Name}", 2);

Expand Down Expand Up @@ -139,7 +144,7 @@ protected override void UIC_PopulateQueryFields()

for (var i = 0; i < _queryDescriptions.Count; i++)
{
GenerateQueryAssignment(_queryDescriptions[i], stringBuilder);
GenerateQueryAssignment(_queryDescriptions[i], context, stringBuilder);

if (i != _queryDescriptions.Count - 1)
stringBuilder.AppendLine();
Expand Down
Loading

0 comments on commit 03917ef

Please sign in to comment.