in src/Bicep.Core/TypeSystem/TypeAssignmentVisitor.cs [359:440]
public override void VisitModuleDeclarationSyntax(ModuleDeclarationSyntax syntax)
=> AssignTypeWithDiagnostics(syntax, diagnostics =>
{
var declaredType = typeManager.GetDeclaredType(syntax);
if (declaredType is null)
{
return ErrorType.Empty();
}
var singleDeclaredType = declaredType.UnwrapArrayType();
this.ValidateDecorators(syntax.Decorators, declaredType, diagnostics);
if (singleDeclaredType is ErrorType)
{
return singleDeclaredType;
}
// We need to validate all of the parameters and outputs to make sure they are valid types.
// This is where we surface errors for 'unknown' resource types.
if (singleDeclaredType is ModuleType moduleType &&
moduleType.Body is ObjectType objectType)
{
if (objectType.Properties.TryGetValue(LanguageConstants.ModuleParamsPropertyName, out var paramsProperty)
&& paramsProperty.TypeReference.Type is ObjectType paramsType)
{
foreach (var property in paramsType.Properties.Values)
{
if (property.TypeReference.Type is ResourceParameterType resourceType)
{
if (!features.ResourceTypedParamsAndOutputsEnabled)
{
diagnostics.Write(DiagnosticBuilder.ForPosition(syntax.Path).ParamOrOutputResourceTypeUnsupported());
}
if (!resourceType.DeclaringNamespace.ResourceTypeProvider.HasDefinedType(resourceType.TypeReference))
{
diagnostics.Write(DiagnosticBuilder.ForPosition(syntax.Path).ModuleParamOrOutputResourceTypeUnavailable(resourceType.TypeReference));
}
}
}
}
if (objectType.Properties.TryGetValue(LanguageConstants.ModuleOutputsPropertyName, out var outputsProperty)
&& outputsProperty.TypeReference.Type is ObjectType outputsType)
{
foreach (var property in outputsType.Properties.Values)
{
if (property.TypeReference.Type is ResourceType resourceType)
{
if (!features.ResourceTypedParamsAndOutputsEnabled)
{
diagnostics.Write(DiagnosticBuilder.ForPosition(syntax.Path).ParamOrOutputResourceTypeUnsupported());
}
if (!resourceType.DeclaringNamespace.ResourceTypeProvider.HasDefinedType(resourceType.TypeReference))
{
diagnostics.Write(DiagnosticBuilder.ForPosition(syntax.Path).ModuleParamOrOutputResourceTypeUnavailable(resourceType.TypeReference));
}
}
}
}
}
if (this.binder.GetSymbolInfo(syntax) is ModuleSymbol moduleSymbol && moduleSymbol.TryGetSemanticModel().IsSuccess(out var moduleSemanticModel, out var _))
{
if (moduleSemanticModel.HasErrors())
{
diagnostics.Write(moduleSemanticModel is ArmTemplateSemanticModel
? DiagnosticBuilder.ForPosition(syntax.Path).ReferencedArmTemplateHasErrors()
: DiagnosticBuilder.ForPosition(syntax.Path).ReferencedModuleHasErrors());
}
diagnostics.WriteMultiple(moduleSemanticModel.Parameters.Values.Select(md => md.TypeReference)
.Concat(moduleSemanticModel.Outputs.Select(md => md.TypeReference))
.SelectMany(resourceDerivedTypeDiagnosticReporter.ReportResourceDerivedTypeDiagnostics)
.Select(builder => builder(DiagnosticBuilder.ForPosition(syntax.Path))));
}
return TypeValidator.NarrowTypeAndCollectDiagnostics(typeManager, binder, this.parsingErrorLookup, diagnostics, syntax.Value, declaredType);
});