diff --git a/NuGet.config b/NuGet.config index 37f0d27ea0..be418c3311 100644 --- a/NuGet.config +++ b/NuGet.config @@ -2,7 +2,8 @@ - + + diff --git a/appveyor.yml b/appveyor.yml index a57b7f4ddb..64fc8eab76 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -init: +init: - git config --global core.autocrlf true branches: only: @@ -10,6 +10,10 @@ branches: build_script: - ps: .\build.ps1 clone_depth: 1 +environment: + global: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: 1 test: off deploy: off os: Visual Studio 2017 Preview diff --git a/build.ps1 b/build.ps1 index 1785334385..5bf0e2c113 100644 --- a/build.ps1 +++ b/build.ps1 @@ -33,7 +33,7 @@ cd $PSScriptRoot $repoFolder = $PSScriptRoot $env:REPO_FOLDER = $repoFolder -$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0.zip" +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" if ($env:KOREBUILD_ZIP) { $koreBuildZip=$env:KOREBUILD_ZIP diff --git a/build.sh b/build.sh index 5e27ed8efb..b0bcadb579 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd $repoFolder -koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0.zip" +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" if [ ! -z $KOREBUILD_ZIP ]; then koreBuildZip=$KOREBUILD_ZIP fi diff --git a/build/common.props b/build/common.props index de7050efe5..6e70cfed6f 100644 --- a/build/common.props +++ b/build/common.props @@ -12,6 +12,9 @@ true $(VersionSuffix)-$(BuildNumber) true + + + full diff --git a/build/dependencies.props b/build/dependencies.props index 9d5495f037..e277dcc05b 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -12,7 +12,7 @@ 2.0.0-* 2.0.0-* 2.3.1 - 2.6.0-beta* + 2.3.0-beta4-* 1.1.92 15.3.0-* diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorExtensions.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorExtensions.cs index 22c406b05f..e0cc152b89 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorExtensions.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/RazorExtensions.cs @@ -29,10 +29,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions builder.Features.Add(new ViewComponentTagHelperPass()); builder.Features.Add(new RazorPageDocumentClassifierPass()); builder.Features.Add(new MvcViewDocumentClassifierPass()); - builder.Features.Add(new AssemblyAttributeInjectionPass()); if (!builder.DesignTime) { + builder.Features.Add(new AssemblyAttributeInjectionPass()); builder.Features.Add(new InstrumentationPass()); } } diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ViewComponentTagHelperDescriptorProvider.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ViewComponentTagHelperDescriptorProvider.cs index 10150c3e80..0abefc5fe5 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ViewComponentTagHelperDescriptorProvider.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/ViewComponentTagHelperDescriptorProvider.cs @@ -55,7 +55,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions var factory = new ViewComponentTagHelperDescriptorFactory(compilation); for (var i = 0; i < types.Count; i++) { - context.Results.Add(factory.CreateDescriptor(types[i])); + var descriptor = factory.CreateDescriptor(types[i]); + + if (descriptor != null) + { + context.Results.Add(descriptor); + } } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/DirectiveTokenEditHandler.cs b/src/Microsoft.AspNetCore.Razor.Language/DirectiveTokenEditHandler.cs index 5c3f4403e0..6abaa03f5c 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/DirectiveTokenEditHandler.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/DirectiveTokenEditHandler.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Razor.Language { } - protected override PartialParseResult CanAcceptChange(Span target, SourceChange change) + protected override PartialParseResultInternal CanAcceptChange(Span target, SourceChange change) { if (AcceptedCharacters == AcceptedCharactersInternal.NonWhiteSpace) { @@ -25,11 +25,11 @@ namespace Microsoft.AspNetCore.Razor.Language // Did not modify whitespace, directive format should be the same. // Return provisional so extensible IR/code gen pieces can see the full directive text // once the user stops editing the document. - return PartialParseResult.Accepted | PartialParseResult.Provisional; + return PartialParseResultInternal.Accepted | PartialParseResultInternal.Provisional; } } - return PartialParseResult.Rejected; + return PartialParseResultInternal.Rejected; } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/AutoCompleteEditHandler.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/AutoCompleteEditHandler.cs index ae4291f987..bd73bbc1b2 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/AutoCompleteEditHandler.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/AutoCompleteEditHandler.cs @@ -31,16 +31,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy public string AutoCompleteString { get; set; } - protected override PartialParseResult CanAcceptChange(Span target, SourceChange change) + protected override PartialParseResultInternal CanAcceptChange(Span target, SourceChange change) { if (((AutoCompleteAtEndOfSpan && IsAtEndOfSpan(target, change)) || IsAtEndOfFirstLine(target, change)) && change.IsInsert && ParserHelpers.IsNewLine(change.NewText) && AutoCompleteString != null) { - return PartialParseResult.Rejected | PartialParseResult.AutoCompleteBlock; + return PartialParseResultInternal.Rejected | PartialParseResultInternal.AutoCompleteBlock; } - return PartialParseResult.Rejected; + return PartialParseResultInternal.Rejected; } public override string ToString() diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/EditResult.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/EditResult.cs index 351116e090..6aff8dea24 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/EditResult.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/EditResult.cs @@ -5,13 +5,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { internal class EditResult { - public EditResult(PartialParseResult result, SpanBuilder editedSpan) + public EditResult(PartialParseResultInternal result, SpanBuilder editedSpan) { Result = result; EditedSpan = editedSpan; } - public PartialParseResult Result { get; set; } + public PartialParseResultInternal Result { get; set; } public SpanBuilder EditedSpan { get; set; } } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/ImplicitExpressionEditHandler.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/ImplicitExpressionEditHandler.cs index 82b9b5db19..ababd6c7f7 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/ImplicitExpressionEditHandler.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/ImplicitExpressionEditHandler.cs @@ -59,11 +59,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return hashCodeCombiner; } - protected override PartialParseResult CanAcceptChange(Span target, SourceChange change) + protected override PartialParseResultInternal CanAcceptChange(Span target, SourceChange change) { if (AcceptedCharacters == AcceptedCharactersInternal.Any) { - return PartialParseResult.Rejected; + return PartialParseResultInternal.Rejected; } // In some editors intellisense insertions are handled as "dotless commits". If an intellisense selection is confirmed @@ -99,7 +99,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // Don't support 0->1 length edits if (lastChar == null) { - return PartialParseResult.Rejected; + return PartialParseResultInternal.Rejected; } // Accepts cases when insertions are made at the end of a span or '.' is inserted within a span. @@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return HandleDeletion(target, lastChar.Value, change); } - return PartialParseResult.Rejected; + return PartialParseResultInternal.Rejected; } // A dotless commit is the process of inserting a '.' with an intellisense selection. @@ -249,17 +249,17 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return string.IsNullOrWhiteSpace(target.Content.Substring(offset)); } - private PartialParseResult HandleDotlessCommitInsertion(Span target) + private PartialParseResultInternal HandleDotlessCommitInsertion(Span target) { - var result = PartialParseResult.Accepted; + var result = PartialParseResultInternal.Accepted; if (!AcceptTrailingDot && target.Content.LastOrDefault() == '.') { - result |= PartialParseResult.Provisional; + result |= PartialParseResultInternal.Provisional; } return result; } - private PartialParseResult HandleReplacement(Span target, SourceChange change) + private PartialParseResultInternal HandleReplacement(Span target, SourceChange change) { // Special Case for IntelliSense commits. // When IntelliSense commits, we get two changes (for example user typed "Date", then committed "DateTime" by pressing ".") @@ -268,24 +268,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // We need partial parsing to accept case #2. var oldText = change.GetOriginalText(target); - var result = PartialParseResult.Rejected; + var result = PartialParseResultInternal.Rejected; if (EndsWithDot(oldText) && EndsWithDot(change.NewText)) { - result = PartialParseResult.Accepted; + result = PartialParseResultInternal.Accepted; if (!AcceptTrailingDot) { - result |= PartialParseResult.Provisional; + result |= PartialParseResultInternal.Provisional; } } return result; } - private PartialParseResult HandleDeletion(Span target, char previousChar, SourceChange change) + private PartialParseResultInternal HandleDeletion(Span target, char previousChar, SourceChange change) { // What's left after deleting? if (previousChar == '.') { - return TryAcceptChange(target, change, PartialParseResult.Accepted | PartialParseResult.Provisional); + return TryAcceptChange(target, change, PartialParseResultInternal.Accepted | PartialParseResultInternal.Provisional); } else if (ParserHelpers.IsIdentifierPart(previousChar)) { @@ -293,11 +293,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } else { - return PartialParseResult.Rejected; + return PartialParseResultInternal.Rejected; } } - private PartialParseResult HandleInsertion(Span target, char previousChar, SourceChange change) + private PartialParseResultInternal HandleInsertion(Span target, char previousChar, SourceChange change) { // What are we inserting after? if (previousChar == '.') @@ -310,11 +310,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } else { - return PartialParseResult.Rejected; + return PartialParseResultInternal.Rejected; } } - private PartialParseResult HandleInsertionAfterIdPart(Span target, SourceChange change) + private PartialParseResultInternal HandleInsertionAfterIdPart(Span target, SourceChange change) { // If the insertion is a full identifier part, accept it if (ParserHelpers.IsIdentifier(change.NewText, requireIdentifierStart: false)) @@ -324,16 +324,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy else if (EndsWithDot(change.NewText)) { // Accept it, possibly provisionally - var result = PartialParseResult.Accepted; + var result = PartialParseResultInternal.Accepted; if (!AcceptTrailingDot) { - result |= PartialParseResult.Provisional; + result |= PartialParseResultInternal.Provisional; } return TryAcceptChange(target, change, result); } else { - return PartialParseResult.Rejected; + return PartialParseResultInternal.Rejected; } } @@ -344,22 +344,22 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy content.Take(content.Length - 1).All(ParserHelpers.IsIdentifierPart)); } - private PartialParseResult HandleInsertionAfterDot(Span target, SourceChange change) + private PartialParseResultInternal HandleInsertionAfterDot(Span target, SourceChange change) { // If the insertion is a full identifier or another dot, accept it if (ParserHelpers.IsIdentifier(change.NewText) || change.NewText == ".") { return TryAcceptChange(target, change); } - return PartialParseResult.Rejected; + return PartialParseResultInternal.Rejected; } - private PartialParseResult TryAcceptChange(Span target, SourceChange change, PartialParseResult acceptResult = PartialParseResult.Accepted) + private PartialParseResultInternal TryAcceptChange(Span target, SourceChange change, PartialParseResultInternal acceptResult = PartialParseResultInternal.Accepted) { var content = change.GetEditedContent(target); if (StartsWithKeyword(content)) { - return PartialParseResult.Rejected | PartialParseResult.SpanContextChanged; + return PartialParseResultInternal.Rejected | PartialParseResultInternal.SpanContextChanged; } return acceptResult; diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/PartialParseResult.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/PartialParseResultInternal.cs similarity index 98% rename from src/Microsoft.AspNetCore.Razor.Language/Legacy/PartialParseResult.cs rename to src/Microsoft.AspNetCore.Razor.Language/Legacy/PartialParseResultInternal.cs index 0b61553b53..a6a79c01bf 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/PartialParseResult.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/PartialParseResultInternal.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy /// Provisional may NOT be set with Rejected and SpanContextChanged may NOT be set with Accepted. /// [Flags] - internal enum PartialParseResult + internal enum PartialParseResultInternal { /// /// Indicates that the edit could not be accepted and that a reparse is underway. diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/SpanEditHandler.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/SpanEditHandler.cs index 4bef77c6f7..dd9511ce70 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/SpanEditHandler.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/SpanEditHandler.cs @@ -38,14 +38,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy public virtual EditResult ApplyChange(Span target, SourceChange change, bool force) { - var result = PartialParseResult.Accepted; + var result = PartialParseResultInternal.Accepted; if (!force) { result = CanAcceptChange(target, change); } // If the change is accepted then apply the change - if ((result & PartialParseResult.Accepted) == PartialParseResult.Accepted) + if ((result & PartialParseResultInternal.Accepted) == PartialParseResultInternal.Accepted) { return new EditResult(result, UpdateSpan(target, change)); } @@ -60,9 +60,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy (changeOldEnd < end || (changeOldEnd == end && AcceptedCharacters != AcceptedCharactersInternal.None)); } - protected virtual PartialParseResult CanAcceptChange(Span target, SourceChange change) + protected virtual PartialParseResultInternal CanAcceptChange(Span target, SourceChange change) { - return PartialParseResult.Rejected; + return PartialParseResultInternal.Rejected; } protected virtual SpanBuilder UpdateSpan(Span target, SourceChange change) diff --git a/src/Microsoft.CodeAnalysis.Razor/DefaultTagHelperDescriptorProvider.cs b/src/Microsoft.CodeAnalysis.Razor/DefaultTagHelperDescriptorProvider.cs index b9bf8f4822..c9effc07a1 100644 --- a/src/Microsoft.CodeAnalysis.Razor/DefaultTagHelperDescriptorProvider.cs +++ b/src/Microsoft.CodeAnalysis.Razor/DefaultTagHelperDescriptorProvider.cs @@ -48,7 +48,11 @@ namespace Microsoft.CodeAnalysis.Razor for (var i = 0; i < types.Count; i++) { var descriptor = factory.CreateDescriptor(types[i]); - context.Results.Add(descriptor); + + if (descriptor != null) + { + context.Results.Add(descriptor); + } } } diff --git a/src/Microsoft.CodeAnalysis.Remote.Razor/RazorLanguageService.cs b/src/Microsoft.CodeAnalysis.Remote.Razor/RazorLanguageService.cs index 930abdee3a..b3a165bcd4 100644 --- a/src/Microsoft.CodeAnalysis.Remote.Razor/RazorLanguageService.cs +++ b/src/Microsoft.CodeAnalysis.Remote.Razor/RazorLanguageService.cs @@ -31,7 +31,7 @@ namespace Microsoft.CodeAnalysis.Remote.Razor { var projectId = ProjectId.CreateFromSerialized(projectIdBytes, projectDebugName); - var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false); + var solution = await GetSolutionAsync().ConfigureAwait(false); var project = solution.GetProject(projectId); var resolver = new DefaultTagHelperResolver(designTime: true); diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/BackgroundParser.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/BackgroundParser.cs new file mode 100644 index 0000000000..b71f4d8814 --- /dev/null +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/BackgroundParser.cs @@ -0,0 +1,419 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Microsoft.VisualStudio.Text; + +namespace Microsoft.VisualStudio.LanguageServices.Razor +{ + internal class BackgroundParser : IDisposable + { + private MainThreadState _main; + private BackgroundThread _bg; + + public BackgroundParser(RazorTemplateEngine templateEngine, string filePath) + { + _main = new MainThreadState(filePath); + _bg = new BackgroundThread(_main, templateEngine, filePath); + + _main.ResultsReady += (sender, args) => OnResultsReady(args); + } + + /// + /// Fired on the main thread. + /// + public event EventHandler ResultsReady; + + public bool IsIdle + { + get { return _main.IsIdle; } + } + + public void Start() + { + _bg.Start(); + } + + public void Cancel() + { + _main.Cancel(); + } + + public void QueueChange(SourceChange change, ITextSnapshot snapshot) + { + var edit = new Edit(change, snapshot); + _main.QueueChange(edit); + } + + public void Dispose() + { + _main.Cancel(); + } + + public IDisposable SynchronizeMainThreadState() + { + return _main.Lock(); + } + + protected virtual void OnResultsReady(DocumentParseCompleteEventArgs args) + { + var handler = ResultsReady; + if (handler != null) + { + handler(this, args); + } + } + + private static bool TreesAreDifferent(RazorSyntaxTree leftTree, RazorSyntaxTree rightTree, IEnumerable edits, CancellationToken cancelToken) + { + return TreesAreDifferent(leftTree.Root, rightTree.Root, edits.Select(edit => edit.Change), cancelToken); + } + + internal static bool TreesAreDifferent(Block leftTree, Block rightTree, IEnumerable changes, CancellationToken cancelToken) + { + // Apply all the pending changes to the original tree + // PERF: If this becomes a bottleneck, we can probably do it the other way around, + // i.e. visit the tree and find applicable changes for each node. + foreach (var change in changes) + { + cancelToken.ThrowIfCancellationRequested(); + + var changeOwner = leftTree.LocateOwner(change); + + // Apply the change to the tree + if (changeOwner == null) + { + return true; + } + + var result = changeOwner.EditHandler.ApplyChange(changeOwner, change, force: true); + changeOwner.ReplaceWith(result.EditedSpan); + } + + // Now compare the trees + var treesDifferent = !leftTree.EquivalentTo(rightTree); + return treesDifferent; + } + + private abstract class ThreadStateBase + { +#if DEBUG + private int _id = -1; +#endif + protected ThreadStateBase() + { + } + + [Conditional("DEBUG")] + protected void SetThreadId(int id) + { +#if DEBUG + _id = id; +#endif + } + + [Conditional("DEBUG")] + protected void EnsureOnThread() + { +#if DEBUG + Debug.Assert(_id != -1, "SetThreadId was never called!"); + Debug.Assert(Thread.CurrentThread.ManagedThreadId == _id, "Called from an unexpected thread!"); +#endif + } + + [Conditional("DEBUG")] + protected void EnsureNotOnThread() + { +#if DEBUG + Debug.Assert(_id != -1, "SetThreadId was never called!"); + Debug.Assert(Thread.CurrentThread.ManagedThreadId != _id, "Called from an unexpected thread!"); +#endif + } + } + + private class MainThreadState : ThreadStateBase, IDisposable + { + private readonly CancellationTokenSource _cancelSource = new CancellationTokenSource(); + private readonly ManualResetEventSlim _hasParcel = new ManualResetEventSlim(false); + private CancellationTokenSource _currentParcelCancelSource; + + private string _fileName; + private readonly object _stateLock = new object(); + private IList _changes = new List(); + + public MainThreadState(string fileName) + { + _fileName = fileName; + + SetThreadId(Thread.CurrentThread.ManagedThreadId); + } + + public event EventHandler ResultsReady; + + public CancellationToken CancelToken + { + get { return _cancelSource.Token; } + } + + public bool IsIdle + { + get + { + lock (_stateLock) + { + return _currentParcelCancelSource == null; + } + } + } + + public void Cancel() + { + EnsureOnThread(); + _cancelSource.Cancel(); + } + + public IDisposable Lock() + { + Monitor.Enter(_stateLock); + return new DisposableAction(() => Monitor.Exit(_stateLock)); + } + + public void QueueChange(Edit edit) + { + EnsureOnThread(); + lock (_stateLock) + { + // CurrentParcel token source is not null ==> There's a parse underway + if (_currentParcelCancelSource != null) + { + _currentParcelCancelSource.Cancel(); + } + + _changes.Add(edit); + _hasParcel.Set(); + } + } + + public WorkParcel GetParcel() + { + EnsureNotOnThread(); // Only the background thread can get a parcel + _hasParcel.Wait(_cancelSource.Token); + _hasParcel.Reset(); + lock (_stateLock) + { + // Create a cancellation source for this parcel + _currentParcelCancelSource = new CancellationTokenSource(); + + var changes = _changes; + _changes = new List(); + return new WorkParcel(changes, _currentParcelCancelSource.Token); + } + } + + public void ReturnParcel(DocumentParseCompleteEventArgs args) + { + lock (_stateLock) + { + // Clear the current parcel cancellation source + if (_currentParcelCancelSource != null) + { + _currentParcelCancelSource.Dispose(); + _currentParcelCancelSource = null; + } + + // If there are things waiting to be parsed, just don't fire the event because we're already out of date + if (_changes.Any()) + { + return; + } + } + var handler = ResultsReady; + if (handler != null) + { + handler(this, args); + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (_currentParcelCancelSource != null) + { + _currentParcelCancelSource.Dispose(); + _currentParcelCancelSource = null; + } + _cancelSource.Dispose(); + _hasParcel.Dispose(); + } + } + } + + private class BackgroundThread : ThreadStateBase + { + private MainThreadState _main; + private Thread _backgroundThread; + private CancellationToken _shutdownToken; + private RazorTemplateEngine _templateEngine; + private string _filePath; + private RazorSyntaxTree _currentSyntaxTree; + private IList _previouslyDiscarded = new List(); + + public BackgroundThread(MainThreadState main, RazorTemplateEngine templateEngine, string fileName) + { + // Run on MAIN thread! + _main = main; + _shutdownToken = _main.CancelToken; + _templateEngine = templateEngine; + _filePath = fileName; + + _backgroundThread = new Thread(WorkerLoop); + SetThreadId(_backgroundThread.ManagedThreadId); + } + + // **** ANY THREAD **** + public void Start() + { + _backgroundThread.Start(); + } + + // **** BACKGROUND THREAD **** + private void WorkerLoop() + { + var fileNameOnly = Path.GetFileName(_filePath); + + try + { + EnsureOnThread(); + + while (!_shutdownToken.IsCancellationRequested) + { + // Grab the parcel of work to do + var parcel = _main.GetParcel(); + if (parcel.Edits.Any()) + { + try + { + DocumentParseCompleteEventArgs args = null; + using (var linkedCancel = CancellationTokenSource.CreateLinkedTokenSource(_shutdownToken, parcel.CancelToken)) + { + if (!linkedCancel.IsCancellationRequested) + { + // Collect ALL changes + List allEdits; + + if (_previouslyDiscarded != null) + { + allEdits = Enumerable.Concat(_previouslyDiscarded, parcel.Edits).ToList(); + } + else + { + allEdits = parcel.Edits.ToList(); + } + + var finalEdit = allEdits.Last(); + + var results = ParseChange(finalEdit.Snapshot, linkedCancel.Token); + + if (results != null && !linkedCancel.IsCancellationRequested) + { + // Clear discarded changes list + _previouslyDiscarded = null; + + var treeStructureChanged = _currentSyntaxTree == null || TreesAreDifferent(_currentSyntaxTree, results.GetSyntaxTree(), allEdits, parcel.CancelToken); + _currentSyntaxTree = results.GetSyntaxTree(); + + // Build Arguments + args = new DocumentParseCompleteEventArgs( + finalEdit.Change, + finalEdit.Snapshot, + treeStructureChanged, + results); + } + else + { + // Parse completed but we were cancelled in the mean time. Add these to the discarded changes set + _previouslyDiscarded = allEdits; + } + } + } + if (args != null) + { + _main.ReturnParcel(args); + } + } + catch (OperationCanceledException) + { + } + } + else + { + Thread.Yield(); + } + } + } + catch (OperationCanceledException) + { + // Do nothing. Just shut down. + } + finally + { + // Clean up main thread resources + _main.Dispose(); + } + } + + private RazorCodeDocument ParseChange(ITextSnapshot snapshot, CancellationToken token) + { + EnsureOnThread(); + + var sourceDocument = new TextSnapshotSourceDocument(snapshot, _filePath); + var imports = _templateEngine.GetImports(_filePath); + + var codeDocument = RazorCodeDocument.Create(sourceDocument, imports); + + _templateEngine.GenerateCode(codeDocument); + return codeDocument; + } + } + + private class WorkParcel + { + public WorkParcel(IList changes, CancellationToken cancelToken) + { + Edits = changes; + CancelToken = cancelToken; + } + + public CancellationToken CancelToken { get; } + + public IList Edits { get; } + } + + private class Edit + { + public Edit(SourceChange change, ITextSnapshot snapshot) + { + Change = change; + Snapshot = snapshot; + } + + public SourceChange Change { get; } + + public ITextSnapshot Snapshot { get; set; } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDirectiveResolver.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDirectiveResolver.cs index 63b6f1781e..870bbc6617 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDirectiveResolver.cs +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDirectiveResolver.cs @@ -23,11 +23,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor using (var session = await client.CreateSessionAsync(project.Solution)) { - var directives = await session.InvokeAsync>( - "GetDirectivesAsync", - new object[] { project.Id.Id, "Foo", }, - cancellationToken) - .ConfigureAwait(false); + var directives = await session.InvokeAsync>("GetDirectivesAsync", new object[] { project.Id.Id, "Foo", }).ConfigureAwait(false); return directives; } } @@ -41,4 +37,4 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor } } } -#endif +#endif \ No newline at end of file diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDocumentGenerator.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDocumentGenerator.cs index 181b98f9b1..308e67e585 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDocumentGenerator.cs +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDocumentGenerator.cs @@ -21,11 +21,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor using (var session = await client.CreateSessionAsync(project.Solution)) { - var document = await session.InvokeAsync( - "GenerateDocumentAsync", - new object[] { project.Id.Id, "Foo", filePath, text }, - cancellationToken) - .ConfigureAwait(false); + var document = await session.InvokeAsync("GenerateDocumentAsync", new object[] { project.Id.Id, "Foo", filePath, text }).ConfigureAwait(false); return document; } } diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs index 5d8ba6b26d..22804f9b90 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs @@ -44,10 +44,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor if (session != null) { var jsonObject = await session.InvokeAsync( - "GetTagHelpersAsync", - new object[] { project.Id.Id, "Foo", }, - CancellationToken.None - ).ConfigureAwait(false); + "GetTagHelpersAsync", + new object[] { project.Id.Id, "Foo", }).ConfigureAwait(false); result = GetTagHelperResolutionResult(jsonObject); diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/DocumentParseCompleteEventArgs.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/DocumentParseCompleteEventArgs.cs new file mode 100644 index 0000000000..c8dc5065c8 --- /dev/null +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/DocumentParseCompleteEventArgs.cs @@ -0,0 +1,47 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.VisualStudio.Text; + +namespace Microsoft.VisualStudio.LanguageServices.Razor +{ + /// + /// Arguments for the event in . + /// + public sealed class DocumentParseCompleteEventArgs : EventArgs + { + public DocumentParseCompleteEventArgs( + SourceChange change, + ITextSnapshot buffer, + bool treeStructureChanged, + RazorCodeDocument codeDocument) + { + SourceChange = change; + Buffer = buffer; + TreeStructureChanged = treeStructureChanged; + CodeDocument = codeDocument; + } + + /// + /// The which triggered the re-parse. + /// + public SourceChange SourceChange { get; } + + /// + /// The text snapshot used in the re-parse. + /// + public ITextSnapshot Buffer { get; } + + /// + /// Indicates if the tree structure has actually changed since the previous re-parse. + /// + public bool TreeStructureChanged { get; } + + /// + /// The result of the parsing and code generation. + /// + public RazorCodeDocument CodeDocument { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/PartialParseResult.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/PartialParseResult.cs new file mode 100644 index 0000000000..2571342f69 --- /dev/null +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/PartialParseResult.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.VisualStudio.LanguageServices.Razor +{ + [Flags] + public enum PartialParseResult + { + Rejected = 1, + + Accepted = 2, + + Provisional = 4, + + SpanContextChanged = 8, + + AutoCompleteBlock = 16 + } +} diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/RazorEditorParser.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/RazorEditorParser.cs new file mode 100644 index 0000000000..4b4a4efe06 --- /dev/null +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/RazorEditorParser.cs @@ -0,0 +1,190 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Microsoft.VisualStudio.Text; + +namespace Microsoft.VisualStudio.LanguageServices.Razor +{ + public class RazorEditorParser : IDisposable + { + private AspNetCore.Razor.Language.Legacy.Span _lastChangeOwner; + private AspNetCore.Razor.Language.Legacy.Span _lastAutoCompleteSpan; + private BackgroundParser _parser; + + public RazorEditorParser(RazorTemplateEngine templateEngine, string filePath) + { + if (templateEngine == null) + { + throw new ArgumentNullException(nameof(templateEngine)); + } + + if (string.IsNullOrEmpty(filePath)) + { + throw new ArgumentException( + AspNetCore.Razor.Language.Resources.ArgumentCannotBeNullOrEmpty, + nameof(filePath)); + } + + TemplateEngine = templateEngine; + FilePath = filePath; + _parser = new BackgroundParser(templateEngine, filePath); + _parser.ResultsReady += (sender, args) => OnDocumentParseComplete(args); + _parser.Start(); + } + + /// + /// Event fired when a full reparse of the document completes. + /// + public event EventHandler DocumentParseComplete; + + public RazorTemplateEngine TemplateEngine { get; } + + public string FilePath { get; } + + // Internal for testing. + internal RazorSyntaxTree CurrentSyntaxTree { get; private set; } + + // Internal for testing. + internal bool LastResultProvisional { get; private set; } + + public virtual string GetAutoCompleteString() + { + if (_lastAutoCompleteSpan?.EditHandler is AutoCompleteEditHandler editHandler) + { + return editHandler.AutoCompleteString; + } + + return null; + } + + public virtual PartialParseResult CheckForStructureChanges(SourceChange change, ITextSnapshot snapshot) + { + if (snapshot == null) + { + throw new ArgumentNullException(nameof(snapshot)); + } + + var result = PartialParseResultInternal.Rejected; + + using (_parser.SynchronizeMainThreadState()) + { + // Check if we can partial-parse + if (CurrentSyntaxTree != null && _parser.IsIdle) + { + result = TryPartialParse(change); + } + } + + // If partial parsing failed or there were outstanding parser tasks, start a full reparse + if ((result & PartialParseResultInternal.Rejected) == PartialParseResultInternal.Rejected) + { + _parser.QueueChange(change, snapshot); + } + + // Otherwise, remember if this was provisionally accepted for next partial parse + LastResultProvisional = (result & PartialParseResultInternal.Provisional) == PartialParseResultInternal.Provisional; + VerifyFlagsAreValid(result); + + return (PartialParseResult)result; + } + + /// + /// Disposes of this parser. Should be called when the editor window is closed and the document is unloaded. + /// + public void Dispose() + { + _parser.Dispose(); + GC.SuppressFinalize(this); + } + + private PartialParseResultInternal TryPartialParse(SourceChange change) + { + var result = PartialParseResultInternal.Rejected; + + // Try the last change owner + if (_lastChangeOwner != null && _lastChangeOwner.EditHandler.OwnsChange(_lastChangeOwner, change)) + { + var editResult = _lastChangeOwner.EditHandler.ApplyChange(_lastChangeOwner, change); + result = editResult.Result; + if ((editResult.Result & PartialParseResultInternal.Rejected) != PartialParseResultInternal.Rejected) + { + _lastChangeOwner.ReplaceWith(editResult.EditedSpan); + } + + return result; + } + + // Locate the span responsible for this change + _lastChangeOwner = CurrentSyntaxTree.Root.LocateOwner(change); + + if (LastResultProvisional) + { + // Last change owner couldn't accept this, so we must do a full reparse + result = PartialParseResultInternal.Rejected; + } + else if (_lastChangeOwner != null) + { + var editResult = _lastChangeOwner.EditHandler.ApplyChange(_lastChangeOwner, change); + result = editResult.Result; + if ((editResult.Result & PartialParseResultInternal.Rejected) != PartialParseResultInternal.Rejected) + { + _lastChangeOwner.ReplaceWith(editResult.EditedSpan); + } + if ((result & PartialParseResultInternal.AutoCompleteBlock) == PartialParseResultInternal.AutoCompleteBlock) + { + _lastAutoCompleteSpan = _lastChangeOwner; + } + else + { + _lastAutoCompleteSpan = null; + } + } + + return result; + } + + private void OnDocumentParseComplete(DocumentParseCompleteEventArgs args) + { + using (_parser.SynchronizeMainThreadState()) + { + CurrentSyntaxTree = args.CodeDocument.GetSyntaxTree(); + _lastChangeOwner = null; + } + + Debug.Assert(args != null, "Event arguments cannot be null"); + EventHandler handler = DocumentParseComplete; + if (handler != null) + { + try + { + handler(this, args); + } + catch (Exception ex) + { + Debug.WriteLine("[RzEd] Document Parse Complete Handler Threw: " + ex.ToString()); + } + } + } + + [Conditional("DEBUG")] + private static void VerifyFlagsAreValid(PartialParseResultInternal result) + { + Debug.Assert(((result & PartialParseResultInternal.Accepted) == PartialParseResultInternal.Accepted) || + ((result & PartialParseResultInternal.Rejected) == PartialParseResultInternal.Rejected), + "Partial Parse result does not have either of Accepted or Rejected flags set"); + Debug.Assert(((result & PartialParseResultInternal.Rejected) == PartialParseResultInternal.Rejected) || + ((result & PartialParseResultInternal.SpanContextChanged) != PartialParseResultInternal.SpanContextChanged), + "Partial Parse result was Accepted AND had SpanContextChanged flag set"); + Debug.Assert(((result & PartialParseResultInternal.Rejected) == PartialParseResultInternal.Rejected) || + ((result & PartialParseResultInternal.AutoCompleteBlock) != PartialParseResultInternal.AutoCompleteBlock), + "Partial Parse result was Accepted AND had AutoCompleteBlock flag set"); + Debug.Assert(((result & PartialParseResultInternal.Accepted) == PartialParseResultInternal.Accepted) || + ((result & PartialParseResultInternal.Provisional) != PartialParseResultInternal.Provisional), + "Partial Parse result was Rejected AND had Provisional flag set"); + } + } +} diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/TextSnapshotSourceDocument.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/TextSnapshotSourceDocument.cs new file mode 100644 index 0000000000..37bb73f106 --- /dev/null +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/TextSnapshotSourceDocument.cs @@ -0,0 +1,79 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Text; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.VisualStudio.Text; + +namespace Microsoft.VisualStudio.LanguageServices.Razor +{ + internal class TextSnapshotSourceDocument : RazorSourceDocument + { + private readonly ITextSnapshot _buffer; + private readonly RazorSourceLineCollection _lines; + + public TextSnapshotSourceDocument(ITextSnapshot snapshot, string filePath) + { + if (snapshot == null) + { + throw new ArgumentNullException(nameof(snapshot)); + } + + if (filePath == null) + { + throw new ArgumentNullException(nameof(filePath)); + } + + _buffer = snapshot; + FilePath = filePath; + + _lines = new DefaultRazorSourceLineCollection(this); + } + + public override char this[int position] => _buffer[position]; + + public override Encoding Encoding => Encoding.UTF8; + + public override int Length => _buffer.Length; + + public override RazorSourceLineCollection Lines => _lines; + + public override string FilePath { get; } + + public override void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) + { + if (destination == null) + { + throw new ArgumentNullException(nameof(destination)); + } + + if (sourceIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(sourceIndex)); + } + + if (destinationIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(destinationIndex)); + } + + if (count < 0 || count > Length - sourceIndex || count > destination.Length - destinationIndex) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (count == 0) + { + return; + } + + for (var i = 0; i < count; i++) + { + destination[destinationIndex + i] = this[sourceIndex + i]; + } + } + + public override byte[] GetChecksum() => throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs index e66a1821e9..3edf343f5e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt index 50937c0523..b29d7ed8cd 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt index 0a7bf87384..e25ebcea7e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic_DesignTime.mappings.txt @@ -1,34 +1,34 @@ Source Location: (13:0,13 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) |this.ToString()| -Generated Location: (1215:27,13 [15] ) +Generated Location: (1037:26,13 [15] ) |this.ToString()| Source Location: (54:2,5 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) |string.Format("{0}", "Hello")| -Generated Location: (1351:32,6 [29] ) +Generated Location: (1173:31,6 [29] ) |string.Format("{0}", "Hello")| Source Location: (95:4,2 [25] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) | var cls = "foo"; | -Generated Location: (1497:37,2 [25] ) +Generated Location: (1319:36,2 [25] ) | var cls = "foo"; | Source Location: (134:7,11 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) |if(cls != null) { | -Generated Location: (1645:43,11 [18] ) +Generated Location: (1467:42,11 [18] ) |if(cls != null) { | Source Location: (153:7,30 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) |cls| -Generated Location: (1807:48,30 [3] ) +Generated Location: (1629:47,30 [3] ) |cls| Source Location: (156:7,33 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Basic.cshtml) | }| -Generated Location: (1958:53,33 [2] ) +Generated Location: (1780:52,33 [2] ) | }| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs index a7b8552963..1a14b13feb 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives_cshtml), null)] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt index db82ec98df..e5d9732ac5 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives_cshtml), null)] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt index 5040b0c49b..bb3e3bdbe3 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt @@ -1,5 +1,5 @@ Source Location: (159:11,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml) |MyService| -Generated Location: (885:19,0 [17] ) +Generated Location: (678:18,0 [17] ) |MyService| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs index b5d991e664..0c96a6c7e0 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt index 8dc6ecfbaf..73169535b3 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsViewModel_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt index 8c06ba4310..4f38bd7343 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel_DesignTime.mappings.txt @@ -1,10 +1,10 @@ Source Location: (10:0,10 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml) |MyBasePageForViews| -Generated Location: (844:19,0 [26] ) +Generated Location: (654:18,0 [26] ) |MyBasePageForViews| Source Location: (45:1,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsViewModel.cshtml) |MyModel| -Generated Location: (984:23,0 [7] ) +Generated Location: (794:22,0 [7] ) |MyModel| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs index a582e3c8ea..e3748d4f91 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports_cshtml), null)] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt index 23a23a6be8..e6a7b3f4c0 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InheritsWithViewImports_cshtml), null)] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt index 466d9442d6..4ae600111e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports_DesignTime.mappings.txt @@ -1,5 +1,5 @@ Source Location: (14:1,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InheritsWithViewImports.cshtml) |MyModel| -Generated Location: (863:19,0 [7] ) +Generated Location: (653:18,0 [7] ) |MyModel| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs index d02c1e7153..10050cba80 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt index 55881976e6..132fe4ed61 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt index a367708790..64bb4804b3 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel_DesignTime.mappings.txt @@ -1,25 +1,25 @@ Source Location: (7:0,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) |MyModel| -Generated Location: (870:19,0 [7] ) +Generated Location: (682:18,0 [7] ) |MyModel| Source Location: (24:1,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) |MyApp| -Generated Location: (972:23,0 [5] ) +Generated Location: (784:22,0 [5] ) |MyApp| Source Location: (30:1,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) |MyPropertyName| -Generated Location: (1092:27,22 [14] ) +Generated Location: (904:26,22 [14] ) |MyPropertyName| Source Location: (54:2,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) |MyService| -Generated Location: (1176:31,0 [17] ) +Generated Location: (988:30,0 [17] ) |MyService| Source Location: (72:2,26 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithModel.cshtml) |Html| -Generated Location: (1320:35,22 [4] ) +Generated Location: (1132:34,22 [4] ) |Html| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs index 9fe8fcea96..2c3776aedd 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt index 1475f81591..f9bf4e3c8c 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt index 4b57e22971..fb80df37b7 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon_DesignTime.mappings.txt @@ -1,45 +1,45 @@ Source Location: (7:0,7 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) |MyModel| -Generated Location: (878:19,0 [7] ) +Generated Location: (686:18,0 [7] ) |MyModel| Source Location: (24:1,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) |MyApp| -Generated Location: (980:23,0 [5] ) +Generated Location: (788:22,0 [5] ) |MyApp| Source Location: (30:1,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) |MyPropertyName| -Generated Location: (1100:27,22 [14] ) +Generated Location: (908:26,22 [14] ) |MyPropertyName| Source Location: (58:2,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) |MyService| -Generated Location: (1184:31,0 [17] ) +Generated Location: (992:30,0 [17] ) |MyService| Source Location: (76:2,26 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) |Html| -Generated Location: (1328:35,22 [4] ) +Generated Location: (1136:34,22 [4] ) |Html| Source Location: (93:3,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) |MyApp| -Generated Location: (1402:39,0 [5] ) +Generated Location: (1210:38,0 [5] ) |MyApp| Source Location: (99:3,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) |MyPropertyName2| -Generated Location: (1522:43,22 [15] ) +Generated Location: (1330:42,22 [15] ) |MyPropertyName2| Source Location: (129:4,8 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) |MyService| -Generated Location: (1607:47,0 [17] ) +Generated Location: (1415:46,0 [17] ) |MyService| Source Location: (147:4,26 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InjectWithSemicolon.cshtml) |Html2| -Generated Location: (1751:51,22 [5] ) +Generated Location: (1559:50,22 [5] ) |Html2| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs index 31fbdf1f5c..b8e43e2f76 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt index cb3f9996d4..73671c0430 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt index 9c407fea70..ec01d63774 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject_DesignTime.mappings.txt @@ -1,10 +1,10 @@ Source Location: (8:0,8 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml) |MyApp| -Generated Location: (852:19,0 [5] ) +Generated Location: (673:18,0 [5] ) |MyApp| Source Location: (14:0,14 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inject.cshtml) |MyPropertyName| -Generated Location: (972:23,22 [14] ) +Generated Location: (793:22,22 [14] ) |MyPropertyName| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs index 6657bc8117..d4bee96fbd 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt index d02e6b2453..5d1c4a4884 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs index 8c60cab876..44ef10a7fb 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml), null)] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt index 8a72021fa5..71a96d869b 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml), null)] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs index 9a3d439cac..8dc9887854 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt index 1910045295..529d7a140b 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt index dfcb4f8d9f..0a0cb62f30 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper_DesignTime.mappings.txt @@ -1,20 +1,20 @@ Source Location: (7:0,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) |DateTime| -Generated Location: (955:20,0 [8] ) +Generated Location: (758:19,0 [8] ) |DateTime| Source Location: (33:2,14 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) |"InputTestTagHelper, AppCode"| -Generated Location: (1096:24,37 [29] ) +Generated Location: (899:23,37 [29] ) |"InputTestTagHelper, AppCode"| Source Location: (83:4,17 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) |Date| -Generated Location: (1744:37,102 [4] ) +Generated Location: (1547:36,102 [4] ) |Date| Source Location: (111:5,18 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml) |Model| -Generated Location: (2060:43,94 [5] ) +Generated Location: (1863:42,94 [5] ) |Model| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs index 27cc0ec409..b12ca26651 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt index 9c40b2e3d8..b346a02ef5 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt index 4a3c1949a8..226138531b 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model_DesignTime.mappings.txt @@ -1,5 +1,5 @@ Source Location: (7:0,7 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Model.cshtml) |System.Collections.IEnumerable| -Generated Location: (873:19,0 [30] ) +Generated Location: (695:18,0 [30] ) |System.Collections.IEnumerable| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs index 90be5ff812..a766ae3900 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MultipleModels_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt index 67d683d383..7c125bef61 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MultipleModels_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt index f9c7929a64..65348abd7b 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels_DesignTime.mappings.txt @@ -1,10 +1,10 @@ Source Location: (7:0,7 [21] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml) |ThisShouldBeGenerated| -Generated Location: (882:19,0 [21] ) +Generated Location: (695:18,0 [21] ) |ThisShouldBeGenerated| Source Location: (37:1,7 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MultipleModels.cshtml) |System.Collections.IEnumerable| -Generated Location: (1012:23,0 [30] ) +Generated Location: (825:22,0 [30] ) |System.Collections.IEnumerable| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs index 2ec80564ca..b584c46a88 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(Test.Namespace.PageWithNamespace_Page), null)] namespace Test.Namespace { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt index 0e651c1602..0dc65607e5 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(Test.Namespace.PageWithNamespace_Page), null)] NamespaceDeclaration - - Test.Namespace UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt index d8bbdb7fc0..341492ab00 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace_DesignTime.mappings.txt @@ -1,5 +1,5 @@ Source Location: (18:1,11 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PageWithNamespace.cshtml) |Test.Namespace| -Generated Location: (813:19,44 [14] ) +Generated Location: (664:18,44 [14] ) |Test.Namespace| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs index 651b053ac7..6cccda46f2 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel_cshtml), null)] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt index 03371b20a9..8662b30f1e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel_cshtml), null)] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt index a3eb999a7e..0f57e118d6 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel_DesignTime.mappings.txt @@ -1,16 +1,16 @@ Source Location: (38:3,1 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) |using Microsoft.AspNetCore.Mvc.RazorPages| -Generated Location: (696:15,0 [41] ) +Generated Location: (487:14,0 [41] ) |using Microsoft.AspNetCore.Mvc.RazorPages| Source Location: (23:2,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) |"*, AppCode"| -Generated Location: (1153:25,37 [12] ) +Generated Location: (944:24,37 [12] ) |"*, AppCode"| Source Location: (566:24,47 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) |Name| -Generated Location: (1716:38,47 [4] ) +Generated Location: (1507:37,47 [4] ) |Name| Source Location: (95:5,12 [283] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml) @@ -28,7 +28,7 @@ Source Location: (95:5,12 [283] TestFiles/IntegrationTests/CodeGenerationIntegra public string Name { get; set; } } | -Generated Location: (2197:49,12 [283] ) +Generated Location: (1988:48,12 [283] ) | public IActionResult OnPost(Customer customer) { diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs index 69edd86113..3fc1ec92eb 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages_cshtml), null)] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt index e999ab5136..f1df7922a5 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages_cshtml), null)] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt index 7a61069555..88bdded9c2 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages_DesignTime.mappings.txt @@ -1,21 +1,21 @@ Source Location: (55:4,1 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) |using Microsoft.AspNetCore.Mvc.RazorPages| -Generated Location: (672:15,0 [41] ) +Generated Location: (475:14,0 [41] ) |using Microsoft.AspNetCore.Mvc.RazorPages| Source Location: (16:2,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) |NewModel| -Generated Location: (1080:25,0 [8] ) +Generated Location: (883:24,0 [8] ) |NewModel| Source Location: (40:3,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) |"*, AppCode"| -Generated Location: (1221:29,37 [12] ) +Generated Location: (1024:28,37 [12] ) |"*, AppCode"| Source Location: (661:28,47 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) |Model.Name| -Generated Location: (1772:42,47 [10] ) +Generated Location: (1575:41,47 [10] ) |Model.Name| Source Location: (112:6,12 [360] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml) @@ -36,7 +36,7 @@ Source Location: (112:6,12 [360] TestFiles/IntegrationTests/CodeGenerationIntegr public string Name { get; set; } } | -Generated Location: (2247:53,12 [360] ) +Generated Location: (2050:52,12 [360] ) | public class NewModel : PageModel { diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs index 2b61bb0cc8..027acd82f3 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt index 9aa8cca84e..0e6e005998 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt index 9751860c02..9344e08ed2 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper_DesignTime.mappings.txt @@ -1,19 +1,19 @@ Source Location: (14:0,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) |"*, AppCode"| -Generated Location: (1168:21,37 [12] ) +Generated Location: (973:20,37 [12] ) |"*, AppCode"| Source Location: (30:1,2 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) | var foo = "Hello"; | -Generated Location: (1614:33,2 [26] ) +Generated Location: (1419:32,2 [26] ) | var foo = "Hello"; | Source Location: (83:5,22 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml) |foo| -Generated Location: (2072:41,22 [3] ) +Generated Location: (1877:40,22 [3] ) |foo| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs index 18664f53b8..360ee6de22 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(Test.Namespace.ViewWithNamespace_View))] namespace Test.Namespace { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt index 9afe163ebb..817da953cc 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(Test.Namespace.ViewWithNamespace_View))] NamespaceDeclaration - - Test.Namespace UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt index 3046e73b88..18b68f476b 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace_DesignTime.mappings.txt @@ -1,5 +1,5 @@ Source Location: (11:0,11 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewWithNamespace.cshtml) |Test.Namespace| -Generated Location: (808:19,44 [14] ) +Generated Location: (673:18,44 [14] ) |Test.Namespace| diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs index 201561c059..38286b1076 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.codegen.cs @@ -1,6 +1,5 @@ // #pragma warning disable 1591 -[assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports_cshtml))] namespace AspNetCore { #line hidden diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt index acc47ece3f..c8e3cafb06 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.ir.txt @@ -1,6 +1,4 @@ Document - - CSharpCode - - IntermediateToken - - CSharp - [assembly:global::Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute(null, typeof(AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports_cshtml))] NamespaceDeclaration - - AspNetCore UsingDirective - - TModel = global::System.Object UsingDirective - (1:0,1 [12] ) - System diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt index 3aabc5a086..848c1a44ad 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports_DesignTime.mappings.txt @@ -1,10 +1,10 @@ Source Location: (8:0,8 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml) |IHtmlHelper| -Generated Location: (864:19,0 [19] ) +Generated Location: (679:18,0 [19] ) |IHtmlHelper| Source Location: (28:0,28 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/_ViewImports.cshtml) |Model| -Generated Location: (1012:23,22 [5] ) +Generated Location: (827:22,22 [5] ) |Model| diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs index 1a5aae94b7..0ddfa731e4 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test var result = directiveTokenHandler.CanAcceptChange(target, sourceChange); // Assert - Assert.Equal(PartialParseResult.Accepted | PartialParseResult.Provisional, result); + Assert.Equal(PartialParseResultInternal.Accepted | PartialParseResultInternal.Provisional, result); } [Theory] @@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test var result = directiveTokenHandler.CanAcceptChange(target, sourceChange); // Assert - Assert.Equal(PartialParseResult.Rejected, result); + Assert.Equal(PartialParseResultInternal.Rejected, result); } private class TestDirectiveTokenEditHandler : DirectiveTokenEditHandler @@ -59,7 +59,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test { } - public new PartialParseResult CanAcceptChange(Span target, SourceChange change) + public new PartialParseResultInternal CanAcceptChange(Span target, SourceChange change) => base.CanAcceptChange(target, change); } } diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/StringTextBuffer.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/StringTextBuffer.cs deleted file mode 100644 index 3f5a94a859..0000000000 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/StringTextBuffer.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNetCore.Razor.Language.Legacy -{ - public class StringTextBuffer : ITextBuffer, IDisposable - { - private string _buffer; - public bool Disposed { get; set; } - - public StringTextBuffer(string buffer) - { - _buffer = buffer; - } - - public int Length - { - get { return _buffer.Length; } - } - - public int Position { get; set; } - - public int Read() - { - if (Position >= _buffer.Length) - { - return -1; - } - return _buffer[Position++]; - } - - public int Peek() - { - if (Position >= _buffer.Length) - { - return -1; - } - return _buffer[Position]; - } - - public void Dispose() - { - Disposed = true; - } - - public object VersionToken - { - get { return _buffer; } - } - } -} diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DesignTime/Simple.cshtml b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DesignTime/Simple.cshtml deleted file mode 100644 index b50db22f77..0000000000 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DesignTime/Simple.cshtml +++ /dev/null @@ -1,16 +0,0 @@ -@{ - string hello = "Hello, World"; -} - - - - Simple Page - - -

Simple Page

-

@hello

-

- @foreach(char c in hello) {@c} -

- - \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DesignTime/Simple.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DesignTime/Simple.txt deleted file mode 100644 index 69d42ccf0e..0000000000 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DesignTime/Simple.txt +++ /dev/null @@ -1,43 +0,0 @@ -namespace Razor -{ - #line hidden - public class Template - { - #pragma warning disable 219 - private void __RazorDirectiveTokenHelpers__() { - } - #pragma warning restore 219 - private static System.Object __o = null; - #pragma warning disable 1998 - public async override global::System.Threading.Tasks.Task ExecuteAsync() - { -#line 1 "C:\This\Path\Is\Just\For\Line\Pragmas.cshtml" - - string hello = "Hello, World"; - -#line default -#line hidden -#line 11 "C:\This\Path\Is\Just\For\Line\Pragmas.cshtml" - __o = hello; - -#line default -#line hidden -#line 13 "C:\This\Path\Is\Just\For\Line\Pragmas.cshtml" - foreach(char c in hello) { - -#line default -#line hidden -#line 13 "C:\This\Path\Is\Just\For\Line\Pragmas.cshtml" - __o = c; - -#line default -#line hidden -#line 13 "C:\This\Path\Is\Just\For\Line\Pragmas.cshtml" - } - -#line default -#line hidden - } - #pragma warning restore 1998 - } -} diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BlockExtensions.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/BlockExtensions.cs similarity index 100% rename from test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BlockExtensions.cs rename to test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/BlockExtensions.cs diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BlockFactory.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/BlockFactory.cs similarity index 100% rename from test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BlockFactory.cs rename to test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/BlockFactory.cs diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BlockTypes.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/BlockTypes.cs similarity index 100% rename from test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BlockTypes.cs rename to test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/BlockTypes.cs diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/ErrorCollector.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ErrorCollector.cs similarity index 100% rename from test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/ErrorCollector.cs rename to test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ErrorCollector.cs diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/ParserTestBase.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs similarity index 100% rename from test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/ParserTestBase.cs rename to test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/ParserTestBase.cs diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/RawTextSymbol.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/RawTextSymbol.cs similarity index 100% rename from test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/RawTextSymbol.cs rename to test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/RawTextSymbol.cs diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TestSpanBuilder.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/TestSpanBuilder.cs similarity index 100% rename from test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TestSpanBuilder.cs rename to test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/TestSpanBuilder.cs diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/SyntaxTreeVerifier.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/SyntaxTreeVerifier.cs similarity index 100% rename from test/Microsoft.AspNetCore.Razor.Language.Test/SyntaxTreeVerifier.cs rename to test/Microsoft.AspNetCore.Razor.Test.Common/Language/SyntaxTreeVerifier.cs diff --git a/test/Microsoft.AspNetCore.Razor.Test.Common/Microsoft.AspNetCore.Razor.Test.Common.csproj b/test/Microsoft.AspNetCore.Razor.Test.Common/Microsoft.AspNetCore.Razor.Test.Common.csproj index 7aa0660765..43182ff223 100644 --- a/test/Microsoft.AspNetCore.Razor.Test.Common/Microsoft.AspNetCore.Razor.Test.Common.csproj +++ b/test/Microsoft.AspNetCore.Razor.Test.Common/Microsoft.AspNetCore.Razor.Test.Common.csproj @@ -6,7 +6,6 @@ $(DefineConstants);GENERATE_BASELINES $(DefineConstants);__RemoveThisBitTo__GENERATE_BASELINES netcoreapp2.0;net46 - netcoreapp2.0 diff --git a/test/Microsoft.CodeAnalysis.Razor.Test/DefaultTagHelperDescriptorProviderTest.cs b/test/Microsoft.CodeAnalysis.Razor.Test/DefaultTagHelperDescriptorProviderTest.cs new file mode 100644 index 0000000000..58e850876d --- /dev/null +++ b/test/Microsoft.CodeAnalysis.Razor.Test/DefaultTagHelperDescriptorProviderTest.cs @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Linq; +using System.Reflection; +using Microsoft.AspNetCore.Razor.Language; +using Xunit; + +namespace Microsoft.CodeAnalysis.Razor +{ + public class DefaultTagHelperDescriptorProviderTest + { + private static readonly Assembly _assembly = typeof(DefaultTagHelperDescriptorProviderTest).GetTypeInfo().Assembly; + + [Fact] + public void Execute_DoesNotAddEditorBrowsableNeverDescriptorsAtDesignTime() + { + // Arrange + var editorBrowsableTypeName = "Microsoft.CodeAnalysis.Razor.Workspaces.Test.EditorBrowsableTagHelper"; + var compilation = TestCompilation.Create(_assembly); + var descriptorProvider = new DefaultTagHelperDescriptorProvider() + { + DesignTime = true, + }; + var context = TagHelperDescriptorProviderContext.Create(); + + // Act + descriptorProvider.Execute(context); + + // Assert + Assert.NotNull(compilation.GetTypeByMetadataName(editorBrowsableTypeName)); + var nullDescriptors = context.Results.Where(descriptor => descriptor == null); + Assert.Empty(nullDescriptors); + var editorBrowsableDescriptor = context.Results.Where(descriptor => descriptor.GetTypeName() == editorBrowsableTypeName); + Assert.Empty(editorBrowsableDescriptor); + } + } +} diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Microsoft.VisualStudio.LanguageServices.Razor.Test.csproj b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Microsoft.VisualStudio.LanguageServices.Razor.Test.csproj index 96bf0959fb..1b1eb040d1 100644 --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Microsoft.VisualStudio.LanguageServices.Razor.Test.csproj +++ b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Microsoft.VisualStudio.LanguageServices.Razor.Test.csproj @@ -20,6 +20,7 @@ + diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/RazorEditorParserTest.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/RazorEditorParserTest.cs new file mode 100644 index 0000000000..5fd369d42a --- /dev/null +++ b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/RazorEditorParserTest.cs @@ -0,0 +1,1479 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using Microsoft.AspNetCore.Mvc.Razor.Extensions; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Microsoft.VisualStudio.Text; +using Xunit; + +namespace Microsoft.VisualStudio.LanguageServices.Razor +{ + public class RazorEditorParserTest + { + private static readonly TestFile SimpleCSHTMLDocument = TestFile.Create("TestFiles/DesignTime/Simple.cshtml", typeof(RazorEditorParserTest)); + private static readonly TestFile SimpleCSHTMLDocumentGenerated = TestFile.Create("TestFiles/DesignTime/Simple.txt", typeof(RazorEditorParserTest)); + private const string TestLinePragmaFileName = "C:\\This\\Path\\Is\\Just\\For\\Line\\Pragmas.cshtml"; + + public static TheoryData TagHelperPartialParseRejectData + { + get + { + // change, (Block)expectedDocument + return new TheoryData + { + { + CreateInsertionChange("

", 2, " "), + new MarkupBlock( + new MarkupTagHelperBlock("p")) + }, + { + CreateInsertionChange("

", 6, " "), + new MarkupBlock( + new MarkupTagHelperBlock("p")) + }, + { + CreateInsertionChange("

", 12, " "), + new MarkupBlock( + new MarkupTagHelperBlock( + "p", + attributes: new List + { + new TagHelperAttributeNode( + "some-attr", + value: null, + attributeStructure: AttributeStructure.Minimized) + })) + }, + { + CreateInsertionChange("

", 12, "ibute"), + new MarkupBlock( + new MarkupTagHelperBlock( + "p", + attributes: new List + { + new TagHelperAttributeNode( + "some-attribute", + value: null, + attributeStructure: AttributeStructure.Minimized) + })) + }, + { + CreateInsertionChange("

", 2, " before"), + new MarkupBlock( + new MarkupTagHelperBlock( + "p", + attributes: new List + { + new TagHelperAttributeNode( + "before", + value: null, + attributeStructure: AttributeStructure.Minimized), + new TagHelperAttributeNode( + "some-attr", + value: null, + attributeStructure: AttributeStructure.Minimized) + })) + }, + }; + } + } + + [Theory] + [MemberData(nameof(TagHelperPartialParseRejectData))] + public void TagHelperTagBodiesRejectPartialChanges(object editObject, object expectedDocument) + { + // Arrange + var edit = (TestEdit)editObject; + var builder = TagHelperDescriptorBuilder.Create("PTagHelper", "TestAssembly"); + builder.SetTypeName("PTagHelper"); + builder.TagMatchingRule(rule => rule.TagName = "p"); + var descriptors = new[] + { + builder.Build() + }; + + var parser = new RazorEditorParser(CreateTemplateEngine(@"C:\This\Is\A\Test\Path"), @"C:\This\Is\A\Test\Path"); + + using (var manager = new TestParserManager(parser)) + { + manager.InitializeWithDocument(edit.OldSnapshot); + + // Act + var result = manager.CheckForStructureChangesAndWait(edit); + + // Assert + Assert.Equal(PartialParseResult.Rejected, result); + Assert.Equal(2, manager.ParseCount); + } + } + + public static TheoryData TagHelperAttributeAcceptData + { + get + { + var factory = new SpanFactory(); + + // change, (Block)expectedDocument, partialParseResult + return new TheoryData + { + { + CreateInsertionChange("

", 22, "."), + new MarkupBlock( + new MarkupTagHelperBlock( + "p", + attributes: new List + { + new TagHelperAttributeNode( + "str-attr", + new MarkupBlock( + new MarkupBlock( + new ExpressionBlock( + factory.CodeTransition(), + factory + .Code("DateTime.") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)))), + AttributeStructure.SingleQuotes) + })), + PartialParseResult.Accepted | PartialParseResult.Provisional + }, + { + CreateInsertionChange("

", 21, "."), + new MarkupBlock( + new MarkupTagHelperBlock( + "p", + attributes: new List + { + new TagHelperAttributeNode( + "obj-attr", + factory.CodeMarkup("DateTime."), + AttributeStructure.SingleQuotes) + })), + PartialParseResult.Accepted + }, + { + CreateInsertionChange("

", 25, "."), + new MarkupBlock( + new MarkupTagHelperBlock( + "p", + attributes: new List + { + new TagHelperAttributeNode( + "obj-attr", + factory.CodeMarkup("1 + DateTime."), + AttributeStructure.SingleQuotes) + })), + PartialParseResult.Accepted + }, + { + CreateInsertionChange("

", 34, "."), + new MarkupBlock( + new MarkupTagHelperBlock( + "p", + attributes: new List + { + new TagHelperAttributeNode( + "before-attr", + value: null, + attributeStructure: AttributeStructure.Minimized), + new TagHelperAttributeNode( + "str-attr", + new MarkupBlock( + new MarkupBlock( + new ExpressionBlock( + factory.CodeTransition(), + factory + .Code("DateTime.") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)))), + AttributeStructure.SingleQuotes), + new TagHelperAttributeNode( + "after-attr", + value: null, + attributeStructure: AttributeStructure.Minimized), + })), + PartialParseResult.Accepted | PartialParseResult.Provisional + }, + { + CreateInsertionChange("

", 29, "."), + new MarkupBlock( + new MarkupTagHelperBlock( + "p", + attributes: new List + { + new TagHelperAttributeNode( + "str-attr", + new MarkupBlock( + factory.Markup("before"), + new MarkupBlock( + factory.Markup(" "), + new ExpressionBlock( + factory.CodeTransition(), + factory + .Code("DateTime.") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace))), + factory.Markup(" after")), + AttributeStructure.SingleQuotes) + })), + PartialParseResult.Accepted | PartialParseResult.Provisional + }, + }; + } + } + + [Theory] + [MemberData(nameof(TagHelperAttributeAcceptData))] + public void TagHelperAttributesAreLocatedAndAcceptChangesCorrectly( + object editObject, + object expectedDocument, + PartialParseResult partialParseResult) + { + // Arrange + var edit = (TestEdit)editObject; + 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 parser = new RazorEditorParser(CreateTemplateEngine(@"C:\This\Is\A\Test\Path", descriptors), @"C:\This\Is\A\Test\Path"); + + using (var manager = new TestParserManager(parser)) + { + manager.InitializeWithDocument(edit.OldSnapshot); + + // Act + var result = manager.CheckForStructureChangesAndWait(edit); + + // Assert + Assert.Equal(partialParseResult, result); + Assert.Equal(1, manager.ParseCount); + } + } + + [Fact] + public void ConstructorRequiresNonNullPhysicalPath() + { + Assert.Throws("filePath", () => new RazorEditorParser(CreateTemplateEngine(), null)); + } + + [Fact] + public void ConstructorRequiresNonEmptyPhysicalPath() + { + Assert.Throws("filePath", () => new RazorEditorParser(CreateTemplateEngine(), string.Empty)); + } + + [Theory] + [InlineData(" ")] + [InlineData("\r\n")] + [InlineData("abcdefg")] + [InlineData("\f\r\n abcd \t")] + public void TreesAreDifferentReturnsFalseForAddedContent(string content) + { + // Arrange + var factory = new SpanFactory(); + var blockFactory = new BlockFactory(factory); + var original = new MarkupBlock( + blockFactory.MarkupTagBlock("

"), + blockFactory.TagHelperBlock( + tagName: "div", + tagMode: TagMode.StartTagAndEndTag, + start: new SourceLocation(3, 0, 3), + startTag: blockFactory.MarkupTagBlock("

"), + children: new SyntaxTreeNode[] + { + factory.Markup($"{Environment.NewLine}{Environment.NewLine}") + }, + endTag: blockFactory.MarkupTagBlock("
")), + blockFactory.MarkupTagBlock("

")); + + factory.Reset(); + + var modified = new MarkupBlock( + blockFactory.MarkupTagBlock("

"), + blockFactory.TagHelperBlock( + tagName: "div", + tagMode: TagMode.StartTagAndEndTag, + start: new SourceLocation(3, 0, 3), + startTag: blockFactory.MarkupTagBlock("

"), + children: new SyntaxTreeNode[] + { + factory.Markup($"{Environment.NewLine}{content}{Environment.NewLine}") + }, + endTag: blockFactory.MarkupTagBlock("
")), + blockFactory.MarkupTagBlock("

")); + original.LinkNodes(); + modified.LinkNodes(); + + // Act + var treesAreDifferent = BackgroundParser.TreesAreDifferent( + original, + modified, + new[] + { + new SourceChange( + absoluteIndex: 8 + Environment.NewLine.Length, + length: 0, + newText: content) + }, + CancellationToken.None); + + // Assert + Assert.False(treesAreDifferent); + } + + [Fact] + public void TreesAreDifferentReturnsTrueIfTreeStructureIsDifferent() + { + var factory = new SpanFactory(); + var original = new MarkupBlock( + factory.Markup("

"), + new ExpressionBlock( + factory.CodeTransition()), + factory.Markup("

")); + var modified = new MarkupBlock( + factory.Markup("

"), + new ExpressionBlock( + factory.CodeTransition("@"), + factory.Code("f") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)), + factory.Markup("

")); + Assert.True(BackgroundParser.TreesAreDifferent( + original, + modified, + new[] + { + new SourceChange(absoluteIndex: 4, length: 0, newText: "f") + }, + CancellationToken.None)); + } + + [Fact] + public void TreesAreDifferentReturnsFalseIfTreeStructureIsSame() + { + var factory = new SpanFactory(); + var original = new MarkupBlock( + factory.Markup("

"), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("f") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)), + factory.Markup("

")); + factory.Reset(); + var modified = new MarkupBlock( + factory.Markup("

"), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("foo") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)), + factory.Markup("

")); + original.LinkNodes(); + modified.LinkNodes(); + Assert.False(BackgroundParser.TreesAreDifferent( + original, + modified, + new[] + { + new SourceChange(absoluteIndex: 5, length: 0, newText: "oo") + }, + CancellationToken.None)); + } + + [Fact] + public void CheckForStructureChangesStartsFullReparseIfChangeOverlapsMultipleSpans() + { + // Arrange + using (var parser = new RazorEditorParser(CreateTemplateEngine(), TestLinePragmaFileName)) + { + var original = new StringTextSnapshot("Foo @bar Baz"); + var changed = new StringTextSnapshot("Foo @bap Daz"); + var change = new SourceChange(7, 3, "p D"); + + var parseComplete = new ManualResetEventSlim(); + var parseCount = 0; + parser.DocumentParseComplete += (sender, args) => + { + Interlocked.Increment(ref parseCount); + parseComplete.Set(); + }; + + Assert.Equal(PartialParseResult.Rejected, parser.CheckForStructureChanges(change, original)); + DoWithTimeoutIfNotDebugging(parseComplete.Wait); // Wait for the parse to finish + parseComplete.Reset(); + + // Act + var result = parser.CheckForStructureChanges(change, original); + + // Assert + Assert.Equal(PartialParseResult.Rejected, result); + DoWithTimeoutIfNotDebugging(parseComplete.Wait); + Assert.Equal(2, parseCount); + } + } + + [Fact] + public void AwaitPeriodInsertionAcceptedProvisionally() + { + // Arrange + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("foo @await Html. baz"); + var old = new StringTextSnapshot("foo @await Html baz"); + + // Act and Assert + RunPartialParseTest(new TestEdit(15, 0, old, 1, changed, "."), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("await Html.").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.WhiteSpace | AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz")), additionalFlags: PartialParseResult.Provisional); + } + + [Fact] + public void ImplicitExpressionAcceptsInnerInsertionsInStatementBlock() + { + // Arrange + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("@{" + Environment.NewLine + + " @DateTime..Now" + Environment.NewLine + + "}"); + var old = new StringTextSnapshot("@{" + Environment.NewLine + + " @DateTime.Now" + Environment.NewLine + + "}"); + + // Act and Assert + RunPartialParseTest(new TestEdit(17, 0, old, 1, changed, "."), + new MarkupBlock( + factory.EmptyHtml(), + new StatementBlock( + factory.CodeTransition(), + factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None), + factory.Code(Environment.NewLine + " ") + .AsStatement() + .AutoCompleteWith(autoCompleteString: null), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("DateTime..Now") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Code(Environment.NewLine).AsStatement(), + factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), + factory.EmptyHtml())); + } + + [Fact] + public void ImplicitExpressionAcceptsInnerInsertions() + { + // Arrange + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("foo @DateTime..Now baz"); + var old = new StringTextSnapshot("foo @DateTime.Now baz"); + + // Act and Assert + RunPartialParseTest(new TestEdit(13, 0, old, 1, changed, "."), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("DateTime..Now").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz")), additionalFlags: PartialParseResult.Provisional); + } + + [Fact] + public void ImplicitExpressionAcceptsWholeIdentifierReplacement() + { + // Arrange + var factory = new SpanFactory(); + var old = new StringTextSnapshot("foo @date baz"); + var changed = new StringTextSnapshot("foo @DateTime baz"); + + // Act and Assert + RunPartialParseTest(new TestEdit(5, 4, old, 8, changed, "DateTime"), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("DateTime").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + } + + [Fact] + public void ImplicitExpressionRejectsWholeIdentifierReplacementToKeyword() + { + // Arrange + var parser = new RazorEditorParser(CreateTemplateEngine(@"C:\This\Is\A\Test\Path"), @"C:\This\Is\A\Test\Path"); + + using (var manager = new TestParserManager(parser)) + { + var old = new StringTextSnapshot("foo @date baz"); + var changed = new StringTextSnapshot("foo @if baz"); + var edit = new TestEdit(5, 4, old, 2, changed, "if"); + manager.InitializeWithDocument(old); + + // Act + var result = manager.CheckForStructureChangesAndWait(edit); + + // Assert + Assert.Equal(PartialParseResult.Rejected, result); + Assert.Equal(2, manager.ParseCount); + } + } + + [Fact] + public void ImplicitExpressionRejectsWholeIdentifierReplacementToDirective() + { + // Arrange + var parser = new RazorEditorParser(CreateTemplateEngine(@"C:\This\Is\A\Test\Path"), @"C:\This\Is\A\Test\Path"); + + using (var manager = new TestParserManager(parser)) + { + var old = new StringTextSnapshot("foo @date baz"); + var changed = new StringTextSnapshot("foo @inherits baz"); + var SourceChange = new TestEdit(5, 4, old, 8, changed, "inherits"); + manager.InitializeWithDocument(old); + + // Act + var result = manager.CheckForStructureChangesAndWait(SourceChange); + + // Assert + Assert.Equal(PartialParseResult.Rejected | PartialParseResult.SpanContextChanged, result); + Assert.Equal(2, manager.ParseCount); + } + } + + [Fact] + public void ImplicitExpressionAcceptsPrefixIdentifierReplacements_SingleSymbol() + { + // Arrange + var factory = new SpanFactory(); + var old = new StringTextSnapshot("foo @dTime baz"); + var changed = new StringTextSnapshot("foo @DateTime baz"); + + // Act and Assert + RunPartialParseTest(new TestEdit(5, 1, old, 4, changed, "Date"), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("DateTime").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + } + + [Fact] + public void ImplicitExpressionAcceptsPrefixIdentifierReplacements_MultipleSymbols() + { + // Arrange + var factory = new SpanFactory(); + var old = new StringTextSnapshot("foo @dTime.Now baz"); + var changed = new StringTextSnapshot("foo @DateTime.Now baz"); + + // Act and Assert + RunPartialParseTest(new TestEdit(5, 1, old, 4, changed, "Date"), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("DateTime.Now").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + } + + [Fact] + public void ImplicitExpressionAcceptsSuffixIdentifierReplacements_SingleSymbol() + { + // Arrange + var factory = new SpanFactory(); + var old = new StringTextSnapshot("foo @Datet baz"); + var changed = new StringTextSnapshot("foo @DateTime baz"); + + // Act and Assert + RunPartialParseTest(new TestEdit(9, 1, old, 4, changed, "Time"), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("DateTime").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + } + + [Fact] + public void ImplicitExpressionAcceptsSuffixIdentifierReplacements_MultipleSymbols() + { + // Arrange + var factory = new SpanFactory(); + var old = new StringTextSnapshot("foo @DateTime.n baz"); + var changed = new StringTextSnapshot("foo @DateTime.Now baz"); + + // Act and Assert + RunPartialParseTest(new TestEdit(14, 1, old, 3, changed, "Now"), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("DateTime.Now").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + } + + [Fact] + public void ImplicitExpressionAcceptsSurroundedIdentifierReplacements() + { + // Arrange + var factory = new SpanFactory(); + var old = new StringTextSnapshot("foo @DateTime.n.ToString() baz"); + var changed = new StringTextSnapshot("foo @DateTime.Now.ToString() baz"); + + // Act and Assert + RunPartialParseTest(new TestEdit(14, 1, old, 3, changed, "Now"), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("DateTime.Now.ToString()").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + } + + [Fact] + public void ImplicitExpressionAcceptsDotlessCommitInsertionsInStatementBlockAfterIdentifiers() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("@{" + Environment.NewLine + + " @DateTime." + Environment.NewLine + + "}"); + var old = new StringTextSnapshot("@{" + Environment.NewLine + + " @DateTime" + Environment.NewLine + + "}"); + + var edit = new TestEdit(15 + Environment.NewLine.Length, 0, old, 1, changed, "."); + using (var manager = CreateParserManager()) + { + Action applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) => + { + var result = manager.CheckForStructureChangesAndWait(edit); + + // Assert + Assert.Equal(expectedResult, result); + Assert.Equal(1, manager.ParseCount); + ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, new MarkupBlock( + factory.EmptyHtml(), + new StatementBlock( + factory.CodeTransition(), + factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None), + factory.Code(Environment.NewLine + " ") + .AsStatement() + .AutoCompleteWith(autoCompleteString: null), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code(expectedCode) + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Code(Environment.NewLine).AsStatement(), + factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), + factory.EmptyHtml())); + }; + + manager.InitializeWithDocument(edit.OldSnapshot); + + // This is the process of a dotless commit when doing "." insertions to commit intellisense changes. + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateTime."); + + old = changed; + changed = new StringTextSnapshot("@{" + Environment.NewLine + + " @DateTime.." + Environment.NewLine + + "}"); + edit = new TestEdit(16 + Environment.NewLine.Length, 0, old, 1, changed, "."); + + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateTime.."); + + old = changed; + changed = new StringTextSnapshot("@{" + Environment.NewLine + + " @DateTime.Now." + Environment.NewLine + + "}"); + edit = new TestEdit(16 + Environment.NewLine.Length, 0, old, 3, changed, "Now"); + + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateTime.Now."); + } + } + + [Fact] + public void ImplicitExpressionAcceptsDotlessCommitInsertionsInStatementBlock() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("@{" + Environment.NewLine + + " @DateT." + Environment.NewLine + + "}"); + var old = new StringTextSnapshot("@{" + Environment.NewLine + + " @DateT" + Environment.NewLine + + "}"); + + var edit = new TestEdit(12 + Environment.NewLine.Length, 0, old, 1, changed, "."); + using (var manager = CreateParserManager()) + { + Action applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) => + { + var result = manager.CheckForStructureChangesAndWait(edit); + + // Assert + Assert.Equal(expectedResult, result); + Assert.Equal(1, manager.ParseCount); + ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, new MarkupBlock( + factory.EmptyHtml(), + new StatementBlock( + factory.CodeTransition(), + factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None), + factory.Code(Environment.NewLine + " ") + .AsStatement() + .AutoCompleteWith(autoCompleteString: null), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code(expectedCode) + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Code(Environment.NewLine).AsStatement(), + factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), + factory.EmptyHtml())); + }; + + manager.InitializeWithDocument(edit.OldSnapshot); + + // This is the process of a dotless commit when doing "." insertions to commit intellisense changes. + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateT."); + + old = changed; + changed = new StringTextSnapshot("@{" + Environment.NewLine + + " @DateTime." + Environment.NewLine + + "}"); + edit = new TestEdit(12 + Environment.NewLine.Length, 0, old, 3, changed, "ime"); + + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateTime."); + } + } + + [Fact] + public void ImplicitExpressionProvisionallyAcceptsDotlessCommitInsertions() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("foo @DateT. baz"); + var old = new StringTextSnapshot("foo @DateT baz"); + var edit = new TestEdit(10, 0, old, 1, changed, "."); + using (var manager = CreateParserManager()) + { + Action applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) => + { + var result = manager.CheckForStructureChangesAndWait(edit); + + // Assert + Assert.Equal(expectedResult, result); + Assert.Equal(1, manager.ParseCount); + + ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code(expectedCode).AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + }; + + manager.InitializeWithDocument(edit.OldSnapshot); + + // This is the process of a dotless commit when doing "." insertions to commit intellisense changes. + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateT."); + + old = changed; + changed = new StringTextSnapshot("foo @DateTime. baz"); + edit = new TestEdit(10, 0, old, 3, changed, "ime"); + + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime."); + } + } + + [Fact] + public void ImplicitExpressionProvisionallyAcceptsDotlessCommitInsertionsAfterIdentifiers() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("foo @DateTime. baz"); + var old = new StringTextSnapshot("foo @DateTime baz"); + var edit = new TestEdit(13, 0, old, 1, changed, "."); + using (var manager = CreateParserManager()) + { + Action applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) => + { + var result = manager.CheckForStructureChangesAndWait(edit); + + // Assert + Assert.Equal(expectedResult, result); + Assert.Equal(1, manager.ParseCount); + + ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code(expectedCode).AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + }; + + manager.InitializeWithDocument(edit.OldSnapshot); + + // This is the process of a dotless commit when doing "." insertions to commit intellisense changes. + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime."); + + old = changed; + changed = new StringTextSnapshot("foo @DateTime.. baz"); + edit = new TestEdit(14, 0, old, 1, changed, "."); + + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime.."); + + old = changed; + changed = new StringTextSnapshot("foo @DateTime.Now. baz"); + edit = new TestEdit(14, 0, old, 3, changed, "Now"); + + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime.Now."); + } + } + + [Fact] + public void ImplicitExpressionProvisionallyAcceptsCaseInsensitiveDotlessCommitInsertions_NewRoslynIntegration() + { + var factory = new SpanFactory(); + var old = new StringTextSnapshot("foo @date baz"); + var changed = new StringTextSnapshot("foo @date. baz"); + var edit = new TestEdit(9, 0, old, 1, changed, "."); + using (var manager = CreateParserManager()) + { + Action applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) => + { + var result = manager.CheckForStructureChangesAndWait(edit); + + // Assert + Assert.Equal(expectedResult, result); + Assert.Equal(1, manager.ParseCount); + + ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code(expectedCode).AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + }; + + manager.InitializeWithDocument(edit.OldSnapshot); + + // This is the process of a dotless commit when doing "." insertions to commit intellisense changes. + + // @date => @date. + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "date."); + + old = changed; + changed = new StringTextSnapshot("foo @date baz"); + edit = new TestEdit(9, 1, old, 0, changed, ""); + + // @date. => @date + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "date"); + + old = changed; + changed = new StringTextSnapshot("foo @DateTime baz"); + edit = new TestEdit(5, 4, old, 8, changed, "DateTime"); + + // @date => @DateTime + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateTime"); + + old = changed; + changed = new StringTextSnapshot("foo @DateTime. baz"); + edit = new TestEdit(13, 0, old, 1, changed, "."); + + // @DateTime => @DateTime. + applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime."); + } + } + + [Fact] + public void ImplicitExpressionProvisionallyAcceptsDeleteOfIdentifierPartsIfDotRemains() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("foo @User. baz"); + var old = new StringTextSnapshot("foo @User.Name baz"); + RunPartialParseTest(new TestEdit(10, 4, old, 0, changed, string.Empty), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("User.").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz")), + additionalFlags: PartialParseResult.Provisional); + } + + [Fact] + public void ImplicitExpressionAcceptsDeleteOfIdentifierPartsIfSomeOfIdentifierRemains() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("foo @Us baz"); + var old = new StringTextSnapshot("foo @User baz"); + RunPartialParseTest(new TestEdit(7, 2, old, 0, changed, string.Empty), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("Us").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + } + + [Fact] + public void ImplicitExpressionProvisionallyAcceptsMultipleInsertionIfItCausesIdentifierExpansionAndTrailingDot() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("foo @User. baz"); + var old = new StringTextSnapshot("foo @U baz"); + RunPartialParseTest(new TestEdit(6, 0, old, 4, changed, "ser."), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("User.").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz")), + additionalFlags: PartialParseResult.Provisional); + } + + [Fact] + public void ImplicitExpressionAcceptsMultipleInsertionIfItOnlyCausesIdentifierExpansion() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("foo @barbiz baz"); + var old = new StringTextSnapshot("foo @bar baz"); + RunPartialParseTest(new TestEdit(8, 0, old, 3, changed, "biz"), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("barbiz").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" baz"))); + } + + [Fact] + public void ImplicitExpressionAcceptsIdentifierExpansionAtEndOfNonWhitespaceCharacters() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("@{" + Environment.NewLine + + " @food" + Environment.NewLine + + "}"); + var old = new StringTextSnapshot("@{" + Environment.NewLine + + " @foo" + Environment.NewLine + + "}"); + RunPartialParseTest(new TestEdit(10 + Environment.NewLine.Length, 0, old, 1, changed, "d"), + new MarkupBlock( + factory.EmptyHtml(), + new StatementBlock( + factory.CodeTransition(), + factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None), + factory.Code(Environment.NewLine + " ") + .AsStatement() + .AutoCompleteWith(autoCompleteString: null), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("food") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Code(Environment.NewLine).AsStatement(), + factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), + factory.EmptyHtml())); + } + + [Fact] + public void ImplicitExpressionAcceptsIdentifierAfterDotAtEndOfNonWhitespaceCharacters() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("@{" + Environment.NewLine + + " @foo.d" + Environment.NewLine + + "}"); + var old = new StringTextSnapshot("@{" + Environment.NewLine + + " @foo." + Environment.NewLine + + "}"); + RunPartialParseTest(new TestEdit(11 + Environment.NewLine.Length, 0, old, 1, changed, "d"), + new MarkupBlock( + factory.EmptyHtml(), + new StatementBlock( + factory.CodeTransition(), + factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None), + factory.Code(Environment.NewLine + " ") + .AsStatement() + .AutoCompleteWith(autoCompleteString: null), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("foo.d") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Code(Environment.NewLine).AsStatement(), + factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), + factory.EmptyHtml())); + } + + [Fact] + public void ImplicitExpressionAcceptsDotAtEndOfNonWhitespaceCharacters() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("@{" + Environment.NewLine + + " @foo." + Environment.NewLine + + "}"); + var old = new StringTextSnapshot("@{" + Environment.NewLine + + " @foo" + Environment.NewLine + + "}"); + RunPartialParseTest(new TestEdit(10 + Environment.NewLine.Length, 0, old, 1, changed, "."), + new MarkupBlock( + factory.EmptyHtml(), + new StatementBlock( + factory.CodeTransition(), + factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None), + factory.Code(Environment.NewLine + " ") + .AsStatement() + .AutoCompleteWith(autoCompleteString: null), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code(@"foo.") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Code(Environment.NewLine).AsStatement(), + factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), + factory.EmptyHtml())); + } + + [Fact] + public void ImplicitExpressionRejectsChangeWhichWouldHaveBeenAcceptedIfLastChangeWasProvisionallyAcceptedOnDifferentSpan() + { + var factory = new SpanFactory(); + + // Arrange + var dotTyped = new TestEdit(8, 0, new StringTextSnapshot("foo @foo @bar"), 1, new StringTextSnapshot("foo @foo. @bar"), "."); + var charTyped = new TestEdit(14, 0, new StringTextSnapshot("foo @foo. @bar"), 1, new StringTextSnapshot("foo @foo. @barb"), "b"); + using (var manager = CreateParserManager()) + { + manager.InitializeWithDocument(dotTyped.OldSnapshot); + + // Apply the dot change + Assert.Equal(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped)); + + // Act (apply the identifier start char change) + var result = manager.CheckForStructureChangesAndWait(charTyped); + + // Assert + Assert.Equal(PartialParseResult.Rejected, result); + Assert.False(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not"); + ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("foo") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(". "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("barb") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.EmptyHtml())); + } + } + + [Fact] + public void ImplicitExpressionAcceptsIdentifierTypedAfterDotIfLastChangeWasProvisionalAcceptanceOfDot() + { + var factory = new SpanFactory(); + + // Arrange + var dotTyped = new TestEdit(8, 0, new StringTextSnapshot("foo @foo bar"), 1, new StringTextSnapshot("foo @foo. bar"), "."); + var charTyped = new TestEdit(9, 0, new StringTextSnapshot("foo @foo. bar"), 1, new StringTextSnapshot("foo @foo.b bar"), "b"); + using (var manager = CreateParserManager()) + { + manager.InitializeWithDocument(dotTyped.OldSnapshot); + + // Apply the dot change + Assert.Equal(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped)); + + // Act (apply the identifier start char change) + var result = manager.CheckForStructureChangesAndWait(charTyped); + + // Assert + Assert.Equal(PartialParseResult.Accepted, result); + Assert.False(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not"); + ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("foo.b") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" bar"))); + } + } + + [Fact] + public void ImplicitExpressionProvisionallyAcceptsDotAfterIdentifierInMarkup() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("foo @foo. bar"); + var old = new StringTextSnapshot("foo @foo bar"); + RunPartialParseTest(new TestEdit(8, 0, old, 1, changed, "."), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("foo.") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" bar")), + additionalFlags: PartialParseResult.Provisional); + } + + [Fact] + public void ImplicitExpressionAcceptsAdditionalIdentifierCharactersIfEndOfSpanIsIdentifier() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("foo @foob bar"); + var old = new StringTextSnapshot("foo @foo bar"); + RunPartialParseTest(new TestEdit(8, 0, old, 1, changed, "b"), + new MarkupBlock( + factory.Markup("foo "), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("foob") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.Markup(" bar"))); + } + + [Fact] + public void ImplicitExpressionAcceptsAdditionalIdentifierStartCharactersIfEndOfSpanIsDot() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("@{@foo.b}"); + var old = new StringTextSnapshot("@{@foo.}"); + RunPartialParseTest(new TestEdit(7, 0, old, 1, changed, "b"), + new MarkupBlock( + factory.EmptyHtml(), + new StatementBlock( + factory.CodeTransition(), + factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None), + factory.EmptyCSharp() + .AsStatement() + .AutoCompleteWith(autoCompleteString: null), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("foo.b") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.EmptyCSharp().AsStatement(), + factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), + factory.EmptyHtml())); + } + + [Fact] + public void ImplicitExpressionAcceptsDotIfTrailingDotsAreAllowed() + { + var factory = new SpanFactory(); + var changed = new StringTextSnapshot("@{@foo.}"); + var old = new StringTextSnapshot("@{@foo}"); + RunPartialParseTest(new TestEdit(6, 0, old, 1, changed, "."), + new MarkupBlock( + factory.EmptyHtml(), + new StatementBlock( + factory.CodeTransition(), + factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None), + factory.EmptyCSharp() + .AsStatement() + .AutoCompleteWith(autoCompleteString: null), + new ExpressionBlock( + factory.CodeTransition(), + factory.Code("foo.") + .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + factory.EmptyCSharp().AsStatement(), + factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), + factory.EmptyHtml())); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfIfKeywordTyped() + { + RunTypeKeywordTest("if"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfDoKeywordTyped() + { + RunTypeKeywordTest("do"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfTryKeywordTyped() + { + RunTypeKeywordTest("try"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfForKeywordTyped() + { + RunTypeKeywordTest("for"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfForEachKeywordTyped() + { + RunTypeKeywordTest("foreach"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfWhileKeywordTyped() + { + RunTypeKeywordTest("while"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfSwitchKeywordTyped() + { + RunTypeKeywordTest("switch"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfLockKeywordTyped() + { + RunTypeKeywordTest("lock"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfUsingKeywordTyped() + { + RunTypeKeywordTest("using"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfSectionKeywordTyped() + { + RunTypeKeywordTest("section"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfInheritsKeywordTyped() + { + RunTypeKeywordTest("inherits"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfFunctionsKeywordTyped() + { + RunTypeKeywordTest("functions"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfNamespaceKeywordTyped() + { + RunTypeKeywordTest("namespace"); + } + + [Fact] + public void ImplicitExpressionCorrectlyTriggersReparseIfClassKeywordTyped() + { + RunTypeKeywordTest("class"); + } + + private static TestEdit CreateInsertionChange(string initialText, int insertionLocation, string insertionText) + { + var changedText = initialText.Insert(insertionLocation, insertionText); + var sourceChange = new SourceChange(insertionLocation, 0, insertionText); + var oldSnapshot = new StringTextSnapshot(initialText); + var changedSnapshot = new StringTextSnapshot(changedText); + return new TestEdit + { + Change = sourceChange, + OldSnapshot = oldSnapshot, + NewSnapshot = changedSnapshot, + }; + } + + private static void RunFullReparseTest(TestEdit edit, PartialParseResult additionalFlags = (PartialParseResult)0) + { + // Arrange + using (var manager = CreateParserManager()) + { + manager.InitializeWithDocument(edit.OldSnapshot); + + // Act + var result = manager.CheckForStructureChangesAndWait(edit); + + // Assert + Assert.Equal(PartialParseResult.Rejected | additionalFlags, result); + Assert.Equal(2, manager.ParseCount); + } + } + + private static void RunPartialParseTest(TestEdit edit, Block newTreeRoot, PartialParseResult additionalFlags = (PartialParseResult)0) + { + // Arrange + using (var manager = CreateParserManager()) + { + manager.InitializeWithDocument(edit.OldSnapshot); + + // Act + var result = manager.CheckForStructureChangesAndWait(edit); + + // Assert + Assert.Equal(PartialParseResult.Accepted | additionalFlags, result); + Assert.Equal(1, manager.ParseCount); + ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, newTreeRoot); + } + } + + private static TestParserManager CreateParserManager() + { + var parser = new RazorEditorParser(CreateTemplateEngine(), TestLinePragmaFileName); + return new TestParserManager(parser); + } + + private static RazorTemplateEngine CreateTemplateEngine( + string path = TestLinePragmaFileName, + IEnumerable tagHelpers = null) + { + var engine = RazorEngine.CreateDesignTime(builder => + { + RazorExtensions.Register(builder); + + if (tagHelpers != null) + { + builder.AddTagHelpers(tagHelpers); + } + }); + + // GetImports on RazorTemplateEngine will at least check that the item exists, so we need to pretend + // that it does. + var items = new List(); + items.Add(new TestRazorProjectItem(path)); + + var project = new TestRazorProject(items); + + var templateEngine = new RazorTemplateEngine(engine, project); + templateEngine.Options.DefaultImports = RazorSourceDocument.Create("@addTagHelper *, Test", "_TestImports.cshtml"); + return templateEngine; + } + + private static void RunTypeKeywordTest(string keyword) + { + var before = "@" + keyword.Substring(0, keyword.Length - 1); + var after = "@" + keyword; + var changed = new StringTextSnapshot(after); + var old = new StringTextSnapshot(before); + var change = new SourceChange(keyword.Length, 0, keyword[keyword.Length - 1].ToString()); + var edit = new TestEdit + { + Change = change, + NewSnapshot = changed, + OldSnapshot = old + }; + RunFullReparseTest(edit, additionalFlags: PartialParseResult.SpanContextChanged); + } + + private static void DoWithTimeoutIfNotDebugging(Func withTimeout) + { +#if DEBUG + if (Debugger.IsAttached) + { + withTimeout(Timeout.Infinite); + } + else + { +#endif + Assert.True(withTimeout((int)TimeSpan.FromSeconds(1).TotalMilliseconds), "Timeout expired!"); +#if DEBUG + } +#endif + } + + private class TestParserManager : IDisposable + { + public int ParseCount; + + private readonly ManualResetEventSlim _parserComplete; + + public TestParserManager(RazorEditorParser parser) + { + _parserComplete = new ManualResetEventSlim(); + ParseCount = 0; + Parser = parser; + parser.DocumentParseComplete += (sender, args) => + { + Interlocked.Increment(ref ParseCount); + _parserComplete.Set(); + }; + } + + public RazorEditorParser Parser { get; } + + public void InitializeWithDocument(ITextSnapshot snapshot) + { + var initialChange = new SourceChange(0, 0, string.Empty); + var edit = new TestEdit + { + Change = initialChange, + OldSnapshot = snapshot, + NewSnapshot = snapshot + }; + CheckForStructureChangesAndWait(edit); + } + + public PartialParseResult CheckForStructureChangesAndWait(TestEdit edit) + { + var result = Parser.CheckForStructureChanges(edit.Change, edit.NewSnapshot); + if (result.HasFlag(PartialParseResult.Rejected)) + { + WaitForParse(); + } + return result; + } + + public void WaitForParse() + { + DoWithTimeoutIfNotDebugging(_parserComplete.Wait); // Wait for the parse to finish + _parserComplete.Reset(); + } + + public void Dispose() + { + Parser.Dispose(); + } + } + + private class TestEdit + { + public TestEdit() + { + } + + public TestEdit(int position, int oldLength, ITextSnapshot oldSnapshot, int newLength, ITextSnapshot newSnapshot, string newText) + { + Change = new SourceChange(position, oldLength, newText); + OldSnapshot = oldSnapshot; + NewSnapshot = newSnapshot; + } + + public SourceChange Change { get; set; } + + public ITextSnapshot OldSnapshot { get; set; } + + public ITextSnapshot NewSnapshot { get; set; } + } + } +} \ No newline at end of file diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/StringTextSnapshot.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/StringTextSnapshot.cs new file mode 100644 index 0000000000..c6e183029b --- /dev/null +++ b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/StringTextSnapshot.cs @@ -0,0 +1,106 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Utilities; + +namespace Microsoft.AspNetCore.Razor.Language.Legacy +{ + public class StringTextSnapshot : ITextSnapshot + { + private readonly string _content; + + public StringTextSnapshot(string content) + { + _content = content; + } + + public char this[int position] => _content[position]; + + public VisualStudio.Text.ITextBuffer TextBuffer => throw new NotImplementedException(); + + public IContentType ContentType => throw new NotImplementedException(); + + public ITextVersion Version => throw new NotImplementedException(); + + public int Length => _content.Length; + + public int LineCount => throw new NotImplementedException(); + + public IEnumerable Lines => throw new NotImplementedException(); + + public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) + { + _content.CopyTo(sourceIndex, destination, destinationIndex, count); + } + + public ITrackingPoint CreateTrackingPoint(int position, PointTrackingMode trackingMode) + { + throw new NotImplementedException(); + } + + public ITrackingPoint CreateTrackingPoint(int position, PointTrackingMode trackingMode, TrackingFidelityMode trackingFidelity) + { + throw new NotImplementedException(); + } + + public ITrackingSpan CreateTrackingSpan(VisualStudio.Text.Span span, SpanTrackingMode trackingMode) + { + throw new NotImplementedException(); + } + + public ITrackingSpan CreateTrackingSpan(VisualStudio.Text.Span span, SpanTrackingMode trackingMode, TrackingFidelityMode trackingFidelity) + { + throw new NotImplementedException(); + } + + public ITrackingSpan CreateTrackingSpan(int start, int length, SpanTrackingMode trackingMode) + { + throw new NotImplementedException(); + } + + public ITrackingSpan CreateTrackingSpan(int start, int length, SpanTrackingMode trackingMode, TrackingFidelityMode trackingFidelity) + { + throw new NotImplementedException(); + } + + public ITextSnapshotLine GetLineFromLineNumber(int lineNumber) + { + throw new NotImplementedException(); + } + + public ITextSnapshotLine GetLineFromPosition(int position) + { + throw new NotImplementedException(); + } + + public int GetLineNumberFromPosition(int position) + { + throw new NotImplementedException(); + } + + public string GetText(VisualStudio.Text.Span span) + { + throw new NotImplementedException(); + } + + public string GetText(int startIndex, int length) => _content.Substring(startIndex, length); + + public string GetText() => _content; + + public char[] ToCharArray(int startIndex, int length) => _content.ToCharArray(); + + public void Write(TextWriter writer, VisualStudio.Text.Span span) + { + throw new NotImplementedException(); + } + + public void Write(TextWriter writer) + { + throw new NotImplementedException(); + } + } +} diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestBoundAttributeDescriptorBuilderExtensions.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestBoundAttributeDescriptorBuilderExtensions.cs similarity index 97% rename from test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestBoundAttributeDescriptorBuilderExtensions.cs rename to test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestBoundAttributeDescriptorBuilderExtensions.cs index 23987d03bf..d784d7b1c0 100644 --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestBoundAttributeDescriptorBuilderExtensions.cs +++ b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestBoundAttributeDescriptorBuilderExtensions.cs @@ -2,8 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNetCore.Razor.Language; -namespace Microsoft.AspNetCore.Razor.Language +namespace Microsoft.VisualStudio.LanguageServices.Razor { public static class TestBoundAttributeDescriptorBuilderExtensions { diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestRequiredAttributeDescriptorBuilderExtensions.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestRequiredAttributeDescriptorBuilderExtensions.cs similarity index 95% rename from test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestRequiredAttributeDescriptorBuilderExtensions.cs rename to test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestRequiredAttributeDescriptorBuilderExtensions.cs index da638e1750..16c4ea9100 100644 --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestRequiredAttributeDescriptorBuilderExtensions.cs +++ b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestRequiredAttributeDescriptorBuilderExtensions.cs @@ -2,8 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNetCore.Razor.Language; -namespace Microsoft.AspNetCore.Razor.Language +namespace Microsoft.VisualStudio.LanguageServices.Razor { public static class TestRequiredAttributeDescriptorBuilderExtensions { diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestTagHelperDescriptorBuilderExtensions.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestTagHelperDescriptorBuilderExtensions.cs similarity index 97% rename from test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestTagHelperDescriptorBuilderExtensions.cs rename to test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestTagHelperDescriptorBuilderExtensions.cs index 5bc81a7792..c32a61580e 100644 --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestTagHelperDescriptorBuilderExtensions.cs +++ b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestTagHelperDescriptorBuilderExtensions.cs @@ -2,8 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNetCore.Razor.Language; -namespace Microsoft.AspNetCore.Razor.Language +namespace Microsoft.VisualStudio.LanguageServices.Razor { public static class TestTagHelperDescriptorBuilderExtensions { diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestTagMatchingRuleDescriptorBuilderExtensions.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestTagMatchingRuleDescriptorBuilderExtensions.cs similarity index 95% rename from test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestTagMatchingRuleDescriptorBuilderExtensions.cs rename to test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestTagMatchingRuleDescriptorBuilderExtensions.cs index f052818fe6..5373498774 100644 --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestTagMatchingRuleDescriptorBuilderExtensions.cs +++ b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Test/TestTagMatchingRuleDescriptorBuilderExtensions.cs @@ -2,8 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNetCore.Razor.Language; -namespace Microsoft.AspNetCore.Razor.Language +namespace Microsoft.VisualStudio.LanguageServices.Razor { public static class TestTagMatchingRuleDescriptorBuilderExtensions {