Example #1
0
        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");
            }
        }
Example #2
0
        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"));
        }
Example #3
0
        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;
 }
Example #6
0
 public TemplateEmitter(SemanticModel.SemanticModel model)
 {
     this.model = model;
 }
Example #7
0
 public EmitterContext(SemanticModel.SemanticModel semanticModel)
 {
     this.SemanticModel        = semanticModel;
     this.VariablesToInline    = InlineDependencyVisitor.GetVariablesToInline(semanticModel);
     this.ResourceDependencies = ResourceDependencyVisitor.GetResourceDependencies(semanticModel);
 }
Example #8
0
 public TemplateWriter(JsonTextWriter writer, SemanticModel.SemanticModel semanticModel)
 {
     this.writer  = writer;
     this.context = new EmitterContext(semanticModel);
     this.emitter = new ExpressionEmitter(writer, context);
 }
Example #9
0
        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());
        }
Example #10
0
 public EmitLimitationVisitor(IList <ErrorDiagnostic> diagnostics, SemanticModel.SemanticModel model)
 {
     this.diagnostics = diagnostics;
     this.model       = model;
 }
Example #11
0
 private ResourceDependencyVisitor(SemanticModel.SemanticModel model)
 {
     this.model = model;
     this.resourceDependencies = new Dictionary <DeclaredSymbol, HashSet <DeclaredSymbol> >();
     this.currentDeclaration   = null;
 }
Example #12
0
        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());
        }