public static LanguageExpression FormatLocallyScopedResourceId(SemanticModel.SemanticModel semanticModel, string fullyQualifiedType, IEnumerable <LanguageExpression> nameSegments) { var initialArgs = new JTokenExpression(fullyQualifiedType).AsEnumerable(); switch (semanticModel.TargetScope) { case ResourceScopeType.TenantScope: var tenantArgs = initialArgs.Concat(nameSegments); return(new FunctionExpression("tenantResourceId", tenantArgs.ToArray(), new LanguageExpression[0])); case ResourceScopeType.SubscriptionScope: var subscriptionArgs = initialArgs.Concat(nameSegments); return(new FunctionExpression("subscriptionResourceId", subscriptionArgs.ToArray(), new LanguageExpression[0])); case ResourceScopeType.ResourceGroupScope: var resourceGroupArgs = initialArgs.Concat(nameSegments); return(new FunctionExpression("resourceId", resourceGroupArgs.ToArray(), new LanguageExpression[0])); case ResourceScopeType.ManagementGroupScope: // We need to do things slightly differently for Management Groups, because there is no IL to output for "Give me a fully-qualified resource id at the current scope", // and we don't even have a mechanism for reliably getting the current scope (e.g. something like 'deployment().scope'). There are plans to add a managementGroupResourceId function, // but until we have it, we should generate unqualified resource Ids. There should not be a risk of collision, because we do not allow mixing of resource scopes in a single bicep file. return(ExpressionConverter.GenerateUnqualifiedResourceId(fullyQualifiedType, nameSegments)); default: // this should have already been caught during compilation throw new InvalidOperationException($"Invalid target scope {semanticModel.TargetScope} for module"); } }
public TypeSymbol GetDeclaredType(ResourceScopeType containingScope, SemanticModel.SemanticModel moduleSemanticModel) { var paramTypeProperties = new List <TypeProperty>(); foreach (var param in moduleSemanticModel.Root.ParameterDeclarations) { var typePropertyFlags = TypePropertyFlags.WriteOnly; if (SyntaxHelper.TryGetDefaultValue(param.DeclaringParameter) == null) { // if there's no default value, it must be specified typePropertyFlags |= TypePropertyFlags.Required; } paramTypeProperties.Add(new TypeProperty(param.Name, param.Type, typePropertyFlags)); } var outputTypeProperties = new List <TypeProperty>(); foreach (var output in moduleSemanticModel.Root.OutputDeclarations) { outputTypeProperties.Add(new TypeProperty(output.Name, output.Type, TypePropertyFlags.ReadOnly)); } return(LanguageConstants.CreateModuleType(paramTypeProperties, outputTypeProperties, moduleSemanticModel.TargetScope, containingScope, "module")); }
public static EmitLimitationInfo Calculate(SemanticModel.SemanticModel semanticModel) { var diagnosticWriter = ToListDiagnosticWriter.Create(); var moduleScopeData = GetSupportedScopeInfo(semanticModel, diagnosticWriter); return(new EmitLimitationInfo(diagnosticWriter.GetDiagnostics(), moduleScopeData)); }
public static ImmutableHashSet <VariableSymbol> GetVariablesToInline(SemanticModel.SemanticModel model) { var visitor = new InlineDependencyVisitor(model); visitor.Visit(model.Root.Syntax); return(visitor.shouldInlineCache .Where(kvp => kvp.Value) .Select(kvp => kvp.Key) .ToImmutableHashSet()); }
private InlineDependencyVisitor(SemanticModel.SemanticModel model) { this.model = model; this.shouldInlineCache = new Dictionary <VariableSymbol, bool>(); this.currentDeclaration = null; }
public TemplateEmitter(SemanticModel.SemanticModel model) { this.model = model; }
public EmitterContext(SemanticModel.SemanticModel semanticModel) { this.SemanticModel = semanticModel; this.VariablesToInline = InlineDependencyVisitor.GetVariablesToInline(semanticModel); this.ResourceDependencies = ResourceDependencyVisitor.GetResourceDependencies(semanticModel); }
public TemplateWriter(JsonTextWriter writer, SemanticModel.SemanticModel semanticModel) { this.writer = writer; this.context = new EmitterContext(semanticModel); this.emitter = new ExpressionEmitter(writer, context); }
public static ImmutableDictionary <ModuleSymbol, ScopeHelper.ScopeData> GetSupportedScopeInfo(SemanticModel.SemanticModel semanticModel, IDiagnosticWriter diagnosticWriter) { var moduleScopeData = new Dictionary <ModuleSymbol, ScopeHelper.ScopeData>(); foreach (var moduleSymbol in semanticModel.Root.ModuleDeclarations) { var scopeProperty = (moduleSymbol.DeclaringModule.Body as ObjectSyntax)?.SafeGetPropertyByName(LanguageConstants.ModuleScopePropertyName); if (scopeProperty == null) { // no scope provided - assume the parent scope moduleScopeData[moduleSymbol] = new ScopeHelper.ScopeData { RequestedScope = semanticModel.TargetScope }; continue; } var scopeType = semanticModel.GetTypeInfo(scopeProperty.Value); var scopeData = ScopeHelper.TryGetScopeData(semanticModel.TargetScope, scopeType); if (scopeData != null) { moduleScopeData[moduleSymbol] = scopeData; continue; } switch (semanticModel.TargetScope) { case ResourceScopeType.TenantScope: diagnosticWriter.Write(scopeProperty.Value, x => x.InvalidModuleScopeForTenantScope()); break; case ResourceScopeType.ManagementGroupScope: diagnosticWriter.Write(scopeProperty.Value, x => x.InvalidModuleScopeForManagementScope()); break; case ResourceScopeType.SubscriptionScope: diagnosticWriter.Write(scopeProperty.Value, x => x.InvalidModuleScopeForSubscriptionScope()); break; case ResourceScopeType.ResourceGroupScope: diagnosticWriter.Write(scopeProperty.Value, x => x.InvalidModuleScopeForResourceGroup()); break; default: throw new InvalidOperationException($"Unrecognized target scope {semanticModel.TargetScope}"); } } return(moduleScopeData.ToImmutableDictionary()); }
public EmitLimitationVisitor(IList <ErrorDiagnostic> diagnostics, SemanticModel.SemanticModel model) { this.diagnostics = diagnostics; this.model = model; }
private ResourceDependencyVisitor(SemanticModel.SemanticModel model) { this.model = model; this.resourceDependencies = new Dictionary <DeclaredSymbol, HashSet <DeclaredSymbol> >(); this.currentDeclaration = null; }
public static ImmutableDictionary <DeclaredSymbol, ImmutableHashSet <DeclaredSymbol> > GetResourceDependencies(SemanticModel.SemanticModel model) { var visitor = new ResourceDependencyVisitor(model); visitor.Visit(model.Root.Syntax); var output = new Dictionary <DeclaredSymbol, ImmutableHashSet <DeclaredSymbol> >(); foreach (var kvp in visitor.resourceDependencies) { if (kvp.Key is ResourceSymbol resourceSymbol) { output[resourceSymbol] = kvp.Value.ToImmutableHashSet(); } if (kvp.Key is ModuleSymbol moduleSymbol) { output[moduleSymbol] = kvp.Value.ToImmutableHashSet(); } } return(output.ToImmutableDictionary()); }