From 1c122c29fd77b1dbe6b48b403ab74638ca69016c Mon Sep 17 00:00:00 2001 From: Anthony Martin <38542602+anthony-c-martin@users.noreply.github.com> Date: Wed, 20 Mar 2024 09:43:08 -0400 Subject: [PATCH] Fix for issue 13663 --- .../ScenarioTests.cs | 33 +++++++++++++++++++ .../ArmDeclarationToExpressionConverter.cs | 19 +++++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/Bicep.Core.IntegrationTests/ScenarioTests.cs b/src/Bicep.Core.IntegrationTests/ScenarioTests.cs index 2e012476d41..04e8bc8d43e 100644 --- a/src/Bicep.Core.IntegrationTests/ScenarioTests.cs +++ b/src/Bicep.Core.IntegrationTests/ScenarioTests.cs @@ -5950,4 +5950,37 @@ public void Distinction_between_empty_and_untyped_objects_should_survive_compila ("BCP037", DiagnosticLevel.Warning, """The property "snap" is not allowed on objects of type "{ }". No other properties are allowed."""), }); } + + // https://github.com/Azure/bicep/issues/13663 + [TestMethod] + public void Test_Issue13663() + { + var moduleResult = CompilationHelper.Compile(""" +type moduleTags = { + *: string +} + +@export() +func genModuleTags(moduleName string) moduleTags => { + '${contains(moduleName, 'name') ? 'name' : 'noName '} name': moduleName +} +"""); + + var result = CompilationHelper.Compile( + ("main.bicep", """ +import * as sharedTypes from 'compiled.json' + +var moduleTags = sharedTypes.genModuleTags('name') + +output moduleTags object = moduleTags +"""), + ("compiled.json", moduleResult.Template!.ToString())); + + var evaluated = TemplateEvaluator.Evaluate(result.Template); + + evaluated.Should().HaveValueAtPath("$.outputs['moduleTags'].value", new JObject + { + ["name name"] = "name", + }); + } } diff --git a/src/Bicep.Core/Emit/CompileTimeImports/ArmDeclarationToExpressionConverter.cs b/src/Bicep.Core/Emit/CompileTimeImports/ArmDeclarationToExpressionConverter.cs index 642b4a1af84..b5904e2948f 100644 --- a/src/Bicep.Core/Emit/CompileTimeImports/ArmDeclarationToExpressionConverter.cs +++ b/src/Bicep.Core/Emit/CompileTimeImports/ArmDeclarationToExpressionConverter.cs @@ -409,6 +409,21 @@ private Expression ConvertToVariableValue(string originalName) private Expression ConvertToExpression(IReadOnlyDictionary parsedExpressions, JToken toConvert) { + ObjectPropertyExpression convertObjectProperty(JProperty property) + { + // The ExpressionsEngine.ParseLanguageExpressionsRecursive method represent key name lookups + // by storing the JProperty, rather than the key string. + var key = parsedExpressions.TryGetValue(property, out var keyExpression) ? + ConvertToExpression(keyExpression) : + ConvertToExpression(parsedExpressions, property.Name); + + return new( + sourceSyntax, + key, + ConvertToExpression(parsedExpressions, property.Value)); + } + + if (parsedExpressions.TryGetValue(toConvert, out var armExpression)) { return ConvertToExpression(armExpression); @@ -417,9 +432,7 @@ private Expression ConvertToExpression(IReadOnlyDictionary ExpressionFactory.CreateObject( - objectToCovert.Properties().Select(jProperty => new ObjectPropertyExpression(sourceSyntax, - ConvertToExpression(parsedExpressions, jProperty.Name), - ConvertToExpression(parsedExpressions, jProperty.Value))), + objectToCovert.Properties().Select(convertObjectProperty), sourceSyntax), JArray arrayToConvert => ExpressionFactory.CreateArray( arrayToConvert.Select(item => ConvertToExpression(parsedExpressions, item)),