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
21 changes: 21 additions & 0 deletions src/Bicep.Core.IntegrationTests/ScenarioTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7537,4 +7537,25 @@ param bar true

result.Should().NotHaveAnyDiagnostics();
}

[TestMethod]
public void Test_Issue17555()
{
var result = CompilationHelper.Compile("""
metadata name = 'ts-devopspool'
metadata description = 'Creates a managed devops pool'
metadata version = '1.0.0'

@description('Optional, default value is empty. Resource tags. Dictionary of tag names and values. See Tags in templates')
param parTags object = {}

#disable-next-line no-unused-vars
var varTags = union(parTags, {
'ts-name': deployment().properties.template.metadata.name
'ts-version': deployment().properties.template.metadata.version
})
""");

result.Should().NotHaveAnyDiagnostics();
}
}
36 changes: 20 additions & 16 deletions src/Bicep.Core/Semantics/Namespaces/AzNamespaceType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,20 @@ private static ObjectType GetEnvironmentReturnType()
}, null);
}

private static ObjectType GetDeploymentReturnType(bool resourceGroupScope)
private static FunctionResult GetDeploymentReturnResult(SemanticModel model, IDiagnosticWriter diagnostics, FunctionCallSyntaxBase functionCall, ImmutableArray<TypeSymbol> argumentTypes)
{
List<NamedTypeProperty> templateProperties = [new("contentVersion", LanguageConstants.String)];
if (model.Root.MetadataDeclarations.Length > 0)
{
templateProperties.Add(new("metadata", new ObjectType(
"metadataProperties",
TypeSymbolValidationFlags.Default,
model.Root.MetadataDeclarations.Select(md => new NamedTypeProperty(
md.Name,
md.Type,
Description: md.TryGetDescriptionFromDecorator(model))))));
}

// Note: there are other properties which could be included here, but they allow you to break out of the bicep world.
// We're going to omit them and only include what is truly necessary. If we get feature requests to expose more properties, we should discuss this further.
// Properties such as 'template', 'templateHash', 'parameters' depend on the codegen, and feel like they could be fragile.
Expand All @@ -204,10 +216,7 @@ private static ObjectType GetDeploymentReturnType(bool resourceGroupScope)
new NamedTypeProperty("name", LanguageConstants.String),
new NamedTypeProperty("properties", new ObjectType("properties", TypeSymbolValidationFlags.Default, new []
{
new NamedTypeProperty("template", new ObjectType("templateProperties", TypeSymbolValidationFlags.Default, new []
{
new NamedTypeProperty("contentVersion", LanguageConstants.String)
}, null)),
new NamedTypeProperty("template", new ObjectType("templateProperties", TypeSymbolValidationFlags.Default, templateProperties, null)),
new NamedTypeProperty("templateLink", new ObjectType("templateLinkProperties", TypeSymbolValidationFlags.Default, new []
{
new NamedTypeProperty("id", LanguageConstants.String),
Expand All @@ -216,14 +225,14 @@ private static ObjectType GetDeploymentReturnType(bool resourceGroupScope)
}, null)),
};

if (!resourceGroupScope)
if (model.TargetScope != ResourceScope.ResourceGroup)
{
// deployments in the 'resourcegroup' scope do not have the 'location' property. All other scopes do.
var locationProperty = new NamedTypeProperty("location", LanguageConstants.String);
properties = properties.Concat(locationProperty.AsEnumerable());
}

return new ObjectType("deployment", TypeSymbolValidationFlags.Default, properties, null);
return new(new ObjectType("deployment", TypeSymbolValidationFlags.Default, properties, null));
}

private static ObjectType GetDeployerReturnType()
Expand Down Expand Up @@ -315,17 +324,12 @@ private static ObjectType GetDeployerReturnType()

yield return (
new FunctionOverloadBuilder("deployment")
.WithReturnType(GetDeploymentReturnType(resourceGroupScope: true))
.WithReturnResultBuilder(
GetDeploymentReturnResult,
new ObjectType("deployment", TypeSymbolValidationFlags.Default, [], new TypeProperty(LanguageConstants.Any)))
.WithGenericDescription("Returns information about the current deployment operation.")
.Build(),
ResourceScope.ResourceGroup);

yield return (
new FunctionOverloadBuilder("deployment")
.WithReturnType(GetDeploymentReturnType(resourceGroupScope: false))
.WithGenericDescription("Returns information about the current deployment operation.")
.Build(),
ResourceScope.Tenant | ResourceScope.ManagementGroup | ResourceScope.Subscription);
ResourceScope.Tenant | ResourceScope.ManagementGroup | ResourceScope.Subscription | ResourceScope.ResourceGroup);

yield return (
new FunctionOverloadBuilder("deployer")
Expand Down
Loading