- Renamed many of our `RazorSourceDocument` abstractions to not include the word `Razor`.
- Added a `GetChecksum()` method to `RazorSourceDocument` to allow source documents to compute their own checksums.
- Re-generated codegen tests that did not normalize new lines. Ones that did re-generate newlines converted from stream => string => normalized string and then ran the Razor parser.
- Added tests to validate `GetChecksum` for all source document types.
- Removed unused `LegacySourceDocument`.
- Went from `typeName __Generated__SomeViewComponentTagHelper.PropertyName` to `typeName SomeViewComponentTagHelper.PropertyName`.
- Updated `TagHelperBoundDescriptorBuilder` to allow setting of `DisplayName`.
- Added `TagHelperBoundAttributeDescriptorBuilderTest` class to verify new `DisplayName` additions.
- Updated `ViewComponentTagHelperDescriptorFactoryTest` expectations.
#1251
- Replaced the magic strings with extension methods that produce the same behavior as the string keys did.
- Added tests to validate new extension methods.
#1307
The new @namespace directive isn't sanitizing class and namespace names
when generating them. This means that a file-system-legal character like
'-' will show up in a class name, and that's not good.
Note that the old code paths (document classifiers) already had tests for
this and did it properly. It was only missing from @namespace.
- Went from `__Generated__SomeViewComponentTagHelper` to `SomeViewComponentTagHelper`.
- Updated `TagHelperDescriptorBuilder` to allow setting of `DisplayName`.
- Added `TagHelperDescriptorBuilderTest` class to verify new `DisplayName` additions.
- Updated `ViewComponentTagHelperDescriptorFactoryTest` expectations.
#1251
- Without a directive string token having a `SpanKind.Code` it cannot have any sort of C# coloring associated with it.
- Updated tests to reflect new `SpanKind` expectations.
#1269
Created internal + public versions of
- BlockKind
- SpanKind
- AcceptedCharacters
That way these types are only exposed through the VS apis and not
through the runtime API surface.
Also deleted RazorEditorParser. Yep. It's going to take significant work
to just port it to the language services assembly. Let's reevaluate this
when we get closer to the next foundational update.
- Instead of rendering a null assigning statement for a type token we now render a `default(TTypeToken)`. With this approach type tokens can be value types without creating a design time error.
- Re-generated baseline files to reflect new directive token code generation.
#1176
This change adds an API for Tag Helper discovery.
I also got rid of the 'design time' flag for the provider as an
experimental change. We need to think through the consequences of this
before committing to it. Right now I've left those tests failing until we
can make a decision.
This change decouples VCTH discovery a bit more, but we're still not ready
to move that into a the MVC extensions assembly. For that we need the
ability to discover the MVC extensibility.
- This makes it so if you have catch all `TagHelperDescriptor`s their completions don't apply to every existing completion. Instead, they now only apply to already TagHelperified completions and existing completions that are prefixed with a non-empty TagHelperPrefix.
- Updated existing test to have new expectations.
- Added new test to validate non-empty tag helper prefix case.
#1230
This change removes the default usings for 'System' and
'System.Threading.Tasks' and adds them to the MVC template engine.
This is preparation for removing this feature from the razor options, I
wanted to get all of the intentional diff out of the way.
- The change wasn't exactly what was expected. The core `ServiceHub` is still what calls into our `Stream`, `IServiceProvider` overload (as intended) which means we needed to call down into the proper basetype constructor to start using Roslyn's non-obsolete one.
- Had to manually start the `StreamJsonRpc` property to work around race conditions in the ServiceHub APIs.
#976
This is a MEF service that can actively or passively track open ITextViews
and give us information about the Razor initialization state and eventing
when it changes.
The purpose of this is to act as a bridge between the VS mef world and the
roslyn world.
For now this doesn't do any passive tracking of Razor documents, it's only
on demand. That means it will only be initialized and used right now when
you are using the Razor developer tools. This is just to reduce our risk,
it's not ideal to ship code in VS that's doing something without anyone
looking at the result.
- Moved the type out of the Legacy namespace.
- Renamed the types method to `GetBinding` since `TagHelper` is now inferred.
- Updated test names to reflect new method/class name.
- Updated product code variables to reflect new naming (provider => binder).
#1289
- Added a `GetAttributeCompletions` API that's consistent with current Razor's editor expectations.
- Added unit tests to validate all code paths of the new `GetAttributeCompletions` method.
#1120
- This involved not using the `First()` method when reading the directives tokens.
- Added two tests to validate an empty directive token and a missed directive token for the `@namespace` directive.
#1268
- Found that our extensible directive string parsing system wasn't consistent with the rest of the extensible directive tokens. Basically, if there were malformed string tokens we'd consume them and pass them along to extensible directive passes. This was a big no-no because it means extensible directive passes weren't able to rely on tokens being passed to them being well-formed.
- Fixed up existing extensible directive tests that relied on output of string tokens.
#1247
- Added C# 7 test to validate questionable features work end-to-end.
- Had to add several explicit package references to let our VS specific packages work as expected.
#1046
- Made a targeted fix to PageDirective that stops it from crashing Visual Studio when its malformed.
- Added unit test to validate PageDirective didn't throw when attempting to determine if something was a page.
- Added an integration test to validate malformed page tags can make their way through the entire Razor pipeline and don't destroy the rest of the content.
#1247
- Prior to this change we'd try to substring a TagHelper directive with length 1 but our substring call would be for -1 (explosions).
- Added tests to validate that `@tagHelperPrefix`, `@removeTagHelper` and `@addTagHelper` all behave properly when they have malformed quotes.
#1242
- Prior to this TModel would be set to a potentially non-fully qualified name. This would cause errors in default MVC templates.
- Regenerated test files to reflect new TModel.
- Updated unit test to reflect new behavior.
#1222
- Prior to this if you had a `TagHelper` whos output hint was not in the final form of the completions we'd fall through into a schema check which resulted in a completion being added when it shouldn't. Example: `TagHelper` for `my-tr` that has an output hint of `tr` would end up getting added to the completion list under `body` because `my-tr` was not in the schema and would then be treated like the `environment` `TagHelper` (a new element).
- Added a test to validate that `TagHelper`s with output hints are cross referenced vs. existing completions and do not fall through to a schema check.
#1225
- We don't want tooling applying tag helper prefix to what we deem `TagHelper`s. Ultimately we should consume all the necessary data and do that work.
- Added two tests to validate that we're applying tag helper prefix to `TagHelper` element completions for catch-all's and non-catch-alls.
#1224
- Prior to this catch-alls were explicitly ignored not to populate the IntelliSense with an excess amount of `TagHelper`s. To maintain backwards compatible expectations this commit reverts that expectation.
- Scoped an existing test to only test its primary scenario.
- Added a new test to verify that catch-alls accurately apply to all completions (including dynamically added ones).
#1219
The problem is that @inject uses the type name, and @namespace can change
it. Setting an explicit order makes sure that these things happen in a
sensible sequence.
- Added a new `TagHelperCompletionService` which can be queried for information on what completion information should be provided.
- Added tests to validate the completion service's expectations.
- Fixed an issue where `TagHelper`s with output hints that did not exist in a passed in completion would never be highlighted as `TagHelper`'s; even when their primary targeting element was already in the element completion list.
#1181
This change adds support for @namespace, and introduces a set of
changes that are needed to support @namespace in the parser.
@namespace and @class have always been treated as reserved words by Razor,
with the intent that someday they would be allowed as directives.
This changes makes that possible.
You will still get an error about @namespace being a reserved word if you
don't have the directive.
- A `null` parent tag in all of our other API represents "any" parent tag, or in this case "root". Prior to this change we'd expect the caller to do their own verification of the parent and then assume all `TagHelperDescriptor`s are valid; this isn't sufficient because only our code base should have that knowledge.
#1188
- Prior to this change the `TagHelper` parsing would strip the opt-out character (`!`) from tag names that got passed to the TagHelper matching services. At design time this proved to be a problem because they have their own understanding of the HTML document and only pass us full tag names (names that include `!`). This changes the matching conventions to immediately return false if a tag name is seen to contain the `TagHelper` opt-out.
- Added two `DefaultTagHelperFactService` tests to verify that tag names with opt-out prefixes are denied `TagHelperDescriptor`s.
#1186
This change adds support for accepting a namespace name in extensible
directives. This will be needed for the @namespace directive.
Implemented new parsing and codegen for namespaces using nameof().
Also fixed any issue where we were not global::-qualifying object where it
was used in the design time code for tokens.
- Prior to this change default imports would get line pragmas generated for them because thye'd have a source location but no file path (they were a dynamic document).
- Re-generated C# files to reflect new line pragma changes.
#1110
- The lazy addition of namespaces gives the main document lowering phase an opportunity to add source location information which we then add after the main lowering.
- Re-generated csharp to capture addition of using statements that were previously overridden by defaults/imports.
#1174
- We were generating line pragmas for using directives but not line mappings. This resulted in 0 IntelliSense when written within the Razor editor.
- Regenerated test files to reflect new line mappings.
#1162
- At design time we weren't generating line mappings when a user would type `@` or `@(`. This results in no C# IntelliSense being provided to the user because the editor hasn't mapped any of Razor to the C# buffer.
- Modified the `DefaultIRLoweringPhase` to allow for marker symbols, these symbols .
- Re-generated test files to account for 0 length line mappings on empty expression nodes.
#1155
- At design time we weren't generating line mappings when a user would type `@` or `@(`. This results in no C# IntelliSense being provided to the user because the editor hasn't mapped any of Razor to the C# buffer.
- Updated the design time renderer and design time writer to account for empty expressions.
- Modified the `DefaultIRLoweringPhase` to set source locations on empty expression nodes.
- Re-generated test files to account for 0 length line mappings on empty expression nodes.
#1155
- Prior to this if all instances of `TagHelper`s in an assembly had editor browsable never we'd log an error saying that no TagHelpers were found for that assembly. Until we can evaluate a better fix for this issue I've removed the logic that logs those errors and its corresponding tests/resources.
#1145
- Add API to enable the editor to query information on the state of `TagHelper`s within a Razor document.
- Refactored methods from `TagHelperDescriptorProvider` to be in a `TagHelperDescriptorConventions` class so the language service could use them.
- Added `DefaultTagHelperFactService` tests.
#1120
This is a new API for tooling to call to get a RazorTemplateEngine that's
initialized correctly. For now this is hardcoded to use MVC's conventions.
This is also a very temporary design to get us past the next wave of
changes.
We'll eventually want to change this to an ILanguageService, but this will
require some new plumbing in the editor, so let's defer that for another
day.
(cherry picked from commit a73b5f58a8713076433d24668b99705388b6d6b3)
The RazorParserOptions were only configurable via an internal interface
and an extension method on the builder. This isn't suitable for VS because
we need to be able to update the configuration while the editor is open,
without creating a new engine.
- When `RequiredAttributeDescriptor`s are displayed in an editor their display name differs based on their name comparison mode. If their name comparison mode happens to be a prefix match then we need to append three dots to indicate that it's a required prefix for an attribute.
- Added a new descriptor builder test to validate `DisplayName` is created correctly.
#1119
- Normalize paths to be absolute and to also use forward slashes.
- Updated our `EnsureValidPath` method to be `NormalizeAndEnsureValidPath`.
- Added tests to validate new `NormalizeAndEnsureValidPath`.
- Updated existing tests to react to `NormalizeAndEnsureValidPath` correctly.
#1106
This is a code dump from tooling -> Razor
This service will exist to answer questions about syntax trees for the
editor. Right now I'm just moving in the code in the simplest way
possible. Tests + cleanup to follow.
- Removed all design time descriptors and put their API surface into their corresponding descriptor. Part of removing the design time API surface was removing the tracking of `<Remarks>`, it wasn't used so there's on need to track it until we need it.
- Removed the Type requirement from `TagHelperDescriptor`. With this separation we'll be able to have abstract `TagHelper`s that aren't based on a class implementation.
- Removed Prefix from the `TagHelperDescriptor` API surface. It was a legacy requirement based on how the Razor parser was put together. We can work around this now.
- Stripped correlation information from the immediate `TagHelperDescriptor` API surface. Instead this information is now tracked in `TagMatchingRule`s. This change means that you will not have multiple `TagHelperDescriptor`s per `TagHelper`; instead it's all tracked in a single descriptor. A side effect of this change was the transformation of `IsIndexer` => 3 new properties.
- Renamed many descriptor types and property names.
- Added builder APIs to construct TagHelpers since they're inherently immutable in their API surface.
- Added `ITagHelperDescriptorBuilder` to represent `TagHelper`s that are built from an `ITagHelper` implementing class. It re-introduces the `TypeName` association of a `TagHelper`.
- Added `ITagHelperBoundAttributeDescriptorBuilder` to represent that an attribute was associated with a property.
- Added validation methods to the descriptor builders to enable consumers to validate the current state of the builder and add diagnostics as necessary.
- Moved descriptors away from RazorError.
- Updated the various comparers to understand the descriptors new API.
- Added a new `RazorDiagnosticFactory` abstraction to handle `RazorDiagnostic`s and their corresponding errors/ids etc. This new API should allow for easy addition of new `RazorDiagnostic` errors.
- Updated the `DefaultTagHelperDescriptorFactory` to construct `TagHelperDescriptor`s using the new builder APIs and in the new descriptor format (1 descriptor per type).
- Updated `ViewComponentTagHelperDescriptorFactory` to construct `TagHelperDescriptor`s with the builder API.
- With both factory implementations code was duplicated because the ViewComponent work will be moving outside of Razor once we have the proper hooks.
- Updated `TagHelper` binding bits to capture a binding result in order to query which rules appy to a given tag name.
Addressed feedback
- Update tests to react to new `TagHelperDescriptor` API.
- Remove case sensitive comparers and some cleanup
- Added TagHelperDescriptorJsonConverter, RazorDiagnosticJsonConverter and added serialization tests
We still need this for now. Both constructors call the non-obsolete
constructor on the base class.
Will remove this once ServiceHub starts calling the new constructor.
VS has gone RTM so, updating to the RTM versions of those dependencies.
Roslyn does not publish our shim packages on NuGet.org, so updating those
to a non-ancient version for projects that use 2.0.0. The projects that
use 1.3.x are staying put for now.
The code change is dealing with something that was obsoleted.
This will log to the VS activity log any time we fail to discovery
taghelpers due to an exception. There's no real user experience around
this... if someone is having an issue we can ask them to send us the log
or post the relevant portion.
The issue here is that the OOP host doesn't yet have support for
documentation, it will just return null. Fixing this code to look for the
documentation after we get the descriptors back into VS.
I tested this and confirmed that it works with TagHelpers in dlls + xml
file documenation as well as TagHelpers compiled in the project itself.
Deletes CSharpIRToken to use the more general RazorIRToken class.
Rather than using the visitor to visit tokens, now writing a
CSharpExpresionIRNode is an 'atom', and will write its tokens itself.
This IR node will be part of the new token model for IR. It will be used
by all nodes that contain user content. Going forward, tokens will be the
thing that contains text and produces line mappings.
This commit just introduces the class.
- Decided to not expose the resolutions errors in the Razor extension. If we feel that it's good debug information we can add it later.
- Added a `TagHelperResolutionResult` type to Razor.Workspaces so it can be used in the language and remote service.
#1014
We need the visitor to allow control over whether to recurse or not into
something. This change makes the old ParserVisitor class behave much more
like the newer IR Walkers.
We need this for the tokens refactor because IR lowering will not be just
a trivial visitor anymore in the future.
This change fixes a bug where DefaultRazorIRLoweringPhase is too
aggressive in merging HTML spans. You can hit the bug by delimiting two
html spans with a metacode character like:
<foo>@{ <bar/> }</foo>
The lowering phase will combine these HTML nodes, which is invalid as they
don't have contiguous spans.
The change here is to merge spans only when they both have an invalid
location or are contiguous.
Introducing ExtensionIRNode and an implementation of templates based on
the new feature set.
Now TemplateIRNode is-a ExtensionIRNode. It's implemented using just
extensibility and isn't part of the standard razor codegen. I'm adding it
to the RazorEngine so that it's still there by default.
I've also included a pattern for visitors to special case
ExtensionIRNode-derived classes that they know about. This requires a
little bit of boilerplate but makes it easy to traverse just the nodes you
care about while keeping the set of nodes open.
For now the general codegen feature still hasn't had a refactor, but this
opens things up for us to start finishing things like MVC's @inject
directive.
- Added DirectiveRemovalIRPass
- Added IRazorDocumentClassifierPhase, IRazorDirectiveClassifierPhase and
IRazorIROptimizationPhase
- Added all the related passes and default implementations
- Refactored DefaultDirectiveIRPass to do the right thing
- Execute method in IR passes now return void
- Added tests for the new phases
This is a new abstraction that represents the api surface available for
codegen to target. Every kind of document should have an associated
RuntimeTarget or just use the default.
To prevent breakage, our DocumentClassifierBase class will provide a
default API set to implementors (like MVC).
I haven't fundamentally changed how codegen is done yet, I've just hidden
it behind a new abstraction. The RuntimeTarget now is also responsible for
selecting between design time and runtime.
The bulk of the noise here is from splitting a lot of the codegen stuff
into its own files.