diff --git a/NuGetPackageVerifier.json b/NuGetPackageVerifier.json index 14e2c66584..6cbde058da 100644 --- a/NuGetPackageVerifier.json +++ b/NuGetPackageVerifier.json @@ -5,17 +5,7 @@ ], "packages": { "Microsoft.AspNetCore.Razor": { }, - "Microsoft.AspNet.Razor.VSRC1": { - "DOC_MISSING": { - "lib/net451/Microsoft.AspNet.Razor.VSRC1.dll": "Enter justification" - } - }, - "Microsoft.AspNetCore.Razor.Runtime": { }, - "Microsoft.AspNet.Razor.Runtime.VSRC1": { - "DOC_MISSING": { - "lib/net451/Microsoft.AspNet.Razor.Runtime.VSRC1.dll": "Enter justification" - } - } + "Microsoft.AspNetCore.Razor.Runtime": { } } }, "adx-nonshipping": { // Packages written by the ADX team but that don't ship on NuGet.org (thus, no need to scan anything in them) diff --git a/Razor.sln b/Razor.sln index 5084517467..9edc90c924 100644 --- a/Razor.sln +++ b/Razor.sln @@ -1,6 +1,7 @@ + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +VisualStudioVersion = 14.0.24720.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C0D6505-79B3-49D0-B4C3-176F0F1836ED}" EndProject @@ -16,10 +17,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Razor. EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Razor.Test.Sources", "src\Microsoft.AspNetCore.Razor.Test.Sources\Microsoft.AspNetCore.Razor.Test.Sources.xproj", "{E3A2A305-634D-4BA6-95DB-AA06D6C442B0}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Razor.Runtime.VSRC1", "src\Microsoft.AspNet.Razor.Runtime.VSRC1\Microsoft.AspNet.Razor.Runtime.VSRC1.xproj", "{5E8EC8BB-69B9-43D4-A095-7A06F65838E2}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Razor.VSRC1", "src\Microsoft.AspNet.Razor.VSRC1\Microsoft.AspNet.Razor.VSRC1.xproj", "{AB5ABC37-201B-41FF-9FAF-E948B0D33F5A}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -46,14 +43,6 @@ Global {E3A2A305-634D-4BA6-95DB-AA06D6C442B0}.Debug|Any CPU.Build.0 = Debug|Any CPU {E3A2A305-634D-4BA6-95DB-AA06D6C442B0}.Release|Any CPU.ActiveCfg = Release|Any CPU {E3A2A305-634D-4BA6-95DB-AA06D6C442B0}.Release|Any CPU.Build.0 = Release|Any CPU - {5E8EC8BB-69B9-43D4-A095-7A06F65838E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5E8EC8BB-69B9-43D4-A095-7A06F65838E2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5E8EC8BB-69B9-43D4-A095-7A06F65838E2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5E8EC8BB-69B9-43D4-A095-7A06F65838E2}.Release|Any CPU.Build.0 = Release|Any CPU - {AB5ABC37-201B-41FF-9FAF-E948B0D33F5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AB5ABC37-201B-41FF-9FAF-E948B0D33F5A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AB5ABC37-201B-41FF-9FAF-E948B0D33F5A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AB5ABC37-201B-41FF-9FAF-E948B0D33F5A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -64,7 +53,5 @@ Global {D0196096-1B01-4133-AACE-1A10A0F7247C} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} {0535998A-E32C-4D1A-80D1-0B15A513C471} = {92463391-81BE-462B-AC3C-78C6C760741F} {E3A2A305-634D-4BA6-95DB-AA06D6C442B0} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} - {5E8EC8BB-69B9-43D4-A095-7A06F65838E2} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} - {AB5ABC37-201B-41FF-9FAF-E948B0D33F5A} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} EndGlobalSection EndGlobal diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/BufferedHtmlContent.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/BufferedHtmlContent.cs deleted file mode 100644 index 9d098518b8..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/BufferedHtmlContent.cs +++ /dev/null @@ -1,125 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using Microsoft.AspNet.Html.Abstractions; -using Microsoft.Extensions.WebEncoders; - -namespace Microsoft.Extensions.Internal -{ - /// - /// Enumerable object collection which knows how to write itself. - /// - [DebuggerDisplay("{DebuggerToString()}")] - internal class BufferedHtmlContent : IHtmlContentBuilder - { - // This is not List because that would lead to wrapping all strings to IHtmlContent - // which is not space performant. - // internal for testing. - internal List Entries { get; } = new List(); - - /// - /// Appends the to the collection. - /// - /// The string to be appended. - /// A reference to this instance after the Append operation has completed. - public IHtmlContentBuilder Append(string unencoded) - { - Entries.Add(unencoded); - return this; - } - - /// - /// Appends a to the collection. - /// - /// The to be appended. - /// A reference to this instance after the Append operation has completed. - public IHtmlContentBuilder Append(IHtmlContent htmlContent) - { - Entries.Add(htmlContent); - return this; - } - - /// - /// Appends the HTML encoded to the collection. - /// - /// The HTML encoded string to be appended. - /// A reference to this instance after the Append operation has completed. - public IHtmlContentBuilder AppendHtml(string encoded) - { - Entries.Add(new HtmlEncodedString(encoded)); - return this; - } - /// - /// Removes all the entries from the collection. - /// - /// A reference to this instance after the Clear operation has completed. - public IHtmlContentBuilder Clear() - { - Entries.Clear(); - return this; - } - - /// - public void WriteTo(TextWriter writer, IHtmlEncoder encoder) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (encoder == null) - { - throw new ArgumentNullException(nameof(encoder)); - } - - foreach (var entry in Entries) - { - if (entry == null) - { - continue; - } - - var entryAsString = entry as string; - if (entryAsString != null) - { - encoder.HtmlEncode(entryAsString, writer); - } - else - { - // Only string, IHtmlContent values can be added to the buffer. - ((IHtmlContent)entry).WriteTo(writer, encoder); - } - } - } - - private string DebuggerToString() - { - using (var writer = new StringWriter()) - { - WriteTo(writer, HtmlEncoder.Default); - return writer.ToString(); - } - } - - private class HtmlEncodedString : IHtmlContent - { - public static readonly IHtmlContent NewLine = new HtmlEncodedString(Environment.NewLine); - - private readonly string _value; - - public HtmlEncodedString(string value) - { - _value = value; - } - - public void WriteTo(TextWriter writer, IHtmlEncoder encoder) - { - writer.Write(_value); - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/ClosedGenericMatcher.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/ClosedGenericMatcher.cs deleted file mode 100644 index 490196d915..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/ClosedGenericMatcher.cs +++ /dev/null @@ -1,55 +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; -using System.Linq; -using System.Reflection; - -namespace Microsoft.Extensions.Internal -{ - /// - /// Helper related to generic interface definitions and implementing classes. - /// - internal static class ClosedGenericMatcher - { - /// - /// Determine whether is or implements a closed generic - /// created from . - /// - /// The of interest. - /// The open generic to match. Usually an interface. - /// - /// The closed generic created from that - /// is or implements. null if the two s have no such - /// relationship. - /// - /// - /// This method will return if is - /// typeof(KeyValuePair{,}), and is - /// typeof(KeyValuePair{string, object}). - /// - public static Type ExtractGenericInterface(Type queryType, Type interfaceType) - { - if (queryType == null) - { - throw new ArgumentNullException(nameof(queryType)); - } - - if (interfaceType == null) - { - throw new ArgumentNullException(nameof(interfaceType)); - } - - Func matchesInterface = - type => type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == interfaceType; - if (matchesInterface(queryType)) - { - // Checked type matches (i.e. is a closed generic type created from) the open generic type. - return queryType; - } - - // Otherwise check all interfaces the type implements for a match. - return queryType.GetTypeInfo().ImplementedInterfaces.FirstOrDefault(matchesInterface); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/CopyOnWriteDictionary.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/CopyOnWriteDictionary.cs deleted file mode 100644 index 1408059ad9..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/CopyOnWriteDictionary.cs +++ /dev/null @@ -1,155 +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; -using System.Collections; -using System.Collections.Generic; - -namespace Microsoft.Extensions.Internal -{ - internal class CopyOnWriteDictionary : IDictionary - { - private readonly IDictionary _sourceDictionary; - private readonly IEqualityComparer _comparer; - private IDictionary _innerDictionary; - - public CopyOnWriteDictionary( - IDictionary sourceDictionary, - IEqualityComparer comparer) - { - if (sourceDictionary == null) - { - throw new ArgumentNullException(nameof(sourceDictionary)); - } - - if (comparer == null) - { - throw new ArgumentNullException(nameof(comparer)); - } - - _sourceDictionary = sourceDictionary; - _comparer = comparer; - } - - private IDictionary ReadDictionary - { - get - { - return _innerDictionary ?? _sourceDictionary; - } - } - - private IDictionary WriteDictionary - { - get - { - if (_innerDictionary == null) - { - _innerDictionary = new Dictionary(_sourceDictionary, - _comparer); - } - - return _innerDictionary; - } - } - - public virtual ICollection Keys - { - get - { - return ReadDictionary.Keys; - } - } - - public virtual ICollection Values - { - get - { - return ReadDictionary.Values; - } - } - - public virtual int Count - { - get - { - return ReadDictionary.Count; - } - } - - public virtual bool IsReadOnly - { - get - { - return false; - } - } - - public virtual TValue this[TKey key] - { - get - { - return ReadDictionary[key]; - } - set - { - WriteDictionary[key] = value; - } - } - - public virtual bool ContainsKey(TKey key) - { - return ReadDictionary.ContainsKey(key); - } - - public virtual void Add(TKey key, TValue value) - { - WriteDictionary.Add(key, value); - } - - public virtual bool Remove(TKey key) - { - return WriteDictionary.Remove(key); - } - - public virtual bool TryGetValue(TKey key, out TValue value) - { - return ReadDictionary.TryGetValue(key, out value); - } - - public virtual void Add(KeyValuePair item) - { - WriteDictionary.Add(item); - } - - public virtual void Clear() - { - WriteDictionary.Clear(); - } - - public virtual bool Contains(KeyValuePair item) - { - return ReadDictionary.Contains(item); - } - - public virtual void CopyTo(KeyValuePair[] array, int arrayIndex) - { - ReadDictionary.CopyTo(array, arrayIndex); - } - - public bool Remove(KeyValuePair item) - { - return WriteDictionary.Remove(item); - } - - public virtual IEnumerator> GetEnumerator() - { - return ReadDictionary.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/CopyOnWriteDictionaryHolder.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/CopyOnWriteDictionaryHolder.cs deleted file mode 100644 index 7cd935e940..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/CopyOnWriteDictionaryHolder.cs +++ /dev/null @@ -1,166 +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; -using System.Collections.Generic; - -namespace Microsoft.Extensions.Internal -{ - internal struct CopyOnWriteDictionaryHolder - { - private readonly Dictionary _source; - private Dictionary _copy; - - public CopyOnWriteDictionaryHolder(Dictionary source) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - _source = source; - _copy = null; - } - - public CopyOnWriteDictionaryHolder(CopyOnWriteDictionaryHolder source) - { - _source = source._copy ?? source._source; - _copy = null; - } - - public bool HasBeenCopied => _copy != null; - - public Dictionary ReadDictionary - { - get - { - if (_copy != null) - { - return _copy; - } - else if (_source != null) - { - return _source; - } - else - { - // Default-Constructor case - _copy = new Dictionary(); - return _copy; - } - } - } - - public Dictionary WriteDictionary - { - get - { - if (_copy == null && _source == null) - { - // Default-Constructor case - _copy = new Dictionary(); - } - else if (_copy == null) - { - _copy = new Dictionary(_source, _source.Comparer); - } - - return _copy; - } - } - - public Dictionary.KeyCollection Keys - { - get - { - return ReadDictionary.Keys; - } - } - - public Dictionary.ValueCollection Values - { - get - { - return ReadDictionary.Values; - } - } - - public int Count - { - get - { - return ReadDictionary.Count; - } - } - - public bool IsReadOnly - { - get - { - return false; - } - } - - public TValue this[TKey key] - { - get - { - return ReadDictionary[key]; - } - set - { - WriteDictionary[key] = value; - } - } - - public bool ContainsKey(TKey key) - { - return ReadDictionary.ContainsKey(key); - } - - public void Add(TKey key, TValue value) - { - WriteDictionary.Add(key, value); - } - - public bool Remove(TKey key) - { - return WriteDictionary.Remove(key); - } - - public bool TryGetValue(TKey key, out TValue value) - { - return ReadDictionary.TryGetValue(key, out value); - } - - public void Add(KeyValuePair item) - { - ((ICollection>)WriteDictionary).Add(item); - } - - public void Clear() - { - WriteDictionary.Clear(); - } - - public bool Contains(KeyValuePair item) - { - return ((ICollection>)ReadDictionary).Contains(item); - } - - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - ((ICollection>)ReadDictionary).CopyTo(array, arrayIndex); - } - - public bool Remove(KeyValuePair item) - { - return ((ICollection>)WriteDictionary).Remove(item); - } - - public Dictionary.Enumerator GetEnumerator() - { - return ReadDictionary.GetEnumerator(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Microsoft.AspNet.Razor.Runtime.VSRC1.xproj b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Microsoft.AspNet.Razor.Runtime.VSRC1.xproj deleted file mode 100644 index d178f985f4..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Microsoft.AspNet.Razor.Runtime.VSRC1.xproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 5e8ec8bb-69b9-43d4-a095-7a06f65838e2 - ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ - - - 2.0 - - - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Properties/AssemblyInfo.cs deleted file mode 100644 index 866f034f96..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,12 +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.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; - -[assembly: AssemblyMetadata("Serviceable", "True")] -[assembly: NeutralResourcesLanguage("en-us")] -[assembly: AssemblyCompany("Microsoft Corporation.")] -[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] -[assembly: AssemblyProduct("Microsoft ASP.NET Core")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Properties/Resources.Designer.cs deleted file mode 100644 index aebe15cd72..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Properties/Resources.Designer.cs +++ /dev/null @@ -1,478 +0,0 @@ -// -namespace Microsoft.AspNet.Razor.Runtime -{ - using System.Globalization; - using System.Reflection; - using System.Resources; - - internal static class Resources - { - private static readonly ResourceManager _resourceManager - = new ResourceManager("Microsoft.AspNet.Razor.Runtime.VSRC1.Resources", typeof(Resources).GetTypeInfo().Assembly); - - /// - /// Invalid tag helper directive look up text '{0}'. The correct look up text format is: "typeName, assemblyName". - /// - internal static string TagHelperDescriptorResolver_InvalidTagHelperLookupText - { - get { return GetString("TagHelperDescriptorResolver_InvalidTagHelperLookupText"); } - } - - /// - /// Invalid tag helper directive look up text '{0}'. The correct look up text format is: "typeName, assemblyName". - /// - internal static string FormatTagHelperDescriptorResolver_InvalidTagHelperLookupText(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorResolver_InvalidTagHelperLookupText"), p0); - } - - /// - /// Cannot resolve TagHelper containing assembly '{0}'. Error: {1} - /// - internal static string TagHelperTypeResolver_CannotResolveTagHelperAssembly - { - get { return GetString("TagHelperTypeResolver_CannotResolveTagHelperAssembly"); } - } - - /// - /// Cannot resolve TagHelper containing assembly '{0}'. Error: {1} - /// - internal static string FormatTagHelperTypeResolver_CannotResolveTagHelperAssembly(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperTypeResolver_CannotResolveTagHelperAssembly"), p0, p1); - } - - /// - /// Tag helper directive assembly name cannot be null or empty. - /// - internal static string TagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull - { - get { return GetString("TagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull"); } - } - - /// - /// Tag helper directive assembly name cannot be null or empty. - /// - internal static string FormatTagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull() - { - return GetString("TagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull"); - } - - /// - /// Must call '{2}.{1}' before calling '{2}.{0}'. - /// - internal static string ScopeManager_EndCannotBeCalledWithoutACallToBegin - { - get { return GetString("ScopeManager_EndCannotBeCalledWithoutACallToBegin"); } - } - - /// - /// Must call '{2}.{1}' before calling '{2}.{0}'. - /// - internal static string FormatScopeManager_EndCannotBeCalledWithoutACallToBegin(object p0, object p1, object p2) - { - return string.Format(CultureInfo.CurrentCulture, GetString("ScopeManager_EndCannotBeCalledWithoutACallToBegin"), p0, p1, p2); - } - - /// - /// {0} name cannot be null or whitespace. - /// - internal static string HtmlTargetElementAttribute_NameCannotBeNullOrWhitespace - { - get { return GetString("HtmlTargetElementAttribute_NameCannotBeNullOrWhitespace"); } - } - - /// - /// {0} name cannot be null or whitespace. - /// - internal static string FormatHtmlTargetElementAttribute_NameCannotBeNullOrWhitespace(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("HtmlTargetElementAttribute_NameCannotBeNullOrWhitespace"), p0); - } - - /// - /// The value cannot be null or empty. - /// - internal static string ArgumentCannotBeNullOrEmpty - { - get { return GetString("ArgumentCannotBeNullOrEmpty"); } - } - - /// - /// The value cannot be null or empty. - /// - internal static string FormatArgumentCannotBeNullOrEmpty() - { - return GetString("ArgumentCannotBeNullOrEmpty"); - } - - /// - /// Encountered an unexpected error when attempting to resolve tag helper directive '{0}' with value '{1}'. Error: {2} - /// - internal static string TagHelperDescriptorResolver_EncounteredUnexpectedError - { - get { return GetString("TagHelperDescriptorResolver_EncounteredUnexpectedError"); } - } - - /// - /// Encountered an unexpected error when attempting to resolve tag helper directive '{0}' with value '{1}'. Error: {2} - /// - internal static string FormatTagHelperDescriptorResolver_EncounteredUnexpectedError(object p0, object p1, object p2) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorResolver_EncounteredUnexpectedError"), p0, p1, p2); - } - - /// - /// Tag helpers cannot target {0} name '{1}' because it contains a '{2}' character. - /// - internal static string HtmlTargetElementAttribute_InvalidName - { - get { return GetString("HtmlTargetElementAttribute_InvalidName"); } - } - - /// - /// Tag helpers cannot target {0} name '{1}' because it contains a '{2}' character. - /// - internal static string FormatHtmlTargetElementAttribute_InvalidName(object p0, object p1, object p2) - { - return string.Format(CultureInfo.CurrentCulture, GetString("HtmlTargetElementAttribute_InvalidName"), p0, p1, p2); - } - - /// - /// Invalid tag helper directive '{0}'. Cannot have multiple '{0}' directives on a page. - /// - internal static string TagHelperDescriptorResolver_InvalidTagHelperDirective - { - get { return GetString("TagHelperDescriptorResolver_InvalidTagHelperDirective"); } - } - - /// - /// Invalid tag helper directive '{0}'. Cannot have multiple '{0}' directives on a page. - /// - internal static string FormatTagHelperDescriptorResolver_InvalidTagHelperDirective(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorResolver_InvalidTagHelperDirective"), p0); - } - - /// - /// Invalid tag helper directive '{0}' value. '{1}' is not allowed in prefix '{2}'. - /// - internal static string TagHelperDescriptorResolver_InvalidTagHelperPrefixValue - { - get { return GetString("TagHelperDescriptorResolver_InvalidTagHelperPrefixValue"); } - } - - /// - /// Invalid tag helper directive '{0}' value. '{1}' is not allowed in prefix '{2}'. - /// - internal static string FormatTagHelperDescriptorResolver_InvalidTagHelperPrefixValue(object p0, object p1, object p2) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorResolver_InvalidTagHelperPrefixValue"), p0, p1, p2); - } - - /// - /// Attribute - /// - internal static string TagHelperDescriptorFactory_Attribute - { - get { return GetString("TagHelperDescriptorFactory_Attribute"); } - } - - /// - /// Attribute - /// - internal static string FormatTagHelperDescriptorFactory_Attribute() - { - return GetString("TagHelperDescriptorFactory_Attribute"); - } - - /// - /// name - /// - internal static string TagHelperDescriptorFactory_Name - { - get { return GetString("TagHelperDescriptorFactory_Name"); } - } - - /// - /// name - /// - internal static string FormatTagHelperDescriptorFactory_Name() - { - return GetString("TagHelperDescriptorFactory_Name"); - } - - /// - /// prefix - /// - internal static string TagHelperDescriptorFactory_Prefix - { - get { return GetString("TagHelperDescriptorFactory_Prefix"); } - } - - /// - /// prefix - /// - internal static string FormatTagHelperDescriptorFactory_Prefix() - { - return GetString("TagHelperDescriptorFactory_Prefix"); - } - - /// - /// Tag - /// - internal static string TagHelperDescriptorFactory_Tag - { - get { return GetString("TagHelperDescriptorFactory_Tag"); } - } - - /// - /// Tag - /// - internal static string FormatTagHelperDescriptorFactory_Tag() - { - return GetString("TagHelperDescriptorFactory_Tag"); - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. An '{2}' must not be associated with a property with no public setter unless its type implements '{3}'. - /// - internal static string TagHelperDescriptorFactory_InvalidAttributeNameAttribute - { - get { return GetString("TagHelperDescriptorFactory_InvalidAttributeNameAttribute"); } - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. An '{2}' must not be associated with a property with no public setter unless its type implements '{3}'. - /// - internal static string FormatTagHelperDescriptorFactory_InvalidAttributeNameAttribute(object p0, object p1, object p2, object p3) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidAttributeNameAttribute"), p0, p1, p2, p3); - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with {2} '{3}' because {2} contains a '{4}' character. - /// - internal static string TagHelperDescriptorFactory_InvalidAttributeNameOrPrefixCharacter - { - get { return GetString("TagHelperDescriptorFactory_InvalidAttributeNameOrPrefixCharacter"); } - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with {2} '{3}' because {2} contains a '{4}' character. - /// - internal static string FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixCharacter(object p0, object p1, object p2, object p3, object p4) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidAttributeNameOrPrefixCharacter"), p0, p1, p2, p3, p4); - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with {2} '{3}' because {2} starts with '{4}'. - /// - internal static string TagHelperDescriptorFactory_InvalidAttributeNameOrPrefixStart - { - get { return GetString("TagHelperDescriptorFactory_InvalidAttributeNameOrPrefixStart"); } - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with {2} '{3}' because {2} starts with '{4}'. - /// - internal static string FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixStart(object p0, object p1, object p2, object p3, object p4) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidAttributeNameOrPrefixStart"), p0, p1, p2, p3, p4); - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with a whitespace {2}. - /// - internal static string TagHelperDescriptorFactory_InvalidAttributeNameOrPrefixWhitespace - { - get { return GetString("TagHelperDescriptorFactory_InvalidAttributeNameOrPrefixWhitespace"); } - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with a whitespace {2}. - /// - internal static string FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixWhitespace(object p0, object p1, object p2) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidAttributeNameOrPrefixWhitespace"), p0, p1, p2); - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with a null or empty name. - /// - internal static string TagHelperDescriptorFactory_InvalidAttributeNameNullOrEmpty - { - get { return GetString("TagHelperDescriptorFactory_InvalidAttributeNameNullOrEmpty"); } - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with a null or empty name. - /// - internal static string FormatTagHelperDescriptorFactory_InvalidAttributeNameNullOrEmpty(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidAttributeNameNullOrEmpty"), p0, p1); - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. '{2}.{3}' must be null or empty if property has no public setter. - /// - internal static string TagHelperDescriptorFactory_InvalidAttributeNameNotNullOrEmpty - { - get { return GetString("TagHelperDescriptorFactory_InvalidAttributeNameNotNullOrEmpty"); } - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. '{2}.{3}' must be null or empty if property has no public setter. - /// - internal static string FormatTagHelperDescriptorFactory_InvalidAttributeNameNotNullOrEmpty(object p0, object p1, object p2, object p3) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidAttributeNameNotNullOrEmpty"), p0, p1, p2, p3); - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. '{2}.{3}' must not be null if property has no public setter and its type implements '{4}'. - /// - internal static string TagHelperDescriptorFactory_InvalidAttributePrefixNull - { - get { return GetString("TagHelperDescriptorFactory_InvalidAttributePrefixNull"); } - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. '{2}.{3}' must not be null if property has no public setter and its type implements '{4}'. - /// - internal static string FormatTagHelperDescriptorFactory_InvalidAttributePrefixNull(object p0, object p1, object p2, object p3, object p4) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidAttributePrefixNull"), p0, p1, p2, p3, p4); - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. '{2}.{3}' must be null unless property type implements '{4}'. - /// - internal static string TagHelperDescriptorFactory_InvalidAttributePrefixNotNull - { - get { return GetString("TagHelperDescriptorFactory_InvalidAttributePrefixNotNull"); } - } - - /// - /// Invalid tag helper bound property '{0}.{1}'. '{2}.{3}' must be null unless property type implements '{4}'. - /// - internal static string FormatTagHelperDescriptorFactory_InvalidAttributePrefixNotNull(object p0, object p1, object p2, object p3, object p4) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidAttributePrefixNotNull"), p0, p1, p2, p3, p4); - } - - /// - /// Cannot add a '{0}' with a null '{1}'. - /// - internal static string TagHelperAttributeList_CannotAddWithNullName - { - get { return GetString("TagHelperAttributeList_CannotAddWithNullName"); } - } - - /// - /// Cannot add a '{0}' with a null '{1}'. - /// - internal static string FormatTagHelperAttributeList_CannotAddWithNullName(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperAttributeList_CannotAddWithNullName"), p0, p1); - } - - /// - /// Cannot add a {0} with inconsistent names. The {1} property '{2}' must match the location '{3}'. - /// - internal static string TagHelperAttributeList_CannotAddAttribute - { - get { return GetString("TagHelperAttributeList_CannotAddAttribute"); } - } - - /// - /// Cannot add a {0} with inconsistent names. The {1} property '{2}' must match the location '{3}'. - /// - internal static string FormatTagHelperAttributeList_CannotAddAttribute(object p0, object p1, object p2, object p3) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperAttributeList_CannotAddAttribute"), p0, p1, p2, p3); - } - - /// - /// Invalid '{0}' tag name '{1}' for tag helper '{2}'. Tag helpers cannot restrict child elements that contain a '{3}' character. - /// - internal static string TagHelperDescriptorFactory_InvalidRestrictChildrenAttributeName - { - get { return GetString("TagHelperDescriptorFactory_InvalidRestrictChildrenAttributeName"); } - } - - /// - /// Invalid '{0}' tag name '{1}' for tag helper '{2}'. Tag helpers cannot restrict child elements that contain a '{3}' character. - /// - internal static string FormatTagHelperDescriptorFactory_InvalidRestrictChildrenAttributeName(object p0, object p1, object p2, object p3) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidRestrictChildrenAttributeName"), p0, p1, p2, p3); - } - - /// - /// Invalid '{0}' tag name for tag helper '{1}'. Name cannot be null or whitespace. - /// - internal static string TagHelperDescriptorFactory_InvalidRestrictChildrenAttributeNameNullWhitespace - { - get { return GetString("TagHelperDescriptorFactory_InvalidRestrictChildrenAttributeNameNullWhitespace"); } - } - - /// - /// Invalid '{0}' tag name for tag helper '{1}'. Name cannot be null or whitespace. - /// - internal static string FormatTagHelperDescriptorFactory_InvalidRestrictChildrenAttributeNameNullWhitespace(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidRestrictChildrenAttributeNameNullWhitespace"), p0, p1); - } - - /// - /// Parent Tag - /// - internal static string TagHelperDescriptorFactory_ParentTag - { - get { return GetString("TagHelperDescriptorFactory_ParentTag"); } - } - - /// - /// Parent Tag - /// - internal static string FormatTagHelperDescriptorFactory_ParentTag() - { - return GetString("TagHelperDescriptorFactory_ParentTag"); - } - - /// - /// Argument must be an instance of '{0}'. - /// - internal static string ArgumentMustBeAnInstanceOf - { - get { return GetString("ArgumentMustBeAnInstanceOf"); } - } - - /// - /// Argument must be an instance of '{0}'. - /// - internal static string FormatArgumentMustBeAnInstanceOf(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("ArgumentMustBeAnInstanceOf"), p0); - } - - private static string GetString(string name, params string[] formatterNames) - { - var value = _resourceManager.GetString(name); - - System.Diagnostics.Debug.Assert(value != null); - - if (formatterNames != null) - { - for (var i = 0; i < formatterNames.Length; i++) - { - value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); - } - } - - return value; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Resources.resx b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Resources.resx deleted file mode 100644 index cfc6719220..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Resources.resx +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Invalid tag helper directive look up text '{0}'. The correct look up text format is: "typeName, assemblyName". - - - Cannot resolve TagHelper containing assembly '{0}'. Error: {1} - - - Tag helper directive assembly name cannot be null or empty. - - - Must call '{2}.{1}' before calling '{2}.{0}'. - - - {0} name cannot be null or whitespace. - - - The value cannot be null or empty. - - - Encountered an unexpected error when attempting to resolve tag helper directive '{0}' with value '{1}'. Error: {2} - - - Tag helpers cannot target {0} name '{1}' because it contains a '{2}' character. - - - Invalid tag helper directive '{0}'. Cannot have multiple '{0}' directives on a page. - - - Invalid tag helper directive '{0}' value. '{1}' is not allowed in prefix '{2}'. - - - Attribute - - - name - - - prefix - - - Tag - - - Invalid tag helper bound property '{0}.{1}'. An '{2}' must not be associated with a property with no public setter unless its type implements '{3}'. - - - Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with {2} '{3}' because {2} contains a '{4}' character. - - - Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with {2} '{3}' because {2} starts with '{4}'. - - - Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with a whitespace {2}. - - - Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes with a null or empty name. - - - Invalid tag helper bound property '{0}.{1}'. '{2}.{3}' must be null or empty if property has no public setter. - - - Invalid tag helper bound property '{0}.{1}'. '{2}.{3}' must not be null if property has no public setter and its type implements '{4}'. - - - Invalid tag helper bound property '{0}.{1}'. '{2}.{3}' must be null unless property type implements '{4}'. - - - Cannot add a '{0}' with a null '{1}'. - - - Cannot add a {0} with inconsistent names. The {1} property '{2}' must match the location '{3}'. - - - Invalid '{0}' tag name '{1}' for tag helper '{2}'. Tag helpers cannot restrict child elements that contain a '{3}' character. - - - Invalid '{0}' tag name for tag helper '{1}'. Name cannot be null or whitespace. - - - Parent Tag - - - Argument must be an instance of '{0}'. - - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/Constants.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/Constants.cs deleted file mode 100644 index 34710fe909..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/Constants.cs +++ /dev/null @@ -1,12 +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.AspNet.Razor.Runtime.TagHelpers -{ - internal static class Constants - { - public static readonly TimeSpan RegexMatchTimeout = TimeSpan.FromSeconds(10); - } -} diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/IMemberInfo.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/IMemberInfo.cs deleted file mode 100644 index 6d569b0df1..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/IMemberInfo.cs +++ /dev/null @@ -1,30 +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; -using System.Collections.Generic; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// Metadata common to types and properties. - /// - public interface IMemberInfo - { - /// - /// Gets the name. - /// - string Name { get; } - - /// - /// Retrieves a collection of custom s of type applied - /// to this instance of . - /// - /// The type of to search for. - /// A sequence of custom s of type - /// . - /// Result not include inherited s. - IEnumerable GetCustomAttributes() - where TAttribute : Attribute; - } -} diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/IPropertyInfo.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/IPropertyInfo.cs deleted file mode 100644 index beb0840b57..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/IPropertyInfo.cs +++ /dev/null @@ -1,26 +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. - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// Contains property metadata. - /// - public interface IPropertyInfo : IMemberInfo - { - /// - /// Gets a value indicating whether this property has a public getter. - /// - bool HasPublicGetter { get; } - - /// - /// Gets a value indicating whether this property has a public setter. - /// - bool HasPublicSetter { get; } - - /// - /// Gets the of the property. - /// - ITypeInfo PropertyType { get; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/ITypeInfo.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/ITypeInfo.cs deleted file mode 100644 index 00b670925f..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/ITypeInfo.cs +++ /dev/null @@ -1,69 +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; -using System.Collections.Generic; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// Contains type metadata. - /// - public interface ITypeInfo : IMemberInfo, IEquatable - { - /// - /// Fully qualified name of the type. - /// - /// - /// On CoreCLR, some BCL types get type forwarded to the full desktop framework implementations at - /// runtime. For e.g. we compile against System.String in System.Runtime which is type forwarded to - /// mscorlib at runtime. Consequently for generic types where the includes the assembly - /// qualified name of generic parameters, FullNames would not match. - /// Use to compare s instead. - /// - string FullName { get; } - - /// - /// Gets s for all properties of the current type excluding indexers. - /// - /// - /// Indexers in this context refer to the CLR notion of an indexer (this [string name] - /// and does not overlap with the semantics of - /// . - /// - IEnumerable Properties { get; } - - /// - /// Gets a value indicating whether the type is public. - /// - bool IsPublic { get; } - - /// - /// Gets a value indicating whether the type is abstract or an interface. - /// - bool IsAbstract { get; } - - /// - /// Gets a value indicating whether the type is generic. - /// - bool IsGenericType { get; } - - /// - /// Gets a value indicating whether the type implements the interface. - /// - bool ImplementsInterface(ITypeInfo interfaceTypeInfo); - - /// - /// Gets the for the TKey and TValue parameters of - /// . - /// - /// - /// The of TKey and TValue - /// parameters if the type implements , otherwise null. - /// - /// - /// For open generic types, for generic type parameters is null. - /// - ITypeInfo[] GetGenericDictionaryParameters(); - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/RuntimePropertyInfo.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/RuntimePropertyInfo.cs deleted file mode 100644 index 03c4d51751..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/RuntimePropertyInfo.cs +++ /dev/null @@ -1,54 +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; -using System.Collections.Generic; -using System.Reflection; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// adapter for instances. - /// - public class RuntimePropertyInfo : IPropertyInfo - { - /// - /// Initializes a new instance of . - /// - /// The instance to adapt. - public RuntimePropertyInfo(PropertyInfo propertyInfo) - { - if (propertyInfo == null) - { - throw new ArgumentNullException(nameof(propertyInfo)); - } - - Property = propertyInfo; - } - - /// - /// The instance. - /// - public PropertyInfo Property { get; } - - /// - public bool HasPublicGetter => Property.GetMethod != null && Property.GetMethod.IsPublic; - - /// - public bool HasPublicSetter => Property.SetMethod != null && Property.SetMethod.IsPublic; - - /// - public string Name => Property.Name; - - /// - public ITypeInfo PropertyType => new RuntimeTypeInfo(Property.PropertyType.GetTypeInfo()); - - /// - public IEnumerable GetCustomAttributes() where TAttribute : Attribute - => Property.GetCustomAttributes(inherit: false); - - /// - public override string ToString() => - Property.ToString(); - } -} diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/RuntimeTypeInfo.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/RuntimeTypeInfo.cs deleted file mode 100644 index eed802bf01..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/RuntimeTypeInfo.cs +++ /dev/null @@ -1,179 +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; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text.RegularExpressions; -using Microsoft.AspNet.Razor.TagHelpers; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// adapter for instances. - /// - public class RuntimeTypeInfo : ITypeInfo - { - private static readonly Regex _fullNameSanitizer = new Regex( - @", [A-Za-z\.]+, Version=\d+\.\d+\.\d+\.\d+, Culture=neutral, PublicKeyToken=\w+", - RegexOptions.ExplicitCapture, - Constants.RegexMatchTimeout); - - private static readonly TypeInfo TagHelperTypeInfo = typeof(ITagHelper).GetTypeInfo(); - private IEnumerable _properties; - private string _sanitizedFullName; - - /// - /// Initializes a new instance of - /// - /// The instance to adapt. - public RuntimeTypeInfo(TypeInfo typeInfo) - { - if (typeInfo == null) - { - throw new ArgumentNullException(nameof(typeInfo)); - } - - TypeInfo = typeInfo; - } - - /// - /// The instance. - /// - public TypeInfo TypeInfo { get; } - - /// - public string Name => TypeInfo.Name; - - /// - public string FullName => TypeInfo.FullName; - - /// - public bool IsAbstract => TypeInfo.IsAbstract; - - /// - public bool IsGenericType => TypeInfo.IsGenericType; - - /// - public bool IsPublic => TypeInfo.IsPublic; - - /// - public IEnumerable Properties - { - get - { - if (_properties == null) - { - _properties = TypeInfo - .AsType() - .GetRuntimeProperties() - .Where(property => property.GetIndexParameters().Length == 0) - .Select(property => new RuntimePropertyInfo(property)); - } - - return _properties; - } - } - - /// - public bool ImplementsInterface(ITypeInfo interfaceTypeInfo) - { - if (interfaceTypeInfo == null) - { - throw new ArgumentNullException(nameof(interfaceTypeInfo)); - } - - var runtimeTypeInfo = interfaceTypeInfo as RuntimeTypeInfo; - if (runtimeTypeInfo == null) - { - throw new ArgumentException( - Resources.FormatArgumentMustBeAnInstanceOf(typeof(RuntimeTypeInfo).FullName), - nameof(interfaceTypeInfo)); - } - - return runtimeTypeInfo.TypeInfo.IsInterface && runtimeTypeInfo.TypeInfo.IsAssignableFrom(TypeInfo); - } - - private string SanitizedFullName - { - get - { - if (_sanitizedFullName == null) - { - _sanitizedFullName = SanitizeFullName(FullName); - } - - return _sanitizedFullName; - } - } - - /// - public IEnumerable GetCustomAttributes() where TAttribute : Attribute => - TypeInfo.GetCustomAttributes(inherit: false); - - /// - public ITypeInfo[] GetGenericDictionaryParameters() - { - return ClosedGenericMatcher.ExtractGenericInterface( - TypeInfo.AsType(), - typeof(IDictionary<,>)) - ?.GenericTypeArguments - .Select(type => type.IsGenericParameter ? null : new RuntimeTypeInfo(type.GetTypeInfo())) - .ToArray(); - } - - /// - public override string ToString() => TypeInfo.ToString(); - - /// - public override bool Equals(object obj) - { - return Equals(obj as ITypeInfo); - } - - /// - public bool Equals(ITypeInfo other) - { - if (other == null) - { - return false; - } - - var otherRuntimeType = other as RuntimeTypeInfo; - if (otherRuntimeType != null) - { - return otherRuntimeType.TypeInfo == TypeInfo; - } - - return string.Equals( - SanitizedFullName, - SanitizeFullName(other.FullName), - StringComparison.Ordinal); - } - - /// - public override int GetHashCode() => SanitizedFullName.GetHashCode(); - - /// - /// Removes assembly qualification from generic type parameters for the specified . - /// - /// Full name. - /// Full name without fully qualified generic parameters. - /// - /// typeof().FullName is - /// List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089] - /// Sanitize(typeof(.FullName returns - /// List`1[[System.String] - /// - public static string SanitizeFullName(string fullName) - { - // In CoreCLR, some types (such as System.String) are type forwarded from System.Runtime - // to mscorlib at runtime. Type names of generic type parameters includes the assembly qualified name; - // consequently the type name generated at precompilation differs from the one at runtime. We'll - // avoid dealing with these inconsistencies by removing assembly information from TypeInfo.FullName. - return _fullNameSanitizer.Replace(fullName, string.Empty); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperDescriptorFactory.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperDescriptorFactory.cs deleted file mode 100644 index def04994f4..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperDescriptorFactory.cs +++ /dev/null @@ -1,753 +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; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Reflection; -using System.Text.RegularExpressions; -using Microsoft.AspNet.Razor.Compilation.TagHelpers; -using Microsoft.AspNet.Razor.TagHelpers; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// Factory for s from s. - /// - public static class TagHelperDescriptorFactory - { - private const string DataDashPrefix = "data-"; - private const string TagHelperNameEnding = "TagHelper"; - private const string HtmlCaseRegexReplacement = "-$1$2"; - - // This matches the following AFTER the start of the input string (MATCH). - // Any letter/number followed by an uppercase letter then lowercase letter: 1(Aa), a(Aa), A(Aa) - // Any lowercase letter followed by an uppercase letter: a(A) - // Each match is then prefixed by a "-" via the ToHtmlCase method. - private static readonly Regex HtmlCaseRegex = - new Regex( - "(? InvalidNonWhitespaceNameCharacters { get; } = new HashSet( - new[] { '@', '!', '<', '/', '?', '[', '>', ']', '=', '"', '\'', '*' }); - - /// - /// Creates a from the given . - /// - /// The assembly name that contains . - /// The to create a from. - /// - /// Indicates if the returned s should include - /// design time specific information. - /// The used to collect s encountered - /// when creating s for the given . - /// - /// A collection of s that describe the given . - /// - public static IEnumerable CreateDescriptors( - string assemblyName, - ITypeInfo typeInfo, - bool designTime, - ErrorSink errorSink) - { - if (typeInfo == null) - { - throw new ArgumentNullException(nameof(typeInfo)); - } - - if (errorSink == null) - { - throw new ArgumentNullException(nameof(errorSink)); - } - - if (ShouldSkipDescriptorCreation(designTime, typeInfo)) - { - return Enumerable.Empty(); - } - - var attributeDescriptors = GetAttributeDescriptors(typeInfo, designTime, errorSink); - var targetElementAttributes = GetValidHtmlTargetElementAttributes(typeInfo, errorSink); - var allowedChildren = GetAllowedChildren(typeInfo, errorSink); - - var tagHelperDescriptors = - BuildTagHelperDescriptors( - typeInfo, - assemblyName, - attributeDescriptors, - targetElementAttributes, - allowedChildren, - designTime); - - return tagHelperDescriptors.Distinct(TagHelperDescriptorComparer.Default); - } - - private static IEnumerable GetValidHtmlTargetElementAttributes( - ITypeInfo typeInfo, - ErrorSink errorSink) - { - var targetElementAttributes = typeInfo.GetCustomAttributes(); - - return targetElementAttributes.Where( - attribute => ValidHtmlTargetElementAttributeNames(attribute, errorSink)); - } - - private static IEnumerable BuildTagHelperDescriptors( - ITypeInfo typeInfo, - string assemblyName, - IEnumerable attributeDescriptors, - IEnumerable targetElementAttributes, - IEnumerable allowedChildren, - bool designTime) - { - TagHelperDesignTimeDescriptor typeDesignTimeDescriptor = null; - -#if !DOTNET5_4 - if (designTime) - { - var runtimeTypeInfo = typeInfo as RuntimeTypeInfo; - if (runtimeTypeInfo != null) - { - typeDesignTimeDescriptor = - TagHelperDesignTimeDescriptorFactory.CreateDescriptor(runtimeTypeInfo.TypeInfo.AsType()); - } - } -#endif - - var typeName = typeInfo.FullName; - - // If there isn't an attribute specifying the tag name derive it from the name - if (!targetElementAttributes.Any()) - { - var name = typeInfo.Name; - - if (name.EndsWith(TagHelperNameEnding, StringComparison.OrdinalIgnoreCase)) - { - name = name.Substring(0, name.Length - TagHelperNameEnding.Length); - } - - return new[] - { - BuildTagHelperDescriptor( - ToHtmlCase(name), - typeName, - assemblyName, - attributeDescriptors, - requiredAttributes: Enumerable.Empty(), - allowedChildren: allowedChildren, - tagStructure: default(TagStructure), - parentTag: null, - designTimeDescriptor: typeDesignTimeDescriptor) - }; - } - - return targetElementAttributes.Select( - attribute => - BuildTagHelperDescriptor( - typeName, - assemblyName, - attributeDescriptors, - attribute, - allowedChildren, - typeDesignTimeDescriptor)); - } - - private static IEnumerable GetAllowedChildren(ITypeInfo typeInfo, ErrorSink errorSink) - { - var restrictChildrenAttribute = typeInfo - .GetCustomAttributes() - .FirstOrDefault(); - if (restrictChildrenAttribute == null) - { - return null; - } - - var allowedChildren = restrictChildrenAttribute.ChildTags; - var validAllowedChildren = GetValidAllowedChildren(allowedChildren, typeInfo.FullName, errorSink); - - if (validAllowedChildren.Any()) - { - return validAllowedChildren; - } - else - { - // All allowed children were invalid, return null to indicate that any child is acceptable. - return null; - } - } - - // Internal for unit testing - internal static IEnumerable GetValidAllowedChildren( - IEnumerable allowedChildren, - string tagHelperName, - ErrorSink errorSink) - { - var validAllowedChildren = new List(); - - foreach (var name in allowedChildren) - { - var valid = TryValidateName( - name, - whitespaceError: - Resources.FormatTagHelperDescriptorFactory_InvalidRestrictChildrenAttributeNameNullWhitespace( - nameof(RestrictChildrenAttribute), - tagHelperName), - characterErrorBuilder: (invalidCharacter) => - Resources.FormatTagHelperDescriptorFactory_InvalidRestrictChildrenAttributeName( - nameof(RestrictChildrenAttribute), - name, - tagHelperName, - invalidCharacter), - errorSink: errorSink); - - if (valid) - { - validAllowedChildren.Add(name); - } - } - - return validAllowedChildren; - } - - private static TagHelperDescriptor BuildTagHelperDescriptor( - string typeName, - string assemblyName, - IEnumerable attributeDescriptors, - HtmlTargetElementAttribute targetElementAttribute, - IEnumerable allowedChildren, - TagHelperDesignTimeDescriptor designTimeDescriptor) - { - var requiredAttributes = GetCommaSeparatedValues(targetElementAttribute.Attributes); - - return BuildTagHelperDescriptor( - targetElementAttribute.Tag, - typeName, - assemblyName, - attributeDescriptors, - requiredAttributes, - allowedChildren, - targetElementAttribute.ParentTag, - targetElementAttribute.TagStructure, - designTimeDescriptor); - } - - private static TagHelperDescriptor BuildTagHelperDescriptor( - string tagName, - string typeName, - string assemblyName, - IEnumerable attributeDescriptors, - IEnumerable requiredAttributes, - IEnumerable allowedChildren, - string parentTag, - TagStructure tagStructure, - TagHelperDesignTimeDescriptor designTimeDescriptor) - { - return new TagHelperDescriptor - { - TagName = tagName, - TypeName = typeName, - AssemblyName = assemblyName, - Attributes = attributeDescriptors, - RequiredAttributes = requiredAttributes, - AllowedChildren = allowedChildren, - RequiredParent = parentTag, - TagStructure = tagStructure, - DesignTimeDescriptor = designTimeDescriptor - }; - } - - /// - /// Internal for testing. - /// - internal static IEnumerable GetCommaSeparatedValues(string text) - { - // We don't want to remove empty entries, need to notify users of invalid values. - return text?.Split(',').Select(tagName => tagName.Trim()) ?? Enumerable.Empty(); - } - - /// - /// Internal for testing. - /// - internal static bool ValidHtmlTargetElementAttributeNames( - HtmlTargetElementAttribute attribute, - ErrorSink errorSink) - { - var validTagName = ValidateName(attribute.Tag, targetingAttributes: false, errorSink: errorSink); - var validAttributeNames = true; - var attributeNames = GetCommaSeparatedValues(attribute.Attributes); - - foreach (var attributeName in attributeNames) - { - if (!ValidateName(attributeName, targetingAttributes: true, errorSink: errorSink)) - { - validAttributeNames = false; - } - } - - var validParentTagName = ValidateParentTagName(attribute.ParentTag, errorSink); - - return validTagName && validAttributeNames && validParentTagName; - } - - /// - /// Internal for unit testing. - /// - internal static bool ValidateParentTagName(string parentTag, ErrorSink errorSink) - { - return parentTag == null || - TryValidateName( - parentTag, - Resources.FormatHtmlTargetElementAttribute_NameCannotBeNullOrWhitespace( - Resources.TagHelperDescriptorFactory_ParentTag), - characterErrorBuilder: (invalidCharacter) => - Resources.FormatHtmlTargetElementAttribute_InvalidName( - Resources.TagHelperDescriptorFactory_ParentTag.ToLower(), - parentTag, - invalidCharacter), - errorSink: errorSink); - } - - private static bool ValidateName( - string name, - bool targetingAttributes, - ErrorSink errorSink) - { - if (!targetingAttributes && - string.Equals( - name, - TagHelperDescriptorProvider.ElementCatchAllTarget, - StringComparison.OrdinalIgnoreCase)) - { - // '*' as the entire name is OK in the HtmlTargetElement catch-all case. - return true; - } - else if (targetingAttributes && - name.EndsWith( - TagHelperDescriptorProvider.RequiredAttributeWildcardSuffix, - StringComparison.OrdinalIgnoreCase)) - { - // A single '*' at the end of a required attribute is valid; everywhere else is invalid. Strip it from - // the end so we can validate the rest of the name. - name = name.Substring(0, name.Length - 1); - } - - var targetName = targetingAttributes ? - Resources.TagHelperDescriptorFactory_Attribute : - Resources.TagHelperDescriptorFactory_Tag; - - var validName = TryValidateName( - name, - whitespaceError: Resources.FormatHtmlTargetElementAttribute_NameCannotBeNullOrWhitespace(targetName), - characterErrorBuilder: (invalidCharacter) => - Resources.FormatHtmlTargetElementAttribute_InvalidName( - targetName.ToLower(), - name, - invalidCharacter), - errorSink: errorSink); - - return validName; - } - - private static bool TryValidateName( - string name, - string whitespaceError, - Func characterErrorBuilder, - ErrorSink errorSink) - { - var validName = true; - - if (string.IsNullOrWhiteSpace(name)) - { - errorSink.OnError(SourceLocation.Zero, whitespaceError, length: 0); - - validName = false; - } - else - { - foreach (var character in name) - { - if (char.IsWhiteSpace(character) || - InvalidNonWhitespaceNameCharacters.Contains(character)) - { - var error = characterErrorBuilder(character); - errorSink.OnError(SourceLocation.Zero, error, length: 0); - - validName = false; - } - } - } - - return validName; - } - - private static IEnumerable GetAttributeDescriptors( - ITypeInfo type, - bool designTime, - ErrorSink errorSink) - { - var attributeDescriptors = new List(); - - // Keep indexer descriptors separate to avoid sorting the combined list later. - var indexerDescriptors = new List(); - - var accessibleProperties = type.Properties.Where(IsAccessibleProperty); - foreach (var property in accessibleProperties) - { - if (ShouldSkipDescriptorCreation(designTime, property)) - { - continue; - } - - var attributeNameAttribute = property - .GetCustomAttributes() - .FirstOrDefault(); - var hasExplicitName = - attributeNameAttribute != null && !string.IsNullOrEmpty(attributeNameAttribute.Name); - var attributeName = hasExplicitName ? attributeNameAttribute.Name : ToHtmlCase(property.Name); - - TagHelperAttributeDescriptor mainDescriptor = null; - if (property.HasPublicSetter) - { - mainDescriptor = ToAttributeDescriptor(property, attributeName, designTime); - if (!ValidateTagHelperAttributeDescriptor(mainDescriptor, type, errorSink)) - { - // HtmlAttributeNameAttribute.Name is invalid. Ignore this property completely. - continue; - } - } - else if (hasExplicitName) - { - // Specified HtmlAttributeNameAttribute.Name though property has no public setter. - errorSink.OnError( - SourceLocation.Zero, - Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameNotNullOrEmpty( - type.FullName, - property.Name, - typeof(HtmlAttributeNameAttribute).FullName, - nameof(HtmlAttributeNameAttribute.Name)), - length: 0); - continue; - } - - bool isInvalid; - var indexerDescriptor = ToIndexerAttributeDescriptor( - property, - attributeNameAttribute, - parentType: type, - errorSink: errorSink, - defaultPrefix: attributeName + "-", - designTime: designTime, - isInvalid: out isInvalid); - if (indexerDescriptor != null && - !ValidateTagHelperAttributeDescriptor(indexerDescriptor, type, errorSink)) - { - isInvalid = true; - } - - if (isInvalid) - { - // The property type or HtmlAttributeNameAttribute.DictionaryAttributePrefix (or perhaps the - // HTML-casing of the property name) is invalid. Ignore this property completely. - continue; - } - - if (mainDescriptor != null) - { - attributeDescriptors.Add(mainDescriptor); - } - - if (indexerDescriptor != null) - { - indexerDescriptors.Add(indexerDescriptor); - } - } - - attributeDescriptors.AddRange(indexerDescriptors); - - return attributeDescriptors; - } - - // Internal for testing. - internal static bool ValidateTagHelperAttributeDescriptor( - TagHelperAttributeDescriptor attributeDescriptor, - ITypeInfo parentType, - ErrorSink errorSink) - { - string nameOrPrefix; - if (attributeDescriptor.IsIndexer) - { - nameOrPrefix = Resources.TagHelperDescriptorFactory_Prefix; - } - else if (string.IsNullOrEmpty(attributeDescriptor.Name)) - { - errorSink.OnError( - SourceLocation.Zero, - Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameNullOrEmpty( - parentType.FullName, - attributeDescriptor.PropertyName), - length: 0); - - return false; - } - else - { - nameOrPrefix = Resources.TagHelperDescriptorFactory_Name; - } - - return ValidateTagHelperAttributeNameOrPrefix( - attributeDescriptor.Name, - parentType, - attributeDescriptor.PropertyName, - errorSink, - nameOrPrefix); - } - - private static bool ShouldSkipDescriptorCreation(bool designTime, IMemberInfo memberInfo) - { - if (designTime) - { - var editorBrowsableAttribute = memberInfo - .GetCustomAttributes() - .FirstOrDefault(); - - return editorBrowsableAttribute != null && - editorBrowsableAttribute.State == EditorBrowsableState.Never; - } - - return false; - } - - private static bool ValidateTagHelperAttributeNameOrPrefix( - string attributeNameOrPrefix, - ITypeInfo parentType, - string propertyName, - ErrorSink errorSink, - string nameOrPrefix) - { - if (string.IsNullOrEmpty(attributeNameOrPrefix)) - { - // ValidateTagHelperAttributeDescriptor validates Name is non-null and non-empty. The empty string is - // valid for DictionaryAttributePrefix and null is impossible at this point because it means "don't - // create a descriptor". (Empty DictionaryAttributePrefix is a corner case which would bind every - // attribute of a target element. Likely not particularly useful but unclear what minimum length - // should be required and what scenarios a minimum length would break.) - return true; - } - - if (string.IsNullOrWhiteSpace(attributeNameOrPrefix)) - { - // Provide a single error if the entire name is whitespace, not an error per character. - errorSink.OnError( - SourceLocation.Zero, - Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixWhitespace( - parentType.FullName, - propertyName, - nameOrPrefix), - length: 0); - - return false; - } - - // data-* attributes are explicitly not implemented by user agents and are not intended for use on - // the server; therefore it's invalid for TagHelpers to bind to them. - if (attributeNameOrPrefix.StartsWith(DataDashPrefix, StringComparison.OrdinalIgnoreCase)) - { - errorSink.OnError( - SourceLocation.Zero, - Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixStart( - parentType.FullName, - propertyName, - nameOrPrefix, - attributeNameOrPrefix, - DataDashPrefix), - length: 0); - - return false; - } - - var isValid = true; - foreach (var character in attributeNameOrPrefix) - { - if (char.IsWhiteSpace(character) || InvalidNonWhitespaceNameCharacters.Contains(character)) - { - errorSink.OnError( - SourceLocation.Zero, - Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixCharacter( - parentType.FullName, - propertyName, - nameOrPrefix, - attributeNameOrPrefix, - character), - length: 0); - - isValid = false; - } - } - - return isValid; - } - - private static TagHelperAttributeDescriptor ToAttributeDescriptor( - IPropertyInfo property, - string attributeName, - bool designTime) - { - return ToAttributeDescriptor( - property, - attributeName, - property.PropertyType.FullName, - isIndexer: false, - isStringProperty: StringTypeInfo.Equals(property.PropertyType), - designTime: designTime); - } - - private static TagHelperAttributeDescriptor ToIndexerAttributeDescriptor( - IPropertyInfo property, - HtmlAttributeNameAttribute attributeNameAttribute, - ITypeInfo parentType, - ErrorSink errorSink, - string defaultPrefix, - bool designTime, - out bool isInvalid) - { - isInvalid = false; - var hasPublicSetter = property.HasPublicSetter; - var dictionaryTypeArguments = property.PropertyType.GetGenericDictionaryParameters(); - if (!StringTypeInfo.Equals(dictionaryTypeArguments?[0])) - { - if (attributeNameAttribute?.DictionaryAttributePrefix != null) - { - // DictionaryAttributePrefix is not supported unless associated with an - // IDictionary property. - isInvalid = true; - errorSink.OnError( - SourceLocation.Zero, - Resources.FormatTagHelperDescriptorFactory_InvalidAttributePrefixNotNull( - parentType.FullName, - property.Name, - nameof(HtmlAttributeNameAttribute), - nameof(HtmlAttributeNameAttribute.DictionaryAttributePrefix), - "IDictionary"), - length: 0); - } - else if (attributeNameAttribute != null && !hasPublicSetter) - { - // Associated an HtmlAttributeNameAttribute with a non-dictionary property that lacks a public - // setter. - isInvalid = true; - errorSink.OnError( - SourceLocation.Zero, - Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameAttribute( - parentType.FullName, - property.Name, - nameof(HtmlAttributeNameAttribute), - "IDictionary"), - length: 0); - } - - return null; - } - else if (!hasPublicSetter && - attributeNameAttribute != null && - !attributeNameAttribute.DictionaryAttributePrefixSet) - { - // Must set DictionaryAttributePrefix when using HtmlAttributeNameAttribute with a dictionary property - // that lacks a public setter. - isInvalid = true; - errorSink.OnError( - SourceLocation.Zero, - Resources.FormatTagHelperDescriptorFactory_InvalidAttributePrefixNull( - parentType.FullName, - property.Name, - nameof(HtmlAttributeNameAttribute), - nameof(HtmlAttributeNameAttribute.DictionaryAttributePrefix), - "IDictionary"), - length: 0); - - return null; - } - - // Potential prefix case. Use default prefix (based on name)? - var useDefault = attributeNameAttribute == null || !attributeNameAttribute.DictionaryAttributePrefixSet; - - var prefix = useDefault ? defaultPrefix : attributeNameAttribute.DictionaryAttributePrefix; - if (prefix == null) - { - // DictionaryAttributePrefix explicitly set to null. Ignore. - return null; - } - - return ToAttributeDescriptor( - property, - attributeName: prefix, - typeName: dictionaryTypeArguments[1].FullName, - isIndexer: true, - isStringProperty: StringTypeInfo.Equals(dictionaryTypeArguments[1]), - designTime: designTime); - } - - private static TagHelperAttributeDescriptor ToAttributeDescriptor( - IPropertyInfo property, - string attributeName, - string typeName, - bool isIndexer, - bool isStringProperty, - bool designTime) - { - TagHelperAttributeDesignTimeDescriptor propertyDesignTimeDescriptor = null; - -#if !DOTNET5_4 - if (designTime) - { - var runtimeProperty = property as RuntimePropertyInfo; - if (runtimeProperty != null) - { - propertyDesignTimeDescriptor = - TagHelperDesignTimeDescriptorFactory.CreateAttributeDescriptor(runtimeProperty.Property); - } - } -#endif - - return new TagHelperAttributeDescriptor - { - Name = attributeName, - PropertyName = property.Name, - TypeName = typeName, - IsStringProperty = isStringProperty, - IsIndexer = isIndexer, - DesignTimeDescriptor = propertyDesignTimeDescriptor - }; - } - - private static bool IsAccessibleProperty(IPropertyInfo property) - { - // Accessible properties are those with public getters and without [HtmlAttributeNotBound]. - return property.HasPublicGetter && - property.GetCustomAttributes().FirstOrDefault() == null; - } - - /// - /// Converts from pascal/camel case to lower kebab-case. - /// - /// - /// SomeThing => some-thing - /// capsONInside => caps-on-inside - /// CAPSOnOUTSIDE => caps-on-outside - /// ALLCAPS => allcaps - /// One1Two2Three3 => one1-two2-three3 - /// ONE1TWO2THREE3 => one1two2three3 - /// First_Second_ThirdHi => first_second_third-hi - /// - private static string ToHtmlCase(string name) - { - return HtmlCaseRegex.Replace(name, HtmlCaseRegexReplacement).ToLowerInvariant(); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperDescriptorResolver.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperDescriptorResolver.cs deleted file mode 100644 index d96346ea0a..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperDescriptorResolver.cs +++ /dev/null @@ -1,307 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Microsoft.AspNet.Razor.Compilation.TagHelpers; -using Microsoft.AspNet.Razor.Parser; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// Used to resolve s. - /// - public class TagHelperDescriptorResolver : ITagHelperDescriptorResolver - { - private static readonly IReadOnlyDictionary _directiveNames = - new Dictionary - { - { TagHelperDirectiveType.AddTagHelper, SyntaxConstants.CSharp.AddTagHelperKeyword }, - { TagHelperDirectiveType.RemoveTagHelper, SyntaxConstants.CSharp.RemoveTagHelperKeyword }, - { TagHelperDirectiveType.TagHelperPrefix, SyntaxConstants.CSharp.TagHelperPrefixKeyword }, - }; - - private readonly TagHelperTypeResolver _typeResolver; - private readonly bool _designTime; - - /// - /// Instantiates a new instance of the class. - /// - /// Indicates whether resolved s should include - /// design time specific information. - public TagHelperDescriptorResolver(bool designTime) - : this(new TagHelperTypeResolver(), designTime) - { - } - - /// - /// Instantiates a new instance of class with the - /// specified . - /// - /// The . - /// Indicates whether resolved s should include - /// design time specific information. - public TagHelperDescriptorResolver(TagHelperTypeResolver typeResolver, bool designTime) - { - _typeResolver = typeResolver; - _designTime = designTime; - } - - /// - public IEnumerable Resolve(TagHelperDescriptorResolutionContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - var resolvedDescriptors = new HashSet(TagHelperDescriptorComparer.Default); - - // tagHelperPrefix directives do not affect which TagHelperDescriptors are added or removed from the final - // list, need to remove them. - var actionableDirectiveDescriptors = context.DirectiveDescriptors.Where( - directive => directive.DirectiveType != TagHelperDirectiveType.TagHelperPrefix); - - foreach (var directiveDescriptor in actionableDirectiveDescriptors) - { - try - { - var lookupInfo = GetLookupInfo(directiveDescriptor, context.ErrorSink); - - // Could not resolve the lookup info. - if (lookupInfo == null) - { - return Enumerable.Empty(); - } - - if (directiveDescriptor.DirectiveType == TagHelperDirectiveType.RemoveTagHelper) - { - resolvedDescriptors.RemoveWhere(descriptor => MatchesLookupInfo(descriptor, lookupInfo)); - } - else if (directiveDescriptor.DirectiveType == TagHelperDirectiveType.AddTagHelper) - { - var descriptors = ResolveDescriptorsInAssembly( - lookupInfo.AssemblyName, - lookupInfo.AssemblyNameLocation, - context.ErrorSink); - - // Only use descriptors that match our lookup info - descriptors = descriptors.Where(descriptor => MatchesLookupInfo(descriptor, lookupInfo)); - - resolvedDescriptors.UnionWith(descriptors); - } - } - catch (Exception ex) - { - string directiveName; - _directiveNames.TryGetValue(directiveDescriptor.DirectiveType, out directiveName); - Debug.Assert(!string.IsNullOrEmpty(directiveName)); - - context.ErrorSink.OnError( - directiveDescriptor.Location, - Resources.FormatTagHelperDescriptorResolver_EncounteredUnexpectedError( - "@" + directiveName, - directiveDescriptor.DirectiveText, - ex.Message), - GetErrorLength(directiveDescriptor.DirectiveText)); - } - } - - var prefixedDescriptors = PrefixDescriptors(context, resolvedDescriptors); - - return prefixedDescriptors; - } - - /// - /// Resolves all s for s from the - /// given . - /// - /// - /// The name of the assembly to resolve s from. - /// - /// The of the directive. - /// Used to record errors found when resolving s - /// within the given . - /// s for s from the given - /// . - // This is meant to be overridden by tooling to enable assembly level caching. - protected virtual IEnumerable ResolveDescriptorsInAssembly( - string assemblyName, - SourceLocation documentLocation, - ErrorSink errorSink) - { - // Resolve valid tag helper types from the assembly. - var tagHelperTypes = _typeResolver.Resolve(assemblyName, documentLocation, errorSink); - - // Convert types to TagHelperDescriptors - var descriptors = tagHelperTypes.SelectMany( - type => TagHelperDescriptorFactory.CreateDescriptors(assemblyName, type, _designTime, errorSink)); - - return descriptors; - } - - private static IEnumerable PrefixDescriptors( - TagHelperDescriptorResolutionContext context, - IEnumerable descriptors) - { - var tagHelperPrefix = ResolveTagHelperPrefix(context); - - if (!string.IsNullOrEmpty(tagHelperPrefix)) - { - return descriptors.Select(descriptor => - new TagHelperDescriptor - { - Prefix = tagHelperPrefix, - TagName = descriptor.TagName, - TypeName = descriptor.TypeName, - AssemblyName = descriptor.AssemblyName, - Attributes = descriptor.Attributes, - RequiredAttributes = descriptor.RequiredAttributes, - AllowedChildren = descriptor.AllowedChildren, - RequiredParent = descriptor.RequiredParent, - TagStructure = descriptor.TagStructure, - DesignTimeDescriptor = descriptor.DesignTimeDescriptor - }); - } - - return descriptors; - } - - private static string ResolveTagHelperPrefix(TagHelperDescriptorResolutionContext context) - { - var prefixDirectiveDescriptors = context.DirectiveDescriptors.Where( - descriptor => descriptor.DirectiveType == TagHelperDirectiveType.TagHelperPrefix); - - TagHelperDirectiveDescriptor prefixDirective = null; - - foreach (var directive in prefixDirectiveDescriptors) - { - if (prefixDirective == null) - { - prefixDirective = directive; - } - else - { - // For each invalid @tagHelperPrefix we need to create an error. - context.ErrorSink.OnError( - directive.Location, - Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperDirective( - SyntaxConstants.CSharp.TagHelperPrefixKeyword), - GetErrorLength(directive.DirectiveText)); - } - } - - var prefix = prefixDirective?.DirectiveText; - - if (prefix != null && !EnsureValidPrefix(prefix, prefixDirective.Location, context.ErrorSink)) - { - prefix = null; - } - - return prefix; - } - - private static bool EnsureValidPrefix( - string prefix, - SourceLocation directiveLocation, - ErrorSink errorSink) - { - foreach (var character in prefix) - { - // Prefixes are correlated with tag names, tag names cannot have whitespace. - if (char.IsWhiteSpace(character) || - TagHelperDescriptorFactory.InvalidNonWhitespaceNameCharacters.Contains(character)) - { - errorSink.OnError( - directiveLocation, - Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperPrefixValue( - SyntaxConstants.CSharp.TagHelperPrefixKeyword, - character, - prefix), - prefix.Length); - - return false; - } - } - - return true; - } - - private static bool MatchesLookupInfo(TagHelperDescriptor descriptor, LookupInfo lookupInfo) - { - if (!string.Equals(descriptor.AssemblyName, lookupInfo.AssemblyName, StringComparison.Ordinal)) - { - return false; - } - - if (lookupInfo.TypePattern.EndsWith("*", StringComparison.Ordinal)) - { - if (lookupInfo.TypePattern.Length == 1) - { - // TypePattern is "*". - return true; - } - - var lookupTypeName = lookupInfo.TypePattern.Substring(0, lookupInfo.TypePattern.Length - 1); - - return descriptor.TypeName.StartsWith(lookupTypeName, StringComparison.Ordinal); - } - - return string.Equals(descriptor.TypeName, lookupInfo.TypePattern, StringComparison.Ordinal); - } - - private static LookupInfo GetLookupInfo( - TagHelperDirectiveDescriptor directiveDescriptor, - ErrorSink errorSink) - { - var lookupText = directiveDescriptor.DirectiveText; - var lookupStrings = lookupText?.Split(new[] { ',' }); - - // Ensure that we have valid lookupStrings to work with. The valid format is "typeName, assemblyName" - if (lookupStrings == null || - lookupStrings.Any(string.IsNullOrWhiteSpace) || - lookupStrings.Length != 2) - { - errorSink.OnError( - directiveDescriptor.Location, - Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperLookupText(lookupText), - GetErrorLength(lookupText)); - - return null; - } - - var trimmedAssemblyName = lookupStrings[1].Trim(); - - // + 1 is for the comma separator in the lookup text. - var assemblyNameIndex = lookupStrings[0].Length + 1 + lookupStrings[1].IndexOf(trimmedAssemblyName); - var assemblyNamePrefix = directiveDescriptor.DirectiveText.Substring(0, assemblyNameIndex); - var assemblyNameLocation = SourceLocation.Advance(directiveDescriptor.Location, assemblyNamePrefix); - - return new LookupInfo - { - TypePattern = lookupStrings[0].Trim(), - AssemblyName = trimmedAssemblyName, - AssemblyNameLocation = assemblyNameLocation, - }; - } - - private static int GetErrorLength(string directiveText) - { - var nonNullLength = directiveText == null ? 1 : directiveText.Length; - var normalizeEmptyStringLength = Math.Max(nonNullLength, 1); - - return normalizeEmptyStringLength; - } - - private class LookupInfo - { - public string AssemblyName { get; set; } - - public string TypePattern { get; set; } - - public SourceLocation AssemblyNameLocation { get; set; } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperDesignTimeDescriptorFactory.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperDesignTimeDescriptorFactory.cs deleted file mode 100644 index 22757e37a2..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperDesignTimeDescriptorFactory.cs +++ /dev/null @@ -1,215 +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. - -#if !DOTNET5_4 // Cannot accurately resolve the location of the documentation XML file in coreclr. -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using Microsoft.AspNet.Razor.Compilation.TagHelpers; -using Microsoft.AspNet.Razor.TagHelpers; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// Factory for providing s from s and - /// s from s. - /// - public static class TagHelperDesignTimeDescriptorFactory - { - /// - /// Creates a from the given . - /// - /// - /// The to create a from. - /// - /// A that describes design time specific information - /// for the given . - public static TagHelperDesignTimeDescriptor CreateDescriptor(Type type) - { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } - - var id = XmlDocumentationProvider.GetId(type); - var documentationDescriptor = CreateDocumentationDescriptor(type.Assembly, id); - - // Purposefully not using the TypeInfo.GetCustomAttributes method here to make it easier to mock the Type. - var outputElementHintAttribute = type - .GetCustomAttributes(inherit: false) - ?.OfType() - .FirstOrDefault(); - var outputElementHint = outputElementHintAttribute?.OutputElement; - - if (documentationDescriptor != null || outputElementHint != null) - { - return new TagHelperDesignTimeDescriptor - { - Summary = documentationDescriptor?.Summary, - Remarks = documentationDescriptor?.Remarks, - OutputElementHint = outputElementHint - }; - } - - return null; - } - - /// - /// Creates a from the given - /// . - /// - /// - /// The to create a from. - /// - /// A that describes design time specific - /// information for the given . - public static TagHelperAttributeDesignTimeDescriptor CreateAttributeDescriptor( - PropertyInfo propertyInfo) - { - if (propertyInfo == null) - { - throw new ArgumentNullException(nameof(propertyInfo)); - } - - var id = XmlDocumentationProvider.GetId(propertyInfo); - var declaringAssembly = propertyInfo.DeclaringType.Assembly; - var documentationDescriptor = CreateDocumentationDescriptor(declaringAssembly, id); - - if (documentationDescriptor != null) - { - return new TagHelperAttributeDesignTimeDescriptor - { - Summary = documentationDescriptor.Summary, - Remarks = documentationDescriptor.Remarks - }; - } - - return null; - } - - private static DocumentationDescriptor CreateDocumentationDescriptor(Assembly assembly, string id) - { - var assemblyLocation = assembly.Location; - - if (string.IsNullOrEmpty(assemblyLocation) && !string.IsNullOrEmpty(assembly.CodeBase)) - { - var uri = new UriBuilder(assembly.CodeBase); - - // Normalize the path to a UNC path. This will remove things like file:// from start of the uri.Path. - assemblyLocation = Uri.UnescapeDataString(uri.Path); - } - - // Couldn't resolve a valid assemblyLocation. - if (string.IsNullOrEmpty(assemblyLocation)) - { - return null; - } - - var xmlDocumentationFile = GetXmlDocumentationFile(assembly, assemblyLocation); - - // Only want to process the file if it exists. - if (xmlDocumentationFile != null) - { - var documentationProvider = new XmlDocumentationProvider(xmlDocumentationFile.FullName); - - var summary = documentationProvider.GetSummary(id); - var remarks = documentationProvider.GetRemarks(id); - - if (!string.IsNullOrEmpty(summary) || !string.IsNullOrEmpty(remarks)) - { - return new DocumentationDescriptor - { - Summary = summary, - Remarks = remarks - }; - } - } - - return null; - } - - private static FileInfo GetXmlDocumentationFile(Assembly assembly, string assemblyLocation) - { - try - { - var assemblyDirectory = Path.GetDirectoryName(assemblyLocation); - var assemblyName = Path.GetFileName(assemblyLocation); - var assemblyXmlDocumentationName = Path.ChangeExtension(assemblyName, ".xml"); - - // Check for a localized XML file for the current culture. - var xmlDocumentationFile = GetLocalizedXmlDocumentationFile( - CultureInfo.CurrentCulture, - assemblyDirectory, - assemblyXmlDocumentationName); - - if (xmlDocumentationFile == null) - { - // Check for a culture-neutral XML file next to the assembly - xmlDocumentationFile = new FileInfo( - Path.Combine(assemblyDirectory, assemblyXmlDocumentationName)); - - if (!xmlDocumentationFile.Exists) - { - xmlDocumentationFile = null; - } - } - - return xmlDocumentationFile; - } - catch (ArgumentException) - { - // Could not resolve XML file. - return null; - } - } - - private static IEnumerable ExpandPaths( - CultureInfo culture, - string assemblyDirectory, - string assemblyXmlDocumentationName) - { - // Following the fall-back process defined by: - // https://msdn.microsoft.com/en-us/library/sb6a8618.aspx#cpconpackagingdeployingresourcesanchor1 - do - { - var cultureName = culture.Name; - var cultureSpecificFileName = - Path.ChangeExtension(assemblyXmlDocumentationName, cultureName + ".xml"); - - // Look for a culture specific XML file next to the assembly. - yield return Path.Combine(assemblyDirectory, cultureSpecificFileName); - - // Look for an XML file with the same name as the assembly in a culture specific directory. - yield return Path.Combine(assemblyDirectory, cultureName, assemblyXmlDocumentationName); - - // Look for a culture specific XML file in a culture specific directory. - yield return Path.Combine(assemblyDirectory, cultureName, cultureSpecificFileName); - - culture = culture.Parent; - } while (culture != null && culture != CultureInfo.InvariantCulture); - } - - private static FileInfo GetLocalizedXmlDocumentationFile( - CultureInfo culture, - string assemblyDirectory, - string assemblyXmlDocumentationName) - { - var localizedXmlPaths = ExpandPaths(culture, assemblyDirectory, assemblyXmlDocumentationName); - var xmlDocumentationFile = localizedXmlPaths - .Select(path => new FileInfo(path)) - .FirstOrDefault(file => file.Exists); - - return xmlDocumentationFile; - } - - private class DocumentationDescriptor - { - public string Summary { get; set; } - public string Remarks { get; set; } - } - } -} -#endif \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperExecutionContext.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperExecutionContext.cs deleted file mode 100644 index 1b9068611f..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperExecutionContext.cs +++ /dev/null @@ -1,255 +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; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNet.Razor.TagHelpers; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// Class used to store information about a 's execution lifetime. - /// - public class TagHelperExecutionContext - { - private readonly List _tagHelpers; - private readonly Func _executeChildContentAsync; - private readonly Action _startTagHelperWritingScope; - private readonly Func _endTagHelperWritingScope; - private TagHelperContent _childContent; - - /// - /// Internal for testing purposes only. - /// - internal TagHelperExecutionContext(string tagName, TagMode tagMode) - : this(tagName, - tagMode, - items: new Dictionary(), - uniqueId: string.Empty, - executeChildContentAsync: async () => await Task.FromResult(result: true), - startTagHelperWritingScope: () => { }, - endTagHelperWritingScope: () => new DefaultTagHelperContent()) - { - } - - /// - /// Instantiates a new . - /// - /// The HTML tag name in the Razor source. - /// HTML syntax of the element in the Razor source. - /// The collection of items used to communicate with other - /// s - /// An identifier unique to the HTML element this context is for. - /// A delegate used to execute the child content asynchronously. - /// A delegate used to start a writing scope in a Razor page. - /// A delegate used to end a writing scope in a Razor page. - public TagHelperExecutionContext( - string tagName, - TagMode tagMode, - IDictionary items, - string uniqueId, - Func executeChildContentAsync, - Action startTagHelperWritingScope, - Func endTagHelperWritingScope) - { - if (tagName == null) - { - throw new ArgumentNullException(nameof(tagName)); - } - - if (items == null) - { - throw new ArgumentNullException(nameof(items)); - } - - if (uniqueId == null) - { - throw new ArgumentNullException(nameof(uniqueId)); - } - - if (executeChildContentAsync == null) - { - throw new ArgumentNullException(nameof(executeChildContentAsync)); - } - - if (startTagHelperWritingScope == null) - { - throw new ArgumentNullException(nameof(startTagHelperWritingScope)); - } - - if (endTagHelperWritingScope == null) - { - throw new ArgumentNullException(nameof(endTagHelperWritingScope)); - } - - _tagHelpers = new List(); - _executeChildContentAsync = executeChildContentAsync; - _startTagHelperWritingScope = startTagHelperWritingScope; - _endTagHelperWritingScope = endTagHelperWritingScope; - - TagMode = tagMode; - HTMLAttributes = new TagHelperAttributeList(); - AllAttributes = new TagHelperAttributeList(); - TagName = tagName; - Items = items; - UniqueId = uniqueId; - } - - /// - /// Gets the HTML syntax of the element in the Razor source. - /// - public TagMode TagMode { get; } - - /// - /// Indicates if has been called. - /// - public bool ChildContentRetrieved - { - get - { - return _childContent != null; - } - } - - /// - /// Gets the collection of items used to communicate with other s. - /// - public IDictionary Items { get; } - - /// - /// HTML attributes. - /// - public TagHelperAttributeList HTMLAttributes { get; } - - /// - /// bound attributes and HTML attributes. - /// - public TagHelperAttributeList AllAttributes { get; } - - /// - /// An identifier unique to the HTML element this context is for. - /// - public string UniqueId { get; } - - /// - /// s that should be run. - /// - public IEnumerable TagHelpers - { - get - { - return _tagHelpers; - } - } - - /// - /// The HTML tag name in the Razor source. - /// - public string TagName { get; } - - /// - /// The s' output. - /// - public TagHelperOutput Output { get; set; } - - /// - /// Tracks the given . - /// - /// The tag helper to track. - public void Add(ITagHelper tagHelper) - { - if (tagHelper == null) - { - throw new ArgumentNullException(nameof(tagHelper)); - } - - _tagHelpers.Add(tagHelper); - } - - /// - /// Tracks the minimized HTML attribute in and . - /// - /// The minimized HTML attribute name. - public void AddMinimizedHtmlAttribute(string name) - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - HTMLAttributes.Add( - new TagHelperAttribute - { - Name = name, - Minimized = true - }); - AllAttributes.Add( - new TagHelperAttribute - { - Name = name, - Minimized = true - }); - } - - /// - /// Tracks the HTML attribute in and . - /// - /// The HTML attribute name. - /// The HTML attribute value. - public void AddHtmlAttribute(string name, object value) - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - HTMLAttributes.Add(name, value); - AllAttributes.Add(name, value); - } - - /// - /// Tracks the bound attribute in . - /// - /// The bound attribute name. - /// The attribute value. - public void AddTagHelperAttribute(string name, object value) - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - AllAttributes.Add(name, value); - } - - /// - /// Executes the child content asynchronously. - /// - /// A which on completion executes all child content. - public Task ExecuteChildContentAsync() - { - return _executeChildContentAsync(); - } - - /// - /// Execute and retrieve the rendered child content asynchronously. - /// - /// A that on completion returns the rendered child content. - /// - /// Child content is only executed once. Successive calls to this method or successive executions of the - /// returned return a cached result. - /// - public async Task GetChildContentAsync(bool useCachedResult) - { - if (!useCachedResult || _childContent == null) - { - _startTagHelperWritingScope(); - await _executeChildContentAsync(); - _childContent = _endTagHelperWritingScope(); - } - - return new DefaultTagHelperContent().SetContent(_childContent); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperRunner.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperRunner.cs deleted file mode 100644 index c6ebeddef4..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperRunner.cs +++ /dev/null @@ -1,57 +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; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNet.Razor.TagHelpers; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// A class used to run s. - /// - public class TagHelperRunner - { - /// - /// Calls the method on s. - /// - /// Contains information associated with running s. - /// - /// Resulting from processing all of the - /// 's s. - public async Task RunAsync(TagHelperExecutionContext executionContext) - { - if (executionContext == null) - { - throw new ArgumentNullException(nameof(executionContext)); - } - - var tagHelperContext = new TagHelperContext( - executionContext.AllAttributes, - executionContext.Items, - executionContext.UniqueId); - var orderedTagHelpers = executionContext.TagHelpers.OrderBy(tagHelper => tagHelper.Order); - - foreach (var tagHelper in orderedTagHelpers) - { - tagHelper.Init(tagHelperContext); - } - - var tagHelperOutput = new TagHelperOutput( - executionContext.TagName, - executionContext.HTMLAttributes, - executionContext.GetChildContentAsync) - { - TagMode = executionContext.TagMode, - }; - - foreach (var tagHelper in orderedTagHelpers) - { - await tagHelper.ProcessAsync(tagHelperContext, tagHelperOutput); - } - - return tagHelperOutput; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperScopeManager.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperScopeManager.cs deleted file mode 100644 index f2ae450871..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperScopeManager.cs +++ /dev/null @@ -1,124 +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; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNet.Razor.TagHelpers; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// Class that manages scopes. - /// - public class TagHelperScopeManager - { - private readonly Stack _executionScopes; - - /// - /// Instantiates a new . - /// - public TagHelperScopeManager() - { - _executionScopes = new Stack(); - } - - /// - /// Starts a scope. - /// - /// The HTML tag name that the scope is associated with. - /// HTML syntax of the element in the Razor source. - /// An identifier unique to the HTML element this scope is for. - /// A delegate used to execute the child content asynchronously. - /// A delegate used to start a writing scope in a Razor page. - /// A delegate used to end a writing scope in a Razor page. - /// A to use. - public TagHelperExecutionContext Begin( - string tagName, - TagMode tagMode, - string uniqueId, - Func executeChildContentAsync, - Action startTagHelperWritingScope, - Func endTagHelperWritingScope) - { - if (tagName == null) - { - throw new ArgumentNullException(nameof(tagName)); - } - - if (uniqueId == null) - { - throw new ArgumentNullException(nameof(uniqueId)); - } - - if (executeChildContentAsync == null) - { - throw new ArgumentNullException(nameof(executeChildContentAsync)); - } - - if (startTagHelperWritingScope == null) - { - throw new ArgumentNullException(nameof(startTagHelperWritingScope)); - } - - if (endTagHelperWritingScope == null) - { - throw new ArgumentNullException(nameof(endTagHelperWritingScope)); - } - - IDictionary items; - - // If we're not wrapped by another TagHelper, then there will not be a parentExecutionContext. - if (_executionScopes.Count > 0) - { - items = new CopyOnWriteDictionary( - _executionScopes.Peek().Items, - comparer: EqualityComparer.Default); - } - else - { - items = new Dictionary(); - } - - var executionContext = new TagHelperExecutionContext( - tagName, - tagMode, - items, - uniqueId, - executeChildContentAsync, - startTagHelperWritingScope, - endTagHelperWritingScope); - - _executionScopes.Push(executionContext); - - return executionContext; - } - - /// - /// Ends a scope. - /// - /// If the current scope is nested, the parent . - /// null otherwise. - public TagHelperExecutionContext End() - { - if (_executionScopes.Count == 0) - { - throw new InvalidOperationException( - Resources.FormatScopeManager_EndCannotBeCalledWithoutACallToBegin( - nameof(End), - nameof(Begin), - nameof(TagHelperScopeManager))); - } - - _executionScopes.Pop(); - - if (_executionScopes.Count != 0) - { - return _executionScopes.Peek(); - } - - return null; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperTypeResolver.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperTypeResolver.cs deleted file mode 100644 index e132ce345f..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/TagHelperTypeResolver.cs +++ /dev/null @@ -1,116 +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; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Microsoft.AspNet.Razor.TagHelpers; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// Class that locates valid s within an assembly. - /// - public class TagHelperTypeResolver - { - private static readonly ITypeInfo ITagHelperTypeInfo = new RuntimeTypeInfo(typeof(ITagHelper).GetTypeInfo()); - - /// - /// Locates valid types from the named . - /// - /// The name of an to search. - /// The of the associated - /// responsible for the current call. - /// - /// The used to record errors found when resolving - /// types. - /// An of valid types. - public IEnumerable Resolve( - string name, - SourceLocation documentLocation, - ErrorSink errorSink) - { - if (errorSink == null) - { - throw new ArgumentNullException(nameof(errorSink)); - } - - if (string.IsNullOrEmpty(name)) - { - var errorLength = name == null ? 1 : Math.Max(name.Length, 1); - errorSink.OnError( - documentLocation, - Resources.TagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull, - errorLength); - - return Enumerable.Empty(); - } - - var assemblyName = new AssemblyName(name); - - IEnumerable libraryTypes; - try - { - libraryTypes = GetTopLevelExportedTypes(assemblyName); - } - catch (Exception ex) - { - errorSink.OnError( - documentLocation, - Resources.FormatTagHelperTypeResolver_CannotResolveTagHelperAssembly( - assemblyName.Name, - ex.Message), - name.Length); - - return Enumerable.Empty(); - } - - return libraryTypes.Where(IsTagHelper); - } - - /// - /// Returns all non-nested exported types from the given - /// - /// The to get s from. - /// - /// An of types exported from the given . - /// - protected virtual IEnumerable GetTopLevelExportedTypes(AssemblyName assemblyName) - { - if (assemblyName == null) - { - throw new ArgumentNullException(nameof(assemblyName)); - } - - var exportedTypeInfos = GetExportedTypes(assemblyName); - - return exportedTypeInfos - .Where(typeInfo => !typeInfo.IsNested) - .Select(typeInfo => new RuntimeTypeInfo(typeInfo)); - } - - /// - /// Returns all exported types from the given - /// - /// The to get s from. - /// - /// An of types exported from the given . - /// - protected virtual IEnumerable GetExportedTypes(AssemblyName assemblyName) - { - var assembly = Assembly.Load(assemblyName); - - return assembly.ExportedTypes.Select(type => type.GetTypeInfo()); - } - - // Internal for testing. - internal virtual bool IsTagHelper(ITypeInfo typeInfo) - { - return typeInfo.IsPublic && - !typeInfo.IsAbstract && - !typeInfo.IsGenericType && - typeInfo.ImplementsInterface(ITagHelperTypeInfo); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/XmlDocumentationProvider.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/XmlDocumentationProvider.cs deleted file mode 100644 index e7c236af9e..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/Runtime/TagHelpers/XmlDocumentationProvider.cs +++ /dev/null @@ -1,129 +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. - -#if !DOTNET5_4 -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Xml.Linq; - -namespace Microsoft.AspNet.Razor.Runtime.TagHelpers -{ - /// - /// Extracts summary and remarks XML documentation from an XML documentation file. - /// - public class XmlDocumentationProvider - { - private readonly IEnumerable _members; - - /// - /// Instantiates a new instance of the . - /// - /// Path to the XML documentation file to read. - public XmlDocumentationProvider(string xmlFileLocation) - { - // XML file processing is defined by: https://msdn.microsoft.com/en-us/library/fsbx0t7x.aspx - var xmlDocumentation = XDocument.Load(xmlFileLocation); - var documentationRootMembers = xmlDocumentation.Root.Element("members"); - _members = documentationRootMembers.Elements("member"); - } - - /// - /// Retrieves the <summary> documentation for the given . - /// - /// The id to lookup. - /// <summary> documentation for the given . - public string GetSummary(string id) - { - var associatedMemeber = GetMember(id); - var summaryElement = associatedMemeber?.Element("summary"); - - if (summaryElement != null) - { - var summaryValue = GetElementValue(summaryElement); - - return summaryValue; - } - - return null; - } - - /// - /// Retrieves the <remarks> documentation for the given . - /// - /// The id to lookup. - /// <remarks> documentation for the given . - public string GetRemarks(string id) - { - var associatedMemeber = GetMember(id); - var remarksElement = associatedMemeber?.Element("remarks"); - - if (remarksElement != null) - { - var remarksValue = GetElementValue(remarksElement); - - return remarksValue; - } - - return null; - } - - /// - /// Generates the identifier for the given . - /// - /// The to get the identifier for. - /// The identifier for the given . - public static string GetId(Type type) - { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } - - return $"T:{type.FullName}"; - } - - /// - /// Generates the identifier for the given . - /// - /// The to get the identifier for. - /// The identifier for the given . - public static string GetId(PropertyInfo propertyInfo) - { - if (propertyInfo == null) - { - throw new ArgumentNullException(nameof(propertyInfo)); - } - - var declaringTypeInfo = propertyInfo.DeclaringType; - return $"P:{declaringTypeInfo.FullName}.{propertyInfo.Name}"; - } - - private XElement GetMember(string id) - { - var associatedMemeber = _members - .FirstOrDefault(element => - string.Equals(element.Attribute("name").Value, id, StringComparison.Ordinal)); - - return associatedMemeber; - } - - private static string GetElementValue(XElement element) - { - var stringBuilder = new StringBuilder(); - var node = element.FirstNode; - - while (node != null) - { - stringBuilder.Append(node.ToString(SaveOptions.DisableFormatting)); - - node = node.NextNode; - } - - return stringBuilder.ToString().Trim(); - } - } -} -#endif \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/DefaultTagHelperContent.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/DefaultTagHelperContent.cs deleted file mode 100644 index 38a28193ae..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/DefaultTagHelperContent.cs +++ /dev/null @@ -1,231 +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; -using System.Diagnostics; -using System.IO; -using System.Text; -using Microsoft.AspNet.Html.Abstractions; -using Microsoft.AspNet.Razor.TagHelpers; -using Microsoft.Extensions.Internal; -using Microsoft.Extensions.WebEncoders; - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// Default concrete . - /// - [DebuggerDisplay("{DebuggerToString(),nq}")] - public class DefaultTagHelperContent : TagHelperContent - { - private BufferedHtmlContent _buffer; - - private BufferedHtmlContent Buffer - { - get - { - if (_buffer == null) - { - _buffer = new BufferedHtmlContent(); - } - - return _buffer; - } - } - - /// - public override bool IsModified => _buffer != null; - - /// - /// Returns true for a cleared . - public override bool IsWhiteSpace - { - get - { - if (_buffer == null) - { - return true; - } - - using (var writer = new EmptyOrWhiteSpaceWriter()) - { - foreach (var entry in _buffer.Entries) - { - if (entry == null) - { - continue; - } - - var stringValue = entry as string; - if (stringValue != null) - { - if (!string.IsNullOrWhiteSpace(stringValue)) - { - return false; - } - } - else - { - ((IHtmlContent)entry).WriteTo(writer, HtmlEncoder.Default); - if (!writer.IsWhiteSpace) - { - return false; - } - } - } - } - - return true; - } - } - - /// - public override bool IsEmpty - { - get - { - if (_buffer == null) - { - return true; - } - - using (var writer = new EmptyOrWhiteSpaceWriter()) - { - foreach (var entry in _buffer.Entries) - { - if (entry == null) - { - continue; - } - - var stringValue = entry as string; - if (stringValue != null) - { - if (!string.IsNullOrEmpty(stringValue)) - { - return false; - } - } - else - { - ((IHtmlContent)entry).WriteTo(writer, HtmlEncoder.Default); - if (!writer.IsEmpty) - { - return false; - } - } - } - } - - return true; - } - } - - /// - public override TagHelperContent Append(string unencoded) - { - Buffer.Append(unencoded); - return this; - } - - /// - public override TagHelperContent AppendHtml(string encoded) - { - Buffer.AppendHtml(encoded); - return this; - } - - /// - public override TagHelperContent Append(IHtmlContent htmlContent) - { - Buffer.Append(htmlContent); - return this; - } - - /// - public override TagHelperContent Clear() - { - Buffer.Clear(); - return this; - } - - /// - public override string GetContent() - { - return GetContent(HtmlEncoder.Default); - } - - /// - public override string GetContent(IHtmlEncoder encoder) - { - if (_buffer == null) - { - return string.Empty; - } - - using (var writer = new StringWriter()) - { - WriteTo(writer, encoder); - return writer.ToString(); - } - } - - /// - public override void WriteTo(TextWriter writer, IHtmlEncoder encoder) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (encoder == null) - { - throw new ArgumentNullException(nameof(encoder)); - } - - Buffer.WriteTo(writer, encoder); - } - - private string DebuggerToString() - { - return GetContent(); - } - - // Overrides Write(string) to find if the content written is empty/whitespace. - private class EmptyOrWhiteSpaceWriter : TextWriter - { - public override Encoding Encoding - { - get - { - throw new NotImplementedException(); - } - } - - public bool IsEmpty { get; private set; } = true; - - public bool IsWhiteSpace { get; private set; } = true; - -#if DOTNET5_4 - // This is an abstract method in DNXCore - public override void Write(char value) - { - throw new NotImplementedException(); - } -#endif - - public override void Write(string value) - { - if (IsEmpty && !string.IsNullOrEmpty(value)) - { - IsEmpty = false; - } - - if (IsWhiteSpace && !string.IsNullOrWhiteSpace(value)) - { - IsWhiteSpace = false; - } - } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/HtmlAttributeNameAttribute.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/HtmlAttributeNameAttribute.cs deleted file mode 100644 index 597aa0a88e..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/HtmlAttributeNameAttribute.cs +++ /dev/null @@ -1,92 +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.AspNet.Razor.TagHelpers -{ - /// - /// Used to override an property's HTML attribute name. - /// - [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] - public sealed class HtmlAttributeNameAttribute : Attribute - { - private string _dictionaryAttributePrefix; - - /// - /// Instantiates a new instance of the class with - /// equal to null. - /// - /// - /// Associated property must not have a public setter and must be compatible with - /// where TKey is - /// . - /// - public HtmlAttributeNameAttribute() - { - } - - /// - /// Instantiates a new instance of the class. - /// - /// - /// HTML attribute name for the associated property. Must be null or empty if associated property does - /// not have a public setter and is compatible with - /// where TKey is - /// . Otherwise must not be null or empty. - /// - public HtmlAttributeNameAttribute(string name) - { - Name = name; - } - - /// - /// HTML attribute name of the associated property. - /// - /// - /// null or empty if and only if associated property does not have a public setter and is compatible - /// with where TKey is - /// . - /// - public string Name { get; } - - /// - /// Gets or sets the prefix used to match HTML attribute names. Matching attributes are added to the - /// associated property (an ). - /// - /// - /// If non-null associated property must be compatible with - /// where TKey is - /// . - /// - /// - /// - /// If associated property is compatible with - /// , default value is Name + "-". - /// must not be null or empty in this case. - /// - /// - /// Otherwise default value is null. - /// - /// - public string DictionaryAttributePrefix - { - get - { - return _dictionaryAttributePrefix; - } - set - { - _dictionaryAttributePrefix = value; - DictionaryAttributePrefixSet = true; - } - } - - /// - /// Gets an indication whether has been set. Used to distinguish an - /// uninitialized value from an explicit null setting. - /// - /// true if was set. false otherwise. - public bool DictionaryAttributePrefixSet { get; private set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/HtmlAttributeNotBoundAttribute.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/HtmlAttributeNotBoundAttribute.cs deleted file mode 100644 index 15421d0736..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/HtmlAttributeNotBoundAttribute.cs +++ /dev/null @@ -1,21 +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.AspNet.Razor.TagHelpers -{ - /// - /// Indicates the associated property should not be bound to HTML attributes. - /// - [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] - public sealed class HtmlAttributeNotBoundAttribute : Attribute - { - /// - /// Instantiates a new instance of the class. - /// - public HtmlAttributeNotBoundAttribute() - { - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/HtmlTargetElementAttribute.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/HtmlTargetElementAttribute.cs deleted file mode 100644 index 7a3f789e4f..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/HtmlTargetElementAttribute.cs +++ /dev/null @@ -1,85 +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; -using Microsoft.AspNet.Razor.Compilation.TagHelpers; - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// Provides an 's target. - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] - public sealed class HtmlTargetElementAttribute : Attribute - { - public const string ElementCatchAllTarget = TagHelperDescriptorProvider.ElementCatchAllTarget; - - /// - /// Instantiates a new instance of the class that targets all HTML - /// elements with the required . - /// - /// is set to *. - public HtmlTargetElementAttribute() - : this(ElementCatchAllTarget) - { - } - - /// - /// Instantiates a new instance of the class with the given - /// as its value. - /// - /// - /// The HTML tag the targets. - /// - /// A * value indicates this - /// targets all HTML elements with the required . - public HtmlTargetElementAttribute(string tag) - { - Tag = tag; - } - - /// - /// The HTML tag the targets. A * value indicates this - /// targets all HTML elements with the required . - /// - public string Tag { get; } - - /// - /// A comma-separated of attribute names the HTML element must contain for the - /// to run. * at the end of an attribute name acts as a prefix match. - /// - public string Attributes { get; set; } - - /// - /// The expected tag structure. Defaults to . - /// - /// - /// If and no other tag helpers applying to the same element specify - /// their the behavior is used: - /// - /// - /// <my-tag-helper></my-tag-helper> - /// <!-- OR --> - /// <my-tag-helper /> - /// - /// Otherwise, if another tag helper applying to the same element does specify their behavior, that behavior - /// is used. - /// - /// - /// If HTML elements can be written in the following formats: - /// - /// <my-tag-helper> - /// <!-- OR --> - /// <my-tag-helper /> - /// - /// - /// - public TagStructure TagStructure { get; set; } - - /// - /// The required HTML element name of the direct parent. A null value indicates any HTML element name is - /// allowed. - /// - public string ParentTag { get; set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/IReadOnlyTagHelperAttribute.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/IReadOnlyTagHelperAttribute.cs deleted file mode 100644 index 5b7148b80c..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/IReadOnlyTagHelperAttribute.cs +++ /dev/null @@ -1,29 +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.AspNet.Razor.TagHelpers -{ - /// - /// A read-only HTML tag helper attribute. - /// - public interface IReadOnlyTagHelperAttribute : IEquatable - { - /// - /// Gets the name of the attribute. - /// - string Name { get; } - - /// - /// Gets the value of the attribute. - /// - object Value { get; } - - /// - /// Gets an indication whether the attribute is minimized or not. - /// - /// If true, will be ignored. - bool Minimized { get; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/ITagHelper.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/ITagHelper.cs deleted file mode 100644 index 5cb6151f22..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/ITagHelper.cs +++ /dev/null @@ -1,41 +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.Threading.Tasks; - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// Contract used to filter matching HTML elements. - /// - public interface ITagHelper - { - /// - /// When a set of s are executed, their's - /// are first invoked in the specified ; then their - /// 's are invoked in the specified - /// . Lower values are executed first. - /// - int Order { get; } - - /// - /// Initializes the with the given . Additions to - /// should be done within this method to ensure they're added prior to - /// executing the children. - /// - /// Contains information associated with the current HTML tag. - /// When more than one runs on the same element, - /// may be invoked prior to . - /// - void Init(TagHelperContext context); - - /// - /// Asynchronously executes the with the given and - /// . - /// - /// Contains information associated with the current HTML tag. - /// A stateful HTML element used to generate an HTML tag. - /// A that on completion updates the . - Task ProcessAsync(TagHelperContext context, TagHelperOutput output); - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/OutputElementHintAttribute.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/OutputElementHintAttribute.cs deleted file mode 100644 index a7cae8fd69..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/OutputElementHintAttribute.cs +++ /dev/null @@ -1,35 +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.AspNet.Razor.TagHelpers -{ - /// - /// Provides a hint of the 's output element. - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] - public sealed class OutputElementHintAttribute : Attribute - { - /// - /// Instantiates a new instance of the class. - /// - /// - /// The HTML element the may output. - /// - public OutputElementHintAttribute(string outputElement) - { - if (outputElement == null) - { - throw new ArgumentNullException(nameof(outputElement)); - } - - OutputElement = outputElement; - } - - /// - /// The HTML element the may output. - /// - public string OutputElement { get; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/ReadOnlyTagHelperAttributeList.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/ReadOnlyTagHelperAttributeList.cs deleted file mode 100644 index 19694da295..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/ReadOnlyTagHelperAttributeList.cs +++ /dev/null @@ -1,235 +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; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// A read-only collection of s. - /// - /// - /// The type of s in the collection. - /// - public class ReadOnlyTagHelperAttributeList : IReadOnlyList - where TAttribute : IReadOnlyTagHelperAttribute - { - /// - /// Instantiates a new instance of with an empty - /// collection. - /// - protected ReadOnlyTagHelperAttributeList() - { - Attributes = new List(); - } - - /// - /// Instantiates a new instance of with the specified - /// . - /// - /// The collection to wrap. - public ReadOnlyTagHelperAttributeList(IEnumerable attributes) - { - if (attributes == null) - { - throw new ArgumentNullException(nameof(attributes)); - } - - Attributes = new List(attributes); - } - - /// - /// The underlying collection of s. - /// - /// Intended for use in a non-read-only subclass. Changes to this will - /// affect all getters that provides. - protected List Attributes { get; } - - /// - public TAttribute this[int index] - { - get - { - return Attributes[index]; - } - } - - /// - /// Gets the first with - /// matching . - /// - /// - /// The of the to get. - /// - /// The first with - /// matching . - /// - /// is compared case-insensitively. - public TAttribute this[string name] - { - get - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - return Attributes.FirstOrDefault(attribute => NameEquals(name, attribute)); - } - } - - /// - public int Count - { - get - { - return Attributes.Count; - } - } - - /// - /// Determines whether a matching exists in the - /// collection. - /// - /// The to locate. - /// - /// true if an matching exists in the - /// collection; otherwise, false. - /// - /// - /// s is compared case-insensitively. - /// - public bool Contains(TAttribute item) - { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } - - return Attributes.Contains(item); - } - - /// - /// Determines whether a with the same - /// exists in the collection. - /// - /// The of the - /// to get. - /// - /// true if a with the same - /// exists in the collection; otherwise, false. - /// - /// is compared case-insensitively. - public bool ContainsName(string name) - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - return Attributes.Any(attribute => NameEquals(name, attribute)); - } - - /// - /// Searches for a matching in the collection and - /// returns the zero-based index of the first occurrence. - /// - /// The to locate. - /// The zero-based index of the first occurrence of a matching - /// in the collection, if found; otherwise, –1. - /// - /// s is compared case-insensitively. - /// - public int IndexOf(TAttribute item) - { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } - - return Attributes.IndexOf(item); - } - - /// - /// Retrieves the first with - /// matching . - /// - /// The of the - /// to get. - /// When this method returns, the first with - /// matching , if found; otherwise, - /// null. - /// true if a with the same - /// exists in the collection; otherwise, false. - /// is compared case-insensitively. - public bool TryGetAttribute(string name, out TAttribute attribute) - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - attribute = Attributes.FirstOrDefault(attr => NameEquals(name, attr)); - - return attribute != null; - } - - /// - /// Retrieves s in the collection with - /// matching . - /// - /// The of the - /// s to get. - /// When this method returns, the s with - /// matching , if at least one is - /// found; otherwise, null. - /// true if at least one with the same - /// exists in the collection; otherwise, false. - /// is compared case-insensitively. - public bool TryGetAttributes(string name, out IEnumerable attributes) - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - attributes = Attributes.Where(attribute => NameEquals(name, attribute)); - - return attributes.Any(); - } - - /// - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - /// - public IEnumerator GetEnumerator() - { - return Attributes.GetEnumerator(); - } - - /// - /// Determines if the specified has the same name as . - /// - /// The value to compare against s - /// . - /// The attribute to compare against. - /// true if case-insensitively matches s - /// . - protected static bool NameEquals(string name, TAttribute attribute) - { - if (attribute == null) - { - throw new ArgumentNullException(nameof(attribute)); - } - - return string.Equals(name, attribute.Name, StringComparison.OrdinalIgnoreCase); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/RestrictChildrenAttribute.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/RestrictChildrenAttribute.cs deleted file mode 100644 index 7f0626c134..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/RestrictChildrenAttribute.cs +++ /dev/null @@ -1,42 +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; -using System.Collections.Generic; - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// Restricts children of the 's element. - /// - /// Combining this attribute with a that specifies its - /// as will result - /// in this attribute being ignored. - [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] - public class RestrictChildrenAttribute : Attribute - { - /// - /// Instantiates a new instance of the class. - /// - /// - /// The tag name of an element allowed as a child. - /// - /// - /// Additional names of elements allowed as children. - /// - public RestrictChildrenAttribute(string childTag, params string[] childTags) - { - var concatenatedNames = new string[1 + childTags.Length]; - concatenatedNames[0] = childTag; - - childTags.CopyTo(concatenatedNames, 1); - - ChildTags = concatenatedNames; - } - - /// - /// Get the names of elements allowed as children. - /// - public IEnumerable ChildTags { get; } - } -} diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelper.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelper.cs deleted file mode 100644 index 267a243deb..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelper.cs +++ /dev/null @@ -1,47 +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.Threading.Tasks; - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// Class used to filter matching HTML elements. - /// - public abstract class TagHelper : ITagHelper - { - /// - /// Default order is 0. - public virtual int Order { get; } = 0; - - /// - public virtual void Init(TagHelperContext context) - { - } - - /// - /// Synchronously executes the with the given and - /// . - /// - /// Contains information associated with the current HTML tag. - /// A stateful HTML element used to generate an HTML tag. - public virtual void Process(TagHelperContext context, TagHelperOutput output) - { - } - - /// - /// Asynchronously executes the with the given and - /// . - /// - /// Contains information associated with the current HTML tag. - /// A stateful HTML element used to generate an HTML tag. - /// A that on completion updates the . - /// By default this calls into .. -#pragma warning disable 1998 - public virtual async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) - { - Process(context, output); - } -#pragma warning restore 1998 - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperAttribute.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperAttribute.cs deleted file mode 100644 index 9262bbe790..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperAttribute.cs +++ /dev/null @@ -1,104 +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.AspNet.Razor.TagHelpers -{ - /// - /// An HTML tag helper attribute. - /// - public class TagHelperAttribute : IReadOnlyTagHelperAttribute - { - private static readonly int TypeHashCode = typeof(TagHelperAttribute).GetHashCode(); - - /// - /// Instantiates a new instance of . - /// - public TagHelperAttribute() - { - } - - /// - /// Instantiates a new instance of with values provided by the given - /// . - /// - /// A whose values should be copied. - public TagHelperAttribute(IReadOnlyTagHelperAttribute attribute) - : this(attribute?.Name, attribute?.Value) - { - if (attribute == null) - { - throw new ArgumentNullException(nameof(attribute)); - } - - Minimized = attribute.Minimized; - } - - /// - /// Instantiates a new instance of with the specified - /// and . - /// - /// The of the attribute. - /// The of the attribute. - public TagHelperAttribute(string name, object value) - { - Name = name; - Value = value; - } - - /// - /// Gets or sets the name of the attribute. - /// - public string Name { get; set; } - - /// - /// Gets or sets the value of the attribute. - /// - public object Value { get; set; } - - /// - /// Gets or sets an indication whether the attribute is minimized or not. - /// - /// If true, will be ignored. - public bool Minimized { get; set; } - - /// - /// Converts the specified into a . - /// - /// The of the created . - /// Created s is set to null. - public static implicit operator TagHelperAttribute(string value) - { - return new TagHelperAttribute - { - Value = value - }; - } - - /// - /// is compared case-insensitively. - public bool Equals(IReadOnlyTagHelperAttribute other) - { - return - other != null && - string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase) && - Minimized == other.Minimized && - (Minimized || Equals(Value, other.Value)); - } - - /// - public override bool Equals(object obj) - { - var other = obj as IReadOnlyTagHelperAttribute; - - return Equals(other); - } - - /// - public override int GetHashCode() - { - return TypeHashCode; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperAttributeList.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperAttributeList.cs deleted file mode 100644 index a98971701d..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperAttributeList.cs +++ /dev/null @@ -1,292 +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; -using System.Collections.Generic; -using Microsoft.AspNet.Razor.Runtime; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// A collection of s. - /// - public class TagHelperAttributeList : ReadOnlyTagHelperAttributeList, IList - { - /// - /// Instantiates a new instance of with an empty collection. - /// - public TagHelperAttributeList() - : base() - { - } - - /// - /// Instantiates a new instance of with the specified - /// . - /// - /// The collection to wrap. - public TagHelperAttributeList(IEnumerable attributes) - : base(attributes) - { - if (attributes == null) - { - throw new ArgumentNullException(nameof(attributes)); - } - } - - /// - /// - /// 's must not be null. - /// - public new TagHelperAttribute this[int index] - { - get - { - return base[index]; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - if (value.Name == null) - { - throw new ArgumentException( - Resources.FormatTagHelperAttributeList_CannotAddWithNullName( - typeof(TagHelperAttribute).FullName, - nameof(TagHelperAttribute.Name)), - nameof(value)); - } - - Attributes[index] = value; - } - } - - /// - /// Gets the first with matching - /// . When setting, replaces the first matching - /// with the specified and removes any additional - /// matching s. If a matching is not found, - /// adds the specified to the end of the collection. - /// - /// - /// The of the to get or set. - /// - /// The first with matching - /// . - /// - /// is compared case-insensitively. When setting, - /// s must be null or - /// case-insensitively match the specified . - /// - /// - /// var attributes = new TagHelperAttributeList(); - /// - /// // Will "value" be converted to a TagHelperAttribute with a null Name - /// attributes["name"] = "value"; - /// - /// // TagHelperAttribute.Name must match the specified name. - /// attributes["name"] = new TagHelperAttribute("name", "value"); - /// - /// - public new TagHelperAttribute this[string name] - { - get - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - return base[name]; - } - set - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - // Name will be null if user attempts to set the attribute via an implicit conversion: - // output.Attributes["someName"] = "someValue" - if (value.Name == null) - { - value.Name = name; - } - else if (!NameEquals(name, value)) - { - throw new ArgumentException( - Resources.FormatTagHelperAttributeList_CannotAddAttribute( - nameof(TagHelperAttribute), - nameof(TagHelperAttribute.Name), - value.Name, - name), - nameof(name)); - } - - var attributeReplaced = false; - - for (var i = 0; i < Attributes.Count; i++) - { - if (NameEquals(name, Attributes[i])) - { - // We replace the first attribute with the provided value, remove all the rest. - if (!attributeReplaced) - { - // We replace the first attribute we find with the same name. - Attributes[i] = value; - attributeReplaced = true; - } - else - { - Attributes.RemoveAt(i--); - } - } - } - - // If we didn't replace an attribute value we should add value to the end of the collection. - if (!attributeReplaced) - { - Add(value); - } - } - } - - /// - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - /// - /// Adds a to the end of the collection with the specified - /// and . - /// - /// The of the attribute to add. - /// The of the attribute to add. - public void Add(string name, object value) - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - Attributes.Add(new TagHelperAttribute(name, value)); - } - - /// - /// - /// 's must not be null. - /// - public void Add(TagHelperAttribute attribute) - { - if (attribute == null) - { - throw new ArgumentNullException(nameof(attribute)); - } - - if (attribute.Name == null) - { - throw new ArgumentException( - Resources.FormatTagHelperAttributeList_CannotAddWithNullName( - typeof(TagHelperAttribute).FullName, - nameof(TagHelperAttribute.Name)), - nameof(attribute)); - } - - Attributes.Add(attribute); - } - - /// - /// - /// 's must not be null. - /// - public void Insert(int index, TagHelperAttribute attribute) - { - if (attribute == null) - { - throw new ArgumentNullException(nameof(attribute)); - } - - if (attribute.Name == null) - { - throw new ArgumentException( - Resources.FormatTagHelperAttributeList_CannotAddWithNullName( - typeof(TagHelperAttribute).FullName, - nameof(TagHelperAttribute.Name)), - nameof(attribute)); - } - - Attributes.Insert(index, attribute); - } - - /// - public void CopyTo(TagHelperAttribute[] array, int index) - { - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - - Attributes.CopyTo(array, index); - } - - /// - /// - /// s is compared case-insensitively. - /// - public bool Remove(TagHelperAttribute attribute) - { - if (attribute == null) - { - throw new ArgumentNullException(nameof(attribute)); - } - - return Attributes.Remove(attribute); - } - - /// - public void RemoveAt(int index) - { - Attributes.RemoveAt(index); - } - - /// - /// Removes all s with matching - /// . - /// - /// - /// The of s to remove. - /// - /// - /// true if at least 1 was removed; otherwise, false. - /// - /// is compared case-insensitively. - public bool RemoveAll(string name) - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - return Attributes.RemoveAll(attribute => NameEquals(name, attribute)) > 0; - } - - /// - public void Clear() - { - Attributes.Clear(); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperContent.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperContent.cs deleted file mode 100644 index 8fe406274f..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperContent.cs +++ /dev/null @@ -1,171 +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; -using System.IO; -using Microsoft.AspNet.Html.Abstractions; -using Microsoft.Extensions.WebEncoders; - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// Abstract class used to buffer content returned by s. - /// - public abstract class TagHelperContent : IHtmlContentBuilder - { - /// - /// Gets a value indicating whether the content was modifed. - /// - public abstract bool IsModified { get; } - - /// - /// Gets a value indicating whether the content is empty. - /// - public abstract bool IsEmpty { get; } - - /// - /// Gets a value indicating whether the content is whitespace. - /// - public abstract bool IsWhiteSpace { get; } - - /// - /// Sets the content. - /// - /// The that replaces the content. - /// A reference to this instance after the set operation has completed. - public TagHelperContent SetContent(IHtmlContent htmlContent) - { - HtmlContentBuilderExtensions.SetContent(this, htmlContent); - return this; - } - - /// - /// Sets the content. - /// - /// - /// The that replaces the content. The value is assume to be unencoded - /// as-provided and will be HTML encoded before being written. - /// - /// A reference to this instance after the set operation has completed. - public TagHelperContent SetContent(string unencoded) - { - HtmlContentBuilderExtensions.SetContent(this, unencoded); - return this; - } - - /// - /// Sets the content. - /// - /// - /// The that replaces the content. The value is assume to be HTML encoded - /// as-provided and no further encoding will be performed. - /// - /// A reference to this instance after the set operation has completed. - public TagHelperContent SetHtmlContent(string encoded) - { - HtmlContentBuilderExtensions.SetHtmlContent(this, encoded); - return this; - } - - /// - /// Appends to the existing content. - /// - /// The to be appended. - /// A reference to this instance after the append operation has completed. - public abstract TagHelperContent Append(string unencoded); - - /// - /// Appends to the existing content. - /// - /// The to be appended. - /// A reference to this instance after the append operation has completed. - public abstract TagHelperContent Append(IHtmlContent htmlContent); - - /// - /// Appends to the existing content. is assumed - /// to be an HTML encoded and no further encoding will be performed. - /// - /// The to be appended. - /// A reference to this instance after the append operation has completed. - public abstract TagHelperContent AppendHtml(string encoded); - - /// - /// Appends the specified to the existing content after - /// replacing each format item with the HTML encoded representation of the - /// corresponding item in the array. - /// - /// - /// The composite format (see http://msdn.microsoft.com/en-us/library/txafckwd.aspx). - /// - /// The object array to format. - /// A reference to this instance after the append operation has completed. - public TagHelperContent AppendFormat(string format, params object[] args) - { - HtmlContentBuilderExtensions.AppendFormat(this, null, format, args); - return this; - } - - /// - /// Appends the specified to the existing content with information from the - /// after replacing each format item with the HTML encoded - /// representation of the corresponding item in the array. - /// - /// An object that supplies culture-specific formatting information. - /// - /// The composite format (see http://msdn.microsoft.com/en-us/library/txafckwd.aspx). - /// - /// The object array to format. - /// A reference to this instance after the append operation has completed. - public TagHelperContent AppendFormat(IFormatProvider provider, string format, params object[] args) - { - HtmlContentBuilderExtensions.AppendFormat(this, provider, format, args); - return this; - } - - /// - /// Clears the content. - /// - /// A reference to this instance after the clear operation has completed. - public abstract TagHelperContent Clear(); - - /// - /// Gets the content. - /// - /// A containing the content. - public abstract string GetContent(); - - /// - /// Gets the content. - /// - /// The . - /// A containing the content. - public abstract string GetContent(IHtmlEncoder encoder); - - /// - public abstract void WriteTo(TextWriter writer, IHtmlEncoder encoder); - - /// - IHtmlContentBuilder IHtmlContentBuilder.Append(IHtmlContent content) - { - return Append(content); - } - - /// - IHtmlContentBuilder IHtmlContentBuilder.Append(string unencoded) - { - return Append(unencoded); - } - - /// - IHtmlContentBuilder IHtmlContentBuilder.AppendHtml(string encoded) - { - return AppendHtml(encoded); - } - - /// - IHtmlContentBuilder IHtmlContentBuilder.Clear() - { - return Clear(); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperContext.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperContext.cs deleted file mode 100644 index 272ec5a48c..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperContext.cs +++ /dev/null @@ -1,67 +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; -using System.Collections.Generic; -using System.Linq; - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// Contains information related to the execution of s. - /// - public class TagHelperContext - { - /// - /// Instantiates a new . - /// - /// Every attribute associated with the current HTML element. - /// Collection of items used to communicate with other s. - /// The unique identifier for the source element this - /// applies to. - public TagHelperContext( - IEnumerable allAttributes, - IDictionary items, - string uniqueId) - { - if (allAttributes == null) - { - throw new ArgumentNullException(nameof(allAttributes)); - } - - if (items == null) - { - throw new ArgumentNullException(nameof(items)); - } - - if (uniqueId == null) - { - throw new ArgumentNullException(nameof(uniqueId)); - } - - AllAttributes = new ReadOnlyTagHelperAttributeList( - allAttributes.Select(attribute => new TagHelperAttribute(attribute.Name, attribute.Value))); - Items = items; - UniqueId = uniqueId; - } - - /// - /// Every attribute associated with the current HTML element. - /// - public ReadOnlyTagHelperAttributeList AllAttributes { get; } - - /// - /// Gets the collection of items used to communicate with other s. - /// - /// - /// This is copy-on-write in order to ensure items added to this - /// collection are visible only to other s targeting child elements. - /// - public IDictionary Items { get; } - - /// - /// An identifier unique to the HTML element this context is for. - /// - public string UniqueId { get; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperOutput.cs b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperOutput.cs deleted file mode 100644 index af8eca767c..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/TagHelpers/TagHelperOutput.cs +++ /dev/null @@ -1,155 +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; -using System.Threading.Tasks; - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// Class used to represent the output of an . - /// - public class TagHelperOutput - { - private readonly Func> _getChildContentAsync; - - // Internal for testing - internal TagHelperOutput(string tagName) - : this( - tagName, - new TagHelperAttributeList(), - (cachedResult) => Task.FromResult(new DefaultTagHelperContent())) - { - } - - /// - /// Instantiates a new instance of . - /// - /// The HTML element's tag name. - /// The HTML attributes. - /// A delegate used to execute and retrieve the rendered child content - /// asynchronously. - public TagHelperOutput( - string tagName, - TagHelperAttributeList attributes, - Func> getChildContentAsync) - { - if (attributes == null) - { - throw new ArgumentNullException(nameof(attributes)); - } - - if (getChildContentAsync == null) - { - throw new ArgumentNullException(nameof(getChildContentAsync)); - } - - TagName = tagName; - Attributes = new TagHelperAttributeList(attributes); - _getChildContentAsync = getChildContentAsync; - } - - /// - /// The HTML element's tag name. - /// - /// - /// A whitespace or null value results in no start or end tag being rendered. - /// - public string TagName { get; set; } - - /// - /// Content that precedes the HTML element. - /// - /// Value is rendered before the HTML element. - public TagHelperContent PreElement { get; } = new DefaultTagHelperContent(); - - /// - /// The HTML element's pre content. - /// - /// Value is prepended to the 's final output. - public TagHelperContent PreContent { get; } = new DefaultTagHelperContent(); - - /// - /// The HTML element's main content. - /// - /// Value occurs in the 's final output after and - /// before - public TagHelperContent Content { get; } = new DefaultTagHelperContent(); - - /// - /// The HTML element's post content. - /// - /// Value is appended to the 's final output. - public TagHelperContent PostContent { get; } = new DefaultTagHelperContent(); - - /// - /// Content that follows the HTML element. - /// - /// Value is rendered after the HTML element. - public TagHelperContent PostElement { get; } = new DefaultTagHelperContent(); - - /// - /// true if has been set, false otherwise. - /// - public bool IsContentModified - { - get - { - return Content.IsModified; - } - } - - /// - /// Syntax of the element in the generated HTML. - /// - public TagMode TagMode { get; set; } - - /// - /// The HTML element's attributes. - /// - /// - /// MVC will HTML encode values when generating the start tag. It will not HTML encode - /// a Microsoft.AspNet.Mvc.Rendering.HtmlString instance. MVC converts most other types to a - /// , then HTML encodes the result. - /// - public TagHelperAttributeList Attributes { get; } - - /// - /// Changes to generate nothing. - /// - /// - /// Sets to null, and clears , , - /// , , and to suppress output. - /// - public void SuppressOutput() - { - TagName = null; - PreElement.Clear(); - PreContent.Clear(); - Content.Clear(); - PostContent.Clear(); - PostElement.Clear(); - } - - /// - /// A delegate used to execute children asynchronously. - /// - /// A that on completion returns content rendered by children. - /// This method is memoized. - public Task GetChildContentAsync() - { - return GetChildContentAsync(useCachedResult: true); - } - - /// - /// A delegate used to execute children asynchronously. - /// - /// If true multiple calls to this method will not cause re-execution - /// of child content; cached content will be returned. - /// A that on completion returns content rendered by children. - public Task GetChildContentAsync(bool useCachedResult) - { - return _getChildContentAsync(useCachedResult); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/project.json b/src/Microsoft.AspNet.Razor.Runtime.VSRC1/project.json deleted file mode 100644 index 76d4709f4c..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.VSRC1/project.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "description": "Runtime components for rendering Razor pages.", - "version": "4.0.0-rc1-final", - "buildOptions": { - "warningsAsErrors": true, - "keyFile": "../../tools/Key.snk" - }, - "packOptions": { - "repository": { - "type": "git", - "url": "git://github.com/aspnet/razor" - } - }, - "dependencies": { - "Microsoft.AspNet.Html.Abstractions": "1.0.0-rc1-final", - "Microsoft.AspNet.Razor.VSRC1": "4.0.0-rc1-final" - }, - "frameworks": { - "net451": { - "frameworkAssemblies": { - "System.Xml": "4.0.0.0", - "System.Xml.Linq": "4.0.0.0" - } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CSharpRazorCodeLanguage.cs b/src/Microsoft.AspNet.Razor.VSRC1/CSharpRazorCodeLanguage.cs deleted file mode 100644 index 7c48b45c85..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CSharpRazorCodeLanguage.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 Microsoft.AspNet.Razor.Chunks.Generators; -using Microsoft.AspNet.Razor.CodeGenerators; -using Microsoft.AspNet.Razor.Parser; -#if NET451 - -#endif - -namespace Microsoft.AspNet.Razor -{ - /// - /// Defines the C# Code Language for Razor - /// - public class CSharpRazorCodeLanguage : RazorCodeLanguage - { - private const string CSharpLanguageName = "csharp"; - - /// - /// Returns the name of the language: "csharp" - /// - public override string LanguageName - { - get { return CSharpLanguageName; } - } - - /// - /// Constructs a new instance of the code parser for this language - /// - public override ParserBase CreateCodeParser() - { - return new CSharpCodeParser(); - } - - /// - /// Constructs a new instance of the chunk generator for this language with the specified settings - /// - public override RazorChunkGenerator CreateChunkGenerator( - string className, - string rootNamespaceName, - string sourceFileName, - RazorEngineHost host) - { - return new RazorChunkGenerator(className, rootNamespaceName, sourceFileName, host); - } - - public override CodeGenerator CreateCodeGenerator(CodeGeneratorContext context) - { - return new CSharpCodeGenerator(context); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/AddTagHelperChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/AddTagHelperChunk.cs deleted file mode 100644 index cd10865d85..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/AddTagHelperChunk.cs +++ /dev/null @@ -1,16 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - /// - /// A used to look up s. - /// - public class AddTagHelperChunk : Chunk - { - /// - /// Text used to look up s. - /// - public string LookupText { get; set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Chunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Chunk.cs deleted file mode 100644 index b63733bc99..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Chunk.cs +++ /dev/null @@ -1,13 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class Chunk - { - public SourceLocation Start { get; set; } - public SyntaxTreeNode Association { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ChunkTree.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ChunkTree.cs deleted file mode 100644 index 8d45935c3c..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ChunkTree.cs +++ /dev/null @@ -1,17 +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.Collections.Generic; - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class ChunkTree - { - public ChunkTree() - { - Chunks = new List(); - } - - public IList Chunks { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ChunkTreeBuilder.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ChunkTreeBuilder.cs deleted file mode 100644 index fe828e4752..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ChunkTreeBuilder.cs +++ /dev/null @@ -1,169 +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.Collections.Generic; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class ChunkTreeBuilder - { - private readonly Stack _parentStack; - private Chunk _lastChunk; - - public ChunkTreeBuilder() - { - ChunkTree = new ChunkTree(); - _parentStack = new Stack(); - } - - public ChunkTree ChunkTree { get; private set; } - - public void AddChunk(Chunk chunk, SyntaxTreeNode association, bool topLevel = false) - { - _lastChunk = chunk; - - chunk.Start = association.Start; - chunk.Association = association; - - // If we're not in the middle of a parent chunk - if (_parentStack.Count == 0 || topLevel == true) - { - ChunkTree.Chunks.Add(chunk); - } - else - { - _parentStack.Peek().Children.Add(chunk); - } - } - - public void AddTagHelperPrefixDirectiveChunk(string prefix, SyntaxTreeNode association) - { - AddChunk( - new TagHelperPrefixDirectiveChunk - { - Prefix = prefix - }, - association, - topLevel: true); - } - - public void AddAddTagHelperChunk(string lookupText, SyntaxTreeNode association) - { - AddChunk(new AddTagHelperChunk - { - LookupText = lookupText - }, association, topLevel: true); - } - - public void AddRemoveTagHelperChunk(string lookupText, SyntaxTreeNode association) - { - AddChunk(new RemoveTagHelperChunk - { - LookupText = lookupText - }, association, topLevel: true); - } - - public void AddLiteralChunk(string literal, SyntaxTreeNode association) - { - // If the previous chunk was also a LiteralChunk, append the content of the current node to the previous one. - var literalChunk = _lastChunk as LiteralChunk; - if (literalChunk != null) - { - // Literal chunks are always associated with Spans - var lastSpan = (Span)literalChunk.Association; - var currentSpan = (Span)association; - - var builder = new SpanBuilder(lastSpan); - foreach (var symbol in currentSpan.Symbols) - { - builder.Accept(symbol); - } - - literalChunk.Association = builder.Build(); - literalChunk.Text += literal; - } - else - { - AddChunk(new LiteralChunk - { - Text = literal, - }, association); - } - } - - public void AddExpressionChunk(string expression, SyntaxTreeNode association) - { - AddChunk(new ExpressionChunk - { - Code = expression - }, association); - } - - public void AddStatementChunk(string code, SyntaxTreeNode association) - { - AddChunk(new StatementChunk - { - Code = code, - }, association); - } - - public void AddUsingChunk(string usingNamespace, SyntaxTreeNode association) - { - AddChunk(new UsingChunk - { - Namespace = usingNamespace, - }, association, topLevel: true); - } - - public void AddTypeMemberChunk(string code, SyntaxTreeNode association) - { - AddChunk(new TypeMemberChunk - { - Code = code, - }, association, topLevel: true); - } - - public void AddLiteralCodeAttributeChunk(string code, SyntaxTreeNode association) - { - AddChunk(new LiteralCodeAttributeChunk - { - Code = code, - }, association); - } - - public void AddSetBaseTypeChunk(string typeName, SyntaxTreeNode association) - { - AddChunk(new SetBaseTypeChunk - { - TypeName = typeName.Trim() - }, association, topLevel: true); - } - - public T StartParentChunk(SyntaxTreeNode association) where T : ParentChunk, new() - { - return StartParentChunk(association, topLevel: false); - } - - public T StartParentChunk(SyntaxTreeNode association, bool topLevel) where T : ParentChunk, new() - { - var parentChunk = new T(); - - return StartParentChunk(parentChunk, association, topLevel); - } - - public T StartParentChunk(T parentChunk, SyntaxTreeNode association, bool topLevel) where T : ParentChunk - { - AddChunk(parentChunk, association, topLevel); - - _parentStack.Push(parentChunk); - - return parentChunk; - } - - public void EndParentChunk() - { - _lastChunk = _parentStack.Pop(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/CodeAttributeChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/CodeAttributeChunk.cs deleted file mode 100644 index cecd46ce19..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/CodeAttributeChunk.cs +++ /dev/null @@ -1,14 +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 Microsoft.AspNet.Razor.Text; - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class CodeAttributeChunk : ParentChunk - { - public string Attribute { get; set; } - public LocationTagged Prefix { get; set; } - public LocationTagged Suffix { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/DynamicCodeAttributeChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/DynamicCodeAttributeChunk.cs deleted file mode 100644 index 54c0092c02..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/DynamicCodeAttributeChunk.cs +++ /dev/null @@ -1,12 +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 Microsoft.AspNet.Razor.Text; - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class DynamicCodeAttributeChunk : ParentChunk - { - public LocationTagged Prefix { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ExpressionBlockChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ExpressionBlockChunk.cs deleted file mode 100644 index dc6dc0bc8a..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ExpressionBlockChunk.cs +++ /dev/null @@ -1,9 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class ExpressionBlockChunk : ParentChunk - { - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ExpressionChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ExpressionChunk.cs deleted file mode 100644 index c783151248..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ExpressionChunk.cs +++ /dev/null @@ -1,15 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class ExpressionChunk : Chunk - { - public string Code { get; set; } - - public override string ToString() - { - return Start + " = " + Code; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/AddImportChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/AddImportChunkGenerator.cs deleted file mode 100644 index 27d1ba712a..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/AddImportChunkGenerator.cs +++ /dev/null @@ -1,48 +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; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class AddImportChunkGenerator : SpanChunkGenerator - { - public AddImportChunkGenerator(string ns) - { - Namespace = ns; - } - - public string Namespace { get; } - - public override void GenerateChunk(Span target, ChunkGeneratorContext context) - { - var ns = Namespace; - - if (!string.IsNullOrEmpty(ns) && char.IsWhiteSpace(ns[0])) - { - ns = ns.Substring(1); - } - - context.ChunkTreeBuilder.AddUsingChunk(ns, target); - } - - public override string ToString() - { - return "Import:" + Namespace + ";"; - } - - public override bool Equals(object obj) - { - var other = obj as AddImportChunkGenerator; - return other != null && - string.Equals(Namespace, other.Namespace, StringComparison.Ordinal); - } - - public override int GetHashCode() - { - // Hash code should include only immutable properties. - return Namespace == null ? 0 : StringComparer.Ordinal.GetHashCode(Namespace); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/AddOrRemoveTagHelperChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/AddOrRemoveTagHelperChunkGenerator.cs deleted file mode 100644 index bfc64a4ebf..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/AddOrRemoveTagHelperChunkGenerator.cs +++ /dev/null @@ -1,60 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - /// - /// A responsible for generating s and - /// s. - /// - public class AddOrRemoveTagHelperChunkGenerator : SpanChunkGenerator - { - /// - /// Instantiates a new . - /// - /// - /// Text used to look up s that should be added or removed. - /// - public AddOrRemoveTagHelperChunkGenerator(bool removeTagHelperDescriptors, string lookupText) - { - RemoveTagHelperDescriptors = removeTagHelperDescriptors; - LookupText = lookupText; - } - - /// - /// Gets the text used to look up s that should be added to or - /// removed from the Razor page. - /// - public string LookupText { get; } - - /// - /// Whether we want to remove s from the Razor page. - /// - /// If true generates s, - /// s otherwise. - public bool RemoveTagHelperDescriptors { get; } - - /// - /// Generates s if is - /// true, otherwise s are generated. - /// - /// - /// The responsible for this . - /// - /// A instance that contains information about - /// the current chunk generation process. - public override void GenerateChunk(Span target, ChunkGeneratorContext context) - { - if (RemoveTagHelperDescriptors) - { - context.ChunkTreeBuilder.AddRemoveTagHelperChunk(LookupText, target); - } - else - { - context.ChunkTreeBuilder.AddAddTagHelperChunk(LookupText, target); - } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/AttributeBlockChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/AttributeBlockChunkGenerator.cs deleted file mode 100644 index 9469fb35b1..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/AttributeBlockChunkGenerator.cs +++ /dev/null @@ -1,65 +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; -using System.Globalization; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Text; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class AttributeBlockChunkGenerator : ParentChunkGenerator - { - public AttributeBlockChunkGenerator(string name, LocationTagged prefix, LocationTagged suffix) - { - Name = name; - Prefix = prefix; - Suffix = suffix; - } - - public string Name { get; } - - public LocationTagged Prefix { get; } - - public LocationTagged Suffix { get; } - - public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context) - { - var chunk = context.ChunkTreeBuilder.StartParentChunk(target); - - chunk.Attribute = Name; - chunk.Prefix = Prefix; - chunk.Suffix = Suffix; - } - - public override void GenerateEndParentChunk(Block target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.EndParentChunk(); - } - - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "Attr:{0},{1:F},{2:F}", Name, Prefix, Suffix); - } - - public override bool Equals(object obj) - { - var other = obj as AttributeBlockChunkGenerator; - return other != null && - string.Equals(other.Name, Name, StringComparison.Ordinal) && - Equals(other.Prefix, Prefix) && - Equals(other.Suffix, Suffix); - } - - public override int GetHashCode() - { - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(Name, StringComparer.Ordinal); - hashCodeCombiner.Add(Prefix); - hashCodeCombiner.Add(Suffix); - - return hashCodeCombiner; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ChunkGeneratorContext.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ChunkGeneratorContext.cs deleted file mode 100644 index 95ff4493f8..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ChunkGeneratorContext.cs +++ /dev/null @@ -1,44 +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. - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class ChunkGeneratorContext - { - protected ChunkGeneratorContext(ChunkGeneratorContext context) - : this( - context.Host, - context.ClassName, - context.RootNamespace, - context.SourceFile, - // True because we're pulling from the provided context's source file. - shouldGenerateLinePragmas: true) - { - ChunkTreeBuilder = context.ChunkTreeBuilder; - } - - public ChunkGeneratorContext( - RazorEngineHost host, - string className, - string rootNamespace, - string sourceFile, - bool shouldGenerateLinePragmas) - { - ChunkTreeBuilder = new ChunkTreeBuilder(); - Host = host; - SourceFile = shouldGenerateLinePragmas ? sourceFile : null; - RootNamespace = rootNamespace; - ClassName = className; - } - - public string SourceFile { get; internal set; } - - public string RootNamespace { get; } - - public string ClassName { get; } - - public RazorEngineHost Host { get; } - - public ChunkTreeBuilder ChunkTreeBuilder { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/DynamicAttributeBlockChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/DynamicAttributeBlockChunkGenerator.cs deleted file mode 100644 index 05879b6da2..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/DynamicAttributeBlockChunkGenerator.cs +++ /dev/null @@ -1,56 +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.Globalization; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Text; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class DynamicAttributeBlockChunkGenerator : ParentChunkGenerator - { - public DynamicAttributeBlockChunkGenerator(LocationTagged prefix, int offset, int line, int col) - : this(prefix, new SourceLocation(offset, line, col)) - { - } - - public DynamicAttributeBlockChunkGenerator(LocationTagged prefix, SourceLocation valueStart) - { - Prefix = prefix; - ValueStart = valueStart; - } - - public LocationTagged Prefix { get; } - - public SourceLocation ValueStart { get; } - - public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context) - { - var chunk = context.ChunkTreeBuilder.StartParentChunk(target); - chunk.Start = ValueStart; - chunk.Prefix = Prefix; - } - - public override void GenerateEndParentChunk(Block target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.EndParentChunk(); - } - - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "DynAttr:{0:F}", Prefix); - } - - public override bool Equals(object obj) - { - var other = obj as DynamicAttributeBlockChunkGenerator; - return other != null && - Equals(other.Prefix, Prefix); - } - - public override int GetHashCode() - { - return Prefix == null ? 0 : Prefix.GetHashCode(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ExpressionChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ExpressionChunkGenerator.cs deleted file mode 100644 index adfee65da3..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ExpressionChunkGenerator.cs +++ /dev/null @@ -1,43 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class ExpressionChunkGenerator : ISpanChunkGenerator, IParentChunkGenerator - { - private static readonly int TypeHashCode = typeof(ExpressionChunkGenerator).GetHashCode(); - - public void GenerateStartParentChunk(Block target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.StartParentChunk(target); - } - - public void GenerateChunk(Span target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.AddExpressionChunk(target.Content, target); - } - - public void GenerateEndParentChunk(Block target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.EndParentChunk(); - } - - public override string ToString() - { - return "Expr"; - } - - public override bool Equals(object obj) - { - return obj != null && - GetType() == obj.GetType(); - } - - public override int GetHashCode() - { - return TypeHashCode; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/IParentChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/IParentChunkGenerator.cs deleted file mode 100644 index d4a300ba82..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/IParentChunkGenerator.cs +++ /dev/null @@ -1,13 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public interface IParentChunkGenerator - { - void GenerateStartParentChunk(Block target, ChunkGeneratorContext context); - void GenerateEndParentChunk(Block target, ChunkGeneratorContext context); - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ISpanChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ISpanChunkGenerator.cs deleted file mode 100644 index 48fcf0faad..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ISpanChunkGenerator.cs +++ /dev/null @@ -1,12 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public interface ISpanChunkGenerator - { - void GenerateChunk(Span target, ChunkGeneratorContext context); - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/LiteralAttributeChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/LiteralAttributeChunkGenerator.cs deleted file mode 100644 index 71b1b93ef6..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/LiteralAttributeChunkGenerator.cs +++ /dev/null @@ -1,83 +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.Globalization; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Text; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class LiteralAttributeChunkGenerator : SpanChunkGenerator - { - public LiteralAttributeChunkGenerator( - LocationTagged prefix, - LocationTagged valueGenerator) - { - Prefix = prefix; - ValueGenerator = valueGenerator; - } - - public LiteralAttributeChunkGenerator(LocationTagged prefix, LocationTagged value) - { - Prefix = prefix; - Value = value; - } - - public LocationTagged Prefix { get; } - - public LocationTagged Value { get; } - - public LocationTagged ValueGenerator { get; } - - public override void GenerateChunk(Span target, ChunkGeneratorContext context) - { - var chunk = context.ChunkTreeBuilder.StartParentChunk(target); - chunk.Prefix = Prefix; - chunk.Value = Value; - - if (ValueGenerator != null) - { - chunk.ValueLocation = ValueGenerator.Location; - - ValueGenerator.Value.GenerateChunk(target, context); - - chunk.ValueLocation = ValueGenerator.Location; - } - - context.ChunkTreeBuilder.EndParentChunk(); - } - - public override string ToString() - { - if (ValueGenerator == null) - { - return string.Format(CultureInfo.CurrentCulture, "LitAttr:{0:F},{1:F}", Prefix, Value); - } - else - { - return string.Format(CultureInfo.CurrentCulture, "LitAttr:{0:F},", Prefix, ValueGenerator); - } - } - - public override bool Equals(object obj) - { - var other = obj as LiteralAttributeChunkGenerator; - return other != null && - Equals(other.Prefix, Prefix) && - Equals(other.Value, Value) && - Equals(other.ValueGenerator, ValueGenerator); - } - - public override int GetHashCode() - { - var hashCodeCombiner = HashCodeCombiner.Start(); - - hashCodeCombiner.Add(Prefix); - hashCodeCombiner.Add(Value); - hashCodeCombiner.Add(ValueGenerator); - - return hashCodeCombiner; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/MarkupChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/MarkupChunkGenerator.cs deleted file mode 100644 index 26267b29be..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/MarkupChunkGenerator.cs +++ /dev/null @@ -1,20 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class MarkupChunkGenerator : SpanChunkGenerator - { - public override void GenerateChunk(Span target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.AddLiteralChunk(target.Content, target); - } - - public override string ToString() - { - return "Markup"; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ParentChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ParentChunkGenerator.cs deleted file mode 100644 index 54629c6260..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/ParentChunkGenerator.cs +++ /dev/null @@ -1,54 +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.Diagnostics.CodeAnalysis; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public abstract class ParentChunkGenerator : IParentChunkGenerator - { - private static readonly int TypeHashCode = typeof(ParentChunkGenerator).GetHashCode(); - - [SuppressMessage( - "Microsoft.Security", - "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", - Justification = "This class has no instance state")] - public static readonly IParentChunkGenerator Null = new NullParentChunkGenerator(); - - public virtual void GenerateStartParentChunk(Block target, ChunkGeneratorContext context) - { - } - - public virtual void GenerateEndParentChunk(Block target, ChunkGeneratorContext context) - { - } - - public override bool Equals(object obj) - { - return obj != null && - GetType() == obj.GetType(); - } - - public override int GetHashCode() - { - return TypeHashCode; - } - - private class NullParentChunkGenerator : IParentChunkGenerator - { - public void GenerateStartParentChunk(Block target, ChunkGeneratorContext context) - { - } - - public void GenerateEndParentChunk(Block target, ChunkGeneratorContext context) - { - } - - public override string ToString() - { - return "None"; - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/RazorChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/RazorChunkGenerator.cs deleted file mode 100644 index a6d057f3b1..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/RazorChunkGenerator.cs +++ /dev/null @@ -1,93 +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; -using Microsoft.AspNet.Razor.Parser; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class RazorChunkGenerator : ParserVisitor - { - private ChunkGeneratorContext _context; - - public RazorChunkGenerator( - string className, - string rootNamespaceName, - string sourceFileName, - RazorEngineHost host) - { - if (rootNamespaceName == null) - { - throw new ArgumentNullException(nameof(rootNamespaceName)); - } - - if (host == null) - { - throw new ArgumentNullException(nameof(host)); - } - - if (string.IsNullOrEmpty(className)) - { - throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, nameof(className)); - } - - ClassName = className; - RootNamespaceName = rootNamespaceName; - SourceFileName = sourceFileName; - GenerateLinePragmas = string.IsNullOrEmpty(SourceFileName) ? false : true; - Host = host; - } - - // Data pulled from constructor - public string ClassName { get; private set; } - public string RootNamespaceName { get; private set; } - public string SourceFileName { get; private set; } - public RazorEngineHost Host { get; private set; } - - // Generation settings - public bool GenerateLinePragmas { get; set; } - public bool DesignTimeMode { get; set; } - - public ChunkGeneratorContext Context - { - get - { - EnsureContextInitialized(); - return _context; - } - } - - public override void VisitStartBlock(Block block) - { - block.ChunkGenerator.GenerateStartParentChunk(block, Context); - } - - public override void VisitEndBlock(Block block) - { - block.ChunkGenerator.GenerateEndParentChunk(block, Context); - } - - public override void VisitSpan(Span span) - { - span.ChunkGenerator.GenerateChunk(span, Context); - } - - private void EnsureContextInitialized() - { - if (_context == null) - { - _context = new ChunkGeneratorContext(Host, - ClassName, - RootNamespaceName, - SourceFileName, - GenerateLinePragmas); - Initialize(_context); - } - } - - protected virtual void Initialize(ChunkGeneratorContext context) - { - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/RazorCommentChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/RazorCommentChunkGenerator.cs deleted file mode 100644 index ba0d202987..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/RazorCommentChunkGenerator.cs +++ /dev/null @@ -1,10 +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. - - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class RazorCommentChunkGenerator : ParentChunkGenerator - { - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/SectionChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/SectionChunkGenerator.cs deleted file mode 100644 index 4ed679c982..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/SectionChunkGenerator.cs +++ /dev/null @@ -1,47 +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; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class SectionChunkGenerator : ParentChunkGenerator - { - public SectionChunkGenerator(string sectionName) - { - SectionName = sectionName; - } - - public string SectionName { get; } - - public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context) - { - var chunk = context.ChunkTreeBuilder.StartParentChunk(target); - - chunk.Name = SectionName; - } - - public override void GenerateEndParentChunk(Block target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.EndParentChunk(); - } - - public override bool Equals(object obj) - { - var other = obj as SectionChunkGenerator; - return base.Equals(other) && - string.Equals(SectionName, other.SectionName, StringComparison.Ordinal); - } - - public override int GetHashCode() - { - return SectionName == null ? 0 : StringComparer.Ordinal.GetHashCode(SectionName); - } - - public override string ToString() - { - return "Section:" + SectionName; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/SetBaseTypeChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/SetBaseTypeChunkGenerator.cs deleted file mode 100644 index 4b4384ea38..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/SetBaseTypeChunkGenerator.cs +++ /dev/null @@ -1,40 +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; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class SetBaseTypeChunkGenerator : SpanChunkGenerator - { - public SetBaseTypeChunkGenerator(string baseType) - { - BaseType = baseType; - } - - public string BaseType { get; } - - public override void GenerateChunk(Span target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.AddSetBaseTypeChunk(BaseType, target); - } - - public override string ToString() - { - return "Base:" + BaseType; - } - - public override bool Equals(object obj) - { - var other = obj as SetBaseTypeChunkGenerator; - return other != null && - string.Equals(BaseType, other.BaseType, StringComparison.Ordinal); - } - - public override int GetHashCode() - { - return BaseType.GetHashCode(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/SpanChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/SpanChunkGenerator.cs deleted file mode 100644 index 225d33c8c1..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/SpanChunkGenerator.cs +++ /dev/null @@ -1,46 +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.Diagnostics.CodeAnalysis; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public abstract class SpanChunkGenerator : ISpanChunkGenerator - { - private static readonly int TypeHashCode = typeof(SpanChunkGenerator).GetHashCode(); - - [SuppressMessage( - "Microsoft.Security", - "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", - Justification = "This class has no instance state")] - public static readonly ISpanChunkGenerator Null = new NullSpanChunkGenerator(); - - public virtual void GenerateChunk(Span target, ChunkGeneratorContext context) - { - } - - public override bool Equals(object obj) - { - return obj != null && - GetType() == obj.GetType(); - } - - public override int GetHashCode() - { - return TypeHashCode; - } - - private class NullSpanChunkGenerator : ISpanChunkGenerator - { - public void GenerateChunk(Span target, ChunkGeneratorContext context) - { - } - - public override string ToString() - { - return "None"; - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/StatementChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/StatementChunkGenerator.cs deleted file mode 100644 index 7504fefc7e..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/StatementChunkGenerator.cs +++ /dev/null @@ -1,20 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class StatementChunkGenerator : SpanChunkGenerator - { - public override void GenerateChunk(Span target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.AddStatementChunk(target.Content, target); - } - - public override string ToString() - { - return "Stmt"; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TagHelperChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TagHelperChunkGenerator.cs deleted file mode 100644 index fbe2f28b71..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TagHelperChunkGenerator.cs +++ /dev/null @@ -1,107 +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.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Parser.TagHelpers; -using Microsoft.AspNet.Razor.Compilation.TagHelpers; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - /// - /// A that is responsible for generating valid s. - /// - public class TagHelperChunkGenerator : ParentChunkGenerator - { - private IEnumerable _tagHelperDescriptors; - - /// - /// Instantiates a new . - /// - /// - /// s associated with the current HTML tag. - /// - public TagHelperChunkGenerator(IEnumerable tagHelperDescriptors) - { - _tagHelperDescriptors = tagHelperDescriptors; - } - - /// - /// Starts the generation of a . - /// - /// - /// The responsible for this . - /// - /// A instance that contains information about - /// the current chunk generation process. - public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context) - { - var tagHelperBlock = target as TagHelperBlock; - - Debug.Assert( - tagHelperBlock != null, - $"A {nameof(TagHelperChunkGenerator)} must only be used with {nameof(TagHelperBlock)}s."); - - var attributes = new List>(); - - // We need to create a chunk generator to create chunks for each of the attributes. - var chunkGenerator = context.Host.CreateChunkGenerator( - context.ClassName, - context.RootNamespace, - context.SourceFile); - - foreach (var attribute in tagHelperBlock.Attributes) - { - ParentChunk attributeChunkValue = null; - - if (attribute.Value != null) - { - // Populates the chunk tree with chunks associated with attributes - attribute.Value.Accept(chunkGenerator); - - var chunks = chunkGenerator.Context.ChunkTreeBuilder.ChunkTree.Chunks; - var first = chunks.FirstOrDefault(); - - attributeChunkValue = new ParentChunk - { - Association = first?.Association, - Children = chunks, - Start = first == null ? SourceLocation.Zero : first.Start - }; - } - - attributes.Add(new KeyValuePair(attribute.Key, attributeChunkValue)); - - // Reset the chunk tree builder so we can build a new one for the next attribute - chunkGenerator.Context.ChunkTreeBuilder = new ChunkTreeBuilder(); - } - - var unprefixedTagName = tagHelperBlock.TagName.Substring(_tagHelperDescriptors.First().Prefix.Length); - - context.ChunkTreeBuilder.StartParentChunk( - new TagHelperChunk( - unprefixedTagName, - tagHelperBlock.TagMode, - attributes, - _tagHelperDescriptors), - target, - topLevel: false); - } - - /// - /// Ends the generation of a capturing all previously visited children - /// since the method was called. - /// - /// - /// The responsible for this . - /// - /// A instance that contains information about - /// the current chunk generation process. - public override void GenerateEndParentChunk(Block target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.EndParentChunk(); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TagHelperPrefixDirectiveChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TagHelperPrefixDirectiveChunkGenerator.cs deleted file mode 100644 index dd00b86540..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TagHelperPrefixDirectiveChunkGenerator.cs +++ /dev/null @@ -1,43 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - /// - /// A responsible for generating - /// s. - /// - public class TagHelperPrefixDirectiveChunkGenerator : SpanChunkGenerator - { - /// - /// Instantiates a new . - /// - /// - /// Text used as a required prefix when matching HTML. - /// - public TagHelperPrefixDirectiveChunkGenerator(string prefix) - { - Prefix = prefix; - } - - /// - /// Text used as a required prefix when matching HTML. - /// - public string Prefix { get; } - - /// - /// Generates s. - /// - /// - /// The responsible for this . - /// - /// A instance that contains information about - /// the current chunk generation process. - public override void GenerateChunk(Span target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.AddTagHelperPrefixDirectiveChunk(Prefix, target); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TemplateBlockChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TemplateBlockChunkGenerator.cs deleted file mode 100644 index 6874c7b37d..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TemplateBlockChunkGenerator.cs +++ /dev/null @@ -1,20 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class TemplateBlockChunkGenerator : ParentChunkGenerator - { - public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.StartParentChunk(target); - } - - public override void GenerateEndParentChunk(Block target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.EndParentChunk(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TypeMemberChunkGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TypeMemberChunkGenerator.cs deleted file mode 100644 index cfda1aa1ed..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/Generators/TypeMemberChunkGenerator.cs +++ /dev/null @@ -1,20 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Chunks.Generators -{ - public class TypeMemberChunkGenerator : SpanChunkGenerator - { - public override void GenerateChunk(Span target, ChunkGeneratorContext context) - { - context.ChunkTreeBuilder.AddTypeMemberChunk(target.Content, target); - } - - public override string ToString() - { - return "TypeMember"; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/LiteralChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/LiteralChunk.cs deleted file mode 100644 index 756e131ee2..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/LiteralChunk.cs +++ /dev/null @@ -1,15 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class LiteralChunk : Chunk - { - public string Text { get; set; } - - public override string ToString() - { - return Start + " = " + Text; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/LiteralCodeAttributeChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/LiteralCodeAttributeChunk.cs deleted file mode 100644 index dce9c0d5c6..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/LiteralCodeAttributeChunk.cs +++ /dev/null @@ -1,15 +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 Microsoft.AspNet.Razor.Text; - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class LiteralCodeAttributeChunk : ParentChunk - { - public string Code { get; set; } - public LocationTagged Prefix { get; set; } - public LocationTagged Value { get; set; } - public SourceLocation ValueLocation { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ParentChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ParentChunk.cs deleted file mode 100644 index da88454827..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/ParentChunk.cs +++ /dev/null @@ -1,17 +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.Collections.Generic; - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class ParentChunk : Chunk - { - public ParentChunk() - { - Children = new List(); - } - - public IList Children { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/RemoveTagHelperChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/RemoveTagHelperChunk.cs deleted file mode 100644 index 6de311905b..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/RemoveTagHelperChunk.cs +++ /dev/null @@ -1,18 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - /// - /// A used to look up s that should be ignored - /// within the Razor page. - /// - public class RemoveTagHelperChunk : Chunk - { - /// - /// Text used to look up s that should be ignored within the Razor - /// page. - /// - public string LookupText { get; set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/SectionChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/SectionChunk.cs deleted file mode 100644 index 6262484a22..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/SectionChunk.cs +++ /dev/null @@ -1,10 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class SectionChunk : ParentChunk - { - public string Name { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/SetBaseTypeChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/SetBaseTypeChunk.cs deleted file mode 100644 index 06d9e270d7..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/SetBaseTypeChunk.cs +++ /dev/null @@ -1,10 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class SetBaseTypeChunk : Chunk - { - public string TypeName { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/StatementChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/StatementChunk.cs deleted file mode 100644 index 49e40dc6fa..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/StatementChunk.cs +++ /dev/null @@ -1,15 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class StatementChunk : Chunk - { - public string Code { get; set; } - - public override string ToString() - { - return Start + " = " + Code; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TagHelperChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TagHelperChunk.cs deleted file mode 100644 index 3e0a700685..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TagHelperChunk.cs +++ /dev/null @@ -1,60 +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.Collections.Generic; -using Microsoft.AspNet.Razor.TagHelpers; -using Microsoft.AspNet.Razor.Compilation.TagHelpers; - -namespace Microsoft.AspNet.Razor.Chunks -{ - /// - /// A that represents a special HTML tag. - /// - public class TagHelperChunk : ParentChunk - { - /// - /// Instantiates a new . - /// - /// The tag name associated with the tag helpers HTML element. - /// HTML syntax of the element in the Razor source. - /// The attributes associated with the tag helpers HTML element. - /// - /// The s associated with this tag helpers HTML element. - /// - public TagHelperChunk( - string tagName, - TagMode tagMode, - IList> attributes, - IEnumerable descriptors) - { - TagName = tagName; - TagMode = tagMode; - Attributes = attributes; - Descriptors = descriptors; - } - - /// - /// The HTML attributes. - /// - /// - /// These attributes are => so attribute values can consist - /// of all sorts of Razor specific pieces. - /// - public IList> Attributes { get; set; } - - /// - /// The s that are associated with the tag helpers HTML element. - /// - public IEnumerable Descriptors { get; set; } - - /// - /// The HTML tag name. - /// - public string TagName { get; set; } - - /// - /// Gets the HTML syntax of the element in the Razor source. - /// - public TagMode TagMode { get; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TagHelperPrefixDirectiveChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TagHelperPrefixDirectiveChunk.cs deleted file mode 100644 index a935f2b60a..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TagHelperPrefixDirectiveChunk.cs +++ /dev/null @@ -1,17 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - /// - /// A for the @tagHelperPrefix directive. - /// - public class TagHelperPrefixDirectiveChunk : Chunk - { - /// - /// Text used as a required prefix when matching HTML start and end tags in the Razor source to available - /// tag helpers. - /// - public string Prefix { get; set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TemplateChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TemplateChunk.cs deleted file mode 100644 index 4089f96245..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TemplateChunk.cs +++ /dev/null @@ -1,9 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class TemplateChunk : ParentChunk - { - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TypeMemberChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TypeMemberChunk.cs deleted file mode 100644 index 394ce2a399..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/TypeMemberChunk.cs +++ /dev/null @@ -1,10 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class TypeMemberChunk : Chunk - { - public string Code { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/UsingChunk.cs b/src/Microsoft.AspNet.Razor.VSRC1/Chunks/UsingChunk.cs deleted file mode 100644 index 60902ac7c1..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Chunks/UsingChunk.cs +++ /dev/null @@ -1,10 +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. - -namespace Microsoft.AspNet.Razor.Chunks -{ - public class UsingChunk : Chunk - { - public string Namespace { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpCodeGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpCodeGenerator.cs deleted file mode 100644 index 5d46d4f23e..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpCodeGenerator.cs +++ /dev/null @@ -1,177 +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; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNet.Razor.Chunks; -using Microsoft.AspNet.Razor.CodeGenerators.Visitors; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public class CSharpCodeGenerator : CodeGenerator - { - // See http://msdn.microsoft.com/en-us/library/system.codedom.codechecksumpragma.checksumalgorithmid.aspx - private const string Sha1AlgorithmId = "{ff1816ec-aa5e-4d10-87f7-6f4963833460}"; - private const int DisableAsyncWarning = 1998; - - public CSharpCodeGenerator(CodeGeneratorContext context) - : base(context) - { - } - - private ChunkTree Tree { get { return Context.ChunkTreeBuilder.ChunkTree; } } - public RazorEngineHost Host { get { return Context.Host; } } - - /// - /// Protected for testing. - /// - /// A new instance of . - protected virtual CSharpCodeWriter CreateCodeWriter() - { - return new CSharpCodeWriter(); - } - - public override CodeGeneratorResult Generate() - { - var writer = CreateCodeWriter(); - - if (!Host.DesignTimeMode && !string.IsNullOrEmpty(Context.Checksum)) - { - writer.Write("#pragma checksum \"") - .Write(Context.SourceFile) - .Write("\" \"") - .Write(Sha1AlgorithmId) - .Write("\" \"") - .Write(Context.Checksum) - .WriteLine("\""); - } - - using (writer.BuildNamespace(Context.RootNamespace)) - { - // Write out using directives - AddImports(Tree, writer, Host.NamespaceImports); - // Separate the usings and the class - writer.WriteLine(); - - using (BuildClassDeclaration(writer)) - { - if (Host.DesignTimeMode) - { - writer.WriteLine("private static object @__o;"); - } - - var csharpCodeVisitor = CreateCSharpCodeVisitor(writer, Context); - - new CSharpTypeMemberVisitor(csharpCodeVisitor, writer, Context).Accept(Tree.Chunks); - CreateCSharpDesignTimeCodeVisitor(csharpCodeVisitor, writer, Context) - .AcceptTree(Tree); - new CSharpTagHelperFieldDeclarationVisitor(writer, Context).Accept(Tree.Chunks); - - BuildConstructor(writer); - - // Add space in-between constructor and method body - writer.WriteLine(); - - using (writer.BuildDisableWarningScope(DisableAsyncWarning)) - { - using (writer.BuildMethodDeclaration("public override async", "Task", Host.GeneratedClassContext.ExecuteMethodName)) - { - new CSharpTagHelperRunnerInitializationVisitor(writer, Context).Accept(Tree.Chunks); - csharpCodeVisitor.Accept(Tree.Chunks); - } - } - } - } - - return new CodeGeneratorResult(writer.GenerateCode(), writer.LineMappingManager.Mappings); - } - - protected virtual CSharpCodeVisitor CreateCSharpCodeVisitor( - CSharpCodeWriter writer, - CodeGeneratorContext context) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - return new CSharpCodeVisitor(writer, context); - } - - protected virtual CSharpDesignTimeCodeVisitor CreateCSharpDesignTimeCodeVisitor( - CSharpCodeVisitor csharpCodeVisitor, - CSharpCodeWriter writer, - CodeGeneratorContext context) - { - if (csharpCodeVisitor == null) - { - throw new ArgumentNullException(nameof(csharpCodeVisitor)); - } - - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - return new CSharpDesignTimeCodeVisitor(csharpCodeVisitor, writer, context); - } - - protected virtual CSharpCodeWritingScope BuildClassDeclaration(CSharpCodeWriter writer) - { - var baseTypeVisitor = new CSharpBaseTypeVisitor(writer, Context); - baseTypeVisitor.Accept(Tree.Chunks); - - var baseType = baseTypeVisitor.CurrentBaseType ?? Host.DefaultBaseClass; - - var baseTypes = string.IsNullOrEmpty(baseType) ? Enumerable.Empty() : new string[] { baseType }; - - return writer.BuildClassDeclaration("public", Context.ClassName, baseTypes); - } - - protected virtual void BuildConstructor(CSharpCodeWriter writer) - { - writer.WriteLineHiddenDirective(); - using (writer.BuildConstructor(Context.ClassName)) - { - // Any constructor based logic that we need to add? - }; - } - - private void AddImports(ChunkTree chunkTree, CSharpCodeWriter writer, IEnumerable defaultImports) - { - // Write out using directives - var usingVisitor = new CSharpUsingVisitor(writer, Context); - foreach (Chunk chunk in Tree.Chunks) - { - usingVisitor.Accept(chunk); - } - - defaultImports = defaultImports.Except(usingVisitor.ImportedUsings); - - foreach (string import in defaultImports) - { - writer.WriteUsing(import); - } - - var taskNamespace = typeof(Task).Namespace; - - // We need to add the task namespace but ONLY if it hasn't been added by the default imports or using imports yet. - if (!defaultImports.Contains(taskNamespace) && !usingVisitor.ImportedUsings.Contains(taskNamespace)) - { - writer.WriteUsing(taskNamespace); - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpCodeWriter.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpCodeWriter.cs deleted file mode 100644 index 78c35736a7..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpCodeWriter.cs +++ /dev/null @@ -1,513 +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; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using Microsoft.AspNet.Razor.Chunks.Generators; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Text; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public class CSharpCodeWriter : CodeWriter - { - private const string InstanceMethodFormat = "{0}.{1}"; - - public CSharpCodeWriter() - { - LineMappingManager = new LineMappingManager(); - } - - public LineMappingManager LineMappingManager { get; private set; } - - public new CSharpCodeWriter Write(string data) - { - return (CSharpCodeWriter)base.Write(data); - } - - public new CSharpCodeWriter Indent(int size) - { - return (CSharpCodeWriter)base.Indent(size); - } - - public new CSharpCodeWriter ResetIndent() - { - return (CSharpCodeWriter)base.ResetIndent(); - } - - public new CSharpCodeWriter SetIndent(int size) - { - return (CSharpCodeWriter)base.SetIndent(size); - } - - public new CSharpCodeWriter IncreaseIndent(int size) - { - return (CSharpCodeWriter)base.IncreaseIndent(size); - } - - public new CSharpCodeWriter DecreaseIndent(int size) - { - return (CSharpCodeWriter)base.DecreaseIndent(size); - } - - public new CSharpCodeWriter WriteLine(string data) - { - return (CSharpCodeWriter)base.WriteLine(data); - } - - public new CSharpCodeWriter WriteLine() - { - return (CSharpCodeWriter)base.WriteLine(); - } - - public CSharpCodeWriter WriteVariableDeclaration(string type, string name, string value) - { - Write(type).Write(" ").Write(name); - if (!string.IsNullOrEmpty(value)) - { - Write(" = ").Write(value); - } - else - { - Write(" = null"); - } - - WriteLine(";"); - - return this; - } - - public CSharpCodeWriter WriteComment(string comment) - { - return Write("// ").WriteLine(comment); - } - - public CSharpCodeWriter WriteBooleanLiteral(bool value) - { - return Write(value.ToString().ToLowerInvariant()); - } - - public CSharpCodeWriter WriteStartAssignment(string name) - { - return Write(name).Write(" = "); - } - - public CSharpCodeWriter WriteParameterSeparator() - { - return Write(", "); - } - - public CSharpCodeWriter WriteStartNewObject(string typeName) - { - return Write("new ").Write(typeName).Write("("); - } - - public CSharpCodeWriter WriteLocationTaggedString(LocationTagged value) - { - WriteStringLiteral(value.Value); - WriteParameterSeparator(); - Write(value.Location.AbsoluteIndex.ToString(CultureInfo.CurrentCulture)); - - return this; - } - - public CSharpCodeWriter WriteStringLiteral(string literal) - { - if (literal.Length >= 256 && literal.Length <= 1500 && literal.IndexOf('\0') == -1) - { - WriteVerbatimStringLiteral(literal); - } - else - { - WriteCStyleStringLiteral(literal); - } - - return this; - } - - public CSharpCodeWriter WriteLineHiddenDirective() - { - return WriteLine("#line hidden"); - } - - public CSharpCodeWriter WritePragma(string value) - { - return Write("#pragma ").WriteLine(value); - } - - public CSharpCodeWriter WriteUsing(string name) - { - return WriteUsing(name, endLine: true); - } - - public CSharpCodeWriter WriteUsing(string name, bool endLine) - { - Write(string.Format("using {0}", name)); - - if (endLine) - { - WriteLine(";"); - } - - return this; - } - - public CSharpCodeWriter WriteLineDefaultDirective() - { - return WriteLine("#line default"); - } - - public CSharpCodeWriter WriteStartReturn() - { - return Write("return "); - } - - public CSharpCodeWriter WriteReturn(string value) - { - return WriteReturn(value, endLine: true); - } - - public CSharpCodeWriter WriteReturn(string value, bool endLine) - { - Write("return ").Write(value); - - if (endLine) - { - Write(";"); - } - - return WriteLine(); - } - - /// - /// Writes a #line pragma directive for the line number at the specified . - /// - /// The location to generate the line pragma for. - /// The file to generate the line pragma for. - /// The current instance of . - public CSharpCodeWriter WriteLineNumberDirective(SourceLocation location, string file) - { - if (location.FilePath != null) - { - file = location.FilePath; - } - - if (!string.IsNullOrEmpty(LastWrite) && - !LastWrite.EndsWith(NewLine, StringComparison.Ordinal)) - { - WriteLine(); - } - - var lineNumberAsString = (location.LineIndex + 1).ToString(CultureInfo.InvariantCulture); - return Write("#line ").Write(lineNumberAsString).Write(" \"").Write(file).WriteLine("\""); - } - - public CSharpCodeWriter WriteStartMethodInvocation(string methodName) - { - return WriteStartMethodInvocation(methodName, new string[0]); - } - - public CSharpCodeWriter WriteStartMethodInvocation(string methodName, params string[] genericArguments) - { - Write(methodName); - - if (genericArguments.Length > 0) - { - Write("<").Write(string.Join(", ", genericArguments)).Write(">"); - } - - return Write("("); - } - - public CSharpCodeWriter WriteEndMethodInvocation() - { - return WriteEndMethodInvocation(endLine: true); - } - public CSharpCodeWriter WriteEndMethodInvocation(bool endLine) - { - Write(")"); - if (endLine) - { - WriteLine(";"); - } - - return this; - } - - // Writes a method invocation for the given instance name. - public CSharpCodeWriter WriteInstanceMethodInvocation(string instanceName, - string methodName, - params string[] parameters) - { - if (instanceName == null) - { - throw new ArgumentNullException(nameof(instanceName)); - } - - if (methodName == null) - { - throw new ArgumentNullException(nameof(methodName)); - } - - return WriteInstanceMethodInvocation(instanceName, methodName, endLine: true, parameters: parameters); - } - - // Writes a method invocation for the given instance name. - public CSharpCodeWriter WriteInstanceMethodInvocation(string instanceName, - string methodName, - bool endLine, - params string[] parameters) - { - if (instanceName == null) - { - throw new ArgumentNullException(nameof(instanceName)); - } - - if (methodName == null) - { - throw new ArgumentNullException(nameof(methodName)); - } - - return WriteMethodInvocation( - string.Format(CultureInfo.InvariantCulture, InstanceMethodFormat, instanceName, methodName), - endLine, - parameters); - } - - public CSharpCodeWriter WriteStartInstanceMethodInvocation(string instanceName, - string methodName) - { - if (instanceName == null) - { - throw new ArgumentNullException(nameof(instanceName)); - } - - if (methodName == null) - { - throw new ArgumentNullException(nameof(methodName)); - } - - return WriteStartMethodInvocation( - string.Format(CultureInfo.InvariantCulture, InstanceMethodFormat, instanceName, methodName)); - } - - public CSharpCodeWriter WriteMethodInvocation(string methodName, params string[] parameters) - { - return WriteMethodInvocation(methodName, endLine: true, parameters: parameters); - } - - public CSharpCodeWriter WriteMethodInvocation(string methodName, bool endLine, params string[] parameters) - { - return WriteStartMethodInvocation(methodName).Write(string.Join(", ", parameters)).WriteEndMethodInvocation(endLine); - } - - public CSharpDisableWarningScope BuildDisableWarningScope(int warning) - { - return new CSharpDisableWarningScope(this, warning); - } - - public CSharpCodeWritingScope BuildScope() - { - return new CSharpCodeWritingScope(this); - } - - public CSharpCodeWritingScope BuildLambda(bool endLine, params string[] parameterNames) - { - return BuildLambda(endLine, async: false, parameterNames: parameterNames); - } - - public CSharpCodeWritingScope BuildAsyncLambda(bool endLine, params string[] parameterNames) - { - return BuildLambda(endLine, async: true, parameterNames: parameterNames); - } - - private CSharpCodeWritingScope BuildLambda(bool endLine, bool async, string[] parameterNames) - { - if (async) - { - Write("async"); - } - - Write("(").Write(string.Join(", ", parameterNames)).Write(") => "); - - var scope = new CSharpCodeWritingScope(this); - - if (endLine) - { - // End the lambda with a semicolon - scope.OnClose += () => - { - WriteLine(";"); - }; - } - - return scope; - } - - public CSharpCodeWritingScope BuildNamespace(string name) - { - Write("namespace ").WriteLine(name); - - return new CSharpCodeWritingScope(this); - } - - public CSharpCodeWritingScope BuildClassDeclaration(string accessibility, string name) - { - return BuildClassDeclaration(accessibility, name, Enumerable.Empty()); - } - - public CSharpCodeWritingScope BuildClassDeclaration(string accessibility, string name, string baseType) - { - return BuildClassDeclaration(accessibility, name, new string[] { baseType }); - } - - public CSharpCodeWritingScope BuildClassDeclaration(string accessibility, string name, IEnumerable baseTypes) - { - Write(accessibility).Write(" class ").Write(name); - - if (baseTypes.Count() > 0) - { - Write(" : "); - Write(string.Join(", ", baseTypes)); - } - - WriteLine(); - - return new CSharpCodeWritingScope(this); - } - - public CSharpCodeWritingScope BuildConstructor(string name) - { - return BuildConstructor("public", name); - } - - public CSharpCodeWritingScope BuildConstructor(string accessibility, string name) - { - return BuildConstructor(accessibility, name, Enumerable.Empty>()); - } - - public CSharpCodeWritingScope BuildConstructor(string accessibility, string name, IEnumerable> parameters) - { - Write(accessibility).Write(" ").Write(name).Write("(").Write(string.Join(", ", parameters.Select(p => p.Key + " " + p.Value))).WriteLine(")"); - - return new CSharpCodeWritingScope(this); - } - - public CSharpCodeWritingScope BuildMethodDeclaration(string accessibility, string returnType, string name) - { - return BuildMethodDeclaration(accessibility, returnType, name, Enumerable.Empty>()); - } - - public CSharpCodeWritingScope BuildMethodDeclaration(string accessibility, string returnType, string name, IEnumerable> parameters) - { - Write(accessibility).Write(" ").Write(returnType).Write(" ").Write(name).Write("(").Write(string.Join(", ", parameters.Select(p => p.Key + " " + p.Value))).WriteLine(")"); - - return new CSharpCodeWritingScope(this); - } - - // TODO: Do I need to look at the document content to determine its mapping length? - public CSharpLineMappingWriter BuildLineMapping(SourceLocation documentLocation, int contentLength, string sourceFilename) - { - return new CSharpLineMappingWriter(this, documentLocation, contentLength, sourceFilename); - } - - private void WriteVerbatimStringLiteral(string literal) - { - Write("@\""); - - foreach (char c in literal) - { - if (c == '\"') - { - Write("\"\""); - } - else - { - Write(c.ToString()); - } - } - - Write("\""); - } - - private void WriteCStyleStringLiteral(string literal) - { - // From CSharpCodeGenerator.QuoteSnippetStringCStyle in CodeDOM - Write("\""); - for (int i = 0; i < literal.Length; i++) - { - switch (literal[i]) - { - case '\r': - Write("\\r"); - break; - case '\t': - Write("\\t"); - break; - case '\"': - Write("\\\""); - break; - case '\'': - Write("\\\'"); - break; - case '\\': - Write("\\\\"); - break; - case '\0': - Write("\\\0"); - break; - case '\n': - Write("\\n"); - break; - case '\u2028': - case '\u2029': - Write("\\u"); - Write(((int)literal[i]).ToString("X4", CultureInfo.InvariantCulture)); - break; - default: - Write(literal[i].ToString()); - break; - } - if (i > 0 && i % 80 == 0) - { - // If current character is a high surrogate and the following - // character is a low surrogate, don't break them. - // Otherwise when we write the string to a file, we might lose - // the characters. - if (Char.IsHighSurrogate(literal[i]) - && (i < literal.Length - 1) - && Char.IsLowSurrogate(literal[i + 1])) - { - Write(literal[++i].ToString()); - } - - Write("\" +"); - Write(NewLine); - Write("\""); - } - } - Write("\""); - } - - public CSharpCodeWriter WriteStartInstrumentationContext( - ChunkGeneratorContext context, - SyntaxTreeNode syntaxNode, - bool isLiteral) - { - WriteStartMethodInvocation(context.Host.GeneratedClassContext.BeginContextMethodName); - Write(syntaxNode.Start.AbsoluteIndex.ToString(CultureInfo.InvariantCulture)); - WriteParameterSeparator(); - Write(syntaxNode.Length.ToString(CultureInfo.InvariantCulture)); - WriteParameterSeparator(); - Write(isLiteral ? "true" : "false"); - return WriteEndMethodInvocation(); - } - - public CSharpCodeWriter WriteEndInstrumentationContext(ChunkGeneratorContext context) - { - return WriteMethodInvocation(context.Host.GeneratedClassContext.EndContextMethodName); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpCodeWritingScope.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpCodeWritingScope.cs deleted file mode 100644 index 2616c149b0..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpCodeWritingScope.cs +++ /dev/null @@ -1,69 +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; -using System.Linq; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public struct CSharpCodeWritingScope : IDisposable - { - private CodeWriter _writer; - private bool _autoSpace; - private int _tabSize; - private int _startIndent; - - public CSharpCodeWritingScope(CodeWriter writer) : this(writer, true) { } - public CSharpCodeWritingScope(CodeWriter writer, int tabSize) : this(writer, tabSize, true) { } - // TODO: Make indents (tabs) environment specific - public CSharpCodeWritingScope(CodeWriter writer, bool autoSpace) : this(writer, 4, autoSpace) { } - public CSharpCodeWritingScope(CodeWriter writer, int tabSize, bool autoSpace) - { - _writer = writer; - _autoSpace = true; - _tabSize = tabSize; - _startIndent = -1; // Set in WriteStartScope - - OnClose = () => { }; - - WriteStartScope(); - } - - public Action OnClose; - - public void Dispose() - { - WriteEndScope(); - OnClose(); - } - - private void WriteStartScope() - { - TryAutoSpace(" "); - - _writer.WriteLine("{").IncreaseIndent(_tabSize); - _startIndent = _writer.CurrentIndent; - } - - private void WriteEndScope() - { - TryAutoSpace(_writer.NewLine); - - // Ensure the scope hasn't been modified - if (_writer.CurrentIndent == _startIndent) - { - _writer.DecreaseIndent(_tabSize); - } - - _writer.WriteLine("}"); - } - - private void TryAutoSpace(string spaceCharacter) - { - if (_autoSpace && _writer.LastWrite.Length > 0 && !Char.IsWhiteSpace(_writer.LastWrite.Last())) - { - _writer.Write(spaceCharacter); - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpDisableWarningScope.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpDisableWarningScope.cs deleted file mode 100644 index 3c319c5f12..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpDisableWarningScope.cs +++ /dev/null @@ -1,29 +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.AspNet.Razor.CodeGenerators -{ - public struct CSharpDisableWarningScope : IDisposable - { - private CSharpCodeWriter _writer; - int _warningNumber; - - public CSharpDisableWarningScope(CSharpCodeWriter writer) : this(writer, 219) - { } - - public CSharpDisableWarningScope(CSharpCodeWriter writer, int warningNumber) - { - _writer = writer; - _warningNumber = warningNumber; - - _writer.WritePragma("warning disable " + _warningNumber); - } - - public void Dispose() - { - _writer.WritePragma("warning restore " + _warningNumber); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpLineMappingWriter.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpLineMappingWriter.cs deleted file mode 100644 index e4f003e024..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpLineMappingWriter.cs +++ /dev/null @@ -1,136 +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.AspNet.Razor.CodeGenerators -{ - public class CSharpLineMappingWriter : IDisposable - { - private readonly CSharpCodeWriter _writer; - private readonly MappingLocation _documentMapping; - private readonly int _startIndent; - private readonly bool _writePragmas; - private readonly bool _addLineMapping; - - private SourceLocation _generatedLocation; - private int _generatedContentLength; - - private CSharpLineMappingWriter(CSharpCodeWriter writer, bool addLineMappings) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - _writer = writer; - _addLineMapping = addLineMappings; - _startIndent = _writer.CurrentIndent; - _writer.ResetIndent(); - } - - public CSharpLineMappingWriter(CSharpCodeWriter writer, SourceLocation documentLocation, int contentLength) - : this(writer, addLineMappings: true) - { - _documentMapping = new MappingLocation(documentLocation, contentLength); - _generatedLocation = _writer.GetCurrentSourceLocation(); - } - - public CSharpLineMappingWriter( - CSharpCodeWriter writer, - SourceLocation documentLocation, - int contentLength, - string sourceFilename) - : this(writer, documentLocation, contentLength) - { - _writePragmas = true; - - _writer.WriteLineNumberDirective(documentLocation, sourceFilename); - _generatedLocation = _writer.GetCurrentSourceLocation(); - } - - /// - /// Initializes a new instance of used for generation of runtime - /// line mappings. The constructed instance of does not track - /// mappings between the Razor content and the generated content. - /// - /// The to write output to. - /// The of the Razor content being mapping. - /// The input file path. - public CSharpLineMappingWriter( - CSharpCodeWriter writer, - SourceLocation documentLocation, - string sourceFileName) - : this(writer, addLineMappings: false) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - _writePragmas = true; - _writer.WriteLineNumberDirective(documentLocation, sourceFileName); - } - - public void MarkLineMappingStart() - { - _generatedLocation = _writer.GetCurrentSourceLocation(); - } - - public void MarkLineMappingEnd() - { - _generatedContentLength = _writer.GenerateCode().Length - _generatedLocation.AbsoluteIndex; - } - - public void Dispose() - { - if (_addLineMapping) - { - // Verify that the generated length has not already been calculated - if (_generatedContentLength == 0) - { - _generatedContentLength = _writer.GenerateCode().Length - _generatedLocation.AbsoluteIndex; - } - - var generatedLocation = new MappingLocation(_generatedLocation, _generatedContentLength); - var documentMapping = _documentMapping; - if (documentMapping.ContentLength == -1) - { - documentMapping = new MappingLocation( - location: new SourceLocation( - _documentMapping.FilePath, - _documentMapping.AbsoluteIndex, - _documentMapping.LineIndex, - _documentMapping.CharacterIndex), - contentLength: _generatedContentLength); - } - - _writer.LineMappingManager.AddMapping( - documentLocation: documentMapping, - generatedLocation: generatedLocation); - } - - if (_writePragmas) - { - // Need to add an additional line at the end IF there wasn't one already written. - // This is needed to work with the C# editor's handling of #line ... - var endsWithNewline = _writer.GenerateCode().EndsWith("\n"); - - // Always write at least 1 empty line to potentially separate code from pragmas. - _writer.WriteLine(); - - // Check if the previous empty line wasn't enough to separate code from pragmas. - if (!endsWithNewline) - { - _writer.WriteLine(); - } - - _writer.WriteLineDefaultDirective() - .WriteLineHiddenDirective(); - } - - // Reset indent back to when it was started - _writer.SetIndent(_startIndent); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpPaddingBuilder.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpPaddingBuilder.cs deleted file mode 100644 index 43fbcb2d48..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpPaddingBuilder.cs +++ /dev/null @@ -1,180 +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; -using Microsoft.AspNet.Razor.Parser; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public class CSharpPaddingBuilder - { - private static readonly char[] _newLineChars = { '\r', '\n' }; - - private readonly RazorEngineHost _host; - - public CSharpPaddingBuilder(RazorEngineHost host) - { - _host = host; - } - - // Special case for statement padding to account for brace positioning in the editor. - public string BuildStatementPadding(Span target) - { - if (target == null) - { - throw new ArgumentNullException(nameof(target)); - } - - var padding = CalculatePadding(target, generatedStart: 0); - - // We treat statement padding specially so for brace positioning, so that in the following example: - // @if (foo > 0) - // { - // } - // - // the braces shows up under the @ rather than under the if. - if (_host.DesignTimeMode && - padding > 0 && - target.Previous.Kind == SpanKind.Transition && // target.Previous is guaranteed to not be null if you have padding. - string.Equals(target.Previous.Content, SyntaxConstants.TransitionString, StringComparison.Ordinal)) - { - padding--; - } - - var generatedCode = BuildPaddingInternal(padding); - - return generatedCode; - } - - public string BuildExpressionPadding(Span target) - { - return BuildExpressionPadding(target, generatedStart: 0); - } - - public string BuildExpressionPadding(Span target, int generatedStart) - { - if (target == null) - { - throw new ArgumentNullException(nameof(target)); - } - - var padding = CalculatePadding(target, generatedStart); - - return BuildPaddingInternal(padding); - } - - internal int CalculatePadding(Span target, int generatedStart) - { - if (target == null) - { - throw new ArgumentNullException(nameof(target)); - } - - int padding; - - padding = CollectSpacesAndTabs(target, _host.TabSize) - generatedStart; - - // if we add generated text that is longer than the padding we wanted to insert we have no recourse and we have to skip padding - // example: - // Razor code at column zero: @somecode() - // Generated code will be: - // In design time: __o = somecode(); - // In Run time: Write(somecode()); - // - // In both cases the padding would have been 1 space to remote the space the @ symbol takes, which will be smaller than the 6 - // chars the hidden generated code takes. - if (padding < 0) - { - padding = 0; - } - - return padding; - } - - private string BuildPaddingInternal(int padding) - { - if (_host.DesignTimeMode && _host.IsIndentingWithTabs) - { - var spaces = padding % _host.TabSize; - var tabs = padding / _host.TabSize; - - return new string('\t', tabs) + new string(' ', spaces); - } - else - { - return new string(' ', padding); - } - } - - private static int CollectSpacesAndTabs(Span target, int tabSize) - { - var firstSpanInLine = target; - - string currentContent = null; - - while (firstSpanInLine.Previous != null) - { - // When scanning previous spans we need to be break down the spans with spaces. The parser combines - // whitespace into existing spans so you'll see tabs, newlines etc. within spans. We only care about - // the \t in existing spans. - var previousContent = firstSpanInLine.Previous.Content ?? string.Empty; - - var lastNewLineIndex = previousContent.LastIndexOfAny(_newLineChars); - - if (lastNewLineIndex < 0) - { - firstSpanInLine = firstSpanInLine.Previous; - } - else - { - if (lastNewLineIndex != previousContent.Length - 1) - { - firstSpanInLine = firstSpanInLine.Previous; - currentContent = previousContent.Substring(lastNewLineIndex + 1); - } - - break; - } - } - - // We need to walk from the beginning of the line, because space + tab(tabSize) = tabSize columns, but tab(tabSize) + space = tabSize+1 columns. - var currentSpanInLine = firstSpanInLine; - - if (currentContent == null) - { - currentContent = currentSpanInLine.Content; - } - - var padding = 0; - while (currentSpanInLine != target) - { - if (currentContent != null) - { - for (int i = 0; i < currentContent.Length; i++) - { - if (currentContent[i] == '\t') - { - // Example: - // : - // iter 1) 1 - // iter 2) 2 - // iter 3) 4 = 2 + (4 - 2) - // iter 4) 8 = 4 + (4 - 0) - padding = padding + (tabSize - (padding % tabSize)); - } - else - { - padding++; - } - } - } - - currentSpanInLine = currentSpanInLine.Next; - currentContent = currentSpanInLine.Content; - } - - return padding; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpTagHelperCodeRenderer.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpTagHelperCodeRenderer.cs deleted file mode 100644 index dbd26e3a2c..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CSharpTagHelperCodeRenderer.cs +++ /dev/null @@ -1,761 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using Microsoft.AspNet.Razor.Chunks; -using Microsoft.AspNet.Razor.CodeGenerators.Visitors; -using Microsoft.AspNet.Razor.TagHelpers; -using Microsoft.AspNet.Razor.Compilation.TagHelpers; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - /// - /// Renders tag helper rendering code. - /// - public class CSharpTagHelperCodeRenderer - { - internal static readonly string ExecutionContextVariableName = "__tagHelperExecutionContext"; - internal static readonly string StringValueBufferVariableName = "__tagHelperStringValueBuffer"; - internal static readonly string ScopeManagerVariableName = "__tagHelperScopeManager"; - internal static readonly string RunnerVariableName = "__tagHelperRunner"; - - private readonly CSharpCodeWriter _writer; - private readonly CodeGeneratorContext _context; - private readonly IChunkVisitor _bodyVisitor; - private readonly IChunkVisitor _literalBodyVisitor; - private readonly TagHelperAttributeCodeVisitor _attributeCodeVisitor; - private readonly GeneratedTagHelperContext _tagHelperContext; - private readonly bool _designTimeMode; - - /// - /// Instantiates a new . - /// - /// The used to render chunks found in the body. - /// The used to write code. - /// A instance that contains information about - /// the current code generation process. - public CSharpTagHelperCodeRenderer( - IChunkVisitor bodyVisitor, - CSharpCodeWriter writer, - CodeGeneratorContext context) - { - if (bodyVisitor == null) - { - throw new ArgumentNullException(nameof(bodyVisitor)); - } - - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - _bodyVisitor = bodyVisitor; - _writer = writer; - _context = context; - _tagHelperContext = context.Host.GeneratedClassContext.GeneratedTagHelperContext; - _designTimeMode = context.Host.DesignTimeMode; - - _literalBodyVisitor = new CSharpLiteralCodeVisitor(this, writer, context); - _attributeCodeVisitor = new TagHelperAttributeCodeVisitor(writer, context); - AttributeValueCodeRenderer = new TagHelperAttributeValueCodeRenderer(); - } - - public TagHelperAttributeValueCodeRenderer AttributeValueCodeRenderer { get; set; } - - /// - /// Renders the code for the given . - /// - /// A to render. - public void RenderTagHelper(TagHelperChunk chunk) - { - // Remove any duplicate TagHelperDescriptors that reference the same type name. Duplicates can occur when - // multiple HtmlTargetElement attributes are on a TagHelper type and matches overlap for an HTML element. - // Having more than one descriptor with the same TagHelper type results in generated code that runs - // the same TagHelper X many times (instead of once) over a single HTML element. - var tagHelperDescriptors = chunk.Descriptors.Distinct(TypeBasedTagHelperDescriptorComparer.Default); - - RenderBeginTagHelperScope(chunk.TagName, chunk.TagMode, chunk.Children); - - RenderTagHelpersCreation(chunk, tagHelperDescriptors); - - RenderAttributes(chunk.Attributes, tagHelperDescriptors); - - // No need to run anything in design time mode. - if (!_designTimeMode) - { - RenderRunTagHelpers(); - RenderWriteTagHelperMethodCall(chunk); - RenderEndTagHelpersScope(); - } - } - - internal static string GetVariableName(TagHelperDescriptor descriptor) - { - return "__" + descriptor.TypeName.Replace('.', '_'); - } - - private void RenderBeginTagHelperScope(string tagName, TagMode tagMode, IList children) - { - // Scopes/execution contexts are a runtime feature. - if (_designTimeMode) - { - // Render all of the tag helper children inline for IntelliSense. - _bodyVisitor.Accept(children); - return; - } - - // Call into the tag helper scope manager to start a new tag helper scope. - // Also capture the value as the current execution context. - _writer - .WriteStartAssignment(ExecutionContextVariableName) - .WriteStartInstanceMethodInvocation( - ScopeManagerVariableName, - _tagHelperContext.ScopeManagerBeginMethodName); - - // Assign a unique ID for this instance of the source HTML tag. This must be unique - // per call site, e.g. if the tag is on the view twice, there should be two IDs. - _writer.WriteStringLiteral(tagName) - .WriteParameterSeparator() - .Write(nameof(TagMode)) - .Write(".") - .Write(tagMode.ToString()) - .WriteParameterSeparator() - .WriteStringLiteral(GenerateUniqueId()) - .WriteParameterSeparator(); - - // We remove the target writer so TagHelper authors can retrieve content. - var oldWriter = _context.TargetWriterName; - _context.TargetWriterName = null; - - using (_writer.BuildAsyncLambda(endLine: false)) - { - // Render all of the tag helper children. - _bodyVisitor.Accept(children); - } - - _context.TargetWriterName = oldWriter; - - _writer.WriteParameterSeparator() - .Write(_tagHelperContext.StartTagHelperWritingScopeMethodName) - .WriteParameterSeparator() - .Write(_tagHelperContext.EndTagHelperWritingScopeMethodName) - .WriteEndMethodInvocation(); - } - - /// - /// Generates a unique ID for an HTML element. - /// - /// - /// A globally unique ID. - /// - protected virtual string GenerateUniqueId() - { - return Guid.NewGuid().ToString("N"); - } - - private void RenderTagHelpersCreation( - TagHelperChunk chunk, - IEnumerable tagHelperDescriptors) - { - // This is to maintain value accessors for attributes when creating the TagHelpers. - // Ultimately it enables us to do scenarios like this: - // myTagHelper1.Foo = DateTime.Now; - // myTagHelper2.Foo = myTagHelper1.Foo; - var htmlAttributeValues = new Dictionary(StringComparer.OrdinalIgnoreCase); - - foreach (var tagHelperDescriptor in tagHelperDescriptors) - { - var tagHelperVariableName = GetVariableName(tagHelperDescriptor); - - // Create the tag helper - _writer.WriteStartAssignment(tagHelperVariableName) - .WriteStartMethodInvocation(_tagHelperContext.CreateTagHelperMethodName, - tagHelperDescriptor.TypeName) - .WriteEndMethodInvocation(); - - // Execution contexts and throwing errors for null dictionary properties are a runtime feature. - if (_designTimeMode) - { - continue; - } - - _writer.WriteInstanceMethodInvocation( - ExecutionContextVariableName, - _tagHelperContext.ExecutionContextAddMethodName, - tagHelperVariableName); - - // Track dictionary properties we have confirmed are non-null. - var confirmedDictionaries = new HashSet(StringComparer.Ordinal); - - // Ensure that all created TagHelpers have initialized dictionary bound properties which are used - // via TagHelper indexers. - foreach (var chunkAttribute in chunk.Attributes) - { - var associatedAttributeDescriptor = tagHelperDescriptor.Attributes.FirstOrDefault( - attributeDescriptor => attributeDescriptor.IsNameMatch(chunkAttribute.Key)); - - if (associatedAttributeDescriptor != null && - associatedAttributeDescriptor.IsIndexer && - confirmedDictionaries.Add(associatedAttributeDescriptor.PropertyName)) - { - // Throw a reasonable Exception at runtime if the dictionary property is null. - _writer - .Write("if (") - .Write(tagHelperVariableName) - .Write(".") - .Write(associatedAttributeDescriptor.PropertyName) - .WriteLine(" == null)"); - using (_writer.BuildScope()) - { - // System is in Host.NamespaceImports for all MVC scenarios. No need to generate FullName - // of InvalidOperationException type. - _writer - .Write("throw ") - .WriteStartNewObject(nameof(InvalidOperationException)) - .WriteStartMethodInvocation(_tagHelperContext.FormatInvalidIndexerAssignmentMethodName) - .WriteStringLiteral(chunkAttribute.Key) - .WriteParameterSeparator() - .WriteStringLiteral(tagHelperDescriptor.TypeName) - .WriteParameterSeparator() - .WriteStringLiteral(associatedAttributeDescriptor.PropertyName) - .WriteEndMethodInvocation(endLine: false) // End of method call - .WriteEndMethodInvocation(endLine: true); // End of new expression / throw statement - } - } - } - } - } - - private void RenderAttributes( - IList> chunkAttributes, - IEnumerable tagHelperDescriptors) - { - var renderedBoundAttributeNames = new HashSet(StringComparer.OrdinalIgnoreCase); - - // Go through the HTML attributes in source order, assigning to properties or indexers or adding to - // TagHelperExecutionContext.HTMLAttributes' as we go. - foreach (var attribute in chunkAttributes) - { - var attributeName = attribute.Key; - var attributeValueChunk = attribute.Value; - var associatedDescriptors = tagHelperDescriptors.Where(descriptor => - descriptor.Attributes.Any(attributeDescriptor => attributeDescriptor.IsNameMatch(attributeName))); - - // Bound attributes have associated descriptors. First attribute value wins if there are duplicates; - // later values of duplicate bound attributes are treated as if they were unbound. - if (associatedDescriptors.Any() && renderedBoundAttributeNames.Add(attributeName)) - { - if (attributeValueChunk == null) - { - // Minimized attributes are not valid for bound attributes. TagHelperBlockRewriter has already - // logged an error if it was a bound attribute; so we can skip. - continue; - } - - // We need to capture the tag helper's property value accessor so we can retrieve it later - // if there are more tag helpers that need the value. - string valueAccessor = null; - - foreach (var associatedDescriptor in associatedDescriptors) - { - var associatedAttributeDescriptor = associatedDescriptor.Attributes.First( - attributeDescriptor => attributeDescriptor.IsNameMatch(attributeName)); - var tagHelperVariableName = GetVariableName(associatedDescriptor); - - valueAccessor = RenderBoundAttribute( - attributeName, - attributeValueChunk, - tagHelperVariableName, - valueAccessor, - associatedAttributeDescriptor); - } - } - else - { - RenderUnboundAttribute(attributeName, attributeValueChunk); - } - } - } - - private string RenderBoundAttribute( - string attributeName, - Chunk attributeValueChunk, - string tagHelperVariableName, - string previousValueAccessor, - TagHelperAttributeDescriptor attributeDescriptor) - { - var currentValueAccessor = string.Format( - CultureInfo.InvariantCulture, - "{0}.{1}", - tagHelperVariableName, - attributeDescriptor.PropertyName); - - if (attributeDescriptor.IsIndexer) - { - var dictionaryKey = attributeName.Substring(attributeDescriptor.Name.Length); - currentValueAccessor += $"[\"{dictionaryKey}\"]"; - } - - // If this attribute value has not been seen before, need to record its value. - if (previousValueAccessor == null) - { - // Bufferable attributes are attributes that can have Razor code inside of them. Such - // attributes have string values and may be calculated using a temporary TextWriter or other - // buffer. - var bufferableAttribute = attributeDescriptor.IsStringProperty; - - RenderNewAttributeValueAssignment( - attributeDescriptor, - bufferableAttribute, - attributeValueChunk, - currentValueAccessor); - - if (_designTimeMode) - { - // Execution contexts are a runtime feature. - return currentValueAccessor; - } - - // We need to inform the context of the attribute value. - _writer - .WriteStartInstanceMethodInvocation( - ExecutionContextVariableName, - _tagHelperContext.ExecutionContextAddTagHelperAttributeMethodName) - .WriteStringLiteral(attributeName) - .WriteParameterSeparator() - .Write(currentValueAccessor) - .WriteEndMethodInvocation(); - - return currentValueAccessor; - } - else - { - // The attribute value has already been determined and accessor was passed to us as - // previousValueAccessor, we don't want to evaluate the value twice so lets just use the - // previousValueLocation. - _writer - .WriteStartAssignment(currentValueAccessor) - .Write(previousValueAccessor) - .WriteLine(";"); - - return previousValueAccessor; - } - } - - // Render assignment of attribute value to the value accessor. - private void RenderNewAttributeValueAssignment( - TagHelperAttributeDescriptor attributeDescriptor, - bool bufferableAttribute, - Chunk attributeValueChunk, - string valueAccessor) - { - // Plain text values are non Razor code (@DateTime.Now) values. If an attribute is bufferable it - // may be more than just a plain text value, it may also contain Razor code which is why we attempt - // to retrieve a plain text value here. - string textValue; - var isPlainTextValue = TryGetPlainTextValue(attributeValueChunk, out textValue); - - if (bufferableAttribute) - { - if (!isPlainTextValue) - { - // If we haven't recorded a value and we need to buffer an attribute value and the value is not - // plain text then we need to prepare the value prior to setting it below. - BuildBufferedWritingScope(attributeValueChunk, htmlEncodeValues: false); - } - - _writer.WriteStartAssignment(valueAccessor); - - if (isPlainTextValue) - { - // If the attribute is bufferable but has a plain text value that means the value - // is a string which needs to be surrounded in quotes. - RenderQuotedAttributeValue(textValue, attributeDescriptor); - } - else - { - // The value contains more than plain text e.g. stringAttribute ="Time: @DateTime.Now". - RenderBufferedAttributeValue(attributeDescriptor); - } - - _writer.WriteLine(";"); - } - else - { - // Write out simple assignment for non-string property value. Try to keep the whole - // statement together and the #line pragma correct to make debugging possible. - using (var lineMapper = new CSharpLineMappingWriter( - _writer, - attributeValueChunk.Association.Start, - _context.SourceFile)) - { - // Place the assignment LHS to align RHS with original attribute value's indentation. - // Unfortunately originalIndent is incorrect if original line contains tabs. Unable to - // use a CSharpPaddingBuilder because the Association has no Previous node; lost the - // original Span sequence when the parse tree was rewritten. - var originalIndent = attributeValueChunk.Start.CharacterIndex; - var generatedLength = valueAccessor.Length + " = ".Length; - var newIndent = originalIndent - generatedLength; - if (newIndent > 0) - { - _writer.Indent(newIndent); - } - - _writer.WriteStartAssignment(valueAccessor); - lineMapper.MarkLineMappingStart(); - - // Write out bare expression for this attribute value. Property is not a string. - // So quoting or buffering are not helpful. - RenderRawAttributeValue(attributeValueChunk, attributeDescriptor, isPlainTextValue); - - // End the assignment to the attribute. - lineMapper.MarkLineMappingEnd(); - _writer.WriteLine(";"); - } - } - } - - private void RenderUnboundAttribute(string attributeName, Chunk attributeValueChunk) - { - // Render children to provide IntelliSense at design time. No need for the execution context logic, it's - // a runtime feature. - if (_designTimeMode) - { - if (attributeValueChunk != null) - { - _bodyVisitor.Accept(attributeValueChunk); - } - - return; - } - - // If we have a minimized attribute there is no value - if (attributeValueChunk == null) - { - _writer - .WriteStartInstanceMethodInvocation( - ExecutionContextVariableName, - _tagHelperContext.ExecutionContextAddMinimizedHtmlAttributeMethodName) - .WriteStringLiteral(attributeName) - .WriteEndMethodInvocation(); - } - else - { - string textValue = null; - var isPlainTextValue = TryGetPlainTextValue(attributeValueChunk, out textValue); - - if (isPlainTextValue) - { - // If it's a plain text value then we need to surround the value with quotes. - _writer - .WriteStartInstanceMethodInvocation( - ExecutionContextVariableName, - _tagHelperContext.ExecutionContextAddHtmlAttributeMethodName) - .WriteStringLiteral(attributeName) - .WriteParameterSeparator() - .WriteStartMethodInvocation(_tagHelperContext.MarkAsHtmlEncodedMethodName) - .WriteStringLiteral(textValue) - .WriteEndMethodInvocation(endLine: false) - .WriteEndMethodInvocation(); - } - else if (IsDynamicAttributeValue(attributeValueChunk)) - { - // Dynamic attribute value should be run through the conditional attribute removal system. It's - // unbound and contains C#. - - // TagHelper attribute rendering is buffered by default. We do not want to write to the current - // writer. - var currentTargetWriter = _context.TargetWriterName; - var currentWriteAttributeMethodName = _context.Host.GeneratedClassContext.WriteAttributeValueMethodName; - _context.TargetWriterName = null; - - Debug.Assert(attributeValueChunk is ParentChunk); - var children = ((ParentChunk)attributeValueChunk).Children; - var attributeCount = children.Count(c => c is DynamicCodeAttributeChunk || c is LiteralCodeAttributeChunk); - - _writer - .WriteStartMethodInvocation(_tagHelperContext.BeginAddHtmlAttributeValuesMethodName) - .Write(ExecutionContextVariableName) - .WriteParameterSeparator() - .WriteStringLiteral(attributeName) - .WriteParameterSeparator() - .Write(attributeCount.ToString(CultureInfo.InvariantCulture)) - .WriteEndMethodInvocation(); - - _attributeCodeVisitor.Accept(attributeValueChunk); - - _writer.WriteMethodInvocation( - _tagHelperContext.EndAddHtmlAttributeValuesMethodName, - ExecutionContextVariableName); - - _context.TargetWriterName = currentTargetWriter; - } - else - { - // HTML attributes are always strings. This attribute contains C# but is not dynamic. This occurs - // when the attribute is a data-* attribute. - - // Attribute value is not plain text, must be buffered to determine its final value. - BuildBufferedWritingScope(attributeValueChunk, htmlEncodeValues: true); - - _writer - .WriteStartInstanceMethodInvocation( - ExecutionContextVariableName, - _tagHelperContext.ExecutionContextAddHtmlAttributeMethodName) - .WriteStringLiteral(attributeName) - .WriteParameterSeparator() - .WriteStartMethodInvocation(_tagHelperContext.MarkAsHtmlEncodedMethodName); - - RenderBufferedAttributeValueAccessor(_writer); - - _writer - .WriteEndMethodInvocation(endLine: false) - .WriteEndMethodInvocation(); - } - } - } - - private void RenderEndTagHelpersScope() - { - _writer.WriteStartAssignment(ExecutionContextVariableName) - .WriteInstanceMethodInvocation(ScopeManagerVariableName, - _tagHelperContext.ScopeManagerEndMethodName); - } - - private void RenderWriteTagHelperMethodCall(TagHelperChunk chunk) - { - _writer - .WriteStartInstrumentationContext(_context, chunk.Association, isLiteral: false) - .Write("await "); - - if (!string.IsNullOrEmpty(_context.TargetWriterName)) - { - _writer - .WriteStartMethodInvocation(_tagHelperContext.WriteTagHelperToAsyncMethodName) - .Write(_context.TargetWriterName) - .WriteParameterSeparator(); - } - else - { - _writer.WriteStartMethodInvocation(_tagHelperContext.WriteTagHelperAsyncMethodName); - } - - _writer - .Write(ExecutionContextVariableName) - .WriteEndMethodInvocation() - .WriteEndInstrumentationContext(_context); - } - - private void RenderRunTagHelpers() - { - _writer.Write(ExecutionContextVariableName) - .Write(".") - .WriteStartAssignment(_tagHelperContext.ExecutionContextOutputPropertyName) - .Write("await ") - .WriteStartInstanceMethodInvocation(RunnerVariableName, - _tagHelperContext.RunnerRunAsyncMethodName); - - _writer.Write(ExecutionContextVariableName) - .WriteEndMethodInvocation(); - } - - private void RenderBufferedAttributeValue(TagHelperAttributeDescriptor attributeDescriptor) - { - // Pass complexValue: false because variable.ToString() replaces any original complexity in the expression. - RenderAttributeValue( - attributeDescriptor, - valueRenderer: (writer) => - { - RenderBufferedAttributeValueAccessor(writer); - }, - complexValue: false); - } - - private void RenderRawAttributeValue( - Chunk attributeValueChunk, - TagHelperAttributeDescriptor attributeDescriptor, - bool isPlainTextValue) - { - RenderAttributeValue( - attributeDescriptor, - valueRenderer: (writer) => - { - var visitor = - new CSharpTagHelperAttributeValueVisitor(writer, _context, attributeDescriptor.TypeName); - visitor.Accept(attributeValueChunk); - }, - complexValue: !isPlainTextValue); - } - - private void RenderQuotedAttributeValue(string value, TagHelperAttributeDescriptor attributeDescriptor) - { - RenderAttributeValue( - attributeDescriptor, - valueRenderer: (writer) => - { - writer.WriteStringLiteral(value); - }, - complexValue: false); - } - - // Render a buffered writing scope for the HTML attribute value. - private void BuildBufferedWritingScope(Chunk htmlAttributeChunk, bool htmlEncodeValues) - { - // We're building a writing scope around the provided chunks which captures everything written from the - // page. Therefore, we do not want to write to any other buffer since we're using the pages buffer to - // ensure we capture all content that's written, directly or indirectly. - var oldWriter = _context.TargetWriterName; - _context.TargetWriterName = null; - - // Need to disable instrumentation inside of writing scopes, the instrumentation will not detect - // content written inside writing scopes. - var oldInstrumentation = _context.Host.EnableInstrumentation; - - try - { - _context.Host.EnableInstrumentation = false; - - // Scopes are a runtime feature. - if (!_designTimeMode) - { - _writer.WriteMethodInvocation(_tagHelperContext.StartTagHelperWritingScopeMethodName); - } - - var visitor = htmlEncodeValues ? _bodyVisitor : _literalBodyVisitor; - visitor.Accept(htmlAttributeChunk); - - // Scopes are a runtime feature. - if (!_designTimeMode) - { - _writer.WriteStartAssignment(StringValueBufferVariableName) - .WriteMethodInvocation(_tagHelperContext.EndTagHelperWritingScopeMethodName); - } - } - finally - { - // Reset instrumentation back to what it was, leaving the writing scope. - _context.Host.EnableInstrumentation = oldInstrumentation; - - // Reset the writer/buffer back to what it was, leaving the writing scope. - _context.TargetWriterName = oldWriter; - } - } - - private void RenderAttributeValue(TagHelperAttributeDescriptor attributeDescriptor, - Action valueRenderer, - bool complexValue) - { - AttributeValueCodeRenderer.RenderAttributeValue( - attributeDescriptor, - _writer, - _context, - valueRenderer, - complexValue); - } - - private void RenderBufferedAttributeValueAccessor(CSharpCodeWriter writer) - { - if (_designTimeMode) - { - // There is no value buffer in design time mode but we still want to write out a value. We write a - // value to ensure the tag helper's property type is string. - writer.Write("string.Empty"); - } - else - { - writer.WriteInstanceMethodInvocation( - StringValueBufferVariableName, - _tagHelperContext.TagHelperContentGetContentMethodName, - endLine: false, - parameters: new string[] { _tagHelperContext.HtmlEncoderPropertyName }); - } - } - - private static bool IsDynamicAttributeValue(Chunk attributeValueChunk) - { - var parentChunk = attributeValueChunk as ParentChunk; - if (parentChunk != null) - { - return parentChunk.Children.Any(child => child is DynamicCodeAttributeChunk); - } - - return false; - } - - private static bool TryGetPlainTextValue(Chunk chunk, out string plainText) - { - var parentChunk = chunk as ParentChunk; - - plainText = null; - - if (parentChunk == null || parentChunk.Children.Count != 1) - { - return false; - } - - var literalChildChunk = parentChunk.Children[0] as LiteralChunk; - - if (literalChildChunk == null) - { - return false; - } - - plainText = literalChildChunk.Text; - - return true; - } - - // A CSharpCodeVisitor which does not HTML encode values. Used when rendering bound string attribute values. - private class CSharpLiteralCodeVisitor : CSharpCodeVisitor - { - public CSharpLiteralCodeVisitor( - CSharpTagHelperCodeRenderer tagHelperRenderer, - CSharpCodeWriter writer, - CodeGeneratorContext context) - : base(writer, context) - { - // Ensure that no matter how this class is used, we don't create numerous CSharpTagHelperCodeRenderer - // instances. - TagHelperRenderer = tagHelperRenderer; - } - - protected override string WriteMethodName - { - get - { - return Context.Host.GeneratedClassContext.WriteLiteralMethodName; - } - } - - protected override string WriteToMethodName - { - get - { - return Context.Host.GeneratedClassContext.WriteLiteralToMethodName; - } - } - } - - private class TagHelperAttributeCodeVisitor : CSharpCodeVisitor - { - public TagHelperAttributeCodeVisitor( - CSharpCodeWriter writer, - CodeGeneratorContext context) - : base(writer, context) - { - } - - protected override string WriteAttributeValueMethodName => - Context.Host.GeneratedClassContext.GeneratedTagHelperContext.AddHtmlAttributeValueMethodName; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeGenerator.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeGenerator.cs deleted file mode 100644 index e4930f42cb..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeGenerator.cs +++ /dev/null @@ -1,22 +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. - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public abstract class CodeGenerator - { - private readonly CodeGeneratorContext _context; - - public CodeGenerator(CodeGeneratorContext context) - { - _context = context; - } - - protected CodeGeneratorContext Context - { - get { return _context; } - } - - public abstract CodeGeneratorResult Generate(); - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeGeneratorContext.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeGeneratorContext.cs deleted file mode 100644 index b3dc00fcdc..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeGeneratorContext.cs +++ /dev/null @@ -1,75 +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 Microsoft.AspNet.Razor.Chunks.Generators; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - /// - /// Context object with information used to generate a Razor page. - /// - public class CodeGeneratorContext : ChunkGeneratorContext - { - /// - /// Instantiates a new instance of the object. - /// - /// A to copy information from. - /// - /// The used to collect s encountered - /// when parsing the current Razor document. - /// - public CodeGeneratorContext(ChunkGeneratorContext generatorContext, ErrorSink errorSink) - : base(generatorContext) - { - ErrorSink = errorSink; - ExpressionRenderingMode = ExpressionRenderingMode.WriteToOutput; - } - - // Internal for testing. - internal CodeGeneratorContext( - RazorEngineHost host, - string className, - string rootNamespace, - string sourceFile, - bool shouldGenerateLinePragmas, - ErrorSink errorSink) - : base(host, className, rootNamespace, sourceFile, shouldGenerateLinePragmas) - { - ErrorSink = errorSink; - ExpressionRenderingMode = ExpressionRenderingMode.WriteToOutput; - } - - /// - /// The current C# rendering mode. - /// - /// - /// forces C# generation to write - /// s to the output page, i.e. WriteLiteral("Hello World"). - /// writes values in their - /// rawest form, i.g. "Hello World". - /// - public ExpressionRenderingMode ExpressionRenderingMode { get; set; } - - /// - /// The C# writer to write information to. - /// - /// - /// If is null values will be written using a default write method - /// i.e. WriteLiteral("Hello World"). - /// If is not null values will be written to the given - /// , i.e. WriteLiteralTo(myWriter, "Hello World"). - /// - public string TargetWriterName { get; set; } - - /// - /// Gets or sets the SHA1 based checksum for the file whose location is defined by - /// . - /// - public string Checksum { get; set; } - - /// - /// Used to aggregate s. - /// - public ErrorSink ErrorSink { get; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeGeneratorResult.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeGeneratorResult.cs deleted file mode 100644 index 2d03a5fd4f..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeGeneratorResult.cs +++ /dev/null @@ -1,19 +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.Collections.Generic; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public class CodeGeneratorResult - { - public CodeGeneratorResult(string code, IList designTimeLineMappings) - { - Code = code; - DesignTimeLineMappings = designTimeLineMappings; - } - - public string Code { get; private set; } - public IList DesignTimeLineMappings { get; private set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeWriter.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeWriter.cs deleted file mode 100644 index 8190243d03..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/CodeWriter.cs +++ /dev/null @@ -1,216 +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; -using System.IO; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public class CodeWriter : IDisposable - { - private static readonly char[] NewLineCharacters = new char[] { '\r', '\n' }; - private readonly StringWriter _writer = new StringWriter(); - private bool _newLine; - private string _cache = string.Empty; - private bool _dirty = false; - - private int _absoluteIndex; - private int _currentLineIndex; - private int _currentLineCharacterIndex; - - public string LastWrite { get; private set; } - - public int CurrentIndent { get; private set; } - - public string NewLine - { - get - { - return _writer.NewLine; - } - set - { - _writer.NewLine = value; - } - } - - public CodeWriter ResetIndent() - { - return SetIndent(0); - } - - public CodeWriter IncreaseIndent(int size) - { - CurrentIndent += size; - - return this; - } - - public CodeWriter DecreaseIndent(int size) - { - CurrentIndent -= size; - - return this; - } - - public CodeWriter SetIndent(int size) - { - CurrentIndent = size; - - return this; - } - - public CodeWriter Indent(int size) - { - if (_newLine) - { - _writer.Write(new string(' ', size)); - Flush(); - - _currentLineCharacterIndex += size; - _absoluteIndex += size; - - _dirty = true; - _newLine = false; - } - - return this; - } - - public CodeWriter Write(string data) - { - Indent(CurrentIndent); - - _writer.Write(data); - Flush(); - - LastWrite = data; - _dirty = true; - _newLine = false; - - if (data == null || data.Length == 0) - { - return this; - } - - _absoluteIndex += data.Length; - - // The data string might contain a partial newline where the previously - // written string has part of the newline. - var i = 0; - int? trailingPartStart = null; - var builder = _writer.GetStringBuilder(); - - if ( - // Check the last character of the previous write operation. - builder.Length - data.Length - 1 >= 0 && - builder[builder.Length - data.Length - 1] == '\r' && - - // Check the first character of the current write operation. - builder[builder.Length - data.Length] == '\n') - { - // This is newline that's spread across two writes. Skip the first character of the - // current write operation. - // - // We don't need to increment our newline counter because we already did that when we - // saw the \r. - i += 1; - trailingPartStart = 1; - } - - // Iterate the string, stopping at each occurrence of a newline character. This lets us count the - // newline occurrences and keep the index of the last one. - while ((i = data.IndexOfAny(NewLineCharacters, i)) >= 0) - { - // Newline found. - _currentLineIndex++; - _currentLineCharacterIndex = 0; - - i++; - - // We might have stopped at a \r, so check if it's followed by \n and then advance the index to - // start the next search after it. - if (data.Length > i && - data[i - 1] == '\r' && - data[i] == '\n') - { - i++; - } - - // The 'suffix' of the current line starts after this newline token. - trailingPartStart = i; - } - - if (trailingPartStart == null) - { - // No newlines, just add the length of the data buffer - _currentLineCharacterIndex += data.Length; - } - else - { - // Newlines found, add the trailing part of 'data' - _currentLineCharacterIndex += (data.Length - trailingPartStart.Value); - } - - return this; - } - - public CodeWriter WriteLine() - { - LastWrite = _writer.NewLine; - - _writer.WriteLine(); - Flush(); - - _currentLineIndex++; - _currentLineCharacterIndex = 0; - _absoluteIndex += _writer.NewLine.Length; - - _dirty = true; - _newLine = true; - - return this; - } - - public CodeWriter WriteLine(string data) - { - return Write(data).WriteLine(); - } - - public CodeWriter Flush() - { - _writer.Flush(); - - return this; - } - - public string GenerateCode() - { - if (_dirty) - { - _cache = _writer.ToString(); - _dirty = false; - } - - return _cache; - } - - public SourceLocation GetCurrentSourceLocation() - { - return new SourceLocation(_absoluteIndex, _currentLineIndex, _currentLineCharacterIndex); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _writer.Dispose(); - } - } - - public void Dispose() - { - Dispose(disposing: true); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/ExpressionRenderingMode.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/ExpressionRenderingMode.cs deleted file mode 100644 index d580d375f1..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/ExpressionRenderingMode.cs +++ /dev/null @@ -1,29 +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. - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public enum ExpressionRenderingMode - { - /// - /// Indicates that expressions should be written to the output stream - /// - /// - /// If @foo is rendered with WriteToOutput, the code generator would output the following code: - /// - /// Write(foo); - /// - WriteToOutput, - - /// - /// Indicates that expressions should simply be placed as-is in the code, and the context in which - /// the code exists will be used to render it - /// - /// - /// If @foo is rendered with InjectCode, the code generator would output the following code: - /// - /// foo - /// - InjectCode - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/GeneratedClassContext.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/GeneratedClassContext.cs deleted file mode 100644 index 71eba9c828..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/GeneratedClassContext.cs +++ /dev/null @@ -1,219 +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; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public struct GeneratedClassContext - { - public static readonly string DefaultWriteMethodName = "Write"; - public static readonly string DefaultWriteLiteralMethodName = "WriteLiteral"; - public static readonly string DefaultExecuteMethodName = "ExecuteAsync"; - public static readonly string DefaultBeginWriteAttributeMethodName = "BeginWriteAttribute"; - public static readonly string DefaultBeginWriteAttributeToMethodName = "BeginWriteAttributeTo"; - public static readonly string DefaultEndWriteAttributeMethodName = "EndWriteAttribute"; - public static readonly string DefaultEndWriteAttributeToMethodName = "EndWriteAttributeTo"; - public static readonly string DefaultWriteAttributeValueMethodName = "WriteAttributeValue"; - public static readonly string DefaultWriteAttributeValueToMethodName = "WriteAttributeValueTo"; - - public static readonly GeneratedClassContext Default = - new GeneratedClassContext( - DefaultExecuteMethodName, - DefaultWriteMethodName, - DefaultWriteLiteralMethodName, - new GeneratedTagHelperContext()); - - public GeneratedClassContext( - string executeMethodName, - string writeMethodName, - string writeLiteralMethodName, - GeneratedTagHelperContext generatedTagHelperContext) - : this() - { - if (generatedTagHelperContext == null) - { - throw new ArgumentNullException(nameof(generatedTagHelperContext)); - } - - if (string.IsNullOrEmpty(executeMethodName)) - { - throw new ArgumentException( - CommonResources.Argument_Cannot_Be_Null_Or_Empty, - nameof(executeMethodName)); - } - if (string.IsNullOrEmpty(writeMethodName)) - { - throw new ArgumentException( - CommonResources.Argument_Cannot_Be_Null_Or_Empty, - nameof(writeMethodName)); - } - if (string.IsNullOrEmpty(writeLiteralMethodName)) - { - throw new ArgumentException( - CommonResources.Argument_Cannot_Be_Null_Or_Empty, - nameof(writeLiteralMethodName)); - } - - GeneratedTagHelperContext = generatedTagHelperContext; - - WriteMethodName = writeMethodName; - WriteLiteralMethodName = writeLiteralMethodName; - ExecuteMethodName = executeMethodName; - - WriteToMethodName = null; - WriteLiteralToMethodName = null; - TemplateTypeName = null; - DefineSectionMethodName = null; - - BeginWriteAttributeMethodName = DefaultBeginWriteAttributeMethodName; - BeginWriteAttributeToMethodName = DefaultBeginWriteAttributeToMethodName; - EndWriteAttributeMethodName = DefaultEndWriteAttributeMethodName; - EndWriteAttributeToMethodName = DefaultEndWriteAttributeToMethodName; - WriteAttributeValueMethodName = DefaultWriteAttributeValueMethodName; - WriteAttributeValueToMethodName = DefaultWriteAttributeValueToMethodName; - } - - public GeneratedClassContext( - string executeMethodName, - string writeMethodName, - string writeLiteralMethodName, - string writeToMethodName, - string writeLiteralToMethodName, - string templateTypeName, - GeneratedTagHelperContext generatedTagHelperContext) - : this(executeMethodName, - writeMethodName, - writeLiteralMethodName, - generatedTagHelperContext) - { - WriteToMethodName = writeToMethodName; - WriteLiteralToMethodName = writeLiteralToMethodName; - TemplateTypeName = templateTypeName; - } - - public GeneratedClassContext( - string executeMethodName, - string writeMethodName, - string writeLiteralMethodName, - string writeToMethodName, - string writeLiteralToMethodName, - string templateTypeName, - string defineSectionMethodName, - GeneratedTagHelperContext generatedTagHelperContext) - : this(executeMethodName, - writeMethodName, - writeLiteralMethodName, - writeToMethodName, - writeLiteralToMethodName, - templateTypeName, - generatedTagHelperContext) - { - DefineSectionMethodName = defineSectionMethodName; - } - - public GeneratedClassContext( - string executeMethodName, - string writeMethodName, - string writeLiteralMethodName, - string writeToMethodName, - string writeLiteralToMethodName, - string templateTypeName, - string defineSectionMethodName, - string beginContextMethodName, - string endContextMethodName, - GeneratedTagHelperContext generatedTagHelperContext) - : this(executeMethodName, - writeMethodName, - writeLiteralMethodName, - writeToMethodName, - writeLiteralToMethodName, - templateTypeName, - defineSectionMethodName, - generatedTagHelperContext) - { - BeginContextMethodName = beginContextMethodName; - EndContextMethodName = endContextMethodName; - } - - // Required Items - public string WriteMethodName { get; } - public string WriteLiteralMethodName { get; } - public string WriteToMethodName { get; } - public string WriteLiteralToMethodName { get; } - public string ExecuteMethodName { get; } - public GeneratedTagHelperContext GeneratedTagHelperContext { get; } - - // Optional Items - public string BeginContextMethodName { get; set; } - public string EndContextMethodName { get; set; } - public string DefineSectionMethodName { get; set; } - public string TemplateTypeName { get; set; } - - public string BeginWriteAttributeMethodName { get; set; } - public string BeginWriteAttributeToMethodName { get; set; } - public string EndWriteAttributeMethodName { get; set; } - public string EndWriteAttributeToMethodName { get; set; } - public string WriteAttributeValueMethodName { get; set; } - public string WriteAttributeValueToMethodName { get; set; } - - public bool AllowSections - { - get { return !string.IsNullOrEmpty(DefineSectionMethodName); } - } - - public bool AllowTemplates - { - get { return !string.IsNullOrEmpty(TemplateTypeName); } - } - - public bool SupportsInstrumentation - { - get { return !string.IsNullOrEmpty(BeginContextMethodName) && !string.IsNullOrEmpty(EndContextMethodName); } - } - - public override bool Equals(object obj) - { - if (!(obj is GeneratedClassContext)) - { - return false; - } - - var other = (GeneratedClassContext)obj; - return string.Equals(DefineSectionMethodName, other.DefineSectionMethodName, StringComparison.Ordinal) && - string.Equals(WriteMethodName, other.WriteMethodName, StringComparison.Ordinal) && - string.Equals(WriteLiteralMethodName, other.WriteLiteralMethodName, StringComparison.Ordinal) && - string.Equals(WriteToMethodName, other.WriteToMethodName, StringComparison.Ordinal) && - string.Equals(WriteLiteralToMethodName, other.WriteLiteralToMethodName, StringComparison.Ordinal) && - string.Equals(ExecuteMethodName, other.ExecuteMethodName, StringComparison.Ordinal) && - string.Equals(TemplateTypeName, other.TemplateTypeName, StringComparison.Ordinal) && - string.Equals(BeginContextMethodName, other.BeginContextMethodName, StringComparison.Ordinal) && - string.Equals(EndContextMethodName, other.EndContextMethodName, StringComparison.Ordinal); - } - - public override int GetHashCode() - { - // Hash code should include only immutable properties. - var hashCodeCombiner = HashCodeCombiner.Start(); - - hashCodeCombiner.Add(WriteMethodName, StringComparer.Ordinal); - hashCodeCombiner.Add(WriteLiteralMethodName, StringComparer.Ordinal); - hashCodeCombiner.Add(WriteToMethodName, StringComparer.Ordinal); - hashCodeCombiner.Add(WriteLiteralToMethodName, StringComparer.Ordinal); - hashCodeCombiner.Add(ExecuteMethodName, StringComparer.Ordinal); - - return hashCodeCombiner; - } - - public static bool operator ==(GeneratedClassContext left, GeneratedClassContext right) - { - return left.Equals(right); - } - - public static bool operator !=(GeneratedClassContext left, GeneratedClassContext right) - { - return !left.Equals(right); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/GeneratedTagHelperContext.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/GeneratedTagHelperContext.cs deleted file mode 100644 index 138f9a74f1..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/GeneratedTagHelperContext.cs +++ /dev/null @@ -1,209 +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. - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - /// - /// Contains necessary information for the tag helper code generation process. - /// - public class GeneratedTagHelperContext - { - /// - /// Instantiates a new instance of the with default values. - /// - public GeneratedTagHelperContext() - { - BeginAddHtmlAttributeValuesMethodName = "BeginAddHtmlAttributeValues"; - EndAddHtmlAttributeValuesMethodName = "EndAddHtmlAttributeValues"; - AddHtmlAttributeValueMethodName = "AddHtmlAttributeValue"; - CreateTagHelperMethodName = "CreateTagHelper"; - RunnerRunAsyncMethodName = "RunAsync"; - ScopeManagerBeginMethodName = "Begin"; - ScopeManagerEndMethodName = "End"; - ExecutionContextAddMethodName = "Add"; - ExecutionContextAddTagHelperAttributeMethodName = "AddTagHelperAttribute"; - ExecutionContextAddMinimizedHtmlAttributeMethodName = "AddMinimizedHtmlAttribute"; - ExecutionContextAddHtmlAttributeMethodName = "AddHtmlAttribute"; - ExecutionContextOutputPropertyName = "Output"; - FormatInvalidIndexerAssignmentMethodName = "FormatInvalidIndexerAssignment"; - MarkAsHtmlEncodedMethodName = "Html.Raw"; - StartTagHelperWritingScopeMethodName = "StartTagHelperWritingScope"; - EndTagHelperWritingScopeMethodName = "EndTagHelperWritingScope"; - RunnerTypeName = "TagHelperRunner"; - ScopeManagerTypeName = "TagHelperScopeManager"; - ExecutionContextTypeName = "TagHelperExecutionContext"; - TagHelperContentTypeName = "TagHelperContent"; - WriteTagHelperAsyncMethodName = "WriteTagHelperAsync"; - WriteTagHelperToAsyncMethodName = "WriteTagHelperToAsync"; - TagHelperContentGetContentMethodName = "GetContent"; - HtmlEncoderPropertyName = "HtmlEncoder"; - } - - /// - /// The name of the method used to begin the addition of unbound, complex tag helper attributes to - /// TagHelperExecutionContexts. - /// - /// - /// Method signature should be - /// - /// public void BeginAddHtmlAttributeValues( - /// TagHelperExecutionContext executionContext, - /// string attributeName) - /// - /// - public string BeginAddHtmlAttributeValuesMethodName { get; set; } - - /// - /// Method name used to end addition of unbound, complex tag helper attributes to TagHelperExecutionContexts. - /// - /// - /// Method signature should be - /// - /// public void EndAddHtmlAttributeValues( - /// TagHelperExecutionContext executionContext) - /// - /// - public string EndAddHtmlAttributeValuesMethodName { get; set; } - - /// - /// Method name used to add individual components of an unbound, complex tag helper attribute to - /// TagHelperExecutionContexts. - /// - /// - /// Method signature: - /// - /// public void AddHtmlAttributeValues( - /// string prefix, - /// int prefixOffset, - /// string value, - /// int valueOffset, - /// int valueLength, - /// bool isLiteral) - /// - /// - public string AddHtmlAttributeValueMethodName { get; set; } - - /// - /// The name of the method used to create a tag helper. - /// - public string CreateTagHelperMethodName { get; set; } - - /// - /// The name of the method used to run tag helpers. - /// - public string RunnerRunAsyncMethodName { get; set; } - - /// - /// The name of the method used to start a scope. - /// - public string ScopeManagerBeginMethodName { get; set; } - - /// - /// The name of the method used to end a scope. - /// - public string ScopeManagerEndMethodName { get; set; } - - /// - /// The name of the method used to add tag helper attributes. - /// - public string ExecutionContextAddTagHelperAttributeMethodName { get; set; } - - /// - /// The name of the method used to add minimized HTML attributes. - /// - public string ExecutionContextAddMinimizedHtmlAttributeMethodName { get; set; } - - /// - /// The name of the method used to add HTML attributes. - /// - public string ExecutionContextAddHtmlAttributeMethodName { get; set; } - - /// - /// The name of the method used to add tag helpers. - /// - public string ExecutionContextAddMethodName { get; set; } - - /// - /// The property accessor for the tag helper's output. - /// - public string ExecutionContextOutputPropertyName { get; set; } - - /// - /// The name of the method used to format an error message about using an indexer when the tag helper property - /// is null. - /// - /// - /// Method signature should be - /// - /// public string FormatInvalidIndexerAssignment( - /// string attributeName, // Name of the HTML attribute associated with the indexer. - /// string tagHelperTypeName, // Full name of the tag helper type. - /// string propertyName) // Dictionary property in the tag helper. - /// - /// - public string FormatInvalidIndexerAssignmentMethodName { get; set; } - - /// - /// The name of the method used to wrap a value and mark it as HTML-encoded. - /// - /// Used together with . - public string MarkAsHtmlEncodedMethodName { get; set; } - - /// - /// The name of the method used to start a new writing scope. - /// - public string StartTagHelperWritingScopeMethodName { get; set; } - - /// - /// The name of the method used to end a writing scope. - /// - public string EndTagHelperWritingScopeMethodName { get; set; } - - /// - /// The name of the type used to run tag helpers. - /// - public string RunnerTypeName { get; set; } - - /// - /// The name of the type used to create scoped instances. - /// - public string ScopeManagerTypeName { get; set; } - - /// - /// The name of the type describing a specific tag helper scope. - /// - /// - /// Contains information about in-scope tag helpers, HTML attributes, and the tag helpers' output. - /// - public string ExecutionContextTypeName { get; set; } - - /// - /// The name of the type containing tag helper content. - /// - /// - /// Contains the data returned by EndTagHelperWriteScope(). - /// - public string TagHelperContentTypeName { get; set; } - - /// - /// The name of the method used to write . - /// - public string WriteTagHelperAsyncMethodName { get; set; } - - /// - /// The name of the method used to write to a specified - /// . - /// - public string WriteTagHelperToAsyncMethodName { get; set; } - - /// - /// The name of the property containing the IHtmlEncoder. - /// - public string HtmlEncoderPropertyName { get; set; } - - /// - /// The name of the method used to convert a TagHelperContent into a . - /// - public string TagHelperContentGetContentMethodName { get; set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/GeneratorResults.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/GeneratorResults.cs deleted file mode 100644 index c9094c1948..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/GeneratorResults.cs +++ /dev/null @@ -1,111 +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; -using System.Collections.Generic; -using Microsoft.AspNet.Razor.Chunks; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Compilation.TagHelpers; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - /// - /// The results of parsing and generating code for a Razor document. - /// - public class GeneratorResults : ParserResults - { - /// - /// Instantiates a new instance. - /// - /// The results of parsing a document. - /// The results of generating code for the document. - /// A for the document. - public GeneratorResults(ParserResults parserResults, - CodeGeneratorResult codeGeneratorResult, - ChunkTree chunkTree) - : this(parserResults.Document, - parserResults.TagHelperDescriptors, - parserResults.ErrorSink, - codeGeneratorResult, - chunkTree) - { - if (parserResults == null) - { - throw new ArgumentNullException(nameof(parserResults)); - } - if (codeGeneratorResult == null) - { - throw new ArgumentNullException(nameof(codeGeneratorResult)); - } - if (chunkTree == null) - { - throw new ArgumentNullException(nameof(chunkTree)); - } - } - - /// - /// Instantiates a new instance. - /// - /// The for the syntax tree. - /// - /// The s that apply to the current Razor document. - /// - /// - /// The used to collect s encountered when parsing the - /// current Razor document. - /// - /// The results of generating code for the document. - /// A for the document. - public GeneratorResults(Block document, - IEnumerable tagHelperDescriptors, - ErrorSink errorSink, - CodeGeneratorResult codeGeneratorResult, - ChunkTree chunkTree) - : base(document, tagHelperDescriptors, errorSink) - { - if (document == null) - { - throw new ArgumentNullException(nameof(document)); - } - - if (tagHelperDescriptors == null) - { - throw new ArgumentNullException(nameof(tagHelperDescriptors)); - } - - if (errorSink == null) - { - throw new ArgumentNullException(nameof(errorSink)); - } - - if (codeGeneratorResult == null) - { - throw new ArgumentNullException(nameof(codeGeneratorResult)); - } - - if (chunkTree == null) - { - throw new ArgumentNullException(nameof(chunkTree)); - } - - GeneratedCode = codeGeneratorResult.Code; - DesignTimeLineMappings = codeGeneratorResult.DesignTimeLineMappings; - ChunkTree = chunkTree; - } - - /// - /// The generated code for the document. - /// - public string GeneratedCode { get; } - - /// - /// s used to project code from a file during design time. - /// - public IList DesignTimeLineMappings { get; } - - /// - /// A for the document. - /// - public ChunkTree ChunkTree { get; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/LineMapping.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/LineMapping.cs deleted file mode 100644 index f8dfc4d1cb..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/LineMapping.cs +++ /dev/null @@ -1,79 +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.Globalization; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public class LineMapping - { - public LineMapping(MappingLocation documentLocation, MappingLocation generatedLocation) - { - DocumentLocation = documentLocation; - GeneratedLocation = generatedLocation; - } - - public MappingLocation DocumentLocation { get; } - - public MappingLocation GeneratedLocation { get; } - - public override bool Equals(object obj) - { - var other = obj as LineMapping; - if (ReferenceEquals(other, null)) - { - return false; - } - - return DocumentLocation.Equals(other.DocumentLocation) && - GeneratedLocation.Equals(other.GeneratedLocation); - } - - public override int GetHashCode() - { - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(DocumentLocation); - hashCodeCombiner.Add(GeneratedLocation); - - return hashCodeCombiner; - } - - public static bool operator ==(LineMapping left, LineMapping right) - { - if (ReferenceEquals(left, right)) - { - // Exact equality e.g. both objects are null. - return true; - } - - if (ReferenceEquals(left, null)) - { - return false; - } - - return left.Equals(right); - } - - public static bool operator !=(LineMapping left, LineMapping right) - { - if (ReferenceEquals(left, right)) - { - // Exact equality e.g. both objects are null. - return false; - } - - if (ReferenceEquals(left, null)) - { - return true; - } - - return !left.Equals(right); - } - - public override string ToString() - { - return string.Format(CultureInfo.CurrentUICulture, "{0} -> {1}", DocumentLocation, GeneratedLocation); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/LineMappingManager.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/LineMappingManager.cs deleted file mode 100644 index 584a83111a..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/LineMappingManager.cs +++ /dev/null @@ -1,22 +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.Collections.Generic; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public class LineMappingManager - { - public LineMappingManager() - { - Mappings = new List(); - } - - public List Mappings { get; } - - public void AddMapping(MappingLocation documentLocation, MappingLocation generatedLocation) - { - Mappings.Add(new LineMapping(documentLocation, generatedLocation)); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/MappingLocation.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/MappingLocation.cs deleted file mode 100644 index 235974058a..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/MappingLocation.cs +++ /dev/null @@ -1,105 +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; -using System.Globalization; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - public class MappingLocation - { - public MappingLocation() - { - } - - public MappingLocation(SourceLocation location, int contentLength) - { - ContentLength = contentLength; - AbsoluteIndex = location.AbsoluteIndex; - LineIndex = location.LineIndex; - CharacterIndex = location.CharacterIndex; - FilePath = location.FilePath; - } - - public int ContentLength { get; } - - public int AbsoluteIndex { get; } - - public int LineIndex { get; } - - public int CharacterIndex { get; } - - public string FilePath { get; } - - public override bool Equals(object obj) - { - var other = obj as MappingLocation; - if (ReferenceEquals(other, null)) - { - return false; - } - - return string.Equals(FilePath, other.FilePath, StringComparison.Ordinal) && - AbsoluteIndex == other.AbsoluteIndex && - ContentLength == other.ContentLength && - LineIndex == other.LineIndex && - CharacterIndex == other.CharacterIndex; - } - - public override int GetHashCode() - { - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(FilePath, StringComparer.Ordinal); - hashCodeCombiner.Add(AbsoluteIndex); - hashCodeCombiner.Add(ContentLength); - hashCodeCombiner.Add(LineIndex); - hashCodeCombiner.Add(CharacterIndex); - - return hashCodeCombiner; - } - - public override string ToString() - { - return string.Format( - CultureInfo.CurrentCulture, "({0}:{1},{2} [{3}] {4})", - AbsoluteIndex, - LineIndex, - CharacterIndex, - ContentLength, - FilePath); - } - - public static bool operator ==(MappingLocation left, MappingLocation right) - { - if (ReferenceEquals(left, right)) - { - // Exact equality e.g. both objects are null. - return true; - } - - if (ReferenceEquals(left, null)) - { - return false; - } - - return left.Equals(right); - } - - public static bool operator !=(MappingLocation left, MappingLocation right) - { - if (ReferenceEquals(left, right)) - { - // Exact equality e.g. both objects are null. - return false; - } - - if (ReferenceEquals(left, null)) - { - return true; - } - - return !left.Equals(right); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/TagHelperAttributeValueCodeRenderer.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/TagHelperAttributeValueCodeRenderer.cs deleted file mode 100644 index 7af38de6b3..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/TagHelperAttributeValueCodeRenderer.cs +++ /dev/null @@ -1,62 +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; -using Microsoft.AspNet.Razor.Compilation.TagHelpers; - -namespace Microsoft.AspNet.Razor.CodeGenerators -{ - /// - /// Renders code for tag helper property initialization. - /// - public class TagHelperAttributeValueCodeRenderer - { - /// - /// Called during Razor's code generation process to generate code that instantiates the value of the tag - /// helper's property. Last value written should not be or end with a semicolon. - /// - /// - /// The to generate code for. - /// - /// The that's used to write code. - /// A instance that contains - /// information about the current code generation process. - /// - /// that renders the raw value of the HTML attribute. - /// - /// - /// Indicates whether or not the source attribute value contains more than simple text. false for plain - /// C# expressions e.g. "PropertyName". true if the attribute value contain at least one in-line - /// Razor construct e.g. "@(@readonly)". - /// - public virtual void RenderAttributeValue( - TagHelperAttributeDescriptor attributeDescriptor, - CSharpCodeWriter writer, - CodeGeneratorContext context, - Action renderAttributeValue, - bool complexValue) - { - if (attributeDescriptor == null) - { - throw new ArgumentNullException(nameof(attributeDescriptor)); - } - - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - if (renderAttributeValue == null) - { - throw new ArgumentNullException(nameof(renderAttributeValue)); - } - - renderAttributeValue(writer); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpBaseTypeVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpBaseTypeVisitor.cs deleted file mode 100644 index 9bd5178000..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpBaseTypeVisitor.cs +++ /dev/null @@ -1,32 +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; -using Microsoft.AspNet.Razor.Chunks; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - public class CSharpBaseTypeVisitor : CodeVisitor - { - public CSharpBaseTypeVisitor(CSharpCodeWriter writer, CodeGeneratorContext context) - : base(writer, context) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - } - - public string CurrentBaseType { get; set; } - - protected override void Visit(SetBaseTypeChunk chunk) - { - CurrentBaseType = chunk.TypeName; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpCodeVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpCodeVisitor.cs deleted file mode 100644 index a6d6b27943..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpCodeVisitor.cs +++ /dev/null @@ -1,563 +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; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using Microsoft.AspNet.Razor.Chunks; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - public class CSharpCodeVisitor : CodeVisitor - { - private const string ItemParameterName = "item"; - private const string ValueWriterName = "__razor_attribute_value_writer"; - private const string TemplateWriterName = "__razor_template_writer"; - - private CSharpPaddingBuilder _paddingBuilder; - private CSharpTagHelperCodeRenderer _tagHelperCodeRenderer; - - public CSharpCodeVisitor(CSharpCodeWriter writer, CodeGeneratorContext context) - : base(writer, context) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - _paddingBuilder = new CSharpPaddingBuilder(context.Host); - } - - public CSharpTagHelperCodeRenderer TagHelperRenderer - { - get - { - if (_tagHelperCodeRenderer == null) - { - _tagHelperCodeRenderer = new CSharpTagHelperCodeRenderer(this, Writer, Context); - } - - return _tagHelperCodeRenderer; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _tagHelperCodeRenderer = value; - } - } - - /// - /// Method used to write an to the current output. - /// - /// Default is to HTML encode all but a few types. - protected virtual string WriteMethodName - { - get - { - return Context.Host.GeneratedClassContext.WriteMethodName; - } - } - - /// - /// Method used to write an to a specified . - /// - /// Default is to HTML encode all but a few types. - protected virtual string WriteToMethodName - { - get - { - return Context.Host.GeneratedClassContext.WriteToMethodName; - } - } - - /// - /// Gets the method name used to generate WriteAttribute invocations in the rendered page. - /// - /// Defaults to - protected virtual string WriteAttributeValueMethodName => - Context.Host.GeneratedClassContext.WriteAttributeValueMethodName; - - protected override void Visit(TagHelperChunk chunk) - { - TagHelperRenderer.RenderTagHelper(chunk); - } - - protected override void Visit(ParentChunk chunk) - { - Accept(chunk.Children); - } - - protected override void Visit(TemplateChunk chunk) - { - Writer.Write(ItemParameterName).Write(" => ") - .WriteStartNewObject(Context.Host.GeneratedClassContext.TemplateTypeName); - - var currentTargetWriterName = Context.TargetWriterName; - Context.TargetWriterName = TemplateWriterName; - - using (Writer.BuildAsyncLambda(endLine: false, parameterNames: TemplateWriterName)) - { - Accept(chunk.Children); - } - - Context.TargetWriterName = currentTargetWriterName; - - Writer.WriteEndMethodInvocation(false).WriteLine(); - } - - protected override void Visit(LiteralChunk chunk) - { - if (Context.Host.DesignTimeMode || string.IsNullOrEmpty(chunk.Text)) - { - // Skip generating the chunk if we're in design time or if the chunk is empty. - return; - } - - if (Context.Host.EnableInstrumentation) - { - Writer.WriteStartInstrumentationContext(Context, chunk.Association, isLiteral: true); - } - - if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput) - { - RenderPreWriteStart(); - } - - Writer.WriteStringLiteral(chunk.Text); - - if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput) - { - Writer.WriteEndMethodInvocation(); - } - - if (Context.Host.EnableInstrumentation) - { - Writer.WriteEndInstrumentationContext(Context); - } - } - - protected override void Visit(ExpressionBlockChunk chunk) - { - if (Context.Host.DesignTimeMode) - { - RenderDesignTimeExpressionBlockChunk(chunk); - } - else - { - RenderRuntimeExpressionBlockChunk(chunk); - } - } - - protected override void Visit(ExpressionChunk chunk) - { - Writer.Write(chunk.Code); - } - - protected override void Visit(StatementChunk chunk) - { - CreateStatementCodeMapping(chunk.Code, chunk); - Writer.WriteLine(); - } - - protected override void Visit(DynamicCodeAttributeChunk chunk) - { - if (Context.Host.DesignTimeMode) - { - // Render the children as is without wrapping them in calls to WriteAttribute - Accept(chunk.Children); - return; - } - - var currentRenderingMode = Context.ExpressionRenderingMode; - var currentTargetWriterName = Context.TargetWriterName; - - CSharpLineMappingWriter lineMappingWriter = null; - var code = chunk.Children.FirstOrDefault(); - if (code is ExpressionChunk || code is ExpressionBlockChunk) - { - // We only want to render the #line pragma if the attribute value will be in-lined. - // Ex: WriteAttributeValue("", 0, DateTime.Now, 0, 0, false) - // For non-inlined scenarios: WriteAttributeValue("", 0, (_) => ..., 0, 0, false) - // the line pragma will be generated inside the lambda. - lineMappingWriter = new CSharpLineMappingWriter(Writer, chunk.Start, Context.SourceFile); - } - - if (!string.IsNullOrEmpty(currentTargetWriterName)) - { - Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteAttributeValueToMethodName) - .Write(currentTargetWriterName) - .WriteParameterSeparator(); - } - else - { - Writer.WriteStartMethodInvocation(WriteAttributeValueMethodName); - } - - Context.TargetWriterName = ValueWriterName; - - if (code is ExpressionChunk || code is ExpressionBlockChunk) - { - Debug.Assert(lineMappingWriter != null); - - Writer - .WriteLocationTaggedString(chunk.Prefix) - .WriteParameterSeparator(); - - Context.ExpressionRenderingMode = ExpressionRenderingMode.InjectCode; - - Accept(code); - - Writer - .WriteParameterSeparator() - .Write(chunk.Start.AbsoluteIndex.ToString(CultureInfo.CurrentCulture)) - .WriteParameterSeparator() - .Write(chunk.Association.Length.ToString(CultureInfo.CurrentCulture)) - .WriteParameterSeparator() - .WriteBooleanLiteral(value: false) - .WriteEndMethodInvocation(); - - lineMappingWriter.Dispose(); - } - else - { - Writer - .WriteLocationTaggedString(chunk.Prefix) - .WriteParameterSeparator() - .WriteStartNewObject(Context.Host.GeneratedClassContext.TemplateTypeName); - - using (Writer.BuildLambda(endLine: false, parameterNames: ValueWriterName)) - { - Accept(chunk.Children); - } - - Writer - .WriteEndMethodInvocation(false) - .WriteParameterSeparator() - .Write(chunk.Start.AbsoluteIndex.ToString(CultureInfo.CurrentCulture)) - .WriteParameterSeparator() - .Write(chunk.Association.Length.ToString(CultureInfo.CurrentCulture)) - .WriteParameterSeparator() - .WriteBooleanLiteral(false) - .WriteEndMethodInvocation(); - } - - Context.TargetWriterName = currentTargetWriterName; - Context.ExpressionRenderingMode = currentRenderingMode; - } - - protected override void Visit(LiteralCodeAttributeChunk chunk) - { - var visitChildren = chunk.Value == null; - - if (Context.Host.DesignTimeMode) - { - // Render the attribute without wrapping it in a call to WriteAttribute - if (visitChildren) - { - Accept(chunk.Children); - } - - return; - } - - if (!string.IsNullOrEmpty(Context.TargetWriterName)) - { - Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteAttributeValueToMethodName) - .Write(Context.TargetWriterName) - .WriteParameterSeparator(); - } - else - { - Writer.WriteStartMethodInvocation(WriteAttributeValueMethodName); - } - - Writer - .WriteLocationTaggedString(chunk.Prefix) - .WriteParameterSeparator(); - - if (visitChildren) - { - var currentRenderingMode = Context.ExpressionRenderingMode; - Context.ExpressionRenderingMode = ExpressionRenderingMode.InjectCode; - - Accept(chunk.Children); - - Context.ExpressionRenderingMode = currentRenderingMode; - - Writer - .WriteParameterSeparator() - .Write(chunk.ValueLocation.AbsoluteIndex.ToString(CultureInfo.CurrentCulture)) - .WriteParameterSeparator() - .Write(chunk.Association.Length.ToString(CultureInfo.CurrentCulture)) - .WriteParameterSeparator() - .WriteBooleanLiteral(false) - .WriteEndMethodInvocation(); - } - else - { - Writer - .WriteLocationTaggedString(chunk.Value) - .WriteParameterSeparator() - .Write(chunk.Association.Length.ToString(CultureInfo.CurrentCulture)) - .WriteParameterSeparator() - .WriteBooleanLiteral(true) - .WriteEndMethodInvocation(); - } - } - - protected override void Visit(CodeAttributeChunk chunk) - { - if (Context.Host.DesignTimeMode) - { - // Render the attribute without wrapping it in a "WriteAttribute" invocation - Accept(chunk.Children); - - return; - } - - if (!string.IsNullOrEmpty(Context.TargetWriterName)) - { - Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.BeginWriteAttributeToMethodName) - .Write(Context.TargetWriterName) - .WriteParameterSeparator(); - } - else - { - Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.BeginWriteAttributeMethodName); - } - - var attributeCount = chunk.Children.Count(c => c is LiteralCodeAttributeChunk || c is DynamicCodeAttributeChunk); - - Writer.WriteStringLiteral(chunk.Attribute) - .WriteParameterSeparator() - .WriteLocationTaggedString(chunk.Prefix) - .WriteParameterSeparator() - .WriteLocationTaggedString(chunk.Suffix) - .WriteParameterSeparator() - .Write(attributeCount.ToString(CultureInfo.CurrentCulture)) - .WriteEndMethodInvocation(); - - Accept(chunk.Children); - - Writer.WriteMethodInvocation(Context.Host.GeneratedClassContext.EndWriteAttributeMethodName); - } - - protected override void Visit(SectionChunk chunk) - { - Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.DefineSectionMethodName) - .WriteStringLiteral(chunk.Name) - .WriteParameterSeparator(); - - var currentTargetWriterName = Context.TargetWriterName; - Context.TargetWriterName = TemplateWriterName; - - using (Writer.BuildAsyncLambda(endLine: false, parameterNames: TemplateWriterName)) - { - Accept(chunk.Children); - } - Context.TargetWriterName = currentTargetWriterName; - Writer.WriteEndMethodInvocation(); - } - - public void RenderDesignTimeExpressionBlockChunk(ExpressionBlockChunk chunk) - { - var firstChild = (ExpressionChunk)chunk.Children.FirstOrDefault(); - - if (firstChild != null) - { - var currentIndent = Writer.CurrentIndent; - var designTimeAssignment = "__o = "; - Writer.ResetIndent(); - - var documentLocation = firstChild.Association.Start; - // This is only here to enable accurate formatting by the C# editor. - Writer.WriteLineNumberDirective(documentLocation, Context.SourceFile); - - // We build the padding with an offset of the design time assignment statement. - Writer.Write(_paddingBuilder.BuildExpressionPadding((Span)firstChild.Association, designTimeAssignment.Length)) - .Write(designTimeAssignment); - - // We map the first line of code but do not write the line pragmas associated with it. - CreateRawCodeMapping(firstChild.Code, documentLocation); - - // Render all but the first child. - // The reason why we render the other children differently is because when formatting the C# code - // the formatter expects the start line to have the assignment statement on it. - Accept(chunk.Children.Skip(1).ToList()); - - Writer.WriteLine(";") - .WriteLine() - .WriteLineDefaultDirective() - .WriteLineHiddenDirective() - .SetIndent(currentIndent); - } - } - - public void RenderRuntimeExpressionBlockChunk(ExpressionBlockChunk chunk) - { - // For expression chunks, such as @value, @(value) etc, pick the first Code or Markup span - // from the expression (in this case "value") and use that to calculate the length. This works - // accurately for most parts. The scenarios that don't work are - // (a) Expressions with inline comments (e.g. @(a @* comment *@ b)) - these have multiple code spans - // (b) Expressions with inline templates (e.g. @Foo(@

Hello world

)). - // Tracked via https://github.com/aspnet/Razor/issues/153 - - var block = (Block)chunk.Association; - var contentSpan = block.Children - .OfType() - .FirstOrDefault(s => s.Kind == SpanKind.Code || s.Kind == SpanKind.Markup); - - if (Context.ExpressionRenderingMode == ExpressionRenderingMode.InjectCode) - { - Accept(chunk.Children); - } - else if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput) - { - if (contentSpan != null) - { - RenderRuntimeExpressionBlockChunkWithContentSpan(chunk, contentSpan); - } - else - { - if (!string.IsNullOrEmpty(Context.TargetWriterName)) - { - Writer - .WriteStartMethodInvocation(WriteToMethodName) - .Write(Context.TargetWriterName) - .WriteParameterSeparator(); - } - else - { - Writer.WriteStartMethodInvocation(WriteMethodName); - } - - Accept(chunk.Children); - - Writer.WriteEndMethodInvocation() - .WriteLine(); - } - } - } - - private void RenderRuntimeExpressionBlockChunkWithContentSpan(ExpressionBlockChunk chunk, Span contentSpan) - { - var generateInstrumentation = ShouldGenerateInstrumentationForExpressions(); - - if (generateInstrumentation) - { - Writer.WriteStartInstrumentationContext(Context, contentSpan, isLiteral: false); - } - - using (var mappingWriter = new CSharpLineMappingWriter(Writer, chunk.Start, Context.SourceFile)) - { - if (!string.IsNullOrEmpty(Context.TargetWriterName)) - { - var generatedStart = - WriteToMethodName.Length + - Context.TargetWriterName.Length + - 3; // 1 for the opening '(' and 2 for ', ' - - var padding = _paddingBuilder.BuildExpressionPadding(contentSpan, generatedStart); - - Writer - .Write(padding) - .WriteStartMethodInvocation(WriteToMethodName) - .Write(Context.TargetWriterName) - .WriteParameterSeparator(); - } - else - { - var generatedStart = - WriteMethodName.Length + - 1; // for the opening '(' - - var padding = _paddingBuilder.BuildExpressionPadding(contentSpan, generatedStart); - - Writer - .Write(padding) - .WriteStartMethodInvocation(WriteMethodName); - } - - Accept(chunk.Children); - - Writer.WriteEndMethodInvocation(); - } - - if (generateInstrumentation) - { - Writer.WriteEndInstrumentationContext(Context); - } - } - - public void CreateStatementCodeMapping(string code, Chunk chunk) - { - CreateCodeMapping(_paddingBuilder.BuildStatementPadding((Span)chunk.Association), code, chunk); - } - - public void CreateExpressionCodeMapping(string code, Chunk chunk) - { - CreateCodeMapping(_paddingBuilder.BuildExpressionPadding((Span)chunk.Association), code, chunk); - } - - public void CreateCodeMapping(string padding, string code, Chunk chunk) - { - using (CSharpLineMappingWriter mappingWriter = Writer.BuildLineMapping(chunk.Start, code.Length, Context.SourceFile)) - { - Writer.Write(padding); - - mappingWriter.MarkLineMappingStart(); - Writer.Write(code); - mappingWriter.MarkLineMappingEnd(); - } - } - - // Raw CodeMapping's do not write out line pragmas, they just map code. - public void CreateRawCodeMapping(string code, SourceLocation documentLocation) - { - using (new CSharpLineMappingWriter(Writer, documentLocation, code.Length)) - { - Writer.Write(code); - } - } - - private bool ShouldGenerateInstrumentationForExpressions() - { - // Only generate instrumentation for expression blocks if instrumentation is enabled and we're generating a - // "Write()" statement. - return Context.Host.EnableInstrumentation && - Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput; - } - - private CSharpCodeWriter RenderPreWriteStart() - { - return RenderPreWriteStart(Writer, Context); - } - - public static CSharpCodeWriter RenderPreWriteStart(CSharpCodeWriter writer, CodeGeneratorContext context) - { - if (!string.IsNullOrEmpty(context.TargetWriterName)) - { - writer.WriteStartMethodInvocation(context.Host.GeneratedClassContext.WriteLiteralToMethodName) - .Write(context.TargetWriterName) - .WriteParameterSeparator(); - } - else - { - writer.WriteStartMethodInvocation(context.Host.GeneratedClassContext.WriteLiteralMethodName); - } - - return writer; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpDesignTimeCodeVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpDesignTimeCodeVisitor.cs deleted file mode 100644 index 3b05fdbc0d..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpDesignTimeCodeVisitor.cs +++ /dev/null @@ -1,112 +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; -using System.Diagnostics; -using System.Globalization; -using Microsoft.AspNet.Razor.Chunks; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - public class CSharpDesignTimeCodeVisitor : CodeVisitor - { - private const string InheritsHelper = "__inheritsHelper"; - private const string DesignTimeHelperMethodName = "__RazorDesignTimeHelpers__"; - private const string TagHelperDirectiveSyntaxHelper = "__tagHelperDirectiveSyntaxHelper"; - private const int DisableVariableNamingWarnings = 219; - - private bool _initializedTagHelperDirectiveSyntaxHelper; - - public CSharpDesignTimeCodeVisitor( - CSharpCodeVisitor csharpCodeVisitor, - CSharpCodeWriter writer, - CodeGeneratorContext context) - : base(writer, context) - { - if (csharpCodeVisitor == null) - { - throw new ArgumentNullException(nameof(csharpCodeVisitor)); - } - - CSharpCodeVisitor = csharpCodeVisitor; - } - - public CSharpCodeVisitor CSharpCodeVisitor { get; } - - public void AcceptTree(ChunkTree tree) - { - if (Context.Host.DesignTimeMode) - { - using (Writer.BuildMethodDeclaration("private", "void", "@" + DesignTimeHelperMethodName)) - { - using (Writer.BuildDisableWarningScope(DisableVariableNamingWarnings)) - { - AcceptTreeCore(tree); - } - } - } - } - - protected virtual void AcceptTreeCore(ChunkTree tree) - { - Accept(tree.Chunks); - } - - protected override void Visit(SetBaseTypeChunk chunk) - { - Debug.Assert(Context.Host.DesignTimeMode); - - if (chunk.Start != SourceLocation.Undefined) - { - using (var lineMappingWriter = - Writer.BuildLineMapping(chunk.Start, chunk.TypeName.Length, Context.SourceFile)) - { - Writer.Indent(chunk.Start.CharacterIndex); - - lineMappingWriter.MarkLineMappingStart(); - Writer.Write(chunk.TypeName); - lineMappingWriter.MarkLineMappingEnd(); - - Writer.Write(" ").Write(InheritsHelper).Write(" = null;"); - } - } - } - - protected override void Visit(TagHelperPrefixDirectiveChunk chunk) - { - VisitTagHelperDirectiveChunk(chunk.Prefix, chunk); - } - - protected override void Visit(AddTagHelperChunk chunk) - { - VisitTagHelperDirectiveChunk(chunk.LookupText, chunk); - } - - protected override void Visit(RemoveTagHelperChunk chunk) - { - VisitTagHelperDirectiveChunk(chunk.LookupText, chunk); - } - - private void VisitTagHelperDirectiveChunk(string text, Chunk chunk) - { - // We should always be in design time mode because of the calling AcceptTree method verification. - Debug.Assert(Context.Host.DesignTimeMode); - - if (!_initializedTagHelperDirectiveSyntaxHelper) - { - _initializedTagHelperDirectiveSyntaxHelper = true; - Writer.WriteVariableDeclaration("string", TagHelperDirectiveSyntaxHelper, "null"); - } - - Writer.WriteStartAssignment(TagHelperDirectiveSyntaxHelper); - - // The parsing mechanism for a TagHelper directive chunk (CSharpCodeParser.TagHelperDirective()) - // removes quotes that surround the text. - CSharpCodeVisitor.CreateExpressionCodeMapping( - string.Format(CultureInfo.InvariantCulture, "\"{0}\"", text), - chunk); - - Writer.WriteLine(";"); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTagHelperAttributeValueVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTagHelperAttributeValueVisitor.cs deleted file mode 100644 index cc2f1eee48..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTagHelperAttributeValueVisitor.cs +++ /dev/null @@ -1,162 +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; -using Microsoft.AspNet.Razor.Chunks; -using Microsoft.AspNet.Razor.Parser; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - /// - /// that writes code for a non- tag helper - /// bound attribute value. - /// - /// - /// Since attribute value is not written out as HTML, does not emit instrumentation. Further this - /// writes identical code at design- and runtime. - /// - public class CSharpTagHelperAttributeValueVisitor : CodeVisitor - { - private string _attributeTypeName; - private bool _firstChild; - - /// - /// Initializes a new instance of the class. - /// - /// The used to write code. - /// - /// A instance that contains information about the current code generation - /// process. - /// - /// - /// Full name of the property for which this - /// is writing the value. - /// - public CSharpTagHelperAttributeValueVisitor( - CSharpCodeWriter writer, - CodeGeneratorContext context, - string attributeTypeName) - : base(writer, context) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - _attributeTypeName = attributeTypeName; - } - - /// - /// Writes code for the given . - /// - /// The to render. - /// - /// Tracks code mappings for all children while writing. - /// - protected override void Visit(ParentChunk chunk) - { - // Line mappings are captured in RenderCode(), not this method. - _firstChild = true; - Accept(chunk.Children); - - if (_firstChild) - { - // Attribute value was empty. - Context.ErrorSink.OnError( - chunk.Association.Start, - RazorResources.TagHelpers_AttributeExpressionRequired, - chunk.Association.Length); - } - } - - /// - /// Writes code for the given . - /// - /// The to render. - protected override void Visit(ExpressionBlockChunk chunk) - { - Accept(chunk.Children); - } - - /// - /// Writes code for the given . - /// - /// The to render. - protected override void Visit(ExpressionChunk chunk) - { - RenderCode(chunk.Code, (Span)chunk.Association); - } - - /// - /// Writes code for the given . - /// - /// The to render. - protected override void Visit(LiteralChunk chunk) - { - RenderCode(chunk.Text, (Span)chunk.Association); - } - - /// - /// Writes code for the given . - /// - /// The to render. - /// - /// Unconditionally adds a to inform user of unexpected @section directive. - /// - protected override void Visit(SectionChunk chunk) - { - Context.ErrorSink.OnError( - chunk.Association.Start, - RazorResources.FormatTagHelpers_Directives_NotSupported_InAttributes( - SyntaxConstants.CSharp.SectionKeyword), - chunk.Association.Length); - } - - /// - /// Writes code for the given . - /// - /// The to render. - /// - /// Unconditionally adds a to inform user of unexpected code block. - /// - protected override void Visit(StatementChunk chunk) - { - Context.ErrorSink.OnError( - chunk.Association.Start, - RazorResources.TagHelpers_CodeBlocks_NotSupported_InAttributes, - chunk.Association.Length); - } - - /// - /// Writes code for the given . - /// - /// The to render. - /// - /// Unconditionally adds a to inform user of unexpected template e.g. - /// @<p>paragraph@</p>. - /// - protected override void Visit(TemplateChunk chunk) - { - Context.ErrorSink.OnError( - chunk.Association.Start, - RazorResources.FormatTagHelpers_InlineMarkupBlocks_NotSupported_InAttributes(_attributeTypeName), - chunk.Association.Length); - } - - // Tracks the code mapping and writes code for a leaf node in the attribute value Chunk tree. - private void RenderCode(string code, Span association) - { - _firstChild = false; - using (new CSharpLineMappingWriter(Writer, association.Start, code.Length)) - { - Writer.Write(code); - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTagHelperFieldDeclarationVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTagHelperFieldDeclarationVisitor.cs deleted file mode 100644 index 0d9436ea4b..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTagHelperFieldDeclarationVisitor.cs +++ /dev/null @@ -1,123 +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; -using System.Collections.Generic; -using Microsoft.AspNet.Razor.Chunks; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - public class CSharpTagHelperFieldDeclarationVisitor : CodeVisitor - { - private readonly HashSet _declaredTagHelpers; - private readonly GeneratedTagHelperContext _tagHelperContext; - private bool _foundTagHelpers; - - public CSharpTagHelperFieldDeclarationVisitor(CSharpCodeWriter writer, - CodeGeneratorContext context) - : base(writer, context) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - _declaredTagHelpers = new HashSet(StringComparer.Ordinal); - _tagHelperContext = Context.Host.GeneratedClassContext.GeneratedTagHelperContext; - } - - protected override void Visit(TagHelperChunk chunk) - { - // We only want to setup tag helper manager fields if there are tag helpers, and only once - if (!_foundTagHelpers) - { - _foundTagHelpers = true; - - // We want to hide declared TagHelper fields so they cannot be stepped over via a debugger. - Writer.WriteLineHiddenDirective(); - - // Runtime fields aren't useful during design time. - if (!Context.Host.DesignTimeMode) - { - // Need to disable the warning "X is assigned to but never used." for the value buffer since - // whether it's used depends on how a TagHelper is used. - Writer.WritePragma("warning disable 0414"); - WritePrivateField(_tagHelperContext.TagHelperContentTypeName, - CSharpTagHelperCodeRenderer.StringValueBufferVariableName, - value: null); - Writer.WritePragma("warning restore 0414"); - - WritePrivateField(_tagHelperContext.ExecutionContextTypeName, - CSharpTagHelperCodeRenderer.ExecutionContextVariableName, - value: null); - - Writer - .Write("private ") - .WriteVariableDeclaration( - _tagHelperContext.RunnerTypeName, - CSharpTagHelperCodeRenderer.RunnerVariableName, - value: null); - - Writer.Write("private ") - .Write(_tagHelperContext.ScopeManagerTypeName) - .Write(" ") - .WriteStartAssignment(CSharpTagHelperCodeRenderer.ScopeManagerVariableName) - .WriteStartNewObject(_tagHelperContext.ScopeManagerTypeName) - .WriteEndMethodInvocation(); - } - } - - foreach (var descriptor in chunk.Descriptors) - { - if (!_declaredTagHelpers.Contains(descriptor.TypeName)) - { - _declaredTagHelpers.Add(descriptor.TypeName); - - WritePrivateField(descriptor.TypeName, - CSharpTagHelperCodeRenderer.GetVariableName(descriptor), - value: null); - } - } - - // We need to dive deeper to ensure we pick up any nested tag helpers. - Accept(chunk.Children); - } - - public override void Accept(Chunk chunk) - { - if (chunk == null) - { - throw new ArgumentNullException(nameof(chunk)); - } - - var parentChunk = chunk as ParentChunk; - - // If we're any ParentChunk other than TagHelperChunk then we want to dive into its Children - // to search for more TagHelperChunk chunks. This if-statement enables us to not override - // each of the special ParentChunk types and then dive into their children. - if (parentChunk != null && !(parentChunk is TagHelperChunk)) - { - Accept(parentChunk.Children); - } - else - { - // If we're a TagHelperChunk or any other non ParentChunk we ".Accept" it. This ensures - // that our overridden Visit(TagHelperChunk) method gets called and is not skipped over. - // If we're a non ParentChunk or a TagHelperChunk then we want to just invoke the Visit - // method for that given chunk (base.Accept indirectly calls the Visit method). - base.Accept(chunk); - } - } - - private void WritePrivateField(string type, string name, string value) - { - Writer.Write("private ") - .WriteVariableDeclaration(type, name, value); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTagHelperRunnerInitializationVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTagHelperRunnerInitializationVisitor.cs deleted file mode 100644 index ec885464fb..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTagHelperRunnerInitializationVisitor.cs +++ /dev/null @@ -1,82 +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; -using Microsoft.AspNet.Razor.Chunks; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - /// - /// The that generates the code to initialize the TagHelperRunner. - /// - public class CSharpTagHelperRunnerInitializationVisitor : CodeVisitor - { - private readonly GeneratedTagHelperContext _tagHelperContext; - private bool _foundTagHelpers; - - /// - /// Creates a new instance of . - /// - /// The used to generate code. - /// The . - public CSharpTagHelperRunnerInitializationVisitor(CSharpCodeWriter writer, - CodeGeneratorContext context) - : base(writer, context) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - _tagHelperContext = Context.Host.GeneratedClassContext.GeneratedTagHelperContext; - } - - /// - public override void Accept(Chunk chunk) - { - if (chunk == null) - { - throw new ArgumentNullException(nameof(chunk)); - } - - // If at any ParentChunk other than a TagHelperChunk, then dive into its Children to search for more - // TagHelperChunk nodes. This method avoids overriding each of the ParentChunk-specific Visit() methods to - // dive into Children. - var parentChunk = chunk as ParentChunk; - if (parentChunk != null && !(parentChunk is TagHelperChunk)) - { - Accept(parentChunk.Children); - } - else - { - // If at a TagHelperChunk or any non-ParentChunk, "Accept()" it. This ensures the Visit(TagHelperChunk) - // method below is called. - base.Accept(chunk); - } - } - - /// - /// Writes the TagHelperRunner initialization code to the Writer. - /// - /// The . - protected override void Visit(TagHelperChunk chunk) - { - if (!_foundTagHelpers && !Context.Host.DesignTimeMode) - { - _foundTagHelpers = true; - - Writer - .WriteStartAssignment(CSharpTagHelperCodeRenderer.RunnerVariableName) - .Write(CSharpTagHelperCodeRenderer.RunnerVariableName) - .Write(" ?? ") - .WriteStartNewObject(_tagHelperContext.RunnerTypeName) - .WriteEndMethodInvocation(); - } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTypeMemberVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTypeMemberVisitor.cs deleted file mode 100644 index 77656f9aa5..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpTypeMemberVisitor.cs +++ /dev/null @@ -1,44 +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; -using Microsoft.AspNet.Razor.Chunks; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - public class CSharpTypeMemberVisitor : CodeVisitor - { - private CSharpCodeVisitor _csharpCodeVisitor; - - public CSharpTypeMemberVisitor(CSharpCodeVisitor csharpCodeVisitor, - CSharpCodeWriter writer, - CodeGeneratorContext context) - : base(writer, context) - { - if (csharpCodeVisitor == null) - { - throw new ArgumentNullException(nameof(csharpCodeVisitor)); - } - - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - _csharpCodeVisitor = csharpCodeVisitor; - } - - protected override void Visit(TypeMemberChunk chunk) - { - if (!string.IsNullOrEmpty(chunk.Code)) - { - _csharpCodeVisitor.CreateCodeMapping(string.Empty, chunk.Code, chunk); - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpUsingVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpUsingVisitor.cs deleted file mode 100644 index e776e6c7ce..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CSharpUsingVisitor.cs +++ /dev/null @@ -1,117 +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; -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNet.Razor.Chunks; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - public class CSharpUsingVisitor : CodeVisitor - { - private static readonly string[] TagHelpersRuntimeNamespaces = new[] - { - "Microsoft.AspNet.Razor.TagHelpers", - "Microsoft.AspNet.Razor.Runtime.TagHelpers" - }; - - private bool _foundTagHelpers; - - public CSharpUsingVisitor(CSharpCodeWriter writer, CodeGeneratorContext context) - : base(writer, context) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - ImportedUsings = new HashSet(StringComparer.Ordinal); - } - - public HashSet ImportedUsings { get; set; } - - /// - public override void Accept(Chunk chunk) - { - if (chunk == null) - { - throw new ArgumentNullException(nameof(chunk)); - } - - // If at any ParentChunk other than a TagHelperChunk, then dive into its Children to search for more - // TagHelperChunk or UsingChunk nodes. This method avoids overriding each of the ParentChunk-specific - // Visit() methods to dive into Children. - var parentChunk = chunk as ParentChunk; - if (parentChunk != null && !(parentChunk is TagHelperChunk)) - { - Accept(parentChunk.Children); - } - else - { - // If at a TagHelperChunk or any non-ParentChunk (e.g. UsingChunk), "Accept()" it. This ensures the - // Visit(UsingChunk) and Visit(TagHelperChunk) methods below are called. - base.Accept(chunk); - } - } - - protected override void Visit(UsingChunk chunk) - { - var documentContent = ((Span)chunk.Association).Content.Trim(); - var mapSemicolon = false; - - if (documentContent.LastOrDefault() == ';') - { - mapSemicolon = true; - } - - ImportedUsings.Add(chunk.Namespace); - - // Depending on if the user has a semicolon in their @using statement we have to conditionally decide - // to include the semicolon in the line mapping. - using (Writer.BuildLineMapping(chunk.Start, documentContent.Length, Context.SourceFile)) - { - Writer.WriteUsing(chunk.Namespace, endLine: false); - - if (mapSemicolon) - { - Writer.Write(";"); - } - } - - if (!mapSemicolon) - { - Writer.WriteLine(";"); - } - } - - protected override void Visit(TagHelperChunk chunk) - { - if (Context.Host.DesignTimeMode) - { - return; - } - - if (!_foundTagHelpers) - { - _foundTagHelpers = true; - - foreach (var tagHelperRuntimeNamespace in TagHelpersRuntimeNamespaces) - { - if (ImportedUsings.Add(tagHelperRuntimeNamespace)) - { - // If we find TagHelpers then we need to add the TagHelper runtime namespaces to our list of - // usings. - Writer.WriteUsing(tagHelperRuntimeNamespace); - } - } - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/ChunkVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/ChunkVisitor.cs deleted file mode 100644 index 1f79be0b17..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/ChunkVisitor.cs +++ /dev/null @@ -1,140 +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; -using System.Collections.Generic; -using Microsoft.AspNet.Razor.Chunks; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - public abstract class ChunkVisitor : IChunkVisitor - where TWriter : CodeWriter - { - public ChunkVisitor(TWriter writer, CodeGeneratorContext context) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - Writer = writer; - Context = context; - } - - protected TWriter Writer { get; private set; } - protected CodeGeneratorContext Context { get; private set; } - - public void Accept(IList chunks) - { - if (chunks == null) - { - throw new ArgumentNullException(nameof(chunks)); - } - - foreach (Chunk chunk in chunks) - { - Accept(chunk); - } - } - - public virtual void Accept(Chunk chunk) - { - if (chunk == null) - { - throw new ArgumentNullException(nameof(chunk)); - } - - if (chunk is LiteralChunk) - { - Visit((LiteralChunk)chunk); - } - else if (chunk is ExpressionBlockChunk) - { - Visit((ExpressionBlockChunk)chunk); - } - else if (chunk is ExpressionChunk) - { - Visit((ExpressionChunk)chunk); - } - else if (chunk is StatementChunk) - { - Visit((StatementChunk)chunk); - } - else if (chunk is TagHelperChunk) - { - Visit((TagHelperChunk)chunk); - } - else if (chunk is TagHelperPrefixDirectiveChunk) - { - Visit((TagHelperPrefixDirectiveChunk)chunk); - } - else if (chunk is AddTagHelperChunk) - { - Visit((AddTagHelperChunk)chunk); - } - else if (chunk is RemoveTagHelperChunk) - { - Visit((RemoveTagHelperChunk)chunk); - } - else if (chunk is TypeMemberChunk) - { - Visit((TypeMemberChunk)chunk); - } - else if (chunk is UsingChunk) - { - Visit((UsingChunk)chunk); - } - else if (chunk is SetBaseTypeChunk) - { - Visit((SetBaseTypeChunk)chunk); - } - else if (chunk is DynamicCodeAttributeChunk) - { - Visit((DynamicCodeAttributeChunk)chunk); - } - else if (chunk is LiteralCodeAttributeChunk) - { - Visit((LiteralCodeAttributeChunk)chunk); - } - else if (chunk is CodeAttributeChunk) - { - Visit((CodeAttributeChunk)chunk); - } - else if (chunk is SectionChunk) - { - Visit((SectionChunk)chunk); - } - else if (chunk is TemplateChunk) - { - Visit((TemplateChunk)chunk); - } - else if (chunk is ParentChunk) - { - Visit((ParentChunk)chunk); - } - } - - protected abstract void Visit(LiteralChunk chunk); - protected abstract void Visit(ExpressionChunk chunk); - protected abstract void Visit(StatementChunk chunk); - protected abstract void Visit(TagHelperChunk chunk); - protected abstract void Visit(TagHelperPrefixDirectiveChunk chunk); - protected abstract void Visit(AddTagHelperChunk chunk); - protected abstract void Visit(RemoveTagHelperChunk chunk); - protected abstract void Visit(UsingChunk chunk); - protected abstract void Visit(ParentChunk chunk); - protected abstract void Visit(DynamicCodeAttributeChunk chunk); - protected abstract void Visit(LiteralCodeAttributeChunk chunk); - protected abstract void Visit(CodeAttributeChunk chunk); - protected abstract void Visit(SectionChunk chunk); - protected abstract void Visit(TypeMemberChunk chunk); - protected abstract void Visit(SetBaseTypeChunk chunk); - protected abstract void Visit(TemplateChunk chunk); - protected abstract void Visit(ExpressionBlockChunk chunk); - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CodeVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CodeVisitor.cs deleted file mode 100644 index c55ada4e65..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/CodeVisitor.cs +++ /dev/null @@ -1,78 +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; -using Microsoft.AspNet.Razor.Chunks; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - public class CodeVisitor : ChunkVisitor - where TWriter : CodeWriter - { - public CodeVisitor(TWriter writer, CodeGeneratorContext context) - : base(writer, context) - { - if (writer == null) - { - throw new ArgumentNullException(nameof(writer)); - } - - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - } - - protected override void Visit(LiteralChunk chunk) - { - } - protected override void Visit(ExpressionBlockChunk chunk) - { - } - protected override void Visit(ExpressionChunk chunk) - { - } - protected override void Visit(StatementChunk chunk) - { - } - protected override void Visit(UsingChunk chunk) - { - } - protected override void Visit(ParentChunk chunk) - { - } - protected override void Visit(DynamicCodeAttributeChunk chunk) - { - } - protected override void Visit(TagHelperChunk chunk) - { - } - protected override void Visit(TagHelperPrefixDirectiveChunk chunk) - { - } - protected override void Visit(AddTagHelperChunk chunk) - { - } - protected override void Visit(RemoveTagHelperChunk chunk) - { - } - protected override void Visit(LiteralCodeAttributeChunk chunk) - { - } - protected override void Visit(CodeAttributeChunk chunk) - { - } - protected override void Visit(SectionChunk chunk) - { - } - protected override void Visit(TypeMemberChunk chunk) - { - } - protected override void Visit(SetBaseTypeChunk chunk) - { - } - protected override void Visit(TemplateChunk chunk) - { - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/IChunkVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/IChunkVisitor.cs deleted file mode 100644 index f7b84c6da8..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CodeGenerators/Visitors/IChunkVisitor.cs +++ /dev/null @@ -1,14 +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.Collections.Generic; -using Microsoft.AspNet.Razor.Chunks; - -namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors -{ - public interface IChunkVisitor - { - void Accept(IList chunks); - void Accept(Chunk chunk); - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/CommonResources.resx b/src/Microsoft.AspNet.Razor.VSRC1/CommonResources.resx deleted file mode 100644 index 7cc5d5ecd7..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/CommonResources.resx +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Value cannot be null or an empty string. - - - Value must be between {0} and {1}. - - - Value must be a value from the "{0}" enumeration. - - - Value must be greater than {0}. - - - Value must be greater than or equal to {0}. - - - Value must be less than {0}. - - - Value must be less than or equal to {0}. - - - Value cannot be an empty string. It must either be null or a non-empty string. - - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/ITagHelperDescriptorResolver.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/ITagHelperDescriptorResolver.cs deleted file mode 100644 index 7bf86b1f25..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/ITagHelperDescriptorResolver.cs +++ /dev/null @@ -1,23 +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.Collections.Generic; - -namespace Microsoft.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// Contract used to resolve s. - /// - public interface ITagHelperDescriptorResolver - { - /// - /// Resolves s based on the given . - /// - /// - /// used to resolve descriptors for the Razor page. - /// - /// An of s based - /// on the given . - IEnumerable Resolve(TagHelperDescriptorResolutionContext resolutionContext); - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperAttributeDescriptor.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperAttributeDescriptor.cs deleted file mode 100644 index 1634e2d7d1..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperAttributeDescriptor.cs +++ /dev/null @@ -1,150 +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; -using System.Reflection; - -namespace Microsoft.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// A metadata class describing a tag helper attribute. - /// - public class TagHelperAttributeDescriptor - { - private string _typeName; - private string _name; - private string _propertyName; - - /// - /// Instantiates a new instance of the class. - /// - public TagHelperAttributeDescriptor() - { - } - - // Internal for testing i.e. for easy TagHelperAttributeDescriptor creation when PropertyInfo is available. - internal TagHelperAttributeDescriptor(string name, PropertyInfo propertyInfo) - { - Name = name; - PropertyName = propertyInfo.Name; - TypeName = propertyInfo.PropertyType.FullName; - } - - /// - /// Gets an indication whether this is used for dictionary indexer - /// assignments. - /// - /// - /// If true this should be associated with all HTML - /// attributes that have names starting with . Otherwise this - /// is used for property assignment and is only associated with an - /// HTML attribute that has the exact . - /// - /// - /// HTML attribute names are matched case-insensitively, regardless of . - /// - public bool IsIndexer { get; set; } - - /// - /// Gets or sets an indication whether this property is of type or, if - /// is true, whether the indexer's value is of type . - /// - /// - /// If true the is for . This causes the Razor parser - /// to allow empty values for HTML attributes matching this . If - /// false empty values for such matching attributes lead to errors. - /// - public bool IsStringProperty { get; set; } - - /// - /// The HTML attribute name or, if is true, the prefix for matching attribute - /// names. - /// - public string Name - { - get - { - return _name; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _name = value; - } - } - - - /// - /// The name of the CLR property that corresponds to the HTML attribute. - /// - public string PropertyName - { - get - { - return _propertyName; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _propertyName = value; - } - } - - /// - /// The full name of the named (see ) property's or, if - /// is true, the full name of the indexer's value . - /// - public string TypeName - { - get - { - return _typeName; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _typeName = value; - IsStringProperty = string.Equals(TypeName, typeof(string).FullName, StringComparison.Ordinal); - } - } - - /// - /// The that contains design time information about - /// this attribute. - /// - public TagHelperAttributeDesignTimeDescriptor DesignTimeDescriptor { get; set; } - - /// - /// Determines whether HTML attribute matches this - /// . - /// - /// Name of the HTML attribute to check. - /// - /// true if this matches . - /// false otherwise. - /// - public bool IsNameMatch(string name) - { - if (IsIndexer) - { - return name.StartsWith(Name, StringComparison.OrdinalIgnoreCase); - } - else - { - return string.Equals(name, Name, StringComparison.OrdinalIgnoreCase); - } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperAttributeDesignTimeDescriptor.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperAttributeDesignTimeDescriptor.cs deleted file mode 100644 index 29298cac99..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperAttributeDesignTimeDescriptor.cs +++ /dev/null @@ -1,21 +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. - -namespace Microsoft.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// A metadata class containing information about tag helper use. - /// - public class TagHelperAttributeDesignTimeDescriptor - { - /// - /// A summary of how to use a tag helper. - /// - public string Summary { get; set; } - - /// - /// Remarks about how to use a tag helper. - /// - public string Remarks { get; set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptor.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptor.cs deleted file mode 100644 index 1a98a9a18f..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptor.cs +++ /dev/null @@ -1,204 +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; -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNet.Razor.TagHelpers; - -namespace Microsoft.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// A metadata class describing a tag helper. - /// - public class TagHelperDescriptor - { - private string _prefix = string.Empty; - private string _tagName; - private string _typeName; - private string _assemblyName; - private IEnumerable _attributes = - Enumerable.Empty(); - private IEnumerable _requiredAttributes = Enumerable.Empty(); - - /// - /// Text used as a required prefix when matching HTML start and end tags in the Razor source to available - /// tag helpers. - /// - public string Prefix - { - get - { - return _prefix; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _prefix = value; - } - } - - /// - /// The tag name that the tag helper should target. - /// - public string TagName - { - get - { - return _tagName; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _tagName = value; - } - } - - /// - /// The full tag name that is required for the tag helper to target an HTML element. - /// - /// This is equivalent to and concatenated. - public string FullTagName - { - get - { - return Prefix + TagName; - } - } - - /// - /// The full name of the tag helper class. - /// - public string TypeName - { - get - { - return _typeName; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _typeName = value; - } - } - - /// - /// The name of the assembly containing the tag helper class. - /// - public string AssemblyName - { - get - { - return _assemblyName; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _assemblyName = value; - } - } - - /// - /// The list of attributes the tag helper expects. - /// - public IEnumerable Attributes - { - get - { - return _attributes; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _attributes = value; - } - } - - /// - /// The list of required attribute names the tag helper expects to target an element. - /// - /// - /// * at the end of an attribute name acts as a prefix match. - /// - public IEnumerable RequiredAttributes - { - get - { - return _requiredAttributes; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _requiredAttributes = value; - } - } - - /// - /// Get the names of elements allowed as children. - /// - /// null indicates all children are allowed. - public IEnumerable AllowedChildren { get; set; } - - /// - /// Get the name of the HTML element required as the immediate parent. - /// - /// null indicates no restriction on parent tag. - public string RequiredParent { get; set; } - - /// - /// The expected tag structure. - /// - /// - /// If and no other tag helpers applying to the same element specify - /// their the behavior is used: - /// - /// - /// <my-tag-helper></my-tag-helper> - /// <!-- OR --> - /// <my-tag-helper /> - /// - /// Otherwise, if another tag helper applying to the same element does specify their behavior, that behavior - /// is used. - /// - /// - /// If HTML elements can be written in the following formats: - /// - /// <my-tag-helper> - /// <!-- OR --> - /// <my-tag-helper /> - /// - /// - /// - public TagStructure TagStructure { get; set; } - - /// - /// The that contains design time information about this - /// tag helper. - /// - public TagHelperDesignTimeDescriptor DesignTimeDescriptor { get; set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptorComparer.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptorComparer.cs deleted file mode 100644 index 62f57d9e9f..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptorComparer.cs +++ /dev/null @@ -1,102 +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; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// An used to check equality between - /// two s. - /// - public class TagHelperDescriptorComparer : IEqualityComparer - { - /// - /// A default instance of the . - /// - public static readonly TagHelperDescriptorComparer Default = new TagHelperDescriptorComparer(); - - /// - /// Initializes a new instance. - /// - protected TagHelperDescriptorComparer() - { - } - - /// - /// - /// Determines equality based on , - /// , , - /// , , - /// and . - /// Ignores because it can be inferred directly from - /// and . - /// - public virtual bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY) - { - if (descriptorX == descriptorY) - { - return true; - } - - return descriptorX != null && - string.Equals(descriptorX.TypeName, descriptorY.TypeName, StringComparison.Ordinal) && - string.Equals(descriptorX.TagName, descriptorY.TagName, StringComparison.OrdinalIgnoreCase) && - string.Equals(descriptorX.AssemblyName, descriptorY.AssemblyName, StringComparison.Ordinal) && - string.Equals( - descriptorX.RequiredParent, - descriptorY.RequiredParent, - StringComparison.OrdinalIgnoreCase) && - Enumerable.SequenceEqual( - descriptorX.RequiredAttributes.OrderBy(attribute => attribute, StringComparer.OrdinalIgnoreCase), - descriptorY.RequiredAttributes.OrderBy(attribute => attribute, StringComparer.OrdinalIgnoreCase), - StringComparer.OrdinalIgnoreCase) && - (descriptorX.AllowedChildren == descriptorY.AllowedChildren || - (descriptorX.AllowedChildren != null && - descriptorY.AllowedChildren != null && - Enumerable.SequenceEqual( - descriptorX.AllowedChildren.OrderBy(child => child, StringComparer.OrdinalIgnoreCase), - descriptorY.AllowedChildren.OrderBy(child => child, StringComparer.OrdinalIgnoreCase), - StringComparer.OrdinalIgnoreCase))) && - descriptorX.TagStructure == descriptorY.TagStructure; - } - - /// - public virtual int GetHashCode(TagHelperDescriptor descriptor) - { - if (descriptor == null) - { - throw new ArgumentNullException(nameof(descriptor)); - } - - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(descriptor.TypeName, StringComparer.Ordinal); - hashCodeCombiner.Add(descriptor.TagName, StringComparer.OrdinalIgnoreCase); - hashCodeCombiner.Add(descriptor.AssemblyName, StringComparer.Ordinal); - hashCodeCombiner.Add(descriptor.RequiredParent, StringComparer.OrdinalIgnoreCase); - hashCodeCombiner.Add(descriptor.TagStructure); - - var attributes = descriptor.RequiredAttributes.OrderBy( - attribute => attribute, - StringComparer.OrdinalIgnoreCase); - foreach (var attribute in attributes) - { - hashCodeCombiner.Add(attribute, StringComparer.OrdinalIgnoreCase); - } - - if (descriptor.AllowedChildren != null) - { - var allowedChildren = descriptor.AllowedChildren.OrderBy(child => child, StringComparer.OrdinalIgnoreCase); - foreach (var child in allowedChildren) - { - hashCodeCombiner.Add(child, StringComparer.OrdinalIgnoreCase); - } - } - - return hashCodeCombiner.CombinedHash; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptorProvider.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptorProvider.cs deleted file mode 100644 index f50a63f007..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptorProvider.cs +++ /dev/null @@ -1,155 +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; -using System.Collections.Generic; -using System.Linq; - -namespace Microsoft.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// Enables retrieval of 's. - /// - public class TagHelperDescriptorProvider - { - public const string ElementCatchAllTarget = "*"; - - public static readonly string RequiredAttributeWildcardSuffix = "*"; - - private IDictionary> _registrations; - private string _tagHelperPrefix; - - /// - /// Instantiates a new instance of the . - /// - /// The descriptors that the will pull from. - public TagHelperDescriptorProvider(IEnumerable descriptors) - { - _registrations = new Dictionary>(StringComparer.OrdinalIgnoreCase); - - // Populate our registrations - foreach (var descriptor in descriptors) - { - Register(descriptor); - } - } - - /// - /// Gets all tag helpers that match the given . - /// - /// The name of the HTML tag to match. Providing a '*' tag name - /// retrieves catch-all s (descriptors that target every tag). - /// Attributes the HTML element must contain to match. - /// The parent tag name of the given tag. - /// s that apply to the given . - /// Will return an empty if no s are - /// found. - public IEnumerable GetDescriptors( - string tagName, - IEnumerable attributeNames, - string parentTagName) - { - if (!string.IsNullOrEmpty(_tagHelperPrefix) && - (tagName.Length <= _tagHelperPrefix.Length || - !tagName.StartsWith(_tagHelperPrefix, StringComparison.OrdinalIgnoreCase))) - { - // The tagName doesn't have the tag helper prefix, we can short circuit. - return Enumerable.Empty(); - } - - HashSet catchAllDescriptors; - IEnumerable descriptors; - - // Ensure there's a HashSet to use. - if (!_registrations.TryGetValue(ElementCatchAllTarget, out catchAllDescriptors)) - { - descriptors = new HashSet(TagHelperDescriptorComparer.Default); - } - else - { - descriptors = catchAllDescriptors; - } - - // If we have a tag name associated with the requested name, we need to combine matchingDescriptors - // with all the catch-all descriptors. - HashSet matchingDescriptors; - if (_registrations.TryGetValue(tagName, out matchingDescriptors)) - { - descriptors = matchingDescriptors.Concat(descriptors); - } - - var applicableDescriptors = ApplyRequiredAttributes(descriptors, attributeNames); - applicableDescriptors = ApplyParentTagFilter(applicableDescriptors, parentTagName); - - return applicableDescriptors; - } - - private IEnumerable ApplyParentTagFilter( - IEnumerable descriptors, - string parentTagName) - { - return descriptors.Where(descriptor => - descriptor.RequiredParent == null || - string.Equals(parentTagName, descriptor.RequiredParent, StringComparison.OrdinalIgnoreCase)); - } - - private IEnumerable ApplyRequiredAttributes( - IEnumerable descriptors, - IEnumerable attributeNames) - { - return descriptors.Where( - descriptor => - { - foreach (var requiredAttribute in descriptor.RequiredAttributes) - { - // '*' at the end of a required attribute indicates: apply to attributes prefixed with the - // required attribute value. - if (requiredAttribute.EndsWith( - RequiredAttributeWildcardSuffix, - StringComparison.OrdinalIgnoreCase)) - { - var prefix = requiredAttribute.Substring(0, requiredAttribute.Length - 1); - - if (!attributeNames.Any( - attributeName => - attributeName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) && - !string.Equals(attributeName, prefix, StringComparison.OrdinalIgnoreCase))) - { - return false; - } - } - else if (!attributeNames.Contains(requiredAttribute, StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - - return true; - }); - } - - private void Register(TagHelperDescriptor descriptor) - { - HashSet descriptorSet; - - if (_tagHelperPrefix == null) - { - _tagHelperPrefix = descriptor.Prefix; - } - - var registrationKey = - string.Equals(descriptor.TagName, ElementCatchAllTarget, StringComparison.Ordinal) ? - ElementCatchAllTarget : - descriptor.FullTagName; - - // Ensure there's a HashSet to add the descriptor to. - if (!_registrations.TryGetValue(registrationKey, out descriptorSet)) - { - descriptorSet = new HashSet(TagHelperDescriptorComparer.Default); - _registrations[registrationKey] = descriptorSet; - } - - descriptorSet.Add(descriptor); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptorResolutionContext.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptorResolutionContext.cs deleted file mode 100644 index 880f6c937e..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDescriptorResolutionContext.cs +++ /dev/null @@ -1,54 +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; -using System.Collections.Generic; - -namespace Microsoft.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// Contains information needed to resolve s. - /// - public class TagHelperDescriptorResolutionContext - { - // Internal for testing purposes - internal TagHelperDescriptorResolutionContext(IEnumerable directiveDescriptors) - : this(directiveDescriptors, new ErrorSink()) - { - } - - /// - /// Instantiates a new instance of . - /// - /// s used to resolve - /// s. - /// Used to aggregate s. - public TagHelperDescriptorResolutionContext( - IEnumerable directiveDescriptors, - ErrorSink errorSink) - { - if (directiveDescriptors == null) - { - throw new ArgumentNullException(nameof(directiveDescriptors)); - } - - if (errorSink == null) - { - throw new ArgumentNullException(nameof(errorSink)); - } - - DirectiveDescriptors = new List(directiveDescriptors); - ErrorSink = errorSink; - } - - /// - /// s used to resolve s. - /// - public IList DirectiveDescriptors { get; private set; } - - /// - /// Used to aggregate s. - /// - public ErrorSink ErrorSink { get; private set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDesignTimeDescriptor.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDesignTimeDescriptor.cs deleted file mode 100644 index 5cdff88a41..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDesignTimeDescriptor.cs +++ /dev/null @@ -1,29 +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. - -namespace Microsoft.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// A metadata class containing design time information about a tag helper. - /// - public class TagHelperDesignTimeDescriptor - { - /// - /// A summary of how to use a tag helper. - /// - public string Summary { get; set; } - - /// - /// Remarks about how to use a tag helper. - /// - public string Remarks { get; set; } - - /// - /// The HTML element a tag helper may output. - /// - /// - /// In IDEs supporting IntelliSense, may override the HTML information provided at design time. - /// - public string OutputElementHint { get; set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDirectiveDescriptor.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDirectiveDescriptor.cs deleted file mode 100644 index b372457b03..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDirectiveDescriptor.cs +++ /dev/null @@ -1,45 +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.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// Contains information needed to resolve s. - /// - public class TagHelperDirectiveDescriptor - { - private string _directiveText; - - /// - /// A used to find tag helper s. - /// - public string DirectiveText - { - get - { - return _directiveText; - } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _directiveText = value; - } - } - - /// - /// The of the directive. - /// - public SourceLocation Location { get; set; } = SourceLocation.Zero; - - /// - /// The of this directive. - /// - public TagHelperDirectiveType DirectiveType { get; set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDirectiveType.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDirectiveType.cs deleted file mode 100644 index d2cec61c63..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TagHelperDirectiveType.cs +++ /dev/null @@ -1,26 +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. - -namespace Microsoft.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// The type of tag helper directive. - /// - public enum TagHelperDirectiveType - { - /// - /// An @addTagHelper directive. - /// - AddTagHelper, - - /// - /// A @removeTagHelper directive. - /// - RemoveTagHelper, - - /// - /// A @tagHelperPrefix directive. - /// - TagHelperPrefix - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TypeBasedTagHelperDescriptorComparer.cs b/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TypeBasedTagHelperDescriptorComparer.cs deleted file mode 100644 index d89e54ad7b..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Compilation/TagHelpers/TypeBasedTagHelperDescriptorComparer.cs +++ /dev/null @@ -1,64 +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; -using System.Collections.Generic; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Compilation.TagHelpers -{ - /// - /// An that checks equality between two - /// s using only their s and - /// s. - /// - /// - /// This class is intended for scenarios where Reflection-based information is all important i.e. - /// , , and related - /// properties are not relevant. - /// - public class TypeBasedTagHelperDescriptorComparer : IEqualityComparer - { - /// - /// A default instance of the . - /// - public static readonly TypeBasedTagHelperDescriptorComparer Default = - new TypeBasedTagHelperDescriptorComparer(); - - private TypeBasedTagHelperDescriptorComparer() - { - } - - /// - /// - /// Determines equality based on and - /// . - /// - public bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY) - { - if (descriptorX == descriptorY) - { - return true; - } - - return descriptorX != null && - string.Equals(descriptorX.AssemblyName, descriptorY.AssemblyName, StringComparison.Ordinal) && - string.Equals(descriptorX.TypeName, descriptorY.TypeName, StringComparison.Ordinal); - } - - /// - public int GetHashCode(TagHelperDescriptor descriptor) - { - if (descriptor == null) - { - throw new ArgumentNullException(nameof(descriptor)); - } - - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(descriptor.AssemblyName, StringComparer.Ordinal); - hashCodeCombiner.Add(descriptor.TypeName, StringComparer.Ordinal); - - return hashCodeCombiner; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/DocumentParseCompleteEventArgs.cs b/src/Microsoft.AspNet.Razor.VSRC1/DocumentParseCompleteEventArgs.cs deleted file mode 100644 index 898d7b0828..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/DocumentParseCompleteEventArgs.cs +++ /dev/null @@ -1,30 +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; -using Microsoft.AspNet.Razor.CodeGenerators; -using Microsoft.AspNet.Razor.Text; - -namespace Microsoft.AspNet.Razor -{ - /// - /// Arguments for the DocumentParseComplete event in RazorEditorParser - /// - public class DocumentParseCompleteEventArgs : EventArgs - { - /// - /// Indicates if the tree structure has actually changed since the previous re-parse. - /// - public bool TreeStructureChanged { get; set; } - - /// - /// The results of the chunk generation and parsing - /// - public GeneratorResults GeneratorResults { get; set; } - - /// - /// The TextChange which triggered the re-parse - /// - public TextChange SourceChange { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Editor/AutoCompleteEditHandler.cs b/src/Microsoft.AspNet.Razor.VSRC1/Editor/AutoCompleteEditHandler.cs deleted file mode 100644 index 115882ec45..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Editor/AutoCompleteEditHandler.cs +++ /dev/null @@ -1,75 +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; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using Microsoft.AspNet.Razor.Editor; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Parser.SyntaxTree -{ - public class AutoCompleteEditHandler : SpanEditHandler - { - private static readonly int TypeHashCode = typeof(AutoCompleteEditHandler).GetHashCode(); - - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Func is the recommended delegate type and requires this level of nesting.")] - public AutoCompleteEditHandler(Func> tokenizer) - : base(tokenizer) - { - } - - public AutoCompleteEditHandler(Func> tokenizer, bool autoCompleteAtEndOfSpan) - : this(tokenizer) - { - AutoCompleteAtEndOfSpan = autoCompleteAtEndOfSpan; - } - - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Func is the recommended delegate type and requires this level of nesting.")] - public AutoCompleteEditHandler(Func> tokenizer, AcceptedCharacters accepted) - : base(tokenizer, accepted) - { - } - - public bool AutoCompleteAtEndOfSpan { get; } - - public string AutoCompleteString { get; set; } - - protected override PartialParseResult CanAcceptChange(Span target, TextChange normalizedChange) - { - if (((AutoCompleteAtEndOfSpan && IsAtEndOfSpan(target, normalizedChange)) || IsAtEndOfFirstLine(target, normalizedChange)) && - normalizedChange.IsInsert && - ParserHelpers.IsNewLine(normalizedChange.NewText) && - AutoCompleteString != null) - { - return PartialParseResult.Rejected | PartialParseResult.AutoCompleteBlock; - } - return PartialParseResult.Rejected; - } - - public override string ToString() - { - return base.ToString() + ",AutoComplete:[" + (AutoCompleteString ?? "") + "]" + (AutoCompleteAtEndOfSpan ? ";AtEnd" : ";AtEOL"); - } - - public override bool Equals(object obj) - { - var other = obj as AutoCompleteEditHandler; - return base.Equals(other) && - string.Equals(other.AutoCompleteString, AutoCompleteString, StringComparison.Ordinal) && - AutoCompleteAtEndOfSpan == other.AutoCompleteAtEndOfSpan; - } - - public override int GetHashCode() - { - // Hash code should include only immutable properties but Equals also checks the type. - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(TypeHashCode); - hashCodeCombiner.Add(AutoCompleteAtEndOfSpan); - - return hashCodeCombiner.CombinedHash; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Editor/BackgroundParser.cs b/src/Microsoft.AspNet.Razor.VSRC1/Editor/BackgroundParser.cs deleted file mode 100644 index 9ecb8d9779..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Editor/BackgroundParser.cs +++ /dev/null @@ -1,493 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Threading; -using Microsoft.AspNet.Razor.CodeGenerators; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Utils; - -namespace Microsoft.AspNet.Razor.Editor -{ - internal class BackgroundParser : IDisposable - { - private MainThreadState _main; - private BackgroundThread _bg; - - public BackgroundParser(RazorEngineHost host, string fileName) - { - _main = new MainThreadState(fileName); - _bg = new BackgroundThread(_main, host, fileName); - - _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(TextChange change) - { - _main.QueueChange(change); - } - - [SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "_main", Justification = "MainThreadState is disposed when the background thread shuts down")] - 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); - } - } - - internal static bool TreesAreDifferent(Block leftTree, Block rightTree, IEnumerable changes) - { - return TreesAreDifferent(leftTree, rightTree, changes, CancellationToken.None); - } - - 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 (TextChange 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() - { - } - - [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This method is only empty in Release builds. In Debug builds it contains references to instance variables")] - [Conditional("DEBUG")] - protected void SetThreadId(int id) - { -#if DEBUG - _id = id; -#endif - } - - [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This method is only empty in Release builds. In Debug builds it contains references to instance variables")] - [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 - } - - [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This method is only empty in Release builds. In Debug builds it contains references to instance variables")] - [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; - - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "Field is used in debug code and may be used later")] - 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(TextChange change) - { - RazorEditorTrace.TraceLine(RazorResources.FormatTrace_QueuingParse(Path.GetFileName(_fileName), change)); - EnsureOnThread(); - lock (_stateLock) - { - // CurrentParcel token source is not null ==> There's a parse underway - if (_currentParcelCancelSource != null) - { - _currentParcelCancelSource.Cancel(); - } - - _changes.Add(change); - _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 RazorEngineHost _host; - private string _fileName; - private Block _currentParseTree; - private IList _previouslyDiscarded = new List(); - - public BackgroundThread(MainThreadState main, RazorEngineHost host, string fileName) - { - // Run on MAIN thread! - _main = main; - _backgroundThread = new Thread(WorkerLoop); - _shutdownToken = _main.CancelToken; - _host = host; - _fileName = fileName; - - SetThreadId(_backgroundThread.ManagedThreadId); - } - - // **** ANY THREAD **** - public void Start() - { - _backgroundThread.Start(); - } - - // **** BACKGROUND THREAD **** - private void WorkerLoop() - { - long? elapsedMs = null; - var fileNameOnly = Path.GetFileName(_fileName); -#if EDITOR_TRACING - var sw = new Stopwatch(); -#endif - - try - { - RazorEditorTrace.TraceLine(RazorResources.FormatTrace_BackgroundThreadStart(fileNameOnly)); - EnsureOnThread(); - -#if DOTNET5_4 - var spinWait = new SpinWait(); -#endif - - while (!_shutdownToken.IsCancellationRequested) - { - // Grab the parcel of work to do - var parcel = _main.GetParcel(); - if (parcel.Changes.Any()) - { - RazorEditorTrace.TraceLine(RazorResources.FormatTrace_ChangesArrived(fileNameOnly, parcel.Changes.Count)); - try - { - DocumentParseCompleteEventArgs args = null; - using (var linkedCancel = CancellationTokenSource.CreateLinkedTokenSource(_shutdownToken, parcel.CancelToken)) - { - if (!linkedCancel.IsCancellationRequested) - { - // Collect ALL changes -#if EDITOR_TRACING - if (_previouslyDiscarded != null && _previouslyDiscarded.Any()) - { - RazorEditorTrace.TraceLine(RazorResources.Trace_CollectedDiscardedChanges, fileNameOnly, _previouslyDiscarded.Count); - } -#endif - List allChanges; - - if (_previouslyDiscarded != null) - { - allChanges = Enumerable.Concat(_previouslyDiscarded, parcel.Changes).ToList(); - } - else - { - allChanges = parcel.Changes.ToList(); - } - - var finalChange = allChanges.Last(); -#if EDITOR_TRACING - sw.Start(); -#endif - var results = ParseChange(finalChange.NewBuffer, linkedCancel.Token); -#if EDITOR_TRACING - sw.Stop(); - elapsedMs = sw.ElapsedMilliseconds; - sw.Reset(); -#endif - RazorEditorTrace.TraceLine( - RazorResources.FormatTrace_ParseComplete( - fileNameOnly, - elapsedMs.HasValue ? elapsedMs.Value.ToString(CultureInfo.InvariantCulture) : "?")); - - if (results != null && !linkedCancel.IsCancellationRequested) - { - // Clear discarded changes list - _previouslyDiscarded = null; - - // Take the current tree and check for differences -#if EDITOR_TRACING - sw.Start(); -#endif - var treeStructureChanged = _currentParseTree == null || TreesAreDifferent(_currentParseTree, results.Document, allChanges, parcel.CancelToken); -#if EDITOR_TRACING - sw.Stop(); - elapsedMs = sw.ElapsedMilliseconds; - sw.Reset(); -#endif - _currentParseTree = results.Document; - RazorEditorTrace.TraceLine(RazorResources.FormatTrace_TreesCompared( - fileNameOnly, - elapsedMs.HasValue ? elapsedMs.Value.ToString(CultureInfo.InvariantCulture) : "?", - treeStructureChanged)); - - // Build Arguments - args = new DocumentParseCompleteEventArgs() - { - GeneratorResults = results, - SourceChange = finalChange, - TreeStructureChanged = treeStructureChanged - }; - } - else - { - // Parse completed but we were cancelled in the mean time. Add these to the discarded changes set - RazorEditorTrace.TraceLine(RazorResources.FormatTrace_ChangesDiscarded(fileNameOnly, allChanges.Count)); - _previouslyDiscarded = allChanges; - } - -#if CHECK_TREE - if (args != null) - { - // Rewind the buffer and sanity check the line mappings - finalChange.NewBuffer.Position = 0; - var lineCount = finalChange.NewBuffer.ReadToEnd().Split(new string[] { Environment.NewLine, "\r", "\n" }, StringSplitOptions.None).Count(); - Debug.Assert( - !args.GeneratorResults.DesignTimeLineMappings.Any(pair => pair.Value.StartLine > lineCount), - "Found a design-time line mapping referring to a line outside the source file!"); - Debug.Assert( - !args.GeneratorResults.Document.Flatten().Any(span => span.Start.LineIndex > lineCount), - "Found a span with a line number outside the source file"); - Debug.Assert( - !args.GeneratorResults.Document.Flatten().Any(span => span.Start.AbsoluteIndex > parcel.NewBuffer.Length), - "Found a span with an absolute offset outside the source file"); - } -#endif - } - } - if (args != null) - { - _main.ReturnParcel(args); - } - } - catch (OperationCanceledException) - { - } - } - else - { - RazorEditorTrace.TraceLine(RazorResources.FormatTrace_NoChangesArrived(fileNameOnly)); -#if DOTNET5_4 - // This does the equivalent of thread.yield under the covers. - spinWait.SpinOnce(); -#else - // No Yield in CoreCLR - - Thread.Yield(); -#endif - } - } - } - catch (OperationCanceledException) - { - // Do nothing. Just shut down. - } - finally - { - RazorEditorTrace.TraceLine(RazorResources.FormatTrace_BackgroundThreadShutdown(fileNameOnly)); - - // Clean up main thread resources - _main.Dispose(); - } - } - - private GeneratorResults ParseChange(ITextBuffer buffer, CancellationToken token) - { - EnsureOnThread(); - - // Create a template engine - var engine = new RazorTemplateEngine(_host); - - // Seek the buffer to the beginning - buffer.Position = 0; - - try - { - return engine.GenerateCode( - input: buffer, - className: null, - rootNamespace: null, - sourceFileName: _fileName, - cancelToken: token); - } - catch (OperationCanceledException) - { - return null; - } - } - } - - private class WorkParcel - { - public WorkParcel(IList changes, CancellationToken cancelToken) - { - Changes = changes; - CancelToken = cancelToken; - } - - public CancellationToken CancelToken { get; private set; } - public IList Changes { get; private set; } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Editor/EditResult.cs b/src/Microsoft.AspNet.Razor.VSRC1/Editor/EditResult.cs deleted file mode 100644 index f491f3ddf4..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Editor/EditResult.cs +++ /dev/null @@ -1,19 +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 Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Editor -{ - public class EditResult - { - public EditResult(PartialParseResult result, SpanBuilder editedSpan) - { - Result = result; - EditedSpan = editedSpan; - } - - public PartialParseResult Result { get; set; } - public SpanBuilder EditedSpan { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Editor/EditorHints.cs b/src/Microsoft.AspNet.Razor.VSRC1/Editor/EditorHints.cs deleted file mode 100644 index 53f8c63982..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Editor/EditorHints.cs +++ /dev/null @@ -1,27 +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.AspNet.Razor.Editor -{ - /// - /// Used within . - /// - [Flags] - public enum EditorHints - { - /// - /// The default (Markup or Code) editor behavior for Statement completion should be used. - /// Editors can always use the default behavior, even if the span is labeled with a different CompletionType. - /// - None = 0, // 0000 0000 - - /// - /// Indicates that Virtual Path completion should be used for this span if the editor supports it. - /// Editors need not support this mode of completion, and will use the default () behavior - /// if they do not support it. - /// - VirtualPath = 1, // 0000 0001 - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Editor/ImplicitExpressionEditHandler.cs b/src/Microsoft.AspNet.Razor.VSRC1/Editor/ImplicitExpressionEditHandler.cs deleted file mode 100644 index 16deff101a..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Editor/ImplicitExpressionEditHandler.cs +++ /dev/null @@ -1,327 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.IO; -using System.Linq; -using Microsoft.AspNet.Razor.Parser; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Editor -{ - public class ImplicitExpressionEditHandler : SpanEditHandler - { - private readonly ISet _keywords; - private readonly IReadOnlyCollection _readOnlyKeywords; - - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Func is the recommended delegate type and requires this level of nesting.")] - public ImplicitExpressionEditHandler(Func> tokenizer, ISet keywords, bool acceptTrailingDot) - : base(tokenizer) - { - _keywords = keywords ?? new HashSet(); - - // HashSet implements IReadOnlyCollection as of 4.6, but does not for 4.5.1. If the runtime cast - // succeeds, avoid creating a new collection. - _readOnlyKeywords = (_keywords as IReadOnlyCollection) ?? _keywords.ToArray(); - - AcceptTrailingDot = acceptTrailingDot; - } - - public bool AcceptTrailingDot { get; } - - public IReadOnlyCollection Keywords - { - get - { - return _readOnlyKeywords; - } - } - - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, "{0};ImplicitExpression[{1}];K{2}", base.ToString(), AcceptTrailingDot ? "ATD" : "RTD", Keywords.Count); - } - - public override bool Equals(object obj) - { - var other = obj as ImplicitExpressionEditHandler; - return base.Equals(other) && - _keywords.SetEquals(other._keywords) && - AcceptTrailingDot == other.AcceptTrailingDot; - } - - public override int GetHashCode() - { - // Hash code should include only immutable properties and base has none. - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(Keywords); - hashCodeCombiner.Add(AcceptTrailingDot); - - return hashCodeCombiner; - } - - protected override PartialParseResult CanAcceptChange(Span target, TextChange normalizedChange) - { - if (AcceptedCharacters == AcceptedCharacters.Any) - { - return PartialParseResult.Rejected; - } - - // In some editors intellisense insertions are handled as "dotless commits". If an intellisense selection is confirmed - // via something like '.' a dotless commit will append a '.' and then insert the remaining intellisense selection prior - // to the appended '.'. This 'if' statement attempts to accept the intermediate steps of a dotless commit via - // intellisense. It will accept two cases: - // 1. '@foo.' -> '@foobaz.'. - // 2. '@foobaz..' -> '@foobaz.bar.'. Includes Sub-cases '@foobaz()..' -> '@foobaz().bar.' etc. - // The key distinction being the double '.' in the second case. - if (IsDotlessCommitInsertion(target, normalizedChange)) - { - return HandleDotlessCommitInsertion(target); - } - - if (IsAcceptableReplace(target, normalizedChange)) - { - return HandleReplacement(target, normalizedChange); - } - var changeRelativePosition = normalizedChange.OldPosition - target.Start.AbsoluteIndex; - - // Get the edit context - char? lastChar = null; - if (changeRelativePosition > 0 && target.Content.Length > 0) - { - lastChar = target.Content[changeRelativePosition - 1]; - } - - // Don't support 0->1 length edits - if (lastChar == null) - { - return PartialParseResult.Rejected; - } - - // Accepts cases when insertions are made at the end of a span or '.' is inserted within a span. - if (IsAcceptableInsertion(target, normalizedChange)) - { - // Handle the insertion - return HandleInsertion(target, lastChar.Value, normalizedChange); - } - - if (IsAcceptableDeletion(target, normalizedChange)) - { - return HandleDeletion(target, lastChar.Value, normalizedChange); - } - - return PartialParseResult.Rejected; - } - - // A dotless commit is the process of inserting a '.' with an intellisense selection. - private static bool IsDotlessCommitInsertion(Span target, TextChange change) - { - return IsNewDotlessCommitInsertion(target, change) || IsSecondaryDotlessCommitInsertion(target, change); - } - - // Completing 'DateTime' in intellisense with a '.' could result in: '@DateT' -> '@DateT.' -> '@DateTime.' which is accepted. - private static bool IsNewDotlessCommitInsertion(Span target, TextChange change) - { - return !IsAtEndOfSpan(target, change) && - change.NewPosition > 0 && - change.NewLength > 0 && - target.Content.Last() == '.' && - ParserHelpers.IsIdentifier(change.NewText, requireIdentifierStart: false) && - (change.OldLength == 0 || ParserHelpers.IsIdentifier(change.OldText, requireIdentifierStart: false)); - } - - // Once a dotless commit has been performed you then have something like '@DateTime.'. This scenario is used to detect the - // situation when you try to perform another dotless commit resulting in a textchange with '..'. Completing 'DateTime.Now' - // in intellisense with a '.' could result in: '@DateTime.' -> '@DateTime..' -> '@DateTime.Now.' which is accepted. - private static bool IsSecondaryDotlessCommitInsertion(Span target, TextChange change) - { - // Do not need to worry about other punctuation, just looking for double '.' (after change) - return change.NewLength == 1 && - !string.IsNullOrEmpty(target.Content) && - target.Content.Last() == '.' && - change.NewText == "." && - change.OldLength == 0; - } - - private static bool IsAcceptableReplace(Span target, TextChange change) - { - return IsEndReplace(target, change) || - (change.IsReplace && RemainingIsWhitespace(target, change)); - } - - private static bool IsAcceptableDeletion(Span target, TextChange change) - { - return IsEndDeletion(target, change) || - (change.IsDelete && RemainingIsWhitespace(target, change)); - } - - // Acceptable insertions can occur at the end of a span or when a '.' is inserted within a span. - private static bool IsAcceptableInsertion(Span target, TextChange change) - { - return change.IsInsert && - (IsAcceptableEndInsertion(target, change) || - IsAcceptableInnerInsertion(target, change)); - } - - // Accepts character insertions at the end of spans. AKA: '@foo' -> '@fooo' or '@foo' -> '@foo ' etc. - private static bool IsAcceptableEndInsertion(Span target, TextChange change) - { - Debug.Assert(change.IsInsert); - - return IsAtEndOfSpan(target, change) || - RemainingIsWhitespace(target, change); - } - - // Accepts '.' insertions in the middle of spans. Ex: '@foo.baz.bar' -> '@foo..baz.bar' - // This is meant to allow intellisense when editing a span. - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "target", Justification = "The 'target' parameter is used in Debug to validate that the function is called in the correct context.")] - private static bool IsAcceptableInnerInsertion(Span target, TextChange change) - { - Debug.Assert(change.IsInsert); - - // Ensure that we're actually inserting in the middle of a span and not at the end. - // This case will fail if the IsAcceptableEndInsertion does not capture an end insertion correctly. - Debug.Assert(!IsAtEndOfSpan(target, change)); - - return change.NewPosition > 0 && - change.NewText == "."; - } - - private static bool RemainingIsWhitespace(Span target, TextChange change) - { - var offset = (change.OldPosition - target.Start.AbsoluteIndex) + change.OldLength; - return string.IsNullOrWhiteSpace(target.Content.Substring(offset)); - } - - private PartialParseResult HandleDotlessCommitInsertion(Span target) - { - var result = PartialParseResult.Accepted; - if (!AcceptTrailingDot && target.Content.LastOrDefault() == '.') - { - result |= PartialParseResult.Provisional; - } - return result; - } - - private PartialParseResult HandleReplacement(Span target, TextChange change) - { - // Special Case for IntelliSense commits. - // When IntelliSense commits, we get two changes (for example user typed "Date", then committed "DateTime" by pressing ".") - // 1. Insert "." at the end of this span - // 2. Replace the "Date." at the end of the span with "DateTime." - // We need partial parsing to accept case #2. - var oldText = GetOldText(target, change); - - var result = PartialParseResult.Rejected; - if (EndsWithDot(oldText) && EndsWithDot(change.NewText)) - { - result = PartialParseResult.Accepted; - if (!AcceptTrailingDot) - { - result |= PartialParseResult.Provisional; - } - } - return result; - } - - private PartialParseResult HandleDeletion(Span target, char previousChar, TextChange change) - { - // What's left after deleting? - if (previousChar == '.') - { - return TryAcceptChange(target, change, PartialParseResult.Accepted | PartialParseResult.Provisional); - } - else if (ParserHelpers.IsIdentifierPart(previousChar)) - { - return TryAcceptChange(target, change); - } - else - { - return PartialParseResult.Rejected; - } - } - - private PartialParseResult HandleInsertion(Span target, char previousChar, TextChange change) - { - // What are we inserting after? - if (previousChar == '.') - { - return HandleInsertionAfterDot(target, change); - } - else if (ParserHelpers.IsIdentifierPart(previousChar) || previousChar == ')' || previousChar == ']') - { - return HandleInsertionAfterIdPart(target, change); - } - else - { - return PartialParseResult.Rejected; - } - } - - private PartialParseResult HandleInsertionAfterIdPart(Span target, TextChange change) - { - // If the insertion is a full identifier part, accept it - if (ParserHelpers.IsIdentifier(change.NewText, requireIdentifierStart: false)) - { - return TryAcceptChange(target, change); - } - else if (EndsWithDot(change.NewText)) - { - // Accept it, possibly provisionally - var result = PartialParseResult.Accepted; - if (!AcceptTrailingDot) - { - result |= PartialParseResult.Provisional; - } - return TryAcceptChange(target, change, result); - } - else - { - return PartialParseResult.Rejected; - } - } - - private static bool EndsWithDot(string content) - { - return (content.Length == 1 && content[0] == '.') || - (content[content.Length - 1] == '.' && - content.Take(content.Length - 1).All(ParserHelpers.IsIdentifierPart)); - } - - private PartialParseResult HandleInsertionAfterDot(Span target, TextChange 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; - } - - private PartialParseResult TryAcceptChange(Span target, TextChange change, PartialParseResult acceptResult = PartialParseResult.Accepted) - { - var content = change.ApplyChange(target); - if (StartsWithKeyword(content)) - { - return PartialParseResult.Rejected | PartialParseResult.SpanContextChanged; - } - - return acceptResult; - } - - private bool StartsWithKeyword(string newContent) - { - using (var reader = new StringReader(newContent)) - { - return _keywords.Contains(reader.ReadWhile(ParserHelpers.IsIdentifierPart)); - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Editor/RazorEditorTrace.cs b/src/Microsoft.AspNet.Razor.VSRC1/Editor/RazorEditorTrace.cs deleted file mode 100644 index 80fa645819..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Editor/RazorEditorTrace.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; -using System.Diagnostics; -#if NET451 -using System.Globalization; -#endif - -namespace Microsoft.AspNet.Razor.Editor -{ - internal static class RazorEditorTrace - { - private static bool? _enabled; - - private static bool IsEnabled() - { - if (_enabled == null) - { - bool enabled; - if (Boolean.TryParse(Environment.GetEnvironmentVariable("RAZOR_EDITOR_TRACE"), out enabled)) - { -#if NET451 - // No Trace in CoreCLR - - Trace.WriteLine(RazorResources.FormatTrace_Startup( - enabled ? RazorResources.Trace_Enabled : RazorResources.Trace_Disabled)); -#endif - _enabled = enabled; - } - else - { - _enabled = false; - } - } - return _enabled.Value; - } - - [Conditional("EDITOR_TRACING")] - public static void TraceLine(string format, params object[] args) - { - if (IsEnabled()) - { -#if NET451 - // No Trace in CoreCLR - - Trace.WriteLine(RazorResources.FormatTrace_Format( - string.Format(CultureInfo.CurrentCulture, format, args))); -#endif - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Editor/SingleLineMarkupEditHandler.cs b/src/Microsoft.AspNet.Razor.VSRC1/Editor/SingleLineMarkupEditHandler.cs deleted file mode 100644 index b2b7289aeb..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Editor/SingleLineMarkupEditHandler.cs +++ /dev/null @@ -1,26 +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; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Editor -{ - public class SingleLineMarkupEditHandler : SpanEditHandler - { - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Func is the recommended delegate type and requires this level of nesting.")] - public SingleLineMarkupEditHandler(Func> tokenizer) - : base(tokenizer) - { - } - - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Func is the recommended delegate type and requires this level of nesting.")] - public SingleLineMarkupEditHandler(Func> tokenizer, AcceptedCharacters accepted) - : base(tokenizer, accepted) - { - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Editor/SpanEditHandler.cs b/src/Microsoft.AspNet.Razor.VSRC1/Editor/SpanEditHandler.cs deleted file mode 100644 index 3931c2262b..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Editor/SpanEditHandler.cs +++ /dev/null @@ -1,185 +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; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Editor -{ - // Manages edits to a span - public class SpanEditHandler - { - private static readonly int TypeHashCode = typeof(SpanEditHandler).GetHashCode(); - - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Func is the recommended delegate type and requires this level of nesting.")] - public SpanEditHandler(Func> tokenizer) - : this(tokenizer, AcceptedCharacters.Any) - { - } - - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Func is the recommended delegate type and requires this level of nesting.")] - public SpanEditHandler(Func> tokenizer, AcceptedCharacters accepted) - { - AcceptedCharacters = accepted; - Tokenizer = tokenizer; - } - - public AcceptedCharacters AcceptedCharacters { get; set; } - - /// - /// Provides a set of hints to editors which may be manipulating the document in which this span is located. - /// - public EditorHints EditorHints { get; set; } - - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Func is the recommended delegate type and requires this level of nesting.")] - public Func> Tokenizer { get; set; } - - public static SpanEditHandler CreateDefault() - { - return CreateDefault(s => Enumerable.Empty()); - } - - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Func is the recommended delegate type and requires this level of nesting.")] - public static SpanEditHandler CreateDefault(Func> tokenizer) - { - return new SpanEditHandler(tokenizer); - } - - public virtual EditResult ApplyChange(Span target, TextChange change) - { - return ApplyChange(target, change, force: false); - } - - public virtual EditResult ApplyChange(Span target, TextChange change, bool force) - { - var result = PartialParseResult.Accepted; - var normalized = change.Normalize(); - if (!force) - { - result = CanAcceptChange(target, normalized); - } - - // If the change is accepted then apply the change - if ((result & PartialParseResult.Accepted) == PartialParseResult.Accepted) - { - return new EditResult(result, UpdateSpan(target, normalized)); - } - return new EditResult(result, new SpanBuilder(target)); - } - - public virtual bool OwnsChange(Span target, TextChange change) - { - var end = target.Start.AbsoluteIndex + target.Length; - var changeOldEnd = change.OldPosition + change.OldLength; - return change.OldPosition >= target.Start.AbsoluteIndex && - (changeOldEnd < end || (changeOldEnd == end && AcceptedCharacters != AcceptedCharacters.None)); - } - - protected virtual PartialParseResult CanAcceptChange(Span target, TextChange normalizedChange) - { - return PartialParseResult.Rejected; - } - - protected virtual SpanBuilder UpdateSpan(Span target, TextChange normalizedChange) - { - var newContent = normalizedChange.ApplyChange(target); - var newSpan = new SpanBuilder(target); - newSpan.ClearSymbols(); - foreach (ISymbol sym in Tokenizer(newContent)) - { - sym.OffsetStart(target.Start); - newSpan.Accept(sym); - } - if (target.Next != null) - { - var newEnd = SourceLocationTracker.CalculateNewLocation(target.Start, newContent); - target.Next.ChangeStart(newEnd); - } - return newSpan; - } - - protected internal static bool IsAtEndOfFirstLine(Span target, TextChange change) - { - var endOfFirstLine = target.Content.IndexOfAny(new char[] { (char)0x000d, (char)0x000a, (char)0x2028, (char)0x2029 }); - return (endOfFirstLine == -1 || (change.OldPosition - target.Start.AbsoluteIndex) <= endOfFirstLine); - } - - /// - /// Returns true if the specified change is an insertion of text at the end of this span. - /// - protected internal static bool IsEndInsertion(Span target, TextChange change) - { - return change.IsInsert && IsAtEndOfSpan(target, change); - } - - /// - /// Returns true if the specified change is an insertion of text at the end of this span. - /// - protected internal static bool IsEndDeletion(Span target, TextChange change) - { - return change.IsDelete && IsAtEndOfSpan(target, change); - } - - /// - /// Returns true if the specified change is a replacement of text at the end of this span. - /// - protected internal static bool IsEndReplace(Span target, TextChange change) - { - return change.IsReplace && IsAtEndOfSpan(target, change); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "This method should only be used on Spans")] - protected internal static bool IsAtEndOfSpan(Span target, TextChange change) - { - return (change.OldPosition + change.OldLength) == (target.Start.AbsoluteIndex + target.Length); - } - - /// - /// Returns the old text referenced by the change. - /// - /// - /// If the content has already been updated by applying the change, this data will be _invalid_ - /// - protected internal static string GetOldText(Span target, TextChange change) - { - return target.Content.Substring(change.OldPosition - target.Start.AbsoluteIndex, change.OldLength); - } - - // Is the specified span to the right of this span and immediately adjacent? - internal static bool IsAdjacentOnRight(Span target, Span other) - { - return target.Start.AbsoluteIndex < other.Start.AbsoluteIndex && target.Start.AbsoluteIndex + target.Length == other.Start.AbsoluteIndex; - } - - // Is the specified span to the left of this span and immediately adjacent? - internal static bool IsAdjacentOnLeft(Span target, Span other) - { - return other.Start.AbsoluteIndex < target.Start.AbsoluteIndex && other.Start.AbsoluteIndex + other.Length == target.Start.AbsoluteIndex; - } - - public override string ToString() - { - return GetType().Name + ";Accepts:" + AcceptedCharacters + ((EditorHints == EditorHints.None) ? string.Empty : (";Hints: " + EditorHints.ToString())); - } - - public override bool Equals(object obj) - { - var other = obj as SpanEditHandler; - return other != null && - GetType() == other.GetType() && - AcceptedCharacters == other.AcceptedCharacters && - EditorHints == other.EditorHints; - } - - public override int GetHashCode() - { - // Hash code should include only immutable properties but Equals also checks the type. - return TypeHashCode; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/ErrorSink.cs b/src/Microsoft.AspNet.Razor.VSRC1/ErrorSink.cs deleted file mode 100644 index 8177f6ccaf..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/ErrorSink.cs +++ /dev/null @@ -1,54 +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.Collections.Generic; - -namespace Microsoft.AspNet.Razor -{ - /// - /// Used to manage s encountered during the Razor parsing phase. - /// - public class ErrorSink - { - private readonly List _errors; - - /// - /// Instantiates a new instance of . - /// - public ErrorSink() - { - _errors = new List(); - } - - /// - /// s collected. - /// - public IEnumerable Errors - { - get - { - return _errors; - } - } - - /// - /// Tracks the given . - /// - /// The to track. - public void OnError(RazorError error) - { - _errors.Add(error); - } - - /// - /// Creates and tracks a new . - /// - /// of the error. - /// A message describing the error. - /// The length of the error. - public void OnError(SourceLocation location, string message, int length) - { - _errors.Add(new RazorError(message, location, length)); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/GlobalSuppressions.cs b/src/Microsoft.AspNet.Razor.VSRC1/GlobalSuppressions.cs deleted file mode 100644 index c67d845ecb..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/GlobalSuppressions.cs +++ /dev/null @@ -1,22 +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. - -// This file is used by Code Analysis to maintain SuppressMessage -// attributes that are applied to this project. -// Project-level suppressions either have no target or are given -// a specific target and scoped to a namespace, type, member, etc. -// -// To add a suppression to this file, right-click the message in the -// Error List, point to "Suppress Message(s)", and click -// "In Project Suppression File". -// You do not need to add suppressions to this file manually. - -using System.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "br", Scope = "resource", Target = "Microsoft.AspNet.Razor.Resources.RazorResources.resources", Justification = "Resource is referencing html tag")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.AspNet.Razor.Tokenizer.Symbols", Justification = "These namespaces are design to group classes by function. They will be reviewed to ensure they remain relevant.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.AspNet.Razor.Tokenizer", Justification = "These namespaces are design to group classes by function. They will be reviewed to ensure they remain relevant.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.AspNet.Razor.Text", Justification = "These namespaces are design to group classes by function. They will be reviewed to ensure they remain relevant.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.AspNet.Razor.Parser", Justification = "These namespaces are design to group classes by function. They will be reviewed to ensure they remain relevant.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.AspNet.Razor.Editor", Justification = "These namespaces are design to group classes by function. They will be reviewed to ensure they remain relevant.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.AspNet.Razor", Justification = "These namespaces are design to group classes by function. They will be reviewed to ensure they remain relevant.")] diff --git a/src/Microsoft.AspNet.Razor.VSRC1/HashCodeCombiner.cs b/src/Microsoft.AspNet.Razor.VSRC1/HashCodeCombiner.cs deleted file mode 100644 index 4df8b46b05..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/HashCodeCombiner.cs +++ /dev/null @@ -1,84 +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.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -namespace Microsoft.Extensions.Internal -{ - internal struct HashCodeCombiner - { - private long _combinedHash64; - - public int CombinedHash - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _combinedHash64.GetHashCode(); } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private HashCodeCombiner(long seed) - { - _combinedHash64 = seed; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(IEnumerable e) - { - if (e == null) - { - Add(0); - } - else - { - var count = 0; - foreach (object o in e) - { - Add(o); - count++; - } - Add(count); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator int(HashCodeCombiner self) - { - return self.CombinedHash; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(int i) - { - _combinedHash64 = ((_combinedHash64 << 5) + _combinedHash64) ^ i; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(string s) - { - var hashCode = (s != null) ? s.GetHashCode() : 0; - Add(hashCode); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(object o) - { - var hashCode = (o != null) ? o.GetHashCode() : 0; - Add(hashCode); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Add(TValue value, IEqualityComparer comparer) - { - var hashCode = value != null ? comparer.GetHashCode(value) : 0; - Add(hashCode); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static HashCodeCombiner Start() - { - return new HashCodeCombiner(0x1505L); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Microsoft.AspNet.Razor.VSRC1.xproj b/src/Microsoft.AspNet.Razor.VSRC1/Microsoft.AspNet.Razor.VSRC1.xproj deleted file mode 100644 index dcbe59743f..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Microsoft.AspNet.Razor.VSRC1.xproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - ab5abc37-201b-41ff-9faf-e948b0d33f5a - ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ - - - 2.0 - - - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Parser/BalancingModes.cs b/src/Microsoft.AspNet.Razor.VSRC1/Parser/BalancingModes.cs deleted file mode 100644 index ab2b13dbc4..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Parser/BalancingModes.cs +++ /dev/null @@ -1,16 +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.AspNet.Razor.Parser -{ - [Flags] - public enum BalancingModes - { - None = 0, - BacktrackOnFailure = 1, - NoErrorOnFailure = 2, - AllowCommentsAndTemplates = 4, - AllowEmbeddedTransitions = 8 - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.Directives.cs b/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.Directives.cs deleted file mode 100644 index c241e160d3..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.Directives.cs +++ /dev/null @@ -1,360 +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; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using Microsoft.AspNet.Razor.Chunks.Generators; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Parser -{ - public partial class CSharpCodeParser - { - private void SetupDirectives() - { - MapDirectives(TagHelperPrefixDirective, SyntaxConstants.CSharp.TagHelperPrefixKeyword); - MapDirectives(AddTagHelperDirective, SyntaxConstants.CSharp.AddTagHelperKeyword); - MapDirectives(RemoveTagHelperDirective, SyntaxConstants.CSharp.RemoveTagHelperKeyword); - MapDirectives(InheritsDirective, SyntaxConstants.CSharp.InheritsKeyword); - MapDirectives(FunctionsDirective, SyntaxConstants.CSharp.FunctionsKeyword); - MapDirectives(SectionDirective, SyntaxConstants.CSharp.SectionKeyword); - } - - protected virtual void TagHelperPrefixDirective() - { - TagHelperDirective( - SyntaxConstants.CSharp.TagHelperPrefixKeyword, - prefix => new TagHelperPrefixDirectiveChunkGenerator(prefix)); - } - - protected virtual void AddTagHelperDirective() - { - TagHelperDirective( - SyntaxConstants.CSharp.AddTagHelperKeyword, - lookupText => - new AddOrRemoveTagHelperChunkGenerator(removeTagHelperDescriptors: false, lookupText: lookupText)); - } - - protected virtual void RemoveTagHelperDirective() - { - TagHelperDirective( - SyntaxConstants.CSharp.RemoveTagHelperKeyword, - lookupText => - new AddOrRemoveTagHelperChunkGenerator(removeTagHelperDescriptors: true, lookupText: lookupText)); - } - - protected virtual void SectionDirective() - { - var nested = Context.IsWithin(BlockType.Section); - var errorReported = false; - - // Set the block and span type - Context.CurrentBlock.Type = BlockType.Section; - - // Verify we're on "section" and accept - AssertDirective(SyntaxConstants.CSharp.SectionKeyword); - var startLocation = CurrentLocation; - AcceptAndMoveNext(); - - if (nested) - { - Context.OnError( - startLocation, - RazorResources.FormatParseError_Sections_Cannot_Be_Nested(RazorResources.SectionExample_CS), - Span.GetContent().Value.Length); - errorReported = true; - } - - var whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false)); - - // Get the section name - var sectionName = string.Empty; - if (!Required(CSharpSymbolType.Identifier, - errorIfNotFound: true, - errorBase: RazorResources.FormatParseError_Unexpected_Character_At_Section_Name_Start)) - { - if (!errorReported) - { - errorReported = true; - } - - PutCurrentBack(); - PutBack(whitespace); - AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false)); - } - else - { - Accept(whitespace); - sectionName = CurrentSymbol.Content; - AcceptAndMoveNext(); - } - Context.CurrentBlock.ChunkGenerator = new SectionChunkGenerator(sectionName); - - var errorLocation = CurrentLocation; - whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false)); - - // Get the starting brace - var sawStartingBrace = At(CSharpSymbolType.LeftBrace); - if (!sawStartingBrace) - { - if (!errorReported) - { - errorReported = true; - Context.OnError( - errorLocation, - RazorResources.ParseError_MissingOpenBraceAfterSection, - length: 1 /* { */); - } - - PutCurrentBack(); - PutBack(whitespace); - AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false)); - Optional(CSharpSymbolType.NewLine); - Output(SpanKind.MetaCode); - CompleteBlock(); - return; - } - else - { - Accept(whitespace); - } - - // Set up edit handler - var editHandler = new AutoCompleteEditHandler(Language.TokenizeString, autoCompleteAtEndOfSpan: true); - - Span.EditHandler = editHandler; - Span.Accept(CurrentSymbol); - - // Output Metacode then switch to section parser - Output(SpanKind.MetaCode); - SectionBlock("{", "}", caseSensitive: true); - - Span.ChunkGenerator = SpanChunkGenerator.Null; - // Check for the terminating "}" - if (!Optional(CSharpSymbolType.RightBrace)) - { - editHandler.AutoCompleteString = "}"; - Context.OnError( - CurrentLocation, - RazorResources.FormatParseError_Expected_X(Language.GetSample(CSharpSymbolType.RightBrace)), - length: 1 /* } */); - } - else - { - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - } - CompleteBlock(insertMarkerIfNecessary: false, captureWhitespaceToEndOfLine: true); - Output(SpanKind.MetaCode); - return; - } - - protected virtual void FunctionsDirective() - { - // Set the block type - Context.CurrentBlock.Type = BlockType.Functions; - - // Verify we're on "functions" and accept - AssertDirective(SyntaxConstants.CSharp.FunctionsKeyword); - var block = new Block(CurrentSymbol); - AcceptAndMoveNext(); - - AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: false)); - - if (!At(CSharpSymbolType.LeftBrace)) - { - Context.OnError( - CurrentLocation, - RazorResources.FormatParseError_Expected_X(Language.GetSample(CSharpSymbolType.LeftBrace)), - length: 1 /* { */); - CompleteBlock(); - Output(SpanKind.MetaCode); - return; - } - else - { - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - } - - // Capture start point and continue - var blockStart = CurrentLocation; - AcceptAndMoveNext(); - - // Output what we've seen and continue - Output(SpanKind.MetaCode); - - var editHandler = new AutoCompleteEditHandler(Language.TokenizeString); - Span.EditHandler = editHandler; - - Balance(BalancingModes.NoErrorOnFailure, CSharpSymbolType.LeftBrace, CSharpSymbolType.RightBrace, blockStart); - Span.ChunkGenerator = new TypeMemberChunkGenerator(); - if (!At(CSharpSymbolType.RightBrace)) - { - editHandler.AutoCompleteString = "}"; - Context.OnError( - blockStart, - RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, "}", "{"), - length: 1 /* } */); - CompleteBlock(); - Output(SpanKind.Code); - } - else - { - Output(SpanKind.Code); - Assert(CSharpSymbolType.RightBrace); - Span.ChunkGenerator = SpanChunkGenerator.Null; - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - AcceptAndMoveNext(); - CompleteBlock(); - Output(SpanKind.MetaCode); - } - } - - protected virtual void InheritsDirective() - { - // Verify we're on the right keyword and accept - AssertDirective(SyntaxConstants.CSharp.InheritsKeyword); - AcceptAndMoveNext(); - - InheritsDirectiveCore(); - } - - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "directive", Justification = "This only occurs in Release builds, where this method is empty by design")] - [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This only occurs in Release builds, where this method is empty by design")] - [Conditional("DEBUG")] - protected void AssertDirective(string directive) - { - Assert(CSharpSymbolType.Identifier); - Debug.Assert(string.Equals(CurrentSymbol.Content, directive, StringComparison.Ordinal)); - } - - protected void InheritsDirectiveCore() - { - BaseTypeDirective( - RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName, - baseType => new SetBaseTypeChunkGenerator(baseType)); - } - - protected void BaseTypeDirective(string noTypeNameError, Func createChunkGenerator) - { - var keywordStartLocation = Span.Start; - - // Set the block type - Context.CurrentBlock.Type = BlockType.Directive; - - var keywordLength = Span.GetContent().Value.Length; - - // Accept whitespace - var remainingWhitespace = AcceptSingleWhiteSpaceCharacter(); - - if (Span.Symbols.Count > 1) - { - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - } - - Output(SpanKind.MetaCode); - - if (remainingWhitespace != null) - { - Accept(remainingWhitespace); - } - - AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); - - if (EndOfFile || At(CSharpSymbolType.WhiteSpace) || At(CSharpSymbolType.NewLine)) - { - Context.OnError( - keywordStartLocation, - noTypeNameError, - keywordLength); - } - - // Parse to the end of the line - AcceptUntil(CSharpSymbolType.NewLine); - if (!Context.DesignTimeMode) - { - // We want the newline to be treated as code, but it causes issues at design-time. - Optional(CSharpSymbolType.NewLine); - } - - // Pull out the type name - string baseType = Span.GetContent(); - - // Set up chunk generation - Span.ChunkGenerator = createChunkGenerator(baseType.Trim()); - - // Output the span and finish the block - CompleteBlock(); - Output(SpanKind.Code, AcceptedCharacters.AnyExceptNewline); - } - - private void TagHelperDirective(string keyword, Func buildChunkGenerator) - { - AssertDirective(keyword); - var keywordStartLocation = CurrentLocation; - - // Accept the directive name - AcceptAndMoveNext(); - - // Set the block type - Context.CurrentBlock.Type = BlockType.Directive; - - var keywordLength = Span.GetContent().Value.Length; - - var foundWhitespace = At(CSharpSymbolType.WhiteSpace); - AcceptWhile(CSharpSymbolType.WhiteSpace); - - // If we found whitespace then any content placed within the whitespace MAY cause a destructive change - // to the document. We can't accept it. - Output(SpanKind.MetaCode, foundWhitespace ? AcceptedCharacters.None : AcceptedCharacters.AnyExceptNewline); - - if (EndOfFile || At(CSharpSymbolType.NewLine)) - { - Context.OnError( - keywordStartLocation, - RazorResources.FormatParseError_DirectiveMustHaveValue(keyword), - keywordLength); - } - else - { - // Need to grab the current location before we accept until the end of the line. - var startLocation = CurrentLocation; - - // Parse to the end of the line. Essentially accepts anything until end of line, comments, invalid code - // etc. - AcceptUntil(CSharpSymbolType.NewLine); - - // Pull out the value minus the spaces at the end - var rawValue = Span.GetContent().Value.TrimEnd(); - var startsWithQuote = rawValue.StartsWith("\"", StringComparison.OrdinalIgnoreCase); - - // If the value starts with a quote then we should generate appropriate C# code to colorize the value. - if (startsWithQuote) - { - // Set up chunk generation - // The generated chunk of this chunk generator is picked up by CSharpDesignTimeHelpersVisitor which - // renders the C# to colorize the user provided value. We trim the quotes around the user's value - // so when we render the code we can project the users value into double quotes to not invoke C# - // IntelliSense. - Span.ChunkGenerator = buildChunkGenerator(rawValue.Trim('"')); - } - - // We expect the directive to be surrounded in quotes. - // The format for tag helper directives are: @directivename "SomeValue" - if (!startsWithQuote || - !rawValue.EndsWith("\"", StringComparison.OrdinalIgnoreCase)) - { - Context.OnError( - startLocation, - RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(keyword), - rawValue.Length); - } - } - - // Output the span and finish the block - CompleteBlock(); - Output(SpanKind.Code, AcceptedCharacters.AnyExceptNewline); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.Expressions.cs b/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.Expressions.cs deleted file mode 100644 index 656f6c37e7..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.Expressions.cs +++ /dev/null @@ -1,39 +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 Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Parser -{ - public partial class CSharpCodeParser - { - private void SetUpExpressions() - { - MapExpressionKeyword(AwaitExpression, CSharpKeyword.Await); - } - - private void AwaitExpression(bool topLevel) - { - // Ensure that we're on the await statement (only runs in debug) - Assert(CSharpKeyword.Await); - - // Accept the "await" and move on - AcceptAndMoveNext(); - - // Accept 1 or more spaces between the await and the following code. - AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); - - // Top level basically indicates if we're within an expression or statement. - // Ex: topLevel true = @await Foo() | topLevel false = @{ await Foo(); } - // Note that in this case @{ @await Foo() } top level is true for await. - // Therefore, if we're top level then we want to act like an implicit expression, - // otherwise just act as whatever we're contained in. - if (topLevel) - { - // Setup the Span to be an async implicit expression (an implicit expresison that allows spaces). - // Spaces are allowed because of "@await Foo()". - AsyncImplicitExpression(); - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.Statements.cs b/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.Statements.cs deleted file mode 100644 index 953c7f10ae..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.Statements.cs +++ /dev/null @@ -1,745 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Microsoft.AspNet.Razor.Chunks.Generators; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Parser -{ - public partial class CSharpCodeParser - { - private static readonly Func IsValidStatementSpacingSymbol = - IsSpacingToken(includeNewLines: true, includeComments: true); - - private void SetUpKeywords() - { - MapKeywords(ConditionalBlock, CSharpKeyword.For, CSharpKeyword.Foreach, CSharpKeyword.While, CSharpKeyword.Switch, CSharpKeyword.Lock); - MapKeywords(CaseStatement, false, CSharpKeyword.Case, CSharpKeyword.Default); - MapKeywords(IfStatement, CSharpKeyword.If); - MapKeywords(TryStatement, CSharpKeyword.Try); - MapKeywords(UsingKeyword, CSharpKeyword.Using); - MapKeywords(DoStatement, CSharpKeyword.Do); - MapKeywords(ReservedDirective, CSharpKeyword.Namespace, CSharpKeyword.Class); - } - - protected virtual void ReservedDirective(bool topLevel) - { - Context.OnError( - CurrentLocation, - RazorResources.FormatParseError_ReservedWord(CurrentSymbol.Content), - CurrentSymbol.Content.Length); - AcceptAndMoveNext(); - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - Span.ChunkGenerator = SpanChunkGenerator.Null; - Context.CurrentBlock.Type = BlockType.Directive; - CompleteBlock(); - Output(SpanKind.MetaCode); - } - - private void KeywordBlock(bool topLevel) - { - HandleKeyword(topLevel, () => - { - Context.CurrentBlock.Type = BlockType.Expression; - Context.CurrentBlock.ChunkGenerator = new ExpressionChunkGenerator(); - ImplicitExpression(); - }); - } - - private void CaseStatement(bool topLevel) - { - Assert(CSharpSymbolType.Keyword); - Debug.Assert(CurrentSymbol.Keyword != null && - (CurrentSymbol.Keyword.Value == CSharpKeyword.Case || - CurrentSymbol.Keyword.Value == CSharpKeyword.Default)); - AcceptUntil(CSharpSymbolType.Colon); - Optional(CSharpSymbolType.Colon); - } - - private void DoStatement(bool topLevel) - { - Assert(CSharpKeyword.Do); - UnconditionalBlock(); - WhileClause(); - if (topLevel) - { - CompleteBlock(); - } - } - - private void WhileClause() - { - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any; - IEnumerable ws = SkipToNextImportantToken(); - - if (At(CSharpKeyword.While)) - { - Accept(ws); - Assert(CSharpKeyword.While); - AcceptAndMoveNext(); - AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - if (AcceptCondition() && Optional(CSharpSymbolType.Semicolon)) - { - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - } - } - else - { - PutCurrentBack(); - PutBack(ws); - } - } - - private void UsingKeyword(bool topLevel) - { - Assert(CSharpKeyword.Using); - var block = new Block(CurrentSymbol); - AcceptAndMoveNext(); - AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); - - if (At(CSharpSymbolType.LeftParenthesis)) - { - // using ( ==> Using Statement - UsingStatement(block); - } - else if (At(CSharpSymbolType.Identifier) || At(CSharpKeyword.Static)) - { - // using Identifier ==> Using Declaration - if (!topLevel) - { - Context.OnError( - block.Start, - RazorResources.ParseError_NamespaceImportAndTypeAlias_Cannot_Exist_Within_CodeBlock, - block.Name.Length); - StandardStatement(); - } - else - { - UsingDeclaration(); - } - } - - if (topLevel) - { - CompleteBlock(); - } - } - - private void UsingDeclaration() - { - // Set block type to directive - Context.CurrentBlock.Type = BlockType.Directive; - - if (At(CSharpSymbolType.Identifier)) - { - // non-static using - NamespaceOrTypeName(); - var whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - if (At(CSharpSymbolType.Assign)) - { - // Alias - Accept(whitespace); - Assert(CSharpSymbolType.Assign); - AcceptAndMoveNext(); - - AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - - // One more namespace or type name - NamespaceOrTypeName(); - } - else - { - PutCurrentBack(); - PutBack(whitespace); - } - } - else if (At(CSharpKeyword.Static)) - { - // static using - AcceptAndMoveNext(); - AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); - NamespaceOrTypeName(); - } - - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.AnyExceptNewline; - Span.ChunkGenerator = new AddImportChunkGenerator( - Span.GetContent(symbols => symbols.Skip(1))); - - // Optional ";" - if (EnsureCurrent()) - { - Optional(CSharpSymbolType.Semicolon); - } - } - - protected bool NamespaceOrTypeName() - { - if (Optional(CSharpSymbolType.Identifier) || Optional(CSharpSymbolType.Keyword)) - { - Optional(CSharpSymbolType.QuestionMark); // Nullable - if (Optional(CSharpSymbolType.DoubleColon)) - { - if (!Optional(CSharpSymbolType.Identifier)) - { - Optional(CSharpSymbolType.Keyword); - } - } - if (At(CSharpSymbolType.LessThan)) - { - TypeArgumentList(); - } - if (Optional(CSharpSymbolType.Dot)) - { - NamespaceOrTypeName(); - } - while (At(CSharpSymbolType.LeftBracket)) - { - Balance(BalancingModes.None); - Optional(CSharpSymbolType.RightBracket); - } - return true; - } - else - { - return false; - } - } - - private void TypeArgumentList() - { - Assert(CSharpSymbolType.LessThan); - Balance(BalancingModes.None); - Optional(CSharpSymbolType.GreaterThan); - } - - private void UsingStatement(Block block) - { - Assert(CSharpSymbolType.LeftParenthesis); - - // Parse condition - if (AcceptCondition()) - { - AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - - // Parse code block - ExpectCodeBlock(block); - } - } - - private void TryStatement(bool topLevel) - { - Assert(CSharpKeyword.Try); - UnconditionalBlock(); - AfterTryClause(); - if (topLevel) - { - CompleteBlock(); - } - } - - private void IfStatement(bool topLevel) - { - Assert(CSharpKeyword.If); - ConditionalBlock(topLevel: false); - AfterIfClause(); - if (topLevel) - { - CompleteBlock(); - } - } - - private void AfterTryClause() - { - // Grab whitespace - var whitespace = SkipToNextImportantToken(); - - // Check for a catch or finally part - if (At(CSharpKeyword.Catch)) - { - Accept(whitespace); - Assert(CSharpKeyword.Catch); - FilterableCatchBlock(); - AfterTryClause(); - } - else if (At(CSharpKeyword.Finally)) - { - Accept(whitespace); - Assert(CSharpKeyword.Finally); - UnconditionalBlock(); - } - else - { - // Return whitespace and end the block - PutCurrentBack(); - PutBack(whitespace); - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any; - } - } - - private void AfterIfClause() - { - // Grab whitespace and razor comments - IEnumerable ws = SkipToNextImportantToken(); - - // Check for an else part - if (At(CSharpKeyword.Else)) - { - Accept(ws); - Assert(CSharpKeyword.Else); - ElseClause(); - } - else - { - // No else, return whitespace - PutCurrentBack(); - PutBack(ws); - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any; - } - } - - private void ElseClause() - { - if (!At(CSharpKeyword.Else)) - { - return; - } - var block = new Block(CurrentSymbol); - - AcceptAndMoveNext(); - AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - if (At(CSharpKeyword.If)) - { - // ElseIf - block.Name = SyntaxConstants.CSharp.ElseIfKeyword; - ConditionalBlock(block); - AfterIfClause(); - } - else if (!EndOfFile) - { - // Else - ExpectCodeBlock(block); - } - } - - private void ExpectCodeBlock(Block block) - { - if (!EndOfFile) - { - // Check for "{" to make sure we're at a block - if (!At(CSharpSymbolType.LeftBrace)) - { - Context.OnError( - CurrentLocation, - RazorResources.FormatParseError_SingleLine_ControlFlowStatements_Not_Allowed( - Language.GetSample(CSharpSymbolType.LeftBrace), - CurrentSymbol.Content), - CurrentSymbol.Content.Length); - } - - // Parse the statement and then we're done - Statement(block); - } - } - - private void UnconditionalBlock() - { - Assert(CSharpSymbolType.Keyword); - var block = new Block(CurrentSymbol); - AcceptAndMoveNext(); - AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - ExpectCodeBlock(block); - } - - private void FilterableCatchBlock() - { - Assert(CSharpKeyword.Catch); - - var block = new Block(CurrentSymbol); - - // Accept "catch" - AcceptAndMoveNext(); - AcceptWhile(IsValidStatementSpacingSymbol); - - // Parse the catch condition if present. If not present, let the C# compiler complain. - if (AcceptCondition()) - { - AcceptWhile(IsValidStatementSpacingSymbol); - - if (At(CSharpKeyword.When)) - { - // Accept "when". - AcceptAndMoveNext(); - AcceptWhile(IsValidStatementSpacingSymbol); - - // Parse the filter condition if present. If not present, let the C# compiler complain. - if (!AcceptCondition()) - { - // Incomplete condition. - return; - } - - AcceptWhile(IsValidStatementSpacingSymbol); - } - - ExpectCodeBlock(block); - } - } - - private void ConditionalBlock(bool topLevel) - { - Assert(CSharpSymbolType.Keyword); - var block = new Block(CurrentSymbol); - ConditionalBlock(block); - if (topLevel) - { - CompleteBlock(); - } - } - - private void ConditionalBlock(Block block) - { - AcceptAndMoveNext(); - AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - - // Parse the condition, if present (if not present, we'll let the C# compiler complain) - if (AcceptCondition()) - { - AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - ExpectCodeBlock(block); - } - } - - private bool AcceptCondition() - { - if (At(CSharpSymbolType.LeftParenthesis)) - { - var complete = Balance(BalancingModes.BacktrackOnFailure | BalancingModes.AllowCommentsAndTemplates); - if (!complete) - { - AcceptUntil(CSharpSymbolType.NewLine); - } - else - { - Optional(CSharpSymbolType.RightParenthesis); - } - return complete; - } - return true; - } - - private void Statement() - { - Statement(null); - } - - private void Statement(Block block) - { - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any; - - // Accept whitespace but always keep the last whitespace node so we can put it back if necessary - var lastWhitespace = AcceptWhiteSpaceInLines(); - Debug.Assert(lastWhitespace == null || (lastWhitespace.Start.AbsoluteIndex + lastWhitespace.Content.Length == CurrentLocation.AbsoluteIndex)); - - if (EndOfFile) - { - if (lastWhitespace != null) - { - Accept(lastWhitespace); - } - return; - } - - var type = CurrentSymbol.Type; - var loc = CurrentLocation; - - var isSingleLineMarkup = type == CSharpSymbolType.Transition && NextIs(CSharpSymbolType.Colon); - var isMarkup = isSingleLineMarkup || - type == CSharpSymbolType.LessThan || - (type == CSharpSymbolType.Transition && NextIs(CSharpSymbolType.LessThan)); - - if (Context.DesignTimeMode || !isMarkup) - { - // CODE owns whitespace, MARKUP owns it ONLY in DesignTimeMode. - if (lastWhitespace != null) - { - Accept(lastWhitespace); - } - } - else - { - var nextSymbol = Lookahead(1); - - // MARKUP owns whitespace EXCEPT in DesignTimeMode. - PutCurrentBack(); - - // Don't putback the whitespace if it precedes a '' tag. - if (nextSymbol != null && !nextSymbol.Content.Equals(SyntaxConstants.TextTagName)) - { - PutBack(lastWhitespace); - } - } - - if (isMarkup) - { - if (type == CSharpSymbolType.Transition && !isSingleLineMarkup) - { - Context.OnError( - loc, - RazorResources.ParseError_AtInCode_Must_Be_Followed_By_Colon_Paren_Or_Identifier_Start, - length: 1 /* @ */); - } - - // Markup block - Output(SpanKind.Code); - if (Context.DesignTimeMode && CurrentSymbol != null && (CurrentSymbol.Type == CSharpSymbolType.LessThan || CurrentSymbol.Type == CSharpSymbolType.Transition)) - { - PutCurrentBack(); - } - OtherParserBlock(); - } - else - { - // What kind of statement is this? - HandleStatement(block, type); - } - } - - private void HandleStatement(Block block, CSharpSymbolType type) - { - switch (type) - { - case CSharpSymbolType.RazorCommentTransition: - Output(SpanKind.Code); - RazorComment(); - Statement(block); - break; - case CSharpSymbolType.LeftBrace: - // Verbatim Block - block = block ?? new Block(RazorResources.BlockName_Code, CurrentLocation); - AcceptAndMoveNext(); - CodeBlock(block); - break; - case CSharpSymbolType.Keyword: - // Keyword block - HandleKeyword(false, StandardStatement); - break; - case CSharpSymbolType.Transition: - // Embedded Expression block - EmbeddedExpression(); - break; - case CSharpSymbolType.RightBrace: - // Possible end of Code Block, just run the continuation - break; - case CSharpSymbolType.Comment: - AcceptAndMoveNext(); - break; - default: - // Other statement - StandardStatement(); - break; - } - } - - private void EmbeddedExpression() - { - // First, verify the type of the block - Assert(CSharpSymbolType.Transition); - var transition = CurrentSymbol; - NextToken(); - - if (At(CSharpSymbolType.Transition)) - { - // Escaped "@" - Output(SpanKind.Code); - - // Output "@" as hidden span - Accept(transition); - Span.ChunkGenerator = SpanChunkGenerator.Null; - Output(SpanKind.Code); - - Assert(CSharpSymbolType.Transition); - AcceptAndMoveNext(); - StandardStatement(); - } - else - { - // Throw errors as necessary, but continue parsing - if (At(CSharpSymbolType.LeftBrace)) - { - Context.OnError( - CurrentLocation, - RazorResources.ParseError_Unexpected_Nested_CodeBlock, - length: 1 /* { */); - } - - // @( or @foo - Nested expression, parse a child block - PutCurrentBack(); - PutBack(transition); - - // Before exiting, add a marker span if necessary - AddMarkerSymbolIfNecessary(); - - NestedBlock(); - } - } - - private void StandardStatement() - { - while (!EndOfFile) - { - var bookmark = CurrentLocation.AbsoluteIndex; - IEnumerable read = ReadWhile(sym => sym.Type != CSharpSymbolType.Semicolon && - sym.Type != CSharpSymbolType.RazorCommentTransition && - sym.Type != CSharpSymbolType.Transition && - sym.Type != CSharpSymbolType.LeftBrace && - sym.Type != CSharpSymbolType.LeftParenthesis && - sym.Type != CSharpSymbolType.LeftBracket && - sym.Type != CSharpSymbolType.RightBrace); - if (At(CSharpSymbolType.LeftBrace) || At(CSharpSymbolType.LeftParenthesis) || At(CSharpSymbolType.LeftBracket)) - { - Accept(read); - if (Balance(BalancingModes.AllowCommentsAndTemplates | BalancingModes.BacktrackOnFailure)) - { - Optional(CSharpSymbolType.RightBrace); - } - else - { - // Recovery - AcceptUntil(CSharpSymbolType.LessThan, CSharpSymbolType.RightBrace); - return; - } - } - else if (At(CSharpSymbolType.Transition) && (NextIs(CSharpSymbolType.LessThan, CSharpSymbolType.Colon))) - { - Accept(read); - Output(SpanKind.Code); - Template(); - } - else if (At(CSharpSymbolType.RazorCommentTransition)) - { - Accept(read); - RazorComment(); - } - else if (At(CSharpSymbolType.Semicolon)) - { - Accept(read); - AcceptAndMoveNext(); - return; - } - else if (At(CSharpSymbolType.RightBrace)) - { - Accept(read); - return; - } - else - { - Context.Source.Position = bookmark; - NextToken(); - AcceptUntil(CSharpSymbolType.LessThan, CSharpSymbolType.RightBrace); - return; - } - } - } - - private void CodeBlock(Block block) - { - CodeBlock(true, block); - } - - private void CodeBlock(bool acceptTerminatingBrace, Block block) - { - EnsureCurrent(); - while (!EndOfFile && !At(CSharpSymbolType.RightBrace)) - { - // Parse a statement, then return here - Statement(); - EnsureCurrent(); - } - - if (EndOfFile) - { - Context.OnError( - block.Start, - RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, '}', '{'), - length: 1 /* { OR } */); - } - else if (acceptTerminatingBrace) - { - Assert(CSharpSymbolType.RightBrace); - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - AcceptAndMoveNext(); - } - } - - private void HandleKeyword(bool topLevel, Action fallback) - { - Debug.Assert(CurrentSymbol.Type == CSharpSymbolType.Keyword && CurrentSymbol.Keyword != null); - Action handler; - if (_keywordParsers.TryGetValue(CurrentSymbol.Keyword.Value, out handler)) - { - handler(topLevel); - } - else - { - fallback(); - } - } - - private IEnumerable SkipToNextImportantToken() - { - while (!EndOfFile) - { - IEnumerable ws = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - if (At(CSharpSymbolType.RazorCommentTransition)) - { - Accept(ws); - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any; - RazorComment(); - } - else - { - return ws; - } - } - return Enumerable.Empty(); - } - - // Common code for Parsers, but FxCop REALLY doesn't like it in the base class.. moving it here for now. - protected override void OutputSpanBeforeRazorComment() - { - AddMarkerSymbolIfNecessary(); - Output(SpanKind.Code); - } - - protected class Block - { - public Block(string name, SourceLocation start) - { - Name = name; - Start = start; - } - - public Block(CSharpSymbol symbol) - : this(GetName(symbol), symbol.Start) - { - } - - public string Name { get; set; } - public SourceLocation Start { get; set; } - - private static string GetName(CSharpSymbol sym) - { - if (sym.Type == CSharpSymbolType.Keyword) - { - return CSharpLanguageCharacteristics.GetKeyword(sym.Keyword.Value); - } - return sym.Content; - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.cs b/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.cs deleted file mode 100644 index 8aaa6ae0f1..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpCodeParser.cs +++ /dev/null @@ -1,662 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using Microsoft.AspNet.Razor.Editor; -using Microsoft.AspNet.Razor.Chunks.Generators; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Tokenizer; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Parser -{ - public partial class CSharpCodeParser : TokenizerBackedParser - { - internal static readonly int UsingKeywordLength = 5; // using - - internal static ISet DefaultKeywords = new HashSet() - { - SyntaxConstants.CSharp.TagHelperPrefixKeyword, - SyntaxConstants.CSharp.AddTagHelperKeyword, - SyntaxConstants.CSharp.RemoveTagHelperKeyword, - "if", - "do", - "try", - "for", - "foreach", - "while", - "switch", - "lock", - "using", - "section", - "inherits", - "functions", - "namespace", - "class", - }; - - private Dictionary _directiveParsers = new Dictionary(); - private Dictionary> _keywordParsers = new Dictionary>(); - - public CSharpCodeParser() - { - Keywords = new HashSet(); - SetUpKeywords(); - SetupDirectives(); - SetUpExpressions(); - } - - protected internal ISet Keywords { get; private set; } - - public bool IsNested { get; set; } - - protected override ParserBase OtherParser - { - get { return Context.MarkupParser; } - } - - protected override LanguageCharacteristics Language - { - get { return CSharpLanguageCharacteristics.Instance; } - } - - protected void MapDirectives(Action handler, params string[] directives) - { - foreach (string directive in directives) - { - _directiveParsers.Add(directive, handler); - Keywords.Add(directive); - } - } - - protected bool TryGetDirectiveHandler(string directive, out Action handler) - { - return _directiveParsers.TryGetValue(directive, out handler); - } - - private void MapExpressionKeyword(Action handler, CSharpKeyword keyword) - { - _keywordParsers.Add(keyword, handler); - - // Expression keywords don't belong in the regular keyword list - } - - private void MapKeywords(Action handler, params CSharpKeyword[] keywords) - { - MapKeywords(handler, topLevel: true, keywords: keywords); - } - - private void MapKeywords(Action handler, bool topLevel, params CSharpKeyword[] keywords) - { - foreach (CSharpKeyword keyword in keywords) - { - _keywordParsers.Add(keyword, handler); - if (topLevel) - { - Keywords.Add(CSharpLanguageCharacteristics.GetKeyword(keyword)); - } - } - } - - [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This only occurs in Release builds, where this method is empty by design")] - [Conditional("DEBUG")] - internal void Assert(CSharpKeyword expectedKeyword) - { - Debug.Assert(CurrentSymbol.Type == CSharpSymbolType.Keyword && CurrentSymbol.Keyword.HasValue && CurrentSymbol.Keyword.Value == expectedKeyword); - } - - protected internal bool At(CSharpKeyword keyword) - { - return At(CSharpSymbolType.Keyword) && CurrentSymbol.Keyword.HasValue && CurrentSymbol.Keyword.Value == keyword; - } - - protected internal bool AcceptIf(CSharpKeyword keyword) - { - if (At(keyword)) - { - AcceptAndMoveNext(); - return true; - } - return false; - } - - protected static Func IsSpacingToken(bool includeNewLines, bool includeComments) - { - return sym => sym.Type == CSharpSymbolType.WhiteSpace || - (includeNewLines && sym.Type == CSharpSymbolType.NewLine) || - (includeComments && sym.Type == CSharpSymbolType.Comment); - } - - public override void ParseBlock() - { - using (PushSpanConfig(DefaultSpanConfig)) - { - if (Context == null) - { - throw new InvalidOperationException(RazorResources.Parser_Context_Not_Set); - } - - // Unless changed, the block is a statement block - using (Context.StartBlock(BlockType.Statement)) - { - NextToken(); - - AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); - - var current = CurrentSymbol; - if (At(CSharpSymbolType.StringLiteral) && CurrentSymbol.Content.Length > 0 && CurrentSymbol.Content[0] == SyntaxConstants.TransitionCharacter) - { - var split = Language.SplitSymbol(CurrentSymbol, 1, CSharpSymbolType.Transition); - current = split.Item1; - Context.Source.Position = split.Item2.Start.AbsoluteIndex; - NextToken(); - } - else if (At(CSharpSymbolType.Transition)) - { - NextToken(); - } - - // Accept "@" if we see it, but if we don't, that's OK. We assume we were started for a good reason - if (current.Type == CSharpSymbolType.Transition) - { - if (Span.Symbols.Count > 0) - { - Output(SpanKind.Code); - } - AtTransition(current); - } - else - { - // No "@" => Jump straight to AfterTransition - AfterTransition(); - } - Output(SpanKind.Code); - } - } - } - - private void DefaultSpanConfig(SpanBuilder span) - { - span.EditHandler = SpanEditHandler.CreateDefault(Language.TokenizeString); - span.ChunkGenerator = new StatementChunkGenerator(); - } - - private void AtTransition(CSharpSymbol current) - { - Debug.Assert(current.Type == CSharpSymbolType.Transition); - Accept(current); - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - Span.ChunkGenerator = SpanChunkGenerator.Null; - - // Output the "@" span and continue here - Output(SpanKind.Transition); - AfterTransition(); - } - - private void AfterTransition() - { - using (PushSpanConfig(DefaultSpanConfig)) - { - EnsureCurrent(); - try - { - // What type of block is this? - if (!EndOfFile) - { - if (CurrentSymbol.Type == CSharpSymbolType.LeftParenthesis) - { - Context.CurrentBlock.Type = BlockType.Expression; - Context.CurrentBlock.ChunkGenerator = new ExpressionChunkGenerator(); - ExplicitExpression(); - return; - } - else if (CurrentSymbol.Type == CSharpSymbolType.Identifier) - { - Action handler; - if (TryGetDirectiveHandler(CurrentSymbol.Content, out handler)) - { - Span.ChunkGenerator = SpanChunkGenerator.Null; - handler(); - return; - } - else - { - if (CurrentSymbol.Content.Equals(SyntaxConstants.CSharp.HelperKeyword)) - { - Context.OnError( - CurrentLocation, - RazorResources.FormatParseError_HelperDirectiveNotAvailable(SyntaxConstants.CSharp.HelperKeyword), - CurrentSymbol.Content.Length); - } - - Context.CurrentBlock.Type = BlockType.Expression; - Context.CurrentBlock.ChunkGenerator = new ExpressionChunkGenerator(); - ImplicitExpression(); - return; - } - } - else if (CurrentSymbol.Type == CSharpSymbolType.Keyword) - { - KeywordBlock(topLevel: true); - return; - } - else if (CurrentSymbol.Type == CSharpSymbolType.LeftBrace) - { - VerbatimBlock(); - return; - } - } - - // Invalid character - Context.CurrentBlock.Type = BlockType.Expression; - Context.CurrentBlock.ChunkGenerator = new ExpressionChunkGenerator(); - AddMarkerSymbolIfNecessary(); - Span.ChunkGenerator = new ExpressionChunkGenerator(); - Span.EditHandler = new ImplicitExpressionEditHandler( - Language.TokenizeString, - DefaultKeywords, - acceptTrailingDot: IsNested) - { - AcceptedCharacters = AcceptedCharacters.NonWhiteSpace - }; - if (At(CSharpSymbolType.WhiteSpace) || At(CSharpSymbolType.NewLine)) - { - Context.OnError( - CurrentLocation, - RazorResources.ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_CS, - CurrentSymbol.Content.Length); - } - else if (EndOfFile) - { - Context.OnError( - CurrentLocation, - RazorResources.ParseError_Unexpected_EndOfFile_At_Start_Of_CodeBlock, - length: 1 /* end of file */); - } - else - { - Context.OnError( - CurrentLocation, - RazorResources.FormatParseError_Unexpected_Character_At_Start_Of_CodeBlock_CS( - CurrentSymbol.Content), - CurrentSymbol.Content.Length); - } - } - finally - { - // Always put current character back in the buffer for the next parser. - PutCurrentBack(); - } - } - } - - private void VerbatimBlock() - { - Assert(CSharpSymbolType.LeftBrace); - var block = new Block(RazorResources.BlockName_Code, CurrentLocation); - AcceptAndMoveNext(); - - // Set up the "{" span and output - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - Span.ChunkGenerator = SpanChunkGenerator.Null; - Output(SpanKind.MetaCode); - - // Set up auto-complete and parse the code block - var editHandler = new AutoCompleteEditHandler(Language.TokenizeString); - Span.EditHandler = editHandler; - CodeBlock(false, block); - - Span.ChunkGenerator = new StatementChunkGenerator(); - AddMarkerSymbolIfNecessary(); - if (!At(CSharpSymbolType.RightBrace)) - { - editHandler.AutoCompleteString = "}"; - } - Output(SpanKind.Code); - - if (Optional(CSharpSymbolType.RightBrace)) - { - // Set up the "}" span - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - Span.ChunkGenerator = SpanChunkGenerator.Null; - } - - if (!IsNested) - { - EnsureCurrent(); - if (At(CSharpSymbolType.NewLine) || - (At(CSharpSymbolType.WhiteSpace) && NextIs(CSharpSymbolType.NewLine))) - { - Context.NullGenerateWhitespaceAndNewLine = true; - } - } - - Output(SpanKind.MetaCode); - } - - private void ImplicitExpression() - { - ImplicitExpression(AcceptedCharacters.NonWhiteSpace); - } - - // Async implicit expressions include the "await" keyword and therefore need to allow spaces to - // separate the "await" and the following code. - private void AsyncImplicitExpression() - { - ImplicitExpression(AcceptedCharacters.AnyExceptNewline); - } - - private void ImplicitExpression(AcceptedCharacters acceptedCharacters) - { - Context.CurrentBlock.Type = BlockType.Expression; - Context.CurrentBlock.ChunkGenerator = new ExpressionChunkGenerator(); - - using (PushSpanConfig(span => - { - span.EditHandler = new ImplicitExpressionEditHandler( - Language.TokenizeString, - Keywords, - acceptTrailingDot: IsNested); - span.EditHandler.AcceptedCharacters = acceptedCharacters; - span.ChunkGenerator = new ExpressionChunkGenerator(); - })) - { - do - { - if (AtIdentifier(allowKeywords: true)) - { - AcceptAndMoveNext(); - } - } - while (MethodCallOrArrayIndex(acceptedCharacters)); - - PutCurrentBack(); - Output(SpanKind.Code); - } - } - - private bool MethodCallOrArrayIndex(AcceptedCharacters acceptedCharacters) - { - if (!EndOfFile) - { - if (CurrentSymbol.Type == CSharpSymbolType.LeftParenthesis || CurrentSymbol.Type == CSharpSymbolType.LeftBracket) - { - // If we end within "(", whitespace is fine - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any; - - CSharpSymbolType right; - bool success; - - using (PushSpanConfig((span, prev) => - { - prev(span); - span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any; - })) - { - right = Language.FlipBracket(CurrentSymbol.Type); - success = Balance(BalancingModes.BacktrackOnFailure | BalancingModes.AllowCommentsAndTemplates); - } - - if (!success) - { - AcceptUntil(CSharpSymbolType.LessThan); - } - if (At(right)) - { - AcceptAndMoveNext(); - - // At the ending brace, restore the initial accepted characters. - Span.EditHandler.AcceptedCharacters = acceptedCharacters; - } - return MethodCallOrArrayIndex(acceptedCharacters); - } - if (At(CSharpSymbolType.QuestionMark)) - { - var next = Lookahead(count: 1); - - if (next != null) - { - if (next.Type == CSharpSymbolType.Dot) - { - // Accept null conditional dot operator (?.). - AcceptAndMoveNext(); - AcceptAndMoveNext(); - - // If the next piece after the ?. is a keyword or identifier then we want to continue. - return At(CSharpSymbolType.Identifier) || At(CSharpSymbolType.Keyword); - } - else if (next.Type == CSharpSymbolType.LeftBracket) - { - // We're at the ? for a null conditional bracket operator (?[). - AcceptAndMoveNext(); - - // Accept the [ and any content inside (it will attempt to balance). - return MethodCallOrArrayIndex(acceptedCharacters); - } - } - } - else if (At(CSharpSymbolType.Dot)) - { - var dot = CurrentSymbol; - if (NextToken()) - { - if (At(CSharpSymbolType.Identifier) || At(CSharpSymbolType.Keyword)) - { - // Accept the dot and return to the start - Accept(dot); - return true; // continue - } - else - { - // Put the symbol back - PutCurrentBack(); - } - } - if (!IsNested) - { - // Put the "." back - PutBack(dot); - } - else - { - Accept(dot); - } - } - else if (!At(CSharpSymbolType.WhiteSpace) && !At(CSharpSymbolType.NewLine)) - { - PutCurrentBack(); - } - } - - // Implicit Expression is complete - return false; - } - - protected void CompleteBlock() - { - CompleteBlock(insertMarkerIfNecessary: true); - } - - protected void CompleteBlock(bool insertMarkerIfNecessary) - { - CompleteBlock(insertMarkerIfNecessary, captureWhitespaceToEndOfLine: insertMarkerIfNecessary); - } - - protected void CompleteBlock(bool insertMarkerIfNecessary, bool captureWhitespaceToEndOfLine) - { - if (insertMarkerIfNecessary && Context.LastAcceptedCharacters != AcceptedCharacters.Any) - { - AddMarkerSymbolIfNecessary(); - } - - EnsureCurrent(); - - // Read whitespace, but not newlines - // If we're not inserting a marker span, we don't need to capture whitespace - if (!Context.WhiteSpaceIsSignificantToAncestorBlock && - Context.CurrentBlock.Type != BlockType.Expression && - captureWhitespaceToEndOfLine && - !Context.DesignTimeMode && - !IsNested) - { - CaptureWhitespaceAtEndOfCodeOnlyLine(); - } - else - { - PutCurrentBack(); - } - } - - private void CaptureWhitespaceAtEndOfCodeOnlyLine() - { - IEnumerable ws = ReadWhile(sym => sym.Type == CSharpSymbolType.WhiteSpace); - if (At(CSharpSymbolType.NewLine)) - { - Accept(ws); - AcceptAndMoveNext(); - PutCurrentBack(); - } - else - { - PutCurrentBack(); - PutBack(ws); - } - } - - private void ConfigureExplicitExpressionSpan(SpanBuilder sb) - { - sb.EditHandler = SpanEditHandler.CreateDefault(Language.TokenizeString); - sb.ChunkGenerator = new ExpressionChunkGenerator(); - } - - private void ExplicitExpression() - { - var block = new Block(RazorResources.BlockName_ExplicitExpression, CurrentLocation); - Assert(CSharpSymbolType.LeftParenthesis); - AcceptAndMoveNext(); - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - Span.ChunkGenerator = SpanChunkGenerator.Null; - Output(SpanKind.MetaCode); - using (PushSpanConfig(ConfigureExplicitExpressionSpan)) - { - var success = Balance( - BalancingModes.BacktrackOnFailure | BalancingModes.NoErrorOnFailure | BalancingModes.AllowCommentsAndTemplates, - CSharpSymbolType.LeftParenthesis, - CSharpSymbolType.RightParenthesis, - block.Start); - - if (!success) - { - AcceptUntil(CSharpSymbolType.LessThan); - Context.OnError( - block.Start, - RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, ")", "("), - length: 1 /* ( */); - } - - // If necessary, put an empty-content marker symbol here - if (Span.Symbols.Count == 0) - { - Accept(new CSharpSymbol(CurrentLocation, string.Empty, CSharpSymbolType.Unknown)); - } - - // Output the content span and then capture the ")" - Output(SpanKind.Code); - } - Optional(CSharpSymbolType.RightParenthesis); - if (!EndOfFile) - { - PutCurrentBack(); - } - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - Span.ChunkGenerator = SpanChunkGenerator.Null; - CompleteBlock(insertMarkerIfNecessary: false); - Output(SpanKind.MetaCode); - } - - private void Template() - { - if (Context.IsWithin(BlockType.Template)) - { - Context.OnError( - CurrentLocation, - RazorResources.ParseError_InlineMarkup_Blocks_Cannot_Be_Nested, - length: 1 /* @ */); - } - Output(SpanKind.Code); - using (Context.StartBlock(BlockType.Template)) - { - Context.CurrentBlock.ChunkGenerator = new TemplateBlockChunkGenerator(); - PutCurrentBack(); - OtherParserBlock(); - } - } - - private void OtherParserBlock() - { - ParseWithOtherParser(p => p.ParseBlock()); - } - - private void SectionBlock(string left, string right, bool caseSensitive) - { - ParseWithOtherParser(p => p.ParseSection(Tuple.Create(left, right), caseSensitive)); - } - - private void NestedBlock() - { - Output(SpanKind.Code); - var wasNested = IsNested; - IsNested = true; - using (PushSpanConfig()) - { - ParseBlock(); - } - Initialize(Span); - IsNested = wasNested; - NextToken(); - } - - protected override bool IsAtEmbeddedTransition(bool allowTemplatesAndComments, bool allowTransitions) - { - // No embedded transitions in C#, so ignore that param - return allowTemplatesAndComments - && ((Language.IsTransition(CurrentSymbol) - && NextIs(CSharpSymbolType.LessThan, CSharpSymbolType.Colon)) - || Language.IsCommentStart(CurrentSymbol)); - } - - protected override void HandleEmbeddedTransition() - { - if (Language.IsTransition(CurrentSymbol)) - { - PutCurrentBack(); - Template(); - } - else if (Language.IsCommentStart(CurrentSymbol)) - { - RazorComment(); - } - } - - private void ParseWithOtherParser(Action parseAction) - { - // When transitioning to the HTML parser we no longer want to act as if we're in a nested C# state. - // For instance, if
@hello.
is in a nested C# block we don't want the trailing '.' to be handled - // as C#; it should be handled as a period because it's wrapped in markup. - var wasNested = IsNested; - IsNested = false; - using (PushSpanConfig()) - { - Context.SwitchActiveParser(); - parseAction(Context.MarkupParser); - Context.SwitchActiveParser(); - } - Initialize(Span); - IsNested = wasNested; - NextToken(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpLanguageCharacteristics.cs b/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpLanguageCharacteristics.cs deleted file mode 100644 index b22fbc277f..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CSharpLanguageCharacteristics.cs +++ /dev/null @@ -1,194 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Tokenizer; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Parser -{ - public class CSharpLanguageCharacteristics : LanguageCharacteristics - { - private static readonly CSharpLanguageCharacteristics _instance = new CSharpLanguageCharacteristics(); - - private static Dictionary _symbolSamples = new Dictionary() - { - { CSharpSymbolType.Arrow, "->" }, - { CSharpSymbolType.Minus, "-" }, - { CSharpSymbolType.Decrement, "--" }, - { CSharpSymbolType.MinusAssign, "-=" }, - { CSharpSymbolType.NotEqual, "!=" }, - { CSharpSymbolType.Not, "!" }, - { CSharpSymbolType.Modulo, "%" }, - { CSharpSymbolType.ModuloAssign, "%=" }, - { CSharpSymbolType.AndAssign, "&=" }, - { CSharpSymbolType.And, "&" }, - { CSharpSymbolType.DoubleAnd, "&&" }, - { CSharpSymbolType.LeftParenthesis, "(" }, - { CSharpSymbolType.RightParenthesis, ")" }, - { CSharpSymbolType.Star, "*" }, - { CSharpSymbolType.MultiplyAssign, "*=" }, - { CSharpSymbolType.Comma, "," }, - { CSharpSymbolType.Dot, "." }, - { CSharpSymbolType.Slash, "/" }, - { CSharpSymbolType.DivideAssign, "/=" }, - { CSharpSymbolType.DoubleColon, "::" }, - { CSharpSymbolType.Colon, ":" }, - { CSharpSymbolType.Semicolon, ";" }, - { CSharpSymbolType.QuestionMark, "?" }, - { CSharpSymbolType.NullCoalesce, "??" }, - { CSharpSymbolType.RightBracket, "]" }, - { CSharpSymbolType.LeftBracket, "[" }, - { CSharpSymbolType.XorAssign, "^=" }, - { CSharpSymbolType.Xor, "^" }, - { CSharpSymbolType.LeftBrace, "{" }, - { CSharpSymbolType.OrAssign, "|=" }, - { CSharpSymbolType.DoubleOr, "||" }, - { CSharpSymbolType.Or, "|" }, - { CSharpSymbolType.RightBrace, "}" }, - { CSharpSymbolType.Tilde, "~" }, - { CSharpSymbolType.Plus, "+" }, - { CSharpSymbolType.PlusAssign, "+=" }, - { CSharpSymbolType.Increment, "++" }, - { CSharpSymbolType.LessThan, "<" }, - { CSharpSymbolType.LessThanEqual, "<=" }, - { CSharpSymbolType.LeftShift, "<<" }, - { CSharpSymbolType.LeftShiftAssign, "<<=" }, - { CSharpSymbolType.Assign, "=" }, - { CSharpSymbolType.Equals, "==" }, - { CSharpSymbolType.GreaterThan, ">" }, - { CSharpSymbolType.GreaterThanEqual, ">=" }, - { CSharpSymbolType.RightShift, ">>" }, - { CSharpSymbolType.RightShiftAssign, ">>>" }, - { CSharpSymbolType.Hash, "#" }, - { CSharpSymbolType.Transition, "@" }, - }; - - private CSharpLanguageCharacteristics() - { - } - - public static CSharpLanguageCharacteristics Instance - { - get { return _instance; } - } - - public override CSharpTokenizer CreateTokenizer(ITextDocument source) - { - return new CSharpTokenizer(source); - } - - protected override CSharpSymbol CreateSymbol(SourceLocation location, string content, CSharpSymbolType type, IEnumerable errors) - { - return new CSharpSymbol(location, content, type, errors); - } - - public override string GetSample(CSharpSymbolType type) - { - return GetSymbolSample(type); - } - - public override CSharpSymbol CreateMarkerSymbol(SourceLocation location) - { - return new CSharpSymbol(location, string.Empty, CSharpSymbolType.Unknown); - } - - public override CSharpSymbolType GetKnownSymbolType(KnownSymbolType type) - { - switch (type) - { - case KnownSymbolType.Identifier: - return CSharpSymbolType.Identifier; - case KnownSymbolType.Keyword: - return CSharpSymbolType.Keyword; - case KnownSymbolType.NewLine: - return CSharpSymbolType.NewLine; - case KnownSymbolType.WhiteSpace: - return CSharpSymbolType.WhiteSpace; - case KnownSymbolType.Transition: - return CSharpSymbolType.Transition; - case KnownSymbolType.CommentStart: - return CSharpSymbolType.RazorCommentTransition; - case KnownSymbolType.CommentStar: - return CSharpSymbolType.RazorCommentStar; - case KnownSymbolType.CommentBody: - return CSharpSymbolType.RazorComment; - default: - return CSharpSymbolType.Unknown; - } - } - - public override CSharpSymbolType FlipBracket(CSharpSymbolType bracket) - { - switch (bracket) - { - case CSharpSymbolType.LeftBrace: - return CSharpSymbolType.RightBrace; - case CSharpSymbolType.LeftBracket: - return CSharpSymbolType.RightBracket; - case CSharpSymbolType.LeftParenthesis: - return CSharpSymbolType.RightParenthesis; - case CSharpSymbolType.LessThan: - return CSharpSymbolType.GreaterThan; - case CSharpSymbolType.RightBrace: - return CSharpSymbolType.LeftBrace; - case CSharpSymbolType.RightBracket: - return CSharpSymbolType.LeftBracket; - case CSharpSymbolType.RightParenthesis: - return CSharpSymbolType.LeftParenthesis; - case CSharpSymbolType.GreaterThan: - return CSharpSymbolType.LessThan; - default: -#if NET451 - // No Debug.Fail - Debug.Fail("FlipBracket must be called with a bracket character"); -#else - Debug.Assert(false, "FlipBracket must be called with a bracket character"); -#endif - return CSharpSymbolType.Unknown; - } - } - - [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "C# Keywords are lower-case")] - public static string GetKeyword(CSharpKeyword keyword) - { - return keyword.ToString().ToLowerInvariant(); - } - - public static string GetSymbolSample(CSharpSymbolType type) - { - string sample; - if (!_symbolSamples.TryGetValue(type, out sample)) - { - switch (type) - { - case CSharpSymbolType.Identifier: - return RazorResources.CSharpSymbol_Identifier; - case CSharpSymbolType.Keyword: - return RazorResources.CSharpSymbol_Keyword; - case CSharpSymbolType.IntegerLiteral: - return RazorResources.CSharpSymbol_IntegerLiteral; - case CSharpSymbolType.NewLine: - return RazorResources.CSharpSymbol_Newline; - case CSharpSymbolType.WhiteSpace: - return RazorResources.CSharpSymbol_Whitespace; - case CSharpSymbolType.Comment: - return RazorResources.CSharpSymbol_Comment; - case CSharpSymbolType.RealLiteral: - return RazorResources.CSharpSymbol_RealLiteral; - case CSharpSymbolType.CharacterLiteral: - return RazorResources.CSharpSymbol_CharacterLiteral; - case CSharpSymbolType.StringLiteral: - return RazorResources.CSharpSymbol_StringLiteral; - default: - return RazorResources.Symbol_Unknown; - } - } - return sample; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CallbackVisitor.cs b/src/Microsoft.AspNet.Razor.VSRC1/Parser/CallbackVisitor.cs deleted file mode 100644 index 68081e1dcc..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Parser/CallbackVisitor.cs +++ /dev/null @@ -1,97 +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; -using System.Threading; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; - -namespace Microsoft.AspNet.Razor.Parser -{ - public class CallbackVisitor : ParserVisitor - { - private Action _spanCallback; - private Action _errorCallback; - private Action _endBlockCallback; - private Action _startBlockCallback; - private Action _completeCallback; - - public CallbackVisitor(Action spanCallback) - : this(spanCallback, _ => - { - }) - { - } - - public CallbackVisitor(Action spanCallback, Action errorCallback) - : this(spanCallback, errorCallback, _ => - { - }, _ => - { - }) - { - } - - public CallbackVisitor(Action spanCallback, Action errorCallback, Action startBlockCallback, Action endBlockCallback) - : this(spanCallback, errorCallback, startBlockCallback, endBlockCallback, () => - { - }) - { - } - - public CallbackVisitor(Action spanCallback, Action errorCallback, Action startBlockCallback, Action endBlockCallback, Action completeCallback) - { - _spanCallback = spanCallback; - _errorCallback = errorCallback; - _startBlockCallback = startBlockCallback; - _endBlockCallback = endBlockCallback; - _completeCallback = completeCallback; - } - - public SynchronizationContext SynchronizationContext { get; set; } - - public override void VisitStartBlock(Block block) - { - base.VisitStartBlock(block); - RaiseCallback(SynchronizationContext, block.Type, _startBlockCallback); - } - - public override void VisitSpan(Span span) - { - base.VisitSpan(span); - RaiseCallback(SynchronizationContext, span, _spanCallback); - } - - public override void VisitEndBlock(Block block) - { - base.VisitEndBlock(block); - RaiseCallback(SynchronizationContext, block.Type, _endBlockCallback); - } - - public override void VisitError(RazorError err) - { - base.VisitError(err); - RaiseCallback(SynchronizationContext, err, _errorCallback); - } - - public override void OnComplete() - { - base.OnComplete(); - RaiseCallback(SynchronizationContext, null, _ => _completeCallback()); - } - - private static void RaiseCallback(SynchronizationContext syncContext, T param, Action callback) - { - if (callback != null) - { - if (syncContext != null) - { - syncContext.Post(state => callback((T)state), param); - } - else - { - callback(param); - } - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Parser/ConditionalAttributeCollapser.cs b/src/Microsoft.AspNet.Razor.VSRC1/Parser/ConditionalAttributeCollapser.cs deleted file mode 100644 index 73be90198c..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Parser/ConditionalAttributeCollapser.cs +++ /dev/null @@ -1,55 +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; -using System.Diagnostics; -using System.Linq; -using Microsoft.AspNet.Razor.Editor; -using Microsoft.AspNet.Razor.Chunks.Generators; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Tokenizer; - -namespace Microsoft.AspNet.Razor.Parser -{ - internal class ConditionalAttributeCollapser : MarkupRewriter - { - public ConditionalAttributeCollapser(Action markupSpanFactory) : base(markupSpanFactory) - { - } - - protected override bool CanRewrite(Block block) - { - var gen = block.ChunkGenerator as AttributeBlockChunkGenerator; - return gen != null && block.Children.Any() && block.Children.All(IsLiteralAttributeValue); - } - - protected override SyntaxTreeNode RewriteBlock(BlockBuilder parent, Block block) - { - // Collect the content of this node - var content = string.Concat(block.Children.Cast().Select(s => s.Content)); - - // Create a new span containing this content - var span = new SpanBuilder(); - span.EditHandler = new SpanEditHandler(HtmlTokenizer.Tokenize); - FillSpan(span, block.Children.Cast().First().Start, content); - return span.Build(); - } - - private bool IsLiteralAttributeValue(SyntaxTreeNode node) - { - if (node.IsBlock) - { - return false; - } - var span = node as Span; - Debug.Assert(span != null); - - var litGen = span.ChunkGenerator as LiteralAttributeChunkGenerator; - - return span != null && - ((litGen != null && litGen.ValueGenerator == null) || - span.ChunkGenerator == SpanChunkGenerator.Null || - span.ChunkGenerator is MarkupChunkGenerator); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Parser/HtmlLanguageCharacteristics.cs b/src/Microsoft.AspNet.Razor.VSRC1/Parser/HtmlLanguageCharacteristics.cs deleted file mode 100644 index dfb1c5eed1..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Parser/HtmlLanguageCharacteristics.cs +++ /dev/null @@ -1,137 +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; -using System.Collections.Generic; -using System.Diagnostics; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Tokenizer; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Parser -{ - public class HtmlLanguageCharacteristics : LanguageCharacteristics - { - private static readonly HtmlLanguageCharacteristics _instance = new HtmlLanguageCharacteristics(); - - private HtmlLanguageCharacteristics() - { - } - - public static HtmlLanguageCharacteristics Instance - { - get { return _instance; } - } - - public override string GetSample(HtmlSymbolType type) - { - switch (type) - { - case HtmlSymbolType.Text: - return RazorResources.HtmlSymbol_Text; - case HtmlSymbolType.WhiteSpace: - return RazorResources.HtmlSymbol_WhiteSpace; - case HtmlSymbolType.NewLine: - return RazorResources.HtmlSymbol_NewLine; - case HtmlSymbolType.OpenAngle: - return "<"; - case HtmlSymbolType.Bang: - return "!"; - case HtmlSymbolType.ForwardSlash: - return "/"; - case HtmlSymbolType.QuestionMark: - return "?"; - case HtmlSymbolType.DoubleHyphen: - return "--"; - case HtmlSymbolType.LeftBracket: - return "["; - case HtmlSymbolType.CloseAngle: - return ">"; - case HtmlSymbolType.RightBracket: - return "]"; - case HtmlSymbolType.Equals: - return "="; - case HtmlSymbolType.DoubleQuote: - return "\""; - case HtmlSymbolType.SingleQuote: - return "'"; - case HtmlSymbolType.Transition: - return "@"; - case HtmlSymbolType.Colon: - return ":"; - case HtmlSymbolType.RazorComment: - return RazorResources.HtmlSymbol_RazorComment; - case HtmlSymbolType.RazorCommentStar: - return "*"; - case HtmlSymbolType.RazorCommentTransition: - return "@"; - default: - return RazorResources.Symbol_Unknown; - } - } - - public override HtmlTokenizer CreateTokenizer(ITextDocument source) - { - return new HtmlTokenizer(source); - } - - public override HtmlSymbolType FlipBracket(HtmlSymbolType bracket) - { - switch (bracket) - { - case HtmlSymbolType.LeftBracket: - return HtmlSymbolType.RightBracket; - case HtmlSymbolType.OpenAngle: - return HtmlSymbolType.CloseAngle; - case HtmlSymbolType.RightBracket: - return HtmlSymbolType.LeftBracket; - case HtmlSymbolType.CloseAngle: - return HtmlSymbolType.OpenAngle; - default: -#if NET451 - // No Debug.Fail in CoreCLR - - Debug.Fail("FlipBracket must be called with a bracket character"); -#else - Debug.Assert(false, "FlipBracket must be called with a bracket character"); -#endif - return HtmlSymbolType.Unknown; - } - } - - public override HtmlSymbol CreateMarkerSymbol(SourceLocation location) - { - return new HtmlSymbol(location, string.Empty, HtmlSymbolType.Unknown); - } - - public override HtmlSymbolType GetKnownSymbolType(KnownSymbolType type) - { - switch (type) - { - case KnownSymbolType.CommentStart: - return HtmlSymbolType.RazorCommentTransition; - case KnownSymbolType.CommentStar: - return HtmlSymbolType.RazorCommentStar; - case KnownSymbolType.CommentBody: - return HtmlSymbolType.RazorComment; - case KnownSymbolType.Identifier: - return HtmlSymbolType.Text; - case KnownSymbolType.Keyword: - return HtmlSymbolType.Text; - case KnownSymbolType.NewLine: - return HtmlSymbolType.NewLine; - case KnownSymbolType.Transition: - return HtmlSymbolType.Transition; - case KnownSymbolType.WhiteSpace: - return HtmlSymbolType.WhiteSpace; - default: - return HtmlSymbolType.Unknown; - } - } - - protected override HtmlSymbol CreateSymbol(SourceLocation location, string content, HtmlSymbolType type, IEnumerable errors) - { - return new HtmlSymbol(location, content, type, errors); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Parser/HtmlMarkupParser.Block.cs b/src/Microsoft.AspNet.Razor.VSRC1/Parser/HtmlMarkupParser.Block.cs deleted file mode 100644 index 0f6a6d52d3..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Parser/HtmlMarkupParser.Block.cs +++ /dev/null @@ -1,1163 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Microsoft.AspNet.Razor.Chunks.Generators; -using Microsoft.AspNet.Razor.Editor; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Parser -{ - public partial class HtmlMarkupParser - { - private const string ScriptTagName = "script"; - - private SourceLocation _lastTagStart = SourceLocation.Zero; - private HtmlSymbol _bufferedOpenAngle; - - public override void ParseBlock() - { - if (Context == null) - { - throw new InvalidOperationException(RazorResources.Parser_Context_Not_Set); - } - - using (PushSpanConfig(DefaultMarkupSpan)) - { - using (Context.StartBlock(BlockType.Markup)) - { - if (!NextToken()) - { - return; - } - - AcceptWhile(IsSpacingToken(includeNewLines: true)); - - if (CurrentSymbol.Type == HtmlSymbolType.OpenAngle) - { - // "<" => Implicit Tag Block - TagBlock(new Stack>()); - } - else if (CurrentSymbol.Type == HtmlSymbolType.Transition) - { - // "@" => Explicit Tag/Single Line Block OR Template - Output(SpanKind.Markup); - - // Definitely have a transition span - Assert(HtmlSymbolType.Transition); - AcceptAndMoveNext(); - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - Span.ChunkGenerator = SpanChunkGenerator.Null; - Output(SpanKind.Transition); - if (At(HtmlSymbolType.Transition)) - { - Span.ChunkGenerator = SpanChunkGenerator.Null; - AcceptAndMoveNext(); - Output(SpanKind.MetaCode); - } - AfterTransition(); - } - else - { - Context.OnError( - CurrentSymbol.Start, - RazorResources.ParseError_MarkupBlock_Must_Start_With_Tag, - CurrentSymbol.Content.Length); - } - Output(SpanKind.Markup); - } - } - } - - private void DefaultMarkupSpan(SpanBuilder span) - { - span.ChunkGenerator = new MarkupChunkGenerator(); - span.EditHandler = new SpanEditHandler(Language.TokenizeString, AcceptedCharacters.Any); - } - - private void AfterTransition() - { - // "@:" => Explicit Single Line Block - if (CurrentSymbol.Type == HtmlSymbolType.Text && CurrentSymbol.Content.Length > 0 && CurrentSymbol.Content[0] == ':') - { - // Split the token - Tuple split = Language.SplitSymbol(CurrentSymbol, 1, HtmlSymbolType.Colon); - - // The first part (left) is added to this span and we return a MetaCode span - Accept(split.Item1); - Span.ChunkGenerator = SpanChunkGenerator.Null; - Output(SpanKind.MetaCode); - if (split.Item2 != null) - { - Accept(split.Item2); - } - NextToken(); - SingleLineMarkup(); - } - else if (CurrentSymbol.Type == HtmlSymbolType.OpenAngle) - { - TagBlock(new Stack>()); - } - } - - private void SingleLineMarkup() - { - // Parse until a newline, it's that simple! - // First, signal to code parser that whitespace is significant to us. - var old = Context.WhiteSpaceIsSignificantToAncestorBlock; - Context.WhiteSpaceIsSignificantToAncestorBlock = true; - Span.EditHandler = new SingleLineMarkupEditHandler(Language.TokenizeString); - SkipToAndParseCode(HtmlSymbolType.NewLine); - if (!EndOfFile && CurrentSymbol.Type == HtmlSymbolType.NewLine) - { - AcceptAndMoveNext(); - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - } - PutCurrentBack(); - Context.WhiteSpaceIsSignificantToAncestorBlock = old; - Output(SpanKind.Markup); - } - - private void TagBlock(Stack> tags) - { - // Skip Whitespace and Text - var complete = false; - do - { - SkipToAndParseCode(HtmlSymbolType.OpenAngle); - - // Output everything prior to the OpenAngle into a markup span - Output(SpanKind.Markup); - - // Do not want to start a new tag block if we're at the end of the file. - IDisposable tagBlockWrapper = null; - try - { - var atSpecialTag = AtSpecialTag; - - if (!EndOfFile && !atSpecialTag) - { - // Start a Block tag. This is used to wrap things like

or etc. - tagBlockWrapper = Context.StartBlock(BlockType.Tag); - } - - if (EndOfFile) - { - EndTagBlock(tags, complete: true); - } - else - { - _bufferedOpenAngle = null; - _lastTagStart = CurrentLocation; - Assert(HtmlSymbolType.OpenAngle); - _bufferedOpenAngle = CurrentSymbol; - var tagStart = CurrentLocation; - if (!NextToken()) - { - Accept(_bufferedOpenAngle); - EndTagBlock(tags, complete: false); - } - else - { - complete = AfterTagStart(tagStart, tags, atSpecialTag, tagBlockWrapper); - } - } - - if (complete) - { - // Completed tags have no accepted characters inside of blocks. - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - } - - // Output the contents of the tag into its own markup span. - Output(SpanKind.Markup); - } - finally - { - // Will be null if we were at end of file or special tag when initially created. - if (tagBlockWrapper != null) - { - // End tag block - tagBlockWrapper.Dispose(); - } - } - } - while (tags.Count > 0); - - EndTagBlock(tags, complete); - } - - private bool AfterTagStart(SourceLocation tagStart, - Stack> tags, - bool atSpecialTag, - IDisposable tagBlockWrapper) - { - if (!EndOfFile) - { - switch (CurrentSymbol.Type) - { - case HtmlSymbolType.ForwardSlash: - // End Tag - return EndTag(tagStart, tags, tagBlockWrapper); - case HtmlSymbolType.Bang: - // Comment, CDATA, DOCTYPE, or a parser-escaped HTML tag. - if (atSpecialTag) - { - Accept(_bufferedOpenAngle); - return BangTag(); - } - else - { - goto default; - } - case HtmlSymbolType.QuestionMark: - // XML PI - Accept(_bufferedOpenAngle); - return XmlPI(); - default: - // Start Tag - return StartTag(tags, tagBlockWrapper); - } - } - if (tags.Count == 0) - { - Context.OnError( - CurrentLocation, - RazorResources.ParseError_OuterTagMissingName, - length: 1 /* end of file */); - } - return false; - } - - private bool XmlPI() - { - // Accept "?" - Assert(HtmlSymbolType.QuestionMark); - AcceptAndMoveNext(); - return AcceptUntilAll(HtmlSymbolType.QuestionMark, HtmlSymbolType.CloseAngle); - } - - private bool BangTag() - { - // Accept "!" - Assert(HtmlSymbolType.Bang); - - if (AcceptAndMoveNext()) - { - if (CurrentSymbol.Type == HtmlSymbolType.DoubleHyphen) - { - AcceptAndMoveNext(); - return AcceptUntilAll(HtmlSymbolType.DoubleHyphen, HtmlSymbolType.CloseAngle); - } - else if (CurrentSymbol.Type == HtmlSymbolType.LeftBracket) - { - if (AcceptAndMoveNext()) - { - return CData(); - } - } - else - { - AcceptAndMoveNext(); - return AcceptUntilAll(HtmlSymbolType.CloseAngle); - } - } - - return false; - } - - private bool CData() - { - if (CurrentSymbol.Type == HtmlSymbolType.Text && string.Equals(CurrentSymbol.Content, "cdata", StringComparison.OrdinalIgnoreCase)) - { - if (AcceptAndMoveNext()) - { - if (CurrentSymbol.Type == HtmlSymbolType.LeftBracket) - { - return AcceptUntilAll(HtmlSymbolType.RightBracket, HtmlSymbolType.RightBracket, HtmlSymbolType.CloseAngle); - } - } - } - - return false; - } - - private bool EndTag(SourceLocation tagStart, - Stack> tags, - IDisposable tagBlockWrapper) - { - // Accept "/" and move next - Assert(HtmlSymbolType.ForwardSlash); - var forwardSlash = CurrentSymbol; - if (!NextToken()) - { - Accept(_bufferedOpenAngle); - Accept(forwardSlash); - return false; - } - else - { - var tagName = string.Empty; - HtmlSymbol bangSymbol = null; - - if (At(HtmlSymbolType.Bang)) - { - bangSymbol = CurrentSymbol; - - var nextSymbol = Lookahead(count: 1); - - if (nextSymbol != null && nextSymbol.Type == HtmlSymbolType.Text) - { - tagName = "!" + nextSymbol.Content; - } - } - else if (At(HtmlSymbolType.Text)) - { - tagName = CurrentSymbol.Content; - } - - var matched = RemoveTag(tags, tagName, tagStart); - - if (tags.Count == 0 && - // Note tagName may contain a '!' escape character. This ensures doesn't match here. - // tags are treated like any other escaped HTML end tag. - string.Equals(tagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase) && - matched) - { - return EndTextTag(forwardSlash, tagBlockWrapper); - } - Accept(_bufferedOpenAngle); - Accept(forwardSlash); - - OptionalBangEscape(); - - AcceptUntil(HtmlSymbolType.CloseAngle); - - // Accept the ">" - return Optional(HtmlSymbolType.CloseAngle); - } - } - - private void RecoverTextTag() - { - // We don't want to skip-to and parse because there shouldn't be anything in the body of text tags. - AcceptUntil(HtmlSymbolType.CloseAngle, HtmlSymbolType.NewLine); - - // Include the close angle in the text tag block if it's there, otherwise just move on - Optional(HtmlSymbolType.CloseAngle); - } - - private bool EndTextTag(HtmlSymbol solidus, IDisposable tagBlockWrapper) - { - Accept(_bufferedOpenAngle); - Accept(solidus); - - var textLocation = CurrentLocation; - Assert(HtmlSymbolType.Text); - AcceptAndMoveNext(); - - var seenCloseAngle = Optional(HtmlSymbolType.CloseAngle); - - if (!seenCloseAngle) - { - Context.OnError( - textLocation, - RazorResources.ParseError_TextTagCannotContainAttributes, - length: 4 /* text */); - - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.Any; - RecoverTextTag(); - } - else - { - Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; - } - - Span.ChunkGenerator = SpanChunkGenerator.Null; - - CompleteTagBlockWithSpan(tagBlockWrapper, Span.EditHandler.AcceptedCharacters, SpanKind.Transition); - - return seenCloseAngle; - } - - // Special tags include - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - The active parser must be the same as either the markup or code parser. - - - code - This is a literal used when composing ParserError_* messages. Most blocks are named by the keyword that starts them, for example "if". However, for those without keywords, a (localizable) name must be used. This literal is ALWAYS used mid-sentence, thus should not be capitalized. - - - explicit expression - This is a literal used when composing ParserError_* messages. Most blocks are named by the keyword that starts them, for example "if". However, for those without keywords, a (localizable) name must be used. This literal is ALWAYS used mid-sentence, thus should not be capitalized. - - - The "CancelBacktrack" method can be called only while in a look-ahead process started with the "BeginLookahead" method. - - - "EndBlock" was called without a matching call to "StartBlock". - - - The "@" character must be followed by a ":", "(", or a C# identifier. If you intended to switch to markup, use an HTML start tag, for example: - -@if(isLoggedIn) { - <p>Hello, @user!</p> -} - - - End of file was reached before the end of the block comment. All comments started with "/*" sequence must be terminated with a matching "*/" sequence. - - - An opening "{0}" is missing the corresponding closing "{1}". - - - The {0} block is missing a closing "{1}" character. Make sure you have a matching "{1}" character for all the "{2}" characters within this block, and that none of the "{1}" characters are being interpreted as markup. - - - Expected "{0}". - - - Inline markup blocks (@<p>Content</p>) cannot be nested. Only one level of inline markup is allowed. - - - Markup in a code block must start with a tag and all start tags must be matched with end tags. Do not use unclosed tags like "<br>". Instead use self-closing tags like "<br/>". - - - The "{0}" element was not closed. All elements must be either self-closing or have a matching end tag. - - - Sections cannot be empty. The "@section" keyword must be followed by a block of markup surrounded by "{}". For example: - -@section Sidebar { - <!-- Markup and text goes here --> -} - - - Namespace imports and type aliases cannot be placed within code blocks. They must immediately follow an "@" character in markup. It is recommended that you put them at the top of the page, as in the following example: - -@using System.Drawing; -@{ - // OK here to use types from System.Drawing in the page. -} - - - Expected a "{0}" but found a "{1}". Block statements must be enclosed in "{{" and "}}". You cannot use single-statement control-flow statements in CSHTML pages. For example, the following is not allowed: - -@if(isLoggedIn) - <p>Hello, @user</p> - -Instead, wrap the contents of the block in "{{}}": - -@if(isLoggedIn) {{ - <p>Hello, @user</p> -}} - {0} is only ever a single character - - - Encountered end tag "{0}" with no matching start tag. Are your start/end tags properly balanced? - - - Unexpected {0} after section keyword. Section names must start with an "_" or alphabetic character, and the remaining characters must be either "_" or alphanumeric. - - - "{0}" is not valid at the start of a code block. Only identifiers, keywords, comments, "(" and "{{" are valid. - "{{" is an escape sequence for string.Format, when outputted to the user it will be displayed as "{" - - - End of file or an unexpected character was reached before the "{0}" tag could be parsed. Elements inside markup blocks must be complete. They must either be self-closing ("<br />") or have matching end tags ("<p>Hello</p>"). If you intended to display a "<" character, use the "&lt;" HTML entity. - - - Unterminated string literal. Strings that start with a quotation mark (") must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@") can span multiple lines. - - - @section Header { ... } - In CSHTML, the @section keyword is case-sensitive and lowercase (as with all C# keywords) - - - "<text>" and "</text>" tags cannot contain attributes. - - - A space or line break was encountered after the "@" character. Only valid identifiers, keywords, comments, "(" and "{" are valid at the start of a code block and they must occur immediately following "@" with no space in between. - - - The 'inherits' keyword must be followed by a type name on the same line. - - - Outer tag is missing a name. The first character of a markup block must be an HTML tag with a valid name. - - - End of file was reached before the end of the block comment. All comments that start with the "@*" sequence must be terminated with a matching "*@" sequence. - - - "{0}" character - - - end of file - - - space or line break - - - End-of-file was found after the "@" character. "@" must be followed by a valid code block. If you want to output an "@", escape it using the sequence: "@@" - - - The {0} property of the {1} structure cannot be null. - - - Parser was started with a null Context property. The Context property must be set BEFORE calling any methods on the parser. - - - "{0}" is a reserved word and cannot be used in implicit expressions. An explicit expression ("@()") must be used. - - - Cannot resume this symbol. Only the symbol immediately preceding the current one can be resumed. - - - Cannot finish span, there is no current block. Call StartBlock at least once before finishing a span - - - Cannot complete the tree, there are still open blocks. - - - Cannot complete the tree, StartBlock must be called at least once. - - - Cannot complete action, the parser has finished. Only CompleteParse can be called to extract the final parser results after the parser has finished - - - Block cannot be built because a Type has not been specified in the BlockBuilder - - - <<character literal>> - - - <<comment>> - - - <<identifier>> - - - <<integer literal>> - - - <<keyword>> - - - <<newline sequence>> - - - <<real literal>> - - - <<string literal>> - - - <<white space>> - - - <<unknown>> - - - In order to put a symbol back, it must have been the symbol which ended at the current position. The specified symbol ends at {0}, but the current position is {1} - - - Unexpected "{" after "@" character. Once inside the body of a code block (@if {}, @{}, etc.) you do not need to use "@{" to switch to code. - - - line break - - - <<newline sequence>> - - - <<razor comment>> - - - <<text>> - - - <<white space>> - - - The parser provided to the ParserContext was not a Markup Parser. - - - Cannot use built-in RazorComment handler, language characteristics does not define the CommentStart, CommentStar and CommentBody known symbol types or parser does not override TokenizerBackedParser.OutputSpanBeforeRazorComment - - - [BG][{0}] Shutdown - - - [BG][{0}] Startup - - - [BG][{0}] {1} changes arrived - - - [BG][{0}] Discarded {1} changes - - - [BG][{0}] Collecting {1} discarded changes - - - Disabled - - - [P][{0}] {3} Change in {2} milliseconds: {1} - - - [P][{0}] Received Change: {1} - - - Enabled - - - [Razor] {0} - - - [BG][{0}] no changes arrived? - - - [BG][{0}] Parse Complete in {1} milliseconds - - - [M][{0}] Queuing Parse for: {1} - - - [Razor] Editor Tracing {0} - - - [BG][{0}] Trees Compared in {1} milliseconds. Different = {2} - - - Section blocks ("{0}") cannot be nested. Only one level of section blocks are allowed. - - - Tag Helper '{0}'s attributes must have names. - - - The tag helper '{0}' must not have C# in the element's attribute declaration area. - - - Directive '{0}' must have a value. - - - Directive '{0}'s value must be surrounded in double quotes. - - - Found a malformed '{0}' tag helper. Tag helpers must have a start and end tag or be self closing. - - - Missing close angle for tag helper '{0}'. - - - TagHelper attributes must be well-formed. - - - The tag helper attribute '{0}' in element '{1}' is missing a key. The syntax is '<{1} {0}{{ key }}="value">'. - - - Non-string tag helper attribute values must not be empty. Add an expression to this attribute value. - - - Code blocks (e.g. @{{var variable = 23;}}) must not appear in non-string tag helper attribute values. - Already in an expression (code) context. If necessary an explicit expression (e.g. @(@readonly)) may be used. - - - @'{0}' directives must not appear in non-string tag helper attribute values. - - - Inline markup blocks (e.g. @<p>content</p>) must not appear in non-string tag helper attribute values. - Expected a '{0}' attribute value, not a string. - - - Attribute '{0}' on tag helper element '{1}' requires a value. Tag helper bound attributes of type '{2}' cannot be empty or contain only whitespace. - - - Cannot perform '{1}' operations on '{0}' instances with different file paths. - - - Tag helpers '{0}' and '{1}' targeting element '{2}' must not expect different {3} values. - - - Found an end tag (</{0}>) for tag helper '{1}' with tag structure that disallows an end tag ('{2}'). - - - The parent <{0}> tag helper does not allow non-tag content. Only child tag helper(s) targeting tag name(s) '{1}' are allowed. - - - The <{0}> tag is not allowed by parent <{1}> tag helper. Only child tags with name(s) '{2}' are allowed. - - - The {0} directive is not supported. - - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor.VSRC1/RazorTemplateEngine.cs b/src/Microsoft.AspNet.Razor.VSRC1/RazorTemplateEngine.cs deleted file mode 100644 index b89ae9c0f4..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/RazorTemplateEngine.cs +++ /dev/null @@ -1,454 +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; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Security.Cryptography; -using System.Text; -using System.Threading; -using Microsoft.AspNet.Razor.Chunks.Generators; -using Microsoft.AspNet.Razor.CodeGenerators; -using Microsoft.AspNet.Razor.Parser; -using Microsoft.AspNet.Razor.Text; - -namespace Microsoft.AspNet.Razor -{ - ///

- /// Entry-point to the Razor Template Engine - /// - public class RazorTemplateEngine - { - private const int BufferSize = 1024; - public static readonly string DefaultClassName = "Template"; - public static readonly string DefaultNamespace = string.Empty; - - /// - /// Constructs a new RazorTemplateEngine with the specified host - /// - /// - /// The host which defines the environment in which the generated template code will live. - /// - public RazorTemplateEngine(RazorEngineHost host) - { - if (host == null) - { - throw new ArgumentNullException(nameof(host)); - } - - Host = host; - } - - /// - /// The RazorEngineHost which defines the environment in which the generated template code will live - /// - public RazorEngineHost Host { get; } - - public ParserResults ParseTemplate(ITextBuffer input) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return ParseTemplate(input, cancelToken: null); - } - - /// - /// Parses the template specified by the TextBuffer and returns it's result - /// - /// - /// - /// IMPORTANT: This does NOT need to be called before GeneratedCode! GenerateCode will automatically - /// parse the document first. - /// - /// - /// The cancel token provided can be used to cancel the parse. However, please note - /// that the parse occurs _synchronously_, on the callers thread. This parameter is - /// provided so that if the caller is in a background thread with a CancellationToken, - /// it can pass it along to the parser. - /// - /// - /// The input text to parse. - /// A token used to cancel the parser. - /// The resulting parse tree. - [SuppressMessage( - "Microsoft.Reliability", "CA2000:Dispose objects before losing scope", - Justification = "Input object would be disposed if we dispose the wrapper. We don't own the input so " + - "we don't want to dispose it")] - public ParserResults ParseTemplate(ITextBuffer input, CancellationToken? cancelToken) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return ParseTemplateCore(input.ToDocument(), sourceFileName: null, cancelToken: cancelToken); - } - - // See ParseTemplate(ITextBuffer, CancellationToken?), - // this overload simply wraps a TextReader in a TextBuffer (see ITextBuffer and BufferingTextReader) - public ParserResults ParseTemplate(TextReader input, string sourceFileName) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return ParseTemplateCore(new SeekableTextReader(input), sourceFileName, cancelToken: null); - } - - [SuppressMessage( - "Microsoft.Reliability", - "CA2000:Dispose objects before losing scope", - Justification = "Input object would be disposed if we dispose the wrapper. We don't own the input so " + - "we don't want to dispose it")] - public ParserResults ParseTemplate(TextReader input, CancellationToken? cancelToken) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return ParseTemplateCore(new SeekableTextReader(input), sourceFileName: null, cancelToken: cancelToken); - } - - protected internal virtual ParserResults ParseTemplateCore( - ITextDocument input, - string sourceFileName, - CancellationToken? cancelToken) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - // Construct the parser - var parser = CreateParser(sourceFileName); - Debug.Assert(parser != null); - return parser.Parse(input); - } - - public GeneratorResults GenerateCode(ITextBuffer input) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return GenerateCode(input, className: null, rootNamespace: null, sourceFileName: null, cancelToken: null); - } - - public GeneratorResults GenerateCode(ITextBuffer input, CancellationToken? cancelToken) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return GenerateCode( - input, - className: null, - rootNamespace: null, - sourceFileName: null, - cancelToken: cancelToken); - } - - public GeneratorResults GenerateCode( - ITextBuffer input, - string className, - string rootNamespace, - string sourceFileName) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return GenerateCode(input, className, rootNamespace, sourceFileName, cancelToken: null); - } - - /// - /// Parses the template specified by the TextBuffer, generates code for it, and returns the constructed code. - /// - /// - /// - /// The cancel token provided can be used to cancel the parse. However, please note - /// that the parse occurs _synchronously_, on the callers thread. This parameter is - /// provided so that if the caller is in a background thread with a CancellationToken, - /// it can pass it along to the parser. - /// - /// - /// The className, rootNamespace and sourceFileName parameters are optional and override the default - /// specified by the Host. For example, the WebPageRazorHost in System.Web.WebPages.Razor configures the - /// Class Name, Root Namespace and Source File Name based on the virtual path of the page being compiled. - /// However, the built-in RazorEngineHost class uses constant defaults, so the caller will likely want to - /// change them using these parameters. - /// - /// - /// The input text to parse. - /// A token used to cancel the parser. - /// - /// The name of the generated class, overriding whatever is specified in the Host. The default value (defined - /// in the Host) can be used by providing null for this argument. - /// - /// The namespace in which the generated class will reside, overriding whatever is - /// specified in the Host. The default value (defined in the Host) can be used by providing null for this - /// argument. - /// - /// - /// The file name to use in line pragmas, usually the original Razor file, overriding whatever is specified in - /// the Host. The default value (defined in the Host) can be used by providing null for this argument. - /// - /// The resulting parse tree AND generated code. - [SuppressMessage( - "Microsoft.Reliability", - "CA2000:Dispose objects before losing scope", - Justification = "Input object would be disposed if we dispose the wrapper. We don't own the input so " + - "we don't want to dispose it")] - public GeneratorResults GenerateCode( - ITextBuffer input, - string className, - string rootNamespace, - string sourceFileName, - CancellationToken? cancelToken) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return GenerateCodeCore( - input.ToDocument(), - className, - rootNamespace, - sourceFileName, - checksum: null, - cancelToken: cancelToken); - } - - // See GenerateCode override which takes ITextBuffer, and BufferingTextReader for details. - public GeneratorResults GenerateCode(TextReader input) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return GenerateCode(input, className: null, rootNamespace: null, sourceFileName: null, cancelToken: null); - } - - public GeneratorResults GenerateCode(TextReader input, CancellationToken? cancelToken) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return GenerateCode( - input, - className: null, - rootNamespace: null, - sourceFileName: null, - cancelToken: cancelToken); - } - - public GeneratorResults GenerateCode( - TextReader input, - string className, - - string rootNamespace, string sourceFileName) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return GenerateCode(input, className, rootNamespace, sourceFileName, cancelToken: null); - } - - /// - /// Parses the contents specified by the and returns the generated code. - /// - /// A that represents the contents to be parsed. - /// The name of the generated class. When null, defaults to - /// (Host.DefaultClassName). - /// The namespace in which the generated class will reside. When null, - /// defaults to (Host.DefaultNamespace). - /// - /// The file name to use in line pragmas, usually the original Razor file. - /// - /// A that represents the results of parsing the content. - /// - /// This overload calculates the checksum of the contents of prior to code - /// generation. The checksum is used for producing the #pragma checksum line pragma required for - /// debugging. - /// - public GeneratorResults GenerateCode( - Stream inputStream, - string className, - string rootNamespace, - string sourceFileName) - { - if (inputStream == null) - { - throw new ArgumentNullException(nameof(inputStream)); - } - - MemoryStream memoryStream = null; - string checksum = null; - try - { - if (!Host.DesignTimeMode) - { - // We don't need to calculate the checksum in design time. - if (!inputStream.CanSeek) - { - memoryStream = new MemoryStream(); - inputStream.CopyTo(memoryStream); - - // We don't have to dispose the input stream since it is owned externally. - inputStream = memoryStream; - } - - inputStream.Position = 0; - checksum = ComputeChecksum(inputStream); - inputStream.Position = 0; - } - - using (var reader = - new StreamReader( - inputStream, - Encoding.UTF8, - detectEncodingFromByteOrderMarks: true, - bufferSize: BufferSize, - leaveOpen: true)) - { - var seekableStream = new SeekableTextReader(reader); - return GenerateCodeCore( - seekableStream, - className, - rootNamespace, - sourceFileName, - checksum, - cancelToken: null); - } - } - finally - { - if (memoryStream != null) - { - memoryStream.Dispose(); - } - } - } - - [SuppressMessage( - "Microsoft.Reliability", - "CA2000:Dispose objects before losing scope", - Justification = "Input object would be disposed if we dispose the wrapper. We don't own the input so " + - "we don't want to dispose it")] - public GeneratorResults GenerateCode( - TextReader input, - string className, - string rootNamespace, - string sourceFileName, - CancellationToken? cancelToken) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - return GenerateCodeCore( - new SeekableTextReader(input), - className, - rootNamespace, - sourceFileName, - checksum: null, - cancelToken: cancelToken); - } - - protected internal virtual GeneratorResults GenerateCodeCore( - ITextDocument input, - string className, - string rootNamespace, - string sourceFileName, - string checksum, - CancellationToken? cancelToken) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - className = (className ?? Host.DefaultClassName) ?? DefaultClassName; - rootNamespace = (rootNamespace ?? Host.DefaultNamespace) ?? DefaultNamespace; - - // Run the parser - var parser = CreateParser(sourceFileName); - Debug.Assert(parser != null); - var results = parser.Parse(input); - - // Generate code - var chunkGenerator = CreateChunkGenerator(className, rootNamespace, sourceFileName); - chunkGenerator.DesignTimeMode = Host.DesignTimeMode; - chunkGenerator.Visit(results); - - var codeGeneratorContext = new CodeGeneratorContext(chunkGenerator.Context, results.ErrorSink); - codeGeneratorContext.Checksum = checksum; - var codeGenerator = CreateCodeGenerator(codeGeneratorContext); - var codeGeneratorResult = codeGenerator.Generate(); - - // Collect results and return - return new GeneratorResults(results, codeGeneratorResult, codeGeneratorContext.ChunkTreeBuilder.ChunkTree); - } - - protected internal virtual RazorChunkGenerator CreateChunkGenerator( - string className, - string rootNamespace, - string sourceFileName) - { - return Host.DecorateChunkGenerator( - Host.CodeLanguage.CreateChunkGenerator(className, rootNamespace, sourceFileName, Host)); - } - - protected internal virtual RazorParser CreateParser(string sourceFileName) - { - var codeParser = Host.CodeLanguage.CreateCodeParser(); - var markupParser = Host.CreateMarkupParser(); - - var parser = new RazorParser( - Host.DecorateCodeParser(codeParser), - Host.DecorateMarkupParser(markupParser), - Host.TagHelperDescriptorResolver) - { - DesignTimeMode = Host.DesignTimeMode - }; - - return Host.DecorateRazorParser(parser, sourceFileName); - } - - protected internal virtual CodeGenerator CreateCodeGenerator(CodeGeneratorContext context) - { - return Host.DecorateCodeGenerator(Host.CodeLanguage.CreateCodeGenerator(context), context); - } - - private static string ComputeChecksum(Stream inputStream) - { - byte[] hashedBytes; - using (var hashAlgorithm = SHA1.Create()) - { - hashedBytes = hashAlgorithm.ComputeHash(inputStream); - } - - var fileHashBuilder = new StringBuilder(hashedBytes.Length * 2); - foreach (var value in hashedBytes) - { - fileHashBuilder.Append(value.ToString("x2")); - } - return fileHashBuilder.ToString(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/SourceLocation.cs b/src/Microsoft.AspNet.Razor.VSRC1/SourceLocation.cs deleted file mode 100644 index 318f6cd1aa..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/SourceLocation.cs +++ /dev/null @@ -1,254 +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; -using System.Globalization; -using Microsoft.AspNet.Razor.Text; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor -{ - /// - /// A location in a Razor file. - /// -#if NET451 - // No Serializable attribute in CoreCLR (no need for it anymore?) - [Serializable] -#endif - public struct SourceLocation : IEquatable, IComparable - { - /// - /// An undefined . - /// - public static readonly SourceLocation Undefined = - new SourceLocation(absoluteIndex: -1, lineIndex: -1, characterIndex: -1); - - /// - /// A with , , and - /// initialized to 0. - /// - public static readonly SourceLocation Zero = - new SourceLocation(absoluteIndex: 0, lineIndex: 0, characterIndex: 0); - - /// - /// Initializes a new instance of . - /// - /// The absolute index. - /// The line index. - /// The character index. - public SourceLocation(int absoluteIndex, int lineIndex, int characterIndex) - : this(filePath: null, absoluteIndex: absoluteIndex, lineIndex: lineIndex, characterIndex: characterIndex) - { - } - - /// - /// Initializes a new instance of . - /// - /// The file path. - /// The absolute index. - /// The line index. - /// The character index. - public SourceLocation(string filePath, int absoluteIndex, int lineIndex, int characterIndex) - { - FilePath = filePath; - AbsoluteIndex = absoluteIndex; - LineIndex = lineIndex; - CharacterIndex = characterIndex; - } - - /// - /// Path of the file. - /// - /// When null, the parser assumes the location is in the file currently being processed. - /// - public string FilePath { get; set; } - - /// Set property is only accessible for deserialization purposes. - public int AbsoluteIndex { get; set; } - - /// - /// Gets the 1-based index of the line referred to by this Source Location. - /// - /// Set property is only accessible for deserialization purposes. - public int LineIndex { get; set; } - - /// Set property is only accessible for deserialization purposes. - public int CharacterIndex { get; set; } - - /// - public override string ToString() - { - return string.Format( - CultureInfo.CurrentCulture, - "({0}:{1},{2})", - AbsoluteIndex, - LineIndex, - CharacterIndex); - } - - /// - public override bool Equals(object obj) - { - return obj is SourceLocation && - Equals((SourceLocation)obj); - } - - /// - public override int GetHashCode() - { - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(FilePath, StringComparer.Ordinal); - hashCodeCombiner.Add(AbsoluteIndex); - - return hashCodeCombiner; - } - - /// - public bool Equals(SourceLocation other) - { - // LineIndex and CharacterIndex can be calculated from AbsoluteIndex and the document content. - return CompareTo(other) == 0; - } - - /// - public int CompareTo(SourceLocation other) - { - var filePathOrdinal = string.Compare(FilePath, other.FilePath, StringComparison.Ordinal); - if (filePathOrdinal != 0) - { - return filePathOrdinal; - } - - return AbsoluteIndex.CompareTo(other.AbsoluteIndex); - } - - /// - /// Advances the by the length of the . - /// - /// The to advance. - /// The to advance by. - /// The advanced . - public static SourceLocation Advance(SourceLocation left, string text) - { - if (text == null) - { - throw new ArgumentNullException(nameof(text)); - } - - var tracker = new SourceLocationTracker(left); - tracker.UpdateLocation(text); - return tracker.CurrentLocation; - } - - /// - /// Adds two s. - /// - /// The left operand. - /// The right operand. - /// A that is the sum of the left and right operands. - /// if the of the left and right operands - /// are different, and neither is null. - public static SourceLocation operator +(SourceLocation left, SourceLocation right) - { - if (!string.Equals(left.FilePath, right.FilePath, StringComparison.Ordinal) && - left.FilePath != null && - right.FilePath != null) - { - // Throw if FilePath for left and right are different, and neither is null. - throw new ArgumentException( - RazorResources.FormatSourceLocationFilePathDoesNotMatch(nameof(SourceLocation), "+"), - nameof(right)); - } - - var resultFilePath = left.FilePath ?? right.FilePath; - if (right.LineIndex > 0) - { - // Column index doesn't matter - return new SourceLocation( - resultFilePath, - left.AbsoluteIndex + right.AbsoluteIndex, - left.LineIndex + right.LineIndex, - right.CharacterIndex); - } - else - { - return new SourceLocation( - resultFilePath, - left.AbsoluteIndex + right.AbsoluteIndex, - left.LineIndex + right.LineIndex, - left.CharacterIndex + right.CharacterIndex); - } - } - - /// - /// Subtracts two s. - /// - /// The left operand. - /// The right operand. - /// A that is the difference of the left and right operands. - /// if the of the left and right operands - /// are different. - public static SourceLocation operator -(SourceLocation left, SourceLocation right) - { - if (!string.Equals(left.FilePath, right.FilePath, StringComparison.Ordinal)) - { - throw new ArgumentException( - RazorResources.FormatSourceLocationFilePathDoesNotMatch(nameof(SourceLocation), "-"), - nameof(right)); - } - - var characterIndex = left.LineIndex != right.LineIndex ? - left.CharacterIndex : left.CharacterIndex - right.CharacterIndex; - - return new SourceLocation( - filePath: null, - absoluteIndex: left.AbsoluteIndex - right.AbsoluteIndex, - lineIndex: left.LineIndex - right.LineIndex, - characterIndex: characterIndex); - } - - /// - /// Determines whether the first operand is less than the second operand. - /// - /// The left operand. - /// The right operand. - /// true if is less than . - public static bool operator <(SourceLocation left, SourceLocation right) - { - return left.CompareTo(right) < 0; - } - - /// - /// Determines whether the first operand is greater than the second operand. - /// - /// The left operand. - /// The right operand. - /// true if is greater than . - public static bool operator >(SourceLocation left, SourceLocation right) - { - return left.CompareTo(right) > 0; - } - - /// - /// Determines whether the operands are equal. - /// - /// The left operand. - /// The right operand. - /// true if and are equal. - public static bool operator ==(SourceLocation left, SourceLocation right) - { - return left.Equals(right); - } - - /// - /// Determines whether the operands are not equal. - /// - /// The left operand. - /// The right operand. - /// true if and are not equal. - public static bool operator !=(SourceLocation left, SourceLocation right) - { - return !left.Equals(right); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/StateMachine.cs b/src/Microsoft.AspNet.Razor.VSRC1/StateMachine.cs deleted file mode 100644 index 0439744b67..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/StateMachine.cs +++ /dev/null @@ -1,106 +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. - -namespace Microsoft.AspNet.Razor -{ - public abstract class StateMachine - { - protected delegate StateResult State(); - - protected abstract State StartState { get; } - - protected State CurrentState { get; set; } - - protected virtual TReturn Turn() - { - if (CurrentState != null) - { - StateResult result; - do - { - // Keep running until we get a null result or output - result = CurrentState(); - CurrentState = result.Next; - } - while (result != null && !result.HasOutput); - - if (result == null) - { - return default(TReturn); // Terminated - } - return result.Output; - } - return default(TReturn); - } - - /// - /// Returns a result indicating that the machine should stop executing and return null output. - /// - protected StateResult Stop() - { - return null; - } - - /// - /// Returns a result indicating that this state has no output and the machine should immediately invoke the specified state - /// - /// - /// By returning no output, the state machine will invoke the next state immediately, before returning - /// controller to the caller of - /// - protected StateResult Transition(State newState) - { - return new StateResult(newState); - } - - /// - /// Returns a result containing the specified output and indicating that the next call to - /// should invoke the provided state. - /// - protected StateResult Transition(TReturn output, State newState) - { - return new StateResult(output, newState); - } - - /// - /// Returns a result indicating that this state has no output and the machine should remain in this state - /// - /// - /// By returning no output, the state machine will re-invoke the current state again before returning - /// controller to the caller of - /// - protected StateResult Stay() - { - return new StateResult(CurrentState); - } - - /// - /// Returns a result containing the specified output and indicating that the next call to - /// should re-invoke the current state. - /// - protected StateResult Stay(TReturn output) - { - return new StateResult(output, CurrentState); - } - - protected class StateResult - { - public StateResult(State next) - { - HasOutput = false; - Next = next; - } - - public StateResult(TReturn output, State next) - { - HasOutput = true; - Output = output; - Next = next; - } - - public bool HasOutput { get; set; } - public TReturn Output { get; set; } - public State Next { get; set; } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/TagHelpers/TagMode.cs b/src/Microsoft.AspNet.Razor.VSRC1/TagHelpers/TagMode.cs deleted file mode 100644 index d6c33d4b4e..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/TagHelpers/TagMode.cs +++ /dev/null @@ -1,26 +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. - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// The mode in which an element should render. - /// - public enum TagMode - { - /// - /// Include both start and end tags. - /// - StartTagAndEndTag, - - /// - /// A self-closed tag. - /// - SelfClosing, - - /// - /// Only a start tag. - /// - StartTagOnly - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/TagHelpers/TagStructure.cs b/src/Microsoft.AspNet.Razor.VSRC1/TagHelpers/TagStructure.cs deleted file mode 100644 index 5c801f3e27..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/TagHelpers/TagStructure.cs +++ /dev/null @@ -1,28 +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. - -namespace Microsoft.AspNet.Razor.TagHelpers -{ - /// - /// The structure the element should be written in. - /// - public enum TagStructure - { - /// - /// If no other tag helper applies to the same element and specifies a , - /// will be used. - /// - Unspecified, - - /// - /// Element can be written as <my-tag-helper></my-tag-helper> or <my-tag-helper />. - /// - NormalOrSelfClosing, - - /// - /// Element can be written as <my-tag-helper> or <my-tag-helper />. - /// - /// Elements with a structure will never have any content. - WithoutEndTag - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/BufferingTextReader.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/BufferingTextReader.cs deleted file mode 100644 index b247b416e4..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/BufferingTextReader.cs +++ /dev/null @@ -1,201 +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; -using System.Collections.Generic; -using System.IO; -using System.Text; -using Microsoft.AspNet.Razor.Utils; - -namespace Microsoft.AspNet.Razor.Text -{ - public class BufferingTextReader : LookaheadTextReader - { - private Stack _backtrackStack = new Stack(); - private int _currentBufferPosition; - - private int _currentCharacter; - private SourceLocationTracker _locationTracker; - - public BufferingTextReader(TextReader source) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - InnerReader = source; - _locationTracker = new SourceLocationTracker(); - - UpdateCurrentCharacter(); - } - - internal StringBuilder Buffer { get; set; } - internal bool Buffering { get; set; } - internal TextReader InnerReader { get; private set; } - - public override SourceLocation CurrentLocation - { - get { return _locationTracker.CurrentLocation; } - } - - protected virtual int CurrentCharacter - { - get { return _currentCharacter; } - } - - public override int Read() - { - var ch = CurrentCharacter; - NextCharacter(); - return ch; - } - - // TODO: Optimize Read(char[],int,int) to copy direct from the buffer where possible - - public override int Peek() - { - return CurrentCharacter; - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - InnerReader.Dispose(); - } - base.Dispose(disposing); - } - - public override IDisposable BeginLookahead() - { - // Is this our first lookahead? - if (Buffer == null) - { - // Yes, setup the backtrack buffer - Buffer = new StringBuilder(); - } - - if (!Buffering) - { - // We're not already buffering, so we need to expand the buffer to hold the first character - ExpandBuffer(); - Buffering = true; - } - - // Mark the position to return to when we backtrack - // Use the closures and the "using" statement rather than an explicit stack - var context = new BacktrackContext() - { - BufferIndex = _currentBufferPosition, - Location = CurrentLocation - }; - _backtrackStack.Push(context); - return new DisposableAction(() => - { - EndLookahead(context); - }); - } - - // REVIEW: This really doesn't sound like the best name for this... - public override void CancelBacktrack() - { - if (_backtrackStack.Count == 0) - { - throw new InvalidOperationException(RazorResources.CancelBacktrack_Must_Be_Called_Within_Lookahead); - } - // Just pop the current backtrack context so that when the lookahead ends, it won't be backtracked - _backtrackStack.Pop(); - } - - private void EndLookahead(BacktrackContext context) - { - // If the specified context is not the one on the stack, it was popped by a call to DoNotBacktrack - if (_backtrackStack.Count > 0 && ReferenceEquals(_backtrackStack.Peek(), context)) - { - _backtrackStack.Pop(); - _currentBufferPosition = context.BufferIndex; - _locationTracker.CurrentLocation = context.Location; - - UpdateCurrentCharacter(); - } - } - - protected virtual void NextCharacter() - { - var prevChar = CurrentCharacter; - if (prevChar == -1) - { - return; // We're at the end of the source - } - - if (Buffering) - { - if (_currentBufferPosition >= Buffer.Length - 1) - { - // If there are no more lookaheads (thus no need to continue with the buffer) we can just clean up the buffer - if (_backtrackStack.Count == 0) - { - // Reset the buffer - Buffer.Length = 0; - _currentBufferPosition = 0; - Buffering = false; - } - else if (!ExpandBuffer()) - { - // Failed to expand the buffer, because we're at the end of the source - _currentBufferPosition = Buffer.Length; // Force the position past the end of the buffer - } - } - else - { - // Not at the end yet, just advance the buffer pointer - _currentBufferPosition++; - } - } - else - { - // Just act like normal - InnerReader.Read(); // Don't care about the return value, Peek() is used to get characters from the source - } - - UpdateCurrentCharacter(); - _locationTracker.UpdateLocation((char)prevChar, (char)CurrentCharacter); - } - - protected bool ExpandBuffer() - { - // Pull another character into the buffer and update the position - var ch = InnerReader.Read(); - - // Only append the character to the buffer if there actually is one - if (ch != -1) - { - Buffer.Append((char)ch); - _currentBufferPosition = Buffer.Length - 1; - return true; - } - return false; - } - - private void UpdateCurrentCharacter() - { - if (Buffering && _currentBufferPosition < Buffer.Length) - { - // Read from the buffer - _currentCharacter = (int)Buffer[_currentBufferPosition]; - } - else - { - // No buffer? Peek from the source - _currentCharacter = InnerReader.Peek(); - } - } - - private class BacktrackContext - { - public int BufferIndex { get; set; } - public SourceLocation Location { get; set; } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/ITextBuffer.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/ITextBuffer.cs deleted file mode 100644 index 17bc920401..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/ITextBuffer.cs +++ /dev/null @@ -1,19 +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. - -namespace Microsoft.AspNet.Razor.Text -{ - public interface ITextBuffer - { - int Length { get; } - int Position { get; set; } - int Read(); - int Peek(); - } - - // TextBuffer with Location tracking - public interface ITextDocument : ITextBuffer - { - SourceLocation Location { get; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/LineTrackingStringBuffer.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/LineTrackingStringBuffer.cs deleted file mode 100644 index ef6e878067..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/LineTrackingStringBuffer.cs +++ /dev/null @@ -1,166 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using Microsoft.AspNet.Razor.Parser; - -namespace Microsoft.AspNet.Razor.Text -{ - internal class LineTrackingStringBuffer - { - private TextLine _currentLine; - private TextLine _endLine; - private IList _lines; - - public LineTrackingStringBuffer() - { - _endLine = new TextLine(0, 0); - _lines = new List() { _endLine }; - } - - public int Length - { - get { return _endLine.End; } - } - - public SourceLocation EndLocation - { - get { return new SourceLocation(Length, _lines.Count - 1, _lines[_lines.Count - 1].Length); } - } - - public void Append(string content) - { - for (int i = 0; i < content.Length; i++) - { - AppendCore(content[i]); - - // \r on it's own: Start a new line, otherwise wait for \n - // Other Newline: Start a new line - if ((content[i] == '\r' && (i + 1 == content.Length || content[i + 1] != '\n')) || (content[i] != '\r' && ParserHelpers.IsNewLine(content[i]))) - { - PushNewLine(); - } - } - } - - public CharacterReference CharAt(int absoluteIndex) - { - var line = FindLine(absoluteIndex); - if (line == null) - { - throw new ArgumentOutOfRangeException(nameof(absoluteIndex)); - } - var idx = absoluteIndex - line.Start; - return new CharacterReference(line.Content[idx], new SourceLocation(absoluteIndex, line.Index, idx)); - } - - private void PushNewLine() - { - _endLine = new TextLine(_endLine.End, _endLine.Index + 1); - _lines.Add(_endLine); - } - - private void AppendCore(char chr) - { - Debug.Assert(_lines.Count > 0); - _lines[_lines.Count - 1].Content.Append(chr); - } - - private TextLine FindLine(int absoluteIndex) - { - TextLine selected = null; - - if (_currentLine != null) - { - if (_currentLine.Contains(absoluteIndex)) - { - // This index is on the last read line - selected = _currentLine; - } - else if (absoluteIndex > _currentLine.Index && _currentLine.Index + 1 < _lines.Count) - { - // This index is ahead of the last read line - selected = ScanLines(absoluteIndex, _currentLine.Index); - } - } - - // Have we found a line yet? - if (selected == null) - { - // Scan from line 0 - selected = ScanLines(absoluteIndex, 0); - } - - Debug.Assert(selected == null || selected.Contains(absoluteIndex)); - _currentLine = selected; - return selected; - } - - private TextLine ScanLines(int absoluteIndex, int startPos) - { - for (int i = 0; i < _lines.Count; i++) - { - var idx = (i + startPos) % _lines.Count; - Debug.Assert(idx >= 0 && idx < _lines.Count); - - if (_lines[idx].Contains(absoluteIndex)) - { - return _lines[idx]; - } - } - return null; - } - - internal struct CharacterReference - { - private readonly char _character; - private readonly SourceLocation _location; - - public CharacterReference(char character, SourceLocation location) - { - _character = character; - _location = location; - } - - public char Character { get { return _character; } } - public SourceLocation Location { get { return _location; } } - } - - private class TextLine - { - private StringBuilder _content = new StringBuilder(); - - public TextLine(int start, int index) - { - Start = start; - Index = index; - } - - public StringBuilder Content - { - get { return _content; } - } - - public int Length - { - get { return Content.Length; } - } - - public int Start { get; set; } - public int Index { get; set; } - - public int End - { - get { return Start + Length; } - } - - public bool Contains(int index) - { - return index < End && index >= Start; - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/LocationTagged.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/LocationTagged.cs deleted file mode 100644 index 5156b7a212..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/LocationTagged.cs +++ /dev/null @@ -1,104 +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; -using System.Diagnostics; -using System.Globalization; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Text -{ - [DebuggerDisplay("({Location})\"{Value}\"")] - public class LocationTagged : IFormattable - { - private LocationTagged() - { - Location = SourceLocation.Undefined; - Value = default(TValue); - } - - public LocationTagged(TValue value, int offset, int line, int col) - : this(value, new SourceLocation(offset, line, col)) - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - } - - public LocationTagged(TValue value, SourceLocation location) - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - Location = location; - Value = value; - } - - public SourceLocation Location { get; } - - public TValue Value { get; } - - public override bool Equals(object obj) - { - LocationTagged other = obj as LocationTagged; - if (ReferenceEquals(other, null)) - { - return false; - } - - return Equals(other.Location, Location) && - Equals(other.Value, Value); - } - - public override int GetHashCode() - { - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(Location); - hashCodeCombiner.Add(Value); - - return hashCodeCombiner.CombinedHash; - } - - public override string ToString() - { - return Value.ToString(); - } - - public string ToString(string format, IFormatProvider formatProvider) - { - if (string.IsNullOrEmpty(format)) - { - format = "P"; - } - if (formatProvider == null) - { - formatProvider = CultureInfo.CurrentCulture; - } - switch (format.ToUpperInvariant()) - { - case "F": - return string.Format(formatProvider, "{0}@{1}", Value, Location); - default: - return Value.ToString(); - } - } - - public static implicit operator TValue(LocationTagged value) - { - return value == null ? default(TValue) : value.Value; - } - - public static bool operator ==(LocationTagged left, LocationTagged right) - { - return Equals(left, right); - } - - public static bool operator !=(LocationTagged left, LocationTagged right) - { - return !Equals(left, right); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/LookaheadTextReader.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/LookaheadTextReader.cs deleted file mode 100644 index 7d84a548a4..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/LookaheadTextReader.cs +++ /dev/null @@ -1,15 +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; -using System.IO; - -namespace Microsoft.AspNet.Razor.Text -{ - public abstract class LookaheadTextReader : TextReader - { - public abstract SourceLocation CurrentLocation { get; } - public abstract IDisposable BeginLookahead(); - public abstract void CancelBacktrack(); - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/LookaheadToken.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/LookaheadToken.cs deleted file mode 100644 index 063c5f95fb..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/LookaheadToken.cs +++ /dev/null @@ -1,37 +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.AspNet.Razor.Text -{ - public class LookaheadToken : IDisposable - { - private Action _cancelAction; - private bool _accepted; - - public LookaheadToken(Action cancelAction) - { - _cancelAction = cancelAction; - } - - public void Accept() - { - _accepted = true; - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (!_accepted) - { - _cancelAction(); - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/SeekableTextReader.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/SeekableTextReader.cs deleted file mode 100644 index d055eded9e..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/SeekableTextReader.cs +++ /dev/null @@ -1,109 +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; -using System.IO; - -namespace Microsoft.AspNet.Razor.Text -{ - public class SeekableTextReader : TextReader, ITextDocument - { - private int _position = 0; - private LineTrackingStringBuffer _buffer = new LineTrackingStringBuffer(); - private SourceLocation _location = SourceLocation.Zero; - private char? _current; - - public SeekableTextReader(string content) - { - _buffer.Append(content); - UpdateState(); - } - - public SeekableTextReader(TextReader source) - : this(source.ReadToEnd()) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - } - - public SeekableTextReader(ITextBuffer buffer) - : this(buffer.ReadToEnd()) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - } - - public SourceLocation Location - { - get { return _location; } - } - - public int Length - { - get { return _buffer.Length; } - } - - public int Position - { - get { return _position; } - set - { - if (_position != value) - { - _position = value; - UpdateState(); - } - } - } - - internal LineTrackingStringBuffer Buffer - { - get { return _buffer; } - } - - public override int Read() - { - if (_current == null) - { - return -1; - } - var chr = _current.Value; - _position++; - UpdateState(); - return chr; - } - - public override int Peek() - { - if (_current == null) - { - return -1; - } - return _current.Value; - } - - private void UpdateState() - { - if (_position < _buffer.Length) - { - LineTrackingStringBuffer.CharacterReference chr = _buffer.CharAt(_position); - _current = chr.Character; - _location = chr.Location; - } - else if (_buffer.Length == 0) - { - _current = null; - _location = SourceLocation.Zero; - } - else - { - _current = null; - _location = _buffer.EndLocation; - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/SourceLocationTracker.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/SourceLocationTracker.cs deleted file mode 100644 index 280917eae0..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/SourceLocationTracker.cs +++ /dev/null @@ -1,102 +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; -using Microsoft.AspNet.Razor.Parser; - -namespace Microsoft.AspNet.Razor.Text -{ - public class SourceLocationTracker - { - private int _absoluteIndex = 0; - private int _characterIndex = 0; - private int _lineIndex = 0; - private SourceLocation _currentLocation; - - public SourceLocationTracker() - : this(SourceLocation.Zero) - { - } - - public SourceLocationTracker(SourceLocation currentLocation) - { - CurrentLocation = currentLocation; - - UpdateInternalState(); - } - - public SourceLocation CurrentLocation - { - get - { - return _currentLocation; - } - set - { - if (_currentLocation != value) - { - _currentLocation = value; - UpdateInternalState(); - } - } - } - - public void UpdateLocation(char characterRead, char nextCharacter) - { - UpdateCharacterCore(characterRead, nextCharacter); - RecalculateSourceLocation(); - } - - public SourceLocationTracker UpdateLocation(string content) - { - for (int i = 0; i < content.Length; i++) - { - var nextCharacter = '\0'; - if (i < content.Length - 1) - { - nextCharacter = content[i + 1]; - } - UpdateCharacterCore(content[i], nextCharacter); - } - RecalculateSourceLocation(); - return this; - } - - private void UpdateCharacterCore(char characterRead, char nextCharacter) - { - _absoluteIndex++; - - if (Environment.NewLine.Length == 1 && characterRead == Environment.NewLine[0] || - ParserHelpers.IsNewLine(characterRead) && (characterRead != '\r' || nextCharacter != '\n')) - { - _lineIndex++; - _characterIndex = 0; - } - else - { - _characterIndex++; - } - } - - private void UpdateInternalState() - { - _absoluteIndex = CurrentLocation.AbsoluteIndex; - _characterIndex = CurrentLocation.CharacterIndex; - _lineIndex = CurrentLocation.LineIndex; - } - - private void RecalculateSourceLocation() - { - _currentLocation = new SourceLocation( - _currentLocation.FilePath, - _absoluteIndex, - _lineIndex, - _characterIndex); - } - - public static SourceLocation CalculateNewLocation(SourceLocation lastPosition, string newContent) - { - return new SourceLocationTracker(lastPosition).UpdateLocation(newContent).CurrentLocation; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/SourceSpan.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/SourceSpan.cs deleted file mode 100644 index 147af1be44..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/SourceSpan.cs +++ /dev/null @@ -1,11 +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. - -namespace Microsoft.AspNet.Razor.Text -{ - public class SourceSpan - { - public SourceLocation Begin { get; set; } - public SourceLocation End { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/TextBufferReader.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/TextBufferReader.cs deleted file mode 100644 index 3aa56ffbb4..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/TextBufferReader.cs +++ /dev/null @@ -1,106 +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; -using System.Collections.Generic; -using Microsoft.AspNet.Razor.Utils; - -namespace Microsoft.AspNet.Razor.Text -{ - public class TextBufferReader : LookaheadTextReader - { - private Stack _bookmarks = new Stack(); - private SourceLocationTracker _tracker = new SourceLocationTracker(); - - public TextBufferReader(ITextBuffer buffer) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - - InnerBuffer = buffer; - } - - internal ITextBuffer InnerBuffer { get; private set; } - - public override SourceLocation CurrentLocation - { - get { return _tracker.CurrentLocation; } - } - - public override int Peek() - { - return InnerBuffer.Peek(); - } - - public override int Read() - { - var read = InnerBuffer.Read(); - if (read != -1) - { - var nextChar = '\0'; - var next = Peek(); - if (next != -1) - { - nextChar = (char)next; - } - _tracker.UpdateLocation((char)read, nextChar); - } - return read; - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - var disposable = InnerBuffer as IDisposable; - if (disposable != null) - { - disposable.Dispose(); - } - } - base.Dispose(disposing); - } - - public override IDisposable BeginLookahead() - { - var context = new BacktrackContext() { Location = CurrentLocation }; - _bookmarks.Push(context); - return new DisposableAction(() => - { - EndLookahead(context); - }); - } - - public override void CancelBacktrack() - { - if (_bookmarks.Count == 0) - { - throw new InvalidOperationException(RazorResources.CancelBacktrack_Must_Be_Called_Within_Lookahead); - } - _bookmarks.Pop(); - } - - private void EndLookahead(BacktrackContext context) - { - if (_bookmarks.Count > 0 && ReferenceEquals(_bookmarks.Peek(), context)) - { - // Backtrack wasn't cancelled, so pop it - _bookmarks.Pop(); - - // Set the new current location - _tracker.CurrentLocation = context.Location; - InnerBuffer.Position = context.Location.AbsoluteIndex; - } - } - - /// - /// Need a class for reference equality to support cancelling backtrack. - /// - private class BacktrackContext - { - public SourceLocation Location { get; set; } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/TextChange.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/TextChange.cs deleted file mode 100644 index ec432b6a4b..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/TextChange.cs +++ /dev/null @@ -1,253 +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; -using System.Diagnostics; -using System.Globalization; -using System.Text; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Text -{ - public struct TextChange - { - private string _newText; - private string _oldText; - - /// - /// Constructor for changes where the position hasn't moved (primarily for tests) - /// - internal TextChange(int position, int oldLength, ITextBuffer oldBuffer, int newLength, ITextBuffer newBuffer) - : this(position, oldLength, oldBuffer, position, newLength, newBuffer) - { - } - - public TextChange( - int oldPosition, - int oldLength, - ITextBuffer oldBuffer, - int newPosition, - int newLength, - ITextBuffer newBuffer) - : this() - { - if (oldBuffer == null) - { - throw new ArgumentNullException(nameof(oldBuffer)); - } - - if (newBuffer == null) - { - throw new ArgumentNullException(nameof(newBuffer)); - } - - if (oldPosition < 0) - { - throw new ArgumentOutOfRangeException(nameof(oldPosition), CommonResources.FormatArgument_Must_Be_GreaterThanOrEqualTo(0)); - } - if (newPosition < 0) - { - throw new ArgumentOutOfRangeException(nameof(newPosition), CommonResources.FormatArgument_Must_Be_GreaterThanOrEqualTo(0)); - } - if (oldLength < 0) - { - throw new ArgumentOutOfRangeException(nameof(oldLength), CommonResources.FormatArgument_Must_Be_GreaterThanOrEqualTo(0)); - } - if (newLength < 0) - { - throw new ArgumentOutOfRangeException(nameof(newLength), CommonResources.FormatArgument_Must_Be_GreaterThanOrEqualTo(0)); - } - - OldPosition = oldPosition; - NewPosition = newPosition; - OldLength = oldLength; - NewLength = newLength; - NewBuffer = newBuffer; - OldBuffer = oldBuffer; - } - - public int OldPosition { get; } - - public int NewPosition { get; } - - public int OldLength { get; } - - public int NewLength { get; } - - public ITextBuffer NewBuffer { get; } - - public ITextBuffer OldBuffer { get; } - - /// - /// Note: This property is not thread safe, and will move position on the textbuffer while being read. - /// https://aspnetwebstack.codeplex.com/workitem/1317, tracks making this immutable and improving the access - /// to ITextBuffer to be thread safe. - /// - public string OldText - { - get - { - if (_oldText == null && OldBuffer != null) - { - _oldText = GetText(OldBuffer, OldPosition, OldLength); - } - return _oldText; - } - } - - /// - /// Note: This property is not thread safe, and will move position on the textbuffer while being read. - /// https://aspnetwebstack.codeplex.com/workitem/1317, tracks making this immutable and improving the access - /// to ITextBuffer to be thread safe. - /// - public string NewText - { - get - { - if (_newText == null) - { - _newText = GetText(NewBuffer, NewPosition, NewLength); - } - return _newText; - } - } - - public bool IsInsert - { - get { return OldLength == 0 && NewLength > 0; } - } - - public bool IsDelete - { - get { return OldLength > 0 && NewLength == 0; } - } - - public bool IsReplace - { - get { return OldLength > 0 && NewLength > 0; } - } - - public override bool Equals(object obj) - { - if (!(obj is TextChange)) - { - return false; - } - - var change = (TextChange)obj; - return change.OldPosition == OldPosition && - change.NewPosition == NewPosition && - change.OldLength == OldLength && - change.NewLength == NewLength && - OldBuffer.Equals(change.OldBuffer) && - NewBuffer.Equals(change.NewBuffer); - } - - public override int GetHashCode() - { - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(OldPosition); - hashCodeCombiner.Add(NewPosition); - hashCodeCombiner.Add(OldLength); - hashCodeCombiner.Add(NewLength); - hashCodeCombiner.Add(OldBuffer); - hashCodeCombiner.Add(NewBuffer); - - return hashCodeCombiner; - } - - public string ApplyChange(string content, int changeOffset) - { - var changeRelativePosition = OldPosition - changeOffset; - - Debug.Assert(changeRelativePosition >= 0); - return content.Remove(changeRelativePosition, OldLength) - .Insert(changeRelativePosition, NewText); - } - - /// - /// Applies the text change to the content of the span and returns the new content. - /// This method doesn't update the span content. - /// - public string ApplyChange(Span span) - { - return ApplyChange(span.Content, span.Start.AbsoluteIndex); - } - - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "({0}:{1}) \"{3}\" -> ({0}:{2}) \"{4}\"", OldPosition, OldLength, NewLength, OldText, NewText); - } - - /// - /// Removes a common prefix from the edit to turn IntelliSense replacements into insertions where possible - /// - /// A normalized text change - public TextChange Normalize() - { - if (OldBuffer != null && IsReplace && NewLength > OldLength && NewText.StartsWith(OldText, StringComparison.Ordinal) && NewPosition == OldPosition) - { - // Normalize the change into an insertion of the uncommon suffix (i.e. strip out the common prefix) - return new TextChange(oldPosition: OldPosition + OldLength, - oldLength: 0, - oldBuffer: OldBuffer, - newPosition: OldPosition + OldLength, - newLength: NewLength - OldLength, - newBuffer: NewBuffer); - } - return this; - } - - private static string GetText(ITextBuffer buffer, int position, int length) - { - // Optimization for the common case of one char inserts, in this case we don't even need to seek the buffer. - if (length == 0) - { - return string.Empty; - } - - var oldPosition = buffer.Position; - try - { - buffer.Position = position; - - // Optimization for the common case of one char inserts, in this case we seek the buffer. - if (length == 1) - { - return ((char)buffer.Read()).ToString(); - } - else - { - var builder = new StringBuilder(); - for (int i = 0; i < length; i++) - { - var c = (char)buffer.Read(); - builder.Append(c); - - // This check is probably not necessary, will revisit when fixing https://aspnetwebstack.codeplex.com/workitem/1317 - if (Char.IsHighSurrogate(c)) - { - builder.Append((char)buffer.Read()); - } - } - return builder.ToString(); - } - } - finally - { - buffer.Position = oldPosition; - } - } - - public static bool operator ==(TextChange left, TextChange right) - { - return left.Equals(right); - } - - public static bool operator !=(TextChange left, TextChange right) - { - return !left.Equals(right); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/TextChangeType.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/TextChangeType.cs deleted file mode 100644 index 84ec14124f..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/TextChangeType.cs +++ /dev/null @@ -1,11 +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. - -namespace Microsoft.AspNet.Razor.Text -{ - public enum TextChangeType - { - Insert, - Remove - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/TextDocumentReader.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/TextDocumentReader.cs deleted file mode 100644 index 1ce682ce2c..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/TextDocumentReader.cs +++ /dev/null @@ -1,43 +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.IO; - -namespace Microsoft.AspNet.Razor.Text -{ - public class TextDocumentReader : TextReader, ITextDocument - { - public TextDocumentReader(ITextDocument source) - { - Document = source; - } - - internal ITextDocument Document { get; private set; } - - public SourceLocation Location - { - get { return Document.Location; } - } - - public int Length - { - get { return Document.Length; } - } - - public int Position - { - get { return Document.Position; } - set { Document.Position = value; } - } - - public override int Read() - { - return Document.Read(); - } - - public override int Peek() - { - return Document.Peek(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Text/TextExtensions.cs b/src/Microsoft.AspNet.Razor.VSRC1/Text/TextExtensions.cs deleted file mode 100644 index 5724df4751..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Text/TextExtensions.cs +++ /dev/null @@ -1,47 +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.Diagnostics.CodeAnalysis; -using System.Text; - -namespace Microsoft.AspNet.Razor.Text -{ - internal static class TextExtensions - { - public static void Seek(this ITextBuffer self, int characters) - { - self.Position += characters; - } - - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The consumer is expected to dispose this object")] - public static ITextDocument ToDocument(this ITextBuffer self) - { - var ret = self as ITextDocument; - if (ret == null) - { - ret = new SeekableTextReader(self); - } - return ret; - } - - public static LookaheadToken BeginLookahead(this ITextBuffer self) - { - var start = self.Position; - return new LookaheadToken(() => - { - self.Position = start; - }); - } - - public static string ReadToEnd(this ITextBuffer self) - { - var builder = new StringBuilder(); - int read; - while ((read = self.Read()) != -1) - { - builder.Append((char)read); - } - return builder.ToString(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/CSharpHelpers.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/CSharpHelpers.cs deleted file mode 100644 index 44c891ca4e..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/CSharpHelpers.cs +++ /dev/null @@ -1,46 +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; -using System.Globalization; - -namespace Microsoft.AspNet.Razor.Tokenizer -{ - public static class CSharpHelpers - { - // CSharp Spec §2.4.2 - public static bool IsIdentifierStart(char character) - { - return Char.IsLetter(character) || - character == '_' || - CharUnicodeInfo.GetUnicodeCategory(character) == UnicodeCategory.LetterNumber; - } - - public static bool IsIdentifierPart(char character) - { - return Char.IsDigit(character) || - IsIdentifierStart(character) || - IsIdentifierPartByUnicodeCategory(character); - } - - public static bool IsRealLiteralSuffix(char character) - { - return character == 'F' || - character == 'f' || - character == 'D' || - character == 'd' || - character == 'M' || - character == 'm'; - } - - private static bool IsIdentifierPartByUnicodeCategory(char character) - { - var category = CharUnicodeInfo.GetUnicodeCategory(character); - - return category == UnicodeCategory.NonSpacingMark || // Mn - category == UnicodeCategory.SpacingCombiningMark || // Mc - category == UnicodeCategory.ConnectorPunctuation || // Pc - category == UnicodeCategory.Format; // Cf - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/CSharpKeywordDetector.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/CSharpKeywordDetector.cs deleted file mode 100644 index 02b7fd8111..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/CSharpKeywordDetector.cs +++ /dev/null @@ -1,105 +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; -using System.Collections.Generic; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Tokenizer -{ - internal static class CSharpKeywordDetector - { - private static readonly Dictionary _keywords = new Dictionary(StringComparer.Ordinal) - { - { "await", CSharpKeyword.Await }, - { "abstract", CSharpKeyword.Abstract }, - { "byte", CSharpKeyword.Byte }, - { "class", CSharpKeyword.Class }, - { "delegate", CSharpKeyword.Delegate }, - { "event", CSharpKeyword.Event }, - { "fixed", CSharpKeyword.Fixed }, - { "if", CSharpKeyword.If }, - { "internal", CSharpKeyword.Internal }, - { "new", CSharpKeyword.New }, - { "override", CSharpKeyword.Override }, - { "readonly", CSharpKeyword.Readonly }, - { "short", CSharpKeyword.Short }, - { "struct", CSharpKeyword.Struct }, - { "try", CSharpKeyword.Try }, - { "unsafe", CSharpKeyword.Unsafe }, - { "volatile", CSharpKeyword.Volatile }, - { "as", CSharpKeyword.As }, - { "do", CSharpKeyword.Do }, - { "is", CSharpKeyword.Is }, - { "params", CSharpKeyword.Params }, - { "ref", CSharpKeyword.Ref }, - { "switch", CSharpKeyword.Switch }, - { "ushort", CSharpKeyword.Ushort }, - { "while", CSharpKeyword.While }, - { "case", CSharpKeyword.Case }, - { "const", CSharpKeyword.Const }, - { "explicit", CSharpKeyword.Explicit }, - { "float", CSharpKeyword.Float }, - { "null", CSharpKeyword.Null }, - { "sizeof", CSharpKeyword.Sizeof }, - { "typeof", CSharpKeyword.Typeof }, - { "implicit", CSharpKeyword.Implicit }, - { "private", CSharpKeyword.Private }, - { "this", CSharpKeyword.This }, - { "using", CSharpKeyword.Using }, - { "extern", CSharpKeyword.Extern }, - { "return", CSharpKeyword.Return }, - { "stackalloc", CSharpKeyword.Stackalloc }, - { "uint", CSharpKeyword.Uint }, - { "base", CSharpKeyword.Base }, - { "catch", CSharpKeyword.Catch }, - { "continue", CSharpKeyword.Continue }, - { "double", CSharpKeyword.Double }, - { "for", CSharpKeyword.For }, - { "in", CSharpKeyword.In }, - { "lock", CSharpKeyword.Lock }, - { "object", CSharpKeyword.Object }, - { "protected", CSharpKeyword.Protected }, - { "static", CSharpKeyword.Static }, - { "false", CSharpKeyword.False }, - { "public", CSharpKeyword.Public }, - { "sbyte", CSharpKeyword.Sbyte }, - { "throw", CSharpKeyword.Throw }, - { "virtual", CSharpKeyword.Virtual }, - { "decimal", CSharpKeyword.Decimal }, - { "else", CSharpKeyword.Else }, - { "operator", CSharpKeyword.Operator }, - { "string", CSharpKeyword.String }, - { "ulong", CSharpKeyword.Ulong }, - { "bool", CSharpKeyword.Bool }, - { "char", CSharpKeyword.Char }, - { "default", CSharpKeyword.Default }, - { "foreach", CSharpKeyword.Foreach }, - { "long", CSharpKeyword.Long }, - { "void", CSharpKeyword.Void }, - { "enum", CSharpKeyword.Enum }, - { "finally", CSharpKeyword.Finally }, - { "int", CSharpKeyword.Int }, - { "out", CSharpKeyword.Out }, - { "sealed", CSharpKeyword.Sealed }, - { "true", CSharpKeyword.True }, - { "goto", CSharpKeyword.Goto }, - { "unchecked", CSharpKeyword.Unchecked }, - { "interface", CSharpKeyword.Interface }, - { "break", CSharpKeyword.Break }, - { "checked", CSharpKeyword.Checked }, - { "namespace", CSharpKeyword.Namespace }, - { "when", CSharpKeyword.When } - }; - - public static CSharpKeyword? SymbolTypeForIdentifier(string id) - { - CSharpKeyword type; - if (!_keywords.TryGetValue(id, out type)) - { - return null; - } - return type; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/CSharpTokenizer.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/CSharpTokenizer.cs deleted file mode 100644 index bfc191b5de..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/CSharpTokenizer.cs +++ /dev/null @@ -1,449 +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; -using System.Collections.Generic; -using System.Diagnostics; -using Microsoft.AspNet.Razor.Parser; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Tokenizer -{ - public class CSharpTokenizer : Tokenizer - { - private Dictionary> _operatorHandlers; - - public CSharpTokenizer(ITextDocument source) - : base(source) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - CurrentState = Data; - - _operatorHandlers = new Dictionary>() - { - { '-', MinusOperator }, - { '<', LessThanOperator }, - { '>', GreaterThanOperator }, - { '&', CreateTwoCharOperatorHandler(CSharpSymbolType.And, '=', CSharpSymbolType.AndAssign, '&', CSharpSymbolType.DoubleAnd) }, - { '|', CreateTwoCharOperatorHandler(CSharpSymbolType.Or, '=', CSharpSymbolType.OrAssign, '|', CSharpSymbolType.DoubleOr) }, - { '+', CreateTwoCharOperatorHandler(CSharpSymbolType.Plus, '=', CSharpSymbolType.PlusAssign, '+', CSharpSymbolType.Increment) }, - { '=', CreateTwoCharOperatorHandler(CSharpSymbolType.Assign, '=', CSharpSymbolType.Equals, '>', CSharpSymbolType.GreaterThanEqual) }, - { '!', CreateTwoCharOperatorHandler(CSharpSymbolType.Not, '=', CSharpSymbolType.NotEqual) }, - { '%', CreateTwoCharOperatorHandler(CSharpSymbolType.Modulo, '=', CSharpSymbolType.ModuloAssign) }, - { '*', CreateTwoCharOperatorHandler(CSharpSymbolType.Star, '=', CSharpSymbolType.MultiplyAssign) }, - { ':', CreateTwoCharOperatorHandler(CSharpSymbolType.Colon, ':', CSharpSymbolType.DoubleColon) }, - { '?', CreateTwoCharOperatorHandler(CSharpSymbolType.QuestionMark, '?', CSharpSymbolType.NullCoalesce) }, - { '^', CreateTwoCharOperatorHandler(CSharpSymbolType.Xor, '=', CSharpSymbolType.XorAssign) }, - { '(', () => CSharpSymbolType.LeftParenthesis }, - { ')', () => CSharpSymbolType.RightParenthesis }, - { '{', () => CSharpSymbolType.LeftBrace }, - { '}', () => CSharpSymbolType.RightBrace }, - { '[', () => CSharpSymbolType.LeftBracket }, - { ']', () => CSharpSymbolType.RightBracket }, - { ',', () => CSharpSymbolType.Comma }, - { ';', () => CSharpSymbolType.Semicolon }, - { '~', () => CSharpSymbolType.Tilde }, - { '#', () => CSharpSymbolType.Hash } - }; - } - - protected override State StartState - { - get { return Data; } - } - - public override CSharpSymbolType RazorCommentType - { - get { return CSharpSymbolType.RazorComment; } - } - - public override CSharpSymbolType RazorCommentTransitionType - { - get { return CSharpSymbolType.RazorCommentTransition; } - } - - public override CSharpSymbolType RazorCommentStarType - { - get { return CSharpSymbolType.RazorCommentStar; } - } - - protected override CSharpSymbol CreateSymbol(SourceLocation start, string content, CSharpSymbolType type, IEnumerable errors) - { - return new CSharpSymbol(start, content, type, errors); - } - - private StateResult Data() - { - if (ParserHelpers.IsNewLine(CurrentCharacter)) - { - // CSharp Spec §2.3.1 - var checkTwoCharNewline = CurrentCharacter == '\r'; - TakeCurrent(); - if (checkTwoCharNewline && CurrentCharacter == '\n') - { - TakeCurrent(); - } - return Stay(EndSymbol(CSharpSymbolType.NewLine)); - } - else if (ParserHelpers.IsWhitespace(CurrentCharacter)) - { - // CSharp Spec §2.3.3 - TakeUntil(c => !ParserHelpers.IsWhitespace(c)); - return Stay(EndSymbol(CSharpSymbolType.WhiteSpace)); - } - else if (CSharpHelpers.IsIdentifierStart(CurrentCharacter)) - { - return Identifier(); - } - else if (Char.IsDigit(CurrentCharacter)) - { - return NumericLiteral(); - } - switch (CurrentCharacter) - { - case '@': - return AtSymbol(); - case '\'': - TakeCurrent(); - return Transition(() => QuotedLiteral('\'', CSharpSymbolType.CharacterLiteral)); - case '"': - TakeCurrent(); - return Transition(() => QuotedLiteral('"', CSharpSymbolType.StringLiteral)); - case '.': - if (Char.IsDigit(Peek())) - { - return RealLiteral(); - } - return Stay(Single(CSharpSymbolType.Dot)); - case '/': - TakeCurrent(); - if (CurrentCharacter == '/') - { - TakeCurrent(); - return SingleLineComment(); - } - else if (CurrentCharacter == '*') - { - TakeCurrent(); - return Transition(BlockComment); - } - else if (CurrentCharacter == '=') - { - TakeCurrent(); - return Stay(EndSymbol(CSharpSymbolType.DivideAssign)); - } - else - { - return Stay(EndSymbol(CSharpSymbolType.Slash)); - } - default: - return Stay(EndSymbol(Operator())); - } - } - - private StateResult AtSymbol() - { - TakeCurrent(); - if (CurrentCharacter == '"') - { - TakeCurrent(); - return Transition(VerbatimStringLiteral); - } - else if (CurrentCharacter == '*') - { - return Transition(EndSymbol(CSharpSymbolType.RazorCommentTransition), AfterRazorCommentTransition); - } - else if (CurrentCharacter == '@') - { - // Could be escaped comment transition - return Transition(EndSymbol(CSharpSymbolType.Transition), () => - { - TakeCurrent(); - return Transition(EndSymbol(CSharpSymbolType.Transition), Data); - }); - } - return Stay(EndSymbol(CSharpSymbolType.Transition)); - } - - private CSharpSymbolType Operator() - { - var first = CurrentCharacter; - TakeCurrent(); - Func handler; - if (_operatorHandlers.TryGetValue(first, out handler)) - { - return handler(); - } - return CSharpSymbolType.Unknown; - } - - private CSharpSymbolType LessThanOperator() - { - if (CurrentCharacter == '=') - { - TakeCurrent(); - return CSharpSymbolType.LessThanEqual; - } - return CSharpSymbolType.LessThan; - } - - private CSharpSymbolType GreaterThanOperator() - { - if (CurrentCharacter == '=') - { - TakeCurrent(); - return CSharpSymbolType.GreaterThanEqual; - } - return CSharpSymbolType.GreaterThan; - } - - private CSharpSymbolType MinusOperator() - { - if (CurrentCharacter == '>') - { - TakeCurrent(); - return CSharpSymbolType.Arrow; - } - else if (CurrentCharacter == '-') - { - TakeCurrent(); - return CSharpSymbolType.Decrement; - } - else if (CurrentCharacter == '=') - { - TakeCurrent(); - return CSharpSymbolType.MinusAssign; - } - return CSharpSymbolType.Minus; - } - - private Func CreateTwoCharOperatorHandler(CSharpSymbolType typeIfOnlyFirst, char second, CSharpSymbolType typeIfBoth) - { - return () => - { - if (CurrentCharacter == second) - { - TakeCurrent(); - return typeIfBoth; - } - return typeIfOnlyFirst; - }; - } - - private Func CreateTwoCharOperatorHandler(CSharpSymbolType typeIfOnlyFirst, char option1, CSharpSymbolType typeIfOption1, char option2, CSharpSymbolType typeIfOption2) - { - return () => - { - if (CurrentCharacter == option1) - { - TakeCurrent(); - return typeIfOption1; - } - else if (CurrentCharacter == option2) - { - TakeCurrent(); - return typeIfOption2; - } - return typeIfOnlyFirst; - }; - } - - private StateResult VerbatimStringLiteral() - { - TakeUntil(c => c == '"'); - if (CurrentCharacter == '"') - { - TakeCurrent(); - if (CurrentCharacter == '"') - { - TakeCurrent(); - // Stay in the literal, this is an escaped " - return Stay(); - } - } - else if (EndOfFile) - { - CurrentErrors.Add( - new RazorError( - RazorResources.ParseError_Unterminated_String_Literal, - CurrentStart, - length: 1 /* end of file */)); - } - return Transition(EndSymbol(CSharpSymbolType.StringLiteral), Data); - } - - private StateResult QuotedLiteral(char quote, CSharpSymbolType literalType) - { - TakeUntil(c => c == '\\' || c == quote || ParserHelpers.IsNewLine(c)); - if (CurrentCharacter == '\\') - { - TakeCurrent(); // Take the '\' - - // If the next char is the same quote that started this - if (CurrentCharacter == quote || CurrentCharacter == '\\') - { - TakeCurrent(); // Take it so that we don't prematurely end the literal. - } - return Stay(); - } - else if (EndOfFile || ParserHelpers.IsNewLine(CurrentCharacter)) - { - CurrentErrors.Add( - new RazorError( - RazorResources.ParseError_Unterminated_String_Literal, - CurrentStart, - length: 1 /* " */)); - } - else - { - TakeCurrent(); // No-op if at EOF - } - return Transition(EndSymbol(literalType), Data); - } - - // CSharp Spec §2.3.2 - private StateResult BlockComment() - { - TakeUntil(c => c == '*'); - if (EndOfFile) - { - CurrentErrors.Add( - new RazorError( - RazorResources.ParseError_BlockComment_Not_Terminated, - CurrentStart, - length: 1 /* end of file */)); - return Transition(EndSymbol(CSharpSymbolType.Comment), Data); - } - if (CurrentCharacter == '*') - { - TakeCurrent(); - if (CurrentCharacter == '/') - { - TakeCurrent(); - return Transition(EndSymbol(CSharpSymbolType.Comment), Data); - } - } - return Stay(); - } - - // CSharp Spec §2.3.2 - private StateResult SingleLineComment() - { - TakeUntil(c => ParserHelpers.IsNewLine(c)); - return Stay(EndSymbol(CSharpSymbolType.Comment)); - } - - // CSharp Spec §2.4.4 - private StateResult NumericLiteral() - { - if (TakeAll("0x", caseSensitive: true)) - { - return HexLiteral(); - } - else - { - return DecimalLiteral(); - } - } - - private StateResult HexLiteral() - { - TakeUntil(c => !ParserHelpers.IsHexDigit(c)); - TakeIntegerSuffix(); - return Stay(EndSymbol(CSharpSymbolType.IntegerLiteral)); - } - - private StateResult DecimalLiteral() - { - TakeUntil(c => !Char.IsDigit(c)); - if (CurrentCharacter == '.' && Char.IsDigit(Peek())) - { - return RealLiteral(); - } - else if (CSharpHelpers.IsRealLiteralSuffix(CurrentCharacter) || - CurrentCharacter == 'E' || CurrentCharacter == 'e') - { - return RealLiteralExponentPart(); - } - else - { - TakeIntegerSuffix(); - return Stay(EndSymbol(CSharpSymbolType.IntegerLiteral)); - } - } - - private StateResult RealLiteralExponentPart() - { - if (CurrentCharacter == 'E' || CurrentCharacter == 'e') - { - TakeCurrent(); - if (CurrentCharacter == '+' || CurrentCharacter == '-') - { - TakeCurrent(); - } - TakeUntil(c => !Char.IsDigit(c)); - } - if (CSharpHelpers.IsRealLiteralSuffix(CurrentCharacter)) - { - TakeCurrent(); - } - return Stay(EndSymbol(CSharpSymbolType.RealLiteral)); - } - - // CSharp Spec §2.4.4.3 - private StateResult RealLiteral() - { - AssertCurrent('.'); - TakeCurrent(); - Debug.Assert(Char.IsDigit(CurrentCharacter)); - TakeUntil(c => !Char.IsDigit(c)); - return RealLiteralExponentPart(); - } - - private void TakeIntegerSuffix() - { - if (Char.ToLowerInvariant(CurrentCharacter) == 'u') - { - TakeCurrent(); - if (Char.ToLowerInvariant(CurrentCharacter) == 'l') - { - TakeCurrent(); - } - } - else if (Char.ToLowerInvariant(CurrentCharacter) == 'l') - { - TakeCurrent(); - if (Char.ToLowerInvariant(CurrentCharacter) == 'u') - { - TakeCurrent(); - } - } - } - - // CSharp Spec §2.4.2 - private StateResult Identifier() - { - Debug.Assert(CSharpHelpers.IsIdentifierStart(CurrentCharacter)); - TakeCurrent(); - TakeUntil(c => !CSharpHelpers.IsIdentifierPart(c)); - CSharpSymbol sym = null; - if (HaveContent) - { - var kwd = CSharpKeywordDetector.SymbolTypeForIdentifier(Buffer.ToString()); - var type = CSharpSymbolType.Identifier; - if (kwd != null) - { - type = CSharpSymbolType.Keyword; - } - sym = new CSharpSymbol(CurrentStart, Buffer.ToString(), type) { Keyword = kwd }; - } - StartSymbol(); - return Stay(sym); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/HtmlTokenizer.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/HtmlTokenizer.cs deleted file mode 100644 index 74a3d784df..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/HtmlTokenizer.cs +++ /dev/null @@ -1,211 +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; -using System.Collections.Generic; -using System.Diagnostics; -using Microsoft.AspNet.Razor.Parser; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Tokenizer -{ - // Tokenizer _loosely_ based on http://dev.w3.org/html5/spec/Overview.html#tokenization - public class HtmlTokenizer : Tokenizer - { - private const char TransitionChar = '@'; - - public HtmlTokenizer(ITextDocument source) - : base(source) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - CurrentState = Data; - } - - protected override State StartState - { - get { return Data; } - } - - public override HtmlSymbolType RazorCommentType - { - get { return HtmlSymbolType.RazorComment; } - } - - public override HtmlSymbolType RazorCommentTransitionType - { - get { return HtmlSymbolType.RazorCommentTransition; } - } - - public override HtmlSymbolType RazorCommentStarType - { - get { return HtmlSymbolType.RazorCommentStar; } - } - - internal static IEnumerable Tokenize(string content) - { - using (SeekableTextReader reader = new SeekableTextReader(content)) - { - var tok = new HtmlTokenizer(reader); - HtmlSymbol sym; - while ((sym = tok.NextSymbol()) != null) - { - yield return sym; - } - } - } - - protected override HtmlSymbol CreateSymbol(SourceLocation start, string content, HtmlSymbolType type, IEnumerable errors) - { - return new HtmlSymbol(start, content, type, errors); - } - - // http://dev.w3.org/html5/spec/Overview.html#data-state - private StateResult Data() - { - if (ParserHelpers.IsWhitespace(CurrentCharacter)) - { - return Stay(Whitespace()); - } - else if (ParserHelpers.IsNewLine(CurrentCharacter)) - { - return Stay(Newline()); - } - else if (CurrentCharacter == '@') - { - TakeCurrent(); - if (CurrentCharacter == '*') - { - return Transition(EndSymbol(HtmlSymbolType.RazorCommentTransition), AfterRazorCommentTransition); - } - else if (CurrentCharacter == '@') - { - // Could be escaped comment transition - return Transition(EndSymbol(HtmlSymbolType.Transition), () => - { - TakeCurrent(); - return Transition(EndSymbol(HtmlSymbolType.Transition), Data); - }); - } - return Stay(EndSymbol(HtmlSymbolType.Transition)); - } - else if (AtSymbol()) - { - return Stay(Symbol()); - } - else - { - return Transition(Text); - } - } - - private StateResult Text() - { - var prev = '\0'; - while (!EndOfFile && !ParserHelpers.IsWhitespaceOrNewLine(CurrentCharacter) && !AtSymbol()) - { - prev = CurrentCharacter; - TakeCurrent(); - } - - if (CurrentCharacter == '@') - { - var next = Peek(); - if (ParserHelpers.IsLetterOrDecimalDigit(prev) && ParserHelpers.IsLetterOrDecimalDigit(next)) - { - TakeCurrent(); // Take the "@" - return Stay(); // Stay in the Text state - } - } - - // Output the Text token and return to the Data state to tokenize the next character (if there is one) - return Transition(EndSymbol(HtmlSymbolType.Text), Data); - } - - private HtmlSymbol Symbol() - { - Debug.Assert(AtSymbol()); - var sym = CurrentCharacter; - TakeCurrent(); - switch (sym) - { - case '<': - return EndSymbol(HtmlSymbolType.OpenAngle); - case '!': - return EndSymbol(HtmlSymbolType.Bang); - case '/': - return EndSymbol(HtmlSymbolType.ForwardSlash); - case '?': - return EndSymbol(HtmlSymbolType.QuestionMark); - case '[': - return EndSymbol(HtmlSymbolType.LeftBracket); - case '>': - return EndSymbol(HtmlSymbolType.CloseAngle); - case ']': - return EndSymbol(HtmlSymbolType.RightBracket); - case '=': - return EndSymbol(HtmlSymbolType.Equals); - case '"': - return EndSymbol(HtmlSymbolType.DoubleQuote); - case '\'': - return EndSymbol(HtmlSymbolType.SingleQuote); - case '-': - Debug.Assert(CurrentCharacter == '-'); - TakeCurrent(); - return EndSymbol(HtmlSymbolType.DoubleHyphen); - default: -#if NET451 - // No Debug.Fail in CoreCLR - - Debug.Fail("Unexpected symbol!"); -#else - Debug.Assert(false, "Unexpected symbol"); -#endif - return EndSymbol(HtmlSymbolType.Unknown); - } - } - - private HtmlSymbol Whitespace() - { - while (ParserHelpers.IsWhitespace(CurrentCharacter)) - { - TakeCurrent(); - } - return EndSymbol(HtmlSymbolType.WhiteSpace); - } - - private HtmlSymbol Newline() - { - Debug.Assert(ParserHelpers.IsNewLine(CurrentCharacter)); - // CSharp Spec §2.3.1 - var checkTwoCharNewline = CurrentCharacter == '\r'; - TakeCurrent(); - if (checkTwoCharNewline && CurrentCharacter == '\n') - { - TakeCurrent(); - } - return EndSymbol(HtmlSymbolType.NewLine); - } - - private bool AtSymbol() - { - return CurrentCharacter == '<' || - CurrentCharacter == '<' || - CurrentCharacter == '!' || - CurrentCharacter == '/' || - CurrentCharacter == '?' || - CurrentCharacter == '[' || - CurrentCharacter == '>' || - CurrentCharacter == ']' || - CurrentCharacter == '=' || - CurrentCharacter == '"' || - CurrentCharacter == '\'' || - CurrentCharacter == '@' || - (CurrentCharacter == '-' && Peek() == '-'); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/ITokenizer.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/ITokenizer.cs deleted file mode 100644 index 00c6f10805..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/ITokenizer.cs +++ /dev/null @@ -1,12 +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 Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Tokenizer -{ - public interface ITokenizer - { - ISymbol NextSymbol(); - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/CSharpKeyword.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/CSharpKeyword.cs deleted file mode 100644 index e5a397ceaf..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/CSharpKeyword.cs +++ /dev/null @@ -1,88 +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. - -namespace Microsoft.AspNet.Razor.Tokenizer.Symbols -{ - public enum CSharpKeyword - { - Await, - Abstract, - Byte, - Class, - Delegate, - Event, - Fixed, - If, - Internal, - New, - Override, - Readonly, - Short, - Struct, - Try, - Unsafe, - Volatile, - As, - Do, - Is, - Params, - Ref, - Switch, - Ushort, - While, - Case, - Const, - Explicit, - Float, - Null, - Sizeof, - Typeof, - Implicit, - Private, - This, - Using, - Extern, - Return, - Stackalloc, - Uint, - Base, - Catch, - Continue, - Double, - For, - In, - Lock, - Object, - Protected, - Static, - False, - Public, - Sbyte, - Throw, - Virtual, - Decimal, - Else, - Operator, - String, - Ulong, - Bool, - Char, - Default, - Foreach, - Long, - Void, - Enum, - Finally, - Int, - Out, - Sealed, - True, - Goto, - Unchecked, - Interface, - Break, - Checked, - Namespace, - When - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/CSharpSymbol.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/CSharpSymbol.cs deleted file mode 100644 index 4cc9acd2c6..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/CSharpSymbol.cs +++ /dev/null @@ -1,74 +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; -using System.Collections.Generic; -using System.Linq; - -namespace Microsoft.AspNet.Razor.Tokenizer.Symbols -{ - public class CSharpSymbol : SymbolBase - { - // Helper constructor - public CSharpSymbol(int offset, int line, int column, string content, CSharpSymbolType type) - : this(new SourceLocation(offset, line, column), content, type, Enumerable.Empty()) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - } - - public CSharpSymbol(SourceLocation start, string content, CSharpSymbolType type) - : this(start, content, type, Enumerable.Empty()) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - } - - public CSharpSymbol( - int offset, - int line, - int column, - string content, - CSharpSymbolType type, - IEnumerable errors) - : base(new SourceLocation(offset, line, column), content, type, errors) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - } - - public CSharpSymbol( - SourceLocation start, - string content, - CSharpSymbolType type, - IEnumerable errors) - : base(start, content, type, errors) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - } - - public bool? EscapedIdentifier { get; set; } - public CSharpKeyword? Keyword { get; set; } - - public override bool Equals(object obj) - { - var other = obj as CSharpSymbol; - return base.Equals(other) && other.Keyword == Keyword; - } - - public override int GetHashCode() - { - // Hash code should include only immutable properties. - return base.GetHashCode(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/CSharpSymbolType.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/CSharpSymbolType.cs deleted file mode 100644 index b221ccb195..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/CSharpSymbolType.cs +++ /dev/null @@ -1,75 +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. - -namespace Microsoft.AspNet.Razor.Tokenizer.Symbols -{ - public enum CSharpSymbolType - { - Unknown, - Identifier, - Keyword, - IntegerLiteral, - NewLine, - WhiteSpace, - Comment, - RealLiteral, - CharacterLiteral, - StringLiteral, - - // Operators - Arrow, - Minus, - Decrement, - MinusAssign, - NotEqual, - Not, - Modulo, - ModuloAssign, - AndAssign, - And, - DoubleAnd, - LeftParenthesis, - RightParenthesis, - Star, - MultiplyAssign, - Comma, - Dot, - Slash, - DivideAssign, - DoubleColon, - Colon, - Semicolon, - QuestionMark, - NullCoalesce, - RightBracket, - LeftBracket, - XorAssign, - Xor, - LeftBrace, - OrAssign, - DoubleOr, - Or, - RightBrace, - Tilde, - Plus, - PlusAssign, - Increment, - LessThan, - LessThanEqual, - LeftShift, - LeftShiftAssign, - Assign, - Equals, - GreaterThan, - GreaterThanEqual, - RightShift, - RightShiftAssign, - Hash, - Transition, - - // Razor specific - RazorCommentTransition, - RazorCommentStar, - RazorComment - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/HtmlSymbol.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/HtmlSymbol.cs deleted file mode 100644 index e7b4c7e881..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/HtmlSymbol.cs +++ /dev/null @@ -1,59 +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; -using System.Collections.Generic; -using System.Linq; - -namespace Microsoft.AspNet.Razor.Tokenizer.Symbols -{ - public class HtmlSymbol : SymbolBase - { - // Helper constructor - public HtmlSymbol(int offset, int line, int column, string content, HtmlSymbolType type) - : this(new SourceLocation(offset, line, column), content, type, Enumerable.Empty()) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - } - - public HtmlSymbol(SourceLocation start, string content, HtmlSymbolType type) - : base(start, content, type, Enumerable.Empty()) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - } - - public HtmlSymbol( - int offset, - int line, - int column, - string content, - HtmlSymbolType type, - IEnumerable errors) - : base(new SourceLocation(offset, line, column), content, type, errors) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - } - - public HtmlSymbol( - SourceLocation start, - string content, - HtmlSymbolType type, - IEnumerable errors) - : base(start, content, type, errors) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/HtmlSymbolType.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/HtmlSymbolType.cs deleted file mode 100644 index 27cbd7e590..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/HtmlSymbolType.cs +++ /dev/null @@ -1,32 +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.AspNet.Razor.Tokenizer.Symbols -{ - [Flags] - public enum HtmlSymbolType - { - Unknown, - Text, // Text which isn't one of the below - WhiteSpace, // Non-newline Whitespace - NewLine, // Newline - OpenAngle, // < - Bang, // ! - ForwardSlash, // / - QuestionMark, // ? - DoubleHyphen, // -- - LeftBracket, // [ - CloseAngle, // > - RightBracket, // ] - Equals, // = - DoubleQuote, // " - SingleQuote, // ' - Transition, // @ - Colon, - RazorComment, - RazorCommentStar, - RazorCommentTransition - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/ISymbol.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/ISymbol.cs deleted file mode 100644 index a2bd22041f..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/ISymbol.cs +++ /dev/null @@ -1,14 +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. - -namespace Microsoft.AspNet.Razor.Tokenizer.Symbols -{ - public interface ISymbol - { - SourceLocation Start { get; } - string Content { get; } - - void OffsetStart(SourceLocation documentStart); - void ChangeStart(SourceLocation newStart); - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/KnownSymbolType.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/KnownSymbolType.cs deleted file mode 100644 index bbcdf842fd..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/KnownSymbolType.cs +++ /dev/null @@ -1,18 +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. - -namespace Microsoft.AspNet.Razor.Tokenizer.Symbols -{ - public enum KnownSymbolType - { - WhiteSpace, - NewLine, - Identifier, - Keyword, - Transition, - Unknown, - CommentStart, - CommentStar, - CommentBody - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/SymbolBase.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/SymbolBase.cs deleted file mode 100644 index fca7684a2e..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/SymbolBase.cs +++ /dev/null @@ -1,75 +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; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using Microsoft.Extensions.Internal; - -namespace Microsoft.AspNet.Razor.Tokenizer.Symbols -{ - public abstract class SymbolBase : ISymbol - where TType : struct - { - protected SymbolBase( - SourceLocation start, - string content, - TType type, - IEnumerable errors) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - - Start = start; - Content = content; - Type = type; - Errors = errors; - } - - public SourceLocation Start { get; private set; } - - public string Content { get; } - - public IEnumerable Errors { get; } - - [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "This is the most appropriate name for this property and conflicts are unlikely")] - public TType Type { get; } - - public override bool Equals(object obj) - { - SymbolBase other = obj as SymbolBase; - return other != null && - Start.Equals(other.Start) && - string.Equals(Content, other.Content, StringComparison.Ordinal) && - Type.Equals(other.Type); - } - - public override int GetHashCode() - { - // Hash code should include only immutable properties. - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(Content, StringComparer.Ordinal); - hashCodeCombiner.Add(Type); - - return hashCodeCombiner; - } - - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, "{0} {1} - [{2}]", Start, Type, Content); - } - - public void OffsetStart(SourceLocation documentStart) - { - Start = documentStart + Start; - } - - public void ChangeStart(SourceLocation newStart) - { - Start = newStart; - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/SymbolExtensions.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/SymbolExtensions.cs deleted file mode 100644 index f8ccaf7826..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/SymbolExtensions.cs +++ /dev/null @@ -1,55 +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; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using Microsoft.AspNet.Razor.Parser.SyntaxTree; -using Microsoft.AspNet.Razor.Text; - -namespace Microsoft.AspNet.Razor.Tokenizer.Symbols -{ - public static class SymbolExtensions - { - public static LocationTagged GetContent(this SpanBuilder span) - { - return GetContent(span, e => e); - } - - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Func is the recommended type for generic delegates and requires this level of nesting")] - public static LocationTagged GetContent(this SpanBuilder span, Func, IEnumerable> filter) - { - return GetContent(filter(span.Symbols), span.Start); - } - - public static LocationTagged GetContent(this IEnumerable symbols, SourceLocation spanStart) - { - if (symbols.Any()) - { - return new LocationTagged(string.Concat(symbols.Select(s => s.Content)), spanStart + symbols.First().Start); - } - else - { - return new LocationTagged(string.Empty, spanStart); - } - } - - public static LocationTagged GetContent(this ISymbol symbol) - { - return new LocationTagged(symbol.Content, symbol.Start); - } - - /// - /// Converts the generic to a and - /// finds the first with type . - /// - /// The instance this method extends. - /// The to search for. - /// The first of type . - public static HtmlSymbol FirstHtmlSymbolAs(this IEnumerable symbols, HtmlSymbolType type) - { - return symbols.OfType().FirstOrDefault(sym => (type & sym.Type) == sym.Type); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/SymbolTypeSuppressions.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/SymbolTypeSuppressions.cs deleted file mode 100644 index 4cfba3241e..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Symbols/SymbolTypeSuppressions.cs +++ /dev/null @@ -1,19 +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.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Foreach", Scope = "member", Target = "Microsoft.AspNet.Razor.Tokenizer.Symbols.CSharpKeyword.#Foreach", Justification = Justifications.SymbolTypeNames)] -[assembly: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Readonly", Scope = "member", Target = "Microsoft.AspNet.Razor.Tokenizer.Symbols.CSharpKeyword.#Readonly", Justification = Justifications.SymbolTypeNames)] -[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sbyte", Scope = "member", Target = "Microsoft.AspNet.Razor.Tokenizer.Symbols.CSharpKeyword.#Sbyte", Justification = Justifications.SymbolTypeNames)] -[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sizeof", Scope = "member", Target = "Microsoft.AspNet.Razor.Tokenizer.Symbols.CSharpKeyword.#Sizeof", Justification = Justifications.SymbolTypeNames)] -[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Stackalloc", Scope = "member", Target = "Microsoft.AspNet.Razor.Tokenizer.Symbols.CSharpKeyword.#Stackalloc", Justification = Justifications.SymbolTypeNames)] -[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Typeof", Scope = "member", Target = "Microsoft.AspNet.Razor.Tokenizer.Symbols.CSharpKeyword.#Typeof", Justification = Justifications.SymbolTypeNames)] -[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Uint", Scope = "member", Target = "Microsoft.AspNet.Razor.Tokenizer.Symbols.CSharpKeyword.#Uint", Justification = Justifications.SymbolTypeNames)] -[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ulong", Scope = "member", Target = "Microsoft.AspNet.Razor.Tokenizer.Symbols.CSharpKeyword.#Ulong", Justification = Justifications.SymbolTypeNames)] -[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ushort", Scope = "member", Target = "Microsoft.AspNet.Razor.Tokenizer.Symbols.CSharpKeyword.#Ushort", Justification = Justifications.SymbolTypeNames)] - -internal static partial class Justifications -{ - internal const string SymbolTypeNames = "Symbol Type Names are spelled according to the language keyword or token they represent"; -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Tokenizer.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Tokenizer.cs deleted file mode 100644 index 6d72895aaa..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/Tokenizer.cs +++ /dev/null @@ -1,321 +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; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -#if DEBUG -using System.Globalization; -#endif -using System.Linq; -using System.Text; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Tokenizer -{ - public abstract partial class Tokenizer : StateMachine, ITokenizer - where TSymbolType : struct - where TSymbol : SymbolBase - { - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "TextDocumentReader does not require disposal")] - protected Tokenizer(ITextDocument source) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - Source = new TextDocumentReader(source); - Buffer = new StringBuilder(); - CurrentErrors = new List(); - StartSymbol(); - } - - public TextDocumentReader Source { get; private set; } - - protected StringBuilder Buffer { get; private set; } - - protected bool EndOfFile - { - get { return Source.Peek() == -1; } - } - - protected IList CurrentErrors { get; private set; } - - public abstract TSymbolType RazorCommentStarType { get; } - public abstract TSymbolType RazorCommentType { get; } - public abstract TSymbolType RazorCommentTransitionType { get; } - - protected bool HaveContent - { - get { return Buffer.Length > 0; } - } - - protected char CurrentCharacter - { - get - { - var peek = Source.Peek(); - return peek == -1 ? '\0' : (char)peek; - } - } - - protected SourceLocation CurrentLocation - { - get { return Source.Location; } - } - - protected SourceLocation CurrentStart { get; private set; } - - public virtual TSymbol NextSymbol() - { - // Post-Condition: Buffer should be empty at the start of Next() - Debug.Assert(Buffer.Length == 0); - StartSymbol(); - - if (EndOfFile) - { - return null; - } - var sym = Turn(); - - // Post-Condition: Buffer should be empty at the end of Next() - Debug.Assert(Buffer.Length == 0); - - return sym; - } - - public void Reset() - { - CurrentState = StartState; - } - - protected abstract TSymbol CreateSymbol(SourceLocation start, string content, TSymbolType type, IEnumerable errors); - - protected TSymbol Single(TSymbolType type) - { - TakeCurrent(); - return EndSymbol(type); - } - - protected void StartSymbol() - { - Buffer.Clear(); - CurrentStart = CurrentLocation; - CurrentErrors.Clear(); - } - - protected TSymbol EndSymbol(TSymbolType type) - { - return EndSymbol(CurrentStart, type); - } - - protected TSymbol EndSymbol(SourceLocation start, TSymbolType type) - { - TSymbol sym = null; - if (HaveContent) - { - sym = CreateSymbol(start, Buffer.ToString(), type, CurrentErrors.ToArray()); - } - StartSymbol(); - return sym; - } - - protected bool TakeUntil(Func predicate) - { - // Take all the characters up to the end character - while (!EndOfFile && !predicate(CurrentCharacter)) - { - TakeCurrent(); - } - - // Why did we end? - return !EndOfFile; - } - - protected void TakeCurrent() - { - if (EndOfFile) - { - return; - } // No-op - Buffer.Append(CurrentCharacter); - MoveNext(); - } - - protected void MoveNext() - { -#if DEBUG - _read.Append(CurrentCharacter); -#endif - Source.Read(); - } - - protected bool TakeAll(string expected, bool caseSensitive) - { - return Lookahead(expected, takeIfMatch: true, caseSensitive: caseSensitive); - } - - protected char Peek() - { - using (LookaheadToken lookahead = Source.BeginLookahead()) - { - MoveNext(); - return CurrentCharacter; - } - } - - protected StateResult AfterRazorCommentTransition() - { - if (CurrentCharacter != '*') - { - // We've been moved since last time we were asked for a symbol... reset the state - return Transition(StartState); - } - AssertCurrent('*'); - TakeCurrent(); - return Transition(EndSymbol(RazorCommentStarType), RazorCommentBody); - } - - protected StateResult RazorCommentBody() - { - TakeUntil(c => c == '*'); - if (CurrentCharacter == '*') - { - var star = CurrentCharacter; - var start = CurrentLocation; - MoveNext(); - if (!EndOfFile && CurrentCharacter == '@') - { - State next = () => - { - Buffer.Append(star); - return Transition(EndSymbol(start, RazorCommentStarType), () => - { - if (CurrentCharacter != '@') - { - // We've been moved since last time we were asked for a symbol... reset the state - return Transition(StartState); - } - TakeCurrent(); - return Transition(EndSymbol(RazorCommentTransitionType), StartState); - }); - }; - - if (HaveContent) - { - return Transition(EndSymbol(RazorCommentType), next); - } - else - { - return Transition(next); - } - } - else - { - Buffer.Append(star); - return Stay(); - } - } - return Transition(EndSymbol(RazorCommentType), StartState); - } - - /// - /// Internal for unit testing - /// - internal bool Lookahead(string expected, bool takeIfMatch, bool caseSensitive) - { - Func filter = c => c; - if (!caseSensitive) - { - filter = Char.ToLowerInvariant; - } - - if (expected.Length == 0 || filter(CurrentCharacter) != filter(expected[0])) - { - return false; - } - - // Capture the current buffer content in case we have to backtrack - string oldBuffer = null; - if (takeIfMatch) - { - oldBuffer = Buffer.ToString(); - } - - using (LookaheadToken lookahead = Source.BeginLookahead()) - { - for (int i = 0; i < expected.Length; i++) - { - if (filter(CurrentCharacter) != filter(expected[i])) - { - if (takeIfMatch) - { - // Clear the buffer and put the old buffer text back - Buffer.Clear(); - Buffer.Append(oldBuffer); - } - // Return without accepting lookahead (thus rejecting it) - return false; - } - if (takeIfMatch) - { - TakeCurrent(); - } - else - { - MoveNext(); - } - } - if (takeIfMatch) - { - lookahead.Accept(); - } - } - return true; - } - - [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This only occurs in Release builds, where this method is empty by design")] - [Conditional("DEBUG")] - internal void AssertCurrent(char current) - { -#if NET451 - // No Debug.Assert with this many arguments in CoreCLR - - Debug.Assert(CurrentCharacter == current, "CurrentCharacter Assumption violated", "Assumed that the current character would be {0}, but it is actually {1}", current, CurrentCharacter); -#else - Debug.Assert(CurrentCharacter == current, string.Format("CurrentCharacter Assumption violated. Assumed that the current character would be {0}, but it is actually {1}", current, CurrentCharacter)); -#endif - } - - ISymbol ITokenizer.NextSymbol() - { - return (ISymbol)NextSymbol(); - } - } - -#if DEBUG - [DebuggerDisplay("{DebugDisplay}")] - public partial class Tokenizer - { - private StringBuilder _read = new StringBuilder(); - - public string DebugDisplay - { - get { return string.Format(CultureInfo.InvariantCulture, "[{0}] [{1}] [{2}]", _read.ToString(), CurrentCharacter, Remaining); } - } - - public string Remaining - { - get - { - var remaining = Source.ReadToEnd(); - Source.Seek(-remaining.Length); - return remaining; - } - } - } -#endif -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/TokenizerView.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/TokenizerView.cs deleted file mode 100644 index 8c4df8bca8..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/TokenizerView.cs +++ /dev/null @@ -1,56 +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; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using Microsoft.AspNet.Razor.Text; -using Microsoft.AspNet.Razor.Tokenizer.Symbols; - -namespace Microsoft.AspNet.Razor.Tokenizer -{ - [SuppressMessage("Microsoft.Design", "CA1005:AvoidExcessiveParametersOnGenericTypes", Justification = "All generic parameters are required")] - public class TokenizerView - where TSymbolType : struct - where TTokenizer : Tokenizer - where TSymbol : SymbolBase - { - public TokenizerView(TTokenizer tokenizer) - { - Tokenizer = tokenizer; - } - - public TTokenizer Tokenizer { get; private set; } - public bool EndOfFile { get; private set; } - public TSymbol Current { get; private set; } - - public ITextDocument Source - { - get { return Tokenizer.Source; } - } - - public bool Next() - { - Current = Tokenizer.NextSymbol(); - EndOfFile = (Current == null); - return !EndOfFile; - } - - public void PutBack(TSymbol symbol) - { - Debug.Assert(Source.Position == symbol.Start.AbsoluteIndex + symbol.Content.Length); - if (Source.Position != symbol.Start.AbsoluteIndex + symbol.Content.Length) - { - // We've already passed this symbol - throw new InvalidOperationException( - RazorResources.FormatTokenizerView_CannotPutBack( - symbol.Start.AbsoluteIndex + symbol.Content.Length, - Source.Position)); - } - Source.Position -= symbol.Content.Length; - Current = null; - EndOfFile = Source.Position >= Source.Length; - Tokenizer.Reset(); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/XmlHelpers.cs b/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/XmlHelpers.cs deleted file mode 100644 index ae60235628..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Tokenizer/XmlHelpers.cs +++ /dev/null @@ -1,51 +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.AspNet.Razor.Tokenizer -{ - internal static class XmlHelpers - { - public static bool IsXmlNameStartChar(char chr) - { - // [4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | - // [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | - // [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] - // http://www.w3.org/TR/REC-xml/#NT-Name - - return Char.IsLetter(chr) || - chr == ':' || - chr == '_' || - IsInRange(chr, 0xC0, 0xD6) || - IsInRange(chr, 0xD8, 0xF6) || - IsInRange(chr, 0xF8, 0x2FF) || - IsInRange(chr, 0x370, 0x37D) || - IsInRange(chr, 0x37F, 0x1FFF) || - IsInRange(chr, 0x200C, 0x200D) || - IsInRange(chr, 0x2070, 0x218F) || - IsInRange(chr, 0x2C00, 0x2FEF) || - IsInRange(chr, 0x3001, 0xD7FF) || - IsInRange(chr, 0xF900, 0xFDCF) || - IsInRange(chr, 0xFDF0, 0xFFFD) || - IsInRange(chr, 0x10000, 0xEFFFF); - } - - public static bool IsXmlNameChar(char chr) - { - // [4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] - // http://www.w3.org/TR/REC-xml/#NT-Name - return Char.IsDigit(chr) || - IsXmlNameStartChar(chr) || - chr == '-' || - chr == '.' || - chr == '·' || // (U+00B7 is middle dot: ·) - IsInRange(chr, 0x0300, 0x036F) || - IsInRange(chr, 0x203F, 0x2040); - } - - public static bool IsInRange(char chr, int low, int high) - { - return ((int)chr >= low) && ((int)chr <= high); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Utils/CharUtils.cs b/src/Microsoft.AspNet.Razor.VSRC1/Utils/CharUtils.cs deleted file mode 100644 index 2d4094ccc0..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Utils/CharUtils.cs +++ /dev/null @@ -1,22 +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.AspNet.Razor.Utils -{ - internal static class CharUtils - { - internal static bool IsNonNewLineWhitespace(char c) - { - return Char.IsWhiteSpace(c) && !IsNewLine(c); - } - - internal static bool IsNewLine(char c) - { - return c == 0x000d // Carriage return - || c == 0x000a // Linefeed - || c == 0x2028 // Line separator - || c == 0x2029; // Paragraph separator - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Utils/DisposableAction.cs b/src/Microsoft.AspNet.Razor.VSRC1/Utils/DisposableAction.cs deleted file mode 100644 index 8ff2f09179..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Utils/DisposableAction.cs +++ /dev/null @@ -1,32 +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.AspNet.Razor.Utils -{ - internal class DisposableAction : IDisposable - { - private Action _action; - private bool _invoked; - - public DisposableAction(Action action) - { - if (action == null) - { - throw new ArgumentNullException(nameof(action)); - } - - _action = action; - } - - public void Dispose() - { - if (!_invoked) - { - _action(); - _invoked = true; - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Utils/EnumUtil.cs b/src/Microsoft.AspNet.Razor.VSRC1/Utils/EnumUtil.cs deleted file mode 100644 index 7f0474a315..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Utils/EnumUtil.cs +++ /dev/null @@ -1,24 +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.Collections.Generic; - -namespace Microsoft.AspNet.Razor.Utils -{ - internal static class EnumUtil - { - public static IEnumerable Single(T item) - { - yield return item; - } - - public static IEnumerable Prepend(T item, IEnumerable enumerable) - { - yield return item; - foreach (T t in enumerable) - { - yield return t; - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/Utils/EnumeratorExtensions.cs b/src/Microsoft.AspNet.Razor.VSRC1/Utils/EnumeratorExtensions.cs deleted file mode 100644 index ad0911da50..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/Utils/EnumeratorExtensions.cs +++ /dev/null @@ -1,16 +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.Collections.Generic; -using System.Linq; - -namespace Microsoft.AspNet.Razor.Utils -{ - internal static class EnumeratorExtensions - { - public static IEnumerable Flatten(this IEnumerable> source) - { - return source.SelectMany(e => e); - } - } -} diff --git a/src/Microsoft.AspNet.Razor.VSRC1/project.json b/src/Microsoft.AspNet.Razor.VSRC1/project.json deleted file mode 100644 index 1baaff1fce..0000000000 --- a/src/Microsoft.AspNet.Razor.VSRC1/project.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "description": "Razor is a markup syntax for adding server-side logic to web pages. This package contains the Razor parser and code generation infrastructure.", - "version": "4.0.0-rc1-final", - "buildOptions": { - "warningsAsErrors": true, - "keyFile": "../../tools/Key.snk" - }, - "packOptions": { - "repository": { - "type": "git", - "url": "git://github.com/aspnet/razor" - } - }, - "dependencies": {}, - "frameworks": { - "net451": {} - } -} \ No newline at end of file