Пример #1
0
        private SemanticModel GetSemanticModelInternal(SyntaxTree syntaxTree)
        {
            var builtinNamespaces =
                new NamespaceSymbol[] { new SystemNamespaceSymbol(), new AzNamespaceSymbol() }
            .ToImmutableDictionary(property => property.Name, property => property, LanguageConstants.IdentifierComparer);

            var bindings       = new Dictionary <SyntaxBase, Symbol>();
            var cyclesBySymbol = new Dictionary <DeclaredSymbol, ImmutableArray <DeclaredSymbol> >();

            var hierarchy = new SyntaxHierarchy();

            hierarchy.AddRoot(syntaxTree.ProgramSyntax);

            // 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(new TypeManager(resourceTypeProvider, bindings, cyclesBySymbol, hierarchy), bindings, this);

            // collect declarations
            var declarations       = new List <DeclaredSymbol>();
            var declarationVisitor = new DeclarationVisitor(symbolContext, declarations);

            declarationVisitor.Visit(syntaxTree.ProgramSyntax);

            // in cases of duplicate declarations we will see multiple declaration symbols in the result list
            // for simplicitly we will bind to the first one
            // it may cause follow-on type errors, but there will also be errors about duplicate identifiers as well
            var uniqueDeclarations = declarations
                                     .ToLookup(x => x.Name, LanguageConstants.IdentifierComparer)
                                     .ToImmutableDictionary(x => x.Key, x => x.First(), LanguageConstants.IdentifierComparer);

            // bind identifiers to declarations
            var binder = new NameBindingVisitor(uniqueDeclarations, bindings, builtinNamespaces);

            binder.Visit(syntaxTree.ProgramSyntax);

            var shortestCycleBySymbol = CyclicCheckVisitor.FindCycles(syntaxTree.ProgramSyntax, uniqueDeclarations, bindings);

            foreach (var kvp in shortestCycleBySymbol)
            {
                cyclesBySymbol.Add(kvp.Key, kvp.Value);
            }

            // TODO: Avoid looping 5 times?
            var file = new FileSymbol(
                syntaxTree.FilePath,
                syntaxTree.ProgramSyntax,
                builtinNamespaces,
                declarations.OfType <ParameterSymbol>(),
                declarations.OfType <VariableSymbol>(),
                declarations.OfType <ResourceSymbol>(),
                declarations.OfType <ModuleSymbol>(),
                declarations.OfType <OutputSymbol>());

            // name binding is done
            // allow type queries now
            symbolContext.Unlock();

            return(new SemanticModel(file, symbolContext.TypeManager, bindings));
        }
Пример #2
0
        private SemanticModel GetSemanticModelInternal()
        {
            var builtinNamespaces = new NamespaceSymbol[] { new SystemNamespaceSymbol(), new AzNamespaceSymbol() }.ToImmutableArray();
            var bindings = new Dictionary <SyntaxBase, Symbol>();

            // 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(new TypeManager(bindings), bindings);

            // collect declarations
            var declarations       = new List <DeclaredSymbol>();
            var declarationVisitor = new DeclarationVisitor(symbolContext, declarations);

            declarationVisitor.Visit(this.ProgramSyntax);

            // in cases of duplicate declarations we will see multiple declaration symbols in the result list
            // for simplicitly we will bind to the first one
            // it may cause follow-on type errors, but there will also be errors about duplicate identifiers as well
            var uniqueDeclarations = declarations
                                     .ToLookup(x => x.Name, LanguageConstants.IdentifierComparer)
                                     .ToImmutableDictionary(x => x.Key, x => x.First(), LanguageConstants.IdentifierComparer);

            // bind identifiers to declarations
            var binder = new NameBindingVisitor(uniqueDeclarations, bindings, builtinNamespaces);

            binder.Visit(this.ProgramSyntax);

            // name binding is done
            // allow type queries now
            symbolContext.Unlock();

            // TODO: Avoid looping 4 times?
            var file = new FileSymbol("main",
                                      this.ProgramSyntax,
                                      builtinNamespaces,
                                      declarations.OfType <ParameterSymbol>(),
                                      declarations.OfType <VariableSymbol>(),
                                      declarations.OfType <ResourceSymbol>(),
                                      declarations.OfType <OutputSymbol>());

            return(new SemanticModel(file, symbolContext.TypeManager, bindings));
        }