Exemplo n.º 1
0
        public void EmptyHierarchy_GetParent_ShouldThrow()
        {
            var    hierarchy = new SyntaxHierarchy();
            Action fail      = () => hierarchy.GetParent(TestSyntaxFactory.CreateNull());

            fail.Should().Throw <ArgumentException>().WithMessage("Unable to determine parent of specified node of type 'NullLiteralSyntax' at span '[0:0]' because it has not been indexed.");
        }
Exemplo n.º 2
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));
        }
Exemplo n.º 3
0
 public BicepFile(Uri fileUri, ImmutableArray <int> lineStarts, ProgramSyntax programSyntax)
 {
     FileUri       = fileUri;
     LineStarts    = lineStarts;
     ProgramSyntax = programSyntax;
     Hierarchy     = new SyntaxHierarchy();
     Hierarchy.AddRoot(ProgramSyntax);
 }
Exemplo n.º 4
0
 public DeclaredTypeManager(SyntaxHierarchy hierarchy, ITypeManager typeManager, IResourceTypeProvider resourceTypeProvider, IReadOnlyDictionary <SyntaxBase, Symbol> bindings, IReadOnlyDictionary <DeclaredSymbol, ImmutableArray <DeclaredSymbol> > cyclesBySyntax, ResourceScopeType targetScope)
 {
     this.hierarchy            = hierarchy;
     this.typeManager          = typeManager;
     this.resourceTypeProvider = resourceTypeProvider;
     this.bindings             = bindings;
     this.cyclesBySyntax       = cyclesBySyntax;
     this.targetScope          = targetScope;
 }
Exemplo n.º 5
0
        public void EmptyFile_GetProgramParent_ShouldReturnNull()
        {
            var hierarchy = new SyntaxHierarchy();
            var program   = SyntaxFactory.CreateFromText(string.Empty);

            hierarchy.AddRoot(program);

            hierarchy.GetParent(program).Should().BeNull();
        }
Exemplo n.º 6
0
        public void EmptyFile_GetProgramParent_ShouldReturnNull()
        {
            var hierarchy = new SyntaxHierarchy();
            var program   = ParserHelper.Parse(string.Empty);

            hierarchy.AddRoot(program);

            hierarchy.GetParent(program).Should().BeNull();
        }
Exemplo n.º 7
0
 public BicepFile(Uri fileUri, ImmutableArray <int> lineStarts, ProgramSyntax programSyntax)
 {
     FileUri       = fileUri;
     LineStarts    = lineStarts;
     ProgramSyntax = programSyntax;
     Hierarchy     = new SyntaxHierarchy();
     Hierarchy.AddRoot(ProgramSyntax);
     DisabledDiagnosticsCache = new DisabledDiagnosticsCache(ProgramSyntax, lineStarts);
 }
Exemplo n.º 8
0
        public void VariousObjects_ShouldProduceNoDiagnosticsWhenAssignedToObjectType(string displayName, ObjectSyntax @object)
        {
            var hierarchy = new SyntaxHierarchy();

            hierarchy.AddRoot(@object);

            var(narrowedType, diagnostics) = NarrowTypeAndCollectDiagnostics(hierarchy, @object, LanguageConstants.Object);

            diagnostics.Should().BeEmpty();
        }
Exemplo n.º 9
0
        public void Variousobjects_ShouldProduceAnErrorWhenAssignedToString(string displayName, ObjectSyntax @object)
        {
            var hierarchy = new SyntaxHierarchy();

            hierarchy.AddRoot(@object);

            var(narrowedType, diagnostics) = NarrowTypeAndCollectDiagnostics(hierarchy, @object, LanguageConstants.Int);

            diagnostics.Should().HaveCount(1);
            diagnostics.Single().Message.Should().Be("Expected a value of type \"int\" but the provided value is of type \"object\".");
        }
Exemplo n.º 10
0
        public void MinimalResourceShouldBeValid()
        {
            var obj = TestSyntaxFactory.CreateObject(new[]
            {
                TestSyntaxFactory.CreateProperty("name", TestSyntaxFactory.CreateString("test"))
            });

            var hierarchy = new SyntaxHierarchy();

            hierarchy.AddRoot(obj);

            var(_, diagnostics) = NarrowTypeAndCollectDiagnostics(hierarchy, obj, CreateDummyResourceType());

            diagnostics.Should().BeEmpty();
        }
Exemplo n.º 11
0
        public void NonEmtyFile_GetParent_ShouldReturnExpectedNode()
        {
            var hierarchy = new SyntaxHierarchy();
            var program   = SyntaxFactory.CreateFromText("param foo string\r\nvar bar = 42");

            hierarchy.AddRoot(program);
            hierarchy.GetParent(program).Should().BeNull();

            var nodes = SyntaxAggregator.Aggregate(program, new List <SyntaxBase>(),
                                                   (accumulated, current) =>
            {
                accumulated.Add(current);
                return(accumulated);
            },
                                                   accumulated => accumulated);

            var paramDecl = nodes.OfType <ParameterDeclarationSyntax>().Single();

            hierarchy.GetParent(paramDecl).Should().BeSameAs(program);

            var varDecl = nodes.OfType <VariableDeclarationSyntax>().Single();

            hierarchy.GetParent(varDecl).Should().BeSameAs(program);

            var newLine = nodes.OfType <Token>().Single(t => t.Type == TokenType.NewLine);

            hierarchy.GetParent(newLine).Should().BeSameAs(program);

            var paramIdSyntax = nodes.OfType <IdentifierSyntax>().Single(id => string.Equals(id.IdentifierName, "foo"));

            hierarchy.GetParent(paramIdSyntax).Should().BeSameAs(paramDecl);

            var varIdSyntax = nodes.OfType <IdentifierSyntax>().Single(id => string.Equals(id.IdentifierName, "bar"));

            hierarchy.GetParent(varIdSyntax).Should().BeSameAs(varDecl);

            var paramTypeSyntax = nodes.OfType <TypeSyntax>().Single();

            hierarchy.GetParent(paramTypeSyntax).Should().BeSameAs(paramDecl);

            var paramTypeToken = nodes.OfType <Token>().Single(t => t.Type == TokenType.Identifier && string.Equals(t.Text, "string"));

            hierarchy.GetParent(paramTypeToken).Should().BeSameAs(paramTypeSyntax);
        }
Exemplo n.º 12
0
 public TypeAssignmentVisitor(
     IResourceTypeProvider resourceTypeProvider,
     TypeManager typeManager,
     IReadOnlyDictionary <SyntaxBase, Symbol> bindings,
     IReadOnlyDictionary <DeclaredSymbol, ImmutableArray <DeclaredSymbol> > cyclesBySymbol,
     SyntaxHierarchy hierarchy,
     ResourceScopeType targetScope)
 {
     this.resourceTypeProvider = resourceTypeProvider;
     this.typeManager          = typeManager;
     // bindings will be modified by name binding after this object is created
     // so we can't make an immutable copy here
     // (using the IReadOnlyDictionary to prevent accidental mutation)
     this.bindings       = bindings;
     this.cyclesBySymbol = cyclesBySymbol;
     this.assignedTypes  = new Dictionary <SyntaxBase, TypeAssignment>();
     this.hierarchy      = hierarchy;
     this.targetScope    = targetScope;
 }
Exemplo n.º 13
0
        public void ResourceWithValidZonesShouldBeAccepted()
        {
            var obj = TestSyntaxFactory.CreateObject(new[]
            {
                TestSyntaxFactory.CreateProperty("name", TestSyntaxFactory.CreateString("test")),
                TestSyntaxFactory.CreateProperty("zones", TestSyntaxFactory.CreateArray(new []
                {
                    TestSyntaxFactory.CreateArrayItem(TestSyntaxFactory.CreateString("1")),
                    TestSyntaxFactory.CreateArrayItem(TestSyntaxFactory.CreateString("2"))
                }))
            });

            var hierarchy = new SyntaxHierarchy();

            hierarchy.AddRoot(obj);

            var(narrowedType, diagnostics) = NarrowTypeAndCollectDiagnostics(hierarchy, obj, CreateDummyResourceType());
            diagnostics.Should().BeEmpty();
        }
Exemplo n.º 14
0
        public void InvalidArrayValuesShouldBeRejected()
        {
            var obj = TestSyntaxFactory.CreateObject(new[]
            {
                TestSyntaxFactory.CreateProperty("name", TestSyntaxFactory.CreateString("test")),

                // zones is an array of strings - set wrong item types
                TestSyntaxFactory.CreateProperty("zones", TestSyntaxFactory.CreateArray(new[]
                {
                    TestSyntaxFactory.CreateArrayItem(TestSyntaxFactory.CreateBool(true)),
                    TestSyntaxFactory.CreateArrayItem(TestSyntaxFactory.CreateInt(2))
                })),

                // this property is an array - specify a string instead
                TestSyntaxFactory.CreateProperty("managedByExtended", TestSyntaxFactory.CreateString("not an array"))
            });

            var hierarchy = new SyntaxHierarchy();

            hierarchy.AddRoot(obj);

            var(narrowedType, diagnostics) = NarrowTypeAndCollectDiagnostics(hierarchy, obj, CreateDummyResourceType());

            diagnostics.OrderBy(x => x.Message).Should().HaveDiagnostics(new[] {
Exemplo n.º 15
0
        public TypeManager(IResourceTypeProvider resourceTypeProvider, IReadOnlyDictionary <SyntaxBase, Symbol> bindings, IReadOnlyDictionary <DeclaredSymbol, ImmutableArray <DeclaredSymbol> > cyclesBySymbol, SyntaxHierarchy hierarchy, ResourceScopeType targetScope)
        {
            this.ResourceTypeProvider = resourceTypeProvider;

            // bindings will be modified by name binding after this object is created
            // so we can't make an immutable copy here
            // (using the IReadOnlyDictionary to prevent accidental mutation)
            this.typeAssignmentVisitor = new TypeAssignmentVisitor(resourceTypeProvider, this, bindings, cyclesBySymbol, hierarchy, targetScope);

            this.declaredTypeManager = new DeclaredTypeManager(hierarchy, this, resourceTypeProvider, bindings, cyclesBySymbol, targetScope);
        }