Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace NetDaemon.HassModel.CodeGenerator;
using Microsoft.CodeAnalysis.CSharp;

namespace NetDaemon.HassModel.CodeGenerator;

internal record ServiceArgument
{
Expand All @@ -14,9 +16,10 @@ internal record ServiceArgument

public string PropertyName => HaName.ToNormalizedPascalCase();

public string VariableName => HaName.ToNormalizedCamelCase();
public string ParameterName => HaName.ToNormalizedCamelCase();

public string ParameterVariableName => Required ? VariableName : $"{VariableName} = null";

public string ParameterDefault => Required ? "" : " = null";
}

internal class ServiceArguments
Expand Down Expand Up @@ -49,15 +52,24 @@ public string GetParametersList()
{
var argumentList = Arguments.OrderByDescending(arg => arg.Required);

var anonymousVariableStr = argumentList.Select(x => $"{x.ParameterTypeName} @{x.ParameterVariableName}");
var anonymousVariableStr = argumentList.Select(x => $"{x.ParameterTypeName} {EscapeIfRequired(x.ParameterName)}{x.ParameterDefault}");

return $"{string.Join(", ", anonymousVariableStr)}";
}

public string GetNewServiceArgumentsTypeExpression()
{
var propertyInitializers = Arguments.Select(x => $"{x.PropertyName} = @{x.VariableName}");
var propertyInitializers = Arguments.Select(x => $"{x.PropertyName} = {EscapeIfRequired(x.ParameterName)}");

return $"new {TypeName} {{ { string.Join(", ", propertyInitializers) } }}";
}

private static string EscapeIfRequired(string name)
{
var match = SyntaxFacts.GetKeywordKind(name) != SyntaxKind.None ||
SyntaxFacts.GetContextualKeywordKind(name) != SyntaxKind.None;

return match ? "@" + name : name;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public static T WithSummaryComment<T>(this T node, string? summary) where T : S
string.IsNullOrWhiteSpace(summary) ? node : node.WithLeadingTrivia(Comment($"///<summary>{summary.ReplaceLineEndings(" ")}</summary>"));

public static T AppendParameterComments<T>(this T node, ServiceArguments arguments) where T : SyntaxNode
=> node.WithLeadingTrivia(node.GetLeadingTrivia().Concat(arguments.Arguments.Select(a => ParameterComment(a.VariableName, a.Comment))));
=> node.WithLeadingTrivia(node.GetLeadingTrivia().Concat(arguments.Arguments.Select(a => ParameterComment(a.ParameterName, a.Comment))));

public static T AppendParameterComment<T>(this T node, string? name, string? description)
where T : SyntaxNode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ private async Task Save<T>(T merged, string fileName)
{
Directory.CreateDirectory(OutputFolder);

var fileStream = File.OpenWrite(fileName);
var fileStream = File.Create(fileName);
await using var _ = fileStream.ConfigureAwait(false);
await JsonSerializer.SerializeAsync(fileStream, merged, JsonSerializerOptions).ConfigureAwait(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,51 @@ public void Run(Entities entities, Services services)

CodeGenTestHelper.AssertCodeCompiles(code.ToString(), appCode);
}


[Fact]
public void TestServiceWithKeyWordFieldName_ParamEscaped()
{
var readOnlyCollection = new HassState[] {
new() { EntityId = "light.light1" },
};

var hassServiceDomains = new HassServiceDomain[] {
new() {
Domain = "light",
Services = new HassService[] {
new() {
Service = "set_value",
Target = new TargetSelector {
Entity = new() { Domain = new [] {"light"} }
},
Fields = new HassServiceField[] {
new() { Field = "class", Selector = new NumberSelector(), },
},
}
}
}
};

// Act:
var code = CodeGenTestHelper.GenerateCompilationUnit(_settings, readOnlyCollection, hassServiceDomains);

var appCode = """
using NetDaemon.HassModel;
using NetDaemon.HassModel.Entities;
using RootNameSpace;

public class Root
{
public void Run(Entities entities, Services services)
{
entities.Light.Light1.SetValue(@class:2);
services.Light.SetValue(new ServiceTarget(), @class:2);
}
}
""";

CodeGenTestHelper.AssertCodeCompiles(code.ToString(), appCode);
}
}