// Internal for testing
        internal void OnDocumentStructureChanged(object state)
        {
            _dispatcher.AssertForegroundThread();

            if (_disposed)
            {
                return;
            }

            var backgroundParserArgs = (BackgroundParserResultsReadyEventArgs)state;

            if (_latestChangeReference == null || // extra hardening
                _latestChangeReference != backgroundParserArgs.ChangeReference ||
                backgroundParserArgs.ChangeReference.Snapshot != TextBuffer.CurrentSnapshot)
            {
                // In the middle of parsing a newer change or about to parse a newer change.
                return;
            }

            _latestChangeReference = null;
            _codeDocument          = backgroundParserArgs.CodeDocument;
            _snapshot      = backgroundParserArgs.ChangeReference.Snapshot;
            _partialParser = new RazorSyntaxTreePartialParser(CodeDocument.GetSyntaxTree());

            var documentStructureChangedArgs = new DocumentStructureChangedEventArgs(
                backgroundParserArgs.ChangeReference.Change,
                backgroundParserArgs.ChangeReference.Snapshot,
                backgroundParserArgs.CodeDocument);

            DocumentStructureChanged?.Invoke(this, documentStructureChangedArgs);
        }
예제 #2
0
        public void TagHelperTagBodiesRejectPartialChanges(object objectEdit)
        {
            // Arrange
            var edit    = (TestEdit)objectEdit;
            var builder = TagHelperDescriptorBuilder.Create("PTagHelper", "TestAssembly");

            builder.SetTypeName("PTagHelper");
            builder.TagMatchingRule(rule => rule.TagName = "p");
            var descriptors = new[]
            {
                builder.Build()
            };
            var projectEngine = CreateProjectEngine(tagHelpers: descriptors);
            var projectItem   = new TestRazorProjectItem("Index.cshtml")
            {
                Content = edit.OldSnapshot.GetText()
            };
            var codeDocument = projectEngine.Process(projectItem);
            var syntaxTree   = codeDocument.GetSyntaxTree();
            var parser       = new RazorSyntaxTreePartialParser(syntaxTree);

            // Act
            var result = parser.Parse(edit.Change);

            // Assert
            Assert.Equal(PartialParseResultInternal.Rejected, result);
        }
        // Internal for testing
        internal void OnDocumentStructureChanged(object state)
        {
            _dispatcher.AssertForegroundThread();

            if (_disposed)
            {
                return;
            }

            var args = (DocumentStructureChangedEventArgs)state;

            if (_latestChangeReference == null || // extra hardening
                !_latestChangeReference.IsAssociatedWith(args) ||
                args.Snapshot != TextBuffer.CurrentSnapshot)
            {
                // In the middle of parsing a newer change or about to parse a newer change.
                return;
            }

            _latestChangeReference = null;
            _codeDocument          = args.CodeDocument;
            _snapshot      = args.Snapshot;
            _partialParser = new RazorSyntaxTreePartialParser(CodeDocument.GetSyntaxTree());

            DocumentStructureChanged?.Invoke(this, args);
        }
예제 #4
0
        public void TagHelperTagBodiesRejectPartialChanges(object objectEdit)
        {
            // Arrange
            var edit    = (TestEdit)objectEdit;
            var builder = TagHelperDescriptorBuilder.Create("PTagHelper", "TestAssembly");

            builder.SetTypeName("PTagHelper");
            builder.TagMatchingRule(rule => rule.TagName = "p");
            var descriptors = new[]
            {
                builder.Build()
            };
            var templateEngine = CreateTemplateEngine(tagHelpers: descriptors);
            var document       = TestRazorCodeDocument.Create(
                TestRazorSourceDocument.Create(edit.OldSnapshot.GetText()),
                new[] { templateEngine.Options.DefaultImports });

            templateEngine.Engine.Process(document);
            var syntaxTree = document.GetSyntaxTree();
            var parser     = new RazorSyntaxTreePartialParser(syntaxTree);

            // Act
            var result = parser.Parse(edit.Change);

            // Assert
            Assert.Equal(PartialParseResultInternal.Rejected, result);
        }
예제 #5
0
        private static void RunPartialParseRejectionTest(TestEdit edit, PartialParseResultInternal additionalFlags = 0)
        {
            var templateEngine = CreateProjectEngine();
            var document       = TestRazorCodeDocument.Create(edit.OldSnapshot.GetText());

            templateEngine.Engine.Process(document);
            var syntaxTree = document.GetSyntaxTree();
            var parser     = new RazorSyntaxTreePartialParser(syntaxTree);

            var(result, _) = parser.Parse(edit.Change);
            Assert.Equal(PartialParseResultInternal.Rejected | additionalFlags, result);
        }
예제 #6
0
        private static void RunPartialParseTest(TestEdit edit, Block expectedTree, PartialParseResultInternal additionalFlags = 0)
        {
            var templateEngine = CreateProjectEngine();
            var document       = TestRazorCodeDocument.Create(edit.OldSnapshot.GetText());

            templateEngine.Engine.Process(document);
            var syntaxTree = document.GetSyntaxTree();
            var parser     = new RazorSyntaxTreePartialParser(syntaxTree);

            var result = parser.Parse(edit.Change);

            Assert.Equal(PartialParseResultInternal.Accepted | additionalFlags, result);
            ParserTestBase.EvaluateParseTree(parser.SyntaxTreeRoot, expectedTree);
        }
예제 #7
0
        private void RunPartialParseTest(TestEdit edit, PartialParseResultInternal additionalFlags = 0)
        {
            var templateEngine = CreateProjectEngine();
            var document       = TestRazorCodeDocument.Create(edit.OldSnapshot.GetText());

            templateEngine.Engine.Process(document);
            var syntaxTree = document.GetSyntaxTree();
            var parser     = new RazorSyntaxTreePartialParser(syntaxTree);

            var(result, _) = parser.Parse(edit.Change);
            Assert.Equal(PartialParseResultInternal.Accepted | additionalFlags, result);

            var newSource     = TestRazorSourceDocument.Create(edit.NewSnapshot.GetText());
            var newSyntaxTree = RazorSyntaxTree.Create(parser.ModifiedSyntaxTreeRoot, newSource, parser.OriginalSyntaxTree.Diagnostics, parser.OriginalSyntaxTree.Options);

            BaselineTest(newSyntaxTree);
        }
예제 #8
0
        private void UpdateParserState(RazorCodeDocument codeDocument, ITextSnapshot snapshot)
        {
            lock (UpdateStateLock)
            {
                if (_snapshot != null && snapshot.Version.VersionNumber < _snapshot.Version.VersionNumber)
                {
                    // Changes flowed out of order due to the slight race condition at the beginning of this method. Our current
                    // CodeDocument and Snapshot are newer then the ones that made it into the lock.
                    return;
                }

                _codeDocument  = codeDocument;
                _snapshot      = snapshot;
                _partialParser = new RazorSyntaxTreePartialParser(_codeDocument.GetSyntaxTree());
                TryUpdateLatestParsedSyntaxTreeSnapshot(_codeDocument, _snapshot);
            }
        }
예제 #9
0
        // Internal for testing
        internal void OnDocumentStructureChanged(object state)
        {
            _dispatcher.AssertForegroundThread();

            if (_disposed)
            {
                return;
            }

            var backgroundParserArgs = (BackgroundParserResultsReadyEventArgs)state;

            if (_latestChangeReference == null || // extra hardening
                _latestChangeReference != backgroundParserArgs.ChangeReference)
            {
                // In the middle of parsing a newer change or about to parse a newer change.
                return;
            }

            if (backgroundParserArgs.ChangeReference.Snapshot != TextBuffer.CurrentSnapshot)
            {
                // Changes have impacted the snapshot after our we recorded our last change reference.
                // This can happen for a multitude of reasons, usually because of a user auto-completing
                // C# statements (causes multiple edits in quick succession). This ensures that our latest
                // parse corresponds to the current snapshot.
                QueueReparse();
                return;
            }

            lock (GetCodeDocumentLock)
            {
                _latestChangeReference = null;
                _codeDocument          = backgroundParserArgs.CodeDocument;
                _snapshot      = backgroundParserArgs.ChangeReference.Snapshot;
                _partialParser = new RazorSyntaxTreePartialParser(_codeDocument.GetSyntaxTree());
                _codeDocumentTaskCompletionSource?.SetResult(_codeDocument);
                _codeDocumentTaskCompletionSource = null;
            }

            var documentStructureChangedArgs = new DocumentStructureChangedEventArgs(
                backgroundParserArgs.ChangeReference.Change,
                backgroundParserArgs.ChangeReference.Snapshot,
                backgroundParserArgs.CodeDocument);

            DocumentStructureChanged?.Invoke(this, documentStructureChangedArgs);
        }
예제 #10
0
        public void TagHelperAttributesAreLocatedAndAcceptChangesCorrectly(object editObject, object partialParseResultObject)
        {
            // Arrange
            var edit = (TestEdit)editObject;
            var partialParseResult = (PartialParseResultInternal)partialParseResultObject;
            var builder            = TagHelperDescriptorBuilder.Create("PTagHelper", "Test");

            builder.SetTypeName("PTagHelper");
            builder.TagMatchingRule(rule => rule.TagName = "p");
            builder.BindAttribute(attribute =>
            {
                attribute.Name     = "obj-attr";
                attribute.TypeName = typeof(object).FullName;
                attribute.SetPropertyName("ObjectAttribute");
            });
            builder.BindAttribute(attribute =>
            {
                attribute.Name     = "str-attr";
                attribute.TypeName = typeof(string).FullName;
                attribute.SetPropertyName("StringAttribute");
            });
            var descriptors    = new[] { builder.Build() };
            var projectEngine  = CreateProjectEngine(tagHelpers: descriptors);
            var sourceDocument = new TestRazorProjectItem("Index.cshtml")
            {
                Content = edit.OldSnapshot.GetText()
            };
            var codeDocument = projectEngine.Process(sourceDocument);
            var syntaxTree   = codeDocument.GetSyntaxTree();
            var parser       = new RazorSyntaxTreePartialParser(syntaxTree);

            // Act
            var result = parser.Parse(edit.Change);

            // Assert
            Assert.Equal(partialParseResult, result);
        }