public SemanticModel(Compilation compilation, SyntaxTree syntaxTree) { Compilation = compilation; SyntaxTree = syntaxTree; // create this in locked mode by default // this blocks accidental type or binding queries until binding is done // (if a type check is done too early, unbound symbol references would cause incorrect type check results) var symbolContext = new SymbolContext(compilation, this); SymbolContext = symbolContext; Binder = new Binder(syntaxTree, symbolContext); TypeManager = new TypeManager(compilation.ResourceTypeProvider, Binder); // name binding is done // allow type queries now symbolContext.Unlock(); this.emitLimitationInfoLazy = new Lazy <EmitLimitationInfo>(() => EmitLimitationCalculator.Calculate(this)); this.symbolHierarchyLazy = new Lazy <SymbolHierarchy>(() => { var hierarchy = new SymbolHierarchy(); hierarchy.AddRoot(this.Root); return(hierarchy); }); this.resourceAncestorsLazy = new Lazy <ResourceAncestorGraph>(() => ResourceAncestorGraph.Compute(syntaxTree, Binder)); }
public SemanticModel(Compilation compilation, BicepFile sourceFile, IFileResolver fileResolver) { Trace.WriteLine($"Building semantic model for {sourceFile.FileUri}"); Compilation = compilation; SourceFile = sourceFile; FileResolver = fileResolver; // create this in locked mode by default // this blocks accidental type or binding queries until binding is done // (if a type check is done too early, unbound symbol references would cause incorrect type check results) var symbolContext = new SymbolContext(compilation, this); SymbolContext = symbolContext; Binder = new Binder(sourceFile, symbolContext); TypeManager = new TypeManager(compilation.ResourceTypeProvider, Binder, fileResolver); // name binding is done // allow type queries now symbolContext.Unlock(); this.emitLimitationInfoLazy = new Lazy <EmitLimitationInfo>(() => EmitLimitationCalculator.Calculate(this)); this.symbolHierarchyLazy = new Lazy <SymbolHierarchy>(() => { var hierarchy = new SymbolHierarchy(); hierarchy.AddRoot(this.Root); return(hierarchy); }); this.resourceAncestorsLazy = new Lazy <ResourceAncestorGraph>(() => ResourceAncestorGraph.Compute(this)); this.ResourceMetadata = new ResourceMetadataCache(this); // lazy loading the linter will delay linter rule loading // and configuration loading until the linter is actually needed this.linterAnalyzerLazy = new Lazy <LinterAnalyzer>(() => new LinterAnalyzer()); this.allResourcesLazy = new Lazy <ImmutableArray <ResourceMetadata> >(() => GetAllResourceMetadata()); // lazy load single use diagnostic set this.allDiagnostics = new Lazy <IEnumerable <IDiagnostic> >(() => AssembleDiagnostics(default));
public SemanticModel(Compilation compilation, BicepFile sourceFile, IFileResolver fileResolver, RootConfiguration configuration) { Trace.WriteLine($"Building semantic model for {sourceFile.FileUri}"); Compilation = compilation; SourceFile = sourceFile; FileResolver = fileResolver; Configuration = configuration; // create this in locked mode by default // this blocks accidental type or binding queries until binding is done // (if a type check is done too early, unbound symbol references would cause incorrect type check results) var symbolContext = new SymbolContext(compilation, this); SymbolContext = symbolContext; Binder = new Binder(compilation.NamespaceProvider, sourceFile, symbolContext); TypeManager = new TypeManager(Binder, fileResolver); // name binding is done // allow type queries now symbolContext.Unlock(); this.emitLimitationInfoLazy = new Lazy <EmitLimitationInfo>(() => EmitLimitationCalculator.Calculate(this)); this.symbolHierarchyLazy = new Lazy <SymbolHierarchy>(() => { var hierarchy = new SymbolHierarchy(); hierarchy.AddRoot(this.Root); return(hierarchy); }); this.resourceAncestorsLazy = new Lazy <ResourceAncestorGraph>(() => ResourceAncestorGraph.Compute(this)); this.ResourceMetadata = new ResourceMetadataCache(this); // lazy loading the linter will delay linter rule loading // and configuration loading until the linter is actually needed this.linterAnalyzerLazy = new Lazy <LinterAnalyzer>(() => new LinterAnalyzer(configuration)); this.allResourcesLazy = new Lazy <ImmutableArray <ResourceMetadata> >(() => GetAllResourceMetadata()); // lazy load single use diagnostic set this.allDiagnostics = new Lazy <IEnumerable <IDiagnostic> >(() => AssembleDiagnostics()); this.parameterTypePropertiesLazy = new Lazy <ImmutableArray <TypeProperty> >(() => { var paramTypeProperties = new List <TypeProperty>(); foreach (var param in this.Root.ParameterDeclarations.DistinctBy(p => p.Name)) { var typePropertyFlags = TypePropertyFlags.WriteOnly; if (SyntaxHelper.TryGetDefaultValue(param.DeclaringParameter) == null) { // if there's no default value, it must be specified typePropertyFlags |= TypePropertyFlags.Required; } var description = SemanticModelHelper.TryGetDescription(this, param.DeclaringParameter); paramTypeProperties.Add(new TypeProperty(param.Name, param.Type, typePropertyFlags, description)); } return(paramTypeProperties.ToImmutableArray()); }); this.outputTypePropertiesLazy = new Lazy <ImmutableArray <TypeProperty> >(() => { var outputTypeProperties = new List <TypeProperty>(); foreach (var output in this.Root.OutputDeclarations.DistinctBy(o => o.Name)) { var description = SemanticModelHelper.TryGetDescription(this, output.DeclaringOutput); outputTypeProperties.Add(new TypeProperty(output.Name, output.Type, TypePropertyFlags.ReadOnly, description)); } return(outputTypeProperties.ToImmutableArray()); }); }
public SemanticModel(Compilation compilation, BicepFile sourceFile, IFileResolver fileResolver, IBicepAnalyzer linterAnalyzer) { Trace.WriteLine($"Building semantic model for {sourceFile.FileUri}"); Compilation = compilation; SourceFile = sourceFile; FileResolver = fileResolver; // create this in locked mode by default // this blocks accidental type or binding queries until binding is done // (if a type check is done too early, unbound symbol references would cause incorrect type check results) var symbolContext = new SymbolContext(compilation, this); SymbolContext = symbolContext; Binder = new Binder(compilation.NamespaceProvider, sourceFile, symbolContext); TypeManager = new TypeManager(compilation.Features, Binder, fileResolver); // name binding is done // allow type queries now symbolContext.Unlock(); this.emitLimitationInfoLazy = new Lazy <EmitLimitationInfo>(() => EmitLimitationCalculator.Calculate(this)); this.symbolHierarchyLazy = new Lazy <SymbolHierarchy>(() => { var hierarchy = new SymbolHierarchy(); hierarchy.AddRoot(this.Root); return(hierarchy); }); this.resourceAncestorsLazy = new Lazy <ResourceAncestorGraph>(() => ResourceAncestorGraph.Compute(this)); this.ResourceMetadata = new ResourceMetadataCache(this); LinterAnalyzer = linterAnalyzer; this.allResourcesLazy = new Lazy <ImmutableArray <ResourceMetadata> >(() => GetAllResourceMetadata()); this.declaredResourcesLazy = new Lazy <ImmutableArray <DeclaredResourceMetadata> >(() => this.AllResources.OfType <DeclaredResourceMetadata>().ToImmutableArray()); // lazy load single use diagnostic set this.allDiagnostics = new Lazy <IEnumerable <IDiagnostic> >(() => AssembleDiagnostics()); this.parametersLazy = new Lazy <ImmutableArray <ParameterMetadata> >(() => { var parameters = new List <ParameterMetadata>(); foreach (var param in this.Root.ParameterDeclarations.DistinctBy(p => p.Name)) { var description = SemanticModelHelper.TryGetDescription(this, param.DeclaringParameter); var isRequired = SyntaxHelper.TryGetDefaultValue(param.DeclaringParameter) == null; if (param.Type is ResourceType resourceType) { // Resource type parameters are a special case, we need to convert to a dedicated // type so we can compare differently for assignment. var type = new UnboundResourceType(resourceType.TypeReference); parameters.Add(new ParameterMetadata(param.Name, type, isRequired, description)); } else { parameters.Add(new ParameterMetadata(param.Name, param.Type, isRequired, description)); } } return(parameters.ToImmutableArray()); }); this.outputsLazy = new Lazy <ImmutableArray <OutputMetadata> >(() => { var outputs = new List <OutputMetadata>(); foreach (var output in this.Root.OutputDeclarations.DistinctBy(o => o.Name)) { var description = SemanticModelHelper.TryGetDescription(this, output.DeclaringOutput); if (output.Type is ResourceType resourceType) { // Resource type parameters are a special case, we need to convert to a dedicated // type so we can compare differently for assignment and code generation. var type = new UnboundResourceType(resourceType.TypeReference); outputs.Add(new OutputMetadata(output.Name, type, description)); } else { outputs.Add(new OutputMetadata(output.Name, output.Type, description)); } } return(outputs.ToImmutableArray()); }); }