コード例 #1
0
ファイル: LexerTests.cs プロジェクト: ScriptBox21/Azure-bicep
        public void ValidDisableNextLineDiagnosticsDirective_WithTrailingWhiteSpaceFollowedByComment_ShouldLexCorrectly()
        {
            string text             = "#disable-next-line BCP226   // test";
            var    diagnosticWriter = ToListDiagnosticWriter.Create();
            var    lexer            = new Lexer(new SlidingTextWindow(text), diagnosticWriter);

            lexer.Lex();

            diagnosticWriter.GetDiagnostics().Should().BeEmpty();

            var tokens = lexer.GetTokens();

            tokens.Count().Should().Be(1);

            var leadingTrivia = tokens.First().LeadingTrivia;

            leadingTrivia.Count().Should().Be(3);

            leadingTrivia.Should().SatisfyRespectively(
                x =>
            {
                x.Text.Should().Be("#disable-next-line BCP226");
                x.Type.Should().Be(SyntaxTriviaType.DisableNextLineDiagnosticsDirective);
            },
                x =>
            {
                x.Text.Should().Be("   ");
                x.Type.Should().Be(SyntaxTriviaType.Whitespace);
            },
                x =>
            {
                x.Text.Should().Be("// test");
                x.Type.Should().Be(SyntaxTriviaType.SingleLineComment);
            });
        }
コード例 #2
0
ファイル: LexerTests.cs プロジェクト: ScriptBox21/Azure-bicep
        public void ValidDisableNextLineDiagnosticsDirective_ShouldLexCorrectly()
        {
            string text             = "#disable-next-line BCP226";
            var    diagnosticWriter = ToListDiagnosticWriter.Create();
            var    lexer            = new Lexer(new SlidingTextWindow(text), diagnosticWriter);

            lexer.Lex();

            diagnosticWriter.GetDiagnostics().Should().BeEmpty();

            var tokens = lexer.GetTokens();

            tokens.Count().Should().Be(1);

            var leadingTrivia = tokens.First().LeadingTrivia;

            leadingTrivia.Count().Should().Be(1);

            var disableNextLineSyntaxTrivia = leadingTrivia.First() as DisableNextLineDiagnosticsSyntaxTrivia;

            disableNextLineSyntaxTrivia.Should().NotBeNull();
            disableNextLineSyntaxTrivia !.DiagnosticCodes.Count().Should().Be(1);

            var firstCode = disableNextLineSyntaxTrivia.DiagnosticCodes.First();

            firstCode.Text.Should().Be("BCP226");
            firstCode.Span.Should().Be(new TextSpan(19, 6));

            disableNextLineSyntaxTrivia.Type.Should().Be(SyntaxTriviaType.DisableNextLineDiagnosticsDirective);
            disableNextLineSyntaxTrivia.Text.Should().Be(text);
            disableNextLineSyntaxTrivia.Span.Should().Be(new TextSpan(0, 25));
        }
コード例 #3
0
ファイル: LexerTests.cs プロジェクト: ScriptBox21/Azure-bicep
        public void DisableNextLineDiagnosticsDirectiveWithLeadingWhiteSpace_ShouldLexCorrectly()
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var lexer            = new Lexer(new SlidingTextWindow("   #disable-next-line no-unused-params"), diagnosticWriter);

            lexer.Lex();

            diagnosticWriter.GetDiagnostics().Should().BeEmpty();

            var endOfFileToken = lexer.GetTokens().First(x => x.Type == TokenType.EndOfFile);

            endOfFileToken.Should().NotBeNull();

            var leadingTrivia = endOfFileToken.LeadingTrivia;

            leadingTrivia.Count().Should().Be(2);

            leadingTrivia.Should().SatisfyRespectively(
                x =>
            {
                x.Type.Should().Be(SyntaxTriviaType.Whitespace);
            },
                x =>
            {
                x.Type.Should().Be(SyntaxTriviaType.DisableNextLineDiagnosticsDirective);
            });
        }
コード例 #4
0
ファイル: LexerTests.cs プロジェクト: ScriptBox21/Azure-bicep
        public void DisableNextLineDiagnosticsDirectiveWithInvalidTrailingCharacter_ShouldLexCorrectly()
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var lexer            = new Lexer(new SlidingTextWindow("#disable-next-line BCP037|"), diagnosticWriter);

            lexer.Lex();

            var diagnostics = diagnosticWriter.GetDiagnostics();

            diagnostics.Should().SatisfyRespectively(
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP001");
                x.Message.Should().Be("The following token is not recognized: \"|\".");
            });

            var tokens = lexer.GetTokens();

            var leadingTrivia = tokens[0].LeadingTrivia;

            leadingTrivia.Count().Should().Be(1);

            leadingTrivia.Should().SatisfyRespectively(
                x =>
            {
                x.Type.Should().Be(SyntaxTriviaType.DisableNextLineDiagnosticsDirective);
                x.Text.Should().Be("#disable-next-line BCP037");
            });
        }
コード例 #5
0
ファイル: LexerTests.cs プロジェクト: ScriptBox21/Azure-bicep
        public void ValidDisableNextLineDiagnosticsDirective_WithinResourceAndWithTrailingWhiteSpace_ShouldLexCorrectly()
        {
            string text             = @"resource vm 'Microsoft.Compute/virtualMachines@2020-12-01' = {
#disable-next-line BCP226   
  properties: vmProperties
}";
            var    diagnosticWriter = ToListDiagnosticWriter.Create();
            var    lexer            = new Lexer(new SlidingTextWindow(text), diagnosticWriter);

            lexer.Lex();

            diagnosticWriter.GetDiagnostics().Should().BeEmpty();

            var tokens = lexer.GetTokens();

            tokens.Count().Should().Be(13);

            var leadingTrivia = tokens.ElementAt(6).LeadingTrivia;

            leadingTrivia.Count().Should().Be(2);

            leadingTrivia.Should().SatisfyRespectively(
                x =>
            {
                x.Text.Should().Be("#disable-next-line BCP226");
                x.Type.Should().Be(SyntaxTriviaType.DisableNextLineDiagnosticsDirective);
            },
                x =>
            {
                x.Text.Should().Be("   ");
                x.Type.Should().Be(SyntaxTriviaType.Whitespace);
            });
        }
コード例 #6
0
        private void AssignTypeWithDiagnostics(SyntaxBase syntax, Func <IDiagnosticWriter, ITypeReference> assignFunc)
        => AssignTypeWithCaching(syntax, () => {
            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var reference        = assignFunc(diagnosticWriter);

            return(new TypeAssignment(reference, diagnosticWriter.GetDiagnostics()));
        });
コード例 #7
0
        private static void RunSingleTokenTest(string text, TokenType expectedTokenType, string expectedMessage, string expectedCode, int expectedStartPosition = 0, int?expectedLength = null, string?expectedTokenText = null)
        {
            expectedTokenText ??= text;
            expectedLength ??= text.Length - expectedStartPosition;

            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var lexer            = new Lexer(new SlidingTextWindow(text), diagnosticWriter);

            lexer.Lex();

            var tokens = lexer.GetTokens().ToImmutableArray();

            tokens.Should().HaveCount(2);
            tokens.Select(t => t.Type).Should().Equal(expectedTokenType, TokenType.EndOfFile);

            tokens.First().Text.Should().Be(expectedTokenText);

            var errors = diagnosticWriter.GetDiagnostics();

            errors.Should().HaveCount(1);

            var error = errors.Single();

            error.Message.Should().Be(expectedMessage);
            error.Code.Should().Be(expectedCode);
            error.Span.Position.Should().Be(expectedStartPosition);
            error.Span.Length.Should().Be(expectedLength);
        }
コード例 #8
0
        public void UnterminatedStringUnexpectedNewline_ShouldBeRecognizedWithError()
        {
            var text             = "'unfinished\n'even more unfinished\r\n'test'";
            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var lexer            = new Lexer(new SlidingTextWindow(text), diagnosticWriter);

            lexer.Lex();

            var tokens = lexer.GetTokens().ToImmutableArray();

            tokens.Should().HaveCount(6);

            tokens.Select(t => t.Type).Should().Equal(TokenType.StringComplete, TokenType.NewLine, TokenType.StringComplete, TokenType.NewLine, TokenType.StringComplete, TokenType.EndOfFile);

            var expectedTexts = new[]
            {
                "'unfinished",
                "\n",
                "'even more unfinished",
                "\r\n",
                "'test'",
                string.Empty
            };

            tokens.Select(t => t.Text).Should().Equal(expectedTexts);

            tokens.Select(t => t.Span.Position).Should().Equal(expectedTexts.Select((s, i) => expectedTexts.Take(i).Select(s => s.Length).Sum()));
            tokens.Select(t => t.Span.Length).Should().Equal(expectedTexts.Select(s => s.Length));
        }
コード例 #9
0
        public void NonExpressionShouldProduceNoViolations(string displayName, SyntaxBase expression)
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();

            TypeValidator.GetCompileTimeConstantViolation(expression, diagnosticWriter);

            diagnosticWriter.GetDiagnostics().Should().BeEmpty();
        }
コード例 #10
0
        public static EmitLimitationInfo Calculate(SemanticModel.SemanticModel semanticModel)
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();

            var moduleScopeData = GetSupportedScopeInfo(semanticModel, diagnosticWriter);

            return(new EmitLimitationInfo(diagnosticWriter.GetDiagnostics(), moduleScopeData));
        }
コード例 #11
0
        public void NonLiteralExpression_IsLiteralExpression_ShouldReturnViolations(string displayName, SyntaxBase expression)
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();

            TypeValidator.GetCompileTimeConstantViolation(expression, diagnosticWriter);

            diagnosticWriter.GetDiagnostics().Should().NotBeEmpty();
        }
コード例 #12
0
        private IEnumerable <Token> GetLineEndingTokens(string contents)
        {
            var lexer = new Lexer(new SlidingTextWindow(contents), ToListDiagnosticWriter.Create());

            lexer.Lex();

            return(lexer.GetTokens().Where(token => token.Type == TokenType.NewLine));
        }
コード例 #13
0
        public static IReadOnlyList <IDiagnostic> GetParseDiagnostics(this SyntaxBase syntax)
        {
            var diagnosticWriter  = ToListDiagnosticWriter.Create();
            var parseErrorVisitor = new ParseDiagnosticsVisitor(diagnosticWriter);

            parseErrorVisitor.Visit(syntax);

            return(diagnosticWriter.GetDiagnostics());
        }
コード例 #14
0
        /// <summary>
        /// Gets all the analyzer diagnostics unsorted.
        /// </summary>
        /// <returns></returns>
        public IReadOnlyList <IDiagnostic> GetAnalyzerDiagnostics()
        {
            var diagnostics = LinterAnalyzer.Analyze(this);

            var diagnosticWriter = ToListDiagnosticWriter.Create();

            diagnosticWriter.WriteMultiple(diagnostics);

            return(diagnosticWriter.GetDiagnostics());
        }
コード例 #15
0
        public static EmitLimitationInfo Calculate(SemanticModel model)
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();

            var moduleScopeData   = GetSupportedScopeInfo(model, diagnosticWriter);
            var resourceScopeData = GetResoureScopeInfo(model, diagnosticWriter);

            DeployTimeConstantVisitor.ValidateDeployTimeConstants(model, diagnosticWriter);

            return(new EmitLimitationInfo(diagnosticWriter.GetDiagnostics(), moduleScopeData, resourceScopeData));
        }
コード例 #16
0
        public void LexerShouldProduceValidStringLiteralTokensOnValidFiles(DataSet dataSet)
        {
            var lexer = new Lexer(new SlidingTextWindow(dataSet.Bicep), ToListDiagnosticWriter.Create());

            lexer.Lex();

            foreach (Token stringToken in lexer.GetTokens().Where(token => token.Type == TokenType.StringComplete))
            {
                Lexer.TryGetStringValue(stringToken).Should().NotBeNull($"because string token at span {stringToken.Span} should have a string value. Token Text = {stringToken.Text}");
            }
        }
コード例 #17
0
        public void CompleteStringsWithUnicodeEscapes_ShouldLexCorrectly(string text)
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var lexer            = new Lexer(new SlidingTextWindow(text), diagnosticWriter);

            lexer.Lex();

            diagnosticWriter.GetDiagnostics().Should().BeEmpty();

            lexer.GetTokens().Select(t => t.Type).Should().Equal(TokenType.StringComplete, TokenType.EndOfFile);
        }
コード例 #18
0
ファイル: Parser.cs プロジェクト: charotAmine/bicep
        public Parser(string text)
        {
            // treating the lexer as an implementation detail of the parser
            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var lexer            = new Lexer(new SlidingTextWindow(text), diagnosticWriter);

            lexer.Lex();

            this.lexerDiagnostics = diagnosticWriter.GetDiagnostics().ToImmutableArray();

            this.reader = new TokenReader(lexer.GetTokens());
        }
コード例 #19
0
        public void LexerShouldRoundtrip(DataSet dataSet)
        {
            var lexer = new Lexer(new SlidingTextWindow(dataSet.Bicep), ToListDiagnosticWriter.Create());

            lexer.Lex();

            var serialized = new StringBuilder();

            new TokenWriter(serialized).WriteTokens(lexer.GetTokens());

            serialized.ToString().Should().Be(dataSet.Bicep, "because the lexer should not lose information");
        }
コード例 #20
0
        public static EmitLimitationInfo Calculate(SemanticModel model)
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();

            var moduleScopeData   = ScopeHelper.GetModuleScopeInfo(model, diagnosticWriter);
            var resourceScopeData = ScopeHelper.GetResoureScopeInfo(model, diagnosticWriter);

            DeployTimeConstantVisitor.ValidateDeployTimeConstants(model, diagnosticWriter);

            diagnosticWriter.WriteMultiple(DetectDuplicateNames(model, resourceScopeData, moduleScopeData));

            return(new EmitLimitationInfo(diagnosticWriter.GetDiagnostics(), moduleScopeData, resourceScopeData));
        }
コード例 #21
0
        /// <summary>
        /// Gets all the semantic diagnostics unsorted. Does not include parser and lexer diagnostics.
        /// </summary>
        /// <returns></returns>
        public IReadOnlyList <Diagnostic> GetSemanticDiagnostics()
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();

            var visitor = new SemanticDiagnosticVisitor(diagnosticWriter);

            visitor.Visit(this.Root);

            var typeValidationDiagnostics = typeManager.GetAllDiagnostics();

            diagnosticWriter.WriteMultiple(typeValidationDiagnostics);

            return(diagnosticWriter.GetDiagnostics());
        }
コード例 #22
0
        public void LexerShouldProduceValidTokenLocations(DataSet dataSet)
        {
            var lexer = new Lexer(new SlidingTextWindow(dataSet.Bicep), ToListDiagnosticWriter.Create());

            lexer.Lex();

            foreach (Token token in lexer.GetTokens())
            {
                // lookup the text of the token in original contents by token's span
                string tokenText = dataSet.Bicep[new Range(token.Span.Position, token.GetEndPosition())];

                tokenText.Should().Be(token.Text, "because token text at location should match original contents at the same location");
            }
        }
コード例 #23
0
ファイル: LexerTests.cs プロジェクト: Princetimber/bicep-1
        public void Multiline_strings_should_lex_correctly(string text, string expectedValue)
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var lexer            = new Lexer(new SlidingTextWindow(text), diagnosticWriter);

            lexer.Lex();

            lexer.GetTokens().Select(t => t.Type).Should().Equal(TokenType.MultilineString, TokenType.EndOfFile);

            var multilineToken = lexer.GetTokens().First();

            multilineToken.Text.Should().Be(text);
            Lexer.TryGetMultilineStringValue(multilineToken).Should().Be(expectedValue);
        }
コード例 #24
0
ファイル: SemanticModel.cs プロジェクト: rchaganti/bicep
        /// <summary>
        /// Gets all the analyzer diagnostics unsorted.
        /// </summary>
        /// <returns></returns>
        public IReadOnlyList <IDiagnostic> GetAnalyzerDiagnostics(ConfigHelper?overrideConfig = default)
        {
            if (overrideConfig != default)
            {
                LinterAnalyzer.OverrideConfig(overrideConfig);
            }

            var diagnostics      = LinterAnalyzer.Analyze(this, overrideConfig);
            var diagnosticWriter = ToListDiagnosticWriter.Create();

            diagnosticWriter.WriteMultiple(diagnostics);

            return(diagnosticWriter.GetDiagnostics());
        }
コード例 #25
0
ファイル: LexerTests.cs プロジェクト: Princetimber/bicep-1
        public void Unterminated_multiline_strings_should_attach_a_diagnostic(string text)
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var lexer            = new Lexer(new SlidingTextWindow(text), diagnosticWriter);

            lexer.Lex();

            lexer.GetTokens().Select(t => t.Type).Should().Equal(TokenType.MultilineString, TokenType.EndOfFile);
            var diagnostics = diagnosticWriter.GetDiagnostics().ToList();

            diagnostics.Should().HaveCount(1);
            var diagnostic = diagnostics.Single();

            diagnostic.Code.Should().Be("BCP140");
            diagnostic.Message.Should().Be($"The multi-line string at this location is not terminated. Terminate it with \"'''\".");
        }
コード例 #26
0
ファイル: LexerTests.cs プロジェクト: ScriptBox21/Azure-bicep
        public void MissingCodesInDisableNextLineDiagnosticsDirective_ShouldBeRecognizedWithError()
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var lexer            = new Lexer(new SlidingTextWindow("#disable-next-line"), diagnosticWriter);

            lexer.Lex();

            var diagnostics = diagnosticWriter.GetDiagnostics();

            diagnostics.Should().SatisfyRespectively(
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP226");
                x.Message.Should().Be("Expected at least one diagnostic code at this location. Valid format is \"#disable-next-line diagnosticCode1 diagnosticCode2 ...\"");
            });
        }
コード例 #27
0
        public static EmitLimitationInfo Calculate(SemanticModel model)
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();

            var moduleScopeData   = ScopeHelper.GetModuleScopeInfo(model, diagnosticWriter);
            var resourceScopeData = ScopeHelper.GetResourceScopeInfo(model, diagnosticWriter);

            DeployTimeConstantValidator.Validate(model, diagnosticWriter);
            ForSyntaxValidatorVisitor.Validate(model, diagnosticWriter);
            FunctionPlacementValidatorVisitor.Validate(model, diagnosticWriter);

            DetectDuplicateNames(model, diagnosticWriter, resourceScopeData, moduleScopeData);
            DetectIncorrectlyFormattedNames(model, diagnosticWriter);
            DetectUnexpectedResourceLoopInvariantProperties(model, diagnosticWriter);
            DetectUnexpectedModuleLoopInvariantProperties(model, diagnosticWriter);
            DetectUnsupportedModuleParameterAssignments(model, diagnosticWriter);

            return(new EmitLimitationInfo(diagnosticWriter.GetDiagnostics(), moduleScopeData, resourceScopeData));
        }
コード例 #28
0
        public void InvalidUnicodeEscapes_ShouldProduceExpectedDiagnostic(string text, string expectedSpanText)
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();
            var lexer            = new Lexer(new SlidingTextWindow(text), diagnosticWriter);

            lexer.Lex();

            lexer.GetTokens().Select(t => t.Type).Should().Equal(TokenType.StringComplete, TokenType.EndOfFile);
            var diagnostics = diagnosticWriter.GetDiagnostics().ToList();

            diagnostics.Should().HaveCount(1);
            var diagnostic = diagnostics.Single();

            diagnostic.Code.Should().Be("BCP133");
            diagnostic.Message.Should().Be(@"The unicode escape sequence is not valid. Valid unicode escape sequences range from \u{0} to \u{10FFFF}.");

            var spanText = text[new Range(diagnostic.Span.Position, diagnostic.Span.GetEndPosition())];

            spanText.Should().Be(expectedSpanText);
        }
コード例 #29
0
        /// <summary>
        /// Gets all the semantic diagnostics unsorted. Does not include parser and lexer diagnostics.
        /// </summary>
        /// <returns></returns>
        public IReadOnlyList <IDiagnostic> GetSemanticDiagnostics()
        {
            var diagnosticWriter = ToListDiagnosticWriter.Create();

            var visitor = new SemanticDiagnosticVisitor(diagnosticWriter);

            visitor.Visit(this.Root);

            foreach (var missingDeclarationSyntax in this.SourceFile.ProgramSyntax.Children.OfType <MissingDeclarationSyntax>())
            {
                // Trigger type checking manually as missing declarations are not bound to any symbol.
                this.TypeManager.GetTypeInfo(missingDeclarationSyntax);
            }

            var typeValidationDiagnostics = TypeManager.GetAllDiagnostics();

            diagnosticWriter.WriteMultiple(typeValidationDiagnostics);
            diagnosticWriter.WriteMultiple(EmitLimitationInfo.Diagnostics);

            return(diagnosticWriter.GetDiagnostics());
        }
コード例 #30
0
        public void LexerShouldProduceContiguousSpans(DataSet dataSet)
        {
            var lexer = new Lexer(new SlidingTextWindow(dataSet.Bicep), ToListDiagnosticWriter.Create());

            lexer.Lex();

            int visitedPosition = 0;

            // local function
            void VisitSpan(TextSpan span, string text)
            {
                // the token should begin at the position where the previous token ended
                span.Position.Should().Be(visitedPosition, $"because token or trivia '{text}' at span '{span}' should begin at position {visitedPosition}.");

                // cover the span of the token
                visitedPosition += span.Length;
            }

            // local function
            void VisitTrivia(IEnumerable <SyntaxTrivia> trivia)
            {
                foreach (var trivium in trivia)
                {
                    VisitSpan(trivium.Span, trivium.Text);
                }
            }

            var tokens = lexer.GetTokens();

            foreach (var token in tokens)
            {
                VisitTrivia(token.LeadingTrivia);
                VisitSpan(token.Span, token.Text);
                VisitTrivia(token.TrailingTrivia);
            }

            // when we're done visited position should match the length of the file
            visitedPosition.Should().Be(dataSet.Bicep.Length);
        }