forked from Azure/bicep
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBinder.cs
66 lines (54 loc) · 2.99 KB
/
Binder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Bicep.Core.Extensions;
using Bicep.Core.Features;
using Bicep.Core.Semantics.Namespaces;
using Bicep.Core.Syntax;
using Bicep.Core.TypeSystem;
using Bicep.Core.Workspaces;
namespace Bicep.Core.Semantics
{
public class Binder : IBinder
{
private readonly BicepSourceFile bicepFile;
private readonly ImmutableDictionary<DeclaredSymbol, ImmutableArray<DeclaredSymbol>> cyclesBySymbol;
public Binder(INamespaceProvider namespaceProvider, IFeatureProvider features, BicepSourceFile sourceFile, ISymbolContext symbolContext)
{
// TODO use lazy or some other pattern for init
this.bicepFile = sourceFile;
this.TargetScope = SyntaxHelper.GetTargetScope(sourceFile);
var fileScope = DeclarationVisitor.GetDeclarations(namespaceProvider, features, TargetScope, sourceFile, symbolContext);
this.NamespaceResolver = GetNamespaceResolver(features, namespaceProvider, sourceFile, this.TargetScope, fileScope);
this.Bindings = NameBindingVisitor.GetBindings(sourceFile.ProgramSyntax, NamespaceResolver, fileScope);
this.cyclesBySymbol = CyclicCheckVisitor.FindCycles(sourceFile.ProgramSyntax, this.Bindings);
this.FileSymbol = new FileSymbol(
symbolContext,
sourceFile,
NamespaceResolver,
fileScope);
}
public ResourceScope TargetScope { get; }
public FileSymbol FileSymbol { get; }
public NamespaceResolver NamespaceResolver { get; }
public ImmutableDictionary<SyntaxBase, Symbol> Bindings { get; }
public SyntaxBase? GetParent(SyntaxBase syntax)
=> bicepFile.Hierarchy.GetParent(syntax);
public bool IsDescendant(SyntaxBase node, SyntaxBase potentialAncestor)
=> bicepFile.Hierarchy.IsDescendant(node, potentialAncestor);
/// <summary>
/// Returns the symbol that was bound to the specified syntax node. Will return null for syntax nodes that never get bound to symbols. Otherwise,
/// a symbol will always be returned. Binding failures are represented with a non-null error symbol.
/// </summary>
/// <param name="syntax">the syntax node</param>
public Symbol? GetSymbolInfo(SyntaxBase syntax) => this.Bindings.TryGetValue(syntax);
public ImmutableArray<DeclaredSymbol>? TryGetCycle(DeclaredSymbol declaredSymbol)
=> this.cyclesBySymbol.TryGetValue(declaredSymbol, out var cycle) ? cycle : null;
private static NamespaceResolver GetNamespaceResolver(IFeatureProvider features, INamespaceProvider namespaceProvider, BicepSourceFile sourceFile, ResourceScope targetScope, ILanguageScope fileScope)
{
return NamespaceResolver.Create(features, namespaceProvider, sourceFile, targetScope, fileScope);
}
}
}