diff --git a/Documentation/contributing.md b/Documentation/contributing.md index d403a200494..53770a4c56f 100644 --- a/Documentation/contributing.md +++ b/Documentation/contributing.md @@ -13,9 +13,9 @@ See [Developer Guide](developer-guide.md) to learn how to develop changes for th This project follows the general [.NET Core Contribution Guidelines](https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/contributing.md). The contribution bar from the general contribution guidelines is copied below. -## Do not change files in the `Shared` directory +## Do not change files in the `Shared`, `WindowsBase`, `PresentationCore`, and `PresentationFramework` directories -The directory [`src/Microsoft.DotNet.Wpf/src/Shared`](https://github.com/dotnet/wpf/tree/master/src/Microsoft.DotNet.Wpf/src/Shared) contains files that are shared between the public GitHub repo and the internal WPF repos. Changes to files in this directory will *not* be accepted since they also affect internal code. Once all the appropriate source has been published to the public repo, this restriction will no longer be needed. +The directories [`src/Microsoft.DotNet.Wpf/src/Shared`](https://github.com/dotnet/wpf/tree/master/src/Microsoft.DotNet.Wpf/src/Shared), [`src/Microsoft.DotNet.Wpf/src/WindowsBase`](https://github.com/dotnet/wpf/tree/master/src/Microsoft.DotNet.Wpf/src/WindowsBase), [`src/Microsoft.DotNet.Wpf/src/PresentationCore`](https://github.com/dotnet/wpf/tree/master/src/Microsoft.DotNet.Wpf/src/PresentationCore), [`src/Microsoft.DotNet.Wpf/src/PresentationFramework`](https://github.com/dotnet/wpf/tree/master/src/Microsoft.DotNet.Wpf/src/PresentationFramework) contains files that are shared between the public GitHub repo and the internal WPF repos. Changes to files in this directory will *not* be accepted since they also affect internal code. Once all the appropriate sources have been published to the public repo, this restriction will no longer be needed. ## Contribution "Bar" @@ -26,3 +26,13 @@ Maintainers will not merge changes that have narrowly-defined benefits due to co Most .NET Core components are cross-platform and we appreciate contributions that either improve their feature set in a given environment or that add support for a new environment. We will typically not accept contributions that implement support for an OS-specific technolology on another operating system. For example, we do not intend to create an implementation of the Windows registry for Linux or an implementation of the macOS keychain for Windows. We also do not intend to accept contributions that provide cross-platform implementations for Windows Forms or WPF. Contributions must also satisfy the other published guidelines defined in this document. + +## Code Formatting Improvements and Minor Enhancements + +We will consider code-formatting improvements that are identified by running code analyzers. + +Our CodeAnalysis rules are not enabled by default. These can be enabled by setting the MSBuild property `EnableAnalyzers=true` (in commandline, it is set as `/p:EnableAnalyzers=true`). + +The code analyzer would likely recommend changes that can result in changes to the generated IL. In general, we prefer code-formatting PR's to be limited to changes that do not have any impact on the IL - these are easier to review and approve and do not require additional testing. + +Please open issues for changes that affect the IL or might require additional validation, and work with the project maintainers to determine whether a PR would be appropriate. diff --git a/Microsoft.Dotnet.Wpf.sln b/Microsoft.Dotnet.Wpf.sln index 08cdda38fe7..3ca30af3c2f 100644 --- a/Microsoft.Dotnet.Wpf.sln +++ b/Microsoft.Dotnet.Wpf.sln @@ -19,7 +19,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Arcade.Wpf EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Wpf.ProjectTemplates.ArchNeutral", "packaging\Microsoft.Dotnet.Wpf.ProjectTemplates\Microsoft.DotNet.Wpf.ProjectTemplates.ArchNeutral.csproj", "{BFF6C118-3369-43B5-ACA6-D65ED00EEBE0}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.DotNet.Wpf.ProjectTemplates", "Microsoft.DotNet.Wpf.ProjectTemplates", "{891FF487-721B-4935-833A-F9ABFEB1E79D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PresentationBuildTasks", "src\Microsoft.DotNet.Wpf\src\PresentationBuildTasks\PresentationBuildTasks.csproj", "{4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.NET.Sdk.WindowsDesktop", "Microsoft.NET.Sdk.WindowsDesktop", "{1D4C8AD7-12E7-4987-98AF-AEE79F53E494}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.WindowsDesktop.ArchNeutral", "packaging\Microsoft.NET.Sdk.WindowsDesktop\Microsoft.NET.Sdk.WindowsDesktop.ArchNeutral.csproj", "{440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.DotNet.Wpf.ProjectTemplates", "Microsoft.DotNet.Wpf.ProjectTemplates", "{22D643D8-87D6-4FE8-9632-58A3CD3DC7CB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -91,6 +97,30 @@ Global {BFF6C118-3369-43B5-ACA6-D65ED00EEBE0}.Release|x64.Build.0 = Release|x64 {BFF6C118-3369-43B5-ACA6-D65ED00EEBE0}.Release|x86.ActiveCfg = Release|Any CPU {BFF6C118-3369-43B5-ACA6-D65ED00EEBE0}.Release|x86.Build.0 = Release|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|x64.ActiveCfg = Debug|x64 + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|x64.Build.0 = Debug|x64 + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|x86.ActiveCfg = Debug|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|x86.Build.0 = Debug|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|Any CPU.Build.0 = Release|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|x64.ActiveCfg = Release|x64 + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|x64.Build.0 = Release|x64 + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|x86.ActiveCfg = Release|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|x86.Build.0 = Release|Any CPU + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Debug|x64.ActiveCfg = Debug|x64 + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Debug|x64.Build.0 = Debug|x64 + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Debug|x86.ActiveCfg = Debug|Any CPU + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Debug|x86.Build.0 = Debug|Any CPU + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Release|Any CPU.Build.0 = Release|Any CPU + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Release|x64.ActiveCfg = Release|x64 + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Release|x64.Build.0 = Release|x64 + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Release|x86.ActiveCfg = Release|Any CPU + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -101,8 +131,10 @@ Global {9A7E395B-E859-40E2-809D-EFB72CF3A2EE} = {BF20132A-191F-4D34-9A1B-831772A6DFCF} {8A2ABE39-2D50-48CA-AC32-078BBA32757A} = {0159B0F1-0626-4BED-8D1B-CBFF4F12C369} {B73BB4AB-68DE-4B91-BBB0-AB4F2D504AC3} = {8A2ABE39-2D50-48CA-AC32-078BBA32757A} - {BFF6C118-3369-43B5-ACA6-D65ED00EEBE0} = {891FF487-721B-4935-833A-F9ABFEB1E79D} - {891FF487-721B-4935-833A-F9ABFEB1E79D} = {0159B0F1-0626-4BED-8D1B-CBFF4F12C369} + {BFF6C118-3369-43B5-ACA6-D65ED00EEBE0} = {22D643D8-87D6-4FE8-9632-58A3CD3DC7CB} + {1D4C8AD7-12E7-4987-98AF-AEE79F53E494} = {0159B0F1-0626-4BED-8D1B-CBFF4F12C369} + {440D06B8-E3DE-4C0D-AD25-CD4F43D836E1} = {1D4C8AD7-12E7-4987-98AF-AEE79F53E494} + {22D643D8-87D6-4FE8-9632-58A3CD3DC7CB} = {0159B0F1-0626-4BED-8D1B-CBFF4F12C369} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D4D12991-F531-4FC3-849D-29946BCA818A} diff --git a/eng/WpfArcadeSdk/tools/ShippingProjects.props b/eng/WpfArcadeSdk/tools/ShippingProjects.props index 63d71786b27..498bb8b1932 100644 --- a/eng/WpfArcadeSdk/tools/ShippingProjects.props +++ b/eng/WpfArcadeSdk/tools/ShippingProjects.props @@ -1,11 +1,11 @@ - System.Xaml + System.Xaml; + PresentationBuildTasks - PresentationBuildTasks; PresentationCore; DirectWriteForwarder; PresentationCore-CommonResources; diff --git a/packaging/Microsoft.NET.Sdk.WindowsDesktop/Microsoft.NET.Sdk.WindowsDesktop.ArchNeutral.csproj b/packaging/Microsoft.NET.Sdk.WindowsDesktop/Microsoft.NET.Sdk.WindowsDesktop.ArchNeutral.csproj new file mode 100644 index 00000000000..9ff025d8cee --- /dev/null +++ b/packaging/Microsoft.NET.Sdk.WindowsDesktop/Microsoft.NET.Sdk.WindowsDesktop.ArchNeutral.csproj @@ -0,0 +1,30 @@ + + + {440d06b8-e3de-4c0d-ad25-cd4f43d836e1} + netcoreapp3.0 + AnyCPU;x64 + true + 3.0.0 + + + + + true + + + + $(MSBuildProjectName.Replace('.ArchNeutral','')) + $(PackageName + WindowsDesktop SDK + + + + + + + + diff --git a/packaging/Microsoft.NET.Sdk.WindowsDesktop/Sdk/Sdk.props b/packaging/Microsoft.NET.Sdk.WindowsDesktop/Sdk/Sdk.props new file mode 100644 index 00000000000..19f8200fa41 --- /dev/null +++ b/packaging/Microsoft.NET.Sdk.WindowsDesktop/Sdk/Sdk.props @@ -0,0 +1,29 @@ + + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + + + + + $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)\..\targets)) + + + + + diff --git a/packaging/Microsoft.NET.Sdk.WindowsDesktop/Sdk/Sdk.targets b/packaging/Microsoft.NET.Sdk.WindowsDesktop/Sdk/Sdk.targets new file mode 100644 index 00000000000..93a6c1e3208 --- /dev/null +++ b/packaging/Microsoft.NET.Sdk.WindowsDesktop/Sdk/Sdk.targets @@ -0,0 +1,22 @@ + + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + + + + + diff --git a/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.props b/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.props new file mode 100644 index 00000000000..97c8b47e938 --- /dev/null +++ b/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.props @@ -0,0 +1,45 @@ + + + + + MSBuild:Compile + + + + + + MSBuild:Compile + + + + + + + + + + + <_SDKImplicitReference Include="WindowsBase"/> + <_SDKImplicitReference Include="PresentationCore"/> + <_SDKImplicitReference Include="PresentationFramework"/> + <_SDKImplicitReference Include="System.Windows.Controls.Ribbon"/> + <_SDKImplicitReference Include="System.Xaml"/> + <_SDKImplicitReference Include="UIAutomationClient"/> + <_SDKImplicitReference Include="UIAutomationClientSideProviders"/> + <_SDKImplicitReference Include="UIAutomationProvider"/> + <_SDKImplicitReference Include="UIAutomationTypes"/> + + + + <_SDKImplicitReference Include="System.Windows.Forms"/> + + + + <_SDKImplicitReference Include="WindowsFormsIntegration"/> + + diff --git a/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.targets b/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.targets new file mode 100644 index 00000000000..0d4999b49ca --- /dev/null +++ b/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.targets @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packaging/Microsoft.NET.Sdk.WindowsDesktop/useSharedDesignerContext.txt b/packaging/Microsoft.NET.Sdk.WindowsDesktop/useSharedDesignerContext.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/Microsoft.DotNet.Wpf/src/Common/src/System/SR.cs b/src/Microsoft.DotNet.Wpf/src/Common/src/System/SR.cs index 3c86205337a..0ecaad06f94 100644 --- a/src/Microsoft.DotNet.Wpf/src/Common/src/System/SR.cs +++ b/src/Microsoft.DotNet.Wpf/src/Common/src/System/SR.cs @@ -14,11 +14,20 @@ namespace MS.Internal.PresentationCore namespace MS.Utility #elif AUTOMATION namespace MS.Internal.Automation +#elif REACHFRAMEWORK +namespace System.Windows.Xps +#elif PRESENTATIONFRAMEWORK +namespace System.Windows +#elif PRESENTATIONUI +namespace System.Windows.TrustUI +#elif WINDOWSFORMSINTEGRATION +namespace System.Windows +#elif RIBBON_IN_FRAMEWORK +namespace Microsoft.Windows.Controls #else namespace System #endif { - internal partial class SR { private static ResourceManager ResourceManager => SRID.ResourceManager; @@ -90,4 +99,4 @@ internal static string Format(string resourceFormat, object p1, object p2, objec return string.Format(resourceFormat, p1, p2, p3); } } -} \ No newline at end of file +} diff --git a/src/Microsoft.DotNet.Wpf/src/Directory.Build.Props b/src/Microsoft.DotNet.Wpf/src/Directory.Build.Props index 01dd165300a..bb9941205e1 100644 --- a/src/Microsoft.DotNet.Wpf/src/Directory.Build.Props +++ b/src/Microsoft.DotNet.Wpf/src/Directory.Build.Props @@ -6,7 +6,6 @@ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb true - $(MSBuildThisFileDirectory)Shared\ $(MSBuildThisFileDirectory)Common\ $(MSBuildThisFileDirectory)WpfGfx\ $(WpfGraphicsPath) diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Localization/LocalizationDirectivesToLocFile.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Localization/LocalizationDirectivesToLocFile.cs new file mode 100644 index 00000000000..20112969618 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Localization/LocalizationDirectivesToLocFile.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace MS.Internal +{ + + internal enum LocalizationDirectivesToLocFile + { + None, // No Localization file generated. + CommentsOnly, // Put the Localization comments to .loc file. + All, // Put the localization comments and attributes to .loc file. + Unknown + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Localization/LocalizationParserHooks.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Localization/LocalizationParserHooks.cs new file mode 100644 index 00000000000..a00ae024482 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Localization/LocalizationParserHooks.cs @@ -0,0 +1,183 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; +using System.IO; +using System.Xml; +using System.Text; + +using MS.Internal.Globalization; +using MS.Internal.Markup; +using MS.Internal.Tasks; + +namespace MS.Internal +{ + internal sealed class LocalizationParserHooks : ParserHooks + { + private MarkupCompiler _compiler; + private ArrayList _commentList; + private LocalizationComment _currentComment; + private LocalizationDirectivesToLocFile _directivesToFile; + private bool _isSecondPass; + + internal LocalizationParserHooks( + MarkupCompiler compiler , + LocalizationDirectivesToLocFile directivesToFile, + bool isSecondPass + ) + { + _compiler = compiler; + _directivesToFile = directivesToFile; + _isSecondPass = isSecondPass; + + // The arrray list holds all the comments collected while parsing Xaml. + _commentList = new ArrayList(); + + // It is the comments current being processed. + _currentComment = new LocalizationComment(); + } + + internal override ParserAction LoadNode(XamlNode tokenNode) + { + switch (tokenNode.TokenType) + { + case XamlNodeType.DocumentStart : + { + // A single ParserHooks might be used to parse multiple bamls. + // We need to clear the comments list at the begining of each baml. + _commentList.Clear(); + _currentComment = new LocalizationComment(); + return ParserAction.Normal; + } + case XamlNodeType.DefAttribute : + { + XamlDefAttributeNode node = (XamlDefAttributeNode) tokenNode; + if (node.Name == XamlReaderHelper.DefinitionUid) + { + _currentComment.Uid = node.Value; + } + + return ParserAction.Normal; + } + case XamlNodeType.Property : + { + XamlPropertyNode node = (XamlPropertyNode) tokenNode; + + // When this parer hook is invoked, comments is always output to a seperate file. + if (LocComments.IsLocCommentsProperty(node.TypeFullName, node.PropName)) + { + // try parse the value. Exception will be thrown if not valid. + LocComments.ParsePropertyComments(node.Value); + _currentComment.Comments = node.Value; + return ParserAction.Skip; // skips outputing this node to baml + } + + if ( _directivesToFile == LocalizationDirectivesToLocFile.All + && LocComments.IsLocLocalizabilityProperty(node.TypeFullName, node.PropName)) + { + // try parse the value. Exception will be thrown if not valid. + LocComments.ParsePropertyLocalizabilityAttributes(node.Value); + _currentComment.Attributes = node.Value; + return ParserAction.Skip; // skips outputing this node to baml + } + + return ParserAction.Normal; + } + case XamlNodeType.EndAttributes : + { + FlushCommentToList(ref _currentComment); + return ParserAction.Normal; + } + case XamlNodeType.DocumentEnd : + { + // + // When reaching document end, we output all the comments we have collected + // so far into a localization comment file. If the parsing was aborted in + // MarkupCompilePass1, we would not out the incomplete set of comments because + // it will not reach document end. + // + + if (_commentList.Count > 0) + { + string absoluteOutputPath = _compiler.TargetPath + _compiler.SourceFileInfo.RelativeSourceFilePath + SharedStrings.LocExtension; + MemoryStream memStream = new MemoryStream(); + + // TaskFileService.WriteFile adds BOM for UTF8 Encoding, thus don't add here + // when creating XmlTextWriter. + using (XmlTextWriter writer = new XmlTextWriter(memStream, new UTF8Encoding(false))) + { + // output XML for each piece of comment + writer.Formatting = Formatting.Indented; + writer.WriteStartElement(LocComments.LocResourcesElement); + writer.WriteAttributeString(LocComments.LocFileNameAttribute, _compiler.SourceFileInfo.RelativeSourceFilePath); + + foreach (LocalizationComment comment in _commentList) + { + writer.WriteStartElement(LocComments.LocCommentsElement); + writer.WriteAttributeString(LocComments.LocCommentIDAttribute, comment.Uid); + + if (comment.Attributes != null) + { + writer.WriteAttributeString(LocComments.LocLocalizabilityAttribute, comment.Attributes); + } + + if (comment.Comments != null) + { + writer.WriteAttributeString(LocComments.LocCommentsAttribute, comment.Comments); + } + + writer.WriteEndElement(); + } + writer.WriteEndElement(); + + writer.Flush(); + _compiler.TaskFileService.WriteFile(memStream.ToArray(), absoluteOutputPath); + } + } + + return ParserAction.Normal; + } + default: + { + return ParserAction.Normal; + } + } + } + + /// + /// Add the existing comment into the cached list and clear the state for the + /// next incoming comment. Comments are only collected in pass1. The method is no-op + /// in pass2. + /// + private void FlushCommentToList(ref LocalizationComment comment) + { + if (_isSecondPass) return; + + if ( _currentComment.Uid != null + && ( _currentComment.Attributes != null + || _currentComment.Comments != null + ) + ) + { + // add the comments into the list and reset + _commentList.Add(_currentComment); + _currentComment = new LocalizationComment(); + } + else + { + // clear all properties + _currentComment.Uid = _currentComment.Attributes = _currentComment.Comments = null; + } + } + + private class LocalizationComment + { + internal string Uid; + internal string Comments; + internal string Attributes; + } + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/CompilationUnit.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/CompilationUnit.cs new file mode 100644 index 00000000000..eec15ddd1fc --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/CompilationUnit.cs @@ -0,0 +1,279 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Security.Permissions; + +namespace MS.Internal +{ + /// + /// The CompilationUnit class + /// + internal class CompilationUnit + { +#region Constructors + + ///constructor + public CompilationUnit(string assemblyName, string language, string defaultNamespace, FileUnit[] fileList) + { + _assemblyName = assemblyName; + _language = language; + _fileList = fileList; + _defaultNamespace = defaultNamespace; + } + +#endregion Constructors + +#region Properties + + internal bool Pass2 + { + get { return _pass2; } + set { _pass2 = value; } + } + + ///Name of the assembly the package is compiled into + public string AssemblyName + { + get { return _assemblyName; } + } + + ///Name of the CLR language the package is compiled into + public string Language + { + get { return _language; } + } + + ///path to the project root + public string SourcePath + { + get { return _sourcePath; } + set { _sourcePath = value; } + } + + ///Default CLR Namespace of the project + public string DefaultNamespace + { + get { return _defaultNamespace; } + } + + ///Application definition file (relative to SourcePath) + public FileUnit ApplicationFile + { + get { return _applicationFile; } + set { _applicationFile = value; } + } + + ///A list of relative (to SourcePath) file path names comprising the package to be compiled + public FileUnit[] FileList + { + get { return _fileList; } + } + +#endregion Properties + +#region Private Data + + private bool _pass2 = false; + private string _assemblyName = string.Empty; + private string _language = string.Empty; + private string _sourcePath = string.Empty; + private string _defaultNamespace = string.Empty; + private FileUnit _applicationFile = FileUnit.Empty; + private FileUnit[] _fileList = null; + +#endregion Private Data + } + +#region ErrorEvent + + /// + /// Delegate for the Error event. + /// + internal delegate void MarkupErrorEventHandler(Object sender, MarkupErrorEventArgs e); + + /// + /// Event args for the Error event + /// + internal class MarkupErrorEventArgs : EventArgs + { +#region Constructors + + /// + /// constructor + /// + internal MarkupErrorEventArgs(Exception e, int lineNum, int linePos, string fileName) + { + _e = e; + _lineNum = lineNum; + _linePos = linePos; + _fileName = fileName; + } + +#endregion Constructors + +#region Properties + + /// + /// The Error Message + /// + public Exception Exception + { + get { return _e; } + } + + /// + /// The line number at which the compile Error occured + /// + public int LineNumber + { + get { return _lineNum; } + } + + /// + /// The character position in the line at which the compile Error occured + /// + public int LinePosition + { + get { return _linePos; } + } + + /// + /// The xaml file in which the compile Error occured + /// + public string FileName + { + get { return _fileName; } + } + +#endregion Properties + +#region Private Data + + private int _lineNum; + private int _linePos; + private Exception _e; + private string _fileName; + +#endregion Private Data + + } + +#endregion ErrorEvent + + +#region SourceFileResolveEvent + + /// + /// Delegate for the SourceFileResolve Event. + /// + internal delegate void SourceFileResolveEventHandler(Object sender, SourceFileResolveEventArgs e); + + /// + /// Event args for the Error event + /// + internal class SourceFileResolveEventArgs: EventArgs + { +#region Constructors + + /// + /// constructor + /// + internal SourceFileResolveEventArgs(FileUnit file) + { + _sourceFileInfo = new SourceFileInfo(file); + } + +#endregion Constructors + +#region Properties + + // + // FileInfo + // + internal SourceFileInfo SourceFileInfo + { + get { return _sourceFileInfo; } + } + +#endregion Properties + +#region Private Data + + private SourceFileInfo _sourceFileInfo; + +#endregion Private Data + + } + +#endregion SourceFileResolveEvent + + +#region ReferenceAssembly + + // + // Reference Assembly + // Passed by CodeGenertation Task. + // Consumed by Parser. + // + internal class ReferenceAssembly : MarshalByRefObject + { + #region Constructor + // + // Constructor + // + internal ReferenceAssembly() + { + _path = null; + _assemblyName = null; + } + // + // Constructor + // + // + // + internal ReferenceAssembly(string path, string assemblyname) + { + Path = path; + AssemblyName = assemblyname; + } + + #endregion Constructor + + #region Internal Properties + + // + // The path for the assembly. + // The path must end with "\", but not include any Assembly Name. + // + // + internal string Path + { + get { return _path; } + set { _path = value; } + } + + // + // AssemblyName without any Extension part. + // + // + internal string AssemblyName + { + get { return _assemblyName; } + set { _assemblyName = value;} + } + + #endregion Internal Properties + + #region private fields + + private string _path; + private string _assemblyName; + + #endregion private fields + + } +#endregion ReferenceAssembly + +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/FileUnit.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/FileUnit.cs new file mode 100644 index 00000000000..8a624a80a1c --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/FileUnit.cs @@ -0,0 +1,55 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Security.Permissions; + +namespace MS.Internal +{ + /// + /// The FileUnit class + /// + [Serializable] + internal struct FileUnit + { + public FileUnit(string path, string linkAlias, string logicalName) + { + _path = path; + _linkAlias = linkAlias; + _logicalName = logicalName; + } + + public string Path + { + get { return _path; } + } + + public string LinkAlias + { + get { return _linkAlias; } + } + + public string LogicalName + { + get { return _logicalName; } + } + + public static FileUnit Empty + { + get { return _empty; } + } + + public override string ToString() + { + return _path; + } + + private string _path; + private string _linkAlias; + private string _logicalName; + + private static FileUnit _empty = new FileUnit(String.Empty, String.Empty, String.Empty); + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs new file mode 100644 index 00000000000..61f388b2ed3 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs @@ -0,0 +1,3538 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: +// Markup Compiler class that compiles the markup in a Xaml file into a +// binary stream (Baml) and\or code (IL) in an assembly. +// +//--------------------------------------------------------------------------- + +#pragma warning disable 1634, 1691 + +using System; +using System.Xml; +using System.IO; +using System.Text; +using System.Reflection; +using System.Globalization; +using System.ComponentModel; +using System.Security.Permissions; +using System.Security.Cryptography; + +using System.CodeDom; +using System.CodeDom.Compiler; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel.Design.Serialization; + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +using System.Threading; +using MS.Internal.Markup; +using MS.Internal.Tasks; +using MS.Utility; // for SR +using Microsoft.Build.Utilities; +using Microsoft.Build.Tasks.Windows; +using System.Runtime.CompilerServices; + +namespace MS.Internal +{ + internal sealed class MarkupCompiler + { +#region ExternalAPI + +#region Public Properties + + ///String that specifies the directory to place the generated files into + public string TargetPath + { + get { return _targetPath; } + set { _targetPath = value; } + } + + /// + /// The version of the assembly + /// + public string AssemblyVersion + { + get { return _assemblyVersion; } + set { _assemblyVersion = value; } + } + + /// + /// The public key token of the assembly + /// + public string AssemblyPublicKeyToken + { + get { return _assemblyPublicKeyToken; } + set { _assemblyPublicKeyToken = value; } + } + + ///Array of loose files associated with this assembly + public string [] ContentList + { + get { return _contentList; } + set { _contentList = value; } + } + + /// + /// Splash screen image to be displayed before application init + /// + public string SplashImage + { + set { _splashImage = value; } + } + + /// Array of local xaml page files to be compiled at pass2 + public string[] LocalXamlPages + { + get { return _localXamlPages; } + } + + /// Local Application xaml file to be compiled at pass2 + public string LocalXamlApplication + { + get { return _localXamlApplication; } + } + + /// + /// ReferenceAssemblyList. every item is an instance of ReferenceAssembly. + /// + /// + public ArrayList ReferenceAssemblyList + { + get { return _referenceAssemblyList; } + set { _referenceAssemblyList = value; } + } + + ///The language source file extension set in a project or the registered default. + public string LanguageSourceExtension + { + get { return _languageSourceExtension; } + set { _languageSourceExtension = value; } + } + + ///Allows to hook a custom parser during compilation. + public ParserHooks ParserHooks + { + get { return _parserHooks; } + set { _parserHooks = value; } + } + + ///If true code for supporting hosting in Browser is generated + public bool HostInBrowser + { + get { return _hostInBrowser; } + set { _hostInBrowser = value; } + } + + ///Generate Debug information in the BAML file. + public bool XamlDebuggingInformation + { + get { return _xamlDebuggingInformation; } + set { _xamlDebuggingInformation = value; } + } + + /// + /// Get/Sets the TaskFileService which is used for abstracting simple + /// files services provided by CLR and the HostObject (IVsMsBuildTaskFileManager) + /// + internal ITaskFileService TaskFileService + { + get { return _taskFileService; } + set { _taskFileService = value; } + } + + /// + /// The CompilerWrapper's TaskLoggingHelper for reporting compiler warnings. + /// + internal TaskLoggingHelper TaskLogger + { + set { _taskLogger = value; } + } + + // If the xaml has local references, then it could have internal element & properties + // but there is no way to determine this until MCPass2. Yet, GeneratedInternalTypeHelper, + // which is the class that allows access to legitimate internals, needs to be generated + // in MCPass1. So, to determine if GeneratedInternalTypeHelper.cs needs to be kept or not, + // MCPass1 & MCPass2 task will use the HasInternals property as indicated below: + + // In pass1, if this property returns true, it will be due to friend internals & so + // MCPass1 will just decide to keep the file & this property will be ignored in MCPass2 + // if that task is executed as well. + + // In pass1, if this property returns false, MCPass2 will look at this property again after + // the Xaml Compiler has been called to compile all the local markup files. Now if this + // property still returns false, the file will be removed, else it will be kept, because + // this property was true as the xaml compiler encountered local or friend internals + // during MCPass2. + + // The above will apply only for a clean build, not incremental build. + public static bool HasInternals + { + get { return XamlTypeMapper.HasInternals; } + } + +#endregion Public Properties + +#region Public Events + + /// + /// The Error event is fired when an error is encountered while compiling a xaml file. + /// + public event MarkupErrorEventHandler Error; + + /// + /// The SourceFileResolve event is fired when it starts to compile one xaml file or handle + /// resource file. The event handler will resolve the original filepath to a new + /// SourcePath and RelativeSourceFilePath. + /// + public event SourceFileResolveEventHandler SourceFileResolve; + +#endregion Public Events + +#region Public Methods + + ///Complies list of file items comprising an Application. + public void Compile(CompilationUnit cu) + { + // KnownTypes, XamlTypeMapper, and ReflectionHelper all hold on to data statically that + // must not be reused between compilations as different compilations can target different + // + // Defensively clear static data even though the prior compilation should have done it. + // This is done to mitigate against a failed cleanup of a prior compilation from influencing + // the current compilation. + XamlTypeMapper.Clear(); + KnownTypes.Clear(); + ReflectionHelper.Dispose(); + + try + { + CompileCore(cu); + } + finally + { + // Don't rely on next compilation to reset as that would unnecessarily delay + // garbage collection of this static data that cannot be reused by the next compilation. + // Also, the ReflectionHelper must be disposed now to release file locks on assemblies. + XamlTypeMapper.Clear(); + KnownTypes.Clear(); + ReflectionHelper.Dispose(); + } + } + + private void CompileCore(CompilationUnit cu) + { + try + { + AssemblyName = cu.AssemblyName; + InitCompilerState(); + + DefaultNamespace = cu.DefaultNamespace; + _compilationUnitSourcePath = cu.SourcePath; + + if (!IsLanguageSupported(cu.Language)) + { + OnError(new Exception(SR.Get(SRID.UnknownLanguage, cu.Language))); + return; + } + + if (!cu.Pass2) + { + EnsureLanguageSourceExtension(); + } + + if (cu.ApplicationFile.Path != null && cu.ApplicationFile.Path.Length > 0) + { + Initialize(cu.ApplicationFile); + ApplicationFile = SourceFileInfo.RelativeSourceFilePath; + + if (ApplicationFile.Length > 0) + { + IsCompilingEntryPointClass = true; + _Compile(cu.ApplicationFile.Path, cu.Pass2); + IsCompilingEntryPointClass = false; + + if (_pendingLocalFiles != null && _pendingLocalFiles.Count == 1) + { + Debug.Assert(!cu.Pass2); + _localXamlApplication = (string)_pendingLocalFiles[0]; + _pendingLocalFiles.Clear(); + } + } + } + + if (cu.FileList != null) + { + for (int i = 0; i < cu.FileList.Length; i++) + { + FileUnit sourceFile = cu.FileList[i]; + + Initialize(sourceFile); + if (SourceFileInfo.RelativeSourceFilePath.Length > 0) + { + _Compile(sourceFile.Path, cu.Pass2); + } + } + + if (_pendingLocalFiles != null && _pendingLocalFiles.Count > 0) + { + Debug.Assert(!cu.Pass2); + _localXamlPages = (string[])_pendingLocalFiles.ToArray(typeof(string)); + _pendingLocalFiles.Clear(); + } + } + + if (!cu.Pass2 && ContentList != null && ContentList.Length > 0) + { + GenerateLooseContentAttributes(); + } + + Debug.Assert(!cu.Pass2 || _pendingLocalFiles == null); + Debug.Assert(_pendingLocalFiles == null || _pendingLocalFiles.Count == 0); + _pendingLocalFiles = null; + + if (cu.Pass2) + { + _localAssembly = null; + _localXamlApplication = null; + _localXamlPages = null; + } + } + finally + { + + if (s_hashAlgorithm != null) + { + s_hashAlgorithm.Clear(); + s_hashAlgorithm = null; + } + } + } + +#endregion Public Methods + +#endregion ExternalAPI + +#region Implementation + +#region Properties + + private CompilerInfo CompilerInfo + { + get { return _ci; } + set + { + _ci = value; + if (value == null) + { + _codeProvider = null; + } + } + } + + private string ApplicationFile + { + get { return _applicationFile; } + set { _applicationFile = value; } + } + + private string DefaultNamespace + { + get { return _defaultNamespace; } + set + { + IsValidCLRNamespace(value, true); + _defaultNamespace = value; + } + } + + private bool IsCodeNeeded + { + get { return _isCodeNeeded; } + set { _isCodeNeeded = value; } + } + + internal bool IsBamlNeeded + { + get { return IsCompilingEntryPointClass ? _isBamlNeeded : true; } + set { _isBamlNeeded = value; } + } + + internal bool IsRootPublic + { + get { return _ccRoot != null && _ccRoot.CodeClass.TypeAttributes == TypeAttributes.Public; } + } + + internal bool ProcessingRootContext + { + get { return _ccRoot == null; } + } + + internal bool IsRootNameScope + { + get + { + CodeContext cc = (CodeContext)_codeContexts.Peek(); + return cc.IsAllowedNameScope; + } + } + + internal bool HasLocalEvent + { + get { return _hasLocalEvent; } + set { _hasLocalEvent = value; } + } + + internal static bool HasLocalReference + { + get { return XamlTypeMapper.HasLocalReference; } + } + + internal Assembly LocalAssembly + { + get + { + if (_localAssembly == null) + { + if (LocalAssemblyFile != null) + { + _localAssembly = ReflectionHelper.LoadAssembly(LocalAssemblyFile.AssemblyName, LocalAssemblyFile.Path); + } + } + + return _localAssembly; + } + } + + internal ReferenceAssembly LocalAssemblyFile + { + get { return _localAssemblyFile; } + set { _localAssemblyFile = value; } + } + + internal string AssemblyName + { + get { return _assemblyName; } + set { _assemblyName = value; } + } + + internal SourceFileInfo SourceFileInfo + { + get { return _sourceFileInfo; } + set { _sourceFileInfo = value; } + } + + internal bool IsCompilingEntryPointClass + { + get { return _isCompilingEntryPointClass; } + set { _isCompilingEntryPointClass = value; _isBamlNeeded = !value; } + } + + internal static string DefinitionNSPrefix + { + get { return _definitionNSPrefix; } + set { _definitionNSPrefix = value; } + } + + internal string Language + { + get { return _language; } + } + +#endregion Properties + +#region CompileUnit + + private void InitCompilerState() + { + _hasGeneratedInternalTypeHelper = false; + CompilerInfo = null; + InitializeReflectionHelper(); + InitializeTypeMapper(); + } + + // + // Generate the SourceFileInfo for the source file. + // Do the appropriate initiallization work and file checking. + // + private void Initialize(FileUnit sourceFile) + { + try + { + // Keep the SourceFileInfo for the passed source file. + SourceFileInfo = OnSourceFileResolve(sourceFile); + + // Process the input file + if (sourceFile.Path == null || !SourceFileInfo.IsXamlFile) + { + ThrowCompilerException(SRID.InvalidMarkupFile); + } + + if (!TaskFileService.Exists(sourceFile.Path)) + { + ThrowCompilerException(SRID.FileNotFound, sourceFile.Path); + } + + // Prime the output directory + if (TargetPath.Length > 0) + { + // check for ending '\' + if (!TargetPath.EndsWith(ESCAPED_BACKSLASH, StringComparison.Ordinal)) + { + TargetPath += ESCAPED_BACKSLASH; + } + } + + int pathEndIndex = SourceFileInfo.RelativeSourceFilePath.LastIndexOf(ESCAPED_BACKSLASH, StringComparison.Ordinal); + string targetPath = TargetPath + SourceFileInfo.RelativeSourceFilePath.Substring(0, pathEndIndex + 1); + + // Create if not already exists + if (targetPath.Length > 0 && !Directory.Exists(targetPath)) + { + Directory.CreateDirectory(targetPath); + } + } + // All exceptions including NullRef & SEH need to be caught by the markupcompiler + // since it is an app and not a component. + #pragma warning suppress 6500 + catch (Exception e) + { + OnError(e); + } + } + + private void _Compile(string relativeSourceFile, bool pass2) + { + bool error = false; + Stream bamlStream = null; + XamlParser xamlParser = null; + + try + { + DefinitionNSPrefix = DEFINITION_PREFIX; + IsCodeNeeded = false; + + _ccRoot = null; + _hasLocalEvent = false; + _codeContexts = new Stack(); + _parserContext = new ParserContext(); + _parserContext.XamlTypeMapper = _typeMapper; + _hasEmittedEventSetterDeclaration = false; + + bamlStream = new MemoryStream(); + BamlRecordWriter bamlWriter = new BamlRecordWriter(bamlStream, _parserContext, true); + bamlWriter.DebugBamlStream = XamlDebuggingInformation; + + xamlParser = new ParserExtension(this, _parserContext, bamlWriter, SourceFileInfo.Stream, pass2); + + xamlParser.ParserHooks = ParserHooks; + + try + { + xamlParser.Parse(); + } + finally + { + _typeMapper.ResetMapper(); + } + } + catch (XamlParseException e) + { + OnError(e); + error = true; + } + // All exceptions including NullRef & SEH need to be caught by the markupcompiler + // since it is an app and not a component. +#pragma warning suppress 6500 + catch (Exception e) + { + OnError(e); + error = true; + } + finally + { + if (!error && + xamlParser.BamlRecordWriter == null && + IsBamlNeeded) + { + if (_pendingLocalFiles == null) + { + _pendingLocalFiles = new ArrayList(10); + } + + _pendingLocalFiles.Add(relativeSourceFile); + } + + if (_codeContexts != null) + { + _codeContexts.Clear(); + _codeContexts = null; + } + + + if (SourceFileInfo != null) + { + SourceFileInfo.CloseStream(); + } + + if (bamlStream != null) + { + bamlStream.Close(); + bamlStream = null; + } + } + } + + private void GenerateSource() + { + Debug.Assert(_codeContexts.Count == 0); + + CodeNamespace cnsImports = IsLanguageCSharp ? new CodeNamespace() : _ccRoot.CodeNS; + + if (IsCodeNeeded) + { + cnsImports.Imports.Add(new CodeNamespaceImport("System")); + + if (_usingNS != null) + { + foreach (string u in _usingNS) + { + cnsImports.Imports.Add(new CodeNamespaceImport(u)); + } + } + + // } end SubClass + _ccRoot.CodeNS.Types.Add(_ccRoot.CodeClass); + } + + if (_usingNS != null) + { + _usingNS.Clear(); + _usingNS = null; + } + + if (IsCompilingEntryPointClass) + { + GenerateAppEntryPoint(); + } + + if (IsCodeNeeded) + { + MemoryStream codeMemStream = new MemoryStream(); + + // using Disposes the StreamWriter when it ends. Disposing the StreamWriter + // also closes the underlying MemoryStream. Furthermore, don't add BOM here since + // TaskFileService.WriteGeneratedCodeFileFile adds it. + using (StreamWriter codeStreamWriter = new StreamWriter(codeMemStream, new UTF8Encoding(false))) + { + CodeGeneratorOptions o = new CodeGeneratorOptions(); + + // } end namespace + CodeCompileUnit ccu = new CodeCompileUnit(); + + // Use SHA1 if compat flag is set + // generate pragma checksum data + if (s_hashAlgorithm == null) + { + s_hashAlgorithm = SHA1.Create(); + s_hashGuid = s_hashSHA1Guid; + } + + CodeChecksumPragma csPragma = new CodeChecksumPragma(); + csPragma.FileName = ParentFolderPrefix + SourceFileInfo.RelativeSourceFilePath + XAML; + csPragma.ChecksumAlgorithmId = s_hashGuid; + csPragma.ChecksumData = TaskFileService.GetChecksum(SourceFileInfo.OriginalFilePath, s_hashGuid); + ccu.StartDirectives.Add(csPragma); + + if (cnsImports != _ccRoot.CodeNS) + { + ccu.Namespaces.Add(cnsImports); + } + + ccu.Namespaces.Add(_ccRoot.CodeNS); + + CodeDomProvider codeProvider = EnsureCodeProvider(); + + if (codeProvider.Supports(GeneratorSupport.PartialTypes) && _ccRoot.SubClass.Length == 0) + { + _ccRoot.CodeClass.IsPartial = true; + } + + codeProvider.GenerateCodeFromCompileUnit(ccu, codeStreamWriter, o); + + codeStreamWriter.Flush(); + TaskFileService.WriteGeneratedCodeFile(codeMemStream.ToArray(), + TargetPath + SourceFileInfo.RelativeSourceFilePath, + SharedStrings.GeneratedExtension, SharedStrings.IntellisenseGeneratedExtension, + LanguageSourceExtension); + } + } + + // Generate the InternalTypeHelper class in a separate code file only once and on an as + // needed basis for the current assembly being built. This class provides support for + // accessing legitimate internal types and properties that are present in the same (local) + // or a friend assembly and it is generated only when any such internals are actually + // encountered in any of the xaml files in the project. + GenerateInternalTypeHelperImplementation(); + } + + // + // Return FileInfo for the given source file. + // + private SourceFileInfo OnSourceFileResolve(FileUnit file) + { + SourceFileInfo sourceFileInfo; + + if (SourceFileResolve != null) + { + // + // If SourceFileResolve event handler is registered, the handler + // is responsible for generating the SourceFileInfo. + // This is for MSBUILD tasks. + // + SourceFileResolveEventArgs scea = new SourceFileResolveEventArgs(file); + + SourceFileResolve(this, scea); + + sourceFileInfo = scea.SourceFileInfo; + } + else + { + // If SourceFileResolve event handler is not registered, generate + // the default SourceFileInfo for this file. + // + sourceFileInfo = new SourceFileInfo(file); + + sourceFileInfo.SourcePath = _compilationUnitSourcePath; + + if (sourceFileInfo.IsXamlFile) + { + int fileExtIndex = file.Path.LastIndexOf(DOT, StringComparison.Ordinal); + + sourceFileInfo.RelativeSourceFilePath = file.Path.Substring(0, fileExtIndex); + } + } + + return sourceFileInfo; + } + +#endregion CompileUnit + +#region ErrorHandling + + static void ThrowCompilerException(string id) + { + string message = SR.Get(id); + ThrowCompilerExceptionImpl(message); + } + + internal static void ThrowCompilerException(string id, string value) + { + string message = SR.Get(id, value); + ThrowCompilerExceptionImpl(message); + } + + internal static void ThrowCompilerException(string id, string value1, string value2) + { + string message = SR.Get(id, value1, value2); + ThrowCompilerExceptionImpl(message); + } + + internal static void ThrowCompilerException(string id, string value1, string value2, string value3) + { + string message = SR.Get(id, value1, value2, value3); + ThrowCompilerExceptionImpl(message); + } + + static void ThrowCompilerException(string id, string value1, string value2, string value3, string value4) + { + string message = SR.Get(id, value1, value2, value3, value4); + ThrowCompilerExceptionImpl(message); + } + + static void ThrowCompilerExceptionImpl(string message) + { + Exception compilerException = new Exception(message); + throw compilerException; + } + + internal void OnError(Exception e) + { + if (Error != null) + { + XamlParseException xe = e as XamlParseException; + int lineNum = xe != null ? xe.LineNumber : 0; + int linePos = xe != null ? xe.LinePosition : 0; + string filename = SourceFileInfo.OriginalFilePath; + + MarkupErrorEventArgs eea = new MarkupErrorEventArgs(e, lineNum, linePos, filename); + Error(this, eea); + } + } + +#endregion ErrorHandling + +#region Definition Namespace processing + + internal void ProcessDefinitionNamespace(XamlDefTagNode xamlDefTagNode) + { + bool exitLoop = false; + XmlReader xmlReader = xamlDefTagNode.XmlReader; + string LocalName = xmlReader.LocalName; + bool isEmptyElement = xamlDefTagNode.IsEmptyElement; + bool isProcessingCodeTag = false; + + do + { + XmlNodeType currNodeType = xmlReader.NodeType; + switch (currNodeType) + { + case XmlNodeType.Element: + { + if (isProcessingCodeTag) + { + ThrowCompilerException(SRID.DefnTagsCannotBeNested, DefinitionNSPrefix, LocalName, xmlReader.LocalName); + } + + switch (LocalName) + { + case CODETAG: + isProcessingCodeTag = true; + if (!IsCodeNeeded) + { + ThrowCompilerException(SRID.MissingClassDefinitionForCodeTag, + _ccRoot.ElementName, + DefinitionNSPrefix, + SourceFileInfo.RelativeSourceFilePath + XAML); + } + + bool moreAttributes = xmlReader.MoveToFirstAttribute(); + while (moreAttributes) + { + string attributeNamespaceUri = xmlReader.LookupNamespace(xmlReader.Prefix); + if (!attributeNamespaceUri.Equals(XamlReaderHelper.DefinitionNamespaceURI) || + !xmlReader.LocalName.Equals(XamlReaderHelper.DefinitionUid)) + { + ThrowCompilerException(SRID.AttributeNotAllowedOnCodeTag, + xmlReader.Name, + DefinitionNSPrefix, + CODETAG); + } + + moreAttributes = xmlReader.MoveToNextAttribute(); + } + + break; + + default: + ThrowCompilerException(SRID.UnknownDefinitionTag, DefinitionNSPrefix, LocalName); + break; + } + + // if an empty element do a Reader to + // get to the next node and then exit + if (isEmptyElement) + { + xmlReader.Read(); + exitLoop = true; + } + + break; + } + + case XmlNodeType.EndElement: + { + xmlReader.Read(); + exitLoop = true; + break; + } + + case XmlNodeType.CDATA: + case XmlNodeType.Text: + { + IXmlLineInfo xmlLineInfo = xmlReader as IXmlLineInfo; + int lineNumber = 0; + + if (null != xmlLineInfo) + { + lineNumber = xmlLineInfo.LineNumber; + } + + if (LocalName.Equals(CODETAG)) + { + AddCodeSnippet(xmlReader.Value, lineNumber); + } + else + { + ThrowCompilerException(SRID.IllegalCDataTextScoping, DefinitionNSPrefix, LocalName, (currNodeType == XmlNodeType.CDATA ? "a CDATA section" : "text content")); + } + + break; + } + } + } + while (!exitLoop && xmlReader.Read()); + } + +#endregion Definition Namespace processing + +#region Baml Hookup Functions + + private CodeMemberMethod EnsureStyleConnector() + { + if (_ccRoot.StyleConnectorFn == null) + { + _ccRoot.StyleConnectorFn = new CodeMemberMethod(); + _ccRoot.StyleConnectorFn.Name = CONNECT; + _ccRoot.StyleConnectorFn.Attributes = MemberAttributes.Public | MemberAttributes.Final; + _ccRoot.StyleConnectorFn.PrivateImplementationType = new CodeTypeReference(KnownTypes.Types[(int)KnownElements.IStyleConnector]); + + // void IStyleConnector.Connect(int connectionId, object target) { + // + CodeParameterDeclarationExpression param1 = new CodeParameterDeclarationExpression(typeof(int), CONNECTIONID); + CodeParameterDeclarationExpression param2 = new CodeParameterDeclarationExpression(typeof(object), TARGET); + _ccRoot.StyleConnectorFn.Parameters.Add(param1); + _ccRoot.StyleConnectorFn.Parameters.Add(param2); + + AddDebuggerNonUserCodeAttribute(_ccRoot.StyleConnectorFn); + AddGeneratedCodeAttribute(_ccRoot.StyleConnectorFn); + AddEditorBrowsableAttribute(_ccRoot.StyleConnectorFn); + AddSuppressMessageAttribute(_ccRoot.StyleConnectorFn, "Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes"); + AddSuppressMessageAttribute(_ccRoot.StyleConnectorFn, "Microsoft.Performance", "CA1800:DoNotCastUnnecessarily"); + AddSuppressMessageAttribute(_ccRoot.StyleConnectorFn, "Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity"); + + if (SwitchStatementSupported()) + { + // switch (connectionId) -- Start Switch + // { + CodeSnippetStatement css = new CodeSnippetStatement(SWITCH_STATEMENT); + _ccRoot.StyleConnectorFn.Statements.Add(css); + } + } + + return _ccRoot.StyleConnectorFn; + } + + internal void ConnectStyleEvent(XamlClrEventNode xamlClrEventNode) + { + CodeConditionStatement ccsConnector = null; + + // validate the event handler name per C# grammar for identifiers + ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value); + + EnsureStyleConnector(); + + if (!xamlClrEventNode.IsSameScope) + { + int connectionId = xamlClrEventNode.ConnectionId; + if (SwitchStatementSupported()) + { + // break any previous case staements as we are starting a new connection scope. + if (_ccRoot.StyleConnectorFn.Statements.Count > 1) + { + CodeSnippetStatement cssBreak = new CodeSnippetStatement(BREAK_STATEMENT); + _ccRoot.StyleConnectorFn.Statements.Add(cssBreak); + } + + // case 1: + // + CodeSnippetStatement cssCase = new CodeSnippetStatement(CASE_STATEMENT + connectionId + COLON); + _ccRoot.StyleConnectorFn.Statements.Add(cssCase); + } + else + { + // if (connectionId == 1) + // + ccsConnector = new CodeConditionStatement(); + ccsConnector.Condition = new CodeBinaryOperatorExpression(new CodeArgumentReferenceExpression(CONNECTIONID), + CodeBinaryOperatorType.ValueEquality, + new CodePrimitiveExpression(connectionId)); + } + } + else if (!SwitchStatementSupported()) + { + // if in the same scope then use the if statement that was last generated + // at the start of the scope + Debug.Assert(_ccRoot.StyleConnectorFn.Statements.Count > 0); + ccsConnector = _ccRoot.StyleConnectorFn.Statements[_ccRoot.StyleConnectorFn.Statements.Count - 1] as CodeConditionStatement; + Debug.Assert(ccsConnector != null); + } + + CodeArgumentReferenceExpression careTarget = new CodeArgumentReferenceExpression(TARGET); + + if (xamlClrEventNode.IsStyleSetterEvent) + { + // EventSetter declaration only once to avoid warning! + if (!_hasEmittedEventSetterDeclaration) + { + _hasEmittedEventSetterDeclaration = true; + + // EventSetter eventSetter; + // + CodeVariableDeclarationStatement cvdsES = new CodeVariableDeclarationStatement(KnownTypes.Types[(int)KnownElements.EventSetter], EVENTSETTER); + _ccRoot.StyleConnectorFn.Statements.Insert(0, cvdsES); + } + + + // eventSetter = new EventSetter(); + // + CodeExpression[] esParams = {}; + CodeVariableReferenceExpression cvreES = new CodeVariableReferenceExpression(EVENTSETTER); + CodeAssignStatement casES = new CodeAssignStatement(cvreES, + new CodeObjectCreateExpression(KnownTypes.Types[(int)KnownElements.EventSetter], + esParams)); + + // eventSetter.Event = Button.ClickEvent; + // + CodePropertyReferenceExpression cpreEvent = new CodePropertyReferenceExpression(cvreES, EVENT); + CodeAssignStatement casEvent = new CodeAssignStatement(cpreEvent, + GetEvent(xamlClrEventNode.EventMember, + xamlClrEventNode.EventName, + xamlClrEventNode.Value)); + + // eventSetter.Handler = new RoutedEventHandler(OnClick); + // + CodePropertyReferenceExpression cpreHandler = new CodePropertyReferenceExpression(cvreES, HANDLER); + CodeAssignStatement casHandler = new CodeAssignStatement(cpreHandler, + GetEventDelegate(null, + xamlClrEventNode.EventMember, + xamlClrEventNode.EventName, + xamlClrEventNode.Value)); + + AddLinePragma(casHandler, xamlClrEventNode.LineNumber); + + // ((Style)target).Setters.Add(eventSetter); + // + CodeCastExpression cceTarget = new CodeCastExpression(KnownTypes.Types[(int)KnownElements.Style], careTarget); + CodePropertyReferenceExpression cpreSetters = new CodePropertyReferenceExpression(cceTarget, SETTERS); + CodeMethodInvokeExpression cmieAdd = new CodeMethodInvokeExpression(cpreSetters, ADD, cvreES); + + if (SwitchStatementSupported()) + { + _ccRoot.StyleConnectorFn.Statements.Add(casES); + _ccRoot.StyleConnectorFn.Statements.Add(casEvent); + _ccRoot.StyleConnectorFn.Statements.Add(casHandler); + _ccRoot.StyleConnectorFn.Statements.Add(new CodeExpressionStatement(cmieAdd)); + } + else + { + ccsConnector.TrueStatements.Add(casES); + ccsConnector.TrueStatements.Add(casEvent); + ccsConnector.TrueStatements.Add(casHandler); + ccsConnector.TrueStatements.Add(new CodeExpressionStatement(cmieAdd)); + // Only add if statement at start of new scope + if (!xamlClrEventNode.IsSameScope) + { + _ccRoot.StyleConnectorFn.Statements.Add(ccsConnector); + } + } + } + else + { + + // + // ((Foo)target).Bar += new BarEventHandler(OnBar); + // + // *or* + // + // ((Foo)target).AddHandler( Baz.BarEvent, new BarEventHandler(OnBar)); + // + + CodeCastExpression cceTarget; + Type eventTarget; + + + // Create the markup event information + + MarkupEventInfo mei = new MarkupEventInfo( xamlClrEventNode.Value, // Event handler string + xamlClrEventNode.EventName, // Event name string + xamlClrEventNode.EventMember, // MemberInfo + xamlClrEventNode.LineNumber); // LineNumber + + + // Get the type that defines the event (e.g. typeof(Button) for Button.Clicked or typeof(Mouse) for Mouse.MouseMove) + + eventTarget = xamlClrEventNode.ListenerType; + + + // Create the type cast expression "(Foo)target" + + cceTarget = new CodeCastExpression( eventTarget, careTarget); + + + // Create the whole code statement (either in += form or in AddHandler form) + + CodeStatement csAddCLREvent = AddCLREvent( eventTarget, null, cceTarget, mei ); + + if (SwitchStatementSupported()) + { + _ccRoot.StyleConnectorFn.Statements.Add( csAddCLREvent ); + } + else + { + ccsConnector.TrueStatements.Add( csAddCLREvent ); + + // Only add if statement at start of new scope + if (!xamlClrEventNode.IsSameScope) + { + _ccRoot.StyleConnectorFn.Statements.Add(ccsConnector); + } + } + } + } + + private void EndStyleEventConnection() + { + if (_ccRoot.StyleConnectorFn != null) + { + _ccRoot.CodeClass.BaseTypes.Add(KnownTypes.Types[(int)KnownElements.IStyleConnector].FullName); + + if (SwitchStatementSupported()) + { + // break any last case staement as we are done with style event connections. + if (_ccRoot.StyleConnectorFn.Statements.Count > 1) + { + CodeSnippetStatement cssBreak = new CodeSnippetStatement(BREAK_STATEMENT); + _ccRoot.StyleConnectorFn.Statements.Add(cssBreak); + } + + // switch (connectionId) + // { + // } -- End Switch + CodeSnippetStatement css = new CodeSnippetStatement(INDENT12 + ENDCURLY); + _ccRoot.StyleConnectorFn.Statements.Add(css); + } + + _ccRoot.CodeClass.Members.Add(_ccRoot.StyleConnectorFn); + _ccRoot.StyleConnectorFn = null; + } + } + + private void EnsureHookupFn() + { + // void IComponentConnector.Connect + // + if (_ccRoot.HookupFn == null) + { + _ccRoot.HookupFn = new CodeMemberMethod(); + _ccRoot.HookupFn.Name = CONNECT; + _ccRoot.HookupFn.Attributes = MemberAttributes.Public | MemberAttributes.Final; + _ccRoot.HookupFn.PrivateImplementationType = new CodeTypeReference(KnownTypes.Types[(int)KnownElements.IComponentConnector]); + + // void IComponentConnector.Connect(int connectionId, object target) { + // + CodeParameterDeclarationExpression param1 = new CodeParameterDeclarationExpression(typeof(int), CONNECTIONID); + CodeParameterDeclarationExpression param2 = new CodeParameterDeclarationExpression(typeof(object), TARGET); + _ccRoot.HookupFn.Parameters.Add(param1); + _ccRoot.HookupFn.Parameters.Add(param2); + + AddDebuggerNonUserCodeAttribute(_ccRoot.HookupFn); + AddGeneratedCodeAttribute(_ccRoot.HookupFn); + AddEditorBrowsableAttribute(_ccRoot.HookupFn); + AddSuppressMessageAttribute(_ccRoot.HookupFn, "Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes"); + AddSuppressMessageAttribute(_ccRoot.HookupFn, "Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity"); + AddSuppressMessageAttribute(_ccRoot.HookupFn, "Microsoft.Performance", "CA1800:DoNotCastUnnecessarily"); + + if (SwitchStatementSupported()) + { + // switch (connectionId) -- Start Switch + // { + CodeSnippetStatement css = new CodeSnippetStatement(SWITCH_STATEMENT); + _ccRoot.HookupFn.Statements.Add(css); + } + } + } + + internal void ConnectNameAndEvents(string elementName, ArrayList events, int connectionId) + { + CodeContext cc = (CodeContext)_codeContexts.Peek(); + bool isAllowedNameScope = cc.IsAllowedNameScope; + + if (_codeContexts.Count > 1 && KnownTypes.Types[(int)KnownElements.INameScope].IsAssignableFrom(cc.ElementType)) + { + cc.IsAllowedNameScope = false; + } + + if ((elementName == null || !isAllowedNameScope) && (events == null || events.Count == 0)) + { + return; + } + + EnsureHookupFn(); + + CodeConditionStatement ccsConnector = null; + + if (SwitchStatementSupported()) + { + // case 1: + // + CodeSnippetStatement cssCase = new CodeSnippetStatement(CASE_STATEMENT + connectionId + COLON); + _ccRoot.HookupFn.Statements.Add(cssCase); + } + else + { + // if (connectionId == 1) + // + ccsConnector = new CodeConditionStatement(); + ccsConnector.Condition = new CodeBinaryOperatorExpression(new CodeArgumentReferenceExpression(CONNECTIONID), + CodeBinaryOperatorType.ValueEquality, + new CodePrimitiveExpression(connectionId)); + } + + + // (System.Windows.Controls.Footype)target; + CodeArgumentReferenceExpression careTarget = new CodeArgumentReferenceExpression(TARGET); + CodeCastExpression cceTarget = new CodeCastExpression(cc.ElementTypeReference, careTarget); + CodeExpression ceEvent = cceTarget; + + // Names in nested Name scopes not be hooked up via ICC.Connect() as no fields are generated in this case. + if (elementName != null && isAllowedNameScope) + { + // this.fooId = (System.Windows.Controls.Footype)target; + // + ceEvent = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), elementName); + CodeAssignStatement casName = new CodeAssignStatement(ceEvent, cceTarget); + if (SwitchStatementSupported()) + { + _ccRoot.HookupFn.Statements.Add(casName); + } + else + { + ccsConnector.TrueStatements.Add(casName); + } + } + + if (events != null) + { + foreach (MarkupEventInfo mei in events) + { + CodeStatement csEvent = AddCLREvent(cc, ceEvent, mei); + + if (SwitchStatementSupported()) + { + _ccRoot.HookupFn.Statements.Add(csEvent); + } + else + { + ccsConnector.TrueStatements.Add(csEvent); + } + } + } + + // return; + // + if (SwitchStatementSupported()) + { + _ccRoot.HookupFn.Statements.Add(new CodeMethodReturnStatement()); + } + else + { + ccsConnector.TrueStatements.Add(new CodeMethodReturnStatement()); + _ccRoot.HookupFn.Statements.Add(ccsConnector); + } + } + + // called from ParserExtension.WriteEndAttributes at the end of an element + // that has x:TypeArguments, to clear the state used to support them. + internal void ClearGenericTypeArgs() + { + _typeArgsList = null; + } + + private void EndHookups() + { + if (_ccRoot.HookupFn != null) + { + var iComponentConnector = new CodeTypeReference(KnownTypes.Types[(int)KnownElements.IComponentConnector]); + _ccRoot.CodeClass.BaseTypes.Add(iComponentConnector); + + // Visual Basic requires InitializeComponent to explicitly implement IComponentConnector.InitializeComponent + // if the class implements the interface. GenerateInitializeComponent handles the cases where the class is not + // the entry point for any programming language. + if (IsLanguageVB && IsCompilingEntryPointClass) + { + _ccRoot.InitializeComponentFn.ImplementationTypes.Add(iComponentConnector); + } + + if (SwitchStatementSupported()) + { + // Don't generate an empty Switch block! + if (_ccRoot.HookupFn.Statements.Count == 1 && + _ccRoot.HookupFn.Statements[0] is CodeSnippetStatement) + { + _ccRoot.HookupFn.Statements.Clear(); + } + else + { + // switch (connectionId) + // { + // } -- End Switch + CodeSnippetStatement css = new CodeSnippetStatement(INDENT12 + ENDCURLY); + _ccRoot.HookupFn.Statements.Add(css); + } + } + + // _contentLoaded = true; + // + CodeFieldReferenceExpression cfreContentLoaded = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), CONTENT_LOADED); + CodeAssignStatement casContentLoaded = new CodeAssignStatement(cfreContentLoaded, new CodePrimitiveExpression(true)); + _ccRoot.HookupFn.Statements.Add(casContentLoaded); + + _ccRoot.CodeClass.Members.Add(_ccRoot.HookupFn); + _ccRoot.HookupFn = null; + } + } + + internal void GenerateBamlFile(MemoryStream bamlMemStream) + { + // write baml file only if we're not doing intellisense build + if ((IsBamlNeeded) && (TaskFileService.IsRealBuild)) + { + string filepath = TargetPath + SourceFileInfo.RelativeSourceFilePath + BAML; + using (FileStream bamlFileStream = new FileStream(filepath, FileMode.Create, FileAccess.Write)) + { + bamlMemStream.WriteTo(bamlFileStream); + } + } + } + +#endregion Baml Hookup Functions + +#region Helpers + + private void InitializeReflectionHelper() + { + var paths = new List(ReferenceAssemblyList?.Count ?? 0); + if (ReferenceAssemblyList != null && ReferenceAssemblyList.Count > 0) + { + for (int i = 0; i < ReferenceAssemblyList.Count; i++) + { + ReferenceAssembly refasm = ReferenceAssemblyList[i] as ReferenceAssembly; + if (refasm != null && refasm.Path.Length > 0) + { + paths.Add(refasm.Path); + } + } + } + ReflectionHelper.Initialize(paths); + } + private void InitializeTypeMapper() + { + _typeMapper = XamlTypeMapper.DefaultMapper; + ReflectionHelper.LocalAssemblyName = AssemblyName; + + if (ReferenceAssemblyList != null && ReferenceAssemblyList.Count > 0) + { + for (int i = 0; i < ReferenceAssemblyList.Count; i++) + { + ReferenceAssembly refasm = ReferenceAssemblyList[i] as ReferenceAssembly; + + if (refasm != null && refasm.Path.Length > 0) + { + _typeMapper.SetAssemblyPath(refasm.AssemblyName, refasm.Path); + } + } + } + + string asmMissing = string.Empty; + if (XamlTypeMapper.AssemblyWB == null) + { + asmMissing = "WindowsBase"; + } + if (XamlTypeMapper.AssemblyPC == null) + { + asmMissing += (asmMissing.Length > 0 ? ", " : string.Empty) + "PresentationCore"; + } + if (XamlTypeMapper.AssemblyPF == null) + { + asmMissing += (asmMissing.Length > 0 ? ", " : string.Empty) + "PresentationFramework"; + } + + if (asmMissing.Length > 0) + { + string message = SR.Get(SRID.WinFXAssemblyMissing, asmMissing); + ApplicationException aeAssemblyMissing = new ApplicationException(message); + throw aeAssemblyMissing; + } + + KnownTypes.InitializeKnownTypes(XamlTypeMapper.AssemblyPF, XamlTypeMapper.AssemblyPC, XamlTypeMapper.AssemblyWB); + _typeMapper.InitializeReferenceXmlnsCache(); + } + + private bool SwitchStatementSupported() + { + return (IsLanguageCSharp || (CompilerInfo != null && (string.Compare(CompilerInfo.GetLanguages()[0], JSCRIPT, StringComparison.OrdinalIgnoreCase) == 0))); + } + + private bool IsInternalAccessSupported + { + get + { + return (CompilerInfo == null || (string.Compare(CompilerInfo.GetLanguages()[0], JSHARP, StringComparison.OrdinalIgnoreCase) != 0)); + } + } + + private bool IsLanguageCaseSensitive() + { + CodeDomProvider cdp = EnsureCodeProvider(); + return cdp.LanguageOptions != LanguageOptions.CaseInsensitive; + } + + private bool IsLanguageCSharp + { + get { return _isLangCSharp; } + } + + private bool IsLanguageVB + { + get { return _isLangVB; } + } + + // Combine namespace and className + private string GetFullClassName(string ns, string className) + { + string fullClass = className; + + if (ns != null && ns.Length > 0) + { + fullClass = ns + DOT + className; + } + + return fullClass; + } + + internal void ValidateFullSubClassName(ref string subClassFullName) + { + bool isValid = false; + int index = subClassFullName.LastIndexOf(DOT, StringComparison.Ordinal); + + if (index > 0) + { + string subClassName = subClassFullName.Substring(index + 1); + isValid = IsValidCLRNamespace(subClassFullName.Substring(0, index), false) && + IsValidClassName(subClassName); + } + else + { + isValid = IsValidClassName(subClassFullName); + } + + if (!isValid) + { + // flag error. Can't throw here as we are pre-scanning and parser context doesn't + // have customized linenum\linepos yet. + subClassFullName = DOT; + } + } + + private bool CrackClassName(ref string className, out string ns) + { + bool isValid = true; + ns = string.Empty; + + if (className.Length > 0) + { + // Split the Namespace + int index = className.LastIndexOf(DOT, StringComparison.Ordinal); + + if (index > 0) + { + ns = className.Substring(0, index); + className = className.Substring(index + 1); + isValid = IsValidCLRNamespace(ns, false); + } + + isValid = isValid && IsValidClassName(className); + } + + return isValid; + } + + internal string GetGenericTypeName(string typeName, string typeArgs) + { + if (typeArgs.Length == 0) + { + ThrowCompilerException(SRID.UnknownGenericType, + DefinitionNSPrefix, + typeArgs, + typeName); + } + + StringBuilder sb = new StringBuilder(typeName, 20); + sb.Append(GENERIC_DELIMITER); + + _typeArgsList = typeArgs.Split(new Char[] { COMMA }); + + sb.Append(_typeArgsList.Length); + + return sb.ToString(); + } + + private static void AddEditorBrowsableAttribute(CodeTypeMember ctmTarget) + { + CodeFieldReferenceExpression cfre = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EditorBrowsableState)), "Never"); + CodeAttributeArgument caa = new CodeAttributeArgument(cfre); + ctmTarget.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(EditorBrowsableAttribute).FullName, caa)); + } + + private static void AddSuppressMessageAttribute(CodeTypeMember ctmTarget, string category, string rule) + { + CodeAttributeDeclaration cad = new CodeAttributeDeclaration( + new CodeTypeReference(typeof(SuppressMessageAttribute)), + new CodeAttributeArgument(new CodePrimitiveExpression(category)), + new CodeAttributeArgument(new CodePrimitiveExpression(rule))); + + ctmTarget.CustomAttributes.Add(cad); + } + + private static void AddDebuggerNonUserCodeAttribute(CodeTypeMember ctmTarget) + { + CodeAttributeDeclaration cad = new CodeAttributeDeclaration( + new CodeTypeReference(typeof(DebuggerNonUserCodeAttribute))); + + ctmTarget.CustomAttributes.Add(cad); + } + + internal static void GenerateXmlComments(CodeTypeMember ctm, string comment) + { + // generate xml comments + + // /// + // /// + CodeCommentStatement ccs = new CodeCommentStatement(SummaryStartTag, true); + ctm.Comments.Add(ccs); + ccs = new CodeCommentStatement(comment, true); + ctm.Comments.Add(ccs); + ccs = new CodeCommentStatement(SummaryEndTag, true); + ctm.Comments.Add(ccs); + } + + private bool IsValidClassName(string className) + { + if (className.Length == 0 ||!NameValidationHelper.IsValidIdentifierName(className)) + { + return false; + } + + return true; + } + + private bool IsValidCLRNamespace(string ns, bool shouldThrow) + { + if (ns.Length > 0) + { + string[] nsParts = ns.Split(new char[] { DOTCHAR }); + + foreach (string nsPart in nsParts) + { + if (!NameValidationHelper.IsValidIdentifierName(nsPart.Trim())) + { + if (shouldThrow) + { + ThrowCompilerException(SRID.InvalidDefaultCLRNamespace, nsPart, ns); + } + else + { + return false; + } + } + } + } + + return true; + } + + internal void ValidateEventHandlerName(string eventName, string handlerName) + { + if (!IsCodeNeeded) + { + ThrowCompilerException(SRID.MissingClassDefinitionForEvent, _ccRoot.ElementName, DefinitionNSPrefix, eventName); + } + + string handler = handlerName.Trim(); + if (handler.Length == 0) + { + ThrowCompilerException(SRID.EmptyEventStringNotAllowed, eventName, handlerName); + } + else if (!NameValidationHelper.IsValidIdentifierName(handler)) + { + ThrowCompilerException(SRID.InvalidEventHandlerName, eventName, handlerName); + } + } + + private string ParentFolderPrefix + { + get + { + string parentFolderPrefix = string.Empty; + if (TargetPath.StartsWith(SourceFileInfo.SourcePath, StringComparison.OrdinalIgnoreCase)) + { + string relPath = TargetPath.Substring(SourceFileInfo.SourcePath.Length); + relPath += SourceFileInfo.RelativeSourceFilePath; + string[] dirs = relPath.Split(new Char[] { ESCAPED_BACKSLASH_CHAR }); + for (int i = 1; i < dirs.Length; i++) + { + parentFolderPrefix += PARENTFOLDER; + } + } + + return parentFolderPrefix; + } + } + + private void AddLinePragma(CodeTypeMember ctm, int lineNumber) + { + CodeLinePragma clp = new CodeLinePragma(ParentFolderPrefix + SourceFileInfo.RelativeSourceFilePath + XAML, lineNumber); + ctm.LinePragma = clp; + } + + private void AddLinePragma(CodeStatement cs, int lineNumber) + { + CodeLinePragma clp = new CodeLinePragma(ParentFolderPrefix + SourceFileInfo.RelativeSourceFilePath + XAML, lineNumber); + cs.LinePragma = clp; + } + + internal MemberAttributes GetMemberAttributes(string modifier) + { + if (!IsCodeNeeded) + { + ThrowCompilerException(SRID.MissingClassWithFieldModifier, DefinitionNSPrefix); + } + + if (_private.Length == 0) + { + bool converted = false; + CodeDomProvider codeProvider = EnsureCodeProvider(); + TypeConverter converter = codeProvider.GetConverter(typeof(MemberAttributes)); + if (converter != null) + { + if (converter.CanConvertTo(typeof(string))) + { + try + { + _private = converter.ConvertToInvariantString(MemberAttributes.Private).ToLowerInvariant(); + _public = converter.ConvertToInvariantString(MemberAttributes.Public).ToLowerInvariant(); + _protected = converter.ConvertToInvariantString(MemberAttributes.Family).ToLowerInvariant(); + _internal = converter.ConvertToInvariantString(MemberAttributes.Assembly).ToLowerInvariant(); + _protectedInternal = converter.ConvertToInvariantString(MemberAttributes.FamilyOrAssembly).ToLowerInvariant(); + converted = true; + } + catch (NotSupportedException) + { + } + } + } + + if (!converted) + { + ThrowCompilerException(SRID.UnknownFieldModifier, MarkupCompiler.DefinitionNSPrefix, modifier, _language); + } + } + + string normalizedModifier = modifier; + if (!IsLanguageCaseSensitive()) + { + normalizedModifier = modifier.ToLowerInvariant(); + } + + if (normalizedModifier.Equals(_private)) + { + return MemberAttributes.Private; + } + else if (normalizedModifier.Equals(_public)) + { + return MemberAttributes.Public; + } + else if (normalizedModifier.Equals(_protected)) + { + return MemberAttributes.Family; + } + else if (normalizedModifier.Equals(_internal)) + { + return MemberAttributes.Assembly; + } + else if (normalizedModifier.Equals(_protectedInternal)) + { + return MemberAttributes.FamilyOrAssembly; + } + else + { + ThrowCompilerException(SRID.UnknownFieldModifier, MarkupCompiler.DefinitionNSPrefix, modifier, _language); + } + + return MemberAttributes.Assembly; + } + + private TypeAttributes GetTypeAttributes(ref string modifier) + { + if (modifier.Length > 0) + { + if (_privateClass.Length == 0) + { + bool converted = false; + CodeDomProvider codeProvider = EnsureCodeProvider(); + TypeConverter converter = codeProvider.GetConverter(typeof(TypeAttributes)); + if (converter != null) + { + if (converter.CanConvertTo(typeof(string))) + { + try + { + _privateClass = converter.ConvertToInvariantString(TypeAttributes.NotPublic).ToLowerInvariant(); + _publicClass = converter.ConvertToInvariantString(TypeAttributes.Public).ToLowerInvariant(); + converted = true; + } + catch (NotSupportedException) + { + } + } + } + + if (!converted) + { + ThrowCompilerException(SRID.UnknownClassModifier, MarkupCompiler.DefinitionNSPrefix, modifier, _language); + } + } + + string normalizedModifier = modifier; + if (!IsLanguageCaseSensitive()) + { + normalizedModifier = modifier.ToLowerInvariant(); + } + + if (normalizedModifier.Equals(_privateClass)) + { + return TypeAttributes.NotPublic; + } + else if (normalizedModifier.Equals(_publicClass)) + { + return TypeAttributes.Public; + } + else + { + // flag error. Can't throw here as we are pre-scanning and parser context doesn't + // have customized linenum\linepos yet. + modifier = DOT; + } + } + + return TypeAttributes.Public; + } + + internal void CheckForNestedNameScope() + { + CodeContext cc = (CodeContext)_codeContexts.Peek(); + if (_codeContexts.Count > 1 && KnownTypes.Types[(int)KnownElements.INameScope].IsAssignableFrom(cc.ElementType)) + { + cc.IsAllowedNameScope = false; + } + } + +#endregion Helpers + +#region Property + + private CodeExpression GetPropertyValueExpression(ITypeDescriptorContext ctx, Type typeToConvertTo, Object value, string attributeValue) + { + CodeExpression ce = null; + InstanceDescriptor desc = null; + TypeConverter converter = null; + + if (value != null && (typeToConvertTo == typeof(String) || typeToConvertTo.IsPrimitive)) + { + ce = new CodePrimitiveExpression(value); + } + else if (typeToConvertTo == typeof(Uri)) + { + converter = new UriTypeConverter(); + if (!UriParser.IsKnownScheme(URISCHEME_PACK)) + { + UriParser.Register(new GenericUriParser(GenericUriParserOptions.GenericAuthority), URISCHEME_PACK, -1); + } + } + else if (typeToConvertTo.IsEnum) + { + converter = new EnumConverter(typeToConvertTo); + } + + if (converter != null) + { + if (value == null) + { + if (attributeValue != null) + { + value = converter.ConvertFromString(ctx, TypeConverterHelper.InvariantEnglishUS, attributeValue); + + if (value == null) + { + return null; + } + } + else + { + ce = new CodePrimitiveExpression(null); + return ce; + } + } + + if (converter.CanConvertTo(ctx, typeof(InstanceDescriptor))) + { + desc = (InstanceDescriptor)converter.ConvertTo(ctx, TypeConverterHelper.InvariantEnglishUS, value, typeof(InstanceDescriptor)); + + Debug.Assert(desc != null); + + // static field ref... + if (desc.MemberInfo is FieldInfo || desc.MemberInfo is PropertyInfo) + { + CodeFieldReferenceExpression cfre = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(desc.MemberInfo.DeclaringType.FullName), desc.MemberInfo.Name); + ce = cfre; + } + else // static method invoke + { + object[] args = new object[desc.Arguments.Count]; + desc.Arguments.CopyTo(args, 0); + CodeExpression[] expressions = new CodeExpression[args.Length]; + + if (desc.MemberInfo is MethodInfo) + { + MethodInfo mi = (MethodInfo)desc.MemberInfo; + ParameterInfo[] parameters = mi.GetParameters(); + + for (int i = 0; i < args.Length; i++) + { + expressions[i] = GetPropertyValueExpression(ctx, parameters[i].ParameterType, args[i], null); + } + + CodeMethodInvokeExpression cmie = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(desc.MemberInfo.DeclaringType.FullName), desc.MemberInfo.Name); + foreach (CodeExpression e in expressions) + { + cmie.Parameters.Add(e); + } + + ce = cmie; + } + else if (desc.MemberInfo is ConstructorInfo) // instance ctor invoke + { + ConstructorInfo ci = (ConstructorInfo)desc.MemberInfo; + ParameterInfo[] parameters = ci.GetParameters(); + + for (int i = 0; i < args.Length; i++) + { + expressions[i] = GetPropertyValueExpression(ctx, parameters[i].ParameterType, args[i], null); + } + + CodeObjectCreateExpression coce = new CodeObjectCreateExpression(desc.MemberInfo.DeclaringType.FullName); + foreach (CodeExpression e in expressions) + { + coce.Parameters.Add(e); + } + + ce = coce; + } + } + } + } + + return ce; + } + +#endregion Property + +#region Event + + // The given MemberInfo could either be an EventInfo for a Clr event or a + // MethodInfo for a static Add{EventName}Handler helper for an attached event + private Type GetEventHandlerType(MemberInfo memberInfo) + { + Type eventHandlerType = null; + if (memberInfo is EventInfo) + { + EventInfo ei = (EventInfo)memberInfo; + eventHandlerType = ei.EventHandlerType; + } + else + { + MethodInfo mi = (MethodInfo)memberInfo; + ParameterInfo[] pis = mi.GetParameters(); + Debug.Assert(pis != null && pis.Length == 2 && KnownTypes.Types[(int)KnownElements.DependencyObject].IsAssignableFrom(pis[0].ParameterType)); + eventHandlerType = pis[1].ParameterType; + } + + return eventHandlerType; + } + + private CodeFieldReferenceExpression GetEvent(MemberInfo miEvent, string eventName, string eventHandler) + { + FieldInfo fiEvent = miEvent.DeclaringType.GetField(eventName + EVENT, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + if (fiEvent == null || fiEvent.FieldType != KnownTypes.Types[(int)KnownElements.RoutedEvent]) + { + ThrowCompilerException(SRID.RoutedEventNotRegistered, miEvent.DeclaringType.FullName, eventName, eventHandler); + } + + CodeTypeReferenceExpression ctreEvent = new CodeTypeReferenceExpression(miEvent.DeclaringType.FullName); + CodeFieldReferenceExpression cfreEvent = new CodeFieldReferenceExpression(ctreEvent, fiEvent.Name); + return cfreEvent; + } + + + private CodeExpression GetEventDelegate(CodeContext cc, MemberInfo miEvent, string eventName, string eventHandler) + { + Type eventTarget = cc != null ? cc.ElementType : miEvent.DeclaringType; + string eventTargetName = eventTarget != null ? eventTarget.FullName : cc.LocalElementFullName; + + bool subClassed = _ccRoot.SubClass.Length > 0; + CodeDelegateCreateExpression cdce = new CodeDelegateCreateExpression(); + + // Fetch the EventHandlerType from either the EventInfo or the MethodInfo + // for the Add{Propertyname}Handler method's MethodInfo + Type eventHandlerType = GetEventHandlerType(miEvent); + string [] typeArgsList = cc != null ? cc.GenericTypeArgs : null; + + cdce.DelegateType = GenerateConstructedTypeReference(eventHandlerType, typeArgsList, eventTarget, eventTargetName, eventName); + cdce.MethodName = eventHandler.Trim() + (subClassed ? HELPER : string.Empty); + cdce.TargetObject = new CodeThisReferenceExpression(); + CodeExpression cDelExp = cdce; + + // NOTE: workaround for VB CodeDom bug which does not produce correct Delegate expression code + if (IsLanguageVB) + { + CodeExpression[] delParams = { cdce }; + CodeObjectCreateExpression coce = new CodeObjectCreateExpression(eventHandlerType, delParams); + cDelExp = coce; + } + + +// The bug that this chunk of code works around was fixed but +// exposes a different bug. To work around the second bug, we +// remove the workaround for the first one. +// Note that the initial bug was not fixed for VB, so the code block above remains. +// else if (Language == CompilerLanguage.JScript) +// { +// CodeCastExpression cce = new CodeCastExpression(mei.ei.EventHandlerType, cdce); +// cDelExp = cce; +// } + + return cDelExp; + } + + + private CodeStatement AddCLREvent(CodeContext cc, CodeExpression ce, MarkupEventInfo mei) + { + // Infer the event target's (aka the listener) type from the current code context + return AddCLREvent( cc.ElementType, cc, ce, mei ); + } + + private CodeStatement AddCLREvent(Type eventTarget, CodeContext cc, CodeExpression ce, MarkupEventInfo mei) + { + + bool subClassed = _ccRoot.SubClass.Length > 0; + CodeStatement csEvent = null; + // param2: + CodeExpression cDelExp = GetEventDelegate(cc, mei.mi, mei.eventName, mei.eventHandler); + + if (mei.mi.DeclaringType.IsAssignableFrom(eventTarget)) + { + // _element.FooEvent += new FooEventHandlerDelegate(OnFoo); + csEvent = new CodeAttachEventStatement(ce, mei.eventName, cDelExp); + } + else if (eventTarget == null || // for known attached events on unknown local tags + KnownTypes.Types[(int)KnownElements.UIElement].IsAssignableFrom(eventTarget) || + KnownTypes.Types[(int)KnownElements.ContentElement].IsAssignableFrom(eventTarget)) + { + // _element.AddHandler(FooEvent, new FooEventHandlerDelegate(OnFoo)); + CodeFieldReferenceExpression cfreEvent = GetEvent(mei.mi, mei.eventName, mei.eventHandler); + CodeMethodInvokeExpression cmieAddHandler = new CodeMethodInvokeExpression(ce, ADDHANDLER, cfreEvent, cDelExp); + csEvent = new CodeExpressionStatement(cmieAddHandler); + } + else + { + string eventTargetName = eventTarget != null ? eventTarget.FullName : cc.LocalElementFullName; + ThrowCompilerException(SRID.UnknownEventAttribute, mei.eventName, mei.eventHandler, eventTargetName); + } + + // When x:SubClass is used, event handlers can be specified in a code-behind file, under this sub class. + // But these handler methods need to be accessible from the intermediary generated sub class. So an empty + // internal virtual method with the same signature as the handler method is generated in this intermediary + // sub class (in the generated file): + // + // internal virtual void OnFooEvent(object sender, FooEventArgs ea) + // { + // } + // + // Since a delegate cannot take the address of a virtual function, a non-virtual helper function + // with the same signature as the above function & which calls the above function is also generated: + // + // private void OnFooEventHelper(object sender, FooEventArgs ea) + // { + // OnFooEvent(sender, ea); + // } + // + // All this is done only if x:Subclass is specified, since this means that this sub class would need to be + // defined in a code-behind file. This also means that inline events (in ) will not be supported. + + if (subClassed) + { + GenerateProtectedEventHandlerMethod(mei); + } + + AddLinePragma(csEvent, mei.lineNumber); + return csEvent; + } + + private void GenerateProtectedEventHandlerMethod(MarkupEventInfo mei) + { + Debug.Assert(_ccRoot != null && _ccRoot.SubClass.Length > 0); + + // Fetch the EventHandlerType from either the EventInfo or the MethodInfo + // for the Add{Propertyname}Handler method's MethodInfo + Type eventHandlerType = GetEventHandlerType(mei.mi); + + MethodInfo methodInvoke = eventHandlerType.GetMethod("Invoke"); + ParameterInfo[] pars = methodInvoke.GetParameters(); + + CodeMemberMethod cmmEventHandler = new CodeMemberMethod(); + CodeMemberMethod cmmEventHandlerHelper = new CodeMemberMethod(); + + AddDebuggerNonUserCodeAttribute(cmmEventHandlerHelper); + AddGeneratedCodeAttribute(cmmEventHandlerHelper); + + cmmEventHandler.Attributes = MemberAttributes.Assembly | MemberAttributes.Overloaded; + cmmEventHandler.ReturnType = new CodeTypeReference(typeof(void)); + cmmEventHandler.Name = mei.eventHandler.Trim(); + + CodeMethodInvokeExpression cmieOnEvent = new CodeMethodInvokeExpression(null, cmmEventHandler.Name); + + for (int i = 0; i < pars.Length; i++) + { + CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(pars[i].ParameterType, pars[i].Name); + cmmEventHandler.Parameters.Add(param); + cmmEventHandlerHelper.Parameters.Add(param); + cmieOnEvent.Parameters.Add(new CodeArgumentReferenceExpression(pars[i].Name)); + } + + // + // internal virtual void OnFooEvent(object sender, FooEventArgs ea) + // { + // } + // + _ccRoot.CodeClass.Members.Add(cmmEventHandler); + + cmmEventHandlerHelper.Name = cmmEventHandler.Name + HELPER; + cmmEventHandlerHelper.ReturnType = new CodeTypeReference(typeof(void)); + cmmEventHandlerHelper.Statements.Add(new CodeExpressionStatement(cmieOnEvent)); + + // + // private void OnFooEventHelper(object sender, FooEventArgs ea) + // { + // OnFooEvent(sender, ea); + // } + // + _ccRoot.CodeClass.Members.Add(cmmEventHandlerHelper); + } + + internal struct MarkupEventInfo + { + internal MarkupEventInfo(string eh, string en, MemberInfo mi, int ln) + { + eventHandler = eh; + eventName = en; + this.mi = mi; + lineNumber = ln; + } + + internal string eventHandler; + internal string eventName; + internal MemberInfo mi; + internal int lineNumber; + } + +#endregion Event + +#region Language + + private CodeDomProvider EnsureCodeProvider() + { + if (_codeProvider == null) + { + Debug.Assert(CompilerInfo != null && CompilerInfo.IsCodeDomProviderTypeValid); + _codeProvider = CompilerInfo.CreateProvider(); + } + + return _codeProvider; + } + + private bool IsLanguageSupported(string language) + { + _language = language; + _isLangCSharp = string.Compare(language, CSHARP, StringComparison.OrdinalIgnoreCase) == 0; + + if (IsLanguageCSharp) + { + _codeProvider = new Microsoft.CSharp.CSharpCodeProvider(); + return true; + } + else + { + _isLangVB = string.Compare(language, VB, StringComparison.OrdinalIgnoreCase) == 0; + if (IsLanguageVB) + { + _codeProvider = new Microsoft.VisualBasic.VBCodeProvider(); + return true; + } + } + + if (CodeDomProvider.IsDefinedLanguage(language)) + { + CompilerInfo = CodeDomProvider.GetCompilerInfo(language); + return (CompilerInfo != null); + } + + return false; + } + + private void EnsureLanguageSourceExtension() + { + // If empty string is passed, use the default language source extension. + if (String.IsNullOrEmpty(LanguageSourceExtension)) + { + if (CompilerInfo != null) + { + string[] listExtensions = CompilerInfo.GetExtensions(); + LanguageSourceExtension = listExtensions[0]; + } + else if (IsLanguageCSharp) + { + LanguageSourceExtension = ".cs"; + } + else if (IsLanguageVB) + { + LanguageSourceExtension = ".vb"; + } + } + } + +#endregion Language + +#region CorePageGen + + internal CodeMemberField AddNameField(string name, int lineNumber, int linePosition) + { + CodeMemberField cmField = NameField(name, lineNumber, linePosition); + if (cmField != null) + { + AddLinePragma(cmField, lineNumber); + } + return cmField; + } + + internal CodeMemberField NameField(string name, int lineNumber, int linePosition) + { + // Warn for named ResourceDictionary items. + if (_codeContexts.Count >= 2) + { + Type resourceDictionary = KnownTypes.Types[(int)KnownElements.ResourceDictionary]; + Type iNameScope = KnownTypes.Types[(int)KnownElements.INameScope]; + object[] contexts = _codeContexts.ToArray(); + for (int i = 1; i < contexts.Length; ++i) + { + Type t = ((CodeContext)contexts[i]).ElementType; + if (iNameScope.IsAssignableFrom(t)) + { + break; + } + if (resourceDictionary.IsAssignableFrom(t)) + { + _taskLogger.LogWarningFromResources( + null, + null, + null, + SourceFileInfo.OriginalFilePath, + lineNumber, + linePosition, + 0, + 0, + SRID.NamedResDictItemWarning, + ((CodeContext)_codeContexts.Peek()).ElementType.FullName, + name + ); + break; + } + } + } + // Names in nested Name scopes should not have Name fields + CodeContext cc = (CodeContext)_codeContexts.Peek(); + if (!cc.IsAllowedNameScope) + { + return null; + } + + CodeMemberField field = new CodeMemberField(); + field.Name = name; + field.Attributes = MemberAttributes.Assembly; + field.Type = cc.ElementTypeReference; + field.CustomAttributes.Add( + new CodeAttributeDeclaration( + new CodeTypeReference("System.Diagnostics.CodeAnalysis.SuppressMessageAttribute"), + new CodeAttributeArgument(new CodePrimitiveExpression("Microsoft.Performance")), + new CodeAttributeArgument(new CodePrimitiveExpression("CA1823:AvoidUnusedPrivateFields")))); + + + // Generate WithEvents ID fields in VB for objects supporting events + field.UserData["WithEvents"] = true; + + _ccRoot.CodeClass.Members.Add(field); + return field; + } + + private void AddCodeSnippet(string codeText, int lineNum) + { + if (codeText == null || codeText.Trim().Length == 0) + return; + + CodeSnippetTypeMember snippet = new CodeSnippetTypeMember(); + AddLinePragma(snippet, lineNum); + snippet.Text = codeText; + _ccRoot.CodeClass.Members.Add(snippet); + } + + internal void AddGenericArguments(ParserContext parserContext, string typeArgs) + { + if (_typeArgsList != null) + { + string localTypeArgNamespace = string.Empty; + string localTypeArgClassName = string.Empty; + + // for each generic param in this Type ... + for (int i = 0; i < _typeArgsList.Length; i++) + { + Type currTypeArg = parserContext.XamlTypeMapper.GetTypeArgsType(_typeArgsList[i].Trim(), + parserContext, + out localTypeArgClassName, + out localTypeArgNamespace); + + if (currTypeArg == null) + { + bool error = false; + if (localTypeArgNamespace.Length == 0 && localTypeArgClassName.Length == 0) + { + error = true; + } + else + { + error = !IsValidClassName(localTypeArgClassName) || + !IsValidCLRNamespace(localTypeArgNamespace, false); + } + + if (error) + { + ThrowCompilerException(SRID.InvalidTypeName, + MarkupCompiler.DefinitionNSPrefix, + typeArgs, + _typeArgsList[i].Trim(), + (i + 1).ToString(CultureInfo.CurrentCulture)); + } + else + { + _typeArgsList[i] = GetFullClassName(localTypeArgNamespace, localTypeArgClassName); + } + } + else + { + _typeArgsList[i] = currTypeArg.FullName; + } + + // construct the type args list for the base class type to be generated + _ccRoot.CodeClass.BaseTypes[0].TypeArguments.Add(new CodeTypeReference(_typeArgsList[i])); + } + } + } + + private static CodeTypeReference GenerateConstructedTypeReference(Type t, string [] typeArgsList, string genericName) + { + CodeTypeReference ctrConstructedType = null; + + // If the type has generic parameters, then need to add TypeArguments to the CodeTypeReference of this Type + if (genericName.Length > 0 || t.IsGenericType) + { + Debug.Assert(genericName.Length > 0 || t.IsGenericTypeDefinition); + + if (t != null) + { + Debug.Assert(genericName.Length == 0 && typeArgsList != null); + + // NOTE: Remove when CodeDom is fixed to understand mangled generic names. + genericName = t.FullName; + int bang = genericName.IndexOf(GENERIC_DELIMITER, StringComparison.Ordinal); + if (bang > 0) + { + genericName = genericName.Substring(0, bang); + } +#if DBG + Type[] typeParams = t.GetGenericArguments(); + + // TypeArgument count must match TypeParameter count on generic type. + Debug.Assert(typeArgsList != null && typeArgsList.Length == typeParams.Length); + + // for each generic param in this Type ... + for (int i = 0; i < typeArgsList.Length; i++) + { + // Type params should always be unbound + Debug.Assert(typeParams[i].IsGenericParameter); + } +#endif + } + + ctrConstructedType = new CodeTypeReference(genericName); + } + else + { + ctrConstructedType = new CodeTypeReference(t.FullName); + } + + return ctrConstructedType; + } + + private static CodeTypeReference GenerateConstructedTypeReference(Type t, string [] typeArgsList, Type refType, string refTypeFullName, string eventName) + { + CodeTypeReference ctrConstructedType = null; + + // If the type has generic parameters, then need to add TypeArguments to the CodeTypeReference of this Type + if (t.IsGenericType) + { + Type[] refTypeParams = null; + CodeTypeReference ctrTypeArg = null; + Type[] typeParams = t.GetGenericArguments(); + + // NOTE: Remove when CodeDom is fixed to understand mangled generic names. + string genericName = t.Namespace + DOT + t.Name; + int bang = genericName.IndexOf(GENERIC_DELIMITER, StringComparison.Ordinal); + if (bang > 0) + { + genericName = genericName.Substring(0, bang); + } + + ctrConstructedType = new CodeTypeReference(genericName); + + // NOTE: For certain types like EventHandler delegate types, CodeDom seems + // to add bogus CodeTypeReferences as TypeArguments, so it needs to be cleared explicitly. + ctrConstructedType.TypeArguments.Clear(); + + // for each generic param in this Type ... + foreach (Type typeParam in typeParams) + { + // if the param is unbound + if (typeParam.IsGenericParameter) + { + // get the generic params of the containing\reference Type, only once + if (refTypeParams == null) + { + if (refType == null || !refType.IsGenericType || !refType.IsGenericTypeDefinition || typeArgsList == null) + { + ThrowCompilerException(SRID.ContainingTagNotGeneric, eventName, ctrConstructedType.BaseType, refTypeFullName); + } + + refTypeParams = refType.GetGenericArguments(); + } + + ctrTypeArg = null; + + // for each reference generic param + for (int i = 0; i < refTypeParams.Length; i++) + { + // if it matches the current generic param of this Type + if (refTypeParams[i] == typeParam) + { + // The TypeArgumentList must have already been populated with full Type names & + // the TypeArgument count must match TypeParameter count on generic reference type. + Debug.Assert(typeArgsList != null && typeArgsList.Length == refTypeParams.Length); + + // Find the Type argument from the list that is in the same position as generic Type param + string currTypeArg = typeArgsList[i]; + + // and create a CodeTypeReference from it + ctrTypeArg = new CodeTypeReference(currTypeArg); + break; + } + } + + // no match! + if (ctrTypeArg == null) + { + ThrowCompilerException(SRID.MatchingTypeArgsNotFoundInRefType, + eventName, + ctrConstructedType.BaseType, + typeParam.FullName, + refTypeFullName + "<" + string.Join(",", typeArgsList) + ">"); + } + } + else + { + ctrTypeArg = new CodeTypeReference(typeParam); + } + + // construct the type args list for the base class type to be generated + ctrConstructedType.TypeArguments.Add(ctrTypeArg); + } + } + else + { + ctrConstructedType = new CodeTypeReference(t.FullName); + } + + return ctrConstructedType; + } + + private static void AddGeneratedCodeAttribute(CodeTypeMember ctmTarget) + { + if (s_generatedCode_ToolName == null || s_generatedCode_ToolVersion == null) + { + AssemblyName assemblyName = new AssemblyName(Assembly.GetExecutingAssembly().FullName); + s_generatedCode_ToolName = assemblyName.Name; + s_generatedCode_ToolVersion = assemblyName.Version.ToString(); + } + + CodeAttributeDeclaration cad = new CodeAttributeDeclaration( + new CodeTypeReference(typeof(GeneratedCodeAttribute)), + new CodeAttributeArgument(new CodePrimitiveExpression(s_generatedCode_ToolName)), + new CodeAttributeArgument(new CodePrimitiveExpression(s_generatedCode_ToolVersion))); + + ctmTarget.CustomAttributes.Add(cad); + } + + private CodeTypeDeclaration GenerateClass(string className, ref string modifier, Type baseClass, string baseClassFullName) + { + // public class MyClass : BaseClass { + // + CodeTypeReference ctrBaseClass = null; + CodeTypeDeclaration ctdClass = new CodeTypeDeclaration(); + ctdClass.Name = className; + if (baseClass != null) + { + // At this point, we should only have fully open generic types if there is a typeargs list. + Debug.Assert(_typeArgsList == null || (baseClass.IsGenericType && baseClass.IsGenericTypeDefinition)); + Debug.Assert(_typeArgsList != null || !baseClass.IsGenericType); + + ctrBaseClass = GenerateConstructedTypeReference(baseClass, _typeArgsList, string.Empty); + + // Add the type reference for the normal or fully constructed generic base class + ctdClass.BaseTypes.Add(ctrBaseClass); + } + else if (baseClassFullName.Length > 0) + { + ctrBaseClass = GenerateConstructedTypeReference(null, _typeArgsList, baseClassFullName); + + // Add the type reference for the local base class + ctdClass.BaseTypes.Add(ctrBaseClass); + } + + ctdClass.TypeAttributes = GetTypeAttributes(ref modifier); + ctdClass.Members.Clear(); + + if (TypeAttributes.Public == ctdClass.TypeAttributes) + { + GenerateXmlComments(ctdClass, className); + } + + // VBNOTE: The VB compiler will generate a ctor with an InitializeComponent call if not explicitly specified + // by the user if this Attribute is set on the class. + if (IsLanguageVB && !IsCompilingEntryPointClass) + { + ctdClass.CustomAttributes.Add(new CodeAttributeDeclaration("Microsoft.VisualBasic.CompilerServices.DesignerGenerated")); + } + + return ctdClass; + } + + private CodeContext GenerateSubClass(ref string className, ref string modifier, Type baseClass, string baseClassFullName) + { + string ns = string.Empty; + string baseClassName = string.Empty; + bool isValidClassName = CrackClassName(ref className, out ns); + + if (!string.IsNullOrEmpty(baseClassFullName)) + { + int dotIndex = baseClassFullName.LastIndexOf(DOTCHAR); + if (dotIndex != -1) + { + baseClassName = baseClassFullName.Substring(dotIndex + 1); + if (!IsValidClassName(baseClassName)) + { + ThrowCompilerException(SRID.InvalidBaseClassName, baseClassName); + } + string bns = baseClassFullName.Substring(0, dotIndex); + if (!IsValidCLRNamespace(bns, false)) + { + ThrowCompilerException(SRID.InvalidBaseClassNamespace, bns, baseClassName); + } + } + } + + if (!isValidClassName) + { + // flag error. Can't throw here as we are pre-scanning and parser context doesn't + // have customized linenum\linepos yet. + className = DOT; + } + else if (IsCompilingEntryPointClass && className.Length == 0) + { + string baseName = baseClass != null ? baseClass.Name : baseClassName; + className = ANONYMOUS_ENTRYCLASS_PREFIX + baseName; + Debug.Assert(!string.IsNullOrEmpty(baseName)); + ns = XamlTypeMapper.GeneratedNamespace; + } + + // namespace MyNamespace + // { + Debug.Assert(_ccRoot == null); + Debug.Assert(_codeContexts == null || _codeContexts.Count == 0, "mismatched CodeContexts"); + CodeNamespace cns = new CodeNamespace(); + cns.Name = ns; + cns.Types.Clear(); + + CodeTypeDeclaration ctdClass = GenerateClass(className, ref modifier, baseClass, baseClassFullName); + CodeContext cc = new CodeContextRoot(ctdClass, cns, baseClass, _typeArgsList, baseClassFullName); + cc.ElementTypeReference = new CodeTypeReference(GetFullClassName(ns, className)); + + return cc; + } + + private void GenerateCreateDelegateHelper() + { + if (!IsInternalAccessSupported || !HasLocalEvent) + { + return; + } + + Debug.Assert(HasLocalReference, "if we have a local event, there should be a local mapping PI for it"); + + // internal Delegate _CreateDelegate(Type delegateType, string handler) + // { + // return Delegate.CreateDelegate(delegateType, this, handler); + // } + // + CodeMemberMethod cmmCD = new CodeMemberMethod(); + cmmCD.Name = CREATEDELEGATEHELPER; + cmmCD.ReturnType = new CodeTypeReference(typeof(Delegate)); + cmmCD.Attributes = MemberAttributes.Assembly | MemberAttributes.Final; + AddDebuggerNonUserCodeAttribute(cmmCD); + AddGeneratedCodeAttribute(cmmCD); + AddSuppressMessageAttribute(cmmCD, "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode"); + + CodeParameterDeclarationExpression param1 = new CodeParameterDeclarationExpression(typeof(Type), DELEGATETYPE); + CodeParameterDeclarationExpression param2 = new CodeParameterDeclarationExpression(typeof(string), HANDLERARG); + cmmCD.Parameters.Add(param1); + cmmCD.Parameters.Add(param2); + + CodeMethodReferenceExpression cmreCD = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(Delegate)), "CreateDelegate"); + CodeMethodInvokeExpression cmieCD = new CodeMethodInvokeExpression(); + cmieCD.Method = cmreCD; + cmieCD.Parameters.Add(new CodeArgumentReferenceExpression(DELEGATETYPE)); + cmieCD.Parameters.Add(new CodeThisReferenceExpression()); + cmieCD.Parameters.Add(new CodeArgumentReferenceExpression(HANDLERARG)); + + cmmCD.Statements.Add(new CodeMethodReturnStatement(cmieCD)); + _ccRoot.CodeClass.Members.Add(cmmCD); + } + + private void GenerateInitializeComponent(bool isApp) + { + // public void InitializeComponent() + // { + // + CodeMemberMethod cmmLC = _ccRoot.InitializeComponentFn; + + if (cmmLC == null) + { + cmmLC = _ccRoot.EnsureInitializeComponentFn; + if (!isApp) + { + cmmLC.ImplementationTypes.Add(new CodeTypeReference(KnownTypes.Types[(int)KnownElements.IComponentConnector])); + } + } + + // if (_contentLoaded) + // { + // return; + // } + // + CodeConditionStatement ccsCL = new CodeConditionStatement(); + ccsCL.Condition = new CodeFieldReferenceExpression(null, CONTENT_LOADED); + ccsCL.TrueStatements.Add(new CodeMethodReturnStatement()); + if (!isApp) + { + cmmLC.Statements.Add(ccsCL); + } + else + { + cmmLC.Statements.Insert(0, ccsCL); + } + + // _contentLoaded = true; + // + CodeAssignStatement casCL = new CodeAssignStatement(new CodeFieldReferenceExpression(null, CONTENT_LOADED), + new CodePrimitiveExpression(true)); + if (!isApp) + { + cmmLC.Statements.Add(casCL); + } + else + { + cmmLC.Statements.Insert(1, casCL); + } + + // Generate canonicalized string as resource id. + bool requestExtensionChange = false; + string resourceID = ResourcesGenerator.GetResourceIdForResourceFile( + SourceFileInfo.RelativeSourceFilePath + XAML, + SourceFileInfo.OriginalFileLinkAlias, + SourceFileInfo.OriginalFileLogicalName, + TargetPath, + Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar, + requestExtensionChange); + + string uriPart = string.Empty; + + string version = String.IsNullOrEmpty(AssemblyVersion) ? String.Empty : COMPONENT_DELIMITER + VER + AssemblyVersion; + string token = String.IsNullOrEmpty(AssemblyPublicKeyToken) ? String.Empty : COMPONENT_DELIMITER + AssemblyPublicKeyToken; + uriPart = FORWARDSLASH + AssemblyName + version + token + COMPONENT_DELIMITER + COMPONENT + FORWARDSLASH + resourceID; + + // + // Uri resourceLocator = new Uri(uriPart, UriKind.Relative); + // + string resVarname = RESOURCE_LOCATER; + + CodeFieldReferenceExpression cfreRelUri = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(System.UriKind)), "Relative"); + + CodeExpression[] uriParams = { new CodePrimitiveExpression(uriPart), cfreRelUri }; + CodeObjectCreateExpression coceResourceLocator = new CodeObjectCreateExpression(typeof(System.Uri), uriParams); + CodeVariableDeclarationStatement cvdsresLocator = new CodeVariableDeclarationStatement(typeof(System.Uri), resVarname, coceResourceLocator); + + cmmLC.Statements.Add(cvdsresLocator); + + // + // System.Windows.Application.LoadComponent(this, resourceLocator); + // + CodeMethodReferenceExpression cmreLoadContent = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(KnownTypes.Types[(int)KnownElements.Application]), LOADCOMPONENT); + CodeMethodInvokeExpression cmieLoadContent = new CodeMethodInvokeExpression(); + + cmieLoadContent.Method = cmreLoadContent; + + CodeVariableReferenceExpression cvreMemStm = new CodeVariableReferenceExpression(resVarname); + + cmieLoadContent.Parameters.Add(new CodeThisReferenceExpression()); + cmieLoadContent.Parameters.Add(cvreMemStm); + + CodeExpressionStatement cesLC = new CodeExpressionStatement(cmieLoadContent); + AddLinePragma(cesLC, 1); + cmmLC.Statements.Add(cesLC); + + // private bool _contentLoaded; + // + CodeMemberField cmfCL = new CodeMemberField(); + cmfCL.Name = CONTENT_LOADED; + cmfCL.Attributes = MemberAttributes.Private; + cmfCL.Type = new CodeTypeReference(typeof(bool)); + _ccRoot.CodeClass.Members.Add(cmfCL); + + if (!isApp) + { + // Make sure that ICC.Connect is generated to avoid compilation errors + EnsureHookupFn(); + } + } + + private void GenerateInternalTypeHelperImplementation() + { + if (!IsInternalAccessSupported || + !(HasInternals || HasLocalReference) || + _hasGeneratedInternalTypeHelper) + { + return; + } + + _hasGeneratedInternalTypeHelper = true; + + // namespace XamlGeneratedNamespace + // { + // + CodeNamespace cns = new CodeNamespace(); + cns.Name = XamlTypeMapper.GeneratedNamespace; + + // [EditorBrowsable(EditorBrowsableState.Never)] + // public sealed class GeneratedInternalTypeHelper : InternalTypeHelper + // { + // + CodeTypeDeclaration ctdClass = new CodeTypeDeclaration(); + ctdClass.Name = XamlTypeMapper.GeneratedInternalTypeHelperClassName; + ctdClass.BaseTypes.Add(new CodeTypeReference("System.Windows.Markup.InternalTypeHelper")); + ctdClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed; + AddDebuggerNonUserCodeAttribute(ctdClass); + AddGeneratedCodeAttribute(ctdClass); + AddEditorBrowsableAttribute(ctdClass); + GenerateXmlComments(ctdClass, ctdClass.Name); + + // protected override object CreateInstance(Type type, CultureInfo culture) + // { + // return Activator.CreateInstance(type, + // BindingFlags.Public | + // BindingFlags.NonPublic | + // BindingFlags.Instance | + // BindingFlags.CreateInstance, + // null, + // null, + // culture); + // } + // + CodeMemberMethod cmmCI = new CodeMemberMethod(); + cmmCI.Name = "CreateInstance"; + cmmCI.Attributes = MemberAttributes.Family | MemberAttributes.Override; + cmmCI.ReturnType = new CodeTypeReference(typeof(Object)); + + CodeParameterDeclarationExpression param1 = new CodeParameterDeclarationExpression(typeof(Type), TYPE); + CodeParameterDeclarationExpression param4 = new CodeParameterDeclarationExpression(typeof(CultureInfo), CULTURE); + cmmCI.Parameters.Add(param1); + cmmCI.Parameters.Add(param4); + + CodeMethodReferenceExpression cmreCI = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(Activator)), "CreateInstance"); + CodeMethodInvokeExpression cmieCI = new CodeMethodInvokeExpression(); + cmieCI.Method = cmreCI; + cmieCI.Parameters.Add(new CodeArgumentReferenceExpression(TYPE)); + CodeFieldReferenceExpression cfre1 = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(BindingFlags)), "Public"); + CodeFieldReferenceExpression cfre2 = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(BindingFlags)), "NonPublic"); + CodeFieldReferenceExpression cfre3 = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(BindingFlags)), "Instance"); + CodeFieldReferenceExpression cfre4 = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(BindingFlags)), "CreateInstance"); + CodeBinaryOperatorExpression cboe1 = new CodeBinaryOperatorExpression(cfre1, CodeBinaryOperatorType.BitwiseOr, cfre2); + CodeBinaryOperatorExpression cboe2 = new CodeBinaryOperatorExpression(cfre3, CodeBinaryOperatorType.BitwiseOr, cfre4); + CodeBinaryOperatorExpression cboeCI = new CodeBinaryOperatorExpression(cboe1, CodeBinaryOperatorType.BitwiseOr, cboe2); + cmieCI.Parameters.Add(cboeCI); + cmieCI.Parameters.Add(new CodePrimitiveExpression(null)); + cmieCI.Parameters.Add(new CodePrimitiveExpression(null)); + cmieCI.Parameters.Add(new CodeArgumentReferenceExpression(CULTURE)); + + cmmCI.Statements.Add(new CodeMethodReturnStatement(cmieCI)); + GenerateXmlComments(cmmCI, cmmCI.Name); + ctdClass.Members.Add(cmmCI); + + // protected override object GetPropertyValue(PropertyInfo propertyInfo, object target, CultureInfo culture) + // { + // return propertyInfo.GetValue(target, BindingFlags.Default, null, null, culture); + // } + // + CodeMemberMethod cmmGPV = new CodeMemberMethod(); + cmmGPV.Name = "GetPropertyValue"; + cmmGPV.Attributes = MemberAttributes.Family | MemberAttributes.Override; + cmmGPV.ReturnType = new CodeTypeReference(typeof(Object)); + + param1 = new CodeParameterDeclarationExpression(typeof(PropertyInfo), PROPINFO); + CodeParameterDeclarationExpression param2 = new CodeParameterDeclarationExpression(typeof(object), TARGET); + cmmGPV.Parameters.Add(param1); + cmmGPV.Parameters.Add(param2); + cmmGPV.Parameters.Add(param4); + + CodeMethodReferenceExpression cmreGPV = new CodeMethodReferenceExpression(new CodeArgumentReferenceExpression(PROPINFO), "GetValue"); + CodeMethodInvokeExpression cmieGPV = new CodeMethodInvokeExpression(); + cmieGPV.Method = cmreGPV; + cmieGPV.Parameters.Add(new CodeArgumentReferenceExpression(TARGET)); + cmieGPV.Parameters.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(BindingFlags)), DEFAULT)); + cmieGPV.Parameters.Add(new CodePrimitiveExpression(null)); + cmieGPV.Parameters.Add(new CodePrimitiveExpression(null)); + cmieGPV.Parameters.Add(new CodeArgumentReferenceExpression(CULTURE)); + + cmmGPV.Statements.Add(new CodeMethodReturnStatement(cmieGPV)); + GenerateXmlComments(cmmGPV, cmmGPV.Name); + ctdClass.Members.Add(cmmGPV); + + // protected override void SetPropertyValue(PropertyInfo propertyInfo, object target, object value, CultureInfo culture) + // { + // propertyInfo.SetValue(target, value, BindingFlags.Default, null, null, culture); + // } + // + CodeMemberMethod cmmSPV = new CodeMemberMethod(); + cmmSPV.Name = "SetPropertyValue"; + cmmSPV.Attributes = MemberAttributes.Family | MemberAttributes.Override; + + CodeParameterDeclarationExpression param3 = new CodeParameterDeclarationExpression(typeof(object), VALUE); + cmmSPV.Parameters.Add(param1); + cmmSPV.Parameters.Add(param2); + cmmSPV.Parameters.Add(param3); + cmmSPV.Parameters.Add(param4); + + CodeMethodReferenceExpression cmreSPV = new CodeMethodReferenceExpression(new CodeArgumentReferenceExpression(PROPINFO), "SetValue"); + CodeMethodInvokeExpression cmieSPV = new CodeMethodInvokeExpression(); + cmieSPV.Method = cmreSPV; + cmieSPV.Parameters.Add(new CodeArgumentReferenceExpression(TARGET)); + cmieSPV.Parameters.Add(new CodeArgumentReferenceExpression(VALUE)); + cmieSPV.Parameters.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(BindingFlags)), DEFAULT)); + cmieSPV.Parameters.Add(new CodePrimitiveExpression(null)); + cmieSPV.Parameters.Add(new CodePrimitiveExpression(null)); + cmieSPV.Parameters.Add(new CodeArgumentReferenceExpression(CULTURE)); + + cmmSPV.Statements.Add(new CodeExpressionStatement(cmieSPV)); + GenerateXmlComments(cmmSPV, cmmSPV.Name); + ctdClass.Members.Add(cmmSPV); + + // protected override Delegate CreateDelegate(Type delegateType, object target, string handler) + // { + // return (Delegate)target.GetType().InvokeMember("_CreateDelegate", + // BindingFlags.Instance | + // BindingFlags.NonPublic | + // BindingFlags.InvokeMethod, + // null, + // target, + // new object[] { delegateType, handler }); + // } + // + CodeMemberMethod cmmCD = new CodeMemberMethod(); + cmmCD.Name = "CreateDelegate"; + cmmCD.Attributes = MemberAttributes.Family | MemberAttributes.Override; + cmmCD.ReturnType = new CodeTypeReference(typeof(Delegate)); + + param1 = new CodeParameterDeclarationExpression(typeof(Type), DELEGATETYPE); + param3 = new CodeParameterDeclarationExpression(typeof(string), HANDLERARG); + cmmCD.Parameters.Add(param1); + cmmCD.Parameters.Add(param2); + cmmCD.Parameters.Add(param3); + + CodeArgumentReferenceExpression careTarget = new CodeArgumentReferenceExpression(TARGET); + CodeMethodReferenceExpression cmreGetType = new CodeMethodReferenceExpression(careTarget, "GetType"); + CodeMethodInvokeExpression cmieGetType = new CodeMethodInvokeExpression(); + cmieGetType.Method = cmreGetType; + + CodeMethodReferenceExpression cmreCD = new CodeMethodReferenceExpression(cmieGetType, "InvokeMember"); + CodeMethodInvokeExpression cmieCD = new CodeMethodInvokeExpression(); + cmieCD.Method = cmreCD; + cmieCD.Parameters.Add(new CodePrimitiveExpression(CREATEDELEGATEHELPER)); + + CodeFieldReferenceExpression cfre5 = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(BindingFlags)), "InvokeMethod"); + CodeBinaryOperatorExpression cboe = new CodeBinaryOperatorExpression(cfre2, CodeBinaryOperatorType.BitwiseOr, cfre3); + CodeBinaryOperatorExpression cboeCD = new CodeBinaryOperatorExpression(cfre5, CodeBinaryOperatorType.BitwiseOr, cboe); + cmieCD.Parameters.Add(cboeCD); + + cmieCD.Parameters.Add(new CodePrimitiveExpression(null)); + cmieCD.Parameters.Add(careTarget); + + CodeArrayCreateExpression caceCD = new CodeArrayCreateExpression(typeof(object)); + CodeArgumentReferenceExpression careDelType = new CodeArgumentReferenceExpression(DELEGATETYPE); + CodeArgumentReferenceExpression careHandler = new CodeArgumentReferenceExpression(HANDLERARG); + caceCD.Initializers.Add(careDelType); + caceCD.Initializers.Add(careHandler); + cmieCD.Parameters.Add(caceCD); + cmieCD.Parameters.Add(new CodePrimitiveExpression(null)); + + CodeCastExpression cceCD = new CodeCastExpression(typeof(Delegate), cmieCD); + cmmCD.Statements.Add(new CodeMethodReturnStatement(cceCD)); + GenerateXmlComments(cmmCD, cmmCD.Name); + ctdClass.Members.Add(cmmCD); + + // protected override void AddEventHandler(EventInfo eventInfo, object target, Delegate handler); + // { + // eventInfo.AddEventHandler(target, handler); + // } + // + CodeMemberMethod cmmAEH = new CodeMemberMethod(); + cmmAEH.Name = "AddEventHandler"; + cmmAEH.Attributes = MemberAttributes.Family | MemberAttributes.Override; + + param1 = new CodeParameterDeclarationExpression(typeof(EventInfo), EVENTINFO); + param3 = new CodeParameterDeclarationExpression(typeof(Delegate), HANDLERARG); + cmmAEH.Parameters.Add(param1); + cmmAEH.Parameters.Add(param2); + cmmAEH.Parameters.Add(param3); + + CodeMethodReferenceExpression cmreAEH = new CodeMethodReferenceExpression(new CodeArgumentReferenceExpression(EVENTINFO), "AddEventHandler"); + CodeMethodInvokeExpression cmieAEH = new CodeMethodInvokeExpression(); + cmieAEH.Method = cmreAEH; + cmieAEH.Parameters.Add(new CodeArgumentReferenceExpression(TARGET)); + cmieAEH.Parameters.Add(new CodeArgumentReferenceExpression(HANDLERARG)); + + cmmAEH.Statements.Add(new CodeExpressionStatement(cmieAEH)); + GenerateXmlComments(cmmAEH, cmmAEH.Name); + ctdClass.Members.Add(cmmAEH); + + // } + // + cns.Types.Add(ctdClass); + + // } + // + CodeCompileUnit ccu = new CodeCompileUnit(); + ccu.Namespaces.Add(cns); + + // For VB only we need to let the parser know about the RootNamespace value + // in order to look for the XamlGeneratedNamespace.GeneratedInternalTypeHelper + // type whose full type name would have been implicitly by the VB comopiler to + // RootNS.XamlGeneratedNamespace.GeneratedInternalTypeHelper + + if (IsLanguageVB && !string.IsNullOrEmpty(DefaultNamespace)) + { + // [assembly: RootNamespaceAttribute("RootNS")] + CodeAttributeDeclaration cad = new CodeAttributeDeclaration( + "System.Windows.Markup.RootNamespaceAttribute", + new CodeAttributeArgument(new CodePrimitiveExpression(DefaultNamespace))); + + ccu.AssemblyCustomAttributes.Add(cad); + } + + MemoryStream codeMemStream = new MemoryStream(); + + // using Disposes the StreamWriter when it ends. Disposing the StreamWriter + // also closes the underlying MemoryStream. Furthermore, don't add BOM here since + // TaskFileService.WriteGeneratedCodeFile adds it. + using (StreamWriter codeStreamWriter = new StreamWriter(codeMemStream, new UTF8Encoding(false))) + { + CodeGeneratorOptions o = new CodeGeneratorOptions(); + CodeDomProvider codeProvider = EnsureCodeProvider(); + codeProvider.GenerateCodeFromCompileUnit(ccu, codeStreamWriter, o); + + codeStreamWriter.Flush(); + TaskFileService.WriteGeneratedCodeFile(codeMemStream.ToArray(), + TargetPath + SharedStrings.GeneratedInternalTypeHelperFileName, + SharedStrings.GeneratedExtension, SharedStrings.IntellisenseGeneratedExtension, + LanguageSourceExtension); + } + } + + internal string StartElement(ref string className, string subClassFullName, ref string modifier, Type elementType, string baseClassFullName) + { + string classFullName = null; + CodeContext cc = null; + + if (_ccRoot == null) + { + if (className.Length > 0) + { + IsCodeNeeded = true; + } + else if (subClassFullName.Length > 0) + { + ThrowCompilerException(SRID.MissingClassWithSubClass, DefinitionNSPrefix); + } + else if (modifier.Length > 0) + { + ThrowCompilerException(SRID.MissingClassWithModifier, DefinitionNSPrefix); + } + else if (_typeArgsList != null) + { + string rootClassName = elementType != null ? elementType.Name : baseClassFullName.Substring(baseClassFullName.LastIndexOf(DOT, StringComparison.Ordinal)+1); + ThrowCompilerException(SRID.MissingClassDefinitionForTypeArgs, rootClassName, DefinitionNSPrefix); + } + + // Don't allow subclassing further from markup-subclasses with content + if (elementType != null && KnownTypes.Types[(int)KnownElements.IComponentConnector].IsAssignableFrom(elementType)) + { + ThrowCompilerException(SRID.SubSubClassingNotAllowed, elementType.FullName); + } + + cc = GenerateSubClass(ref className, ref modifier, elementType, baseClassFullName); + Debug.Assert(_codeContexts.Count == 0, "mismatched codecontext"); + _ccRoot = cc as CodeContextRoot; + Debug.Assert(_ccRoot != null); + + if (IsCodeNeeded) + { + if (subClassFullName.Length > 0) + { + classFullName = subClassFullName; + _ccRoot.SubClass = classFullName; + } + else + { + classFullName = GetFullClassName(_ccRoot.CodeNS.Name, _ccRoot.CodeClass.Name); + } + + if (IsLanguageVB) + { + // This classFullName is going to be used to write Root Start Element. + // If it is for VB, and DefaultClrName is set, we need to put DefaultClrName + // as prefix to any existing full class name. + // + // if this x:Class is set to "MyNS.MyPage, and RootNamespace (DefaultNamespace) + // is set to MyRoot, the finally generated class by VBC would be MyRoot.MyNS.MyPage. + // so in the Baml record, it should keep MyRoot.MyNS.MyPage. + // + + classFullName = GetFullClassName(DefaultNamespace, classFullName); + } + } + + if (IsCompilingEntryPointClass) + { + cc.IsAllowedNameScope = false; + } + } + else + { + cc = new CodeContext(elementType, null, baseClassFullName); + CodeContext ccParent = (CodeContext)_codeContexts.Peek(); + cc.IsAllowedNameScope = ccParent.IsAllowedNameScope; + } + + _codeContexts.Push(cc); + + return classFullName; + } + + internal void EndElement(bool pass2) + { + CodeContext cc = (CodeContext)_codeContexts.Pop(); + Debug.Assert(cc != null); + + if (_codeContexts.Count == 0) + { + Debug.Assert(_ccRoot == (cc as CodeContextRoot)); + Debug.Assert(_ccRoot.CodeClass != null); + + if (!pass2) + { + // For entry point class, a sub-class is always needed + // even if if wasn't otherwise needed by other markup + // like x:Code or events etc. upto this point. + if (IsCompilingEntryPointClass) + { + IsCodeNeeded = true; + } + + if (IsCodeNeeded) + { + if (IsBamlNeeded) + { + GenerateInitializeComponent(IsCompilingEntryPointClass); + if (!IsCompilingEntryPointClass) + { + GenerateCreateDelegateHelper(); + } + } + else + { + Debug.Assert(_ccRoot.HookupFn == null); + } + + EndHookups(); + EndStyleEventConnection(); + } + + GenerateSource(); + } + } + } + + internal void AddUsing(string clrNS) + { + if (String.IsNullOrEmpty(clrNS)) + { + return; + } + + if (_usingNS == null) + { + _usingNS = new ArrayList(); + } + + _usingNS.Add(clrNS); + } + +#endregion CorePageGen + +#region App Entry Point + + // This code block is shared by regular Application and HostInBrowser Application + private CodeVariableReferenceExpression GenerateAppInstance(CodeMemberMethod cmmMain) + { + string appClassName = _ccRoot.SubClass.Length > 0 ? _ccRoot.SubClass + : GetFullClassName(_ccRoot.CodeNS.Name, _ccRoot.CodeClass.Name); + + // MyNS.MyApplication app = new MyNS.MyApplication(); + // + CodeObjectCreateExpression coce; + CodeVariableReferenceExpression cvre = new CodeVariableReferenceExpression(APPVAR); + CodeExpression[] ctorParams = {}; + + coce = new CodeObjectCreateExpression(appClassName, ctorParams); + + CodeVariableDeclarationStatement cvds = new CodeVariableDeclarationStatement(appClassName, APPVAR, coce); + + cmmMain.Statements.Add(cvds); + + return cvre; + } + + internal void AddApplicationProperty(MemberInfo memberInfo, string attributeValue, int lineNumber) + { + Debug.Assert(_ccRoot == (_codeContexts.Peek() as CodeContextRoot)); + Debug.Assert(_ccRoot.ElementType == null || + (memberInfo.DeclaringType.IsAssignableFrom(_ccRoot.ElementType) && (memberInfo is PropertyInfo))); + + TypeConvertContext ctx = new TypeConvertContext(_parserContext, attributeValue); + CodeExpression ceValue = GetPropertyValueExpression(ctx, typeof(Uri), null, attributeValue); + CodeThisReferenceExpression ctreTag = new CodeThisReferenceExpression(); + CodePropertyReferenceExpression cprePropSet = new CodePropertyReferenceExpression(ctreTag, memberInfo.Name); + + CodeStatement csPropSet = new CodeAssignStatement(cprePropSet, ceValue); + + AddLinePragma(csPropSet, lineNumber); + + _ccRoot.EnsureInitializeComponentFn.Statements.Add(csPropSet); + } + + internal void AddApplicationEvent(MarkupEventInfo mei) + { + // validate the event handler name per C# grammar for identifiers + ValidateEventHandlerName(mei.eventName, mei.eventHandler); + + // this.FooEvent += new FooEventHandlerDelegate(this.OnFoo); + CodeThisReferenceExpression ctre = new CodeThisReferenceExpression(); + CodeStatement csEvent = AddCLREvent(_ccRoot, ctre, mei); + + Debug.Assert(_ccRoot == (_codeContexts.Peek() as CodeContextRoot)); + _ccRoot.EnsureInitializeComponentFn.Statements.Add(csEvent); + } + + private CodeMemberMethod GenerateEntryPointMethod() + { + CodeMemberMethod cmmMain = null; + CodeDomProvider codeProvider = EnsureCodeProvider(); + + if (codeProvider.Supports(GeneratorSupport.EntryPointMethod)) + { + // + // [STAThread] + // public static void Main () { + // + + cmmMain = new CodeEntryPointMethod(); + cmmMain.Attributes = MemberAttributes.Public | MemberAttributes.Static; + cmmMain.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(STAThreadAttribute).FullName)); + AddDebuggerNonUserCodeAttribute(cmmMain); + AddGeneratedCodeAttribute(cmmMain); + GenerateXmlComments(cmmMain, "Application Entry Point."); + cmmMain.ReturnType = new CodeTypeReference(typeof(void)); + } + + return cmmMain; + } + + private void GenerateAppEntryPoint() + { + if (ApplicationFile.Length > 0) + { + + // [STAThread] + // public static void Main () { + // + CodeMemberMethod cmmMain = GenerateEntryPointMethod(); + + if (cmmMain != null) + { + CodeVariableReferenceExpression cvreSplashScreen = null; + if (!string.IsNullOrEmpty(_splashImage) && !HostInBrowser) + { + cvreSplashScreen = GenerateSplashScreenInstance(cmmMain); + } + + // MyApplication app = new MyApplication(); + // + CodeVariableReferenceExpression cvreApp = GenerateAppInstance(cmmMain); + + if (_ccRoot.InitializeComponentFn != null) + { + // app.InitializeComponent(); + // + CodeMethodInvokeExpression cmieIT = new CodeMethodInvokeExpression(); + cmieIT.Method = new CodeMethodReferenceExpression(cvreApp, INITIALIZE_COMPONENT); + cmmMain.Statements.Add(new CodeExpressionStatement(cmieIT)); + } + + if (!HostInBrowser) + { + // app.Run(); + // + CodeMethodReferenceExpression cmreRun = new CodeMethodReferenceExpression(cvreApp, "Run"); + CodeMethodInvokeExpression cmieRun = new CodeMethodInvokeExpression(); + cmieRun.Method = cmreRun; + + CodeStatement csRun = new CodeExpressionStatement(cmieRun); + cmmMain.Statements.Add(csRun); + } + + _ccRoot.CodeClass.Members.Add(cmmMain); + } + } + } + + private void GenerateLooseContentAttributes() + { + CodeDomProvider codeProvider = EnsureCodeProvider(); + + if (codeProvider.Supports(GeneratorSupport.AssemblyAttributes)) + { + CodeCompileUnit ccu = new CodeCompileUnit(); + + foreach (string file in ContentList) + { + // [assembly: AssemblyAssociatedContentFileAttribute("file")] + + string normalized = ResourceIDHelper.GetResourceIDFromRelativePath(file); + CodeAttributeDeclaration cad = new CodeAttributeDeclaration( + "System.Windows.Resources.AssemblyAssociatedContentFileAttribute", + new CodeAttributeArgument(new CodePrimitiveExpression(normalized))); + + ccu.AssemblyCustomAttributes.Add(cad); + } + + MemoryStream codeMemStream = new MemoryStream(); + + // using Disposes the StreamWriter when it ends. Disposing the StreamWriter + // also closes the underlying MemoryStream. Furthermore, don't add BOM here since + // TaskFileService.WriteGeneratedCodeFile adds it. + using (StreamWriter codeStreamWriter = new StreamWriter(codeMemStream, new UTF8Encoding(false))) + { + CodeGeneratorOptions o = new CodeGeneratorOptions(); + codeProvider.GenerateCodeFromCompileUnit(ccu, codeStreamWriter, o); + + codeStreamWriter.Flush(); + TaskFileService.WriteGeneratedCodeFile(codeMemStream.ToArray(), + TargetPath + AssemblyName + SharedStrings.ContentFile, + SharedStrings.GeneratedExtension, SharedStrings.IntellisenseGeneratedExtension, + LanguageSourceExtension); + } + } + } + +#endregion App Entry Point + +#region Splash Screen Code Generation + + private CodeVariableReferenceExpression GenerateSplashScreenInstance(CodeMemberMethod cmmMain) + { + // SplashScreen splashScreen = new SplashScreen(Assembly.GetExecutingAssembly(), "splash.png"); + CodeObjectCreateExpression coceApplicationSplashScreen = new CodeObjectCreateExpression(SPLASHCLASSNAME, new CodePrimitiveExpression(GetSplashResourceId())); + // ApplicationSplashScreen splashScreen = ... + CodeVariableDeclarationStatement cvdsAppSplash = new CodeVariableDeclarationStatement(SPLASHCLASSNAME, SPLASHVAR, coceApplicationSplashScreen); + cmmMain.Statements.Add(cvdsAppSplash); + + // splashScreen.Show(true); + CodeVariableReferenceExpression cvreAppSplash = new CodeVariableReferenceExpression(SPLASHVAR); + CodeMethodInvokeExpression cmieShowSplashScreen = new CodeMethodInvokeExpression(cvreAppSplash, "Show", new CodePrimitiveExpression(true)); + cmmMain.Statements.Add(cmieShowSplashScreen); + + return cvreAppSplash; + } + + private string GetSplashResourceId() + { + // Perform the same resouce string mangle that is done in ResourceGenerator + string resourceId; + string fullFilePath = Path.GetFullPath(_splashImage); + string relPath = TaskHelper.GetRootRelativePath(TargetPath, fullFilePath); + + // + // If the resFile is relative to the StagingDir (OutputPath here) + // take the relative path as resource id. + // If the resFile is not relative to StagingDir, but relative + // to the project directory, take this relative path as resource id. + // Otherwise, just take the file name as resource id. + // + + if (string.IsNullOrEmpty(relPath)) + { + relPath = TaskHelper.GetRootRelativePath(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar, fullFilePath); + } + + if (string.IsNullOrEmpty(relPath) == false) + { + resourceId = relPath; + } + else + { + resourceId = Path.GetFileName(fullFilePath); + } + + // Modify resource ID to correspond to canonicalized Uri format + // i.e. - all lower case, use "/" as separator + // ' ' is converted to escaped version %20 + // + + resourceId = ResourceIDHelper.GetResourceIDFromRelativePath(resourceId); + + return resourceId; + } + +#endregion + +#region CodeContext + + private class CodeContext + { + internal CodeContext(Type elementType, string [] typeArgsList, string localElementFullName) + { + _elementType = elementType; + _typeArgsList = typeArgsList; + _localElementFullName = localElementFullName; + } + + internal Type ElementType + { + get { return _elementType; } + } + + internal string ElementName + { + get { return _elementType != null ? _elementType.Name : _localElementFullName.Substring(_localElementFullName.LastIndexOf(DOT, StringComparison.Ordinal) + 1); } + } + + internal string [] GenericTypeArgs + { + get { return _typeArgsList; } + } + + internal string LocalElementFullName + { + get { return _localElementFullName; } + } + + internal bool IsAllowedNameScope + { + get { return _isAllowedNameScope; } + set { _isAllowedNameScope = value; } + } + + internal CodeTypeReference ElementTypeReference + { + get + { + if (_ctrElemTypeRef == null) + { + _ctrElemTypeRef = MarkupCompiler.GenerateConstructedTypeReference(_elementType, _typeArgsList, _localElementFullName); + } + + return _ctrElemTypeRef; + } + + set { _ctrElemTypeRef = value; } + } + + private bool _isAllowedNameScope = true; + private Type _elementType = null; + private string [] _typeArgsList = null; + private string _localElementFullName = string.Empty; + protected CodeTypeReference _ctrElemTypeRef = null; + } + + private class CodeContextRoot : CodeContext + { + internal CodeContextRoot(CodeTypeDeclaration codeClass, + CodeNamespace codeNS, + Type elementType, + string [] typeArgsList, + string localElementFullName) : base (elementType, typeArgsList, localElementFullName) + { + _codeNS = codeNS; + _codeClass = codeClass; + _ctrElemTypeRef = codeClass.BaseTypes[0]; + } + + internal CodeMemberMethod HookupFn + { + get { return _hookupFn; } + set { _hookupFn = value; } + } + + internal CodeMemberMethod StyleConnectorFn + { + get { return _styleConnectorFn; } + set { _styleConnectorFn = value; } + } + + internal CodeMemberMethod InitializeComponentFn + { + get { return _initializeComponentFn; } + } + + internal CodeMemberMethod EnsureInitializeComponentFn + { + get + { + if (_initializeComponentFn == null) + { + _initializeComponentFn = new CodeMemberMethod(); + _initializeComponentFn.Name = INITIALIZE_COMPONENT; + _initializeComponentFn.Attributes = MemberAttributes.Public | MemberAttributes.Final; + AddDebuggerNonUserCodeAttribute(_initializeComponentFn); + AddGeneratedCodeAttribute(_initializeComponentFn); + MarkupCompiler.GenerateXmlComments(_initializeComponentFn, INITIALIZE_COMPONENT); + _codeClass.Members.Add(_initializeComponentFn); + } + + return _initializeComponentFn; + } + } + + internal CodeTypeDeclaration CodeClass + { + get { return _codeClass; } + } + + internal CodeNamespace CodeNS + { + get { return _codeNS; } + } + + // This is used as the class to instantiate when a language does not support partial + // classes. A code-behind file needs to derive this class from the generated sub-class + // that is normally specified by the x:Class attribute. + internal string SubClass + { + get { return _subClass; } + set { _subClass = value; } + } + + private CodeTypeDeclaration _codeClass; + private CodeNamespace _codeNS; + private CodeMemberMethod _initializeComponentFn = null; + private CodeMemberMethod _hookupFn = null; + private CodeMemberMethod _styleConnectorFn = null; + private string _subClass = string.Empty; + } + +#endregion CodeContext + +#endregion Implementation + +#region Private Data + + private string _targetPath = string.Empty; // Current Dir is default + private string[] _contentList = null; + private ArrayList _referenceAssemblyList = null; + private string _localXamlApplication = null; + private string[] _localXamlPages = null; + private string [] _typeArgsList = null; + private ArrayList _pendingLocalFiles = null; + private bool _hostInBrowser = false; + private bool _xamlDebuggingInformation = false; + private string _splashImage = null; + + private bool _isLangCSharp = false; + private bool _isLangVB = false; + private string _language = string.Empty; + private string _languageSourceExtension = string.Empty; + private static string _definitionNSPrefix = DEFINITION_PREFIX; + private CompilerInfo _ci = null; + private CodeDomProvider _codeProvider = null; + private XamlTypeMapper _typeMapper = null; + + private bool _isCompilingEntryPointClass = false; + private bool _isBamlNeeded = false; + private bool _isCodeNeeded = false; + private bool _hasLocalEvent = false; + private bool _hasGeneratedInternalTypeHelper = false; + private string _assemblyName = string.Empty; + private string _assemblyVersion = string.Empty; + private string _assemblyPublicKeyToken = string.Empty; + private string _applicationFile = string.Empty; + private string _defaultNamespace = string.Empty; + private ParserHooks _parserHooks; + + private SourceFileInfo _sourceFileInfo = null; + private string _compilationUnitSourcePath = string.Empty; + private ArrayList _usingNS = null; + private Assembly _localAssembly = null; + private ReferenceAssembly _localAssemblyFile = null; + private ParserContext _parserContext = null; + private CodeContextRoot _ccRoot = null; + private Stack _codeContexts = null; + private ITaskFileService _taskFileService = null; + private TaskLoggingHelper _taskLogger = null; + private bool _hasEmittedEventSetterDeclaration; + + // Per language sccess Modfiers + private string _private = string.Empty; + private string _public = string.Empty; + private string _protected = string.Empty; + private string _internal = string.Empty; + private string _protectedInternal = string.Empty; + private string _privateClass = string.Empty; + private string _publicClass = string.Empty; + + // Prefixes & Tags + private const string INDENT12 = " "; + private const string ANONYMOUS_ENTRYCLASS_PREFIX = "Generated"; + private const string DEFINITION_PREFIX = "x"; + private const char COMMA = ','; + private const string GENERIC_DELIMITER = "`"; + internal const char DOTCHAR = '.'; + internal const string DOT = "."; + internal const string CODETAG = "Code"; + + // Language support + private const string XAML = ".xaml"; + private const string BAML = ".baml"; + private const string VB = "vb"; + private const string CSHARP = "c#"; + private const string JSHARP = "vj#"; + private const string JSCRIPT = "js"; + + // Generated identifiers + private const string CREATEDELEGATEHELPER = "_CreateDelegate"; + private const string CONTENT_LOADED = "_contentLoaded"; + private const string CONNECT = "Connect"; + private const string CONNECTIONID = "connectionId"; + private const string TARGET = "target"; + private const string EVENTSETTER = "eventSetter"; + private const string EVENT = "Event"; + private const string ADDHANDLER = "AddHandler"; + private const string HELPER = "Helper"; + private const string HANDLERARG = "handler"; + private const string TYPE = "type"; + private const string CULTURE = "culture"; + private const string DEFAULT = "Default"; + private const string VALUE = "value"; + private const string DELEGATETYPE = "delegateType"; + private const string PROPINFO = "propertyInfo"; + private const string EVENTINFO = "eventInfo"; + private const string APPVAR = "app"; + private const string SPLASHVAR = "splashScreen"; + private const string SPLASHCLASSNAME = "SplashScreen"; + private const string ARGS = "args"; + private const string INITIALIZE_COMPONENT = "InitializeComponent"; + private const string SWITCH_STATEMENT = INDENT12 + "switch (" + CONNECTIONID + ")\r\n" + INDENT12 + "{"; + private const string BREAK_STATEMENT = INDENT12 + "break;"; + private const string CASE_STATEMENT = INDENT12 + "case "; + private const string ENDCURLY = "}"; + private const string COLON = ":"; + private const string RESOURCE_LOCATER = "resourceLocater"; + private const string LOADCOMPONENT = "LoadComponent"; + private const string SETTERS = "Setters"; + private const string SummaryStartTag = @""; + private const string SummaryEndTag = @""; + internal const string ADD = "Add"; + internal const string HANDLER = "Handler"; + + // Delimiters & Uri processing + private const string VER = "V"; + private const string COMPONENT = "component"; + private const char COMPONENT_DELIMITER = ';'; + private const string ESCAPED_BACKSLASH = "\\"; + private const char ESCAPED_BACKSLASH_CHAR = '\\'; + private const string FORWARDSLASH = "/"; + private const string URISCHEME_PACK = "pack"; + private const string PARENTFOLDER = @"..\"; + + // For generating pragma checksum data + private static HashAlgorithm s_hashAlgorithm; + private static Guid s_hashGuid; + + private static readonly Guid s_hashSHA256Guid = new Guid(0x8829d00f, 0x11b8, 0x4213, 0x87, 0x8b, 0x77, 0x0e, 0x85, 0x97, 0xac, 0x16); + private static readonly Guid s_hashSHA1Guid = new Guid(0xff1816ec, 0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60); + + private static string s_generatedCode_ToolName; + private static string s_generatedCode_ToolVersion; + +#endregion Private Data + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/ParserExtension.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/ParserExtension.cs new file mode 100644 index 00000000000..965cd38f2ad --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/ParserExtension.cs @@ -0,0 +1,948 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: +// Helper class to the MarkupCompiler class that extends the xaml parser by +// overriding callbacks appropriately for compile mode. +// +//--------------------------------------------------------------------------- + +using System; +using MS.Internal.Markup; +using System.Xml; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.ComponentModel; +using MS.Utility; // for SR + +namespace MS.Internal +{ + #region ParserCallbacks + + internal class ParserExtension : XamlParser + { + #region Constructor + + internal ParserExtension(MarkupCompiler compiler, + ParserContext parserContext, + BamlRecordWriter bamlWriter, + Stream xamlStream, + bool pass2) : + base(parserContext, bamlWriter, xamlStream, false) + { + _compiler = compiler; + _pass2 = pass2; + Debug.Assert(bamlWriter != null, "Need a BamlRecordWriter for compiling to Baml"); + } + + #endregion Constructor + + #region Overrides + + public override void WriteElementStart(XamlElementStartNode xamlObjectNode) + { + string classFullName = null; + + classFullName = _compiler.StartElement(ref _class, _subClass, ref _classModifier, xamlObjectNode.ElementType, string.Empty); + + // If we have a serializer for this element's type, then use that + // serializer rather than doing default serialization. + // NOTE: We currently have faith that the serializer will return when + // it is done with the subtree and leave everything in the correct + // state. We may want to limit how much the called serializer can + // read so that it is forced to return at the end of the subtree. + if (xamlObjectNode.SerializerType != null) + { + XamlSerializer serializer; + if (xamlObjectNode.SerializerType == typeof(XamlStyleSerializer)) + { + serializer = new XamlStyleSerializer(ParserHooks); + } + else if (xamlObjectNode.SerializerType == typeof(XamlTemplateSerializer)) + { + serializer = new XamlTemplateSerializer(ParserHooks); + } + else + { + serializer = Activator.CreateInstance( + xamlObjectNode.SerializerType, + BindingFlags.Instance | BindingFlags.Public | + BindingFlags.NonPublic | BindingFlags.CreateInstance, + null, null, null) as XamlSerializer; + } + + if (serializer == null) + { + ThrowException(SRID.ParserNoSerializer, + xamlObjectNode.TypeFullName, + xamlObjectNode.LineNumber, + xamlObjectNode.LinePosition); + } + else + { + serializer.ConvertXamlToBaml(TokenReader, + ParserContext, xamlObjectNode, + BamlRecordWriter); + _compiler.EndElement(_pass2); + } + } + else if (BamlRecordWriter != null) + { + if (classFullName != null) + { + bool isRootPublic = _pass2 ? !_isInternalRoot : _compiler.IsRootPublic; + Type rootType = isRootPublic ? xamlObjectNode.ElementType : typeof(ParserExtension); + XamlElementStartNode xamlRootObjectNode = new XamlElementStartNode( + xamlObjectNode.LineNumber, + xamlObjectNode.LinePosition, + xamlObjectNode.Depth, + _compiler.AssemblyName, + classFullName, + rootType, + xamlObjectNode.SerializerType); + + base.WriteElementStart(xamlRootObjectNode); + } + else + { + base.WriteElementStart(xamlObjectNode); + } + } + } + + private void WriteConnectionId() + { + if (!_isSameScope) + { + base.WriteConnectionId(++_connectionId); + _isSameScope = true; + } + } + + public override void WriteProperty(XamlPropertyNode xamlPropertyNode) + { + MemberInfo memberInfo = xamlPropertyNode.PropInfo; + + if (xamlPropertyNode.AttributeUsage == BamlAttributeUsage.RuntimeName && + memberInfo != null) + { + // NOTE: Error if local element has runtime Name specified. Change this to + // a warning in the future when that feature is available. + if (_compiler.LocalAssembly == memberInfo.ReflectedType.Assembly && + !xamlPropertyNode.IsDefinitionName) + { + ThrowException(SRID.LocalNamePropertyNotAllowed, + memberInfo.ReflectedType.Name, + MarkupCompiler.DefinitionNSPrefix, + xamlPropertyNode.LineNumber, + xamlPropertyNode.LinePosition); + } + + string attributeValue = xamlPropertyNode.Value; + if (!_pass2) + { + Debug.Assert(_name == null && _nameField == null, "Name has already been set"); + _nameField = _compiler.AddNameField(attributeValue, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); + _name = attributeValue; + } + + if (_nameField != null || _compiler.IsRootNameScope) + { + WriteConnectionId(); + } + } + + if (memberInfo != null && + memberInfo.Name.Equals(STARTUPURI) && + KnownTypes.Types[(int)KnownElements.Application].IsAssignableFrom(memberInfo.DeclaringType)) + { + // if Application.StartupUri property then don't bamlize, but gen code since + // this is better for perf as Application is not a DO. + if (!_pass2) + { + _compiler.AddApplicationProperty(memberInfo, + xamlPropertyNode.Value, + xamlPropertyNode.LineNumber); + } + } + else + { + _compiler.IsBamlNeeded = true; + base.WriteProperty(xamlPropertyNode); + } + } + + public override void WriteUnknownTagStart(XamlUnknownTagStartNode xamlUnknownTagStartNode) + { + string localElementFullName = string.Empty; + NamespaceMapEntry[] namespaceMaps = XamlTypeMapper.GetNamespaceMapEntries(xamlUnknownTagStartNode.XmlNamespace); + + if (namespaceMaps != null && namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly) + { + string ns = namespaceMaps[0].ClrNamespace; + if (!string.IsNullOrEmpty(ns)) + { + ns += MarkupCompiler.DOT; + } + localElementFullName = ns + xamlUnknownTagStartNode.Value; + } + + if (localElementFullName.Length > 0 && !_pass2) + { + // if local complex property bail out now and handle in 2nd pass when TypInfo is available + int lastIndex = xamlUnknownTagStartNode.Value.LastIndexOf(MarkupCompiler.DOTCHAR); + if (-1 == lastIndex) + { + _compiler.StartElement(ref _class, + _subClass, + ref _classModifier, + null, + localElementFullName); + } + } + else + { + base.WriteUnknownTagStart(xamlUnknownTagStartNode); + } + } + + public override void WriteUnknownTagEnd(XamlUnknownTagEndNode xamlUnknownTagEndNode) + { + NamespaceMapEntry[] namespaceMaps = XamlTypeMapper.GetNamespaceMapEntries(xamlUnknownTagEndNode.XmlNamespace); + bool localTag = namespaceMaps != null && namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly; + + if (localTag && !_pass2) + { + // if local complex property bail out now and handle in 2nd pass when TypInfo is available + int lastIndex = xamlUnknownTagEndNode.LocalName.LastIndexOf(MarkupCompiler.DOTCHAR); + if (-1 == lastIndex) + { + _compiler.EndElement(_pass2); + } + } + else + { + base.WriteUnknownTagEnd(xamlUnknownTagEndNode); + } + } + + public override void WriteUnknownAttribute(XamlUnknownAttributeNode xamlUnknownAttributeNode) + { + bool localAttrib = false; + string localTagFullName = string.Empty; + string localAttribName = xamlUnknownAttributeNode.Name; + NamespaceMapEntry[] namespaceMaps = null; + MemberInfo miKnownEvent = null; + + if (xamlUnknownAttributeNode.OwnerTypeFullName.Length > 0) + { + // These are attributes on a local tag ... + localTagFullName = xamlUnknownAttributeNode.OwnerTypeFullName; + localAttrib = true; + } + else + { + // These are attributes on a non-local tag ... + namespaceMaps = XamlTypeMapper.GetNamespaceMapEntries(xamlUnknownAttributeNode.XmlNamespace); + localAttrib = namespaceMaps != null && namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly; + } + + if (localAttrib && !_pass2) + { + // ... and if there are any periods in the attribute name, then ... + int lastIndex = localAttribName.LastIndexOf(MarkupCompiler.DOTCHAR); + + if (-1 != lastIndex) + { + // ... these might be attached props or events defined by a locally defined component, + // but being set on this non-local tag. + + TypeAndSerializer typeAndSerializer = null; + string ownerTagName = localAttribName.Substring(0, lastIndex); + + if (namespaceMaps != null) + { + if (namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly) + { + // local prop on a known tag + localTagFullName = namespaceMaps[0].ClrNamespace + MarkupCompiler.DOT + ownerTagName; + } + } + else + { + typeAndSerializer = XamlTypeMapper.GetTypeOnly(xamlUnknownAttributeNode.XmlNamespace, + ownerTagName); + + if (typeAndSerializer != null) + { + // known local attribute on a local tag + + Type ownerTagType = typeAndSerializer.ObjectType; + localTagFullName = ownerTagType.FullName; + localAttribName = localAttribName.Substring(lastIndex + 1); + + // See if attached event first + miKnownEvent = ownerTagType.GetMethod(MarkupCompiler.ADD + localAttribName + MarkupCompiler.HANDLER, + BindingFlags.Public | BindingFlags.Static | + BindingFlags.FlattenHierarchy); + + if (miKnownEvent == null) + { + // Not an attached event, so try for a clr event. + miKnownEvent = ownerTagType.GetEvent(localAttribName, + BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); + } + + if (miKnownEvent != null) + { + if (_events == null) + _events = new ArrayList(); + + _events.Add(new MarkupCompiler.MarkupEventInfo(xamlUnknownAttributeNode.Value, + localAttribName, + miKnownEvent, + xamlUnknownAttributeNode.LineNumber)); + + WriteConnectionId(); + } + } + else + { + namespaceMaps = XamlTypeMapper.GetNamespaceMapEntries(xamlUnknownAttributeNode.XmlNamespace); + if (namespaceMaps != null && namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly) + { + // local prop on local tag + localTagFullName = namespaceMaps[0].ClrNamespace + MarkupCompiler.DOT + ownerTagName; + } + else + { + // unknown prop on local tag -- Error! + localTagFullName = string.Empty; + } + } + } + + if (typeAndSerializer == null) + { + localAttribName = localAttribName.Substring(lastIndex + 1); + } + } + // else if it is an unknown non-attached prop on a non-local tag -- instant error! + } + + if (localTagFullName.Length > 0 && !_pass2) + { + if (xamlUnknownAttributeNode.AttributeUsage == BamlAttributeUsage.RuntimeName) + { + string attributeValue = xamlUnknownAttributeNode.Value; + + Debug.Assert(_name == null && _nameField == null, "Name has already been set"); + _nameField = _compiler.AddNameField(attributeValue, xamlUnknownAttributeNode.LineNumber, xamlUnknownAttributeNode.LinePosition); + _name = attributeValue; + + if (_nameField != null) + { + WriteConnectionId(); + } + } + else if (localAttribName.Equals(STARTUPURI) && + _compiler.IsCompilingEntryPointClass) + { + // if Application.StartuoUri property then don't bamlize, but gen code since + // this is better for perf as Application is not a DO. + PropertyInfo pi = KnownTypes.Types[(int)KnownElements.Application].GetProperty(localAttribName); + _compiler.AddApplicationProperty(pi, + xamlUnknownAttributeNode.Value, + xamlUnknownAttributeNode.LineNumber); + return; + } + else if (miKnownEvent == null) + { + // This may or may not be a local event, but there is no way to know in Pass1. + // So we prepare for the worst case sceanrio and assume it may be one so that + // the Xaml compiler can generate the CreateDelegate code. + _compiler.HasLocalEvent = true; + } + } + else + { + base.WriteUnknownAttribute(xamlUnknownAttributeNode); + } + + _compiler.IsBamlNeeded = true; + } + + public override void WriteElementEnd(XamlElementEndNode xamlEndObjectNode) + { + _compiler.EndElement(_pass2); + base.WriteElementEnd(xamlEndObjectNode); + } + + /// + /// override of GetElementType + /// + public override bool GetElementType( + XmlReader xmlReader, + string localName, + string namespaceUri, + ref string assemblyName, + ref string typeFullName, + ref Type baseType, + ref Type serializerType) + { + if (!ProcessedRootElement && + namespaceUri.Equals(XamlReaderHelper.DefinitionNamespaceURI) && + (localName.Equals(XamlReaderHelper.DefinitionCodeTag) || + localName.Equals(XamlReaderHelper.DefinitionXDataTag))) + { + MarkupCompiler.ThrowCompilerException(SRID.DefinitionTagNotAllowedAtRoot, + xmlReader.Prefix, + localName); + } + + bool foundElement = base.GetElementType(xmlReader, localName, namespaceUri, + ref assemblyName, ref typeFullName, ref baseType, ref serializerType); + + if (!ProcessedRootElement) + { + int count = xmlReader.AttributeCount; + + // save reader's position, to be restored later + string attrName = (xmlReader.NodeType == XmlNodeType.Attribute) ? xmlReader.Name : null; + + _isRootTag = true; + _class = string.Empty; + _subClass = string.Empty; + ProcessedRootElement = true; + XamlTypeMapper.IsProtectedAttributeAllowed = false; + xmlReader.MoveToFirstAttribute(); + + while (--count >= 0) + { + string attribNamespaceURI = xmlReader.LookupNamespace(xmlReader.Prefix); + + if (attribNamespaceURI != null && + attribNamespaceURI.Equals(XamlReaderHelper.DefinitionNamespaceURI)) + { + MarkupCompiler.DefinitionNSPrefix = xmlReader.Prefix; + + if (xmlReader.LocalName == CLASS) + { + _class = xmlReader.Value.Trim(); + if (_class == string.Empty) + { + // flag an error for processing later in WriteDefAttribute + _class = MarkupCompiler.DOT; + } + else + { + // flag this so that the Type Mapper can allow protected + // attributes on the markup sub-classed root element only. + XamlTypeMapper.IsProtectedAttributeAllowed = true; + } + } + else if (xmlReader.LocalName == XamlReaderHelper.DefinitionTypeArgs) + { + string genericName = _compiler.GetGenericTypeName(localName, xmlReader.Value); + + foundElement = base.GetElementType(xmlReader, genericName, namespaceUri, + ref assemblyName, ref typeFullName, ref baseType, ref serializerType); + + if (!foundElement) + { + NamespaceMapEntry[] namespaceMaps = XamlTypeMapper.GetNamespaceMapEntries(namespaceUri); + bool isLocal = namespaceMaps != null && namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly; + if (!isLocal) + { + MarkupCompiler.ThrowCompilerException(SRID.UnknownGenericType, + MarkupCompiler.DefinitionNSPrefix, + xmlReader.Value, + localName); + } + } + } + else if (xmlReader.LocalName == SUBCLASS) + { + _subClass = xmlReader.Value.Trim(); + if (_subClass == string.Empty) + { + // flag an error for processing later in WriteDefAttribute + _subClass = MarkupCompiler.DOT; + } + else + { + _compiler.ValidateFullSubClassName(ref _subClass); + } + } + else if (xmlReader.LocalName == CLASSMODIFIER) + { + if (!_pass2) + { + _classModifier = xmlReader.Value.Trim(); + if (_classModifier == string.Empty) + { + // flag an error for processing later in WriteDefAttribute + _classModifier = MarkupCompiler.DOT; + } + } + else + { + // This direct comparison is ok to do in pass2 as it has already been validated in pass1. + // This is to avoid a costly instantiation of the CodeDomProvider in pass2. + _isInternalRoot = string.Compare("public", xmlReader.Value.Trim(), StringComparison.OrdinalIgnoreCase) != 0; + } + } + } + + xmlReader.MoveToNextAttribute(); + } + + if (namespaceUri.Equals(XamlReaderHelper.DefinitionNamespaceURI)) + { + xmlReader.MoveToElement(); + } + else + { + if (attrName == null) + xmlReader.MoveToFirstAttribute(); + else + xmlReader.MoveToAttribute(attrName); + } + } + else if (!_compiler.IsBamlNeeded && !_compiler.ProcessingRootContext && _compiler.IsCompilingEntryPointClass && xmlReader.Depth > 0) + { + if ((!localName.Equals(MarkupCompiler.CODETAG) && + !localName.Equals(MarkupCompiler.CODETAG + "Extension")) || + !namespaceUri.Equals(XamlReaderHelper.DefinitionNamespaceURI)) + { + _compiler.IsBamlNeeded = true; + } + } + + return foundElement; + } + + /// + /// override of WriteDynamicEvent + /// + public override void WriteClrEvent(XamlClrEventNode xamlClrEventNode) + { + bool isStyleEvent = (xamlClrEventNode.IsStyleSetterEvent || xamlClrEventNode.IsTemplateEvent); + bool localEvent = _compiler.LocalAssembly == xamlClrEventNode.EventMember.ReflectedType.Assembly; + + if (isStyleEvent) + { + if (localEvent) + { + // validate the event handler name per CLS grammar for identifiers + _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value); + xamlClrEventNode.LocalAssemblyName = _compiler.AssemblyName; + // Pass2 should always be true here as otherwise localEvent will be false, but just being paranoid here. + if (_pass2) + { + XamlTypeMapper.HasInternals = true; + } + } + else + { + if (!xamlClrEventNode.IsSameScope) + { + _connectionId++; + } + + xamlClrEventNode.ConnectionId = _connectionId; + + if (!_pass2) + { + _compiler.ConnectStyleEvent(xamlClrEventNode); + } + } + + return; + } + + bool appEvent = KnownTypes.Types[(int)KnownElements.Application].IsAssignableFrom(xamlClrEventNode.EventMember.DeclaringType); + + if (!appEvent) + { + if (!_pass2) + { + // validate the event handler name per CLS grammar for identifiers + _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value); + + if (_events == null) + _events = new ArrayList(); + + _events.Add(new MarkupCompiler.MarkupEventInfo(xamlClrEventNode.Value, + xamlClrEventNode.EventName, + xamlClrEventNode.EventMember, + xamlClrEventNode.LineNumber)); + } + + // if not local event ... + if (!localEvent) + { + WriteConnectionId(); + } + } + else if (!_pass2) + { + // Since Application is not an Element it doesn't implement IComponentConnector and + // so needs to add events directly. + MarkupCompiler.MarkupEventInfo mei = new MarkupCompiler.MarkupEventInfo(xamlClrEventNode.Value, + xamlClrEventNode.EventName, + xamlClrEventNode.EventMember, + xamlClrEventNode.LineNumber); + _compiler.AddApplicationEvent(mei); + } + + if (_pass2) + { + // if local event, add Baml Attribute Record for local event + if (localEvent) + { + // validate the event handler name per C# grammar for identifiers + _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value); + + XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(xamlClrEventNode.LineNumber, + xamlClrEventNode.LinePosition, + xamlClrEventNode.Depth, + xamlClrEventNode.EventMember, + _compiler.AssemblyName, + xamlClrEventNode.EventMember.ReflectedType.FullName, + xamlClrEventNode.EventName, + xamlClrEventNode.Value, + BamlAttributeUsage.Default, + false); + + XamlTypeMapper.HasInternals = true; + + base.WriteProperty(xamlPropertyNode); + } + } + } + + /// + /// override of WriteEndAttributes + /// + public override void WriteEndAttributes(XamlEndAttributesNode xamlEndAttributesNode) + { + if (xamlEndAttributesNode.IsCompact) + return; + + if (_isRootTag) + { + _class = string.Empty; + _classModifier = string.Empty; + _subClass = string.Empty; + XamlTypeMapper.IsProtectedAttributeAllowed = false; + } + + _isRootTag = false; + _isSameScope = false; + + if (!_pass2) + { + if (_nameField == null) + { + if (_isFieldModifierSet) + { + ThrowException(SRID.FieldModifierNotAllowed, + MarkupCompiler.DefinitionNSPrefix, + xamlEndAttributesNode.LineNumber, + xamlEndAttributesNode.LinePosition); + } + } + else if (_fieldModifier != MemberAttributes.Assembly) + { + if (MemberAttributes.Private != _fieldModifier && + MemberAttributes.Assembly != _fieldModifier) + { + MarkupCompiler.GenerateXmlComments(_nameField, _nameField.Name + " Name Field"); + } + + _nameField.Attributes = _fieldModifier; + _fieldModifier = MemberAttributes.Assembly; + } + + _nameField = null; + _isFieldModifierSet = false; + + _compiler.ConnectNameAndEvents(_name, _events, _connectionId); + + _name = null; + + if (_events != null) + { + _events.Clear(); + _events = null; + } + } + else + { + _compiler.CheckForNestedNameScope(); + } + + // Clear the compiler's generic type argument list (see Dev11 923). + _compiler.ClearGenericTypeArgs(); + + base.WriteEndAttributes(xamlEndAttributesNode); + } + + /// + /// override of WriteDefTag + /// + public override void WriteDefTag(XamlDefTagNode xamlDefTagNode) + { + if (!_pass2) + { + _compiler.ProcessDefinitionNamespace(xamlDefTagNode); + } + else + { + // loop through until after the end of the current definition tag is reached. + while (!xamlDefTagNode.IsEmptyElement && xamlDefTagNode.XmlReader.NodeType != XmlNodeType.EndElement) + { + xamlDefTagNode.XmlReader.Read(); + } + + xamlDefTagNode.XmlReader.Read(); + } + } + + /// + /// override for handling a new xmlnamespace Uri + /// + public override void WriteNamespacePrefix(XamlXmlnsPropertyNode xamlXmlnsPropertyNode) + { + if (!_pass2) + { + List cnap = XamlTypeMapper.GetClrNamespacePairFromCache(xamlXmlnsPropertyNode.XmlNamespace); + if (cnap != null) + { + foreach (ClrNamespaceAssemblyPair u in cnap) + { + _compiler.AddUsing(u.ClrNamespace); + } + } + } + + base.WriteNamespacePrefix(xamlXmlnsPropertyNode); + } + + /// + /// override for mapping instructions between clr and xml namespaces + /// + public override void WritePIMapping(XamlPIMappingNode xamlPIMappingNode) + { + if (!_pass2) + { + _compiler.AddUsing(xamlPIMappingNode.ClrNamespace); + } + + // Local assembly! + if ((xamlPIMappingNode.AssemblyName == null) || (xamlPIMappingNode.AssemblyName.Length == 0)) + { + xamlPIMappingNode.AssemblyName = _compiler.AssemblyName; + bool addMapping = !XamlTypeMapper.PITable.Contains(xamlPIMappingNode.XmlNamespace) + || ((ClrNamespaceAssemblyPair)XamlTypeMapper.PITable[xamlPIMappingNode.XmlNamespace]).LocalAssembly + || string.IsNullOrEmpty(((ClrNamespaceAssemblyPair)XamlTypeMapper.PITable[xamlPIMappingNode.XmlNamespace]).AssemblyName); + if (addMapping) + { + ClrNamespaceAssemblyPair namespaceMapping = new ClrNamespaceAssemblyPair(xamlPIMappingNode.ClrNamespace, + xamlPIMappingNode.AssemblyName); + + namespaceMapping.LocalAssembly = true; + XamlTypeMapper.PITable[xamlPIMappingNode.XmlNamespace] = namespaceMapping; + XamlTypeMapper.InvalidateMappingCache(xamlPIMappingNode.XmlNamespace); + if (!_pass2 && BamlRecordWriter != null) + { + BamlRecordWriter = null; + } + } + } + + base.WritePIMapping(xamlPIMappingNode); + } + + /// + /// override of WriteDefAttribute + /// + public override void WriteDefAttribute(XamlDefAttributeNode xamlDefAttributeNode) + { + if (xamlDefAttributeNode.AttributeUsage == BamlAttributeUsage.RuntimeName) + { + string attributeValue = xamlDefAttributeNode.Value; + + if (!_pass2) + { + Debug.Assert(_name == null && _nameField == null, "Name definition has already been set"); + _nameField = _compiler.AddNameField(attributeValue, xamlDefAttributeNode.LineNumber, xamlDefAttributeNode.LinePosition); + _name = attributeValue; + } + + if (_nameField != null || _compiler.IsRootNameScope) + { + WriteConnectionId(); + + // x:Name needs to be written out as a BAML record in order + // to trigger the RegisterName code path in BamlRecordReader. + // This code follows the code in WriteProperty for the RuntimeName property + base.WriteDefAttribute(xamlDefAttributeNode); + } + } + else if (xamlDefAttributeNode.Name == FIELDMODIFIER) + { + if (!_pass2) + { + _fieldModifier = _compiler.GetMemberAttributes(xamlDefAttributeNode.Value); + _isFieldModifierSet = true; + } + } + // Some x: attributes are processed by the compiler, but are unknown + // to the base XamlParser. The compiler specific ones should not be passed + // to XamlParser for processing, but the rest should be. + else + { + bool isClass = xamlDefAttributeNode.Name == CLASS; + bool isClassModifier = xamlDefAttributeNode.Name == CLASSMODIFIER; + bool isTypeArgs = xamlDefAttributeNode.Name == XamlReaderHelper.DefinitionTypeArgs; + bool isSubClass = xamlDefAttributeNode.Name == SUBCLASS; + + if (!isClass && !isClassModifier && !isTypeArgs && !isSubClass) + { + base.WriteDefAttribute(xamlDefAttributeNode); + } + else if (!_isRootTag) + { + ThrowException(SRID.DefinitionAttributeNotAllowed, + MarkupCompiler.DefinitionNSPrefix, + xamlDefAttributeNode.Name, + xamlDefAttributeNode.LineNumber, + xamlDefAttributeNode.LinePosition); + } + else if (isClass) + { + if (_class == MarkupCompiler.DOT) + { + int index = xamlDefAttributeNode.Value.LastIndexOf(MarkupCompiler.DOT, StringComparison.Ordinal); + ThrowException(SRID.InvalidClassName, + MarkupCompiler.DefinitionNSPrefix, + CLASS, + xamlDefAttributeNode.Value, + index >= 0 ? "fully qualified " : string.Empty, + xamlDefAttributeNode.LineNumber, + xamlDefAttributeNode.LinePosition); + } + + _class = string.Empty; + } + else if (isClassModifier) + { + if (_classModifier == MarkupCompiler.DOT) + { + ThrowException(SRID.UnknownClassModifier, + MarkupCompiler.DefinitionNSPrefix, + xamlDefAttributeNode.Value, + _compiler.Language, + xamlDefAttributeNode.LineNumber, + xamlDefAttributeNode.LinePosition); + } + + _classModifier = string.Empty; + } + else if (isSubClass) + { + if (_subClass == MarkupCompiler.DOT) + { + int index = xamlDefAttributeNode.Value.LastIndexOf(MarkupCompiler.DOT, StringComparison.Ordinal); + ThrowException(SRID.InvalidClassName, + MarkupCompiler.DefinitionNSPrefix, + SUBCLASS, + xamlDefAttributeNode.Value, + index >= 0 ? "fully qualified " : string.Empty, + xamlDefAttributeNode.LineNumber, + xamlDefAttributeNode.LinePosition); + } + + _subClass = string.Empty; + } + else if (isTypeArgs) + { + _compiler.AddGenericArguments(ParserContext, xamlDefAttributeNode.Value); + } + } + } + +/* + // NOTE: Enable when Parser is ready to handle multiple errors w/o bailing out. + internal override SerializationErrorAction ParseError(XamlParseException e) + { + _compiler.OnError(e); + return SerializationErrorAction.Ignore; + } +*/ + /// + /// override of Write End Document + /// + public override void WriteDocumentEnd(XamlDocumentEndNode xamlEndDocumentNode) + { + if (BamlRecordWriter != null) + { + MemoryStream bamlMemStream = BamlRecordWriter.BamlStream as MemoryStream; + Debug.Assert(bamlMemStream != null); + base.WriteDocumentEnd(xamlEndDocumentNode); + _compiler.GenerateBamlFile(bamlMemStream); + } + } + + internal override bool CanResolveLocalAssemblies() + { + return _pass2; + } + + bool ProcessedRootElement + { + get { return _processedRootElement; } + set { _processedRootElement = value; } + } + + #endregion Overrides + + #region Data + + private MarkupCompiler _compiler; + private string _name = null; + private string _class = string.Empty; + private string _subClass = string.Empty; + private int _connectionId = 0; + private bool _pass2 = false; + private bool _isRootTag = false; + private bool _processedRootElement = false; + private bool _isSameScope = false; + private bool _isInternalRoot = false; + private ArrayList _events = null; + private bool _isFieldModifierSet = false; + private CodeMemberField _nameField = null; + private string _classModifier = string.Empty; + private MemberAttributes _fieldModifier = MemberAttributes.Assembly; + + private const string CLASS = "Class"; + private const string SUBCLASS = "Subclass"; + private const string CLASSMODIFIER = "ClassModifier"; + private const string FIELDMODIFIER = "FieldModifier"; + private const string STARTUPURI = "StartupUri"; + + #endregion Data + } + + #endregion ParserCallbacks +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Shared/SourceFileInfo.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Shared/SourceFileInfo.cs new file mode 100644 index 00000000000..c1c89be76c0 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Shared/SourceFileInfo.cs @@ -0,0 +1,169 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: +// an internal class that keeps the related information for a source file. +// Such as the relative path, source directory, Link path and +// file stream etc. +// +// This can be shared by different build tasks. +// +//--------------------------------------------------------------------------- + +using System; +using System.Security.Permissions; +using System.IO; + +namespace MS.Internal +{ + #region SourceFileInfo + + // + // SourceFileInfo class + // + internal class SourceFileInfo + { + #region Constructor + // + // Constructor + // + internal SourceFileInfo(FileUnit file) + { + _filePath = file.Path; + _fileLinkAlias = file.LinkAlias; + _fileLogicalName = file.LogicalName; + _sourcePath = null; + _relativeSourceFilePath = null; + + _stream = null; + + _isXamlFile = false; + + if (!string.IsNullOrEmpty(file.Path) && file.Path.ToUpperInvariant().EndsWith(XAML, StringComparison.Ordinal)) + { + _isXamlFile = true; + } + } + + #endregion Constructor + + #region Properties + + // + // The original file Path + // + internal string OriginalFilePath + { + get { return _filePath; } + } + + // + // The original file LinkAlias + // + internal string OriginalFileLinkAlias + { + get { return _fileLinkAlias; } + } + + // + // The original file LogicalName + // + internal string OriginalFileLogicalName + { + get { return _fileLogicalName; } + } + + // + // The new Source Directory for this filepath + // + // If the file is under the project root, this is the project root directory, + // otherwise, this is the directory of the file. + // + internal string SourcePath + { + get { return _sourcePath; } + set { _sourcePath = value; } + } + + // + // The new relative path which is relative to the SourcePath. + // + // If it is XamlFile, the RelativeSourceFilePath would not include the .xaml extension. + // + internal string RelativeSourceFilePath + { + get { return _relativeSourceFilePath; } + set { _relativeSourceFilePath = value; } + } + + // + // Indicate if the source file is a xaml file or not. + // + internal bool IsXamlFile + { + get { return _isXamlFile; } + } + + // + // Stream of the file + // + internal Stream Stream + { + get + { + // + // If the stream is not set for the file, get it from file system in Disk. + // + if ( _stream == null) + { + _stream = File.OpenRead(_filePath); + } + + return _stream; + } + + set + { + _stream = value; + } + } + + #endregion Properties + + #region internal methods + + // + // Close the stream. + // + internal void CloseStream() + { + if (_stream != null) + { + _stream.Close(); + _stream = null; + } + } + + #endregion + + #region Private Data + + private string _filePath; + private string _fileLinkAlias; + private string _fileLogicalName; + private string _sourcePath; + private string _relativeSourceFilePath; + private Stream _stream; + private bool _isXamlFile; + + private const string XAML = ".XAML"; + + #endregion Private Data + + } + #endregion SourceFileInfo + +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerLocalReference.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerLocalReference.cs new file mode 100644 index 00000000000..13e67facd34 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerLocalReference.cs @@ -0,0 +1,347 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//---------------------------------------------------------------------------------------- +// +// Description: +// this internal class handles cache for xaml files which +// want to reference local types. +// +//--------------------------------------------------------------------------------------- + +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + +using Microsoft.Build.Tasks.Windows; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using MS.Utility; + +namespace MS.Internal.Tasks +{ + // + // LocalReferenceFile + // This class keeps xaml file path and whether it is localizable. + // + internal class LocalReferenceFile + { + private bool _localizable; + private string _filePath; + private string _linkAlias; + private string _logicalName; + private static LocalReferenceFile _empty = new LocalReferenceFile(String.Empty, false, String.Empty, String.Empty); + private const char trueChar = 'T'; + private const char falseChar = 'F'; + private const char semiColonChar = ';'; + + internal LocalReferenceFile(string filepath, bool localizable, string linkAlias, string logicalName) + { + _localizable = localizable; + _filePath = filepath; + _linkAlias = linkAlias; + _logicalName = logicalName; + } + + internal bool Localizable + { + get { return _localizable; } + } + + internal string FilePath + { + get { return _filePath; } + } + + internal string LinkAlias + { + get { return _linkAlias; } + } + + internal string LogicalName + { + get { return _logicalName; } + } + + internal static LocalReferenceFile Empty + { + get { return _empty; } + } + + // + // Serialize the instance to a string so that it can saved into a cache file. + // + internal string Serialize() + { + string cacheText = String.Empty; + + if (!String.IsNullOrEmpty(FilePath)) + { + StringBuilder sb = new StringBuilder(); + + if (Localizable) + { + sb.Append(trueChar); + } + else + { + sb.Append(falseChar); + } + + sb.Append(FilePath); + sb.Append(semiColonChar); + sb.Append(LinkAlias); + sb.Append(semiColonChar); + sb.Append(LogicalName); + + cacheText = sb.ToString(); + } + + return cacheText; + } + + // + // Create instance from a cache text string. + // + internal static LocalReferenceFile Deserialize(string cacheInfo) + { + // cachInfo string must follow pattern like Localizable + FilePath. + // Localizable contains one character. + LocalReferenceFile lrf = null; + + if (!String.IsNullOrEmpty(cacheInfo)) + { + bool localizable; + string filePath; + string linkAlias; + string logicalName; + + string[] subStrs = cacheInfo.Split(semiColonChar); + + filePath = subStrs[0]; + linkAlias = subStrs[1]; + logicalName = subStrs[2]; + + localizable = (filePath[0] == trueChar) ? true : false; + + filePath = filePath.Substring(1); + + lrf = new LocalReferenceFile(filePath, localizable, linkAlias, logicalName); + } + + return lrf; + } + } + + // + // CompilerLocalReference + // + internal class CompilerLocalReference + { + // + // ctor of CompilerLocalReference + // + internal CompilerLocalReference(string localCacheFile, ITaskFileService taskFileService) + { + _localCacheFile = localCacheFile; + _taskFileService = taskFileService; + } + + #region internal methods + + // + // Detect whether the local cache file exists or not. + // + // + internal bool CacheFileExists() + { + return _taskFileService.Exists(_localCacheFile); + } + + // + // Clean up the state file. + // + internal void CleanupCache() + { + if (CacheFileExists()) + { + _taskFileService.Delete(_localCacheFile); + } + } + + // + // Save the local reference related information from MarkupCompilePass1 task to cache file. + // + internal bool SaveCacheInformation(MarkupCompilePass1 mcPass1) + { + Debug.Assert(String.IsNullOrEmpty(_localCacheFile) != true, "_localCacheFile must not be empty."); + Debug.Assert(mcPass1 != null, "A valid instance of MarkupCompilePass1 must be passed to method SaveCacheInformation."); + + bool bSuccess = false; + + // Transfer the cache related information from mcPass1 to this instance. + + LocalApplicationFile = mcPass1.LocalApplicationFile; + LocalMarkupPages = mcPass1.LocalMarkupPages; + + // Save the cache information to the cache file. + + MemoryStream memStream = new MemoryStream(); + + // using Disposes the StreamWriter when it ends. Disposing the StreamWriter + // also closes the underlying MemoryStream. Furthermore, don't add BOM here + // since TaskFileService.WriteFile adds it. + using (StreamWriter sw = new StreamWriter(memStream, new UTF8Encoding(false))) + { + // Write InternalTypeHelperFile only when Pass1 asks Pass2 to do further check. + if (mcPass1.FurtherCheckInternalTypeHelper) + { + sw.WriteLine(mcPass1.InternalTypeHelperFile); + } + else + { + sw.WriteLine(String.Empty); + } + + // Write the ApplicationFile for Pass2 compilation. + if (LocalApplicationFile == null) + { + sw.WriteLine(String.Empty); + } + else + { + sw.WriteLine(LocalApplicationFile.Serialize()); + } + + if (LocalMarkupPages != null && LocalMarkupPages.Length > 0) + { + for (int i = 0; i < LocalMarkupPages.Length; i++) + { + sw.WriteLine(LocalMarkupPages[i].Serialize( )); + } + } + + sw.Flush(); + _taskFileService.WriteFile(memStream.ToArray(), _localCacheFile); + + bSuccess = true; + } + + return bSuccess; + } + + // + // Read the Local Reference cache file, load the cached information + // to the corresponding data fields in this class. + // + internal bool LoadCacheFile() + { + Debug.Assert(String.IsNullOrEmpty(_localCacheFile) != true, "_localCacheFile must not be empty."); + + bool loadSuccess = false; + + Stream stream = _taskFileService.GetContent(_localCacheFile); + + // using Disposes the StreamReader when it ends. Disposing the StreamReader + // also closes the underlying MemoryStream. Don't look for BOM at the beginning + // of the stream, since we don't add it when writing. TaskFileService takes care + // of this. + using (StreamReader srCache = new StreamReader(stream, false)) + { + // The first line must be for InternalTypeHelperFile. + // The second line is for Local Application Defintion file. + // For Library, the second line is an empty line. + + InternalTypeHelperFile = srCache.ReadLine(); + + string lineText; + + lineText = srCache.ReadLine(); + + LocalApplicationFile = LocalReferenceFile.Deserialize(lineText); + + ArrayList alMarkupPages = new ArrayList(); + + while (srCache.EndOfStream != true) + { + lineText = srCache.ReadLine(); + LocalReferenceFile lrf = LocalReferenceFile.Deserialize(lineText); + + if (lrf != null) + { + alMarkupPages.Add(lrf); + } + } + + if (alMarkupPages.Count > 0) + { + LocalMarkupPages = (LocalReferenceFile []) alMarkupPages.ToArray(typeof(LocalReferenceFile)); + } + + loadSuccess = true; + } + + return loadSuccess; + + } + + #endregion + + #region internal properties + + internal string CacheFilePath + { + get { return _localCacheFile; } + } + + internal LocalReferenceFile LocalApplicationFile + { + get { return _localApplicationFile; } + set { _localApplicationFile = value; } + } + + internal LocalReferenceFile[] LocalMarkupPages + { + get { return _localMarkupPages; } + set { _localMarkupPages = value; } + } + + // + // InternalTypeHelper file path. + // + // Since Pass2 task doesn't know the code language, it could not generate the real + // InternalTypeHelper code file path on the fly. + // The real file path would be passed from Pass1 task to Pass2 through the cache file. + // + // If this file path is set in the cache file, it means Pass1 asks Passs2 to do the further + // check for this file to see if it is really required, if this file is required for the assembly, + // Pass2 then adds it to the appropriate output Item, otherwise, Pass2 just deletes this file. + // + // If the path is empty, this means Pass1 has already known how to handle the file correctly, + // no further check is required in Pass2. + // + internal string InternalTypeHelperFile + { + get { return _internalTypeHelperFile; } + set { _internalTypeHelperFile = value; } + } + + #endregion + + #region private data + + private LocalReferenceFile _localApplicationFile; + private LocalReferenceFile[] _localMarkupPages; + + private string _localCacheFile; + private string _internalTypeHelperFile = String.Empty; + private ITaskFileService _taskFileService = null; + + #endregion + + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerState.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerState.cs new file mode 100644 index 00000000000..358aa8247f4 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerState.cs @@ -0,0 +1,388 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//---------------------------------------------------------------------------------------- +// +// Description: +// An internal class which handles compiler information cache. It can read +// write the cache file, this is for incremental build support. +// +//--------------------------------------------------------------------------------------- + +using System; +using System.IO; +using System.Collections; +using System.Diagnostics; +using System.Text; +using System.Globalization; + +using Microsoft.Build.Tasks.Windows; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using MS.Utility; + +namespace MS.Internal.Tasks +{ + // + // Only cache information for below types. + // + internal enum CompilerStateType : int + { + AssemblyName = 0x00, + AssemblyVersion, + AssemblyPublicKeyToken, + OutputType, + Language, + LanguageSourceExtension, + OutputPath, + RootNamespace, + LocalizationDirectivesToLocFile, + HostInBrowser, + DefineConstants, + ApplicationFile, + PageMarkup, + ContentFiles, + SourceCodeFiles, + References, + PageMarkupFileNames, + SplashImage, + Pass2Required, + MaxCount, + } + + // + // CompilerState + // + internal class CompilerState + { + // + // ctor of CompilerState + // + internal CompilerState(string stateFilePath, ITaskFileService taskFileService) + { + _cacheInfoList = new String[(int)CompilerStateType.MaxCount]; + _stateFilePath = stateFilePath; + _taskFileService = taskFileService; + } + + #region internal methods + + + // + // Detect whether the state file exists or not. + // + // + internal bool StateFileExists() + { + return _taskFileService.Exists(_stateFilePath); + } + + // + // Clean up the state file. + // + internal void CleanupCache() + { + if (StateFileExists() ) + { + _taskFileService.Delete(_stateFilePath); + } + } + + internal bool SaveStateInformation(MarkupCompilePass1 mcPass1) + { + Debug.Assert(String.IsNullOrEmpty(_stateFilePath) != true, "StateFilePath must not be empty."); + Debug.Assert(mcPass1 != null, "A valid instance of MarkupCompilePass1 must be passed to method SaveCacheInformation."); + Debug.Assert(_cacheInfoList.Length == (int)CompilerStateType.MaxCount, "The Cache string array should be already allocated."); + + // Transfer the cache related information from mcPass1 to this instance. + + AssemblyName = mcPass1.AssemblyName; + AssemblyVersion = mcPass1.AssemblyVersion; + AssemblyPublicKeyToken = mcPass1.AssemblyPublicKeyToken; + OutputType = mcPass1.OutputType; + Language = mcPass1.Language; + LanguageSourceExtension = mcPass1.LanguageSourceExtension; + OutputPath = mcPass1.OutputPath; + RootNamespace = mcPass1.RootNamespace; + LocalizationDirectivesToLocFile = mcPass1.LocalizationDirectivesToLocFile; + HostInBrowser = mcPass1.HostInBrowser; + DefineConstants = mcPass1.DefineConstants; + ApplicationFile = mcPass1.ApplicationFile; + PageMarkup = mcPass1.PageMarkupCache; + ContentFiles = mcPass1.ContentFilesCache; + SourceCodeFiles = mcPass1.SourceCodeFilesCache; + References = mcPass1.ReferencesCache; + PageMarkupFileNames = GenerateStringFromFileNames(mcPass1.PageMarkup); + SplashImage = mcPass1.SplashImageName; + Pass2Required = (mcPass1.RequirePass2ForMainAssembly || mcPass1.RequirePass2ForSatelliteAssembly); + + return SaveStateInformation(); + } + + internal bool SaveStateInformation() + { + bool bSuccess = false; + + // Save the cache information to the cache file. + + MemoryStream memStream = new MemoryStream(); + // using Disposes the StreamWriter when it ends. Disposing the StreamWriter + // also closes the underlying MemoryStream. Furthermore, don't add BOM here + // since TaskFileService.WriteFile adds it. + using (StreamWriter sw = new StreamWriter(memStream, new UTF8Encoding(false))) + { + for (int i =0; i<(int)CompilerStateType.MaxCount; i++) + { + sw.WriteLine(_cacheInfoList[i]); + } + + sw.Flush(); + _taskFileService.WriteFile(memStream.ToArray(), _stateFilePath); + + bSuccess = true; + } + + return bSuccess; + } + + // + // Read the markupcompiler cache file, load the cached information + // to the corresponding data fields in this class. + // + internal bool LoadStateInformation( ) + { + Debug.Assert(String.IsNullOrEmpty(_stateFilePath) != true, "_stateFilePath must be not be empty."); + Debug.Assert(_cacheInfoList.Length == (int)CompilerStateType.MaxCount, "The Cache string array should be already allocated."); + + bool loadSuccess = false; + + Stream stream = null; + if (_taskFileService.IsRealBuild) + { + // Pass2 writes to the cache, but Pass2 doesn't have a HostObject (because it's only + // used for real builds), so it writes directly to the file system. So we need to read + // directly from the file system; if we read via the HostFileManager, we'll get stale + // results that don't reflect updates made in Pass2. + stream = File.OpenRead(_stateFilePath); + } + else + { + stream = _taskFileService.GetContent(_stateFilePath); + } + + // using Disposes the StreamReader when it ends. Disposing the StreamReader + // also closes the underlying MemoryStream. Don't look for BOM at the beginning + // of the stream, since we don't add it when writing. TaskFileService takes care + // of this. + using (StreamReader srCache = new StreamReader(stream, false)) + { + + int i = 0; + + while (srCache.EndOfStream != true) + { + if (i >= (int)CompilerStateType.MaxCount) + { + break; + } + + _cacheInfoList[i] = srCache.ReadLine(); + + i++; + } + + loadSuccess = true; + } + + return loadSuccess; + + } + + // + // Generate cache string for item lists such as PageMarkup, References, + // ContentFiles and CodeFiles etc. + // + internal static string GenerateCacheForFileList(ITaskItem[] fileItemList) + { + string cacheString = String.Empty; + + if (fileItemList != null && fileItemList.Length > 0) + { + int iHashCode = 0; + + int iCount = fileItemList.Length; + + for (int i = 0; i < iCount; i++) + { + iHashCode += fileItemList[i].ItemSpec.GetHashCode(); + } + + StringBuilder sb = new StringBuilder(); + + sb.Append(iCount); + sb.Append(iHashCode); + + cacheString = sb.ToString(); + } + + + return cacheString; + + } + + private static string GenerateStringFromFileNames(ITaskItem[] fileItemList) + { + string fileNames = String.Empty; + + if (fileItemList != null) + { + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < fileItemList.Length; i++) + { + sb.Append(fileItemList[i].ItemSpec); + sb.Append(";"); + } + + fileNames = sb.ToString(); + } + + return fileNames; + } + + #endregion + + #region internal properties + + internal string CacheFilePath + { + get { return _stateFilePath; } + } + + internal string AssemblyName + { + get { return _cacheInfoList[(int)CompilerStateType.AssemblyName]; } + set { _cacheInfoList[(int)CompilerStateType.AssemblyName] = value; } + } + + internal string AssemblyVersion + { + get { return _cacheInfoList[(int)CompilerStateType.AssemblyVersion]; } + set { _cacheInfoList[(int)CompilerStateType.AssemblyVersion] = value; } + } + + internal string AssemblyPublicKeyToken + { + get { return _cacheInfoList[(int)CompilerStateType.AssemblyPublicKeyToken]; } + set { _cacheInfoList[(int)CompilerStateType.AssemblyPublicKeyToken] = value; } + } + + internal string OutputType + { + get { return _cacheInfoList[(int)CompilerStateType.OutputType]; } + set { _cacheInfoList[(int)CompilerStateType.OutputType] = value; } + } + + internal string Language + { + get { return _cacheInfoList[(int)CompilerStateType.Language]; } + set { _cacheInfoList[(int)CompilerStateType.Language] = value; } + } + + internal string LanguageSourceExtension + { + get { return _cacheInfoList[(int)CompilerStateType.LanguageSourceExtension]; } + set { _cacheInfoList[(int)CompilerStateType.LanguageSourceExtension] = value; } + } + + internal string OutputPath + { + get { return _cacheInfoList[(int)CompilerStateType.OutputPath]; } + set { _cacheInfoList[(int)CompilerStateType.OutputPath] = value; } + } + + internal string RootNamespace + { + get { return _cacheInfoList[(int)CompilerStateType.RootNamespace]; } + set { _cacheInfoList[(int)CompilerStateType.RootNamespace] = value; } + } + + internal string LocalizationDirectivesToLocFile + { + get { return _cacheInfoList[(int)CompilerStateType.LocalizationDirectivesToLocFile]; } + set { _cacheInfoList[(int)CompilerStateType.LocalizationDirectivesToLocFile] = value; } + } + + internal string HostInBrowser + { + get { return _cacheInfoList[(int)CompilerStateType.HostInBrowser]; } + set { _cacheInfoList[(int)CompilerStateType.HostInBrowser] = value; } + } + + internal string DefineConstants + { + get { return _cacheInfoList[(int)CompilerStateType.DefineConstants]; } + set { _cacheInfoList[(int)CompilerStateType.DefineConstants] = value; } + } + + internal string ApplicationFile + { + get { return _cacheInfoList[(int)CompilerStateType.ApplicationFile]; } + set { _cacheInfoList[(int)CompilerStateType.ApplicationFile] = value; } + } + + internal string PageMarkup + { + get { return _cacheInfoList[(int)CompilerStateType.PageMarkup]; } + set { _cacheInfoList[(int)CompilerStateType.PageMarkup] = value; } + } + + internal string ContentFiles + { + get { return _cacheInfoList[(int)CompilerStateType.ContentFiles]; } + set { _cacheInfoList[(int)CompilerStateType.ContentFiles] = value; } + } + + internal string SourceCodeFiles + { + get { return _cacheInfoList[(int)CompilerStateType.SourceCodeFiles]; } + set { _cacheInfoList[(int)CompilerStateType.SourceCodeFiles] = value; } + } + + internal string References + { + get { return _cacheInfoList[(int)CompilerStateType.References]; } + set { _cacheInfoList[(int)CompilerStateType.References] = value; } + } + + internal string PageMarkupFileNames + { + get { return _cacheInfoList[(int)CompilerStateType.PageMarkupFileNames]; } + set { _cacheInfoList[(int)CompilerStateType.PageMarkupFileNames] = value; } + } + + internal string SplashImage + { + get { return _cacheInfoList[(int)CompilerStateType.SplashImage]; } + set { _cacheInfoList[(int)CompilerStateType.SplashImage] = value; } + } + + internal bool Pass2Required + { + get { return _cacheInfoList[(int)CompilerStateType.Pass2Required] == bool.TrueString; } + set { _cacheInfoList[(int)CompilerStateType.Pass2Required] = value.ToString(CultureInfo.InvariantCulture); } + } + + #endregion + + #region private data + + private String [] _cacheInfoList; + private string _stateFilePath; + private ITaskFileService _taskFileService = null; + + #endregion + + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerWrapper.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerWrapper.cs new file mode 100644 index 00000000000..08ce31197e4 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerWrapper.cs @@ -0,0 +1,437 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//---------------------------------------------------------------------------------------- +// +// Description: +// A wrapper class which can take inputs from build task and call the underneath +// MarkupCompiler, CompilationUnit and other related types to do the real +// compilation work. +// This wrapper runs in the same Appdomain as MarkupCompiler, CompilationUnit, +// +// It miminizes the communication between two domains among the build tasks and +// the real compiler classes. +// +//--------------------------------------------------------------------------------------- + +using System; +using System.IO; +using System.Collections; +using System.Reflection; +using System.Runtime.InteropServices; + +using MS.Internal.Markup; +using Microsoft.Build.Utilities; +using Microsoft.Build.Framework; +using MS.Internal.Tasks; +using MS.Utility; + +namespace MS.Internal +{ + // + // CompilerWrapper + // + internal class CompilerWrapper : MarshalByRefObject + { + // + // ctor + // + internal CompilerWrapper() + { + _mc = new MarkupCompiler(); + _sourceDir = Directory.GetCurrentDirectory() + "\\"; + _nErrors = 0; + } + + // + // The valid source file extension for the passed language. + // Normally a language supports more valid source file extensions. + // User could choose one of them in project file. + // If this property is not set, we will take use of the default one for the language. + // + internal string LanguageSourceExtension + { + set { _mc.LanguageSourceExtension = value; } + } + + // + // OutputPath : Generated code files, Baml fles will be put in this directory. + // + internal string OutputPath + { + set { _mc.TargetPath = value; } + } + + // + // The version of the assembly + // + internal string AssemblyVersion + { + set { _mc.AssemblyVersion = value; } + } + + // + // The key token of the assembly + // + internal string AssemblyPublicKeyToken + { + set { _mc.AssemblyPublicKeyToken = value; } + } + + // + // ApplicationMarkup + // + internal FileUnit ApplicationMarkup + { + set { _applicationMarkup = value; } + } + + // + // Loose file content list + // + internal string[] ContentFiles + { + set { _mc.ContentList = value; } + } + + /// + /// Splash screen image to be displayed before application init + /// + internal string SplashImage + { + set { _mc.SplashImage = value; } + } + + // + // Assembly References. + // + // + internal ArrayList References + { + set { _mc.ReferenceAssemblyList = value; } + } + + // + //If true code for supporting hosting in Browser is generated + // + internal bool HostInBrowser + { + set { _mc.HostInBrowser = value; } + } + + // + // Generated debugging information in the BAML file. + // + internal bool XamlDebuggingInformation + { + set { _mc.XamlDebuggingInformation = value; } + } + + // + // Controls how to generate localization information for each xaml file. + // Valid values: None, CommentsOnly, All. + // + // + internal int LocalizationDirectivesToLocFile + { + set { _localizationDirectivesToLocFile = value; } + } + + // + // Keep the application definition file if it contains local types which are implemented + // in current target assembly. + // + internal string LocalXamlApplication + { + get { return _mc.LocalXamlApplication; } + } + + + // + // Keep the page markup files if they contain local types which are implemented + // in current target assembly. + // + internal string[] LocalXamlPages + { + get { return _mc.LocalXamlPages; } + } + + + /// + /// Get/Sets the TaskFileService on MarkupCompiler + /// + internal ITaskFileService TaskFileService + { + get { return _mc.TaskFileService; } + set { _mc.TaskFileService = value; } + } + + // + // A wrapper property which maps to MarkupCompiler class's corresponding property. + // This property will be called by MarkupCompilePass1 and Pass2 build tasks. + // + // It indicates whether any xaml file in current xaml list references internal types + // from friend assembly or local target assembly. + // + internal bool HasInternals + { + get { return MarkupCompiler.HasInternals; } + } + + // + // TaskLoggingHelper + // + internal TaskLoggingHelper TaskLogger + { + set + { + _taskLogger = value; + _mc.TaskLogger = value; + } + } + + internal string UnknownErrorID + { + set { _unknownErrorID = value; } + } + + internal int ErrorTimes + { + get { return _nErrors; } + } + + // + // Start the compilation. + // + // + // + // + // + // + // + internal bool DoCompilation(string assemblyName, string language, string rootNamespace, FileUnit[] fileList, bool isSecondPass) + { + bool ret = true; + + CompilationUnit compUnit = new CompilationUnit(assemblyName, language, rootNamespace, fileList); + compUnit.Pass2 = isSecondPass; + + // Set some properties required by the CompilationUnit + compUnit.ApplicationFile = _applicationMarkup; + compUnit.SourcePath = _sourceDir; + + //Set the properties required by MarkupCompiler + + _mc.SourceFileResolve += new SourceFileResolveEventHandler(OnSourceFileResolve); + _mc.Error += new MarkupErrorEventHandler(OnCompilerError); + + LocalizationDirectivesToLocFile localizeFlag = (LocalizationDirectivesToLocFile)_localizationDirectivesToLocFile; + + + // + // Localization file should not be generated for Intellisense build. Thus + // checking IsRealBuild. + // + if ((localizeFlag == MS.Internal.LocalizationDirectivesToLocFile.All + || localizeFlag == MS.Internal.LocalizationDirectivesToLocFile.CommentsOnly) + && (TaskFileService.IsRealBuild)) + { + _mc.ParserHooks = new LocalizationParserHooks(_mc, localizeFlag, isSecondPass); + } + + if (isSecondPass) + { + for (int i = 0; i < _mc.ReferenceAssemblyList.Count; i++) + { + ReferenceAssembly asmReference = _mc.ReferenceAssemblyList[i] as ReferenceAssembly; + + if (asmReference != null) + { + if (String.Compare(asmReference.AssemblyName, assemblyName, StringComparison.OrdinalIgnoreCase) == 0) + { + // Set the local assembly file to markupCompiler + _mc.LocalAssemblyFile = asmReference; + } + } + } + } + + // finally compile the app + _mc.Compile(compUnit); + + return ret; + } + + #region private method + + + // + // Event handler for the Compiler Errors + // + // + // + private void OnCompilerError(Object sender, MarkupErrorEventArgs e) + { + _nErrors++; + + // + // Since Output from LogError() cannot be recognized by VS TaskList, so + // we replaced it with LogErrorFromText( ) and pass all the required information + // such as filename, line, offset, etc. + // + string strErrorCode; + + // Generate error message by going through the whole exception chain, including + // its inner exceptions. + string message = TaskHelper.GetWholeExceptionMessage(e.Exception); + string errorText; + + strErrorCode = _taskLogger.ExtractMessageCode(message, out errorText); + + if (String.IsNullOrEmpty(strErrorCode)) + { + // If the exception is a Xml exception, show a pre-asigned error id for it. + if (IsXmlException(e.Exception)) + { + message = SR.Get(SRID.InvalidXml, message); + strErrorCode = _taskLogger.ExtractMessageCode(message, out errorText); + } + else + { + strErrorCode = _unknownErrorID; + errorText = SR.Get(SRID.UnknownBuildError, errorText); + } + } + + _taskLogger.LogError(null, strErrorCode, null, e.FileName, e.LineNumber, e.LinePosition, 0, 0, errorText); + } + + + // + // Detect if the exception is xmlException + // + private bool IsXmlException(Exception e) + { + bool isXmlException = false; + + while (e != null) + { + if (e is System.Xml.XmlException) + { + isXmlException = true; + break; + } + else + { + e = e.InnerException; + } + } + + return isXmlException; + + } + + // + // Handle the SourceFileResolve Event from MarkupCompiler. + // It tries to GetResolvedFilePath for the new SourceDir and new RelativePath. + // + private void OnSourceFileResolve(Object sender, SourceFileResolveEventArgs e) + { + SourceFileInfo sourceFileInfo = e.SourceFileInfo; + string newSourceDir = _sourceDir; + string newRelativeFilePath; + + if (String.IsNullOrEmpty(sourceFileInfo.OriginalFilePath)) + { + newRelativeFilePath = sourceFileInfo.OriginalFilePath; + } + else + { + newRelativeFilePath = GetResolvedFilePath(sourceFileInfo.OriginalFilePath, ref newSourceDir); + + _taskLogger.LogMessageFromResources(MessageImportance.Low, SRID.FileResolved, sourceFileInfo.OriginalFilePath, newRelativeFilePath, newSourceDir); + } + + if (sourceFileInfo.IsXamlFile) + { + // + // For Xaml Source file, we need to remove the .xaml extension part. + // + int fileExtIndex = newRelativeFilePath.LastIndexOf(MarkupCompiler.DOT, StringComparison.Ordinal); + newRelativeFilePath = newRelativeFilePath.Substring(0, fileExtIndex); + } + + // + // Update the SourcePath and RelativeSourceFilePath property in SourceFileInfo object. + // + sourceFileInfo.SourcePath = newSourceDir; + sourceFileInfo.RelativeSourceFilePath = newRelativeFilePath; + + // Put the stream here. + sourceFileInfo.Stream = TaskFileService.GetContent(sourceFileInfo.OriginalFilePath); + } + + // + // Return a new sourceDir and relative filepath for a given filePath. + // This is for supporting of fullpath or ..\ in the original FilePath. + // + private string GetResolvedFilePath(string filePath, ref string newSourceDir) + { + // make it an absolute path if not already so + if (!Path.IsPathRooted(filePath)) + { + filePath = _sourceDir + filePath; + } + + // get rid of '..' and '.' if any + string fullFilePath = Path.GetFullPath(filePath); + + // Get the relative path based on sourceDir + string relPath = String.Empty; + string newRelativeFilePath; + + if (fullFilePath.StartsWith(_sourceDir,StringComparison.OrdinalIgnoreCase)) + { + relPath = fullFilePath.Substring(_sourceDir.Length); + + // the original file is relative to the SourceDir. + newSourceDir = _sourceDir; + newRelativeFilePath = relPath; + } + else + { + // the original file is not relative to the SourceDir. + // it could have its own fullpath or contains "..\" etc. + // + // In this case, we want to put the filename as relative filepath + // and put the deepest directory that file is in as the new + // SourceDir. + // + int pathEndIndex = fullFilePath.LastIndexOf("\\", StringComparison.Ordinal); + + newSourceDir = fullFilePath.Substring(0, pathEndIndex + 1); + newRelativeFilePath = fullFilePath.Substring(pathEndIndex + 1); + } + + return newRelativeFilePath; + } + + #endregion + + #region private data + + private MarkupCompiler _mc; + private string _sourceDir; + private TaskLoggingHelper _taskLogger; + private int _nErrors; + private string _unknownErrorID; + + private FileUnit _applicationMarkup; + + private int _localizationDirectivesToLocFile; + + #endregion + + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IPersistFileCheckSum.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IPersistFileCheckSum.cs new file mode 100644 index 00000000000..8c5d2079bb3 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IPersistFileCheckSum.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: +// Managed declaration for IPersistFileCheckSum used for +// VS project system for MarkupCompile tasks. +// +// ***********************IMPORTANT************************** +// +// The managed side declaration of this interface should match with +// the native side declaration which lives in VS.NET project tree. +// +//--------------------------------------------------------------------------- + +using System; +using System.Runtime.InteropServices; +using System.Security; + + +namespace MS.Internal +{ + //MIDL_INTERFACE("35355DA7-3EEA-452e-89F3-68344278F806") + // IPersistFileCheckSum : public IUnknown + // { + // public: + // virtual HRESULT STDMETHODCALLTYPE CalculateCheckSum( + // /* [in] */ __RPC__in REFGUID guidCheckSumAlgorithm, + // /* [in] */ DWORD cbBufferSize, + // /* [size_is][out] */ __RPC__out_ecount_full(cbBufferSize) BYTE *pbHash, + // /* [out] */ __RPC__out DWORD *pcbActualSize) = 0; + // }; + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("35355DA7-3EEA-452e-89F3-68344278F806")] + internal interface IPersistFileCheckSum + { + void CalculateCheckSum( [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidCheckSumAlgorithm, + [In, MarshalAs(UnmanagedType.U4)] int cbBufferSize, + [Out, MarshalAs(UnmanagedType.LPArray, + SizeParamIndex=1)] byte[] Hash, + [Out, MarshalAs(UnmanagedType.U4)] out int ActualSize); + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IVsMSBuildTaskFileManager.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IVsMSBuildTaskFileManager.cs new file mode 100644 index 00000000000..7fbac38971f --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IVsMSBuildTaskFileManager.cs @@ -0,0 +1,94 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: +// Managed declaration for IVsMSBuildTaskFileManager used for +// getting HostObject that is implemented by VS project system for +// MarkupCompile tasks. +// +// ***********************IMPORTANT************************** +// +// The managed side declaration of this interface should match with +// the native side declaration which lives in VS.NET project tree. +// +//--------------------------------------------------------------------------- + +using System; +using System.Runtime.InteropServices; +using System.Security; + + +namespace MS.Internal +{ + // + // Internal interface used for Interop in VS.NET hosting scenarios. + // VS.NET project system prepares the hostobject instance which implements + // this interface, The markupcompiler task wants to call this interface + // to get file content from editor buffer and get last modification time. + // + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("33372170-A08F-47F9-B1AE-CD9F2C3BB7C9")] + internal interface IVsMSBuildTaskFileManager + { + // Returns the contents of the specified file based on whats in-memory else what's + // on disk if not in-memory. + [SecurityCritical, SuppressUnmanagedCodeSecurity] + string GetFileContents([In, MarshalAs(UnmanagedType.LPWStr)] string wszFilename); + + // + // Returns the live punkDocData object for the file if it is registered in the RDT, + // else returns NULL. + // + /// + /// Critical - call is SUC'ed + /// + [SecurityCritical, SuppressUnmanagedCodeSecurity] + [return:MarshalAs(UnmanagedType.IUnknown)] + object GetFileDocData([In, MarshalAs(UnmanagedType.LPWStr)] string wszFilename); + + + // Returns the time of the last change to the file. If open in memory, then this is the + // time of the last edit as reported via IVsLastChangeTimeProvider::GetLastChangeTime + // on the open document. If the file is not open, then the last change time of the file + // on disk is returned. + [SecurityCritical, SuppressUnmanagedCodeSecurity] + //System.Runtime.InteropServices.ComTypes.FILETIME GetFileLastChangeTime([In, MarshalAs(UnmanagedType.LPWStr)] string wszFilename); + long GetFileLastChangeTime([In, MarshalAs(UnmanagedType.LPWStr)] string wszFilename); + + // PutGeneratedFileContents -- puts the contents for the generated file + // into an in memory TextBuffer and registers it in the RDT with a RDT_ReadLock. + // This holds the file open in memory until the project is closed (when the + // project will call IVsMSBuildHostObject::Close). If this is an actual + // build operation (ie. UICONTEXT_SolutionBuilding is on) then the file will + // also be saved to disk. If this is only a generation at design time for + // intellisense purposes then the file contents are only put into memory + // and the disk is not modified. The in-memory TextBuffer is always marked + // as clean so the user will not be prompted to save the generated file. + [SecurityCritical, SuppressUnmanagedCodeSecurity] + void PutGeneratedFileContents([In, MarshalAs(UnmanagedType.LPWStr)] string wszFilename, [In, MarshalAs(UnmanagedType.LPWStr)] string strFileContents); + + + // IsRealBuildOperation -- returns TRUE if this is a real Build operation else + // if this is a design-time only generation for intellisense purposes it returns + // FALSE. + [SecurityCritical, SuppressUnmanagedCodeSecurity] + [return:MarshalAs(UnmanagedType.Bool)] + bool IsRealBuildOperation(); + + + // Delete -- deletes a file on disk and removes it from the RDT + [SecurityCritical, SuppressUnmanagedCodeSecurity] + void Delete([In, MarshalAs(UnmanagedType.LPWStr)] string wszFilename); + + + // Exists -- determines whether or not a file exists in the RDT or on disk + [SecurityCritical, SuppressUnmanagedCodeSecurity] + [return:MarshalAs(UnmanagedType.Bool)] + bool Exists([In, MarshalAs(UnmanagedType.LPWStr)] string wszFilename, [In, MarshalAs(UnmanagedType.Bool)] bool fOnlyCheckOnDisk); + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IncrementalCompileAnalyzer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IncrementalCompileAnalyzer.cs new file mode 100644 index 00000000000..bbe98b8b1e0 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IncrementalCompileAnalyzer.cs @@ -0,0 +1,614 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//---------------------------------------------------------------------------------------- +// +// Description: +// Analyze the current project inputs, the compiler state file and local reference +// cache, determine which xaml files require to recompile. +// +//--------------------------------------------------------------------------------------- + +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; + +using Microsoft.Build.Tasks.Windows; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using MS.Utility; + +namespace MS.Internal.Tasks +{ + // + // Keep different categories of recompilation. + // + [Flags] + internal enum RecompileCategory : byte + { + NoRecompile = 0x00, + ApplicationFile = 0x01, + ModifiedPages = 0x02, + PagesWithLocalType = 0x04, + ContentFiles = 0x08, + All = 0x0F + } + + // + // IncrementalCompileAnalyzer + // + internal class IncrementalCompileAnalyzer + { + // + // ctor of IncrementalCompileAnalyzer + // + internal IncrementalCompileAnalyzer(MarkupCompilePass1 mcPass1) + { + _mcPass1 = mcPass1; + _analyzeResult = RecompileCategory.NoRecompile; + } + + #region internal methods + + + // + // Analyze the input files based on the compiler cache files. + // + // Put the analyze result in _analyzeResult and other related data fields, + // such as RecompileMarkupPages, RecompileApplicationFile, etc. + // + // If analyze is failed somehow, throw exception. + // + internal void AnalyzeInputFiles() + { + + // + // First: Detect if the entire project requires re-compile. + // + + // + // If the compiler state file doesn't exist, recompile all the xaml files. + // + if (!CompilerState.StateFileExists()) + { + _analyzeResult = RecompileCategory.All; + } + else + { + // Load the compiler state file. + CompilerState.LoadStateInformation(); + + // if PresenationBuildTasks.dll is changed last build, rebuild the entire project for sure. + + if (IsFileChanged(Assembly.GetExecutingAssembly().Location) || + IsFileListChanged(_mcPass1.ExtraBuildControlFiles)) + { + _analyzeResult = RecompileCategory.All; + } + else + { + // + // Any one single change in below list would request completely re-compile. + // + if (IsSettingModified(CompilerState.References, _mcPass1.ReferencesCache) || + IsSettingModified(CompilerState.ApplicationFile, _mcPass1.ApplicationFile) || + IsSettingModified(CompilerState.RootNamespace, _mcPass1.RootNamespace) || + IsSettingModified(CompilerState.AssemblyName, _mcPass1.AssemblyName) || + IsSettingModified(CompilerState.AssemblyVersion, _mcPass1.AssemblyVersion) || + IsSettingModified(CompilerState.AssemblyPublicKeyToken, _mcPass1.AssemblyPublicKeyToken) || + IsSettingModified(CompilerState.OutputType, _mcPass1.OutputType) || + IsSettingModified(CompilerState.Language, _mcPass1.Language) || + IsSettingModified(CompilerState.LanguageSourceExtension, _mcPass1.LanguageSourceExtension) || + IsSettingModified(CompilerState.OutputPath, _mcPass1.OutputPath) || + IsSettingModified(CompilerState.LocalizationDirectivesToLocFile, _mcPass1.LocalizationDirectivesToLocFile)) + { + _analyzeResult = RecompileCategory.All; + } + else + { + if (_mcPass1.IsApplicationTarget) + { + // + // When application definition file is modified, it could potentially change the application + // class name, it then has impact on all other xaml file compilation, so recompile the entire + // project for this case. + // + if (TaskFileService.Exists(_mcPass1.ApplicationFile) && IsFileChanged(_mcPass1.ApplicationFile)) + { + _analyzeResult = RecompileCategory.All; + } + } + + // + // If any one referenced assembly is updated since last build, the entire project needs to recompile. + // + + if (IsFileListChanged(_mcPass1.References)) + { + _analyzeResult = RecompileCategory.All; + } + } + } + } + + if (_analyzeResult == RecompileCategory.All) + { + UpdateFileListForCleanbuild(); + return; + } + + // + // The entire project recompilation should have already been handled when code goes here. + // Now, Detect the individual xaml files which require to recompile. + // + + if (_mcPass1.IsApplicationTarget) + { + if (IsSettingModified(CompilerState.ContentFiles, _mcPass1.ContentFilesCache)) + { + _analyzeResult |= RecompileCategory.ContentFiles; + } + + // if HostInBrowser setting is changed, it would affect the application file compilation only. + if (IsSettingModified(CompilerState.HostInBrowser, _mcPass1.HostInBrowser)) + { + _analyzeResult |= RecompileCategory.ApplicationFile; + } + + if (IsSettingModified(CompilerState.SplashImage, _mcPass1.SplashImageName)) + { + _analyzeResult |= RecompileCategory.ApplicationFile; + } + } + + // + // If code files are changed, or Define flags are changed, it would affect the xaml file with local types. + // + // If previous build didn't have such local-ref-xaml files, don't bother to do further check for this. + // + + if (CompilerLocalReference.CacheFileExists()) + { + if (IsSettingModified(CompilerState.DefineConstants, _mcPass1.DefineConstants) || + IsSettingModified(CompilerState.SourceCodeFiles, _mcPass1.SourceCodeFilesCache) || + IsFileListChanged(_mcPass1.SourceCodeFiles) ) + { + _analyzeResult |= RecompileCategory.PagesWithLocalType; + } + } + + List modifiedXamlFiles = new List(); + + // + // Detect if any .xaml page is updated since last build + // + if (ListIsNotEmpty(_mcPass1.PageMarkup)) + { + + // + // If the PageMarkup file number or hashcode is changed, it would affect + // the xaml files with local types. + // + // This check is necessary for the senario that a xaml file is removed and the + // removed xaml file could be referenced by other xaml files with local types. + // + if (IsSettingModified(CompilerState.PageMarkup, _mcPass1.PageMarkupCache)) + { + if (CompilerLocalReference.CacheFileExists()) + { + _analyzeResult |= RecompileCategory.PagesWithLocalType; + } + } + + // Below code detects which individual xaml files are modified since last build. + for (int i = 0; i < _mcPass1.PageMarkup.Length; i++) + { + ITaskItem taskItem = _mcPass1.PageMarkup[i]; + string fileName = taskItem.ItemSpec; + string filepath = Path.GetFullPath(fileName); + string linkAlias = taskItem.GetMetadata(SharedStrings.Link); + string logicalName = taskItem.GetMetadata(SharedStrings.LogicalName); + + if (IsFileChanged(filepath)) + { + // add this file to the modified file list. + modifiedXamlFiles.Add(new FileUnit(filepath, linkAlias, logicalName)); + } + else + { + // A previously generated xaml file (with timestamp earlier than of the cache file) + // could be added to the project. This means that the above check for time stamp + // will skip compiling the newly added xaml file. We save the name all the xaml + // files we previously built to the cache file. Retrieve that list and see if + // this xaml file is already in it. If so, we'll skip compiling this xaml file, + // else, this xaml file was just added to the project and thus compile it. + + if (!CompilerState.PageMarkupFileNames.Contains(fileName)) + { + modifiedXamlFiles.Add(new FileUnit(filepath, linkAlias, logicalName)); + } + } + } + + if (modifiedXamlFiles.Count > 0) + { + _analyzeResult |= RecompileCategory.ModifiedPages; + + if (CompilerLocalReference.CacheFileExists()) + { + _analyzeResult |= RecompileCategory.PagesWithLocalType; + } + } + } + + // Check for the case where a required Pass2 wasn't run, e.g. because the build was aborted, + // or because the Compile target was run inside VS. + // If that happened, let's recompile the local-type pages, which will force Pass2 to run. + if (CompilerState.Pass2Required && CompilerLocalReference.CacheFileExists()) + { + _analyzeResult |= RecompileCategory.PagesWithLocalType; + } + + UpdateFileListForIncrementalBuild(modifiedXamlFiles); + + } + + #endregion + + #region internal properties + + // + // Keep the AnlyzeResult. + // + internal RecompileCategory AnalyzeResult + { + get { return _analyzeResult; } + } + + // + // Keep a list of markup pages which require to recompile + // + internal FileUnit[] RecompileMarkupPages + { + get { return _recompileMarkupPages; } + } + + // + // Application file which requires re-compile. + // If the value is String.Empty, the appdef file is not required + // to recompile. + // + internal FileUnit RecompileApplicationFile + { + get { return _recompileApplicationFile; } + } + + + internal string[] ContentFiles + { + get { return _contentFiles; } + } + + #endregion + + #region private properties and methods + + private CompilerState CompilerState + { + get { return _mcPass1.CompilerState; } + } + + private CompilerLocalReference CompilerLocalReference + { + get { return _mcPass1.CompilerLocalReference; } + } + + private ITaskFileService TaskFileService + { + get { return _mcPass1.TaskFileService; } + } + + private DateTime LastCompileTime + { + get + { + DateTime nonSet = new DateTime(0); + if (_lastCompileTime == nonSet) + { + _lastCompileTime = TaskFileService.GetLastChangeTime(CompilerState.CacheFilePath); + + } + + return _lastCompileTime; + } + } + + // + // Compare two strings. + // + private bool IsSettingModified(string textSource, string textTarget) + { + bool IsSettingModified; + + bool isSrcEmpty = String.IsNullOrEmpty(textSource); + bool istgtEmpty = String.IsNullOrEmpty(textTarget); + + if (isSrcEmpty != istgtEmpty) + { + IsSettingModified = true; + } + else + { + if (isSrcEmpty) // Both source and target strings are empty. + { + IsSettingModified = false; + } + else // Both source and target strings are not empty. + { + IsSettingModified = String.Compare(textSource, textTarget, StringComparison.OrdinalIgnoreCase) == 0 ? false : true; + } + } + + return IsSettingModified; + } + + // + // Generate new list of files that require to recompile for incremental build based on _analyzeResult + // + private void UpdateFileListForIncrementalBuild(List modifiedXamlFiles) + { + List recompiledXaml = new List(); + bool recompileApp = false; + int numLocalTypeXamls = 0; + + if ((_analyzeResult & RecompileCategory.ContentFiles) == RecompileCategory.ContentFiles) + { + RecompileContentFiles(); + } + + if ((_analyzeResult & RecompileCategory.ApplicationFile) == RecompileCategory.ApplicationFile) + { + recompileApp = true; + } + + if ((_analyzeResult & RecompileCategory.PagesWithLocalType) == RecompileCategory.PagesWithLocalType && TaskFileService.IsRealBuild) + { + CompilerLocalReference.LoadCacheFile(); + + if (CompilerLocalReference.LocalApplicationFile != null) + { + // Application file contains local types, it will be recompiled. + recompileApp = true; + } + + if (ListIsNotEmpty(CompilerLocalReference.LocalMarkupPages)) + { + numLocalTypeXamls = CompilerLocalReference.LocalMarkupPages.Length; + + for (int i = 0; i < CompilerLocalReference.LocalMarkupPages.Length; i++) + { + LocalReferenceFile localRefFile = CompilerLocalReference.LocalMarkupPages[i]; + recompiledXaml.Add(new FileUnit( + localRefFile.FilePath, + localRefFile.LinkAlias, + localRefFile.LogicalName)); + } + } + + } + + if ((_analyzeResult & RecompileCategory.ModifiedPages) == RecompileCategory.ModifiedPages) + { + // If the xaml is already in the local-type-ref xaml file list, don't add a duplicate file path to recompiledXaml list. + + for (int i = 0; i < modifiedXamlFiles.Count; i++) + { + FileUnit xamlfile = modifiedXamlFiles[i]; + bool addToList; + + addToList = true; + + if (numLocalTypeXamls > 0) + { + for (int j = 0; j < numLocalTypeXamls; j++) + { + if (String.Compare(xamlfile.Path, CompilerLocalReference.LocalMarkupPages[j].FilePath, StringComparison.OrdinalIgnoreCase) == 0) + { + addToList = false; + break; + } + } + } + + if (addToList) + { + recompiledXaml.Add(xamlfile); + } + } + } + + if (recompiledXaml.Count > 0) + { + _recompileMarkupPages = recompiledXaml.ToArray(); + } + + // Set ApplicationFile appropriatelly for this incremental build. + ProcessApplicationFile(recompileApp); + } + + // + // To recompile all the xaml files ( including page and application file). + // Transfer all the xaml files to the recompileMarkupPages. + // + private void UpdateFileListForCleanbuild() + { + if (ListIsNotEmpty(_mcPass1.PageMarkup)) + { + int count = _mcPass1.PageMarkup.Length; + _recompileMarkupPages = new FileUnit[count]; + + for (int i = 0; i < count; i++) + { + ITaskItem taskItem = _mcPass1.PageMarkup[i]; + _recompileMarkupPages[i] = new FileUnit( + Path.GetFullPath(taskItem.ItemSpec), + taskItem.GetMetadata(SharedStrings.Link), + taskItem.GetMetadata(SharedStrings.LogicalName)); + } + } + + RecompileContentFiles(); + + ProcessApplicationFile(true); + } + + // + // Content files are only for Application target type. + // + private void RecompileContentFiles() + { + if (!_mcPass1.IsApplicationTarget) + return; + + if (_contentFiles == null) + { + if (ListIsNotEmpty(_mcPass1.ContentFiles)) + { + string curDir = Directory.GetCurrentDirectory() + "\\"; + + int count = _mcPass1.ContentFiles.Length; + + _contentFiles = new string[count]; + + for (int i = 0; i < count; i++) + { + string fullPath = Path.GetFullPath(_mcPass1.ContentFiles[i].ItemSpec); + + string relContentFilePath = TaskHelper.GetRootRelativePath(curDir, fullPath); + + if (String.IsNullOrEmpty(relContentFilePath)) + { + relContentFilePath = Path.GetFileName(fullPath); + } + + _contentFiles[i] = relContentFilePath; + } + + } + } + } + + // + // Handle Application definition xaml file and Application Class name. + // recompile parameter indicates whether or not to recompile the appdef file. + // If the appdef file is not recompiled, a specially handling is required to + // take application class name from previous build. + // + private void ProcessApplicationFile(bool recompile) + { + if (!_mcPass1.IsApplicationTarget) + { + return; + } + + if (recompile) + { + // + // Take whatever setting in _mcPass1 task. + // + if (_mcPass1.ApplicationMarkup != null && _mcPass1.ApplicationMarkup.Length > 0 && _mcPass1.ApplicationMarkup[0] != null) + { + ITaskItem taskItem = _mcPass1.ApplicationMarkup[0]; + _recompileApplicationFile = new FileUnit( + _mcPass1.ApplicationFile, + taskItem.GetMetadata(SharedStrings.Link), + taskItem.GetMetadata(SharedStrings.LogicalName)); + } + else + { + _recompileApplicationFile = FileUnit.Empty; + } + } + else + { + _recompileApplicationFile = FileUnit.Empty; + + } + } + + // + // Detect if at least one file in the same item list has changed since last build. + // + private bool IsFileListChanged(ITaskItem[] fileList) + { + bool isChanged = false; + + if (ListIsNotEmpty(fileList)) + { + for (int i = 0; i < fileList.Length; i++) + { + if (IsFileChanged(fileList[i].ItemSpec)) + { + isChanged = true; + break; + } + } + } + + return isChanged; + + } + + // + // Detect if the input file was changed since last build. + // + private bool IsFileChanged(string inputFile) + { + bool isChanged = false; + + DateTime dtFile; + + + dtFile = TaskFileService.GetLastChangeTime(inputFile); + + if (dtFile > LastCompileTime) + { + isChanged = true; + } + + return isChanged; + } + + // A helper to detect if the list is not empty. + private bool ListIsNotEmpty(object [] list) + { + bool isNotEmpty = false; + + if (list != null && list.Length > 0) + { + isNotEmpty = true; + } + + return isNotEmpty; + } + + #endregion + + #region private data + + private MarkupCompilePass1 _mcPass1; + private RecompileCategory _analyzeResult; + private DateTime _lastCompileTime = new DateTime(0); + + private FileUnit[] _recompileMarkupPages = null; + private FileUnit _recompileApplicationFile = FileUnit.Empty; + private string[] _contentFiles = null; + + #endregion + + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskFileService.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskFileService.cs new file mode 100644 index 00000000000..e7f218d915d --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskFileService.cs @@ -0,0 +1,447 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: +// +// File service for the input source files in a build task. +// +// The service does something like below: +// +// return stream for a given source file, +// get last modification time in memory or disk. +// +// or get the link metadata part of a source file. +// +// It returns above information no matter the task is hosted +// inside VS or not. +// +//--------------------------------------------------------------------------- + +using System; +using System.IO; +using Microsoft.Build.Utilities; +using Microsoft.Build.Tasks.Windows; +using System.Diagnostics; +using System.Text; +using System.Security.Cryptography; + +namespace MS.Internal +{ + // + // Declaration of interface ITaskFileService + // + internal interface ITaskFileService + { + // + // Get content stream for a given source file + // + Stream GetContent(string srcFile); + + // + // Get MD5 Check Sum for a given source file + // + byte[] GetChecksum(string srcFile, Guid hashGuid); + + // + // Get the last modificatin time for a given file. + // + DateTime GetLastChangeTime(string srcFile); + + // + // Checks to see if file exists + // + bool Exists(string fileName); + + // + // Deletes the specified file + // + void Delete(string fileName); + + // + // Save content stream for the given destination file + // + void WriteFile(byte[] contentArray, string destinationFile); + + // + // Save content stream for the given generated code file. + // This function decides which extension to use for the file + // and whether to put it into memory or merely write it to + // disk based on whether it is a real build or an intellisense + // build operation. It also takes care of deleting the corresponding + // unused generated file (i.e. if real build then it deletes + // the intellisense file otherwise it deletes the non-intellisense + // file. + // NOTE: UTF8 BOM should not be added to the contentArray. This + // method adds BOM before writing file to disk. + // + void WriteGeneratedCodeFile(byte[] contentArray, string destinationFileBaseName, + string generatedExtension, string intellisenseGeneratedExtension, string languageSourceExtension); + + // + // Determines if this is a real build operation or an + // intellisense build operation + // + bool IsRealBuild {get;} + + // + // Determines if this is running in VS or MsBuild + // + bool IsRunningInVS { get; } + } + + // + // TaskFileService class + // + // This class can be used by different build tasks to get source file + // service, the instance is created by those build tasks when task's + // Execute( ) method is called. + // + internal class TaskFileService : MarshalByRefObject, ITaskFileService + { + // + // Ctor + // + public TaskFileService(Task buildTask) + { + _buildTask = buildTask; + _hostFileManager = null; + _isRealBuild = null; + } + + #region ITaskFileService + + // + // Get content stream for a given source file, the content could + // come from memory or disk based on the build host environment. + // + // It is the caller's responsibility to close the stream. + // + public Stream GetContent(string srcFile) + { + Stream fileStream = null; + + if (String.IsNullOrEmpty(srcFile)) + { + throw new ArgumentNullException("srcFile"); + } + + if (HostFileManager != null) + { + // + // Build Host environment has a FileManager, use it to get + // file content from edit buffer in memory. GetFileContents + // removes the BOM before returning the string. + // + string strFileContent = HostFileManager.GetFileContents(srcFile); + + + // IVsMsBuildTaskFileManager.GetFileContents should never return null. + // GetBytes might throw when input is null, but that should be fine. + // + // For xaml file, UTF8 is the standard encoding + // + UTF8Encoding utf8Encoding = new UTF8Encoding(); + byte[] baFileContent = utf8Encoding.GetBytes(strFileContent); + fileStream = new MemoryStream(baFileContent); + + } + else + { + fileStream = File.OpenRead(srcFile); + } + + return fileStream; + } + + public byte[] GetChecksum(string fileName, Guid hashGuid) + { + byte[] hashData=null; + + if (HostFileManager != null) + { + object docData = HostFileManager.GetFileDocData(fileName); + IPersistFileCheckSum fileChecksummer = docData as IPersistFileCheckSum; + if (fileChecksummer != null) + { + byte[] tempBytes = new byte[1024]; + int actualSize; + fileChecksummer.CalculateCheckSum(hashGuid, tempBytes.Length, tempBytes, out actualSize); + hashData = new byte[actualSize]; + for (int i = 0; i < actualSize; i++) + { + hashData[i] = tempBytes[i]; + } + } + } + if (hashData == null) + { + HashAlgorithm hashAlgorithm; + + if (hashGuid == s_hashSHA256Guid) + { + hashAlgorithm = SHA256.Create(); + } + else if (hashGuid == s_hashSHA1Guid) + { + hashAlgorithm = SHA1.Create(); + } + else if (hashGuid == s_hashMD5Guid) + { + hashAlgorithm = MD5.Create(); + } + else + { + hashAlgorithm = null; + } + + if (hashAlgorithm != null) + { + using (Stream fileStream = File.OpenRead(fileName)) + { + hashData = hashAlgorithm.ComputeHash(fileStream); + } + } + } + return hashData; + } + + // + // Get the last modificatin time for a given file. + // + public DateTime GetLastChangeTime(string srcFile) + { + DateTime lastChangeDT = new DateTime(0); + + if (String.IsNullOrEmpty(srcFile)) + { + throw new ArgumentNullException("srcFile"); + } + + if (IsFileInHostManager(srcFile)) + { + long fileTime = HostFileManager.GetFileLastChangeTime(srcFile); + lastChangeDT = DateTime.FromFileTime(fileTime); + } + else + { + lastChangeDT = File.GetLastWriteTime(srcFile); + } + + return lastChangeDT; + } + + + // + // Checks to see if file exists + // + public bool Exists(string fileName) + { + bool fileExists = false; + + if (fileName == null) + { + throw new ArgumentNullException("fileName"); + } + + if (HostFileManager != null) + { + fileExists = HostFileManager.Exists(fileName, IsRealBuild); + } + else + { + fileExists = File.Exists(fileName); + } + + return fileExists; + } + + // + // Deletes the specified file + // + public void Delete(string fileName) + { + if (fileName == null) + { + throw new ArgumentNullException("fileName"); + } + + if (IsFileInHostManager(fileName)) + { + HostFileManager.Delete(fileName); + } + else + { + File.Delete(fileName); + } + } + + // + // Save content stream for the given destination file + // UTF8 BOM should not be added to the contentArray. This + // method adds BOM before writing file to disk. + // + public void WriteFile(byte[] contentArray, string destinationFile) + { + if (String.IsNullOrEmpty(destinationFile)) + { + throw new ArgumentNullException("destinationFile"); + } + + if (contentArray == null) + { + throw new ArgumentNullException("contentArray"); + } + + UTF8Encoding utf8Encoding = new UTF8Encoding(); + string contentStr = utf8Encoding.GetString(contentArray); + + if (IsFileInHostManager(destinationFile)) + { + // PutGeneratedFileContents adds BOM to the file when saving + // to memory or disk. + HostFileManager.PutGeneratedFileContents(destinationFile, contentStr); + } + else + { + // Add BOM for UTF8Encoding since the input contentArray is not supposed to + // have it already. + using (StreamWriter sw = new StreamWriter(destinationFile, false, new UTF8Encoding(true))) + { + sw.WriteLine(contentStr); + } + } + } + + // Save content stream for the given generated code file. + // This function decides which extension to use for the file + // and whether to put it into memory or merely write it to + // disk based on whether it is a real build or an intellisense + // build operation. It also takes care of deleting the corresponding + // unused generated file (i.e. if real build then it deletes + // the intellisense file otherwise it deletes the non-intellisense + // file. + // NOTE: UTF8 BOM should not be added to the contentArray. This + // method adds BOM before writing file to disk. + // + public void WriteGeneratedCodeFile(byte[] contentArray, string destinationFileBaseName, + string generatedExtension, string intellisenseGeneratedExtension, string languageSourceExtension) + { + if (String.IsNullOrEmpty(destinationFileBaseName)) + { + throw new ArgumentNullException("destinationFileBaseName"); + } + + if (contentArray == null) + { + throw new ArgumentNullException("contentArray"); + } + + string buildFile = destinationFileBaseName + generatedExtension + languageSourceExtension; + string intelFile = destinationFileBaseName + intellisenseGeneratedExtension + languageSourceExtension; + + string destinationFile = IsRealBuild ? buildFile : intelFile; + + UTF8Encoding utf8Encoding = new UTF8Encoding(); + string contentStr = utf8Encoding.GetString(contentArray); + + // Add BOM for UTF8Encoding since the input contentArray is not supposed to + // have it already. + using (StreamWriter sw = new StreamWriter(destinationFile, false, new UTF8Encoding(true))) + { + sw.WriteLine(contentStr); + } + + if (IsRealBuild && IsRunningInVS) + { + File.Copy(buildFile, intelFile, /*overwrite*/ true); + } + } + + // + // Tells if this is an intellisense build or a real build. + // Caching the result since this is called a lot of times. + // + public bool IsRealBuild + { + get + { + if (_isRealBuild == null) + { + bool isRealBuild = true; + + if (HostFileManager != null) + { + isRealBuild = HostFileManager.IsRealBuildOperation(); + } + + _isRealBuild = isRealBuild; + } + + return _isRealBuild.Value; + } + } + + public bool IsRunningInVS + { + get + { + MarkupCompilePass1 pass1; + return (HostFileManager != null) || + ( (pass1 = _buildTask as MarkupCompilePass1) != null && + pass1.IsRunningInVisualStudio); + } + } + + #endregion ITaskFileService + + #region private property + + // + // Get the FileManager implemented by the Host system + // + private IVsMSBuildTaskFileManager HostFileManager + { + get + { + if (_hostFileManager == null) + { + if (_buildTask != null && _buildTask.HostObject != null) + { + _hostFileManager = _buildTask.HostObject as IVsMSBuildTaskFileManager; + } + } + + return _hostFileManager; + } + } + + private bool IsFileInHostManager(string destinationFile) + { + if (HostFileManager != null && null != HostFileManager.GetFileDocData(destinationFile)) + { + return true; + } + return false; + } + + #endregion private property + + + #region private data field + + private Task _buildTask; + private IVsMSBuildTaskFileManager _hostFileManager; + private Nullable _isRealBuild; + private static Guid s_hashSHA256Guid = new Guid(0x8829d00f, 0x11b8, 0x4213, 0x87, 0x8b, 0x77, 0x0e, 0x85, 0x97, 0xac, 0x16); + private static Guid s_hashSHA1Guid = new Guid(0xff1816ec, 0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60); + private static Guid s_hashMD5Guid = new Guid(0x406ea660, 0x64cf, 0x4c82, 0xb6, 0xf0, 0x42, 0xd4, 0x81, 0x72, 0xa7, 0x99); + + #endregion private data field + + } + + +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskHelper.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskHelper.cs new file mode 100644 index 00000000000..cb3d1330630 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskHelper.cs @@ -0,0 +1,381 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//----------------------------------------------------------------------------- +// +// Description: +// TaskHelper implements some common functions for all the WCP tasks +// to call. +// +//------------------------------------------------------------------------------ + +using System; +using System.IO; +using System.Collections; +using System.Text; +using System.Runtime.InteropServices; + +using System.Globalization; +using System.Diagnostics; +using System.Reflection; +using System.Resources; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +using Microsoft.Build.Tasks; +using MS.Utility; +using System.Collections.Generic; + + +namespace MS.Internal.Tasks +{ + // + // This is required by the unmanaged API GetGacPath. + // the value indicates the source of the cached assembly. + // + // For our scenario, we just care about GACed assembly. + // + [Flags] + internal enum AssemblyCacheFlags + { + ZAP = 1, + GAC = 2, + DOWNLOAD = 4, + ROOT = 8, + ROOT_EX = 0x80 + } + + #region BaseTask class + // + // TaskHelper which implements some helper methods. + // + internal static class TaskHelper + { + + //------------------------------------------------------ + // + // Internal Helper Methods + // + //------------------------------------------------------ + + #region Internal Methods + + // + // Output the Logo information to the logger for a given task + // (Console or registered Loggers). + // + internal static void DisplayLogo(TaskLoggingHelper log, string taskName) + { + string acPath = Assembly.GetExecutingAssembly().Location; + FileVersionInfo acFileVersionInfo = FileVersionInfo.GetVersionInfo(acPath); + + string avalonFileVersion = acFileVersionInfo.FileVersion; + + log.LogMessage(MessageImportance.Low,Environment.NewLine); + log.LogMessageFromResources(MessageImportance.Low, SRID.TaskLogo, taskName, avalonFileVersion); + log.LogMessageFromResources(MessageImportance.Low, SRID.TaskRight); + log.LogMessage(MessageImportance.Low, Environment.NewLine); + } + + + // + // Create the full file path with the right root path + // + // The original file path + // The root path + // The new fullpath + internal static string CreateFullFilePath(string thePath, string rootPath) + { + // make it an absolute path if not already so + if ( !Path.IsPathRooted(thePath) ) + { + thePath = rootPath + thePath; + } + + // get rid of '..' and '.' if any + thePath = Path.GetFullPath(thePath); + + return thePath; + } + + // + // This helper returns the "relative" portion of a path + // to a given "root" + // - both paths need to be rooted + // - if no match > return empty string + // E.g.: path1 = C:\foo\bar\ + // path2 = C:\foo\bar\baz + // + // return value = "baz" + // + internal static string GetRootRelativePath(string path1, string path2) + { + string relPath = ""; + string fullpath1; + string fullpath2; + + string sourceDir = Directory.GetCurrentDirectory() + "\\"; + + // make sure path1 and Path2 are both full path + // so that they can be compared on right base. + + fullpath1 = CreateFullFilePath (path1, sourceDir); + fullpath2 = CreateFullFilePath (path2, sourceDir); + + if (fullpath2.StartsWith(fullpath1, StringComparison.OrdinalIgnoreCase)) + { + relPath = fullpath2.Substring (fullpath1.Length); + } + + return relPath; + } + + // + // Convert a string to a Boolean value using exactly the same rules as + // MSBuild uses when it assigns project properties to Boolean CLR properties + // in a task class. + // + // The string value to convert + // true if str is "true", "yes", or "on" (case-insensitive), + // otherwise false. + internal static bool BooleanStringValue(string str) + { + bool isBoolean = false; + + if (str != null && str.Length > 0) + { + str = str.ToLower(CultureInfo.InvariantCulture); + + if (str.Equals("true") || str.Equals("yes") || str.Equals("on")) + { + isBoolean = true; + } + } + + return isBoolean; + } + + + // + // return a lower case string + // + // + // + internal static string GetLowerString(string str) + { + string lowerStr = null; + + if (str != null && str.Length > 0) + { + lowerStr = str.ToLower(CultureInfo.InvariantCulture); + } + + return lowerStr; + } + + // + // Check if the passed string stands for a valid culture name. + // + internal static bool IsValidCultureName(string name) + { + + bool bValid = true; + + try + { + // + // If the passed name is empty or null, we still want + // to treat it as valid culture name. + // It means no satellite assembly will be generated, all the + // resource images will go to the main assembly. + // + if (name != null && name.Length > 0) + { + CultureInfo cl; + + cl = new CultureInfo(name); + + // if CultureInfo instance cannot be created for the given name, + // treat it as invalid culture name. + + if (cl == null) + bValid = false; + } + } + catch (ArgumentException) + { + bValid = false; + } + + return bValid; + } + +#if false + [DllImport("fusion.dll", CharSet = CharSet.Unicode)] + internal static extern int GetCachePath(AssemblyCacheFlags cacheFlags, StringBuilder cachePath, ref int pcchPath); +#endif + + private static List _gacPaths; + internal static IEnumerable GetGacPaths() + { + if (_gacPaths != null) return _gacPaths; + +#if false + List gacPaths = new List(); + + AssemblyCacheFlags[] flags = new AssemblyCacheFlags[] { + AssemblyCacheFlags.ROOT, + AssemblyCacheFlags.ROOT_EX + }; + + foreach (AssemblyCacheFlags flag in flags) + { + int gacPathLength = 0; + + // Request the size of buffer for the path. + int hresult = GetCachePath(flag, null, ref gacPathLength); + + // + // When gacPathLength is set to 0 and passed to this method, the return value + // is an error which indicates INSUFFICIENT_BUFFER, so the code here doesn't + // check that return value, but just check whether the returned desired buffer + // length is valid or not. + // + if (gacPathLength > 0) + { + // Allocate the right size for that buffer. + StringBuilder gacPath = new StringBuilder(gacPathLength); + + // Get the real path string to the buffer. + hresult = GetCachePath(flag, gacPath, ref gacPathLength); + + if (hresult >= 0) + { + gacPaths.Add(gacPath.ToString()); + } + } + } + if (gacPaths.Count > 0) + { + _gacPaths = gacPaths; + } +#else + _gacPaths = new List(); +#endif + return _gacPaths; + } + + + // + // Detect whether the referenced assembly could be changed during the build procedure. + // + // Current logic: + // By default, assume it could be changed during the build. + // If knownChangedAssemblies are set, only those assemblies are changeable, all others are not. + // + // If the assembly is not in the knownChangedAssemblies list, + // but it is under GAC or under knownUnchangedReferencePaths, it is not changeable. + // + internal static bool CouldReferenceAssemblyBeChanged(string assemblyPath, string[] knownUnchangedReferencePaths, string[] knownChangedAssemblies) + { + Debug.Assert(String.IsNullOrEmpty(assemblyPath) == false, "assemblyPath should not be empty."); + + bool bCouldbeChanged = true; + + if (String.Compare(Path.GetExtension(assemblyPath), SharedStrings.MetadataDll, StringComparison.OrdinalIgnoreCase) == 0) + { + return false; + } + + if (knownChangedAssemblies != null && knownChangedAssemblies.Length > 0) + { + int length = assemblyPath.Length; + bool bInKnownChangedList = false; + + foreach (string changedAsm in knownChangedAssemblies) + { + if (String.Compare(assemblyPath, 0, changedAsm, 0, length, StringComparison.OrdinalIgnoreCase) == 0) + { + bInKnownChangedList = true; + break; + } + } + + bCouldbeChanged = bInKnownChangedList; + } + else + { + if (knownUnchangedReferencePaths != null && knownUnchangedReferencePaths.Length > 0) + { + foreach (string unchangePath in knownUnchangedReferencePaths) + { + if (assemblyPath.StartsWith(unchangePath, StringComparison.OrdinalIgnoreCase) == true) + { + bCouldbeChanged = false; + break; + } + } + } + if (bCouldbeChanged) + { + IEnumerable gacRoots = GetGacPaths(); + if (gacRoots != null) + { + foreach (string gacRoot in gacRoots) + { + if (!String.IsNullOrEmpty(gacRoot) && assemblyPath.StartsWith(gacRoot, StringComparison.OrdinalIgnoreCase) == true) + { + bCouldbeChanged = false; + } + } + } + } + } + + return bCouldbeChanged; + + } + + + internal static string GetWholeExceptionMessage(Exception exception) + { + Exception e = exception; + string message = e.Message; + + while (e.InnerException != null) + { + Exception eInner = e.InnerException; + if (e.Message.IndexOf(eInner.Message, StringComparison.Ordinal) == -1) + { + message += ", "; + message += eInner.Message; + } + e = eInner; + } + + if (message != null && message.EndsWith(".", StringComparison.Ordinal) == false) + { + message += "."; + } + + return message; + + } + + // + // Helper to create CompilerWrapper. + // + internal static CompilerWrapper CreateCompilerWrapper(bool fInSeparateDomain, ref AppDomain appDomain) + { + return new CompilerWrapper(); + } + + #endregion Internal Methods + + } + + #endregion TaskHelper class +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/shared.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/shared.cs new file mode 100644 index 00000000000..125b8153e7b --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/shared.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//----------------------------------------------------------------------------- +// +// Description: +// Keep some constant string or settings which are shared +// by all the tasks. +// +//------------------------------------------------------------------------------ + +using System; +using System.IO; +using System.Collections; + +namespace MS.Internal.Tasks +{ + #region SharedStrings class + + // + // This class keeps a list of predefined strings. + // Some of them must be synced with target file settings. + // + internal static class SharedStrings + { + + // + // Target type settings. + // + internal const string Exe = "exe"; + internal const string WinExe = "winexe"; + internal const string Library = "library"; + internal const string Module = "module"; + + // + // VB Language name for special handling. + // + internal const string VB = "vb"; + + // + // Some special attribute names for WCP specific Item types. + // + internal const string Localizable="Localizable"; + internal const string Link="Link"; + internal const string LogicalName="LogicalName"; + + // + // externs for generated files + // + internal const string XamlExtension=".xaml"; + internal const string BamlExtension=".baml"; + internal const string GeneratedExtension=".g"; + internal const string IntellisenseGeneratedExtension=".g.i"; + internal const string MainExtension = ".main"; + internal const string LocExtension = ".loc"; + internal const string MetadataDll = ".metadata_dll"; + internal const string ContentFile = "_Content"; + + internal const string CsExtension = ".cs"; + internal const string CsBuildCodeExtension = GeneratedExtension + CsExtension; + internal const string CsIntelCodeExtension = IntellisenseGeneratedExtension + CsExtension; + + // Valid LocalizationDirectivesToLocFile + internal const string Loc_None = "none"; + internal const string Loc_CommentsOnly = "commentsonly"; + internal const string Loc_All = "all"; + + // Incremental build related settings + internal const string StateFile = "_MarkupCompile.cache"; + internal const string LocalTypeCacheFile = "_MarkupCompile.lref"; + + internal const string IntellisenseStateFile = "_MarkupCompile.i.cache"; + internal const string IntellisenseLocalTypeCacheFile = "_MarkupCompile.i.lref"; + // + // File name for a generated class which supports the access of internal + // types in local or friend assemblies. + // + internal const string GeneratedInternalTypeHelperFileName = "GeneratedInternalTypeHelper"; + + } + + #endregion SharedStrings class +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.targets b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.targets new file mode 100644 index 00000000000..5496449671b --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.targets @@ -0,0 +1,953 @@ + + + + + <_PresentationBuildTasksTfm Condition="'$(MSBuildRuntimeType)' == 'Core'">netcoreapp2.1 + <_PresentationBuildTasksTfm Condition="'$(MSBuildRuntimeType)' != 'Core'">net472 + <_PresentationBuildTasksAssembly Condition="'$(_PresentationBuildTasksAssembly)'==''">$(MSBuildThisFileDirectory)..\tools\$(_PresentationBuildTasksTfm)\PresentationBuildTasks.dll + + true + + true + + None + + + + + + + + + + + + + + + + + true + + + false + 1.0.0.0 + Installed + true + .g$(DefaultLanguageSourceExtension) + + 5.1.2600.0 + + + <_RequireMCPass2ForSatelliteAssemblyOnly>false + <_RequireMCPass2ForMainAssembly>false + + + + + true + true + true + true + + + + + + + + + + AssignWinFXEmbeddedResource; + $(PrepareResourceNamesDependsOn) + + + + + + + + + + MarkupCompilePass1; + AfterMarkupCompilePass1; + MarkupCompilePass2ForMainAssembly; + FileClassification; + MainResourcesGeneration; + $(PrepareResourcesDependsOn) + + + + + + + + + + DesignTimeMarkupCompilation; + $(CoreCompileDependsOn) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SatelliteOnlyMarkupCompilePass2; + SatelliteResourceGeneration; + GenerateResourceWithCultureItem; + + + + + + + + + + + + + + + $(CompileDependsOn); + _AfterCompileWinFXInternal + + + + + + <_AfterCompileWinFXInternalDependsOn> + PrepareResourcesForSatelliteAssemblies; + MergeLocalizationDirectives; + AfterCompileWinFX + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_IntellisenseOnlyCompile>false + <_IntellisenseOnlyCompile Condition="'$(BuildingProject)' != 'true'">true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GenerateTemporaryTargetAssembly; + MarkupCompilePass2; + AfterMarkupCompilePass2; + CleanupTemporaryTargetAssembly + + + <_CompileTargetNameForLocalType Condition="'$(_CompileTargetNameForLocalType)' == ''">_CompileTemporaryAssembly + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HostInBrowserValidation; + GenerateApplicationManifest; + ResignApplicationManifest; + GenerateDeploymentManifest; + SignDeploymentManifest + + + + true + $(GenerateManifests) + + + + false + + + + Internet + + + + + $(TargetUrl)/$(TargetDeployManifestFileName) + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(TargetDeployManifestFileName) + -debug "$(StartURL)" + $(StartArguments) -DebugSecurityZoneURL "$(DebugSecurityZoneURL)" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ResourceNameInMainAssembly Condition="'$(UICulture)' == ''">$(AssemblyName).g.resources + + <_ResourceNameInMainAssembly Condition="'$(UICulture)' != ''">$(AssemblyName).unlocalizable.g.resources + + + + + + + + + + + + + + + + + + + + + false + Resx + false + $(IntermediateOutputPath)$(_ResourceNameInMainAssembly) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(UICulture) + false + Resx + true + @(_SatelliteResourceFile) + + + + + + + + + + + + BuildOnlySettings; + PrepareForBuild; + ResolveReferences; + PrepareResources; + ResolveKeySource; + PrepareResourcesForSatelliteAssemblies; + GenerateSerializationAssemblies; + CreateSatelliteAssemblies; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_Temporary Remove="@(_Temporary)" /> + + + + + + + + + + <_Temporary Remove="@(_Temporary)" /> + + + + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/FileClassifier.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/FileClassifier.cs new file mode 100644 index 00000000000..6e494915d3f --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/FileClassifier.cs @@ -0,0 +1,381 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: An MSBuild task that classify the input files to different +// categories based on the input item's attributes. +// +//--------------------------------------------------------------------------- + +using System; +using System.IO; +using System.Collections.Generic; + +using System.Globalization; +using System.Diagnostics; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; + + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +using MS.Utility; +using MS.Internal.Tasks; + +// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler. +// We first need to disable warnings about unknown message numbers and unknown pragmas. +#pragma warning disable 1634, 1691 + +namespace Microsoft.Build.Tasks.Windows +{ + /// + /// The File Classification task puts all the input baml files, image files into different + /// output resource groups, such as Resources for Main assembly and Resources for satellite + /// assembly. + /// + public sealed class FileClassifier : Task + { + //------------------------------------------------------ + // + // Constructors + // + //------------------------------------------------------ + + #region Constructors + + /// + /// Constructor + /// + public FileClassifier() + : base(SR.SharedResourceManager) + { + // set default values for some non-required input items + + _culture = null; + } + + #endregion Constructors + + //------------------------------------------------------ + // + // Public Methods + // + //------------------------------------------------------ + + #region Public Methods + + /// + /// ITask Execute method + /// + /// + public override bool Execute() + { + bool ret = false; + var mainEmbeddedList = new List(); + var satelliteEmbeddedList = new List(); + var clrEmbeddedResourceList = new List(); + var clrSatelliteEmbeddedResourceList = new List(); + + try + { + TaskHelper.DisplayLogo(Log, SR.Get(SRID.FileClassifierTask)); + + ret = VerifyTaskInputs(); + + if (ret != false) + { + // Do the real work to classify input files. + Classify(SourceFiles, mainEmbeddedList, satelliteEmbeddedList); + + if (CLRResourceFiles != null) + { + // Generate the output CLR embedded resource list. + Classify(CLRResourceFiles, clrEmbeddedResourceList, clrSatelliteEmbeddedResourceList); + } + + // move the arraylist to the TaskItem array. + MainEmbeddedFiles = mainEmbeddedList.ToArray(); + SatelliteEmbeddedFiles = satelliteEmbeddedList.ToArray(); + CLREmbeddedResource = clrEmbeddedResourceList.ToArray(); + CLRSatelliteEmbeddedResource = clrSatelliteEmbeddedResourceList.ToArray(); + } + } + catch (Exception e) + { + // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions. + if (e is NullReferenceException || e is SEHException) + { + throw; + } + else + { + string message; + string errorId; + + errorId = Log.ExtractMessageCode(e.Message, out message); + + if (String.IsNullOrEmpty(errorId)) + { + errorId = UnknownErrorID; + message = SR.Get(SRID.UnknownBuildError, message); + } + + Log.LogError(null, errorId, null, null, 0, 0, 0, 0, message, null); + } + + return false; + } +#pragma warning disable 6500 + catch // Non-CLS compliant errors + { + Log.LogErrorWithCodeFromResources(SRID.NonClsError); + return false; + } +#pragma warning restore 6500 + + + return ret; + } + + #endregion Public Methods + + //------------------------------------------------------ + // + // Public Properties + // + //------------------------------------------------------ + + #region Public Properties + + /// + /// SourceFiles: List of Items thatare to be classified + /// + [Required] + public ITaskItem [] SourceFiles { get; set; } + + /// + /// Can have values (exe, or dll) + /// + [Required] + public string OutputType { get; set; } + + /// + /// Culture of the build. Can be null if the build is non-localizable + /// + public string Culture + { + get { return _culture != null ? _culture.ToLower(CultureInfo.InvariantCulture) : null; } + set { _culture = value; } + } + + + /// + /// The CLR resource file list. + /// In Project file, those files will be define by type CLRResource. + /// such as: + /// + /// + public ITaskItem[] CLRResourceFiles { get; set; } + + /// + /// Output Item list for the CLR resources that will be saved in + /// the main assembly. + /// + /// + [Output] + public ITaskItem[] CLREmbeddedResource { get; set; } + + /// + /// Output Item list for the CLR resources that will be saved in + /// the satellite assembly. + /// + /// + [Output] + public ITaskItem[] CLRSatelliteEmbeddedResource { get; set; } + + /// + /// MainEmbeddedFiles + /// + /// Non-localizable resources which will be embedded into the Main assembly. + /// + [Output] + public ITaskItem [] MainEmbeddedFiles { get; set; } + + /// + /// SatelliteEmbeddedFiles + /// + /// Localizable files which are embedded to the Satellite assembly for the + /// culture which is set in Culture property.. + /// + [Output] + public ITaskItem [] SatelliteEmbeddedFiles { get; set; } + + #endregion Public Properties + + //------------------------------------------------------ + // + // Public Events + // + //------------------------------------------------------ + + //------------------------------------------------------ + // + // Protected Methods + // + //------------------------------------------------------ + + + //------------------------------------------------------ + // + // Internal Methods + // + //------------------------------------------------------ + + //------------------------------------------------------ + // + // Internal Properties + // + //------------------------------------------------------ + + //------------------------------------------------------ + // + // Internal Events + // + //------------------------------------------------------ + + + //------------------------------------------------------ + // + // Private Methods + // + //------------------------------------------------------ + + #region Private Methods + + // + // Verify all the propety values set from project file. + // If any input value is set wrongly, report appropriate build error + // and return false. + // + private bool VerifyTaskInputs() + { + bool bValidInput = true; + + // + // Verify different property values + // + // OutputType is marked as Required, it should never be null or emtpy. + // otherwise, the task should have been failed before the code goes here. + + string targetType = OutputType.ToLowerInvariant( ); + switch (targetType) + { + case SharedStrings.Library : + case SharedStrings.Module : + case SharedStrings.WinExe : + case SharedStrings.Exe : + break; + default : + Log.LogErrorWithCodeFromResources(SRID.TargetIsNotSupported, targetType); + bValidInput = false; + break; + } + + // SourceFiles property is marked as Required. + // MSBUILD Engine should have checked the setting for this property + // so don't need to recheck here. + + if (TaskHelper.IsValidCultureName(Culture) == false) + { + Log.LogErrorWithCodeFromResources(SRID.InvalidCulture, Culture); + bValidInput = false; + } + + return bValidInput; + } + + private void Classify(IEnumerable inputItems, List mainList, List satelliteList) + { + foreach (ITaskItem inputItem in inputItems) + { + ITaskItem outputItem = new TaskItem + { + ItemSpec = inputItem.ItemSpec, + }; + + // Selectively copy metadata over. + outputItem.SetMetadata(SharedStrings.Link, inputItem.GetMetadata(SharedStrings.Link)); + outputItem.SetMetadata(SharedStrings.LogicalName, inputItem.GetMetadata(SharedStrings.LogicalName)); + + if (IsItemLocalizable(inputItem)) + { + satelliteList.Add(outputItem); + } + else + { + mainList.Add(outputItem); + } + } + } + + // + // Check if the item is localizable or not. + // + // + // + private bool IsItemLocalizable(ITaskItem fileItem) + { + bool isLocalizable = false; + + // if the default culture is not set, by default all + // the items are not localizable. + + if (Culture != null && Culture.Equals("") == false) + { + string localizableString; + + // Default culture is set, by default the item is localizable + // unless it is set as false in the Localizable attribute. + + isLocalizable = true; + + localizableString = fileItem.GetMetadata(SharedStrings.Localizable); + + if (localizableString != null && String.Compare(localizableString, "false", StringComparison.OrdinalIgnoreCase) ==0 ) + { + isLocalizable = false; + } + } + + return isLocalizable; + } + + #endregion Private Methods + + //------------------------------------------------------ + // + // Private Properties + // + //------------------------------------------------------ + + + //------------------------------------------------------ + // + // Private Fields + // + //------------------------------------------------------ + + #region Private Fields + + private string _culture; + + private const string UnknownErrorID = "FC1000"; + + #endregion Private Fields + + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/GenerateTemporaryTargetAssembly.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/GenerateTemporaryTargetAssembly.cs new file mode 100644 index 00000000000..75865998c2a --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/GenerateTemporaryTargetAssembly.cs @@ -0,0 +1,550 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: This is a MSBuild task which generates a temporary target assembly +// if current project contains a xaml file with local-type-reference. +// +// It generates a temporary project file and then call build-engine +// to compile it. +// +// The new project file will replace all the Reference Items with the +// resolved ReferenctPath, add all the generated code file into Compile +// Item list. +// +//--------------------------------------------------------------------------- + +using System; +using System.IO; +using System.Collections; + +using System.Globalization; +using System.Diagnostics; +using System.Reflection; +using System.Resources; +using System.Xml; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +using MS.Utility; +using MS.Internal.Tasks; + +// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler. +// We first need to disable warnings about unknown message numbers and unknown pragmas. +#pragma warning disable 1634, 1691 + +namespace Microsoft.Build.Tasks.Windows +{ + #region GenerateTemporaryTargetAssembly Task class + + /// + /// This task is used to generate a temporary target assembly. It generates + /// a temporary project file and then compile it. + /// + /// The generated project file is based on current project file, with below + /// modification: + /// + /// A: Add the generated code files (.g.cs) to Compile Item list. + /// B: Replace Reference Item list with ReferenctPath item list. + /// So that it doesn't need to rerun time-consuming task + /// ResolveAssemblyReference (RAR) again. + /// + /// + public sealed class GenerateTemporaryTargetAssembly : Task + { + //------------------------------------------------------ + // + // Constructors + // + //------------------------------------------------------ + + #region Constructors + + /// + /// Constructor + /// + public GenerateTemporaryTargetAssembly() + : base(SR.SharedResourceManager) + { + } + + #endregion Constructors + + //------------------------------------------------------ + // + // Public Methods + // + //------------------------------------------------------ + + #region Public Methods + + /// + /// ITask Execute method + /// + /// + /// Catching all exceptions in this method is appropriate - it will allow the build process to resume if possible after logging errors + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + public override bool Execute() + { + bool retValue = true; + + // Verification + try + { + XmlDocument xmlProjectDoc = null; + + xmlProjectDoc = new XmlDocument( ); + xmlProjectDoc.Load(CurrentProject); + + // + // remove all the WinFX specific item lists + // ApplicationDefinition, Page, MarkupResource and Resource + // + + RemoveItemsByName(xmlProjectDoc, APPDEFNAME); + RemoveItemsByName(xmlProjectDoc, PAGENAME); + RemoveItemsByName(xmlProjectDoc, MARKUPRESOURCENAME); + RemoveItemsByName(xmlProjectDoc, RESOURCENAME); + + // Replace the Reference Item list with ReferencePath + + RemoveItemsByName(xmlProjectDoc, REFERENCETYPENAME); + AddNewItems(xmlProjectDoc, ReferencePathTypeName, ReferencePath); + + // Add GeneratedCodeFiles to Compile item list. + AddNewItems(xmlProjectDoc, CompileTypeName, GeneratedCodeFiles); + + string currentProjectName = Path.GetFileNameWithoutExtension(CurrentProject); + string currentProjectExtension = Path.GetExtension(CurrentProject); + + // Create a random file name + // This can fix the problem of project cache in VS.NET environment. + // + // GetRandomFileName( ) could return any possible file name and extension + // Since this temporary file will be used to represent an MSBUILD project file, + // we will use the same extension as that of the current project file + // + string randomFileName = Path.GetFileNameWithoutExtension(Path.GetRandomFileName()); + + // Don't call Path.ChangeExtension to append currentProjectExtension. It will do + // odd things with project names that already contains a period (like System.Windows. + // Contols.Ribbon.csproj). Instead, just append the extension - after all, we already know + // for a fact that this name (i.e., tempProj) lacks a file extension. + string tempProj = string.Join("_", currentProjectName, randomFileName, WPFTMP); + tempProj = tempProj + currentProjectExtension; + + + // Save the xmlDocument content into the temporary project file. + xmlProjectDoc.Save(tempProj); + + // + // Invoke MSBUILD engine to build this temporary project file. + // + + Hashtable globalProperties = new Hashtable(3); + + // Add AssemblyName, IntermediateOutputPath and _TargetAssemblyProjectName to the global property list + // Note that _TargetAssemblyProjectName is not defined as a property with Output attribute - that doesn't do us much + // good here. We need _TargetAssemblyProjectName to be a well-known property in the new (temporary) project + // file, and having it be available in the current MSBUILD process is not useful. + globalProperties[intermediateOutputPathPropertyName] = IntermediateOutputPath; + + globalProperties[assemblyNamePropertyName] = AssemblyName; + globalProperties[targetAssemblyProjectNamePropertyName] = currentProjectName; + + retValue = BuildEngine.BuildProjectFile(tempProj, new string[] { CompileTargetName }, globalProperties, null); + + // Delete the temporary project file unless diagnostic mode has been requested + if (!GenerateTemporaryTargetAssemblyDebuggingInformation) + { + try + { + File.Delete(tempProj); + } + catch (IOException e) + { + // Failure to delete the file is a non fatal error + Log.LogWarningFromException(e); + } + } + } + catch (Exception e) + { + Log.LogErrorFromException(e); + retValue = false; + } + + return retValue; + } + + #endregion Public Methods + + //------------------------------------------------------ + // + // Public Properties + // + //------------------------------------------------------ + + #region Public Properties + + /// + /// CurrentProject + /// The full path of current project file. + /// + [Required] + public string CurrentProject + { + get { return _currentProject; } + set { _currentProject = value; } + } + + /// + /// MSBuild Binary Path. + /// This is required for Project to work correctly. + /// + [Required] + public string MSBuildBinPath + { + get { return _msbuildBinPath; } + set { _msbuildBinPath = value; } + } + + /// + /// GeneratedCodeFiles + /// A list of generated code files, it could be empty. + /// The list will be added to the Compile item list in new generated project file. + /// + public ITaskItem[] GeneratedCodeFiles + { + get { return _generatedCodeFiles; } + set { _generatedCodeFiles = value; } + } + + /// + /// CompileTypeName + /// The appropriate item name which can be accepted by managed compiler task. + /// It is "Compile" for now. + /// + /// Adding this property is to make the type name configurable, if it is changed, + /// No code is required to change in this task, but set a new type name in project file. + /// + [Required] + public string CompileTypeName + { + get { return _compileTypeName; } + set { _compileTypeName = value; } + } + + + /// + /// ReferencePath + /// A list of resolved reference assemblies. + /// The list will replace the original Reference item list in generated project file. + /// + public ITaskItem[] ReferencePath + { + get { return _referencePath; } + set { _referencePath = value; } + } + + /// + /// ReferencePathTypeName + /// The appropriate item name which is used to keep the Reference list in managed compiler task. + /// It is "ReferencePath" for now. + /// + /// Adding this property is to make the type name configurable, if it is changed, + /// No code is required to change in this task, but set a new type name in project file. + /// + [Required] + public string ReferencePathTypeName + { + get { return _referencePathTypeName; } + set { _referencePathTypeName = value; } + } + + + /// + /// IntermediateOutputPath + /// + /// The value which is set to IntermediateOutputPath property in current project file. + /// + /// Passing this value explicitly is to make sure to generate temporary target assembly + /// in expected directory. + /// + [Required] + public string IntermediateOutputPath + { + get { return _intermediateOutputPath; } + set { _intermediateOutputPath = value; } + } + + /// + /// AssemblyName + /// + /// The value which is set to AssemblyName property in current project file. + /// Passing this value explicitly is to make sure to generate the expected + /// temporary target assembly. + /// + /// + [Required] + public string AssemblyName + { + get { return _assemblyName; } + set { _assemblyName = value; } + } + + /// + /// CompileTargetName + /// + /// The msbuild target name which is used to generate assembly from source code files. + /// Usually it is "CoreCompile" + /// + /// + [Required] + public string CompileTargetName + { + get { return _compileTargetName; } + set { _compileTargetName = value; } + } + + /// + /// Optional task parameter + /// + /// When true, debugging information is enabled for the + /// Task. At this time, the only debugging information that is generated consists of the temporary project that is + /// created to generate the temporary target assembly. This temporary project is normally deleted at the end of this + /// MSBUILD task; when is enable, this temporary project + /// will be retained for inspection by the developer. + /// + /// This is a diagnostic parameter, and it defaults to false. + /// + public bool GenerateTemporaryTargetAssemblyDebuggingInformation + { + get { return _generateTemporaryTargetAssemblyDebuggingInformation; } + set { _generateTemporaryTargetAssemblyDebuggingInformation = value; } + } + + #endregion Public Properties + + //------------------------------------------------------ + // + // Private Methods + // + //------------------------------------------------------ + + #region Private Methods + + // + // Remove specific items from project file. Every item should be under an ItemGroup. + // + private void RemoveItemsByName(XmlDocument xmlProjectDoc, string sItemName) + { + if (xmlProjectDoc == null || String.IsNullOrEmpty(sItemName)) + { + // When the parameters are not valid, simply return it, instead of throwing exceptions. + return; + } + + // + // The project file format is always like below: + // + // + // + // ...... + // + // + // ... + // + // + // .... + // + // + // .... + // + // ... + // + // + // ... + // + // + // + // + // The order of children nodes under Project Root element is random + // + + XmlNode root = xmlProjectDoc.DocumentElement; + + if (root.HasChildNodes == false) + { + // If there is no child element in this project file, just return immediatelly. + return; + } + + for (int i = 0; i < root.ChildNodes.Count; i++) + { + XmlElement nodeGroup = root.ChildNodes[i] as XmlElement; + + if (nodeGroup != null && String.Compare(nodeGroup.Name, ITEMGROUP_NAME, StringComparison.OrdinalIgnoreCase) == 0) + { + // + // This is ItemGroup element. + // + if (nodeGroup.HasChildNodes) + { + ArrayList itemToRemove = new ArrayList(); + + for (int j = 0; j < nodeGroup.ChildNodes.Count; j++) + { + XmlElement nodeItem = nodeGroup.ChildNodes[j] as XmlElement; + + if (nodeItem != null && String.Compare(nodeItem.Name, sItemName, StringComparison.OrdinalIgnoreCase) == 0) + { + // This is the item that need to remove. + // Add it into the temporary array list. + // Don't delete it here, since it would affect the ChildNodes of parent element. + // + itemToRemove.Add(nodeItem); + } + } + + // + // Now it is the right time to delete the elements. + // + if (itemToRemove.Count > 0) + { + foreach (object node in itemToRemove) + { + XmlElement item = node as XmlElement; + + // + // Remove this item from its parent node. + // the parent node should be nodeGroup. + // + if (item != null) + { + nodeGroup.RemoveChild(item); + } + } + } + } + + // + // Removed all the items with given name from this item group. + // + // Continue the loop for the next ItemGroup. + } + + } // end of "for i" statement. + + } + + // + // Add a list of files into an Item in the project file, the ItemName is specified by sItemName. + // + private void AddNewItems(XmlDocument xmlProjectDoc, string sItemName, ITaskItem[] pItemList) + { + if (xmlProjectDoc == null || String.IsNullOrEmpty(sItemName) || pItemList == null) + { + // When the parameters are not valid, simply return it, instead of throwing exceptions. + return; + } + + XmlNode root = xmlProjectDoc.DocumentElement; + + // Create a new ItemGroup element + XmlNode nodeItemGroup = xmlProjectDoc.CreateElement(ITEMGROUP_NAME, root.NamespaceURI); + + // Append this new ItemGroup item into the list of children of the document root. + root.AppendChild(nodeItemGroup); + + XmlElement embedItem = null; + + for (int i = 0; i < pItemList.Length; i++) + { + // Create an element for the given sItemName + XmlElement nodeItem = xmlProjectDoc.CreateElement(sItemName, root.NamespaceURI); + + // Create an Attribute "Include" + XmlAttribute attrInclude = xmlProjectDoc.CreateAttribute(INCLUDE_ATTR_NAME); + + ITaskItem pItem = pItemList[i]; + + // Set the value for Include attribute. + attrInclude.Value = pItem.ItemSpec; + + // Add the attribute to current item node. + nodeItem.SetAttributeNode(attrInclude); + + if (TRUE == pItem.GetMetadata(EMBEDINTEROPTYPES)) + { + embedItem = xmlProjectDoc.CreateElement(EMBEDINTEROPTYPES, root.NamespaceURI); + embedItem.InnerText = TRUE; + nodeItem.AppendChild(embedItem); + } + + string aliases = pItem.GetMetadata(ALIASES); + if (!String.IsNullOrEmpty(aliases)) + { + embedItem = xmlProjectDoc.CreateElement(ALIASES, root.NamespaceURI); + embedItem.InnerText = aliases; + nodeItem.AppendChild(embedItem); + } + + // Add current item node into the children list of ItemGroup + nodeItemGroup.AppendChild(nodeItem); + } + } + + #endregion Private Methods + + + //------------------------------------------------------ + // + // Private Fields + // + //------------------------------------------------------ + + #region Private Fields + + private string _currentProject = String.Empty; + + private ITaskItem[] _generatedCodeFiles; + private ITaskItem[] _referencePath; + + private string _referencePathTypeName; + private string _compileTypeName; + + private string _msbuildBinPath; + + private string _intermediateOutputPath; + private string _assemblyName; + private string _compileTargetName; + private bool _generateTemporaryTargetAssemblyDebuggingInformation = false; + + private const string intermediateOutputPathPropertyName = "IntermediateOutputPath"; + private const string assemblyNamePropertyName = "AssemblyName"; + private const string targetAssemblyProjectNamePropertyName = "_TargetAssemblyProjectName"; + + private const string ALIASES = "Aliases"; + private const string REFERENCETYPENAME = "Reference"; + private const string EMBEDINTEROPTYPES = "EmbedInteropTypes"; + private const string APPDEFNAME = "ApplicationDefinition"; + private const string PAGENAME = "Page"; + private const string MARKUPRESOURCENAME = "MarkupResource"; + private const string RESOURCENAME = "Resource"; + + private const string ITEMGROUP_NAME = "ItemGroup"; + private const string INCLUDE_ATTR_NAME = "Include"; + + private const string TRUE = "True"; + private const string WPFTMP = "wpftmp"; + + #endregion Private Fields + + } + + #endregion GenerateProjectForLocalTypeReference Task class +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass1.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass1.cs new file mode 100644 index 00000000000..8d310630113 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass1.cs @@ -0,0 +1,1906 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: An MSBuild Task that can generate .xaml markup file to specific +// Mangaged language code such as .cs, .js, .vb,etc, and /or binary +// token file .baml +// +//--------------------------------------------------------------------------- + +using System; +using System.IO; +using System.Collections; +using System.Security; +using System.Security.Permissions; + +using System.Globalization; +using System.Diagnostics; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; + +using System.CodeDom; +using System.CodeDom.Compiler; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +using MS.Utility; +using MS.Internal; +using MS.Internal.Tasks; +using MS.Internal.Markup; + +// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler. +// We first need to disable warnings about unknown message numbers and unknown pragmas. +#pragma warning disable 1634, 1691 + +namespace Microsoft.Build.Tasks.Windows +{ + + #region MarkupCompilePass1 Task class + + /// + /// Class of MarkupCompilePass1 Task + /// + public sealed class MarkupCompilePass1 : Task + { + // Security Concerns: + // + // 1) OutputPath property exposes the current dir and is publicly available. + // 2) This class generates code files and copies them on the disk. + // + // The above two are already mitigated by the following facts: + // + // 1) PresentationBuildTasks is not APTCA and thus partial trust assemblies + // cannot call into it. + // 2) There is a possibility that some APTCA assembly (eg. PF.dll) can create + // this object and pass it on to partial trust code. This is mitigated by + // FxCop rule against it. + // + + //------------------------------------------------------ + // + // Constructors + // + //------------------------------------------------------ + + #region Constructors + + /// + /// Constructor + /// + public MarkupCompilePass1( ) : base(SR.SharedResourceManager) + { + // set the source directory + _sourceDir = Directory.GetCurrentDirectory() + "\\"; + + _outputType = SharedStrings.WinExe; + + // By default, no localization information is stripped out. + _localizationDirectives = MS.Internal.LocalizationDirectivesToLocFile.None; + + _nErrors = 0; + + } + + #endregion Constructors + + //------------------------------------------------------ + // + // Public Methods + // + //------------------------------------------------------ + + #region Public Methods + + /// + /// Execute method in Task + /// + /// + public override bool Execute() + { + TaskHelper.DisplayLogo(Log, SR.Get(SRID.MarkupCompilePass1Task)); + + bool bSuccess = true; + + try + { + + // + // Create the TaskFileService instance here + // + + _taskFileService = new TaskFileService(this) as ITaskFileService; + + _compilerState = new CompilerState( + OutputPath + AssemblyName + (TaskFileService.IsRealBuild? SharedStrings.StateFile : SharedStrings.IntellisenseStateFile), + TaskFileService); + + _compilerLocalRefCache = new CompilerLocalReference( + OutputPath + AssemblyName + (TaskFileService.IsRealBuild? SharedStrings.LocalTypeCacheFile : SharedStrings.IntellisenseLocalTypeCacheFile), + TaskFileService); + + if ((PageMarkup == null || PageMarkup.Length == 0) && + (ApplicationMarkup == null || ApplicationMarkup.Length == 0)) + { + // Don't need to do further work. + // stop here. + CleanupCacheFiles(); + return true; + } + + VerifyInputs(); + + Log.LogMessageFromResources(MessageImportance.Low, SRID.CurrentDirectory, SourceDir); + + // If wrong files are set to some properties, the task + // should stop here immediatelly. + + if (_nErrors > 0) + { + Log.LogErrorWithCodeFromResources(SRID.WrongPropertySetting); + } + else + { + + // create output directory + if (!Directory.Exists(OutputPath)) + { + Directory.CreateDirectory(OutputPath); + } + + // Analyze project inputs to detect which xaml files require to recompile. + AnalyzeInputsAndSetting(); + + Log.LogMessageFromResources(MessageImportance.Low, SRID.AnalysisResult, CompilerAnalyzer.AnalyzeResult); + + if (!SkipMarkupCompilation) + { + + if (CompilerAnalyzer.RecompileMarkupPages != null) + { + for (int i = 0; i < CompilerAnalyzer.RecompileMarkupPages.Length; i++) + { + + Log.LogMessageFromResources(MessageImportance.Low, SRID.RecompiledXaml, CompilerAnalyzer.RecompileMarkupPages[i]); + } + } + + // If recompile is required, CompilerAnalyzer contains all the files which need to recompile. + + // Cleanup baml files and code files generated in previous build. + if (TaskFileService.IsRealBuild) + { + CleanupGeneratedFiles(); + } + + // Call the Markup Compiler to do the real compiling work + DoMarkupCompilation(); + } + + + // Generate the required output items. + GenerateOutputItems(); + + Log.LogMessageFromResources(MessageImportance.Low, SRID.CompilationDone); + } + + } +#pragma warning disable 6500 + catch (Exception e) + { + string message; + string errorId; + + errorId = Log.ExtractMessageCode(e.Message, out message); + + if (String.IsNullOrEmpty(errorId)) + { + errorId = UnknownErrorID; + message = SR.Get(SRID.UnknownBuildError, message); + } + + Log.LogError(null, errorId, null, null, 0, 0, 0, 0, message, null); + + _nErrors++; + } + catch // Non-CLS compliant errors + { + Log.LogErrorWithCodeFromResources(SRID.NonClsError); + _nErrors++; + } +#pragma warning restore 6500 + + if (_nErrors > 0) + { + // When error counter is changed, the appropriate error message should have + // been reported, simply return false here. + bSuccess = false; + CleanupCacheFiles(); + } + else + { + Log.LogMessageFromResources(MessageImportance.Low, SRID.CompileSucceed_Pass1); + } + + return bSuccess; + } + + + #endregion Public Methods + + //------------------------------------------------------ + // + // Public Properties + // + //------------------------------------------------------ + + #region Public Properties + + /// + /// The Language the managed compiler supports. + /// the valid languages are C#, VB, Jscript, J#, C++ + /// + [Required] + public string Language + { + get { return _language; } + set { _language = value;} + } + + /// + /// The valid source file extension for the passed language. + /// Normally a language supports more valid source file extensions. + /// User could choose one of them in project file. + /// If this property is not set, we will take use of the default one for the language. + /// + public string LanguageSourceExtension + { + get { return _languageSourceExtension; } + set { _languageSourceExtension = value; } + } + + /// + /// OutputPath : Generated code files, Baml fles will be put in this directory. + /// + [Required] + public string OutputPath + { + get { return _outputDir; } + set + { + string filePath = value; + + // Get the relative path based on sourceDir + _outputDir= TaskHelper.CreateFullFilePath(filePath, SourceDir); + + // Make sure OutputDir always ends with '\\'. + if (!_outputDir.EndsWith("\\", StringComparison.Ordinal)) + { + _outputDir += "\\"; + } + } + } + + /// + /// OutputType + /// Valid types: winexe, exe, library, netmodule. + /// + [Required] + public string OutputType + { + get { return _outputType; } + set { _outputType = TaskHelper.GetLowerString(value); } + } + + /// + /// AssemblyName + /// The short name of assembly which will be generated for this project. + /// + [Required] + public string AssemblyName + { + get { return _assemblyName; } + set { _assemblyName = value; } + } + + /// + /// The version of the assembly + /// + public string AssemblyVersion + { + get { return _assemblyVersion; } + set { _assemblyVersion = value; } + } + + /// + /// The public key token of the assembly + /// + public string AssemblyPublicKeyToken + { + get { return _assemblyPublicKeyToken; } + set { _assemblyPublicKeyToken = value; } + } + + /// + /// Root namespace for the classes inside the project. + /// It is also used as default CLR namespace of a generated code file + /// when the corresponding markup page is not set x:Class attribute. + /// + public string RootNamespace + { + get { return _rootNamespace; } + set { _rootNamespace = value; } + } + + /// + /// The UI Culture controls which culture satellite assembly will hold + /// the generated baml files. + /// If UICulture is not set, the generated baml files will be embedded + /// into main assembly. + /// + public string UICulture + { + get { return _uiCulture; } + set { _uiCulture = value; } + } + + /// + /// Source code file list for the current project. + /// It doesnt include any generated code files. + /// + public ITaskItem[] SourceCodeFiles + { + get { return _sourceCodeFiles; } + set { _sourceCodeFiles = value; } + } + + /// + /// DefineConstants + /// + /// Keep the current value of DefineConstants. + /// + /// DefineConstants can affect the final assembly generation, if DefineConstants + /// value is changed, the public API might be changed in the target assembly, which + /// then has potential impacts on compilation for xaml files which contains local types. + /// + /// + public string DefineConstants + { + get { return _defineConstants; } + set { _defineConstants = value; } + } + + /// + /// ApplicationMarkup + /// + public ITaskItem [] ApplicationMarkup + { + get { return _applicationMarkup; } + set { _applicationMarkup = value;} + } + + /// + /// Description + /// + public ITaskItem [] PageMarkup + { + get { return _pagemarkupFiles; } + set { _pagemarkupFiles = value; } + } + + /// + /// Splash screen image to be displayed before application init + /// + public ITaskItem[] SplashScreen + { + get { return _splashScreen; } + set { _splashScreen = value; } + } + + internal string SplashImageName + { + get + { + if (SplashScreen != null && SplashScreen.Length > 0) + { + return SplashScreen[0].ItemSpec.ToLowerInvariant(); + } + return null; + } + } + + /// + /// Loose file content list + /// + public ITaskItem[] ContentFiles + { + get { return _contentFiles; } + set { _contentFiles = value; } + } + + /// + /// Assembly References. + /// + /// + public ITaskItem[] References + { + get { return _references; } + set { _references = value; } + } + + /// + /// + public bool XamlDebuggingInformation + { + get { return _xamlDebuggingInformation; } + set { _xamlDebuggingInformation = value; } + } + + /// + /// Keep a list of Build control files. + /// If one of them is changed since last build, it would trigger recompilation of all the xaml files. + /// Such as WinFX target file change could require a rebuild etc. + /// + public ITaskItem [] ExtraBuildControlFiles + { + get { return _extraBuildControlFiles; } + set { _extraBuildControlFiles = value; } + } + + /// + ///If true code for supporting hosting in Browser is generated + /// + public string HostInBrowser + { + get { return _hostInBrowser; } + set { _hostInBrowser = TaskHelper.GetLowerString(value); } + } + + /// + /// Controls how to generate localization information for each xaml file. + /// Valid values: None, CommentsOnly, All. + /// + public string LocalizationDirectivesToLocFile + { + get + { + string localizationDirectives = SharedStrings.Loc_None; + + switch (_localizationDirectives) + { + case MS.Internal.LocalizationDirectivesToLocFile.None : + + localizationDirectives = SharedStrings.Loc_None; + break; + + case MS.Internal.LocalizationDirectivesToLocFile.CommentsOnly: + + localizationDirectives = SharedStrings.Loc_CommentsOnly; + break; + + case MS.Internal.LocalizationDirectivesToLocFile.All: + + localizationDirectives = SharedStrings.Loc_All; + + break; + + } + + return localizationDirectives; + + } + + set + { + string localizationDirectives = value; + + if (localizationDirectives != null) + { + localizationDirectives = localizationDirectives.ToLower(CultureInfo.InvariantCulture); + } + + switch (localizationDirectives) + { + case SharedStrings.Loc_None : + + _localizationDirectives = MS.Internal.LocalizationDirectivesToLocFile.None; + break; + + case SharedStrings.Loc_CommentsOnly : + + _localizationDirectives = MS.Internal.LocalizationDirectivesToLocFile.CommentsOnly; + break; + + case SharedStrings.Loc_All : + + _localizationDirectives = MS.Internal.LocalizationDirectivesToLocFile.All; + break; + + default: + _localizationDirectives = MS.Internal.LocalizationDirectivesToLocFile.Unknown; + break; + } + + } + } + + /// + /// Known reference paths hold referenced assemblies which are never changed during the build procedure. + /// such as references in GAC, in framework directory or framework SDK directory etc. + /// Users could add their own known reference paths in project files. + /// + public string[] KnownReferencePaths + { + get + { + return _knownReferencePaths; + } + + set + { + _knownReferencePaths = value; + } + } + + /// + /// A list of reference assemblies that are to change for sure during the build cycle. + /// + /// Such as in VS.NET, if one project wants to reference another project's output, the + /// second project's output could be put in AssembliesGeneratedDuringBuild list. + /// Note: Once this property is set, it must contain the complete list of generated + /// assemblies in this build solution. + /// + public string[] AssembliesGeneratedDuringBuild + { + get + { + return _assembliesGeneratedDuringBuild; + } + + set + { + _assembliesGeneratedDuringBuild = value; + } + + } + + /// + /// Control whether to run the compilation in second appdomain. + /// By default, it is set to true, but project can set this property + /// to false to make markup file compilation faster. + /// + public bool AlwaysCompileMarkupFilesInSeparateDomain + { + get { return _alwaysCompileMarkupFilesInSeparateDomain; } + set { _alwaysCompileMarkupFilesInSeparateDomain = value; } + } + + /// + /// Set to true when called from Visual Studio. + /// + public bool IsRunningInVisualStudio + { + get { return _isRunningInVisualStudio; } + set { _isRunningInVisualStudio = value; } + } + + /// + /// Generated source code files for the given programing language. + /// + [Output] + public ITaskItem [] GeneratedCodeFiles + { + get + { + if (_generatedCodeFiles == null) + _generatedCodeFiles = new TaskItem[0]; + return _generatedCodeFiles; + } + + set + { + _generatedCodeFiles = value; + } + } + + /// + /// Generated Baml files for the passed Markup files. + /// + [Output] + public ITaskItem [] GeneratedBamlFiles + { + get + { + if (_generatedBamlFiles == null) + _generatedBamlFiles = new TaskItem[0]; + return _generatedBamlFiles; + } + + set + { + _generatedBamlFiles = value; + } + } + + /// + /// The generated localization file for each localizable xaml file. + /// + [Output] + public ITaskItem[] GeneratedLocalizationFiles + { + get + { + if (_generatedLocalizationFiles == null) + _generatedLocalizationFiles = new TaskItem[0]; + + return _generatedLocalizationFiles; + } + + set + { + _generatedLocalizationFiles = value; + } + + } + + #region Local Reference Xaml markup files + + /// + /// Indicate whether the project contains xaml files which reference local types and + /// the corresponding baml file will be embedded into main assembly. + /// + [Output] + public bool RequirePass2ForMainAssembly + { + get { return _requirePass2ForMainAssembly; } + set { _requirePass2ForMainAssembly = value; } + } + + /// + /// Indicate whether the project contains xaml files which reference local types and + /// the corresponding baml file will be embedded into satellite assembly for current UICulture. + /// + [Output] + public bool RequirePass2ForSatelliteAssembly + { + get { return _requirePass2ForSatelliteAssembly; } + set { _requirePass2ForSatelliteAssembly = value; } + } + + #endregion Local Reference Xaml markup files + + /// + /// A complete list of files which are generated by MarkupCompiler. + /// + [Output] + public ITaskItem[] AllGeneratedFiles + { + get { return _allGeneratedFiles; } + set { _allGeneratedFiles = value; } + } + + #endregion Public Properties + + #region internal methods + + // + // Get the generated code file and baml file for a given xaml file + // If the generated file doesn't exist, the output paramter is set to empty string. + // + internal void GetGeneratedFiles(string xamlFile, out string codeFile, out string bamlFile) + { + string newSourceDir = SourceDir; + codeFile = String.Empty; + bamlFile = String.Empty; + + if (String.IsNullOrEmpty(xamlFile)) + { + // if xaml file is empty, return it now. + return; + } + + + string relativeFilePath = GetResolvedFilePath(xamlFile, ref newSourceDir); + + // Optimize the number of intermediate strings that get generated + // in the common C# case. (we can add Vb here as well, I suppose) + string buildExtension = (LanguageSourceExtension == SharedStrings.CsExtension) + ? SharedStrings.CsBuildCodeExtension + : SharedStrings.GeneratedExtension + LanguageSourceExtension; + + string intellisenseExtension = (LanguageSourceExtension == SharedStrings.CsExtension) + ? SharedStrings.CsIntelCodeExtension + : SharedStrings.IntellisenseGeneratedExtension + LanguageSourceExtension; + + string buildCodeFile = OutputPath + Path.ChangeExtension(relativeFilePath, buildExtension); + string intelCodeFile = OutputPath + Path.ChangeExtension(relativeFilePath, intellisenseExtension); + + // If the file doesn't exist, return empty string for the corresponding output parameter. + // return .g.i files for intellisense builds + // return .g & .baml files for MsBuild builds (and real VS builds). + if (TaskFileService.IsRealBuild) + { + codeFile = buildCodeFile; + bamlFile = OutputPath + Path.ChangeExtension(relativeFilePath, SharedStrings.BamlExtension); + + if (!TaskFileService.Exists(codeFile)) + { + codeFile = String.Empty; + } + // Baml file is only generated for real build. + if (!TaskFileService.Exists(bamlFile)) + { + bamlFile = String.Empty; + } + } + else + { + codeFile = intelCodeFile; + if (!TaskFileService.Exists(codeFile)) + { + codeFile = String.Empty; + } + } + } + + #endregion internal methods + + + #region internal Properties + + internal bool IsApplicationTarget + { + get { return _isApplicationTarget; } + } + + // + // ApplicationFile + // + internal string ApplicationFile + { + get { return _applicationFile; } + } + + // + // PageMarkupCache + // It is caculated from current PageMarkup list, will be saved in the + // cache file to support incremental compilation. + // + internal string PageMarkupCache + { + get { return _pageMarkupCache; } + } + + // + // ContentFilesCache + // It is caculated from current ContentFiles list, will be saved in the + // cache file to support incremental compilation. + // + internal string ContentFilesCache + { + get { return _contentFilesCache; } + } + + // + // SourceCodeFilesCache + // It is caculated from current SourceCodeFiles list, will be saved in the + // cache file to support incremental compilation. + // + internal string SourceCodeFilesCache + { + get { return _sourceCodeFilesCache; } + } + + // + // ReferencesCache + // It is caculated from current ReferencesCache list, will be saved in the + // cache file to support incremental compilation. + // + internal string ReferencesCache + { + get { return _referencesCache; } + } + + // + // Application File with Local Type + // + internal LocalReferenceFile LocalApplicationFile + { + get { return _localApplicationFile; } + } + + // + // Markup Page files with local types + // + internal LocalReferenceFile[] LocalMarkupPages + { + get { return _localMarkupPages; } + } + + // + // TaskFileService + // + internal ITaskFileService TaskFileService + { + get { return _taskFileService; } + } + + // + // CompilerState + // + internal CompilerState CompilerState + { + get { return _compilerState; } + } + + // + // CompilerLocalReference + // + internal CompilerLocalReference CompilerLocalReference + { + get { return _compilerLocalRefCache; } + } + + // + // Tell MarkupCompilePass2 whether it further handles InternalTypeHelper class. + // + internal bool FurtherCheckInternalTypeHelper + { + get { return _furtherCheckInternalTypeHelper; } + set { _furtherCheckInternalTypeHelper = value; } + } + + // + // Get the file path for the generated InternalTypeHelper class. + // + internal string InternalTypeHelperFile + { + get + { + string fileName = SharedStrings.GeneratedInternalTypeHelperFileName + + (TaskFileService.IsRealBuild? SharedStrings.GeneratedExtension : SharedStrings.IntellisenseGeneratedExtension) + + LanguageSourceExtension; + + return Path.Combine(OutputPath, fileName); + } + } + + + #endregion internal Properties + + //------------------------------------------------------ + // + // Private Methods + // + //------------------------------------------------------ + + #region Private Methods + + // + // Check if all the input properties are set valid values + // If any property contains an invalid value, Error counter _nErrors will + // be changed. + // + private void VerifyInputs() + { + // Check if the OutputType is valid type. + IsSupportedOutputType(OutputType); + + // Check if the Localization property is set correctly. + IsValidLocalizationDirectives(); + + VerifyApplicationFile(); + + if (PageMarkup != null && PageMarkup.Length > 0) + { + VerifyInputTaskItems(PageMarkup); + } + + if (SplashScreen != null && SplashScreen.Length > 1) + { + Log.LogErrorWithCodeFromResources(SRID.MultipleSplashScreenImages); + _nErrors++; + } + } + + // + // Verify if the Application file is set correctly + // in project file. + // + private void VerifyApplicationFile() + { + if (!IsApplicationTarget) + { + // + // For non Application target type. + // + if (ApplicationMarkup != null && ApplicationMarkup.Length > 0) + { + // + // For non-Application target type, Application definition should not be set. + // + Log.LogErrorWithCodeFromResources(SRID.AppDefIsNotRequired); + _nErrors++; + + } + + } + else + { + // + // For Application Target type. + // + if (ApplicationMarkup != null && ApplicationMarkup.Length > 0) + { + if (ApplicationMarkup.Length > 1) + { + Log.LogErrorWithCodeFromResources(SRID.MutlipleApplicationFiles); + _nErrors++; + } + + _applicationFile = TaskHelper.CreateFullFilePath(ApplicationMarkup[0].ItemSpec, SourceDir); + Log.LogMessageFromResources(MessageImportance.Low, SRID.ApplicationDefinitionFile, ApplicationFile); + + if (!TaskFileService.Exists(ApplicationFile)) + { + Log.LogErrorWithCodeFromResources(SRID.FileNotFound, ApplicationFile); + _nErrors++; + } + + } + + } + } + + // + // Don't support local reference xaml compilation for Container and netmodule type. + // + private bool IsSupportedOutputType(string outputType) + { + bool isSupported = false; + + switch (outputType) + { + case SharedStrings.Exe: + case SharedStrings.WinExe: + isSupported = true; + _isApplicationTarget = true; + break; + case SharedStrings.Library: + case SharedStrings.Module: + isSupported = true; + break; + + default: + isSupported = false; + break; + } + + if (isSupported == false) + { + Log.LogErrorWithCodeFromResources(SRID.TargetIsNotSupported, outputType); + + // Keep the error numbers so that the task can stop immediatelly + // later when Execute( ) is called. + _nErrors++; + } + + return isSupported; + } + + private bool IsValidLocalizationDirectives() + { + bool bValid = true; + + if (_localizationDirectives == MS.Internal.LocalizationDirectivesToLocFile.Unknown) + { + bValid = false; + + Log.LogErrorWithCodeFromResources(SRID.WrongLocalizationPropertySetting_Pass1); + + // Keep the error numbers so that the task can stop immediatelly + // later when Execute( ) is called. + _nErrors++; + } + + return bValid; + } + + + // + // Check if the passed TaskItems have valid ItemSpec + // + // + // + private bool VerifyInputTaskItems(ITaskItem[] inputItems) + { + bool bValid = true; + + foreach (ITaskItem inputItem in inputItems) + { + bool bValidItem; + + bValidItem = IsValidInputFile(inputItem.ItemSpec); + + if (bValidItem == false) + { + bValid = false; + } + } + + return bValid; + } + + private bool IsValidInputFile(string filePath) + { + bool bValid = true; + + if (!TaskFileService.Exists(TaskHelper.CreateFullFilePath(filePath, SourceDir))) + { + bValid = false; + Log.LogErrorWithCodeFromResources(SRID.FileNotFound, filePath); + + // Keep the error numbers so that the task can stop immediatelly + // later when Execute( ) is called. + _nErrors ++; + + } + + return bValid; + } + + // + // Return a new sourceDir and relative filepath for a given filePath. + // This is for supporting of fullpath or ..\ in the original FilePath. + // + private string GetResolvedFilePath(string filePath, ref string newSourceDir) + { + // Create a full path for the originalFilePath. + string fullFilePath = TaskHelper.CreateFullFilePath(filePath, SourceDir); + + // Get the relative path based on sourceDir + string relPath = TaskHelper.GetRootRelativePath(SourceDir, fullFilePath); + string newRelativeFilePath; + + if (relPath.Length > 0) + { + // the original file is relative to the SourceDir. + newSourceDir = SourceDir; + newRelativeFilePath = relPath; + } + else + { + // the original file is not relative to the SourceDir. + // it could have its own fullpath or contains "..\" etc. + // + // In this case, we want to put the filename as relative filepath + // and put the deepest directory that file is in as the new + // SourceDir. + // + int pathEndIndex = fullFilePath.LastIndexOf("\\", StringComparison.Ordinal); + + newSourceDir = fullFilePath.Substring(0, pathEndIndex + 1); + newRelativeFilePath = TaskHelper.GetRootRelativePath(newSourceDir, fullFilePath); + } + + return newRelativeFilePath; + } + + // + // Analyze the project setting and input files for incremental build support. + private void AnalyzeInputsAndSetting() + { + // Initialize the cache file paths and related information. + + _pageMarkupCache = CompilerState.GenerateCacheForFileList(PageMarkup); + _contentFilesCache = CompilerState.GenerateCacheForFileList(ContentFiles); + _sourceCodeFilesCache = CompilerState.GenerateCacheForFileList(SourceCodeFiles); + _referencesCache = CompilerState.GenerateCacheForFileList(References); + + _compilerAnalyzer = new IncrementalCompileAnalyzer(this); + + _compilerAnalyzer.AnalyzeInputFiles(); + + + _isCleanBuild = (CompilerAnalyzer.AnalyzeResult == RecompileCategory.All) ? true : false; + + } + + // + // Specially handle Reference list to prepare for xaml file compilation. + // + private ArrayList ProcessReferenceList( ) + { + ArrayList referenceList = new ArrayList(); + + // Generate the asmmebly reference list. + if (References != null && References.Length > 0) + { + ReferenceAssembly asmReference; + string refpath, asmname; + + for (int i = 0; i < References.Length; i++) + { + // The reference path must be full file path. + refpath = References[i].ItemSpec; + refpath = TaskHelper.CreateFullFilePath(refpath, SourceDir); + + asmname = Path.GetFileNameWithoutExtension(refpath); + + asmReference = new ReferenceAssembly(refpath, asmname); + referenceList.Add(asmReference); + + Log.LogMessageFromResources(MessageImportance.Low, SRID.ReferenceFile, refpath); + } + } + + return referenceList; + } + + // Cleanup baml files and code files generated in previous build. + private void CleanupGeneratedFiles( ) + { + string codeFile, bamlFile; + + if (IsApplicationTarget && !String.IsNullOrEmpty(CompilerAnalyzer.RecompileApplicationFile.Path)) + { + GetGeneratedFiles(CompilerAnalyzer.RecompileApplicationFile.Path, out codeFile, out bamlFile); + + if (!String.IsNullOrEmpty(codeFile)) + { + TaskFileService.Delete(codeFile); + } + + if (!String.IsNullOrEmpty(bamlFile)) + { + TaskFileService.Delete(bamlFile); + } + } + + if (CompilerAnalyzer.RecompileMarkupPages != null) + { + for (int i = 0; i < CompilerAnalyzer.RecompileMarkupPages.Length; i++) + { + GetGeneratedFiles(CompilerAnalyzer.RecompileMarkupPages[i].Path, out codeFile, out bamlFile); + + if (!String.IsNullOrEmpty(codeFile)) + { + TaskFileService.Delete(codeFile); + } + + if (!String.IsNullOrEmpty(bamlFile)) + { + TaskFileService.Delete(bamlFile); + } + } + } + + // If the content file setting is changed, the generated content.g.cs code file should be updated later, + // so delete the file here first. + // + // This includes the scenario that all the previous content files are removed from the content item list in + // this build run. + if ((CompilerAnalyzer.AnalyzeResult & RecompileCategory.ContentFiles) == RecompileCategory.ContentFiles) + { + if (TaskFileService.Exists(ContentCodeFile)) + { + TaskFileService.Delete(ContentCodeFile); + } + } + + // If this is for CleanBuild, and the InternalTypeHelper file exists, delete it first. + if (IsCleanBuild && TaskFileService.Exists(InternalTypeHelperFile)) + { + TaskFileService.Delete(InternalTypeHelperFile); + } + } + + // + // Call MarkupCompiler to do the real compilation work. + // + private void DoMarkupCompilation() + { + Log.LogMessageFromResources(MessageImportance.Low, SRID.DoCompilation); + Log.LogMessageFromResources(MessageImportance.Low, SRID.OutputType, OutputType); + + + // When code goes here, the MarkupCompilation is really required, so don't need + // to do more further validation inside this private method. + + AppDomain appDomain = null; + CompilerWrapper compilerWrapper = null; + + try + { + compilerWrapper = TaskHelper.CreateCompilerWrapper(AlwaysCompileMarkupFilesInSeparateDomain, ref appDomain); + + if (compilerWrapper != null) + { + compilerWrapper.OutputPath = OutputPath; + compilerWrapper.AssemblyVersion = AssemblyVersion; + compilerWrapper.AssemblyPublicKeyToken = AssemblyPublicKeyToken; + compilerWrapper.LanguageSourceExtension = LanguageSourceExtension; + compilerWrapper.HostInBrowser = TaskHelper.BooleanStringValue(HostInBrowser); + compilerWrapper.SplashImage = SplashImageName; + + compilerWrapper.TaskLogger = Log; + compilerWrapper.UnknownErrorID = UnknownErrorID; + compilerWrapper.XamlDebuggingInformation = XamlDebuggingInformation; + + compilerWrapper.TaskFileService = TaskFileService; + + if (IsApplicationTarget) + { + compilerWrapper.ApplicationMarkup = CompilerAnalyzer.RecompileApplicationFile; + } + + compilerWrapper.ContentFiles = CompilerAnalyzer.ContentFiles; + + // Process Reference list here. + ArrayList referenceList = ProcessReferenceList(); + + compilerWrapper.References = referenceList; + + compilerWrapper.LocalizationDirectivesToLocFile = (int)_localizationDirectives; + + compilerWrapper.DoCompilation(AssemblyName, Language, RootNamespace, CompilerAnalyzer.RecompileMarkupPages, false); + + // Keep the Local-Type-Ref file lists + + _localXamlPages = compilerWrapper.LocalXamlPages; + _localXamlApplication = compilerWrapper.LocalXamlApplication; + + _hasInternals = compilerWrapper.HasInternals; + } + } + finally + { + + if (compilerWrapper != null && compilerWrapper.ErrorTimes > 0) + { + _nErrors += compilerWrapper.ErrorTimes; + } + + if (appDomain != null) + { + System.Threading.Tasks.Task.Run(() => + { + // Better GC behavior in 4.6 and later when wrapped in Task.Run(). + // Inside of VisualStudio, when DesignTimeMarkupCompilation happens, it uses MarkupCompilePass1 only (not Pass2). + AppDomain.Unload(appDomain); + }); + } + + compilerWrapper = null; + } + } + + + // + // Generate the required Output Items. + // + private void GenerateOutputItems( ) + { + // For the rest target types, + // Create the output lists for CS and Baml files. + + ArrayList bamlFileList = new ArrayList(); + ArrayList csFileList = new ArrayList(); + ArrayList localRefPageList = new ArrayList(); + ArrayList localRefAppdefList = new ArrayList(); + + // Generate Output Items for PageMarkup + if (PageMarkup != null && PageMarkup.Length > 0) + { + GenerateOutputItemsForCompiledXamlFiles(PageMarkup, + _localXamlPages, + ref bamlFileList, + ref csFileList, + ref localRefPageList); + } + + // + // Generate output items for ApplicationDefinition if it is set in the project file. + // + if (ApplicationFile != null && ApplicationFile.Length > 0) + { + string[] appdefLocalList = null; + + if (!String.IsNullOrEmpty(_localXamlApplication)) + { + appdefLocalList = new string[1] { _localXamlApplication }; + } + + GenerateOutputItemsForCompiledXamlFiles(ApplicationMarkup, + appdefLocalList, + ref bamlFileList, + ref csFileList, + ref localRefAppdefList); + } + + if (TaskFileService.Exists(ContentCodeFile)) + { + csFileList.Add(new TaskItem(ContentCodeFile)); + } + + // Generate the Baml, code and /or locally-defined type related output items. + GeneratedBamlFiles = (ITaskItem[])bamlFileList.ToArray(typeof(ITaskItem)); + + if (!SkipMarkupCompilation) + { + if (localRefAppdefList.Count > 0) + { + _localApplicationFile = (LocalReferenceFile)localRefAppdefList[0]; + } + + if (localRefPageList.Count > 0) + { + _localMarkupPages = (LocalReferenceFile[])localRefPageList.ToArray(typeof(LocalReferenceFile)); + } + + // + // If MarkupCompilePass2 is required for Main assembly, there is no need to invoke MarkupCompilePass2 + // for satellite assembly again. + // + if (_requirePass2ForMainAssembly) + { + _requirePass2ForSatelliteAssembly = false; + } + } + + // + // Detect whether or not to ask Pass2 to do further handling for the InternalTypeHelper class. + // + // Only when all of below conditions are true, it requires Pass2 to further handling this wrapper class: + // + // 1. InternalTypeHelper file exists. + // 2. It is a CleanBuild. + // 3. No any xaml files which don't contain local types contains internal types from friend assembly. + // 4. _requirePass2ForMainAssembly is true. + // + // If InternalTypeHelper File exists, Pass1 would always add it to the code file list, so that consequent task + // can take it. If Pass2 determines that this wrapper class is not required, it can simply make an empty file. + // But we still keep the list of generated code files. + + bool existsInternalTypeHelper = TaskFileService.Exists(InternalTypeHelperFile); + + if (IsCleanBuild && existsInternalTypeHelper && _requirePass2ForMainAssembly && !_hasInternals) + { + FurtherCheckInternalTypeHelper = true; + } + else + { + FurtherCheckInternalTypeHelper = false; + } + + if (existsInternalTypeHelper) + { + csFileList.Add(new TaskItem(InternalTypeHelperFile)); + } + + GeneratedCodeFiles = (ITaskItem[])csFileList.ToArray(typeof(ITaskItem)); + + // Generate the Localization Output files + if (_localizationDirectives != MS.Internal.LocalizationDirectivesToLocFile.None) + { + GenerateOutputItemsForLocFiles(); + } + + HandleCacheFiles(); + + // + // Put all the generated files into one output Item so that it can be set to + // FileWrites item in target file, this list of files will be cleaned up for + // next clean build by msbuild. + // The generated files should include Baml files, code files, localization files + // and the cache files. + // + + ArrayList allGeneratedFiles = new ArrayList( ); + + for (int i = 0; i < GeneratedBamlFiles.Length; i++) + { + allGeneratedFiles.Add(GeneratedBamlFiles[i]); + } + + for (int i = 0; i < GeneratedCodeFiles.Length; i++) + { + allGeneratedFiles.Add(GeneratedCodeFiles[i]); + } + + for (int i = 0; i < GeneratedLocalizationFiles.Length; i++) + { + allGeneratedFiles.Add(GeneratedLocalizationFiles[i]); + } + + // Add the CompilerState cache file into the list + + allGeneratedFiles.Add(new TaskItem(CompilerState.CacheFilePath)); + + if (CompilerLocalReference.CacheFileExists()) + { + allGeneratedFiles.Add(new TaskItem(CompilerLocalReference.CacheFilePath)); + } + + AllGeneratedFiles = (ITaskItem[])allGeneratedFiles.ToArray(typeof(ITaskItem)); + + } + + + // + // Both MarkupPage and MarkupResource have the similar code to generate + // output baml, code file and /or locallyDefined xaml files. + // so put all the common code in this private method. + // + // Inputs : + // Xaml file items: PageMarkup or MarkupResource + // LocallyDefined Xaml List (Generated by MarkupCompiler) + // + // Outputs: BamlFile List, + // CodeFile List, + // LocallyDefined Xaml List + // + private void GenerateOutputItemsForCompiledXamlFiles(ITaskItem[] inputXamlItemList, + string[] inputLocalRefXamlFileList, + ref ArrayList outputBamlFileList, + ref ArrayList outputCodeFileList, + ref ArrayList outputLocalRefXamlList) + { + + // + // For each input xaml file, check if the code and baml file are generated or not. + // If baml or code files are generated, put them into the appropriate output file item list. + // + for (int i = 0; i < inputXamlItemList.Length; i++) + { + string genLangFilePath, bamlFile; + + GetGeneratedFiles(inputXamlItemList[i].ItemSpec, out genLangFilePath, out bamlFile); + + if (!String.IsNullOrEmpty(genLangFilePath) && outputCodeFileList != null) + { + TaskItem codeItem; + + codeItem = new TaskItem(); + codeItem.ItemSpec = genLangFilePath; + + outputCodeFileList.Add(codeItem); + + Log.LogMessageFromResources(MessageImportance.Low, SRID.GeneratedCodeFile, codeItem.ItemSpec); + } + + if (!String.IsNullOrEmpty(bamlFile)) + { + TaskItem bamlItem = GenerateBamlItem(bamlFile, inputXamlItemList[i]); + + // Add bamlItem to the output Baml List + outputBamlFileList.Add(bamlItem); + Log.LogMessageFromResources(MessageImportance.Low, SRID.GeneratedBamlFile, bamlItem.ItemSpec); + } + + } // End of for { } loop. + + + // + // If the project contains local-type xaml files, put them into the right output item list here. + // + + // + // If MarkupCompilation is skipped, there is no need to check local-type xaml files. + // + if (!SkipMarkupCompilation && inputLocalRefXamlFileList != null && inputLocalRefXamlFileList.Length > 0) + { + for (int i = 0; i < inputLocalRefXamlFileList.Length; i++) + { + string fullLocalXamlFile = TaskHelper.CreateFullFilePath(inputLocalRefXamlFileList[i], SourceDir); + + LocalReferenceFile localFile = GenerateLocalTypeItem(fullLocalXamlFile, inputXamlItemList); + + if (localFile != null && outputLocalRefXamlList != null) + { + outputLocalRefXamlList.Add(localFile); + } + } + } + } + + + // + // Generate appropriate output file list for local-type xaml file. This information will be saved + // into the .lref cache file so that the MarkupCompilePass2 can take it. + // + private LocalReferenceFile GenerateLocalTypeItem(string localTypeXamlFile, ITaskItem[] inputXamlItemList) + { + LocalReferenceFile localFile = null; + bool isLocalizable = false; + string linkAlias = String.Empty; + string logicalName = String.Empty; + + // + // Check if the local-type xaml file is localizable or not. + // + for (int i = 0; i < inputXamlItemList.Length; i++) + { + ITaskItem inputXamlItem = inputXamlItemList[i]; + + string xamlInputFullPath = TaskHelper.CreateFullFilePath(inputXamlItem.ItemSpec, SourceDir); + + if (String.Compare(localTypeXamlFile, xamlInputFullPath, StringComparison.OrdinalIgnoreCase) == 0) + { + // + // Got this file from the original XamlFile TaskItem list. + // Check if this item is localizable or not and stop the search here. + // + isLocalizable = IsItemLocalizable(inputXamlItem); + linkAlias = inputXamlItem.GetMetadata(SharedStrings.Link); + logicalName = inputXamlItem.GetMetadata(SharedStrings.LogicalName); + break; + } + } + + // + // Generate the instance of LocalReferenceFile for this local-type xaml file. + // + localFile = new LocalReferenceFile(localTypeXamlFile, isLocalizable, linkAlias, logicalName); + + if (isLocalizable) + { + _requirePass2ForSatelliteAssembly = true; + } + else + { + _requirePass2ForMainAssembly = true; + } + + return localFile; + } + + + + // + // Generate a baml TaskItem for the given xaml file, and transfer the appropriate + // source task item's custom attributes to the generated baml item if necessary. + // The xaml file could be an application definition file, a Markup Page. + // The bamlFile must exist before this method is called. + private TaskItem GenerateBamlItem(string bamlFile, ITaskItem SourceItem) + { + TaskItem bamlItem; + + bamlItem = new TaskItem(); + bamlItem.ItemSpec = bamlFile; + + // + // Transfer some special custom attributes from source task item + // to output item. + // Such as transfer the Localizable attribute from a given .xaml file item + // to the generated .baml file item. + // + // Normally MarkupPage and MarkupResource need to transfer their attributes. + // But Application definition doesn't require this. + if (SourceItem != null) + { + string[] listCarryOverAttribute = new string[] { + SharedStrings.Localizable, + SharedStrings.Link, + SharedStrings.LogicalName + }; + + for (int j = 0; j < listCarryOverAttribute.Length; j++) + { + string attributeValue; + + attributeValue = SourceItem.GetMetadata(listCarryOverAttribute[j]); + if (attributeValue != null) + { + bamlItem.SetMetadata(listCarryOverAttribute[j], attributeValue); + } + } + } + + return bamlItem; + } + + // + // Generate output item list for localization files. + // + private void GenerateOutputItemsForLocFiles() + { + + ArrayList locFileItemList = new ArrayList(); + TaskItem tiLoc; + ITaskItem xamlItem; + + if (ApplicationMarkup != null && ApplicationMarkup.Length > 0 && ApplicationMarkup[0] != null) + { + + tiLoc = ProcessLocFileForXamlItem(ApplicationMarkup[0]); + + if (tiLoc != null) + { + // Add this LocItem to the locFileItemList + locFileItemList.Add(tiLoc); + } + } + + if (PageMarkup != null) + { + for (int i = 0; i < PageMarkup.Length; i++) + { + xamlItem = PageMarkup[i]; + + tiLoc = ProcessLocFileForXamlItem(xamlItem); + + if (tiLoc != null) + { + // Add this LocItem to the locFileItemList + locFileItemList.Add(tiLoc); + } + } + } + + // Generate the Output TaskItem List + GeneratedLocalizationFiles = (ITaskItem[])locFileItemList.ToArray(typeof(ITaskItem)); + + } + + // + // General method to handle an input xaml file item for Localization. + // + // If the XamlFile is localizable, generate a TaskItem for LocFile. + // If the XamlFile is not localizable, and if the .loc file is generated, delete it + // so that it won't affect the incremental build next time. + // + private TaskItem ProcessLocFileForXamlItem(ITaskItem xamlItem) + { + TaskItem tiLoc = null; + + string tempDir = SourceDir; // Just for calling GetResolvedFilePath, the value is not used here. + + // Get a relative file path for the passed .xaml file + string xamlRelativeFilePath = GetResolvedFilePath(xamlItem.ItemSpec, ref tempDir); + string locFile; + + // Change the extension from .xaml to .loc + locFile = Path.ChangeExtension(xamlRelativeFilePath, SharedStrings.LocExtension); + + // the .loc file is at OutputPath + relative Path. + locFile = OutputPath + locFile; + + if (TaskFileService.Exists(locFile)) + { + // + // Per discussion with Globalization team: + // + // Globalization requests to collect .loc file for a baml file + // no matter the baml is in main assembly or satelliate assembly. + // + // The localization tool can localize the baml from the main assembly as well. + // + + // Generate a TaskItem to include .loc file + // The item is going to add to the output LocFile list + tiLoc = new TaskItem(locFile); + } + + return tiLoc; + } + + // + // Check if the given TaskItem localizable. + // + private bool IsItemLocalizable(ITaskItem ti) + { + bool bIsLocalizable; + + if (String.IsNullOrEmpty(UICulture)) + { + // if UICulture is not set, all baml files are not localizable. + // The Localizable metadate value is ignored for this case. + bIsLocalizable = false; + } + else + { + string strLocalizable; + + // if UICulture is set, by default all the baml files are localizable unless + // an explicit value "false" is set to Localizable metadata. + bIsLocalizable = true; + + strLocalizable = ti.GetMetadata(SharedStrings.Localizable); + + if (strLocalizable != null && String.Compare(strLocalizable, "false", StringComparison.OrdinalIgnoreCase) == 0) + { + bIsLocalizable = false; + } + } + + return bIsLocalizable; + } + + // + // Cleanup the cache files. + // It could happen if build error occurs. + // + private void CleanupCacheFiles() + { + CompilerState.CleanupCache(); + CompilerLocalReference.CleanupCache(); + } + + + // + // A central place to update cache files based on current build status MarkupCompiler result. + // + // This method should be called after the markupcompiler is done or skipped. + // + private void HandleCacheFiles() + { + // Update the CompilerState file based on new project setting, no matter MarkupCompiler is skipped or not. + CompilerState.SaveStateInformation(this); + + if ( (CompilerAnalyzer.AnalyzeResult & ( RecompileCategory.PagesWithLocalType | RecompileCategory.ModifiedPages )) != RecompileCategory.NoRecompile) + { + // The modified xaml files and all the local-type xaml files should be recompiled, depends on the + // MarkupCompiler return, it will keep or delete the cache file for local type xaml files. + + if (_requirePass2ForMainAssembly || _requirePass2ForSatelliteAssembly) + { + CompilerLocalReference.SaveCacheInformation(this); + } + else + { + CompilerLocalReference.CleanupCache(); + } + } + + // if build doesn't handle the local-ref xaml files, (it implies not handling the modified xaml files either), + // such as the build handles only for Application (HIB change) and Content files changes, or the markup compilation + // is skipped, ( NoRecompile). + // + // For this scenario, if .lref file exists, it should still be kept. + // + + } + + #endregion Private Methods + + //------------------------------------------------------ + // + // Private Properties + // + //------------------------------------------------------ + + #region Private Properties + + // + // The root directory for the applicaiton project. + // + private string SourceDir + { + get { return _sourceDir; } + } + + private IncrementalCompileAnalyzer CompilerAnalyzer + { + get { return _compilerAnalyzer; } + } + + + // + // If no input file is modified, Markup compilation will be skipped. + // But the code still generates the correct output item lists. + // + private bool SkipMarkupCompilation + { + get { return CompilerAnalyzer.AnalyzeResult == RecompileCategory.NoRecompile; } + } + + private string ContentCodeFile + { + get + { + return OutputPath + AssemblyName + SharedStrings.ContentFile + + (TaskFileService.IsRealBuild? SharedStrings.GeneratedExtension : SharedStrings.IntellisenseGeneratedExtension) + + LanguageSourceExtension; + } + } + + // + // Whether this is a clean build or not + // + private bool IsCleanBuild + { + get { return _isCleanBuild; } + } + + #endregion Private Properties + + //------------------------------------------------------ + // + // Private Fields + // + //------------------------------------------------------ + + #region Private Fields + + private string _language; + private string _languageSourceExtension = string.Empty; + private ITaskItem [] _pagemarkupFiles; + private ITaskItem [] _contentFiles; + private ITaskItem [] _references; + private bool _xamlDebuggingInformation = false; + private string _outputType; + private string _assemblyName; + private string _assemblyVersion; + private string _assemblyPublicKeyToken; + private string _rootNamespace = String.Empty; + private ITaskItem [] _applicationMarkup; + private ITaskItem[] _splashScreen; + private bool _alwaysCompileMarkupFilesInSeparateDomain = true; + private bool _isRunningInVisualStudio; + + private string[] _assembliesGeneratedDuringBuild; + private string[] _knownReferencePaths; + + private string _sourceDir; + private string _outputDir; + + private ITaskItem[] _extraBuildControlFiles; + private string _uiCulture = String.Empty; + + private string _applicationFile = String.Empty; + private bool _isApplicationTarget = false; + private string _hostInBrowser = String.Empty; + + private LocalizationDirectivesToLocFile _localizationDirectives; + + private ITaskItem [] _generatedCodeFiles; + private ITaskItem [] _generatedBamlFiles; + private ITaskItem [] _generatedLocalizationFiles; + private ITaskItem [] _allGeneratedFiles = null; + + private string _localXamlApplication; + private string[] _localXamlPages; + private bool _hasInternals = false; + + private int _nErrors; + + private string _defineConstants = String.Empty; + private ITaskItem[] _sourceCodeFiles; + + private string _pageMarkupCache = String.Empty; + private string _contentFilesCache = String.Empty; + private string _sourceCodeFilesCache = String.Empty; + private string _referencesCache = String.Empty; + private LocalReferenceFile _localApplicationFile = null; + private LocalReferenceFile[] _localMarkupPages = null; + + private bool _requirePass2ForMainAssembly = false; + private bool _requirePass2ForSatelliteAssembly = false; + + private bool _furtherCheckInternalTypeHelper = false; + + private CompilerState _compilerState; + private CompilerLocalReference _compilerLocalRefCache; + private IncrementalCompileAnalyzer _compilerAnalyzer; + + private ITaskFileService _taskFileService; + + private bool _isCleanBuild = true; // Indicates whether this is a cleanbuild or incremental build. + + #region const string + + private const string UnknownErrorID = "MC1000"; + + #endregion const string + + #endregion Private Fields + + } + + #endregion MarkupCompilePass1 Task class +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass2.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass2.cs new file mode 100644 index 00000000000..07309c5ada4 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass2.cs @@ -0,0 +1,898 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: A MSBuild Task that can generate .baml file for some special +// xaml markup files that want to take some locally-defined types. +// +//--------------------------------------------------------------------------- + +using System; +using System.IO; +using System.Collections; +using System.Security; +using System.Security.Permissions; +using System.Text; + +using System.Globalization; +using System.Diagnostics; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +using MS.Utility; +using MS.Internal; +using MS.Internal.Tasks; +using MS.Internal.Markup; + +// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler. +// We first need to disable warnings about unknown message numbers and unknown pragmas. +#pragma warning disable 1634, 1691 + +namespace Microsoft.Build.Tasks.Windows +{ + + #region MarkupCompilePass2 Task class + + /// + /// Class of MarkupCompilePass2 Task + /// + public sealed class MarkupCompilePass2 : Task + { + + //------------------------------------------------------ + // + // Constructors + // + //------------------------------------------------------ + + #region Constructors + + /// + /// Constructor + /// + public MarkupCompilePass2( ) : base(SR.SharedResourceManager) + { + // set the source directory + _sourceDir = Directory.GetCurrentDirectory() + "\\"; + + _outputType = SharedStrings.WinExe; + + _nErrors = 0; + + } + + #endregion Constructors + + //------------------------------------------------------ + // + // Public Methods + // + //------------------------------------------------------ + + #region Public Methods + + /// + /// Execute method in Task + /// + /// + public override bool Execute() + { + TaskHelper.DisplayLogo(Log, SR.Get(SRID.MarkupCompilePass2Task)); + + // + // Create the TaskFileService instance here + // + _taskFileService = new TaskFileService(this) as ITaskFileService; + + try + { + IsSupportedOutputType(OutputType); + + Log.LogMessageFromResources(MessageImportance.Low, SRID.CurrentDirectory, SourceDir); + + // If wrong files are set to some properties, the task + // should stop here immediatelly. + + if (_nErrors > 0) + { + Log.LogErrorWithCodeFromResources(SRID.WrongPropertySetting); + } + else + { + bool hasLocalXamlFiles; + + hasLocalXamlFiles = InitLocalXamlCache(); + + if (!hasLocalXamlFiles) + { + // There is no valid input xaml files. + // No need to do further work. + // stop here. + return true; + } + + // create output directory + if (!Directory.Exists(OutputPath)) + { + Directory.CreateDirectory(OutputPath); + } + + // Call the Markup Compiler to do the real compiling work + + ArrayList referenceList; + FileUnit localApplicationFile; + FileUnit[] localXamlPageFileList; + + // Prepare the appropriate file lists required by MarkupCompiler. + PrepareForMarkupCompilation(out localApplicationFile, out localXamlPageFileList, out referenceList); + + // Do the real Pass2 compilation work here. + DoLocalReferenceMarkupCompilation(localApplicationFile, localXamlPageFileList, referenceList); + + // Generate the required output items. + GenerateOutputItems(); + + Log.LogMessageFromResources(MessageImportance.Low, SRID.CompilationDone); + } + } +#pragma warning disable 6500 + catch (Exception e) + { + string message; + string errorId; + + errorId = Log.ExtractMessageCode(e.Message, out message); + + if (String.IsNullOrEmpty(errorId)) + { + errorId = UnknownErrorID; + message = SR.Get(SRID.UnknownBuildError, message); + } + + Log.LogError(null, errorId, null, null, 0, 0, 0, 0, message, null); + + _nErrors++; + + } + catch // Non-CLS compliant errors + { + Log.LogErrorWithCodeFromResources(SRID.NonClsError); + + _nErrors++; + } +#pragma warning restore 6500 + + if (_nErrors > 0) + { + // When error counter is changed, the appropriate error message should have + // been reported. + + // + // The task should cleanup all the cache files so that all the xaml files will + // get chance to recompile next time. + // + + string stateFileName = OutputPath + AssemblyName + + (TaskFileService.IsRealBuild? SharedStrings.StateFile : SharedStrings.IntellisenseStateFile); + + string localTypeCacheFileName = OutputPath + AssemblyName + + (TaskFileService.IsRealBuild? SharedStrings.LocalTypeCacheFile : SharedStrings.IntellisenseLocalTypeCacheFile); + + if (TaskFileService.Exists(stateFileName)) + { + TaskFileService.Delete(stateFileName); + } + + if (TaskFileService.Exists(localTypeCacheFileName)) + { + TaskFileService.Delete(localTypeCacheFileName); + } + + return false; + } + else + { + // Mark Pass2 as completed in the cache + string stateFileName = OutputPath + AssemblyName + + (TaskFileService.IsRealBuild ? SharedStrings.StateFile : SharedStrings.IntellisenseStateFile); + if (TaskFileService.Exists(stateFileName)) + { + CompilerState compilerState = new CompilerState(stateFileName, TaskFileService); + compilerState.LoadStateInformation(); + if (compilerState.Pass2Required) + { + compilerState.Pass2Required = false; + compilerState.SaveStateInformation(); + } + } + + Log.LogMessageFromResources(SRID.CompileSucceed_Pass2); + return true; + } + } + + + #endregion Public Methods + + //------------------------------------------------------ + // + // Public Properties + // + //------------------------------------------------------ + + #region Public Properties + + /// + /// The Language the managed compiler supports. + /// the valid languages are C#, VB, Jscript, J#, C++ + /// + [Required] + public string Language + { + get { return _language; } + set { _language = value; } + } + + /// + /// OutputPath + /// Directory which will contain the generated baml files. + /// + [Required] + public string OutputPath + { + get { return _outputPath; } + set + { + string filePath = value; + + // Get the relative path based on sourceDir + _outputPath= TaskHelper.CreateFullFilePath(filePath, SourceDir); + + // Make sure OutputDir always ends with '\\'. + if (!_outputPath.EndsWith("\\", StringComparison.Ordinal)) + { + _outputPath += "\\"; + } + } + } + + /// + /// OutputType + /// Valid types: exe, winexe, library, netmodule + /// + [Required] + public string OutputType + { + get { return _outputType; } + set { _outputType = TaskHelper.GetLowerString(value); } + } + + /// + /// AssemblyName + /// The short name of assembly which will be generated for this project. + /// + [Required] + public string AssemblyName + { + get { return _assemblyName; } + set { _assemblyName = value; } + } + + /// + /// Root namespace for the classes inside the project. + /// It is also used in the Root element record of the generated baml file + /// when the corresponding markup page is not set x:Class attribute. + /// + public string RootNamespace + { + get { return _rootNamespace; } + set { _rootNamespace = value; } + } + + /// + /// Control whether to run the compilation in second appdomain. + /// By default, it is set to true, but project can set this property + /// to false to make markup file compilation faster. + /// + public bool AlwaysCompileMarkupFilesInSeparateDomain + { + get { return _alwaysCompileMarkupFilesInSeparateDomain; } + set { _alwaysCompileMarkupFilesInSeparateDomain = value; } + } + + /// + /// Assembly References. + /// + /// + public ITaskItem[] References + { + get { return _references; } + set { _references = value; } + } + + /// + /// + public bool XamlDebuggingInformation + { + get { return _xamlDebuggingInformation; } + set { _xamlDebuggingInformation = value; } + } + + /// + /// Known reference paths hold referenced assemblies which are never changed during the build procedure. + /// such as references in GAC, in framework directory or framework SDK directory etc. + /// Users could add their own known reference paths in project files. + /// + public string[] KnownReferencePaths + { + get + { + return _knownReferencePaths; + } + + set + { + _knownReferencePaths = value; + } + } + + /// + /// A list of reference assemblies that are to change for sure during the build cycle. + /// + /// Such as in VS.NET, if one project wants to reference another project's output, the + /// second project's output could be put in AssembliesGeneratedDuringBuild list. + /// Note: Once this property is set, it must contain the complete list of generated + /// assemblies in this build solution. + /// + public string[] AssembliesGeneratedDuringBuild + { + get + { + return _assembliesGeneratedDuringBuild; + } + + set + { + _assembliesGeneratedDuringBuild = value; + } + + } + + /// + /// Generated Baml files for the passed markup xaml files + /// + [Output] + public ITaskItem [] GeneratedBaml + { + get + { + if (_generatedBaml == null) + _generatedBaml = new TaskItem[0]; + return _generatedBaml; + } + + set + { + _generatedBaml = value; + } + } + + /// + /// Controls how to generate localization information for each xaml file. + /// Valid values: None, CommentsOnly, All. + /// + public string LocalizationDirectivesToLocFile + { + get + { + string localizationDirectives = SharedStrings.Loc_None; + + switch (_localizationDirectives) + { + case MS.Internal.LocalizationDirectivesToLocFile.None: + + localizationDirectives = SharedStrings.Loc_None; + break; + + case MS.Internal.LocalizationDirectivesToLocFile.CommentsOnly: + + localizationDirectives = SharedStrings.Loc_CommentsOnly; + break; + + case MS.Internal.LocalizationDirectivesToLocFile.All: + + localizationDirectives = SharedStrings.Loc_All; + + break; + + } + + return localizationDirectives; + } + + set + { + string localizationDirectives = value; + + if (localizationDirectives != null) + { + localizationDirectives = localizationDirectives.ToLower(CultureInfo.InvariantCulture); + } + + switch (localizationDirectives) + { + case SharedStrings.Loc_None: + + _localizationDirectives = MS.Internal.LocalizationDirectivesToLocFile.None; + break; + + case SharedStrings.Loc_CommentsOnly: + + _localizationDirectives = MS.Internal.LocalizationDirectivesToLocFile.CommentsOnly; + break; + + case SharedStrings.Loc_All: + + _localizationDirectives = MS.Internal.LocalizationDirectivesToLocFile.All; + break; + + default: + _localizationDirectives = MS.Internal.LocalizationDirectivesToLocFile.Unknown; + break; + } + + } + } + + + #endregion Public Properties + + //------------------------------------------------------ + // + // Private Properties + // + //------------------------------------------------------ + + // + // TaskFileService + // + private ITaskFileService TaskFileService + { + get { return _taskFileService; } + } + + + //------------------------------------------------------ + // + // Private Methods + // + //------------------------------------------------------ + + #region Private Methods + + // + // Initialze the local xaml cache file. + // + // return value: + // + // If cache doesn't exist, or both LocalAppDef and LocallXaml Pages do not exist, return false + // to indicate no further work required. + // otherwise, return true. + // + private bool InitLocalXamlCache() + { + bool hasLocalFiles = false; + + _compilerLocalRefCache = new CompilerLocalReference( + OutputPath + AssemblyName + (TaskFileService.IsRealBuild? SharedStrings.LocalTypeCacheFile : SharedStrings.IntellisenseLocalTypeCacheFile), + _taskFileService); + + if (_compilerLocalRefCache.CacheFileExists()) + { + _compilerLocalRefCache.LoadCacheFile(); + + _localApplicationFile = _compilerLocalRefCache.LocalApplicationFile; + _localMarkupPages = _compilerLocalRefCache.LocalMarkupPages; + + if (_localApplicationFile != null || (_localMarkupPages != null && _localMarkupPages.Length > 0)) + { + hasLocalFiles = true; + + // + // Initialize InternalTypeHelper file from the cache file first. + // Further handling will be taken after the xaml file compilation is done. + // + // If InternalTypeHelperFile is set in the Cache file, it means Pass1 cannot + // detect whether or not to keep the InternalTypeHelper File until the Pass2 + // xaml file compilation is done. + // + _internalTypeHelperFile = _compilerLocalRefCache.InternalTypeHelperFile; + } + } + + return hasLocalFiles; + } + + // + // Return a new sourceDir and relative filepath for a given filePath. + // This is for supporting of fullpath or ..\ in the original FilePath. + // + private string GetResolvedFilePath(string filePath, ref string newSourceDir) + { + // Create a full path for the originalFilePath. + string fullFilePath = TaskHelper.CreateFullFilePath(filePath, SourceDir); + + // Get the relative path based on sourceDir + string relPath = TaskHelper.GetRootRelativePath(SourceDir, fullFilePath); + string newRelativeFilePath; + + if (relPath.Length > 0) + { + // the original file is relative to the SourceDir. + newSourceDir = SourceDir; + newRelativeFilePath = relPath; + } + else + { + // the original file is not relative to the SourceDir. + // it could have its own fullpath or contains "..\" etc. + // + // In this case, we want to put the filename as relative filepath + // and put the deepest directory that file is in as the new + // SourceDir. + // + int pathEndIndex = fullFilePath.LastIndexOf("\\", StringComparison.Ordinal); + + newSourceDir = fullFilePath.Substring(0, pathEndIndex + 1); + newRelativeFilePath = TaskHelper.GetRootRelativePath(newSourceDir, fullFilePath); + } + + return newRelativeFilePath; + } + + + // + // Generate the necessary file lists and other information required by MarkupCompiler. + // + // Output ArrayLists: localApplicationFile, + // localXamlPageFileList + // referenceList + // + private void PrepareForMarkupCompilation(out FileUnit localApplicationFile, out FileUnit[] localXamlPageFileList, out ArrayList referenceList) + { + Log.LogMessageFromResources(MessageImportance.Low, SRID.PreparingCompile); + Log.LogMessageFromResources(MessageImportance.Low, SRID.OutputType, OutputType); + + // Initialize the output parameters + localXamlPageFileList = new FileUnit[0]; + localApplicationFile = FileUnit.Empty; + referenceList = new ArrayList(); + + if (_localApplicationFile != null) + { + // We don't want to support multiple application definition file per project. + localApplicationFile = new FileUnit(_localApplicationFile.FilePath, _localApplicationFile.LinkAlias, _localApplicationFile.LogicalName); + + Log.LogMessageFromResources(MessageImportance.Low, SRID.LocalRefAppDefFile, localApplicationFile); + + } + + // Generate the Xaml Markup file list + if (_localMarkupPages != null && _localMarkupPages.Length > 0) + { + int localFileNum = _localMarkupPages.Length; + localXamlPageFileList = new FileUnit[localFileNum]; + + for (int i = 0; i < localFileNum; i++) + { + FileUnit localPageFile = new FileUnit(_localMarkupPages[i].FilePath, _localMarkupPages[i].LinkAlias, _localMarkupPages[i].LogicalName); + + localXamlPageFileList[i] = localPageFile; + Log.LogMessageFromResources(MessageImportance.Low, SRID.LocalRefMarkupPage, localPageFile); + } + } + + // + // Generate the asmmebly reference list. + // The temporay target assembly should have been added into Reference list from target file. + // + if (References != null && References.Length > 0) + { + ReferenceAssembly asmReference; + string refpath, asmname; + + for (int i = 0; i < References.Length; i++) + { + refpath = References[i].ItemSpec; + refpath = TaskHelper.CreateFullFilePath(refpath, SourceDir); + + asmname = Path.GetFileNameWithoutExtension(refpath); + + asmReference = new ReferenceAssembly(refpath, asmname); + referenceList.Add(asmReference); + } + } + + } + + // + // Call MarkupCompiler to do the real compilation work. + // + private void DoLocalReferenceMarkupCompilation(FileUnit localApplicationFile, FileUnit[] localXamlPageFileList, ArrayList referenceList) + { + // When code goes here, the MarkupCompilation is really required, so don't need + // to do more further validation inside this private method. + + Log.LogMessageFromResources(MessageImportance.Low, SRID.DoCompilation); + + AppDomain appDomain = null; + CompilerWrapper compilerWrapper = null; + + try + { + compilerWrapper = TaskHelper.CreateCompilerWrapper(AlwaysCompileMarkupFilesInSeparateDomain, ref appDomain); + + if (compilerWrapper != null) + { + + compilerWrapper.OutputPath = OutputPath; + + compilerWrapper.TaskLogger = Log; + compilerWrapper.UnknownErrorID = UnknownErrorID; + compilerWrapper.XamlDebuggingInformation = XamlDebuggingInformation; + + compilerWrapper.TaskFileService = _taskFileService; + + if (OutputType.Equals(SharedStrings.Exe) || OutputType.Equals(SharedStrings.WinExe)) + { + compilerWrapper.ApplicationMarkup = localApplicationFile; + } + + compilerWrapper.References = referenceList; + + compilerWrapper.LocalizationDirectivesToLocFile = (int)_localizationDirectives; + + // This is for Pass2 compilation + compilerWrapper.DoCompilation(AssemblyName, Language, RootNamespace, localXamlPageFileList, true); + + // + // If no any xaml file with local-types wants to reference an internal type from + // current assembly and friend assembly, and InternalTypeHelperFile is set in the + // cache file, now it is the time to remove the content of InternalTypeHelper File. + // + // We still keep the empty file to make other parts of the build system happy. + // + if (!String.IsNullOrEmpty(_internalTypeHelperFile) && !compilerWrapper.HasInternals) + { + if (TaskFileService.Exists(_internalTypeHelperFile)) + { + // Make empty content for this file. + + MemoryStream memStream = new MemoryStream(); + + using (StreamWriter writer = new StreamWriter(memStream, new UTF8Encoding(false))) + { + writer.WriteLine(String.Empty); + writer.Flush(); + TaskFileService.WriteFile(memStream.ToArray(), _internalTypeHelperFile); + } + + Log.LogMessageFromResources(MessageImportance.Low, SRID.InternalTypeHelperNotRequired, _internalTypeHelperFile); + } + } + } + } + finally + { + if (compilerWrapper != null && compilerWrapper.ErrorTimes > 0) + { + _nErrors += compilerWrapper.ErrorTimes; + } + + if (appDomain != null) + { + AppDomain.Unload(appDomain); + compilerWrapper = null; + } + } + + } + + // + // Generate the required Output Items. + // + private void GenerateOutputItems( ) + { + // For the rest target types, + // Create the output lists for Baml files. + ArrayList bamlFileList = new ArrayList(); + string newSourceDir = SourceDir; // Just for calling GetResolvedFilePath + string relativeFile; + + if (_localApplicationFile != null) + { + TaskItem bamlItem; + + relativeFile = GetResolvedFilePath(_localApplicationFile.FilePath, ref newSourceDir); + + bamlItem = GenerateBamlItem(relativeFile, _localApplicationFile.Localizable, _localApplicationFile.LinkAlias, _localApplicationFile.LogicalName); + + if (bamlItem != null) + { + bamlFileList.Add(bamlItem); + + Log.LogMessageFromResources(MessageImportance.Low, SRID.LocalRefGeneratedBamlFile, bamlItem.ItemSpec); + } + } + + if (_localMarkupPages != null && _localMarkupPages.Length > 0) + { + + for (int i = 0; i < _localMarkupPages.Length; i++) + { + // add the baml file + LocalReferenceFile localRefFile = _localMarkupPages[i]; + + relativeFile = GetResolvedFilePath(localRefFile.FilePath, ref newSourceDir); + + TaskItem bamlItem = GenerateBamlItem(relativeFile, localRefFile.Localizable, localRefFile.LinkAlias, localRefFile.LogicalName); + + if (bamlItem != null) + { + bamlFileList.Add(bamlItem); + Log.LogMessageFromResources(MessageImportance.Low, SRID.LocalRefGeneratedBamlFile, bamlItem.ItemSpec); + } + } + } + + // Generate the Baml Output Item + GeneratedBaml = (ITaskItem[])bamlFileList.ToArray(typeof(ITaskItem)); + + } + + // + // Generate a baml TaskItem for the given xaml file, and transfer the appropriate + // source task item's custom attributes to the generated baml item if necessary. + // The xaml file could be an application definition file or a Markup Page + // + // Note: the xaml file must be resolved by calling GetResolvedFilePath( ) or + // CreatFullFilePath( ) before calling this method. + // + private TaskItem GenerateBamlItem(string resolvedXamlfile, bool localizable, string linkAlias, string logicalName) + { + TaskItem bamlItem = null; + + // + // For a given .xaml file (foo.xaml), there are below options for generated file: + // + // 1. A baml file with the same xaml file base name. foo.baml (such as page) + // 2. No baml file generated. such as logical component, + // or some simple Application definition xaml. + // + + string bamlFileName = Path.ChangeExtension(resolvedXamlfile, SharedStrings.BamlExtension); + + string bamlFile = OutputPath + bamlFileName; + + + if (TaskFileService.Exists(bamlFile)) + { + // + // Baml file exists. + // Generate a TaskItem for it. + // + + bamlItem = new TaskItem(); + bamlItem.ItemSpec = bamlFile; + + // Transfer the metadata value from source item to the generated baml item. + bamlItem.SetMetadata(SharedStrings.Localizable, localizable ? "True" : "False"); + bamlItem.SetMetadata(SharedStrings.Link, linkAlias); + bamlItem.SetMetadata(SharedStrings.LogicalName, logicalName); + } + + return bamlItem; + } + + + // + // Don't support local reference xaml compilation for netmodule type. + // + private bool IsSupportedOutputType(string outputType) + { + bool isSupported = false; + + switch (outputType) + { + case SharedStrings.Exe : + case SharedStrings.WinExe: + case SharedStrings.Library : + isSupported = true; + break; + default: + isSupported = false; + break; + } + + if (isSupported == false) + { + Log.LogErrorWithCodeFromResources(SRID.TargetIsNotSupported, outputType); + + // Keep the error numbers so that the task can stop immediatelly + // later when Execute( ) is called. + _nErrors++; + } + + return isSupported; + } + + #endregion Private Methods + + //------------------------------------------------------ + // + // Private Properties + // + //------------------------------------------------------ + + #region Private Properties + + // + // The root directory for the applicaiton project. + // + private string SourceDir + { + get { return _sourceDir; } + } + + #endregion Private Properties + + //------------------------------------------------------ + // + // Private Fields + // + //------------------------------------------------------ + + #region Private Fields + + private ITaskItem [] _references; + private string _outputType; + private string _assemblyName; + private string[] _assembliesGeneratedDuringBuild; + private string[] _knownReferencePaths; + private string _rootNamespace = String.Empty; + private bool _xamlDebuggingInformation = false; + + private bool _alwaysCompileMarkupFilesInSeparateDomain = true; + + private LocalizationDirectivesToLocFile _localizationDirectives = MS.Internal.LocalizationDirectivesToLocFile.None; + + private string _sourceDir; + private string _outputPath; + private string _language; + + private ITaskItem [] _generatedBaml; + + private int _nErrors; + + private CompilerLocalReference _compilerLocalRefCache; + private LocalReferenceFile _localApplicationFile = null; + private LocalReferenceFile[] _localMarkupPages = null; + private string _internalTypeHelperFile = String.Empty; + + private ITaskFileService _taskFileService; + + + private const string UnknownErrorID = "MC2000"; + + #endregion Private Fields + + } + + #endregion MarkupCompilePass2 Task class +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MergeLocalizationDirectives.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MergeLocalizationDirectives.cs new file mode 100644 index 00000000000..f45937dd440 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MergeLocalizationDirectives.cs @@ -0,0 +1,150 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: The task that merges all the localization directives files +// +//--------------------------------------------------------------------------- + + +using System; +using System.IO; +using System.Text; +using System.Xml; +using System.Runtime.InteropServices; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +using MS.Internal.Globalization; +using MS.Internal.Tasks; +using MS.Utility; // For SR + +// Since we disable PreSharp warnings in this file, we first need to disable warnings +// about unknown message numbers and unknown pragmas. +#pragma warning disable 1634, 1691 + +namespace Microsoft.Build.Tasks.Windows +{ + /// + /// This task merges the localization directives files of single bamls + /// into one file corresponding to for the compiled assembly. + /// + public sealed class MergeLocalizationDirectives : Task + { + //-------------------------------- + // Constructor + //-------------------------------- + /// + /// Default constructor of the task + /// + public MergeLocalizationDirectives() : base(SR.SharedResourceManager) + { + } + + //-------------------------------- + // Public methods + //-------------------------------- + + /// + /// Method invoked by MSBuild to merge localization files of single bamls to + /// one file for the whole Assembly. + /// + public override bool Execute() + { + TaskHelper.DisplayLogo(Log, SR.Get(SRID.MergeLocalizationDirectivesTask)); + if (GeneratedLocalizationFiles.Length > 0) + { + try { + + string absoluteFilePath = Path.Combine( + Directory.GetCurrentDirectory(), + _outputFile + ); + + using (StreamWriter streamWriter = new StreamWriter( + new FileStream(absoluteFilePath, FileMode.Create), + new UTF8Encoding(true) + ) + ) + { + + Log.LogMessageFromResources(SRID.CommentFileGenerating, _outputFile); + + streamWriter.WriteLine("<" + LocComments.LocDocumentRoot + ">"); + + // keep things simple and fast. Just keep appending the + // xml fragments that are already outputed. + foreach (ITaskItem item in GeneratedLocalizationFiles) + { + using (StreamReader locStreamReader = new StreamReader(item.ItemSpec)) + { + // directly concat Xml fragments + streamWriter.WriteLine(locStreamReader.ReadToEnd()); + } + } + + streamWriter.WriteLine(""); + Log.LogMessageFromResources(SRID.CommentFileGenerated, _outputFile); + } + } + catch (Exception e) + { + // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions. + if (e is NullReferenceException || e is SEHException) + { + throw; + } + else + { + Log.LogErrorFromException(e); + return false; + } + } +#pragma warning disable 6500 + catch // Non-CLS compliant errors + { + Log.LogErrorWithCodeFromResources(SRID.NonClsError); + return false; + } +#pragma warning restore 6500 + } + + return true; + } + + //-------------------------------- + // Public properties + //-------------------------------- + + /// + /// The list of localization directives files for individual Bamls. + /// + [Required] + public ITaskItem[] GeneratedLocalizationFiles + { + get { return _generatedLocalizationFiles; } + set { _generatedLocalizationFiles = value; } + } + + /// + /// The output path of the compiled assembly + /// + [Required] + [Output] + public string OutputFile + { + get { return _outputFile; } + set { _outputFile = value; } + } + + //--------------------------------- + // Private members + //--------------------------------- + private ITaskItem[] _generatedLocalizationFiles; + private string _outputFile; + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/ResourcesGenerator.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/ResourcesGenerator.cs new file mode 100644 index 00000000000..60acee86827 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/ResourcesGenerator.cs @@ -0,0 +1,446 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: An MSBuild task that generate .resources file from given +// resource files, .jpg, .ico, .baml, etc. +// +//--------------------------------------------------------------------------- + +using System; +using System.IO; +using System.Collections; + +using System.Globalization; +using System.Diagnostics; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +using MS.Utility; +using Microsoft.Build.Tasks.Windows; +using MS.Internal; +using MS.Internal.Tasks; + +// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler. +// We first need to disable warnings about unknown message numbers and unknown pragmas. +#pragma warning disable 1634, 1691 + +namespace Microsoft.Build.Tasks.Windows +{ + public sealed class ResourcesGenerator : Task + { + // We want to avoid holding file handles for arbitrary lengths of time, so we pass instances of this class + // to ResourceWriter which only opens the handle when it's being used. + // We use flags in ResourceWriter so that it will opportunistically dispose the stream. + // This has potential for delaying failures, but that's acceptable in this scenario. + private class LazyFileStream : Stream + { + private readonly string _sourcePath; + private FileStream _sourceStream; + + public LazyFileStream(string path) + { + _sourcePath = Path.GetFullPath(path); + } + + private Stream SourceStream + { + get + { + if (_sourceStream == null) + { + _sourceStream = new FileStream(_sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read); + + // limit size to System.Int32.MaxValue + long length = _sourceStream.Length; + if (length > (long)System.Int32.MaxValue) + { + throw new ApplicationException(SR.Get(SRID.ResourceTooBig, _sourcePath, System.Int32.MaxValue)); + } + + } + return _sourceStream; + } + } + + public override bool CanRead { get { return true; } } + + public override bool CanSeek { get { return true; } } + + public override bool CanWrite { get { return false; } } + + public override void Flush() {} + + public override long Length + { + get { return SourceStream.Length; } + } + + public override long Position + { + get { return SourceStream.Position; } + set { SourceStream.Position = value; } + } + + public override int Read(byte[] buffer, int offset, int count) + { + return SourceStream.Read(buffer, offset, count); + } + + public override long Seek(long offset, SeekOrigin origin) + { + return SourceStream.Seek(offset, origin); + } + + public override void SetLength(long value) + { + // This is backed by a readonly file. + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + // This is backed by a readonly file. + throw new NotSupportedException(); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (null != _sourceStream) + { + _sourceStream.Dispose(); + _sourceStream = null; + } + } + } + } + + //------------------------------------------------------ + // + // Constructors + // + //------------------------------------------------------ + + #region Constructors + + public ResourcesGenerator ( ) + : base(SR.SharedResourceManager) + { + // set the source directory + SourceDir = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar; + } + + #endregion Constructors + + + //------------------------------------------------------ + // + // Public Methods + // + //------------------------------------------------------ + + #region Public Methods + + public override bool Execute() + { + TaskHelper.DisplayLogo(Log, SR.Get(SRID.ResourcesGeneratorTask)); + + // + // Validate the property settings + // + + if (ValidResourceFiles(ResourceFiles) == false) + { + // ValidResourceFiles has already showed up error message. + // Just stop here. + return false; + } + + if (OutputResourcesFile != null && OutputResourcesFile.Length > 1) + { + // Every task should generate only one .resources. + Log.LogErrorWithCodeFromResources(SRID.MoreResourcesFiles); + return false; + } + + try + { + // create output directory + if (!Directory.Exists(OutputPath)) + { + Directory.CreateDirectory(OutputPath); + } + + string resourcesFile = OutputResourcesFile[0].ItemSpec; + + Log.LogMessageFromResources(MessageImportance.Low, SRID.ResourcesGenerating, resourcesFile); + + // Go through all the files and create a resources file. + using (var resWriter = new ResourceWriter(resourcesFile)) + { + foreach (var resourceFile in ResourceFiles) + { + string resFileName = resourceFile.ItemSpec; + string resourceId = GetResourceIdForResourceFile(resourceFile); + + // We're handing off lifetime management for the stream. + // True for the third argument tells resWriter to dispose of the stream when it's done. + resWriter.AddResource(resourceId, new LazyFileStream(resFileName), true); + + Log.LogMessageFromResources(MessageImportance.Low, SRID.ReadResourceFile, resFileName); + Log.LogMessageFromResources(MessageImportance.Low, SRID.ResourceId, resourceId); + + } + // Generate the .resources file. + resWriter.Generate(); + } + + Log.LogMessageFromResources(MessageImportance.Low, SRID.ResourcesGenerated, resourcesFile); + } + catch (Exception e) + { + // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions. + if (e is NullReferenceException || e is SEHException) + { + throw; + } + else + { + string message; + string errorId = Log.ExtractMessageCode(e.Message, out message); + + if (string.IsNullOrEmpty(errorId)) + { + errorId = UnknownErrorID; + message = SR.Get(SRID.UnknownBuildError, message); + } + + Log.LogError(null, errorId, null, null, 0, 0, 0, 0, message, null); + return false; + } + } +#pragma warning disable 6500 + catch // Non-cls compliant errors + { + Log.LogErrorWithCodeFromResources(SRID.NonClsError); + return false; + } +#pragma warning restore 6500 + + return true; + } + + #endregion Public Methods + + //------------------------------------------------------ + // + // Public Properties + // + //------------------------------------------------------ + + #region Public Properties + + /// + /// Image or baml files which will be embedded into Resources File + /// + [Required] + public ITaskItem [] ResourceFiles { get; set; } + + /// + /// The directory where the generated resources file lives. + /// + [Required] + public string OutputPath + { + get { return _outputPath; } + set + { + _outputPath = Path.GetFullPath(value); + + if (!_outputPath.EndsWith((Path.DirectorySeparatorChar).ToString(), StringComparison.Ordinal)) + _outputPath += Path.DirectorySeparatorChar; + } + } + + /// + /// Generated resources file. This is a required input item. + /// Every task should generate only one .resource file. + /// If the resource is for a specific culture, the ItemSpec should have syntax like + /// Filebasename.$(Culture).resources. + /// + /// The file path should also include OutputPath. + /// + [Output] + [Required] + public ITaskItem [] OutputResourcesFile { get; set; } + + #endregion Public Properties + + //------------------------------------------------------ + // + // Private Methods + // + //------------------------------------------------------ + + #region Private Methods + + /// + /// Check if the passed files have valid path + /// + /// + /// + private bool ValidResourceFiles(ITaskItem[] inputFiles) + { + bool bValid = true; + + foreach (ITaskItem inputFile in inputFiles) + { + string strFileName; + + strFileName = inputFile.ItemSpec; + + if (!File.Exists(TaskHelper.CreateFullFilePath(strFileName, SourceDir))) + { + bValid = false; + Log.LogErrorWithCodeFromResources(SRID.FileNotFound, strFileName); + } + } + + return bValid; + } + + + /// + /// Return the correct resource id for the passed resource file path. + /// + /// Resource File Path + /// the resource id + private string GetResourceIdForResourceFile(ITaskItem resFile) + { + bool requestExtensionChange = true; + + return GetResourceIdForResourceFile( + resFile.ItemSpec, + resFile.GetMetadata(SharedStrings.Link), + resFile.GetMetadata(SharedStrings.LogicalName), + OutputPath, + SourceDir, + requestExtensionChange); + } + + internal static string GetResourceIdForResourceFile( + string filePath, + string linkAlias, + string logicalName, + string outputPath, + string sourceDir, + bool requestExtensionChange) + { + string relPath = String.Empty; + + // Please note the subtle distinction between and . + // is treated as a fully resolvable path and is put through the same + // transformations as the original file path. on the other hand + // is treated as an alias for the given resource and is used as is. Whether + // was meant to be treated thus is debatable. Nevertheless in .Net 4.5 it would + // amount to a breaking change to have to change the behavior of and + // hence the choice to support with the desired semantics. All + // said in most of the regular scenarios using or will result in + // the same resourceId being picked. + + if (!String.IsNullOrEmpty(logicalName)) + { + // Use the LogicalName when there is one + logicalName = ReplaceXAMLWithBAML(filePath, logicalName, requestExtensionChange); + relPath = logicalName; + } + else + { + // Always use the Link tag if it's specified. + // This is the way the resource appears in the project. + linkAlias = ReplaceXAMLWithBAML(filePath, linkAlias, requestExtensionChange); + filePath = !string.IsNullOrEmpty(linkAlias) ? linkAlias : filePath; + string fullFilePath = Path.GetFullPath(filePath); + + // + // If the resFile, or it's perceived path, is relative to the StagingDir + // (OutputPath here) take the relative path as resource id. + // If the resFile is not relative to StagingDir, but relative + // to the project directory, take this relative path as resource id. + // Otherwise, just take the file name as resource id. + // + + relPath = TaskHelper.GetRootRelativePath(outputPath, fullFilePath); + + if (string.IsNullOrEmpty(relPath)) + { + relPath = TaskHelper.GetRootRelativePath(sourceDir, fullFilePath); + } + + if (string.IsNullOrEmpty(relPath)) + { + relPath = Path.GetFileName(fullFilePath); + } + } + + // Modify resource ID to correspond to canonicalized Uri format + // i.e. - all lower case, use "/" as separator + // ' ' is converted to escaped version %20 + // + + string resourceId = ResourceIDHelper.GetResourceIDFromRelativePath(relPath); + + return resourceId; + } + + private static string ReplaceXAMLWithBAML(string sourceFilePath, string path, bool requestExtensionChange) + { + if (requestExtensionChange && + Path.GetExtension(sourceFilePath).Equals(SharedStrings.BamlExtension) && + Path.GetExtension(path).Equals(SharedStrings.XamlExtension)) + { + // Replace the path extension to baml only if the source file path is baml + path = Path.ChangeExtension(path, SharedStrings.BamlExtension); + } + + return path; + } + + #endregion Private Methods + //------------------------------------------------------ + // + // Private Properties + // + //------------------------------------------------------ + + #region Private Properties + + private string SourceDir { get; set; } + + #endregion Private Properties + + //------------------------------------------------------ + // + // Private Fields + // + //------------------------------------------------------ + + #region Private Fields + + private string _outputPath; + + private const string UnknownErrorID = "RG1000"; + + #endregion Private Fields + + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/UidManager.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/UidManager.cs new file mode 100644 index 00000000000..d7a7ddedb63 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/UidManager.cs @@ -0,0 +1,1361 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: +// +// Adds, updates or checks validity of Uids (Unique identifiers) +// on all XAML elements in XAML files. +// +//--------------------------------------------------------------------------- + + +using System; +using System.Xml; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.InteropServices; + +using MS.Internal.Markup; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +using MS.Utility; // For SR +using MS.Internal.Tasks; + +// Since we disable PreSharp warnings in this file, we first need to disable warnings about unknown message numbers and unknown pragmas. +#pragma warning disable 1634, 1691 + +namespace Microsoft.Build.Tasks.Windows +{ + /// + /// An MSBuild task that checks or corrects unique identifiers in + /// XAML markup. + /// + public sealed class UidManager : Task + { + //------------------------------------------------------ + // + // Constructors + // + //------------------------------------------------------ + + #region Constructors + + /// + /// Create a UidManager object. + /// + public UidManager() : base(SR.SharedResourceManager) + { + _backupPath = Directory.GetCurrentDirectory(); + } + + #endregion + + //------------------------------------------------------ + // + // Public Methods + // + //------------------------------------------------------ + + #region Public Methods + + /// + /// The method invoked by MSBuild to check or correct Uids. + /// + public override bool Execute() + { + TaskHelper.DisplayLogo(Log, SR.Get(SRID.UidManagerTask)); + + if (MarkupFiles == null || MarkupFiles.Length == 0) + { + Log.LogErrorWithCodeFromResources(SRID.SourceFileNameNeeded); + return false; + } + + try + { + _task = (UidTask)Enum.Parse(typeof(UidTask), _taskAsString); + } + catch (ArgumentException) + { + Log.LogErrorWithCodeFromResources(SRID.BadUidTask, _taskAsString); + return false; + } + + + bool allFilesOk; + try + { + allFilesOk = ManageUids(); + } + catch (Exception e) + { + // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions. + if (e is NullReferenceException || e is SEHException) + { + throw; + } + else + { + string message; + string errorId; + + errorId = Log.ExtractMessageCode(e.Message, out message); + + if (String.IsNullOrEmpty(errorId)) + { + errorId = UnknownErrorID; + message = SR.Get(SRID.UnknownBuildError, message); + } + + Log.LogError(null, errorId, null, null, 0, 0, 0, 0, message, null); + + allFilesOk = false; + } + } +#pragma warning disable 6500 + catch // Non-CLS compliant errors + { + Log.LogErrorWithCodeFromResources(SRID.NonClsError); + allFilesOk = false; + } +#pragma warning restore 6500 + + return allFilesOk; + } + + #endregion + + //------------------------------------------------------ + // + // Public Properties + // + //------------------------------------------------------ + + #region Public Properties + /// + /// The markup file(s) to be checked or updated. + /// + [Required] + public ITaskItem[] MarkupFiles + { + get { return _markupFiles; } + set { _markupFiles = value; } + } + + /// + /// The directory for intermedia files + /// + /// + /// + public string IntermediateDirectory + { + get { return _backupPath; } + set + { + string sourceDir = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar; + _backupPath = TaskHelper.CreateFullFilePath(value, sourceDir); + } + } + + + /// + /// Enum to determine which Uid management task to undertake + /// + private enum UidTask + { + + /// + /// Uid managment task to check validity of Uids + /// + Check = 0, + + /// + /// Uid managment task to Update Uids to a valid state + /// + Update = 1, + + /// + /// Uid managment task to remove all Uids + /// + Remove = 2, + } + + /// + /// Uid management task required + /// + [Required] + public string Task + { + get { return _taskAsString; } + set { _taskAsString = value; } + } + + #endregion + + //------------------------------------------------------ + // + // Private Methods + // + //------------------------------------------------------ + + private bool ManageUids() + { + int countGoodFiles = 0; + // enumerate through each file + foreach (ITaskItem inputFile in _markupFiles) + { + Log.LogMessageFromResources(SRID.CheckingUids, inputFile.ItemSpec); + switch (_task) + { + case UidTask.Check: + { + UidCollector collector = ParseFile(inputFile.ItemSpec); + + bool success = VerifyUid( + collector, // uid collector + true // log error + ); + + if (success) countGoodFiles++; + break; + } + case UidTask.Update: + { + UidCollector collector = ParseFile(inputFile.ItemSpec); + + bool success = VerifyUid( + collector, // uid collector + false // log error + ); + + if (!success) + { + if (SetupBackupDirectory()) + { + // resolve errors + collector.ResolveUidErrors(); + + // temp file to write to + string tempFile = GetTempFileName(inputFile.ItemSpec); + + // backup file of the source file before it is overwritten. + string backupFile = GetBackupFileName(inputFile.ItemSpec); + + using (Stream uidStream = new FileStream(tempFile, FileMode.Create)) + { + using (Stream source = File.OpenRead(inputFile.ItemSpec)) + { + UidWriter writer = new UidWriter(collector, source, uidStream); + writer.UpdateUidWrite(); + } + } + + // backup source file by renaming it. Expect to be (close to) atomic op. + RenameFile(inputFile.ItemSpec, backupFile); + + // rename the uid output onto the source file. Expect to be (close to) atomic op. + RenameFile(tempFile, inputFile.ItemSpec); + + // remove the temp files + RemoveFile(tempFile); + RemoveFile(backupFile); + + countGoodFiles++; + } + } + else + { + // all uids are good. No-op + countGoodFiles++; + } + + break; + } + case UidTask.Remove: + { + UidCollector collector = ParseFile(inputFile.ItemSpec); + + bool hasUid = false; + for (int i = 0; i < collector.Count; i++) + { + if (collector[i].Status != UidStatus.Absent) + { + hasUid = true; + break; + } + } + + if (hasUid) + { + if (SetupBackupDirectory()) + { + // temp file to write to + string tempFile = GetTempFileName(inputFile.ItemSpec); + + // backup file of the source file before it is overwritten. + string backupFile = GetBackupFileName(inputFile.ItemSpec); + + using (Stream uidStream = new FileStream(tempFile, FileMode.Create)) + { + using (Stream source = File.OpenRead(inputFile.ItemSpec)) + { + UidWriter writer = new UidWriter(collector, source, uidStream); + writer.RemoveUidWrite(); + } + } + + // rename the source file to the backup file name. Expect to be (close to) atomic op. + RenameFile(inputFile.ItemSpec, backupFile); + + // rename the output file over to the source file. Expect to be (close to) atomic op. + RenameFile(tempFile, inputFile.ItemSpec); + + // remove the temp files + RemoveFile(tempFile); + RemoveFile(backupFile); + + countGoodFiles++; + } + } + else + { + // There is no Uid in the file. No need to do remove. + countGoodFiles++; + } + + break; + } + } + } + + // spew out the overral log info for the task + switch (_task) + { + case UidTask.Remove: + Log.LogMessageFromResources(SRID.FilesRemovedUid, countGoodFiles); + break; + + case UidTask.Update: + Log.LogMessageFromResources(SRID.FilesUpdatedUid, countGoodFiles); + break; + + case UidTask.Check: + Log.LogMessageFromResources(SRID.FilesPassedUidCheck, countGoodFiles); + + if (_markupFiles.Length > countGoodFiles) + { + Log.LogErrorWithCodeFromResources(SRID.FilesFailedUidCheck, _markupFiles.Length - countGoodFiles); + } + break; + } + + return _markupFiles.Length == countGoodFiles; + } + + + private string GetTempFileName(string fileName) + { + return Path.Combine(_backupPath, Path.ChangeExtension(Path.GetFileName(fileName), "uidtemp")); + } + + private string GetBackupFileName (string fileName) + { + return Path.Combine(_backupPath, Path.ChangeExtension(Path.GetFileName(fileName), "uidbackup")); + } + + private void RenameFile(string src, string dest) + { + RemoveFile(dest); + File.Move(src, dest); + } + + private void RemoveFile(string fileName) + { + if (File.Exists(fileName)) + { + File.Delete(fileName); + } + } + + private bool SetupBackupDirectory() + { + try + { + if (!Directory.Exists(_backupPath)) + { + Directory.CreateDirectory(_backupPath); + } + + return true; + } + catch (Exception e) + { + // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions. + if (e is NullReferenceException || e is SEHException) + { + throw; + } + else + { + Log.LogErrorWithCodeFromResources(SRID.IntermediateDirectoryError, _backupPath); + return false; + } + } +#pragma warning disable 6500 + catch // Non-cls compliant errors + { + Log.LogErrorWithCodeFromResources(SRID.IntermediateDirectoryError, _backupPath); + return false; + } +#pragma warning restore 6500 + } + + + + + /// + /// Verify the Uids in the file + /// + /// UidCollector containing all Uid instances + /// true to log errors while verifying + /// true indicates no errors + private bool VerifyUid( + UidCollector collector, + bool logError + ) + { + bool errorFound = false; + + for (int i = 0; i < collector.Count; i++) + { + Uid currentUid = collector[i]; + if (currentUid.Status == UidStatus.Absent) + { + // Uid missing + if (logError) + { + Log.LogErrorWithCodeFromResources( + null, + collector.FileName, + currentUid.LineNumber, + currentUid.LinePosition, + 0, 0, + SRID.UidMissing, currentUid.ElementName + ); + } + + errorFound = true; + } + else if (currentUid.Status == UidStatus.Duplicate) + { + // Uid duplicates + if (logError) + { + Log.LogErrorWithCodeFromResources( + null, + collector.FileName, + currentUid.LineNumber, + currentUid.LinePosition, + 0, 0, + SRID.MultipleUidUse, currentUid.Value, currentUid.ElementName + ); + + } + + errorFound = true; + } + + } + + return !errorFound; + } + + /// + /// Parse the input file and get all the information of Uids + /// + /// input file + /// UidCollector containing all the information for the Uids in the file + private UidCollector ParseFile(string fileName) + { + UidCollector collector = new UidCollector(fileName ); + + using (Stream xamlStream = File.OpenRead(fileName)) + { + XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); + XmlParserContext context = new XmlParserContext( + null, // nametable + nsmgr, // namespace manager + null, // xml:Lang scope + XmlSpace.Default // XmlSpace + ); + + XmlTextReader reader = new XmlTextReader( + xamlStream, // xml stream + XmlNodeType.Document, // parsing document + context // parser context + ); + + while (reader.Read()) + { + switch (reader.NodeType) + { + case XmlNodeType.Element : + { + if (collector.RootElementLineNumber < 0) + { + collector.RootElementLineNumber = reader.LineNumber; + collector.RootElementLinePosition = reader.LinePosition; + } + + if (reader.Name.IndexOf('.') >= 0) + { + // the name has a dot, which suggests it is a property tag. + // we will ignore adding uid + continue; + } + + Uid currentUid = new Uid( + reader.LineNumber, + reader.LinePosition + reader.Name.Length, + reader.Name, + SpaceInsertion.BeforeUid // insert space before the Uid + ); ; + + if (reader.HasAttributes) + { + reader.MoveToNextAttribute(); + + // As a heuristic to better preserve the source file, add uid to the place of the + // first attribute + currentUid.LineNumber = reader.LineNumber; + currentUid.LinePosition = reader.LinePosition; + currentUid.Space = SpaceInsertion.AfterUid; + + do + { + string namespaceUri = nsmgr.LookupNamespace(reader.Prefix); + + if (reader.LocalName == XamlReaderHelper.DefinitionUid + && namespaceUri == XamlReaderHelper.DefinitionNamespaceURI) + { + // found x:Uid attribute, store the actual value and position + currentUid.Value = reader.Value; + currentUid.LineNumber = reader.LineNumber; + currentUid.LinePosition = reader.LinePosition; + } + else if (reader.LocalName == "Name" + && namespaceUri == XamlReaderHelper.DefaultNamespaceURI) + { + // found Name attribute, store the Name value + currentUid.FrameworkElementName = reader.Value; + } + else if (reader.LocalName == "Name" + && namespaceUri == XamlReaderHelper.DefinitionNamespaceURI) + { + // found x:Name attribute, store the Name value + currentUid.FrameworkElementName = reader.Value; + } + else if (reader.Prefix == "xmlns") + { + // found a namespace declaration, store the namespace prefix + // so that when we need to add a new namespace declaration later + // we won't reuse the namespace prefix. + collector.AddNamespacePrefix(reader.LocalName); + } + } + while (reader.MoveToNextAttribute()); + + } + + if (currentUid.Value == null) + { + // there is no x:Uid found on this element, we need to resolve the + // namespace prefix in order to add the Uid + string prefix = nsmgr.LookupPrefix(XamlReaderHelper.DefinitionNamespaceURI); + if (prefix != string.Empty) + currentUid.NamespacePrefix = prefix; + } + + collector.AddUid(currentUid); + break; + } + } + } + } + + return collector; + } + + //----------------------------------- + // Private members + //----------------------------------- + private UidTask _task; // task + private ITaskItem[] _markupFiles; // input Xaml files + private string _taskAsString; // task string + private string _backupPath; // path to store to backup source Xaml files + private const string UnknownErrorID = "UM1000"; + } + + // represent all the information about a Uid + // The uid may be valid, absent, or duplicate + internal sealed class Uid + { + internal Uid( + int lineNumber, + int linePosition, + string elementName, + SpaceInsertion spaceInsertion + ) + { + LineNumber = lineNumber; + LinePosition = linePosition; + ElementName = elementName; + Value = null; + NamespacePrefix = null; + FrameworkElementName = null; + Status = UidStatus.Valid; + Space = spaceInsertion; + + } + + internal int LineNumber; // Referenced line number of the original document + internal int LinePosition; // Reference line position of the original document + internal string ElementName; // name of the element that needs this uid + internal SpaceInsertion Space; // Insert a space before/after the Uid + + internal string Value; // value of the uid + internal string NamespacePrefix; // namespace prefix for the uid + internal string FrameworkElementName; // the FrameworkElement.Name of element + internal UidStatus Status; // the status of the this uid + + } + + internal enum UidStatus : byte + { + Valid = 0, // uid is valid + Absent = 1, // uid is absent + Duplicate = 2, // uid is duplicated + } + + internal enum SpaceInsertion : byte + { + BeforeUid, // Insert a space before the Uid + AfterUid // Insert a space after the Uid + } + + // a class collects all the information about Uids per file + internal sealed class UidCollector + { + public UidCollector(string fileName) + { + _uids = new List(32); + _namespacePrefixes = new List(2); + _uidTable = new Hashtable(); + _fileName = fileName; + _sequenceMaxIds = new Hashtable(); + } + + // remembering all the namespace prefixes in the file + // in case we need to add a new definition namespace declaration + public void AddNamespacePrefix(string prefix) + { + _namespacePrefixes.Add(prefix); + } + + // add the uid to the collector + public void AddUid(Uid uid) + { + _uids.Add(uid); + + // set the uid status according to the raw data + if (uid.Value == null) + { + uid.Status = UidStatus.Absent; + } + else if (_uidTable.Contains(uid.Value)) + { + uid.Status = UidStatus.Duplicate; + } + else + { + // valid uid, store it + StoreUid(uid.Value); + } + } + + public void ResolveUidErrors() + { + for (int i = 0; i < _uids.Count; i++) + { + Uid currentUid = _uids[i]; + + if ( currentUid.Status == UidStatus.Absent + && currentUid.NamespacePrefix == null + && _namespacePrefixForMissingUid == null) + { + // there is Uid not in scope of any definition namespace + // we will need to generate a new namespace prefix for them + _namespacePrefixForMissingUid = GeneratePrefix(); + } + + if (currentUid.Status != UidStatus.Valid) + { + // resolve invalid uids + currentUid.Value = GetAvailableUid(currentUid); + } + } + } + + public int RootElementLineNumber + { + get { return _rootElementLineNumber; } + set { _rootElementLineNumber = value; } + } + + public int RootElementLinePosition + { + get { return _rootElementLinePosition; } + set { _rootElementLinePosition = value; } + } + + public string FileName + { + get { return _fileName; } + } + + public Uid this[int index] + { + get + { + return _uids[index]; + } + } + + public int Count + { + get { return _uids.Count; } + } + + public string NamespaceAddedForMissingUid + { + get { return _namespacePrefixForMissingUid; } + } + + + //------------------------------------- + // Private methods + //------------------------------------- + private void StoreUid(string value) + { + // we just want to check for existence, so storing a null + _uidTable[value] = null; + + string uidSequence; + Int64 index; + + ParseUid(value, out uidSequence, out index); + if (uidSequence != null) + { + if (_sequenceMaxIds.Contains(uidSequence)) + { + Int64 maxIndex = (Int64)_sequenceMaxIds[uidSequence]; + if (maxIndex < index) + { + _sequenceMaxIds[uidSequence] = index; + } + } + else + { + _sequenceMaxIds[uidSequence] = index; + } + } + } + + private string GetAvailableUid(Uid uid) + { + string availableUid; + + // copy the ID if available + if (uid.FrameworkElementName != null + && (!_uidTable.Contains(uid.FrameworkElementName)) + ) + { + availableUid = uid.FrameworkElementName; + } + else + { + // generate a new id + string sequence = GetElementLocalName(uid.ElementName); + Int64 index; + + if (_sequenceMaxIds.Contains(sequence)) + { + index = (Int64) _sequenceMaxIds[sequence]; + + if (index == Int64.MaxValue) + { + // this sequence reaches the max + // we fallback to create a new sequence + index = -1; + while (index < 0) + { + sequence = (_uidSequenceFallbackCount == 0) ? + UidFallbackSequence + : UidFallbackSequence + _uidSequenceFallbackCount; + + if (_sequenceMaxIds.Contains(sequence)) + { + index = (Int64) _sequenceMaxIds[sequence]; + if (index < Int64.MaxValue) + { + // found the fallback sequence with valid index + index ++; + break; + } + } + else + { + // create a new sequence from 1 + index = 1; + break; + } + + _uidSequenceFallbackCount ++; + } + } + else + { + index ++; + } + } + else + { + // a new sequence + index = 1; + } + + availableUid = sequence + UidSeparator + index; + } + + // store the uid so that it won't be used again + StoreUid(availableUid); + return availableUid; + } + + private void ParseUid(string uid, out string prefix, out Int64 index) + { + // set prefix and index to invalid values + prefix = null; + index = -1; + + if (uid == null) return; + + int separatorIndex = uid.LastIndexOf(UidSeparator); + if (separatorIndex > 0) + { + string suffix = uid.Substring(separatorIndex + 1); + + // Disable Presharp warning 6502 : catch block shouldn't have empty body + #pragma warning disable 6502 + try { + index = Int64.Parse(suffix, TypeConverterHelper.InvariantEnglishUS); + prefix = uid.Substring(0, separatorIndex); + } + catch (FormatException) + { + // wrong format + } + catch (OverflowException) + { + // not acceptable uid + } + #pragma warning restore 6502 + } + } + + private string GetElementLocalName(string typeFullName) + { + int index = typeFullName.LastIndexOf('.'); + if (index > 0) + { + return typeFullName.Substring(index + 1); + } + else + { + return typeFullName; + } + } + + private string GeneratePrefix() + { + Int64 ext = 1; + string prefix = UidNamespaceAbbreviation.ToString(TypeConverterHelper.InvariantEnglishUS); + + // Disable Presharp warning 6502 : catch block shouldn't have empty body + #pragma warning disable 6502 + try + { + // find a prefix that is not used in the Xaml + // from x1, x2, ... x[n] + while (_namespacePrefixes.Contains(prefix)) + { + prefix = UidNamespaceAbbreviation + ext.ToString(TypeConverterHelper.InvariantEnglishUS); + ext++; + } + return prefix; + } + catch (OverflowException) + { + } + #pragma warning restore 6502 + + // if overflows, (extreamly imposible), we will return a guid as the prefix + return Guid.NewGuid().ToString(); + } + + private List _uids; + private Hashtable _uidTable; + private string _fileName; + private Hashtable _sequenceMaxIds; + private List _namespacePrefixes; + private int _rootElementLineNumber = -1; + private int _rootElementLinePosition = -1; + private string _namespacePrefixForMissingUid = null; + private int _uidSequenceFallbackCount = 0; + + private const char UidNamespaceAbbreviation = 'x'; + private const char UidSeparator = '_'; + private const string UidFallbackSequence = "_Uid"; + } + + + // writing to a file, removing or updating uid + internal sealed class UidWriter + { + internal UidWriter(UidCollector collector, Stream source, Stream target) + { + _collector = collector; + _sourceReader = new StreamReader(source); + + UTF8Encoding encoding = new UTF8Encoding(true); + _targetWriter = new StreamWriter(target, encoding); + _lineBuffer = new LineBuffer(_sourceReader.ReadLine()); + } + + // write to target stream and update uids + internal bool UpdateUidWrite() + { + try { + // we need to add a new namespace + if (_collector.NamespaceAddedForMissingUid != null) + { + // write to the beginning of the root element + WriteTillSourcePosition( + _collector.RootElementLineNumber, + _collector.RootElementLinePosition + ); + + WriteElementTag(); + WriteSpace(); + WriteNewNamespace(); + } + + for (int i = 0; i < _collector.Count; i++) + { + Uid currentUid = _collector[i]; + WriteTillSourcePosition(currentUid.LineNumber, currentUid.LinePosition); + + if (currentUid.Status == UidStatus.Absent) + { + + if (currentUid.Space == SpaceInsertion.BeforeUid) + { + WriteSpace(); + } + + WriteNewUid(currentUid); + + if (currentUid.Space == SpaceInsertion.AfterUid) + { + WriteSpace(); + } + } + else if (currentUid.Status == UidStatus.Duplicate) + { + ProcessAttributeStart(WriterAction.Write); + SkipSourceAttributeValue(); + WriteNewAttributeValue(currentUid.Value); + } + } + WriteTillEof(); + return true; + } + catch (Exception e) + { + // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions. + if (e is NullReferenceException || e is SEHException) + { + throw; + } + + return false; + } +#pragma warning disable 6500 + catch + { + return false; + } +#pragma warning restore 6500 + } + + // writing to the target stream removing uids + internal bool RemoveUidWrite() + { + try { + for (int i = 0; i < _collector.Count; i++) + { + Uid currentUid = _collector[i]; + + // skipping valid and duplicate uids. + if ( currentUid.Status == UidStatus.Duplicate + || currentUid.Status == UidStatus.Valid) + { + // write till the space in front of the Uid + WriteTillSourcePosition(currentUid.LineNumber, currentUid.LinePosition - 1); + + // skip the uid + ProcessAttributeStart(WriterAction.Skip); + SkipSourceAttributeValue(); + } + } + + WriteTillEof(); + return true; + } + catch (Exception e) + { + // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions. + if (e is NullReferenceException || e is SEHException) + { + throw; + } + + return false; + } +#pragma warning disable 6500 + catch + { + return false; + } +#pragma warning restore 6500 + } + + private void WriteTillSourcePosition(int lineNumber, int linePosition) + { + // write to the correct line + while (_currentLineNumber < lineNumber) + { + // write out the line buffer + _targetWriter.WriteLine(_lineBuffer.ReadToEnd()); + _currentLineNumber++; + _currentLinePosition = 1; + + // read one more line + _lineBuffer.SetLine(_sourceReader.ReadLine()); + } + + // write to the correct line position + while (_currentLinePosition < linePosition) + { + _targetWriter.Write(_lineBuffer.Read()); + _currentLinePosition++; + } + + } + + private void WriteElementTag() + { + if (_lineBuffer.EOL) + { + // advance to the non-empty line + AdvanceTillNextNonEmptyLine(WriterAction.Write); + } + + char ch = _lineBuffer.Peek(); + + // stop when we see space, "/" or ">". That is the end of the + // element name + while (!Char.IsWhiteSpace(ch) + && ch != '/' + && ch != '>' + ) + { + _targetWriter.Write(ch); + + _currentLinePosition++; + _lineBuffer.Read(); + if (_lineBuffer.EOL) + { + AdvanceTillNextNonEmptyLine(WriterAction.Write); + } + + ch = _lineBuffer.Peek(); + } + } + + private void WriteNewUid(Uid uid) + { + // construct the attribute name, e.g. x:Uid + // "x" will be the resolved namespace prefix for the definition namespace + string attributeName = + (uid.NamespacePrefix == null) ? + _collector.NamespaceAddedForMissingUid + ":" + XamlReaderHelper.DefinitionUid + : uid.NamespacePrefix + ":" + XamlReaderHelper.DefinitionUid; + + // escape all the Xml entities in the value + string attributeValue = EscapedXmlEntities.Replace( + uid.Value, + EscapeMatchEvaluator + ); + + string clause = string.Format( + TypeConverterHelper.InvariantEnglishUS, + "{0}=\"{1}\"", + attributeName, + attributeValue + ); + + _targetWriter.Write(clause); + } + + private void WriteNewNamespace() + { + string clause = string.Format( + TypeConverterHelper.InvariantEnglishUS, + "xmlns:{0}=\"{1}\"", + _collector.NamespaceAddedForMissingUid, + XamlReaderHelper.DefinitionNamespaceURI + ); + + _targetWriter.Write(clause); + } + + private void WriteNewAttributeValue(string value) + { + string attributeValue = EscapedXmlEntities.Replace( + value, + EscapeMatchEvaluator + ); + + _targetWriter.Write( + string.Format( + TypeConverterHelper.InvariantEnglishUS, + "\"{0}\"", + value + ) + ); + } + + private void WriteSpace() + { + // insert a space + _targetWriter.Write(" "); + } + + private void WriteTillEof() + { + _targetWriter.WriteLine(_lineBuffer.ReadToEnd()); + _targetWriter.Write(_sourceReader.ReadToEnd()); + _targetWriter.Flush(); + } + + private void SkipSourceAttributeValue() + { + char ch = (char) 0; + + // read to the start quote of the attribute value + while (ch != '\"' && ch != '\'') + { + if (_lineBuffer.EOL) + { + AdvanceTillNextNonEmptyLine(WriterAction.Skip); + } + + ch = _lineBuffer.Read(); + _currentLinePosition ++; + } + + char attributeValueStart = ch; + // read to the end quote of the attribute value + ch = (char) 0; + while (ch != attributeValueStart) + { + if (_lineBuffer.EOL) + { + AdvanceTillNextNonEmptyLine(WriterAction.Skip); + } + + ch = _lineBuffer.Read(); + _currentLinePosition ++; + } + } + + private void AdvanceTillNextNonEmptyLine(WriterAction action) + { + do + { + if (action == WriterAction.Write) + { + _targetWriter.WriteLine(); + } + + _lineBuffer.SetLine(_sourceReader.ReadLine()); + _currentLineNumber++; + _currentLinePosition = 1; + + } while (_lineBuffer.EOL); + } + + + private void ProcessAttributeStart(WriterAction action) + { + if (_lineBuffer.EOL) + { + AdvanceTillNextNonEmptyLine(action); + } + + char ch; + do + { + ch = _lineBuffer.Read(); + + if (action == WriterAction.Write) + { + _targetWriter.Write(ch); + } + + _currentLinePosition++; + + if (_lineBuffer.EOL) + { + AdvanceTillNextNonEmptyLine(action); + } + + } while (ch != '='); + } + + // + // source position in a file starts from (1,1) + // + + private int _currentLineNumber = 1; // current line number in the source stream + private int _currentLinePosition = 1; // current line position in the source stream + private LineBuffer _lineBuffer; // buffer for one line's content + + private UidCollector _collector; + private StreamReader _sourceReader; + private StreamWriter _targetWriter; + + // + // buffer for the content of a line + // The UidWriter always reads one line at a time from the source + // and store the line in this buffer. + // + private sealed class LineBuffer + { + private int Index; + private string Content; + + public LineBuffer(string line) + { + SetLine(line); + } + + public void SetLine(string line) + { + Content = (line == null) ? string.Empty : line; + Index = 0; + } + + public bool EOL + { + get { return (Index == Content.Length); } + } + + public char Read() + { + if (!EOL) + { + return Content[Index++]; + } + + throw new InvalidOperationException(); + } + + public char Peek() + { + if (!EOL) + { + return Content[Index]; + } + + throw new InvalidOperationException(); + } + + public string ReadToEnd() + { + if (!EOL) + { + int temp = Index; + Index = Content.Length; + + return Content.Substring(temp); + } + + return string.Empty; + } + } + + private enum WriterAction + { + Write = 0, // write the content + Skip = 1, // skip the content + } + + private static Regex EscapedXmlEntities = new Regex("(<|>|\"|'|&)", RegexOptions.CultureInvariant | RegexOptions.Compiled); + private static MatchEvaluator EscapeMatchEvaluator = new MatchEvaluator(EscapeMatch); + + /// + /// the delegate to escape the matched pattern + /// + private static string EscapeMatch(Match match) + { + switch (match.Value) + { + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "\"": + return """; + case "'": + return "'"; + default: + return match.Value; + } + } + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/UpdateManifestForBrowserApplication.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/UpdateManifestForBrowserApplication.cs new file mode 100644 index 00000000000..98468d81b2f --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/UpdateManifestForBrowserApplication.cs @@ -0,0 +1,228 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/////////////////////////////////////////////////////////////////////////////// +// +// Update application manifest for browser-hosted application. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Diagnostics; +using System.Runtime.InteropServices; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.Build.Tasks; +using System.Xml; +using System.Xml.XPath; +using Microsoft.Build.Tasks.Windows; +using System.Collections; + +using MS.Utility; +using MS.Internal.Tasks; + +// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler. +// We first need to disable warnings about unknown message numbers and unknown pragmas. +#pragma warning disable 1634, 1691 + + +namespace Microsoft.Build.Tasks.Windows +{ + #region Manifest Creator Task class + + /// + /// Class of UpdateManifestForBrowserApplication + /// + public sealed class UpdateManifestForBrowserApplication : Task + { + + //------------------------------------------------------ + // + // Constructors + // + //------------------------------------------------------ + + #region Constructors + /// + /// Constructors + /// + public UpdateManifestForBrowserApplication() + : base(SR.SharedResourceManager) + { + } + + #endregion Constructors + + //------------------------------------------------------ + // + // Public Methods + // + //------------------------------------------------------ + + #region Public Methods + + /// + /// Add hostInBrowser element node to the application manifest file. + /// + /// + public override bool Execute() + { + bool successful = true; + TaskHelper.DisplayLogo(Log, SR.Get(SRID.UpdateManifestForBrowserApplicationTask)); + + if (HostInBrowser != true) + { + // HostInBrowser is not true, don't modify the manifest. + // Stop here. + return successful; + } + + try + { + string appManifestFile = ApplicationManifest[0].ItemSpec; + XmlDocument manifestDocument; + + XmlTextReader manifestReader = null; + XmlTextWriter manifestWriter = null; + + //Read the manifest + try + { + manifestReader = new XmlTextReader(appManifestFile); + manifestDocument = new XmlDocument(); + manifestDocument.Load(manifestReader); + } + finally + { + if (manifestReader != null) + { + // Close the manifest reader + manifestReader.Close(); + } + } + + // NOTE: + // + // manifestReader must be closed before the manfiestWriter can + // update the document on the same manifest file. + // + + //Get to entryPoint XML + XmlNodeList entryPointList = manifestDocument.GetElementsByTagName(c_entryPoint); + XmlNode entryPoint = entryPointList[0]; + + //Create element node for browser entry point + XmlElement hostInBrowser; + hostInBrowser = manifestDocument.CreateElement(c_hostInBrowser, c_asmv3); + + // Append HostInBrowser node to the end of list of children of entryPoint. + entryPoint.AppendChild(hostInBrowser); + + // Update the manifest file. + try + { + manifestWriter = new XmlTextWriter(appManifestFile, System.Text.Encoding.UTF8); + manifestWriter.Formatting = Formatting.Indented; + manifestWriter.Indentation = 4; + manifestDocument.WriteTo(manifestWriter); + } + finally + { + if (manifestWriter != null) + { + // Close the manifest writer + manifestWriter.Close(); + } + } + + } + catch (Exception e) + { + // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions. + if (e is NullReferenceException || e is SEHException) + { + throw; + } + else + { + Log.LogErrorFromException(e); + successful = false; + } + } +#pragma warning disable 6500 + catch // Non-cls compliant errors + { + Log.LogErrorWithCodeFromResources(SRID.NonClsError); + successful = false; + } +#pragma warning restore 6500 + + + return successful; + } + + #endregion Public Methods + + //------------------------------------------------------ + // + // Public Properties + // + //------------------------------------------------------ + + #region Public Properties + + /// + /// Host In Browser + /// + /// + [Required] + public bool HostInBrowser + { + get { return _hostInBrowser; } + set + { + _hostInBrowser = value; + } + } + + /// + /// Application Manifest File + /// + /// + [Required] + public ITaskItem[] ApplicationManifest + { + get { return _applicationmanifest; } + set { _applicationmanifest = value; } + } + + #endregion Public Properties + + //------------------------------------------------------ + // + // Private Fields + // + //------------------------------------------------------ + + #region Private Fields + + private ITaskItem[] _applicationmanifest; + private bool _hostInBrowser = false; + + // + // Put some predefined element or attribute name in below + // const strings. + // + private const string c_entryPoint = "entryPoint"; + private const string c_hostInBrowser ="hostInBrowser"; + private const string c_asmv3= "urn:schemas-microsoft-com:asm.v3"; + + #endregion Private Fields + + } + + #endregion Manifest Creator Task class + +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/review.htm b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/review.htm new file mode 100644 index 00000000000..d78727c2c1c --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/review.htm @@ -0,0 +1,1396 @@ + + + + + +

Files changed

+Click on a link to jump to the file. + +

Files added

+
    +
+

Details

+

.\uidmanager.cs

+jump to first change in file +
+-- D:\sp1\windows\wcp\Build\Microsoft\Build\Tasks\Windows\uidmanager.cs#have : D:\sp1\windows\wcp\Build\Microsoft\Build\Tasks\Windows\uidmanager.cs -- .\uidmanager.cs -- includes identical,left-only,right-only,moved-left,moved-right lines
+    
+    //---------------------------------------------------------------------------
+    //
+    // <copyright file="UidManager.cs" company="Microsoft">
+    //    Copyright (C) Microsoft Corporation.  All rights reserved.
+    // </copyright>
+    //
+    // Description:
+    //
+    //     Adds, updates or checks validity of Uids (Unique identifiers)
+    //     on all XAML elements in XAML files.
+    //
+    // History:
+    //  07/24/2003 : dbrown - Created
+    //  04/02/2004 : garyyang - preserved format using XmlTextWriter + StreamWriter 
+    //  11/17/2004 : garyyang - rework UidManager. Preserve source file format 
+    //                          using only stream writer.
+    //---------------------------------------------------------------------------
+    
+    
+    using System;
+    using System.Xml;
+    using System.IO;
+    using System.Text;
+    using System.Text.RegularExpressions;
+    using System.Reflection;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.Globalization;
+    using System.Runtime.InteropServices;
+    
+    using MS.Internal.Markup;
+    
+    using Microsoft.Build.Framework;
+    using Microsoft.Build.Utilities;
+    
+    using MS.Utility;                   // For SR
+    using MS.Internal.Tasks;
+    
+    // Since we disable PreSharp warnings in this file, we first need to disable warnings about unknown message numbers and unknown pragmas.
+    #pragma warning disable 1634, 1691
+    
+    namespace Microsoft.Build.Tasks.Windows
+    {
+        /// <summary>
+        /// An MSBuild task that checks or corrects unique identifiers in
+        /// XAML markup.
+        /// </summary>
+        public sealed class UidManager : Task
+        {
+            //------------------------------------------------------
+            //
+            //  Constructors
+            //
+            //------------------------------------------------------
+    
+            #region Constructors
+    
+            /// <summary>
+            /// Create a UidManager object.
+            /// </summary>
+            public UidManager() : base(SR.ResourceManager)
+            {       
+                _backupPath = Directory.GetCurrentDirectory();
+            }
+    
+            #endregion
+    
+            //------------------------------------------------------
+            //
+            //  Public Methods
+            //
+            //------------------------------------------------------
+    
+            #region Public Methods
+    
+            /// <summary>
+            /// The method invoked by MSBuild to check or correct Uids.
+            /// </summary>
+            public override bool Execute()
+            {
+                TaskHelper.DisplayLogo(Log, SR.Get(SRID.UidManagerTask));
+    
+                if (MarkupFiles == null || MarkupFiles.Length == 0)
+                {
+                    Log.LogErrorWithCodeFromResources(SRID.SourceFileNameNeeded.String);
+                    return false;
+                }
+    
+                try
+                {
+                    _task = (UidTask)Enum.Parse(typeof(UidTask), _taskAsString);
+                }
+                catch (ArgumentException)
+                {
+                    Log.LogErrorWithCodeFromResources(SRID.BadUidTask.String, _taskAsString);
+                    return false;
+                }
+    
+    
+                bool allFilesOk;
+                try
+                {
+                    allFilesOk = ManageUids();
+                }
+                catch (Exception e)
+                {
+                    // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions.
+                    if (e is NullReferenceException || e is SEHException)
+                    {
+                        throw;
+                    }
+                    else
+                    {
+                        string message;
+                        string errorId;
+    
+                        errorId = Log.ExtractMessageCode(e.Message, out message);
+    
+                        if (String.IsNullOrEmpty(errorId))
+                        {
+                            errorId = UnknownErrorID;
+                            message = SR.Get(SRID.UnknownBuildError, message);
+                        }
+    
+                        Log.LogError(null, errorId, null, null, 0, 0, 0, 0, message, null);
+                        
+                        allFilesOk = false;
+                    }
+                }
+    #pragma warning disable 6500
+                catch // Non-CLS compliant errors
+                {
+                    Log.LogErrorWithCodeFromResources(SRID.NonClsError.String);
+                    allFilesOk = false;
+                }
+    #pragma warning restore 6500
+    
+                return allFilesOk;
+            }
+    
+            #endregion
+    
+            //------------------------------------------------------
+            //
+            //  Public Properties
+            //
+            //------------------------------------------------------
+    
+            #region Public Properties
+            ///<summary>
+            /// The markup file(s) to be checked or updated.
+            ///</summary>
+            [Required]
+            public ITaskItem[] MarkupFiles
+            {
+                get { return _markupFiles; }
+                set { _markupFiles = value; }
+            }
+    
+            /// <summary>
+            /// The directory for intermedia files
+            /// </summary>
+            /// <remarks>
+            /// </remarks>
+            public string IntermediateDirectory
+            {
+                get { return _backupPath; }
+                set 
+                { 
+                    string sourceDir = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar;
+                    _backupPath = TaskHelper.CreateFullFilePath(value, sourceDir);
+                }
+            }                
+    
+    
+            ///<summary>
+            /// Enum to determine which Uid management task to undertake
+            ///</summary>
+            private enum UidTask
+            {
+    
+                ///<summary>
+                /// Uid managment task to check validity of Uids
+                ///</summary>
+                Check = 0,
+    
+                ///<summary>
+                /// Uid managment task to Update Uids to a valid state
+                ///</summary>
+                Update = 1,
+    
+                ///<summary>
+                /// Uid managment task to remove all Uids
+                ///</summary>
+                Remove = 2,
+            }
+    
+            ///<summary>
+            /// Uid management task required
+            ///</summary>
+            [Required]
+            public string Task
+            {
+                get { return _taskAsString; }
+                set { _taskAsString = value; }
+            }
+    
+            #endregion
+            
+            //------------------------------------------------------
+            //
+            //  Private Methods
+            //
+            //------------------------------------------------------
+    
+            private bool ManageUids()
+            {
+                int countGoodFiles = 0;
+                // enumerate through each file
+                foreach (ITaskItem inputFile in _markupFiles)
+                {
+                    Log.LogMessageFromResources(SRID.CheckingUids.String, inputFile.ItemSpec);                
+                    switch (_task)
+                    {
+                        case UidTask.Check:
+                        {
+                            UidCollector collector = ParseFile(inputFile.ItemSpec);
+    
+                            bool success = VerifyUid(
+                                collector,          // uid collector
+                                true                // log error
+                                );
+                                
+                            if (success) countGoodFiles++;                        
+                            break;
+                        }
+                        case UidTask.Update:
+                        {
+                            UidCollector collector = ParseFile(inputFile.ItemSpec);
+                            
+                            bool success = VerifyUid(
+                                collector,          // uid collector
+                                false               // log error
+                                );
+    
+                            if (!success)
+                            {
+                                if (SetupBackupDirectory())
+                                {
+                                    // resolve errors 
+                                    collector.ResolveUidErrors();
+    
+                                    // temp file to write to
+                                    string tempFile   = GetTempFileName(inputFile.ItemSpec);
+    
+                                    // backup file of the source file before it is overwritten.
+                                    string backupFile = GetBackupFileName(inputFile.ItemSpec);
+    
+                                    using (Stream uidStream = new FileStream(tempFile, FileMode.Create))
+                                    {
+                                        using (Stream source = File.OpenRead(inputFile.ItemSpec))
+                                        {
+                                            UidWriter writer = new UidWriter(collector, source, uidStream);
+                                            writer.UpdateUidWrite();
+                                        }                                    
+                                    }
+                                    
+                                    // backup source file by renaming it. Expect to be (close to) atomic op.
+                                    RenameFile(inputFile.ItemSpec, backupFile);
+    
+                                    // rename the uid output onto the source file. Expect to be (close to) atomic op.
+                                    RenameFile(tempFile, inputFile.ItemSpec);
+    
+                                    // remove the temp files
+                                    RemoveFile(tempFile);
+                                    RemoveFile(backupFile);
+                                    
+                                    countGoodFiles++;
+                                }
+                            }
+                            else
+                            {
+                                // all uids are good. No-op
+                                countGoodFiles++;
+                            }
+    
+                            break;
+                        }
+                        case UidTask.Remove:
+                        {    
+                            UidCollector collector = ParseFile(inputFile.ItemSpec);
+    
+                            bool hasUid = false;
+                            for (int i = 0; i < collector.Count; i++)
+                            {
+                                if (collector[i].Status != UidStatus.Absent)
+                                {
+                                    hasUid = true;
+                                    break;
+                                }
+                            }
+    
+                            if (hasUid)
+                            {                            
+                                if (SetupBackupDirectory())
+                                {
+                                    // temp file to write to
+                                    string tempFile   = GetTempFileName(inputFile.ItemSpec);
+                                    
+                                    // backup file of the source file before it is overwritten.
+                                    string backupFile = GetBackupFileName(inputFile.ItemSpec);
+    
+                                    using (Stream uidStream = new FileStream(tempFile, FileMode.Create))
+                                    {
+                                        using (Stream source = File.OpenRead(inputFile.ItemSpec))
+                                        {
+                                            UidWriter writer = new UidWriter(collector, source, uidStream);
+                                            writer.RemoveUidWrite();
+                                        }
+                                    }
+    
+                                    // rename the source file to the backup file name. Expect to be (close to) atomic op.
+                                    RenameFile(inputFile.ItemSpec, backupFile);
+    
+                                    // rename the output file over to the source file. Expect to be (close to) atomic op.
+                                    RenameFile(tempFile, inputFile.ItemSpec);
+    
+                                    // remove the temp files
+                                    RemoveFile(tempFile);
+                                    RemoveFile(backupFile);          
+                                            
+                                    countGoodFiles++;
+                                }
+                            }
+                            else
+                            {
+                                // There is no Uid in the file. No need to do remove.
+                                countGoodFiles++;
+                            }
+    
+                            break;
+                        }                    
+                    }
+                }
+    
+                // spew out the overral log info for the task
+                switch (_task)
+                {
+                    case UidTask.Remove:
+                        Log.LogMessageFromResources(SRID.FilesRemovedUid.String, countGoodFiles);
+                        break;
+    
+                    case UidTask.Update:
+                        Log.LogMessageFromResources(SRID.FilesUpdatedUid.String, countGoodFiles);
+                        break;
+    
+                    case UidTask.Check:
+                        Log.LogMessageFromResources(SRID.FilesPassedUidCheck.String, countGoodFiles);
+    
+                        if (_markupFiles.Length > countGoodFiles)
+                        {
+                            Log.LogErrorWithCodeFromResources(SRID.FilesFailedUidCheck.String, _markupFiles.Length - countGoodFiles);
+                        }
+                        break;
+                }
+    
+                return _markupFiles.Length == countGoodFiles;
+            }
+    
+    
+           private string GetTempFileName(string fileName)
+            {
+                return Path.Combine(_backupPath, Path.ChangeExtension(Path.GetFileName(fileName), "uidtemp"));
+            }
+    
+            private string GetBackupFileName (string fileName)
+            {
+                return Path.Combine(_backupPath, Path.ChangeExtension(Path.GetFileName(fileName), "uidbackup"));
+            }
+    
+            private void RenameFile(string src, string dest)
+            {
+                RemoveFile(dest);
+                File.Move(src, dest);
+            }
+    
+            private void RemoveFile(string fileName)
+            {
+                if (File.Exists(fileName))
+                {
+                    File.Delete(fileName);
+                }
+            }
+    
+            private bool SetupBackupDirectory()
+            {
+                try 
+                {
+                    if (!Directory.Exists(_backupPath)) 
+                    {
+                        Directory.CreateDirectory(_backupPath);    
+                    }
+                    
+                    return true;
+                }
+                catch (Exception e)
+                {
+                    // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions.
+                    if (e is NullReferenceException || e is SEHException)
+                    {
+                        throw;
+                    }
+                    else
+                    {
+                        Log.LogErrorWithCodeFromResources(SRID.IntermediateDirectoryError.String, _backupPath);
+                        return false;
+                    }
+                }
+    #pragma warning disable 6500            
+                catch   // Non-cls compliant errors
+                {
+                    Log.LogErrorWithCodeFromResources(SRID.IntermediateDirectoryError.String, _backupPath);
+                    return false;
+                }   
+    #pragma warning restore 6500
+            }        
+    
+    
+    
+    
+            /// <summary>
+            /// Verify the Uids in the file
+            /// </summary>
+            /// <param name="collector">UidCollector containing all Uid instances</param>
+            /// <param name="logError">true to log errors while verifying</param>
+            /// <returns>true indicates no errors</returns>
+            private bool VerifyUid(
+                UidCollector collector, 
+                bool         logError
+                )
+            {
+                bool errorFound = false;
+    
+                for (int i = 0; i < collector.Count; i++)
+                {
+                    Uid currentUid = collector[i];
+                    if (currentUid.Status == UidStatus.Absent)
+                    {
+                        // Uid missing
+                        if (logError)
+                        {
+                            Log.LogErrorWithCodeFromResources(
+                                 null,
+                                 collector.FileName, 
+                                 currentUid.LineNumber, 
+                                 currentUid.LinePosition, 
+                                 0, 0, 
+                                 SRID.UidMissing.String, currentUid.ElementName
+                             );  
+                        }
+                                    
+                        errorFound = true;
+                    }
+                    else if (currentUid.Status == UidStatus.Duplicate)
+                    {
+                        // Uid duplicates
+                        if (logError)
+                        {
+                            Log.LogErrorWithCodeFromResources(
+                                  null,
+                                  collector.FileName,
+                                  currentUid.LineNumber,
+                                  currentUid.LinePosition,
+                                  0, 0,
+                                  SRID.MultipleUidUse.String, currentUid.Value, currentUid.ElementName
+                             );
+    
+                        }
+    
+                        errorFound = true;      
+                    }                    
+    
+                }
+                
+                return !errorFound;
+            }
+    
+            /// <summary>
+            /// Parse the input file and get all the information of Uids 
+            /// </summary>
+            /// <param name="fileName">input file</param>
+            /// <returns>UidCollector containing all the information for the Uids in the file</returns>
+            private UidCollector ParseFile(string fileName)
+            {
+                UidCollector collector = new UidCollector(fileName  );
+                
+                using (Stream xamlStream = File.OpenRead(fileName))
+                {   
+                    XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
+                    XmlParserContext context  = new XmlParserContext(
+                        null,                 // nametable 
+                        nsmgr,                // namespace manager
+                        null,                 // xml:Lang scope 
+                        XmlSpace.Default      // XmlSpace 
+                        );
+    
+                    XmlTextReader reader = new XmlTextReader(
+                        xamlStream,           // xml stream
+                        XmlNodeType.Document, // parsing document 
+                        context               // parser context
+                        );
+    
+                    while (reader.Read())
+                    {
+                        switch (reader.NodeType)
+                        {
+                            case XmlNodeType.Element :
+                            {
+                                if (collector.RootElementLineNumber < 0)
+                                {
+                                    collector.RootElementLineNumber   = reader.LineNumber;
+                                    collector.RootElementLinePosition = reader.LinePosition;
+                                }
+                                
+                                if (reader.Name.IndexOf('.') >= 0)
+                                {
+                                    // the name has a dot, which suggests it is a property tag.
+                                    // we will ignore adding uid
+                                    continue;                                
+                                }
+                                
+                                Uid currentUid = new Uid(
+                                        reader.LineNumber, 
+                                        reader.LinePosition + reader.Name.Length, 
+                                        reader.Name, 
+                                        SpaceInsertion.BeforeUid  // insert space before the Uid
+                                        );                                   ;
+    
+                                if (reader.HasAttributes)
+                                {
+                                    reader.MoveToNextAttribute();
+    
+                                    // As a heuristic to better preserve the source file, add uid to the place of the 
+                                    // first attribute
+                                    currentUid.LineNumber   = reader.LineNumber;
+                                    currentUid.LinePosition = reader.LinePosition;
+                                    currentUid.Space        = SpaceInsertion.AfterUid;
+    
+                                    do
+                                    {
+                                        string namespaceUri = nsmgr.LookupNamespace(reader.Prefix);
+    
+                                        if (reader.LocalName == XamlReaderHelper.DefinitionUid
+                                         && namespaceUri == XamlReaderHelper.DefinitionNamespaceURI)
+                                        {
+                                            // found x:Uid attribute, store the actual value and position
+                                            currentUid.Value        = reader.Value;
+                                            currentUid.LineNumber   = reader.LineNumber;
+                                            currentUid.LinePosition = reader.LinePosition;
+                                        }
+ <!                                     else if (reader.Name == "Name"
+ !>                                     else if (reader.LocalName == "Name"
+                                          && namespaceUri == XamlReaderHelper.DefaultNamespaceURI)
+                                        {
+                                            // found Name attribute, store the Name value
+                                            currentUid.FrameworkElementName = reader.Value;
+                                        }                                    
+ !>                                     else if (reader.LocalName == "Name"
+ !>                                           && namespaceUri == XamlReaderHelper.DefinitionNamespaceURI)
+ !>                                     {
+ !>                                         // found x:Name attribute, store the Name value
+ !>                                         currentUid.FrameworkElementName = reader.Value;
+ !>                                     }                                    
+                                    else if (reader.Prefix == "xmlns")
+                                        {
+                                            // found a namespace declaration, store the namespace prefix
+                                            // so that when we need to add a new namespace declaration later 
+                                            // we won't reuse the namespace prefix.
+                                            collector.AddNamespacePrefix(reader.LocalName);
+                                        }
+                                    }
+                                    while (reader.MoveToNextAttribute());
+                                    
+                                }        
+    
+                                if (currentUid.Value == null)
+                                {
+                                    // there is no x:Uid found on this element, we need to resolve the 
+                                    // namespace prefix in order to add the Uid
+                                    string prefix = nsmgr.LookupPrefix(XamlReaderHelper.DefinitionNamespaceURI);
+                                    if (prefix != string.Empty)
+                                        currentUid.NamespacePrefix = prefix;
+                                }
+    
+                                collector.AddUid(currentUid);
+                                break;
+                            }
+                        }
+                    }                
+                }
+    
+                return collector;
+            }
+    
+            //-----------------------------------
+            // Private members
+            //-----------------------------------
+            private UidTask       _task;            // task 
+            private ITaskItem[]   _markupFiles;     // input Xaml files
+            private string        _taskAsString;    // task string
+            private string        _backupPath;      // path to store to backup source Xaml files
+            internal static readonly CultureInfo EnglishUSCulture = CultureInfo.GetCultureInfo("en-us");
+    
+            private const string UnknownErrorID = "UM1000";
+        }
+        
+        // represent all the information about a Uid 
+        // The uid may be valid, absent, or duplicate
+        internal sealed class Uid
+        {       
+            internal Uid(
+                int     lineNumber, 
+                int     linePosition, 
+                string  elementName,
+                SpaceInsertion    spaceInsertion
+                )
+            {
+                LineNumber          = lineNumber;
+                LinePosition        = linePosition;
+                ElementName         = elementName;            
+                Value               = null;
+                NamespacePrefix     = null;
+                FrameworkElementName  = null;
+                Status              = UidStatus.Valid;
+                Space               = spaceInsertion;
+                
+            }
+    
+            internal int        LineNumber;         // Referenced line number of the original document
+            internal int        LinePosition;       // Reference line position of the original document     
+            internal string     ElementName;        // name of the element that needs this uid
+            internal SpaceInsertion    Space;       // Insert a space before/after the Uid        
+            
+            internal string     Value;              // value of the uid
+            internal string     NamespacePrefix;    // namespace prefix for the uid
+            internal string     FrameworkElementName; // the FrameworkElement.Name of element        
+            internal UidStatus  Status;             // the status of the this uid       
+    
+        }
+    
+        internal enum UidStatus : byte
+        {
+            Valid       = 0,    // uid is valid
+            Absent      = 1,    // uid is absent
+            Duplicate   = 2,    // uid is duplicated
+        }
+    
+        internal enum SpaceInsertion : byte
+        {
+            BeforeUid,          // Insert a space before the Uid
+            AfterUid            // Insert a space after the Uid
+        }
+    
+        // a class collects all the information about Uids per file
+        internal sealed class UidCollector
+        {
+            public UidCollector(string fileName)
+            {
+                _uids               = new List<Uid>(32);
+                _namespacePrefixes  = new List<string>(2);
+                _uidTable           = new Hashtable();
+                _fileName           = fileName;
+                _sequenceMaxIds     = new Hashtable();
+            }
+    
+            // remembering all the namespace prefixes in the file 
+            // in case we need to add a new definition namespace declaration
+            public void AddNamespacePrefix(string prefix)
+            {
+                _namespacePrefixes.Add(prefix);            
+            }
+    
+            // add the uid to the collector
+            public void AddUid(Uid uid)
+            {     
+                _uids.Add(uid);
+                
+                // set the uid status according to the raw data
+                if (uid.Value == null)
+                {
+                    uid.Status = UidStatus.Absent;
+                }
+                else  if (_uidTable.Contains(uid.Value))
+                {
+                    uid.Status = UidStatus.Duplicate;
+                }
+                else
+                {                
+                    // valid uid, store it 
+                    StoreUid(uid.Value);
+                }  
+            }
+    
+            public void ResolveUidErrors()
+            {   
+                for (int i = 0; i < _uids.Count; i++)
+                {
+                    Uid currentUid = _uids[i];
+    
+                    if ( currentUid.Status == UidStatus.Absent 
+                      && currentUid.NamespacePrefix == null 
+                      && _namespacePrefixForMissingUid == null)
+                    {
+                        // there is Uid not in scope of any definition namespace
+                        // we will need to generate a new namespace prefix for them
+                        _namespacePrefixForMissingUid = GeneratePrefix();            
+                    }
+    
+                    if (currentUid.Status != UidStatus.Valid)
+                    {
+                        // resolve invalid uids
+                        currentUid.Value = GetAvailableUid(currentUid);
+                    }                             
+                }          
+            }
+    
+            public int RootElementLineNumber
+            {
+                get { return _rootElementLineNumber; }
+                set { _rootElementLineNumber = value; }
+            }
+    
+            public int RootElementLinePosition
+            {
+                get { return _rootElementLinePosition; }
+                set { _rootElementLinePosition = value; }
+            }
+    
+            public string FileName
+            {
+                get { return _fileName; }
+            }
+    
+            public Uid this[int index]
+            {
+                get
+                {
+                    return _uids[index];
+                }
+            }
+    
+            public int Count
+            {
+                get { return _uids.Count; }
+            }
+    
+            public string NamespaceAddedForMissingUid
+            {
+                get { return _namespacePrefixForMissingUid; }
+            }
+    
+    
+            //-------------------------------------
+            // Private methods
+            //-------------------------------------
+            private void StoreUid(string value)
+            {
+                // we just want to check for existence, so storing a null
+                _uidTable[value] = null;
+    
+                string uidSequence;
+                Int64 index;
+    
+                ParseUid(value, out uidSequence, out index);
+                if (uidSequence != null)
+                {
+                    if (_sequenceMaxIds.Contains(uidSequence))
+                    {
+                        Int64 maxIndex = (Int64)_sequenceMaxIds[uidSequence];
+                        if (maxIndex < index)
+                        {
+                            _sequenceMaxIds[uidSequence] = index;
+                        }
+                    }
+                    else
+                    {
+                        _sequenceMaxIds[uidSequence] = index;
+                    }
+                }
+            }
+    
+            private string GetAvailableUid(Uid uid)
+            {
+                string availableUid;
+    
+                // copy the ID if available
+                if (uid.FrameworkElementName != null 
+                 && (!_uidTable.Contains(uid.FrameworkElementName))
+                 )
+                {
+                    availableUid = uid.FrameworkElementName;
+                }
+                else
+                {
+                    // generate a new id
+                    string sequence = GetElementLocalName(uid.ElementName);
+                    Int64 index;
+                    
+                    if (_sequenceMaxIds.Contains(sequence))
+                    {
+                        index = (Int64) _sequenceMaxIds[sequence];
+                        
+                        if (index == Int64.MaxValue)
+                        {
+                            // this sequence reaches the max
+                            // we fallback to create a new sequence
+                            index = -1;                      
+                            while (index < 0)
+                            {                            
+                                sequence = (_uidSequenceFallbackCount == 0) ? 
+                                    UidFallbackSequence 
+                                  : UidFallbackSequence + _uidSequenceFallbackCount;
+                                
+                                if (_sequenceMaxIds.Contains(sequence))
+                                {
+                                    index = (Int64) _sequenceMaxIds[sequence];
+                                    if (index < Int64.MaxValue)
+                                    {
+                                        // found the fallback sequence with valid index
+                                        index ++;
+                                        break;
+                                    }
+                                }             
+                                else
+                                {
+                                    // create a new sequence from 1
+                                    index = 1; 
+                                    break;
+                                }                            
+    
+                                _uidSequenceFallbackCount ++;
+                            }                        
+                        }
+                        else
+                        {                    
+                            index ++;
+                        }
+                    }
+                    else
+                    {
+                        // a new sequence
+                        index = 1;
+                    }
+                    
+                    availableUid = sequence + UidSeparator + index;
+                }
+    
+                // store the uid so that it won't be used again
+                StoreUid(availableUid);            
+                return availableUid;
+            }
+    
+            private void ParseUid(string uid, out string prefix, out Int64 index)
+            {
+                // set prefix and index to invalid values
+                prefix = null;
+                index  = -1;
+    
+                if (uid == null) return;
+                
+                int separatorIndex = uid.LastIndexOf(UidSeparator);
+                if (separatorIndex > 0)
+                {
+                    string suffix = uid.Substring(separatorIndex + 1);
+                    
+                    // Disable Presharp warning 6502 : catch block shouldn't have empty body
+                    #pragma warning disable 6502                
+                    try {
+                        index  = Int64.Parse(suffix, UidManager.EnglishUSCulture);
+                        prefix = uid.Substring(0, separatorIndex);                         
+                    }
+                    catch (FormatException)
+                    {
+                        // wrong format
+                    }
+                    catch (OverflowException)
+                    {
+                        // not acceptable uid
+                    }
+                    #pragma warning restore 6502
+                }                                    
+            }
+    
+            private string GetElementLocalName(string typeFullName)
+            {
+                int index = typeFullName.LastIndexOf('.');
+                if (index > 0)
+                {
+                    return typeFullName.Substring(index + 1);
+                }
+                else
+                {
+                    return typeFullName;
+                }            
+            }
+    
+            private string GeneratePrefix()
+            {
+                Int64 ext = 1;
+                string prefix = UidNamespaceAbbreviation.ToString(UidManager.EnglishUSCulture);
+                
+                // Disable Presharp warning 6502 : catch block shouldn't have empty body
+                #pragma warning disable 6502
+                try
+                {
+                    // find a prefix that is not used in the Xaml
+                    // from x1, x2, ... x[n]
+                    while (_namespacePrefixes.Contains(prefix))
+                    {
+                        prefix = UidNamespaceAbbreviation + ext.ToString(UidManager.EnglishUSCulture);
+                        ext++;
+                    }
+                    return prefix;
+                }
+                catch (OverflowException)
+                {
+                }
+                #pragma warning restore 6502
+    
+                // if overflows, (extreamly imposible), we will return a guid as the prefix
+                return Guid.NewGuid().ToString();
+            }
+    
+            private List<Uid>             _uids;        
+            private Hashtable             _uidTable;
+            private string                _fileName;
+            private Hashtable             _sequenceMaxIds;
+            private List<string>          _namespacePrefixes;
+            private int                   _rootElementLineNumber        = -1;
+            private int                   _rootElementLinePosition      = -1;
+            private string                _namespacePrefixForMissingUid = null;        
+            private int                   _uidSequenceFallbackCount     = 0;
+    
+            private const char UidNamespaceAbbreviation   = 'x';        
+            private const char UidSeparator               = '_';
+            private const string UidFallbackSequence      = "_Uid";        
+        }
+    
+    
+        // writing to a file, removing or updating uid
+        internal sealed class UidWriter
+        {
+            internal UidWriter(UidCollector collector, Stream source, Stream target)
+            {
+                _collector     = collector;
+                _sourceReader  = new StreamReader(source);
+    
+                 UTF8Encoding encoding = new UTF8Encoding(true);                       
+                _targetWriter  = new StreamWriter(target, encoding);
+                _lineBuffer    = new LineBuffer(_sourceReader.ReadLine());            
+            }
+    
+            // write to target stream and update uids
+            internal bool UpdateUidWrite()
+            {
+                try {
+                    // we need to add a new namespace
+                    if (_collector.NamespaceAddedForMissingUid != null)
+                    {
+                        // write to the beginning of the root element
+                        WriteTillSourcePosition(
+                            _collector.RootElementLineNumber, 
+                            _collector.RootElementLinePosition
+                            );
+                        
+                        WriteElementTag();  
+                        WriteSpace();
+                        WriteNewNamespace();
+                    }
+    
+                    for (int i = 0; i < _collector.Count; i++)
+                    {
+                        Uid currentUid = _collector[i]; 
+                        WriteTillSourcePosition(currentUid.LineNumber, currentUid.LinePosition);
+    
+                        if (currentUid.Status == UidStatus.Absent)
+                        {
+    
+                            if (currentUid.Space == SpaceInsertion.BeforeUid)
+                            {
+                                WriteSpace();                            
+                            }
+                            
+                            WriteNewUid(currentUid);
+    
+                            if (currentUid.Space == SpaceInsertion.AfterUid)
+                            {
+                                WriteSpace();
+                            }
+                        }
+                        else if (currentUid.Status == UidStatus.Duplicate)
+                        {
+                            ProcessAttributeStart(WriterAction.Write);
+                            SkipSourceAttributeValue();
+                            WriteNewAttributeValue(currentUid.Value);
+                        }
+                    }
+                    WriteTillEof();
+                    return true;
+                }
+                catch (Exception e)
+                {
+                    // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions.
+                    if (e is NullReferenceException || e is SEHException)
+                    {
+                        throw;
+                    }
+    
+                    return false;
+                }
+    #pragma warning disable 6500            
+                catch 
+                {
+                    return false;
+                }
+    #pragma warning restore 6500            
+            }
+            
+            // writing to the target stream removing uids
+            internal bool RemoveUidWrite()
+            {
+                try {
+                    for (int i = 0; i < _collector.Count; i++)
+                    {
+                        Uid currentUid = _collector[i];
+    
+                        // skipping valid and duplicate uids.
+                        if ( currentUid.Status == UidStatus.Duplicate
+                          || currentUid.Status == UidStatus.Valid)
+                        {
+                            // write till the space in front of the Uid
+                            WriteTillSourcePosition(currentUid.LineNumber, currentUid.LinePosition - 1);
+    
+                            // skip the uid
+                            ProcessAttributeStart(WriterAction.Skip);
+                            SkipSourceAttributeValue();
+                        }                  
+                    }
+    
+                    WriteTillEof();
+                    return true;
+                }
+                catch (Exception e)
+                {
+                    // PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions.
+                    if (e is NullReferenceException || e is SEHException)
+                    {
+                        throw;
+                    }
+    
+                    return false;
+                }            
+    #pragma warning disable 6500            
+                catch 
+                {
+                    return false;
+                }
+    #pragma warning restore 6500
+            }
+    
+            private void WriteTillSourcePosition(int lineNumber, int linePosition)
+            {     
+                // write to the correct line
+                while (_currentLineNumber < lineNumber)
+                {
+                    // write out the line buffer
+                    _targetWriter.WriteLine(_lineBuffer.ReadToEnd());
+                    _currentLineNumber++;
+                    _currentLinePosition = 1;   
+                    
+                    // read one more line
+                    _lineBuffer.SetLine(_sourceReader.ReadLine());
+                }
+    
+                // write to the correct line position
+                while (_currentLinePosition < linePosition)
+                {
+                    _targetWriter.Write(_lineBuffer.Read());                   
+                    _currentLinePosition++;
+                }
+    
+            }        
+    
+            private void WriteElementTag()
+            {
+                if (_lineBuffer.EOL)
+                {
+                    // advance to the non-empty line
+                    AdvanceTillNextNonEmptyLine(WriterAction.Write);
+                }
+                    
+                char ch = _lineBuffer.Peek();            
+    
+                // stop when we see space, "/" or ">". That is the end of the 
+                // element name
+                while (!Char.IsWhiteSpace(ch)
+                       && ch != '/'
+                       && ch != '>'
+                      )
+                {
+                    _targetWriter.Write(ch);
+    
+                    _currentLinePosition++;
+                    _lineBuffer.Read();
+                    if (_lineBuffer.EOL)
+                    {
+                        AdvanceTillNextNonEmptyLine(WriterAction.Write);
+                    }
+    
+                    ch = _lineBuffer.Peek();
+                } 
+            }
+    
+            private void WriteNewUid(Uid uid)
+            {
+                // construct the attribute name, e.g. x:Uid
+                // "x" will be the resolved namespace prefix for the definition namespace
+                string attributeName = 
+                    (uid.NamespacePrefix == null) ? 
+                     _collector.NamespaceAddedForMissingUid + ":" + XamlReaderHelper.DefinitionUid 
+                   : uid.NamespacePrefix + ":" + XamlReaderHelper.DefinitionUid;
+    
+                // escape all the Xml entities in the value
+                string attributeValue = EscapedXmlEntities.Replace(
+                    uid.Value,                 
+                    EscapeMatchEvaluator
+                    );
+    
+                string clause = string.Format(
+                    UidManager.EnglishUSCulture,
+                    "{0}=\"{1}\"",
+                    attributeName,
+                    attributeValue                
+                    );
+    
+                _targetWriter.Write(clause);
+            }    
+            
+            private void WriteNewNamespace()
+            {
+                string clause = string.Format(
+                    UidManager.EnglishUSCulture,
+                    "xmlns:{0}=\"{1}\"",
+                    _collector.NamespaceAddedForMissingUid,
+                    XamlReaderHelper.DefinitionNamespaceURI
+                    );
+    
+                _targetWriter.Write(clause);            
+            }
+    
+            private void WriteNewAttributeValue(string value)
+            {
+                string attributeValue = EscapedXmlEntities.Replace(
+                    value,                 
+                    EscapeMatchEvaluator
+                    );
+                
+                _targetWriter.Write(
+                    string.Format(
+                        UidManager.EnglishUSCulture,
+                        "\"{0}\"", 
+                        value
+                        )
+                    );
+            }
+    
+            private void WriteSpace()
+            {
+                 // insert a space
+                _targetWriter.Write(" ");
+            }
+    
+            private void WriteTillEof()
+            {
+                _targetWriter.WriteLine(_lineBuffer.ReadToEnd());
+                _targetWriter.Write(_sourceReader.ReadToEnd());
+                _targetWriter.Flush();
+            }    
+    
+            private void SkipSourceAttributeValue()
+            {
+                char ch = (char) 0;
+    
+                // read to the start quote of the attribute value
+                while (ch != '\"' && ch != '\'')
+                {
+                    if (_lineBuffer.EOL)
+                    {
+                        AdvanceTillNextNonEmptyLine(WriterAction.Skip);
+                    }
+    
+                    ch = _lineBuffer.Read();
+                    _currentLinePosition ++;                                
+                }
+    
+                char attributeValueStart = ch;
+                // read to the end quote of the attribute value            
+                ch = (char) 0;
+                while (ch != attributeValueStart)
+                {
+                    if (_lineBuffer.EOL)
+                    {
+                        AdvanceTillNextNonEmptyLine(WriterAction.Skip);
+                    }
+                    
+                    ch = _lineBuffer.Read();
+                    _currentLinePosition ++;                                                
+                }            
+            }            
+    
+            private void AdvanceTillNextNonEmptyLine(WriterAction action)
+            {
+                do
+                {
+                    if (action == WriterAction.Write)
+                    {
+                        _targetWriter.WriteLine();
+                    }
+                    
+                    _lineBuffer.SetLine(_sourceReader.ReadLine());
+                    _currentLineNumber++;
+                    _currentLinePosition = 1;
+    
+                } while (_lineBuffer.EOL);
+            }
+    
+    
+            private void ProcessAttributeStart(WriterAction action)
+            {
+                if (_lineBuffer.EOL)
+                {
+                    AdvanceTillNextNonEmptyLine(action);
+                }   
+                
+                char ch;
+                do
+                {
+                    ch = _lineBuffer.Read();
+    
+                    if (action == WriterAction.Write)
+                    {
+                        _targetWriter.Write(ch);
+                    }
+                    
+                    _currentLinePosition++;
+                    
+                    if (_lineBuffer.EOL)
+                    {
+                        AdvanceTillNextNonEmptyLine(action);
+                    }
+                    
+                } while (ch != '=');
+            }        
+    
+            //
+            // source position in a file starts from (1,1)
+            //
+    
+            private int             _currentLineNumber   = 1;   // current line number in the source stream
+            private int             _currentLinePosition = 1;   // current line position in the source stream
+            private LineBuffer      _lineBuffer;                // buffer for one line's content
+    
+            private UidCollector    _collector;                 
+            private StreamReader    _sourceReader;
+            private StreamWriter    _targetWriter;
+            
+            //
+            // buffer for the content of a line
+            // The UidWriter always reads one line at a time from the source 
+            // and store the line in this buffer. 
+            //
+            private sealed class LineBuffer
+            {
+                private int    Index;
+                private string Content;
+    
+                public LineBuffer(string line)
+                {
+                    SetLine(line);
+                }
+    
+                public void SetLine(string line)
+                {
+                    Content = (line == null) ? string.Empty : line;
+                    Index   = 0;
+                }
+    
+                public bool EOL
+                {
+                    get { return (Index == Content.Length); }
+                }
+    
+                public char Read()
+                {
+                    if (!EOL)
+                    {
+                        return Content[Index++];                   
+                    }
+    
+                    throw new InvalidOperationException();
+                }    
+    
+                public char Peek()
+                {
+                    if (!EOL)
+                    {
+                        return Content[Index];
+                    }
+    
+                    throw new InvalidOperationException();                
+                }
+    
+                public string ReadToEnd()
+                {
+                    if (!EOL)
+                    {
+                        int temp = Index;
+                        Index    = Content.Length;
+    
+                        return Content.Substring(temp);
+                    }
+    
+                    return string.Empty;
+                }
+            }
+    
+            private enum WriterAction
+            {
+                Write = 0,  // write the content
+                Skip  = 1,  // skip the content
+            }
+    
+            private static Regex          EscapedXmlEntities   = new Regex("(<|>|\"|'|&)", RegexOptions.CultureInvariant | RegexOptions.Compiled);        
+            private static MatchEvaluator EscapeMatchEvaluator = new MatchEvaluator(EscapeMatch);
+    
+            /// <summary>
+            /// the delegate to escape the matched pattern
+            /// </summary>
+            private static string EscapeMatch(Match match)
+            {
+                switch (match.Value)
+                {
+                    case "<": 
+                        return "&lt;";
+                    case ">":
+                        return "&gt;";
+                    case "&":
+                        return "&amp;";
+                    case "\"":
+                        return "&quot;";
+                    case "'":
+                        return "&apos;";
+                    default: 
+                       return match.Value;
+                }     
+            }         
+        }    
+    }
+-- 1370 lines listed
+
+There are no more changes for this file. + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.csproj b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.csproj new file mode 100644 index 00000000000..635c3ec5798 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.csproj @@ -0,0 +1,335 @@ + + + net472;netcoreapp2.1 + false + true + true + false + + + + + + $(NoWarn);1058 + + None + PresentationBuildTasks + Library + $(DefineConstants);PBTCOMPILER;PARSERM8BC;NEWLOADER;IGNORABLESUPPORT;ONLYMARKUPEXTENSIONS + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4} + false + full + true + true + AnyCPU;x64 + + + + + None + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + Strings + MS.Utility + CSharp + + + + + + + Common\System\SR.cs + + + + Shared\RefAssemblyAttrs.cs + + + Shared\MS\Internal\ResourceIDHelper.cs + + + Shared\MS\Internal\SecurityHelper.cs + + + Shared\MS\Internal\TokenizerHelper.cs + + + Shared\System\Windows\Markup\ReflectionHelper.cs + + + Shared\MS\Internal\Xaml\Parser\SpecialBracketCharacters.cs + + + Shared\MS\Internal\CriticalExceptions.cs + + + + WindowsBase\System\Windows\Markup\DateTimeConverter2.cs + + + WindowsBase\System\Windows\Markup\TypeTypeConverter.cs + + + Shared\System\Windows\Markup\RuntimeIdentifierPropertyAttribute.cs + + + Shared\System\Windows\Markup\TypeConverterHelper.cs + + + Shared\System\Windows\Markup\XmlCompatibilityReader.cs + + + Shared\System\Windows\Markup\XmlWrappingReader.cs + + + WindowsBase\System\IO\Packaging\Compoundfile\FormatVersion.cs + + + WindowsBase\System\IO\Packaging\Compoundfile\versionPair.cs + + + WindowsBase\MS\Internal\IO\Packaging\Compoundfile\ContainerUtilities.cs + + + PresentationCore\MS\internal\Media\XamlSerializationHelper.cs + + + PresentationCore\MS\internal\Media\ParserStreamGeometryContext.cs + + + PresentationCore\System\Windows\Media\StreamGeometryContext.cs + + + PresentationCore\System\Windows\Media\ParsersCommon.cs + + + PresentationCore\System\Windows\LocalizationCategory.cs + + + PresentationCore\System\Windows\Media\Knowncolors.cs + + + PresentationCore\System\Windows\Modifiability.cs + + + PresentationCore\System\Windows\Readability.cs + + + PresentationFramework\System\Windows\Markup\AttributeData.cs + + + PresentationFramework\System\Windows\Markup\BamlBinaryWriter.cs + + + PresentationFramework\System\Windows\Markup\BamlMapTable.cs + + + PresentationFramework\System\Windows\Markup\BamlRecords.cs + + + PresentationFramework\System\Windows\Markup\BamlRecordWriter.cs + + + PresentationFramework\System\Windows\Markup\BamlRecordHelper.cs + + + PresentationFramework\System\Windows\Markup\BamlVersionHeader.cs + + + + PresentationFramework\System\Windows\Markup\KnownTypes.cs + + + PresentationFramework\System\Windows\Markup\KnownTypesHelper.cs + + + PresentationFramework\System\Windows\Markup\XamlTypeMapper.cs + + + PresentationFramework\System\Windows\Markup\MarkupExtensionParser.cs + + + PresentationFramework\System\Windows\Markup\ParserContext.cs + + + PresentationFramework\System\Windows\Markup\ParserHooks.cs + + + PresentationFramework\System\Windows\Markup\ParserStack.cs + + + PresentationFramework\System\Windows\Markup\StyleModeStack.cs + + + PresentationFramework\System\Windows\Markup\StyleXamlParser.cs + + + PresentationFramework\System\Windows\Markup\TemplateXamlParser.cs + + + PresentationFramework\System\Windows\Markup\TreeBuilder.cs + + + PresentationFramework\System\Windows\Markup\TypeContext.cs + + + PresentationFramework\System\Windows\Markup\XamlBrushSerializer.cs + + + PresentationFramework\System\Windows\Markup\XamlPoint3DCollectionSerializer.cs + + + PresentationFramework\System\Windows\Markup\XamlVector3DCollectionSerializer.cs + + + PresentationFramework\System\Windows\Markup\XamlPointCollectionSerializer.cs + + + PresentationFramework\System\Windows\Markup\XamlInt32CollectionSerializer.cs + + + PresentationFramework\System\Windows\Markup\XamlPathDataSerializer.cs + + + PresentationFramework\System\Windows\Markup\XamlNodes.cs + + + PresentationFramework\System\Windows\Markup\XAMLParseException.cs + + + PresentationFramework\System\Windows\Markup\XamlParser.cs + + + PresentationFramework\System\Windows\Markup\XamlSerializer.cs + + + PresentationFramework\System\Windows\Markup\XamlStyleSerializer.cs + + + PresentationFramework\System\Windows\Markup\XamlTemplateSerializer.cs + + + PresentationFramework\System\Windows\Markup\XamlReaderConstants.cs + + + PresentationFramework\System\Windows\Markup\XamlReaderHelper.cs + + + PresentationFramework\System\Windows\Markup\XmlAttributeProperties.cs + + + PresentationFramework\System\Windows\Markup\XmlnsCache.cs + + + PresentationFramework\System\Windows\Markup\XmlnsDictionary.cs + + + PresentationFramework\System\Windows\SystemResourceKey.cs + + + PresentationFramework\MS\Internal\Globalization\LocalizationComments.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GenerateResourcesSource; + $(CoreCompileDependsOn) + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.sln b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.sln new file mode 100644 index 00000000000..543fa62b442 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28404.58 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PresentationBuildTasks", "PresentationBuildTasks.csproj", "{4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|x64.ActiveCfg = Debug|x64 + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|x64.Build.0 = Debug|x64 + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|x86.ActiveCfg = Debug|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Debug|x86.Build.0 = Debug|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|Any CPU.Build.0 = Release|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|x64.ActiveCfg = Release|x64 + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|x64.Build.0 = Release|x64 + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|x86.ActiveCfg = Release|Any CPU + {4216C2EA-E2B9-4FB2-9803-F73FDC64CAC4}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {86AF908B-1776-407E-A049-E5DCD1BE13B1} + EndGlobalSection +EndGlobal diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Resources/Strings.resx b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Resources/Strings.resx new file mode 100644 index 00000000000..0f24e4e48aa --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Resources/Strings.resx @@ -0,0 +1,861 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + Microsoft (R) Build Task '{0}' Version '{1}'. + + + Copyright (C) Microsoft Corporation 2005. All rights reserved. + + + Current project directory is '{0}'. + + + OutputType is '{0}'. + + + Input file '{0}' is resolved to new relative path '{1}' at directory '{2}'. + + + MarkupCompilePass1 + + + FileClassifier + + + MarkupCompilePass2 + + + UidManager + + + ResourcesGenerator + + + MergeLocalizationDirectives + + + UpdateManifestForBrowserApplication + + + GetWinFXPath + + + MarkupCompilePass1 successfully generated BAML or source code files. + + + Preparing for the markup compilation... + + + Started the markup compilation. + + + Markup compilation is done. + + + Input: Markup ApplicationDefinition file: '{0}'. + + + Input: Assembly Reference file: '{0}'. + + + Analysis Result : '{0}'. + + + Recompiled XAML file : '{0}'. + + + Generated code file: '{0}'. + + + Generated BAML file: '{0}'. + + + MarkupCompilePass2 successfully generated BAML or source code files. + + + Input: Local reference markup ApplicationDefinition file is '{0}'. + + + Input: Local reference markup Page file: '{0}'. + + + Generated BAML file: '{0}'. + + + InternalTypeHelper class is not required for this project, make file '{0}' empty. + + + Generating .resources file: '{0}'... + + + Generated .resources file: '{0}'. + + + Reading Resource file: '{0}'... + + + Resource ID is '{0}'. + + + Checking Uids in file '{0}' ... + + + Uids updated in {0} files. + + + Uids removed from {0} files. + + + Uids valid in {0} files. + + + Generating localization directives file: '{0}' ... + + + Generated localization directives file: '{0}' . + + + Line {0} Position {1} + + + Known type value {0}='{1}' is not a valid known type. + + + Unknown path operation attempted. + + + Unknown build error, '{0}' + + + BG1001: Unknown CLS exception. + + + BG1002: File '{0}' cannot be found. + + + BG1003: The project file contains a property value that is not valid. + + + BG1004: Target Type '{0}' is not supported by this task. + + + MC1001: The LocalizationDirectivesToLocFile property value is not valid and must be changed to None, CommentsOnly, or All for the MarkupCompilePass1 task. + + + MC1002: Library project file cannot specify ApplicationDefinition element. + + + MC1003: Project file cannot specify more than one ApplicationDefinition element. + + + MC1004: Project file cannot specify more than one SplashScreen element. + + + FC1001: The UICulture value '{0}' set in the project file is not valid. + + + RG1001: Input resource file '{0}' exceeds maximum size of {1} bytes. + + + RG1002: ResourcesGenerator can generate only one .resources file at a time. The OutputResourcesFile property in the project file must be set to one file. + + + UM1001: Unrecognized UidManager task name '{0}'. + + + UM1002: Uid "{0}" for element '{1}' is not unique. + + + UM1003: Uid is missing for element '{0}'. + + + UM1004: {0} files failed Uid check. + + + UM1005: You must pass markup files to the task. + + + UM1006: '{0}' directory does not exist and cannot be created. + + + LC1001: Localization comment target property is not valid in string '{0}'. + + + LC1002: Localization comment value is not valid for target property '{0}' in string '{1}'. + + + LC1003: Localization comment has no value set for target property: '{0}'. + + + LC1004: Localizability attribute setting '{0}' is not valid. + + + MC3000: '{0}' XML is not valid. + + + MC3001: TypeConverter syntax error encountered while processing initialization string '{0}'. Property elements are not allowed on objects created via TypeConverter. + + + MC3002: The AsyncRecords attribute must be set on the root tag. + + + MC3003: There are too many attributes specified for '{0}'. + + + MC3004: There are not enough attributes specified for '{0}'. + + + MC3005: The property '{0}' must be in the default namespace or in the element namespace '{1}'. + + + MC3006: Mapper.SetAssemblyPath cannot accept an empty assemblyName. + + + MC3007: Mapper.SetAssemblyPath cannot accept an empty assemblyPath. + + + MC3008: An element of type '{0}' cannot be set on the complex property '{1}'. They are not compatible types. + + + MC3009: Cannot find a public constructor for '{0}' that takes {1} arguments. + + + MC3010: '{0}' Name property value is not valid. Name must start with a letter or an underscore and can contain only letters, digits, and underscores. + + + MC3011: Cannot find the static member '{0}' on the type '{1}'. + + + MC3012: A key for a dictionary cannot be of type '{0}'. Only String, TypeExtension, and StaticExtension are supported. + + + MC3013: SynchronousMode property value is not valid. Valid values are Async and Sync. + + + MC3014: The object being added to an array property is not a valid type. The array is of type '{0}' but the object being added is of type '{1}'. + + + MC3015: The attached property '{0}' is not defined on '{1}' or one of its base classes. + + + MC3016: Two new namespaces cannot be compatible with the same old namespace using an XmlnsCompatibility attribute.�'{0}' namespace is already marked compatible with '{1}'. + + + MC3017: 'Code' tag from xaml namespace found in XAML file. To load this file, you must compile it. + + + MC3018: Cannot modify data in a sealed XmlnsDictionary. + + + MC3019: Cannot reference the static member '{0}' on the type '{1}' as it is not accessible. + + + MC3020: The dictionary key '{0}' is already used. Key attributes are used as keys when inserting objects into a dictionary and must be unique. + + + MC3021: Asynchronous loading is not supported when compiling a XAML file, so a SynchronousMode of '{0}' is not allowed. + + + MC3022: All objects added to an IDictionary must have a Key attribute or some other type of key associated with them. + + + MC3023: The Key attribute can only be used on a tag contained in a Dictionary (such as a ResourceDictionary). + + + MC3024: '{0}' property has already been set and can be set only once. + + + MC3025: Property '{0}' and '{1}' refer to the same property. Duplicate property settings are not allowed. + + + MC3026: '{0}' property element cannot be empty. It must contain child elements or text. + + + MC3027: The EntityReference &{0}; is not recognized. + + + MC3028: Cannot add content to object of type '{0}'. + + + MC3029: '{0}' member is not valid because it does not have a qualifying type name. + + + MC3030: '{0}' property is a read-only IEnumerable property, which means that '{1}' must implement IAddChild. + + + MC3031: Keys and values in XmlnsDictionary must be strings. + + + MC3032: '{1}' cannot be used as a value for '{0}'. Numbers are not valid enumeration values. + + + MC3033: The property '{0}' has already been set on this markup extension and can only be set once. + + + MC3037: Missing XmlNamespace, Assembly or ClrNamespace in Mapping instruction. + + + '{0}' mapping URI is not valid. + + + MC3038: MarkupExtension expressions must end with a '}'. + + + MC3040: Format is not valid for MarkupExtension that specifies constructor arguments in '{0}'. + + + MC3041: Markup extensions require a single '=' between name and value, and a single ',' between constructor parameters and name/value pairs. The arguments '{0}' are not valid. + + + MC3042: Name/value pairs in MarkupExtensions must have the format 'Name = Value' and each pair is separated by a comma. '{0}' does not follow this format. + + + MC3043: Names and Values in a MarkupExtension cannot contain quotes. The MarkupExtension arguments '{0}' are not valid. + + + MC3044: The text '{1}' is not allowed after the closing '{0}' of a MarkupExtension expression. + + + MC3045: Unknown property '{0}' for type '{1}' encountered while parsing a Markup Extension. + + + MC3046: Unknown attribute '{0}' in the '{1}' namespace. Note that only the Key attribute is currently supported in this namespace. + + + MC3047: Internal parser error - Cannot use multiple writable BAML records at the same time. + + + '{0}' property element cannot be nested directly inside another property element. + + + MC3048: '{0}' value is not a valid MarkupExtension expression. Cannot resolve '{1}' in namespace '{2}'. '{1}' must be a subclass of MarkupExtension. + + + MC3049: Cannot place attributes on Array tags. + + + MC3050: Cannot find the type '{0}'. Note that type names are case sensitive. + + + MC3051: The type '{0}' does not support element content. + + + MC3052: XAML file that contains events must be compiled. + + + MC3053: Cannot use property element syntax to specify event handler '{0}'. + + + MC3054: The type '{0}' cannot have a Name attribute. Value types and types without a default constructor can be used as items within a ResourceDictionary. + + + MC3056: No NamespaceURI is defined for the object '{0}'. + + + MC3057: Cannot set properties on property elements. + + + MC3058: Cannot find a custom serializer for '{0}' so it cannot be parsed. + + + MC3059: Style setters do not support child elements. A tag of type '{0}' is not allowed. + + + MC3061: The Element type '{0}' does not have an associated TypeConverter to parse the string '{1}'. + + + MC3062: '{0}' XML namespace prefix does not map to a NamespaceURI, so element '{1}' cannot be resolved. + + + MC3063: Property '{0}' does not have a value. + + + MC3064: Only public or internal classes can be used within markup. '{0}' type is not public or internal. + + + MC3065: '{0}' property is read-only and cannot be set from markup. + + + MC3066: The type reference cannot find a public type named '{0}'. + + + MC3067: SynchronousMode attribute must be on the root tag. + + + MC3068: Text is not valid under an IDictionary or Array property. + + + MC3069: Cannot have both the text '{0}' and the child element '{1}' within a property element. + + + MC3070: A single XAML file cannot reference more than 4,096 different assemblies. + + + MC3071: '{0}' is an undeclared namespace. + + + MC3072: The property '{0}' does not exist in XML namespace '{1}'. + + + MC3073: The attribute '{0}' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml'. + + + MC3074: The tag '{0}' does not exist in XML namespace '{1}'. + + + MC3075: Unrecognized XML node type '{0}' found when determining if the current tag is a property element. + + + MC3077: The class '{0}' does not implement IXmlLineInfo. This is required to get position information for the XAML being parsed. + + + MC3078: Invalid ContentPropertyAttribute on type '{0}', property '{1}' not found. + + + MC3079: MarkupExtensions are not allowed for Uid or Name property values, so '{0}' is not valid. + + + MC3080: The {0} '{1}' cannot be set because it does not have an accessible {2} accessor. + + + MC3081: '{0}' is a read-only property of type IList or IDictionary and cannot be set because it does not have a public or internal get accessor. + + + MC3082: '{0}' cannot be set as the value of a Trigger's Property attribute because it does not have a public or internal get accessor. + + + MC3083: Cannot access the delegate type '{0}' for the '{1}' event. '{0}' has incorrect access level or its assembly does not allow access. + + + MC3084: Cannot nest XML data islands. + + + MC3085: '{0}' element or property cannot contain an XML data island. + + + MC3086: Parent element or property '{0}' requires an XML data island. To distinguish an XML island from surrounding XAML, wrap the XML data island in <x:XData> ... </x:XData>. + + + MC3087: Cannot set content property '{0}' on element '{1}'. '{0}' has incorrect access level or its assembly does not allow access. + + + MC3088: Property elements cannot be in the middle of an element's content. They must be before or after the content. + + + MC3089: The object '{0}' already has a child and cannot add '{1}'. '{0}' can accept only one child. + + + MC3090: TypeConverter syntax error encountered while processing initialization string '{0}'. Element attributes are not allowed on objects created via TypeConverter. + + + MC3091: '{0}' is not valid. Markup extensions require only spaces between the markup extension name and the first parameter. Cannot have comma or equals sign before the first parameter. + + + MC3092: XmlLangProperty attribute must specify a property name. + + + MC3093: Cannot set Name attribute value '{0}' on element '{1}'. '{1}' is under the scope of element '{2}', which already had a name registered when it was defined in another scope. + + + MC3094: Cannot convert string value '{0}' to type '{1}'. + + + MC3095: Close tag must immediately follow TypeConverter initialization string '{0}'. + + + MC3096: Token is not valid. + + + MC3098: Unexpected token '{0}' at position '{1}'. + + + MC3099: Cannot load assembly '{0}' because a different version of that same assembly is loaded '{1}'. + + + MC3100: '{0}' XML namespace prefix does not map to a namespace URI, so cannot resolve property '{1}'. + + + MC4001: Style does not support both {0} tags and Style.{1} property tags for a single Style. Use one or the other. + + + MC4002: The Style property tag '{0}' can only be specified directly under a Style tag. + + + MC4003: Cannot resolve the Style {0} '{1}'. Verify that the owning type is the Style's TargetType, or use Class.Property syntax to specify the {0}. + + + MC4004: Style cannot contain child '{0}'. Style child must be a Setter because it is added to the Setters collection. + + + MC4005: Cannot find the Style {0} '{1}' on the type '{2}'. + + + MC4006: Tags of type '{0}' are not supported in Style sections. + + + MC4007: The event '{0}' cannot be specified on a Target tag in a Style. Use an EventSetter instead. + + + MC4008: The text '{0}' is not allowed at this location within a Style section. + + + MC4009: The property '{0}' cannot be set on Style. + + + MC4011: TargetName property cannot be set on a Style Setter. + + + MC4101: The Name '{0}' has already been defined. Names must be unique. + + + MC4102: Tags of type '{0}' are not supported in template sections. + + + MC4103: The template property tag '{0}' can only be specified immediately after a ControlTemplate tag. + + + MC4104: The property '{0}' cannot be set as a property element on template. Only Triggers and Storyboards are allowed as property elements. + + + MC4105: The text '{0}' is not allowed at this location within a template section. + + + MC4106: Cannot resolve the Template Property '{0}'. Verify that the owning type is the Style's TargetType, or use Class.Property syntax to specify the property. + + + MC4107: A template can have only a single root element. '{0}' is not allowed. + + + MC4108: The root of a Template content section cannot contain an element of type '{0}'. Only FrameworkElement and FrameworkContentElement types are valid. + + + MC4109: Cannot find the Template Property '{0}' on the type '{1}'. + + + MC4110: SourceName property cannot be set within Style.Triggers section. + + + MC4111: Cannot find the Trigger target '{0}'. (The target must appear before any Setters, Triggers, or Conditions that use it.) + + + MC4301: Type name '{0}' does not have the expected format 'className, assembly'. + + + MC4401: Serializer does not support Convert operations. + + + MC4402: Serializer does not support custom BAML serialization operations. + + + MC4501: Major and minor version number components cannot be negative. + + + MC4502: The feature ID string cannot have length 0. + + + MC4601: Choice valid only in AlternateContent. + + + MC4602: Choice cannot follow a Fallback. + + + MC4603: Choice must contain a Requires attribute. + + + MC4604: Requires attribute must contain a valid namespace prefix. + + + MC4605: Fallback valid only in AlternateContent. + + + MC4606: AlternateContent must contain one or more Choice elements. + + + MC4607: AlternateContent must contain only one Fallback element. + + + MC4608: '{0}' attribute is not valid for element '{1}'. + + + MC4609: Unrecognized compatibility element '{0}'. + + + MC4610: '{0}' element is not a valid child of AlternateContent. Only Choice and Fallback elements are valid children of an AlternateContent element. + + + MC4611: '{0}' format is not valid. + + + MC4612: '{0}' prefix is not defined. + + + MC4614: Unrecognized compatibility attribute '{0}'. + + + MC4615: '{0}' namespace is declared ProcessContent but is not declared Ignorable. + + + MC4617: Duplicate ProcessContent declaration for element '{1}' in namespace '{0}'. + + + MC4618: Cannot have both a specific and a wildcard ProcessContent declaration for namespace '{0}'. + + + MC4619: Duplicate wildcard ProcessContent declaration for namespace '{0}'. + + + MC4626: MustUnderstand condition failed on namespace '{0}'. + + + MC4630: Namespace '{0}' has items declared to be preserved but is not declared ignorable. + + + MC4631: Duplicate Preserve declaration for element '{1}' in namespace '{0}'. + + + MC4632: Cannot have both a specific and a wildcard Preserve declaration for namespace '{0}'. + + + MC4633: Duplicate wildcard Preserve declaration for namespace '{0}'. + + + MC4634: '{0}' attribute value is not a valid XML name. + + + MC4640: Namespace '{0}' is marked as compatible with itself using XmlnsCompatibilityAttribute. A namespace cannot directly or indirectly override itself. + + + MC6000: Project file must include the .NET Framework assembly '{0}' in the reference list. + + + MC6001: Markup file is not valid. Specify a source markup file with an .xaml extension. + + + MC6002: Unrecognized tag '{0}:{1}' in namespace 'http://schemas.microsoft.com/winfx/2006/xaml'. Note that tag names are case sensitive. + + + MC6003: '{0}:{1}' contains '{2}'. '{0}:{1}' cannot contain nested content. + + + MC6004: '{0}:{1}' contains '{2}'. '{0}:{1}' can contain only a CDATA or text section. + + + MC6005: {0}="{1}" is not valid. '{1}' is not a valid event handler method name. Only instance methods on the generated or code-behind class are valid. + + + MC6006: {0}.{1}="{2}" is not valid. '{1}' must be a RoutedEvent registered with a name that ends with the keyword "Event". + + + MC6007: '{1}' is not valid. '{0}' is not an event on '{2}'. + + + MC6008: '{0}' is not installed properly on this machine. It must be listed in the <compilers> section of machine.config. + + + MC6009: {0}:ClassModifier attribute cannot be specified on the root tag because a {0}:Class attribute is also required. Either add a {0}:Class attribute or remove the {0}:ClassModifier attribute. + + + MC6010: '{0}:{1}' cannot be specified as the root element. + + + MC6011: '{0}' event has a generic event handler delegate type '{1}'. The type parameters of '{1}' cannot be bound with an appropriate type argument because the containing tag '{2}' is not a generic type. + + + MC6012: '{0}' event has a generic event handler delegate type '{1}'. The type parameter '{2}' on '{1}' does not match any type parameters on the containing generic tag '{3}'. + + + MC6013: {0}:ClassModifier="{1}" is not valid for the language {2}. + + + MC6014: {0}:FieldModifier="{1}" is not valid for the language {2}. + + + MC6015: '{0}' cannot be set on the '{1}:{2}' tag. + + + MC6016: {0}:Class attribute is missing. It is required when a {0}:Subclass attribute is specified. + + + MC6017: '{0}' cannot be the root of a XAML file because it was defined using XAML. + + + MC6018: '{0}' class name is not valid for the locally defined XAML root element. + + + MC6019: '{0}' namespace is not valid for the locally defined XAML root element '{1}'. + + + MC6020: {0}:TypeArguments='{1}' is not valid on the tag '{2}'. Either '{2}' is not a generic type or the number of Type arguments in the attribute is wrong. Remove the {0}:TypeArguments attribute because it is allowed only on generic types, or fix its value to match the arity of the generic type '{2}'. + + + MC6021: {0}:FieldModifier cannot be specified on this tag because it has either no {0}:Name or Name attribute set, or the tag is locally defined and has a Name attribute set, which is not allowed. + + + MC6022: Only a root tag can specify attribute '{0}:{1}'. + + + MC6023: Because '{0}' is implemented in the same assembly, you must set the {1}:Name attribute rather than the Name attribute. + + + MC6024: '{0}' root element requires a {1}:Class attribute to support event handlers in the XAML file. Either remove the event handler for the {2} event, or add a {1}:Class attribute to the root element. + + + MC6025: '{0}' root element is a generic type and requires a {1}:Class attribute to support the {1}:TypeArguments attribute specified on the root element tag. + + + MC6026: '{0}' root element requires a {1}:Class attribute because '{2}' contains a {1}:Code tag. Either remove {1}:Code and its contents, or add a {1}:Class attribute to the root element. + + + MC6027: {0}:{1}="{2}" is not valid. '{2}' is not a valid {3}class name. + + + MC6028: {0}:TypeArguments="{1}" is not valid. '{2}' is not a valid type name reference for the generic argument at position '{3}'. + + + MC6029: '{0}' name is not valid in the default namespace '{1}'. Correct the RootNamespace tag value in the project file. + + + MC6030: {0}="{1}" is not valid. '{0}' event attribute value cannot be a string that is empty or has only white space. + + + MC6031: {0}:FieldModifier attribute cannot be specified because a {0}:Class attribute is also required to generate a Name field with the specified access modifier. Either add a {0}:Class attribute on the root tag or remove the {0}:FieldModifier attribute. + + + A '{0}' is named '{1}'. Do not name ResourceDictionary contents because their instantiation is deferred. + + + MC7001: Premature string termination encountered. + + + MC7002: Missing end quote encountered while parsing token. + + + MC7003: Extra data encountered after token while parsing. + + + MC7004: Empty token encountered while parsing. + + + MC8001: Encountered a closing BracketCharacter '{0}' at Line Number '{1}' and Line Position '{2}' without a corresponding opening BracketCharacter. + + + MC8002: BracketCharacter '{0}' at Line Number '{1}' and Line Position '{2}' does not have a corresponding opening/closing BracketCharacter. + + \ No newline at end of file diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Resources/window.ico b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Resources/window.ico new file mode 100644 index 00000000000..8b74374fbd5 Binary files /dev/null and b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Resources/window.ico differ diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/SR.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/SR.cs new file mode 100644 index 00000000000..08db615610e --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/SR.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Resources; + +namespace MS.Utility +{ + internal static partial class SR + { + public static string Get(string name) + { + return GetResourceString(name, null); + } + + public static string Get(string name, params object[] args) + { + return Format(GetResourceString(name, null), args); + } + + // Expose ResourceManager instance to allow PresentationBuildTask MSBuild tasks + // that derive from Task to pass ResourceManager to their base class constructor. + // (Generated SR.common.cs always defines ResourceManager as private. GenerateCommonSRSource + // target should be updated to accept a parameter for ResourceManager property access + // modifier.) + public static ResourceManager SharedResourceManager + { + get + { + return ResourceManager; + } + } + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/dir.props b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/dir.props new file mode 100644 index 00000000000..0a383a106f4 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/dir.props @@ -0,0 +1,11 @@ + + + + + + + + $(MajorVersion).$(MinorVersion).$(BuildNumberMajor).$(BuildNumberMinor) + SilverlightExtension + + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Media/ParserStreamGeometryContext.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Media/ParserStreamGeometryContext.cs new file mode 100644 index 00000000000..aec3192d730 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Media/ParserStreamGeometryContext.cs @@ -0,0 +1,761 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// This class is used to compress a Path to BAML. +// +// At compile-time this api is called into to "flatten" graphics calls to a BinaryWriter +// At run-time this api is called into to rehydrate the flattened graphics calls +// via invoking methods on a supplied StreamGeometryContext. +// +// Via this compression - we reduce the time spent parsing at startup, we create smaller baml, +// and we reduce creation of temporary strings. +// +//--------------------------------------------------------------------------- + +using MS.Internal; + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Security; +using System.Security.Permissions; +using System.IO; +using MS.Utility; + +#if PBTCOMPILER + +using MS.Internal.Markup; + +namespace MS.Internal.Markup +#else + +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Media3D; +using MS.Internal.PresentationCore; + +namespace MS.Internal.Media +#endif +{ + /// + /// ParserStreamGeometryContext + /// + internal class ParserStreamGeometryContext : StreamGeometryContext + { + enum ParserGeometryContextOpCodes : byte + { + BeginFigure = 0, + LineTo = 1, + QuadraticBezierTo = 2, + BezierTo = 3, + PolyLineTo = 4, + PolyQuadraticBezierTo = 5, + PolyBezierTo = 6, + ArcTo = 7, + Closed = 8, + FillRule = 9, + } + + private const byte HighNibble = 0xF0; + private const byte LowNibble = 0x0F; + + private const byte SetBool1 = 0x10; // 00010000 + private const byte SetBool2 = 0x20; // 00100000 + private const byte SetBool3 = 0x40; // 01000000 + private const byte SetBool4 = 0x80; // 10000000 + + #region Constructors + + /// + /// This constructor exists to prevent external derivation + /// + internal ParserStreamGeometryContext(BinaryWriter bw) + { + _bw = bw; + } + + #endregion Constructors + + + #region internal Methods + +#if PRESENTATION_CORE + internal void SetFillRule(FillRule fillRule) +#else + internal void SetFillRule(bool boolFillRule) +#endif + { +#if PRESENTATION_CORE + bool boolFillRule = FillRuleToBool(fillRule); +#endif + + byte packedByte = PackByte(ParserGeometryContextOpCodes.FillRule, boolFillRule, false); + + _bw.Write(packedByte); + } + + /// + /// BeginFigure - Start a new figure. + /// + /// + /// Stored as [PointAndTwoBools] (see SerializepointAndTwoBools method). + /// + + public override void BeginFigure(Point startPoint, bool isFilled, bool isClosed) + { + // + // We need to update the BeginFigure block of the last figure (if + // there was one). + // + FinishFigure(); + + _startPoint = startPoint; + _isFilled = isFilled; + _isClosed = isClosed; + + _figureStreamPosition = CurrentStreamPosition; + + // + // This will be overwritten later when we start the next figure (i.e. when we're sure isClosed isn't + // going to change). We write it out now to ensure that we reserve exactly the right amount of space. + // Note that the number of bytes written is dependant on the particular value of startPoint, since + // we can compress doubles when they are in fact integral. + // + SerializePointAndTwoBools(ParserGeometryContextOpCodes.BeginFigure, startPoint, isFilled, isClosed); + } + + /// + /// LineTo - append a LineTo to the current figure. + /// + /// + /// Stored as [PointAndTwoBools] (see SerializepointAndTwoBools method). + /// + public override void LineTo(Point point, bool isStroked, bool isSmoothJoin) + { + SerializePointAndTwoBools(ParserGeometryContextOpCodes.LineTo, point, isStroked, isSmoothJoin); + } + + /// + /// QuadraticBezierTo - append a QuadraticBezierTo to the current figure. + /// + /// + /// Stored as [PointAndTwoBools] [Number] [Number] + /// + public override void QuadraticBezierTo(Point point1, Point point2, bool isStroked, bool isSmoothJoin) + { + SerializePointAndTwoBools(ParserGeometryContextOpCodes.QuadraticBezierTo, point1, isStroked, isSmoothJoin); + + XamlSerializationHelper.WriteDouble(_bw, point2.X); + XamlSerializationHelper.WriteDouble(_bw, point2.Y); + } + + /// + /// BezierTo - apply a BezierTo to the current figure. + /// + /// + /// Stored as [PointAndTwoBools] [Number] [Number] [Number] [Number] + /// + public override void BezierTo(Point point1, Point point2, Point point3, bool isStroked, bool isSmoothJoin) + { + SerializePointAndTwoBools(ParserGeometryContextOpCodes.BezierTo, point1, isStroked, isSmoothJoin); + + XamlSerializationHelper.WriteDouble(_bw, point2.X); + XamlSerializationHelper.WriteDouble(_bw, point2.Y); + + XamlSerializationHelper.WriteDouble(_bw, point3.X); + XamlSerializationHelper.WriteDouble(_bw, point3.Y); + } + + /// + /// PolyLineTo - append a PolyLineTo to the current figure. + /// + /// + /// Stored as [ListOfPointAndTwoBools] (see SerializeListOfPointsAndTwoBools method). + /// + public override void PolyLineTo(IList points, bool isStroked, bool isSmoothJoin) + { + SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes.PolyLineTo, points, isStroked, isSmoothJoin); + } + + /// + /// PolyQuadraticBezierTo - append a PolyQuadraticBezierTo to the current figure. + /// + /// + /// Stored as [ListOfPointAndTwoBools] (see SerializeListOfPointsAndTwoBools method). + /// + public override void PolyQuadraticBezierTo(IList points, bool isStroked, bool isSmoothJoin) + { + SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes.PolyQuadraticBezierTo, points, isStroked, isSmoothJoin); + } + + /// + /// PolyBezierTo - append a PolyBezierTo to the current figure. + /// + /// + /// Stored as [ListOfPointAndTwoBools] (see SerializeListOfPointsAndTwoBools method). + /// + public override void PolyBezierTo(IList points, bool isStroked, bool isSmoothJoin) + { + SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes.PolyBezierTo, points, isStroked, isSmoothJoin); + } + + /// + /// ArcTo - append an ArcTo to the current figure. + /// + /// + /// Stored as [PointAndTwoBools] [Packed byte for isLargeArc and sweepDirection] [Pair of Numbers for Size] [Pair of Numbers for rotation Angle] + /// + /// Also note that we've special cased this method signature to avoid moving the enum for SweepDirection into PBT (will require codegen changes). + /// +#if PBTCOMPILER + public override void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, bool sweepDirection, bool isStroked, bool isSmoothJoin) +#else + public override void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked, bool isSmoothJoin) +#endif + { + SerializePointAndTwoBools(ParserGeometryContextOpCodes.ArcTo, point, isStroked, isSmoothJoin); + + // + // Pack isLargeArc & sweepDirection into a single byte. + // + byte packMe = 0; + if (isLargeArc) + { + packMe = LowNibble; + } + +#if PBTCOMPILER + if (sweepDirection) +#else + if (SweepToBool(sweepDirection)) +#endif + { + packMe |= HighNibble; + } + + _bw.Write(packMe); + + // + // Write out Size & Rotation Angle. + // + XamlSerializationHelper.WriteDouble(_bw, size.Width); + XamlSerializationHelper.WriteDouble(_bw, size.Height); + XamlSerializationHelper.WriteDouble(_bw, rotationAngle); + } + + internal bool FigurePending + { + get + { + return (_figureStreamPosition > -1); + } + } + + internal int CurrentStreamPosition + { + get + { + return checked((int)_bw.Seek(0, SeekOrigin.Current)); + } + } + + internal void FinishFigure() + { + if (FigurePending) + { + int currentOffset = CurrentStreamPosition; + + // + // Go back and overwrite our existing begin figure block. See comment in BeginFigure. + // + _bw.Seek(_figureStreamPosition, SeekOrigin.Begin); + SerializePointAndTwoBools(ParserGeometryContextOpCodes.BeginFigure, _startPoint, _isFilled, _isClosed); + + _bw.Seek(currentOffset, SeekOrigin.Begin); + } + } + + /// + /// This is the same as the Close call: + /// Closes the Context and flushes the content. + /// Afterwards the Context can not be used anymore. + /// This call does not require all Push calls to have been Popped. + /// + internal override void DisposeCore() + { + } + + /// + /// SetClosedState - Sets the current closed state of the figure. + /// + internal override void SetClosedState(bool closed) + { + _isClosed = closed; + } + + /// + /// Mark that the stream is Done. + /// + internal void MarkEOF() + { + // + // We need to update the BeginFigure block of the last figure (if + // there was one). + // + FinishFigure(); + _bw.Write((byte) ParserGeometryContextOpCodes.Closed); + } + +#if PRESENTATION_CORE + internal static void Deserialize(BinaryReader br, StreamGeometryContext sc, StreamGeometry geometry) + { + bool closed = false; + Byte currentByte; + + while (!closed) + { + currentByte = br.ReadByte(); + + ParserGeometryContextOpCodes opCode = UnPackOpCode(currentByte); + + switch(opCode) + { + case ParserGeometryContextOpCodes.FillRule : + DeserializeFillRule(br, currentByte, geometry); + break; + + case ParserGeometryContextOpCodes.BeginFigure : + DeserializeBeginFigure(br, currentByte, sc); + break; + + case ParserGeometryContextOpCodes.LineTo : + DeserializeLineTo(br, currentByte, sc); + break; + + case ParserGeometryContextOpCodes.QuadraticBezierTo : + DeserializeQuadraticBezierTo(br, currentByte, sc); + break; + + case ParserGeometryContextOpCodes.BezierTo : + DeserializeBezierTo(br, currentByte, sc); + break; + + case ParserGeometryContextOpCodes.PolyLineTo : + DeserializePolyLineTo(br, currentByte, sc); + break; + + case ParserGeometryContextOpCodes.PolyQuadraticBezierTo : + DeserializePolyQuadraticBezierTo(br, currentByte, sc); + break; + + case ParserGeometryContextOpCodes.PolyBezierTo : + DeserializePolyBezierTo(br, currentByte, sc); + break; + + case ParserGeometryContextOpCodes.ArcTo : + DeserializeArcTo(br, currentByte, sc); + break; + + case ParserGeometryContextOpCodes.Closed : + closed = true; + break; + } + } + } +#endif + #endregion internal Methods + + #region private Methods + + // + // Deserialization Methods. + // + // These are only required at "runtime" - therefore only in PRESENTATION_CORE + // + +#if PRESENTATION_CORE + + private static void DeserializeFillRule(BinaryReader br, Byte firstByte, StreamGeometry geometry) + { + bool boolFillRule; + bool unused; + FillRule fillRule; + + UnPackBools(firstByte, out boolFillRule, out unused); + + fillRule = BoolToFillRule(boolFillRule); + + geometry.FillRule = fillRule; + + } + + private static void DeserializeBeginFigure(BinaryReader br, Byte firstByte, StreamGeometryContext sc) + { + Point point; + bool isFilled; + bool isClosed; + + DeserializePointAndTwoBools(br, firstByte, out point, out isFilled, out isClosed); + + sc.BeginFigure(point, isFilled, isClosed); + } + + private static void DeserializeLineTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc) + { + Point point; + bool isStroked; + bool isSmoothJoin; + + DeserializePointAndTwoBools(br, firstByte, out point, out isStroked, out isSmoothJoin); + + sc.LineTo(point, isStroked, isSmoothJoin); + } + + private static void DeserializeQuadraticBezierTo(BinaryReader br, byte firstByte, StreamGeometryContext sc) + { + Point point1; + Point point2 = new Point(); + bool isStroked; + bool isSmoothJoin; + + DeserializePointAndTwoBools(br, firstByte, out point1, out isStroked, out isSmoothJoin); + + point2.X = XamlSerializationHelper.ReadDouble(br); + point2.Y = XamlSerializationHelper.ReadDouble(br); + + sc.QuadraticBezierTo(point1, point2, isStroked, isSmoothJoin); + } + + private static void DeserializeBezierTo(BinaryReader br, byte firstByte, StreamGeometryContext sc) + { + Point point1; + Point point2 = new Point(); + Point point3 = new Point(); + + bool isStroked; + bool isSmoothJoin; + + DeserializePointAndTwoBools(br, firstByte, out point1, out isStroked, out isSmoothJoin); + + point2.X = XamlSerializationHelper.ReadDouble(br); + point2.Y = XamlSerializationHelper.ReadDouble(br); + + point3.X = XamlSerializationHelper.ReadDouble(br); + point3.Y = XamlSerializationHelper.ReadDouble(br); + + sc.BezierTo(point1, point2, point3, isStroked, isSmoothJoin); + } + + private static void DeserializePolyLineTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc) + { + bool isStroked; + bool isSmoothJoin; + IList points; + + points = DeserializeListOfPointsAndTwoBools(br, firstByte, out isStroked, out isSmoothJoin); + + sc.PolyLineTo(points, isStroked, isSmoothJoin); + } + + private static void DeserializePolyQuadraticBezierTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc) + { + bool isStroked; + bool isSmoothJoin; + IList points; + + points = DeserializeListOfPointsAndTwoBools(br, firstByte, out isStroked, out isSmoothJoin); + + sc.PolyQuadraticBezierTo(points, isStroked, isSmoothJoin); + } + + private static void DeserializePolyBezierTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc) + { + bool isStroked; + bool isSmoothJoin; + IList points; + + points = DeserializeListOfPointsAndTwoBools(br, firstByte, out isStroked, out isSmoothJoin); + + sc.PolyBezierTo(points, isStroked, isSmoothJoin); + } + + + private static void DeserializeArcTo(BinaryReader br, byte firstByte, StreamGeometryContext sc) + { + Point point; + Size size = new Size(); + double rotationAngle; + bool isStroked; + bool isSmoothJoin; + bool isLargeArc; + SweepDirection sweepDirection; + + DeserializePointAndTwoBools(br, firstByte, out point, out isStroked, out isSmoothJoin); + + // Read the packed byte for isLargeArd & sweepDirection. + + // + // Pack isLargeArc & sweepDirection into a signle byte. + // + byte packedByte = br.ReadByte(); + + isLargeArc = ((packedByte & LowNibble) != 0); + + sweepDirection = BoolToSweep(((packedByte & HighNibble) != 0)); + + + size.Width = XamlSerializationHelper.ReadDouble(br); + size.Height = XamlSerializationHelper.ReadDouble(br); + rotationAngle = XamlSerializationHelper.ReadDouble(br); + + sc.ArcTo(point, size, rotationAngle, isLargeArc, sweepDirection, isStroked, isSmoothJoin); + } + + // + // Private Deserialization helpers. + // + + private static void UnPackBools(byte packedByte, out bool bool1, out bool bool2) + { + bool1 = (packedByte & SetBool1) != 0; + bool2 = (packedByte & SetBool2) != 0; + } + + private static void UnPackBools(byte packedByte, out bool bool1, out bool bool2, out bool bool3, out bool bool4) + { + bool1 = (packedByte & SetBool1) != 0; + bool2 = (packedByte & SetBool2) != 0; + bool3 = (packedByte & SetBool3) != 0; + bool4 = (packedByte & SetBool4) != 0; + } + + private static ParserGeometryContextOpCodes UnPackOpCode(byte packedByte) + { + return ((ParserGeometryContextOpCodes) (packedByte & 0x0F)); + } + + private static IList DeserializeListOfPointsAndTwoBools(BinaryReader br, Byte firstByte, out bool bool1, out bool bool2) + { + int count; + IList points; + Point point; + + // Pack the two bools into one byte + UnPackBools(firstByte, out bool1, out bool2); + + count = br.ReadInt32(); + + points = new List(count); + + for(int i = 0; i < count; i++) + { + point = new Point(XamlSerializationHelper.ReadDouble(br), + XamlSerializationHelper.ReadDouble(br)); + + points.Add(point); + } + + return points; + } + + + private static void DeserializePointAndTwoBools(BinaryReader br, Byte firstByte, out Point point, out bool bool1, out bool bool2) + { + bool isScaledIntegerX = false; + bool isScaledIntegerY = false; + + UnPackBools(firstByte, out bool1, out bool2, out isScaledIntegerX, out isScaledIntegerY); + + point = new Point(DeserializeDouble(br, isScaledIntegerX), + DeserializeDouble(br, isScaledIntegerY)); + } + + private static Double DeserializeDouble(BinaryReader br, bool isScaledInt) + { + if (isScaledInt) + { + return XamlSerializationHelper.ReadScaledInteger(br); + } + else + { + return XamlSerializationHelper.ReadDouble(br); + } + } + + // + // Private serialization helpers + // + + private static SweepDirection BoolToSweep(bool value) + { + if(!value) + return SweepDirection.Counterclockwise; + else + return SweepDirection.Clockwise; + } + + private static bool SweepToBool(SweepDirection sweep) + { + if (sweep == SweepDirection.Counterclockwise) + return false; + else + return true; + } + + private static FillRule BoolToFillRule(bool value) + { + if(!value) + return FillRule.EvenOdd; + else + return FillRule.Nonzero; + } + + private static bool FillRuleToBool(FillRule fill) + { + if (fill == FillRule.EvenOdd) + return false; + else + return true; + } + +#endif + + // + // SerializePointAndTwoBools + // + // Binary format is : + // + // + // + // Where : + // := OpCode + bool1 + bool2 + isScaledIntegerX + isScaledIntegerY + // := | | + // := | | + // := + // + // By packing the flags for isScaledInteger into the first byte - we save 2 extra bytes per number for the common case. + // + // As a result - most LineTo's (and other operations) will be stored in 9 bytes. + // Some LineTo's will be 6 (or even sometimes 3) + // Max LineTo will be 19 (two doubles). + private void SerializePointAndTwoBools(ParserGeometryContextOpCodes opCode, + Point point, + bool bool1, + bool bool2) + { + int intValueX = 0; + int intValueY = 0; + bool isScaledIntegerX, isScaledIntegerY; + + isScaledIntegerX = XamlSerializationHelper.CanConvertToInteger(point.X, ref intValueX); + isScaledIntegerY = XamlSerializationHelper.CanConvertToInteger(point.Y, ref intValueY); + + _bw.Write(PackByte(opCode, bool1, bool2, isScaledIntegerX, isScaledIntegerY)); + + SerializeDouble(point.X, isScaledIntegerX, intValueX); + SerializeDouble(point.Y, isScaledIntegerY, intValueY); + } + + // SerializeListOfPointsAndTwoBools + // + // Binary format is : + // + // ... + // + // := OpCode + bool1 + bool2 + // := int32 + // := | | + private void SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes opCode, IList points, bool bool1, bool bool2) + { + // Pack the two bools into one byte + Byte packedByte = PackByte(opCode, bool1, bool2); + _bw.Write(packedByte); + + // Write the count. + _bw.Write(points.Count); + + // Write out all the Points + for(int i = 0; i < points.Count; i++) + { + XamlSerializationHelper.WriteDouble(_bw, points[i].X); + XamlSerializationHelper.WriteDouble(_bw, points[i].Y); + } + } + + private void SerializeDouble(double value, bool isScaledInt, int scaledIntValue) + { + if (isScaledInt) + { + _bw.Write(scaledIntValue); + } + else + { + XamlSerializationHelper.WriteDouble(_bw, value); + } + } + + private static byte PackByte(ParserGeometryContextOpCodes opCode, bool bool1, bool bool2) + { + return PackByte(opCode, bool1, bool2, false, false); + } + + + // PackByte + // Packs an op-code, and up to 4 booleans into a single byte. + // + // Binary format is : + // First 4 bits map directly to the op-code. + // Next 4 bits map to booleans 1 - 4. + // + // Like this: + // + // 7| 6 | 5 | 4 | 3 | 2 | 1 | 0 | + // |||<- Op Code -> + // + private static byte PackByte(ParserGeometryContextOpCodes opCode, bool bool1, bool bool2, bool bool3, bool bool4) + { + byte packedByte = (byte) opCode; + + if (packedByte >= 16) + { + throw new ArgumentException(SR.Get(SRID.UnknownPathOperationType)); + } + + if (bool1) + { + packedByte |= SetBool1; + } + + if (bool2) + { + packedByte |= SetBool2; + } + + if (bool3) + { + packedByte |= SetBool3; + } + + if (bool4) + { + packedByte |= SetBool4; + } + + return packedByte; + } + + #endregion private Methods + + private BinaryWriter _bw; + + Point _startPoint; + bool _isClosed; + bool _isFilled; + + int _figureStreamPosition = -1; + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Media/XamlSerializationHelper.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Media/XamlSerializationHelper.cs new file mode 100644 index 00000000000..fdb3fd6fe9e --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Media/XamlSerializationHelper.cs @@ -0,0 +1,468 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: Utilities for converting types to custom Binary format +// +//--------------------------------------------------------------------------- + +using System; +using System.IO; +using System.Collections; +using System.Globalization; // CultureInfo + +#if PRESENTATION_CORE +using MS.Internal.PresentationCore; // FriendAccessAllowed +#elif PRESENTATIONFRAMEWORK +using MS.Internal.PresentationFramework; +#endif + +#if PBTCOMPILER +using System.Collections.Generic; +using TypeConverterHelper = MS.Internal.Markup; + +namespace MS.Internal.Markup +#else +using System.Windows; +using System.Windows.Media ; +using System.Windows.Media.Media3D; +using TypeConverterHelper = System.Windows.Markup; + +namespace MS.Internal.Media +#endif +{ + +#if PBTCOMPILER + + + // + // Internal class used during serialization of Point3D, or Vectors. + // + // We define this struct so that we can create a collection of types during serialization. + // If we used defined avalon types, like Point & Vector, we'd have to bring these into PBT + // with a compiler change everytime these types are changed. + // + // The type is called "ThreeDoubles" to make clear what it is and what it's for. + // + // If either Vector3D or Point3D changes - we will need to change this code. + // + internal class ThreeDoublesMarkup + { + + internal ThreeDoublesMarkup( double X, double Y, double Z) + { + _x = X; + _y = Y; + _z = Z; + } + + internal double X + { + get + { + return _x; + } + } + + internal double Y + { + get + { + return _y; + } + } + + internal double Z + { + get + { + return _z; + } + } + + double _x ; + double _y ; + double _z ; + + } + + internal struct Point + { + internal Point(double x, double y) + { + _x = x; + _y = y; + } + + internal double X + { + set + { + _x = value; + } + get + { + return _x; + } + } + + internal double Y + { + set + { + _y = value; + } + get + { + return _y; + } + } + + private double _x; + private double _y; + } + + internal struct Size + { + internal Size(double width, double height) + { + _width = width; + _height = height; + } + + internal double Width + { + set + { + _width = value; + } + get + { + return _width; + } + } + + internal double Height + { + set + { + _height = value; + } + get + { + return _height; + } + } + + private double _width; + private double _height; + } + + +#endif + + internal static class XamlSerializationHelper + { + + // ===================================================== + // + // All PBT specific types and methods go here. + // + // ====================================================== + + + + internal enum SerializationFloatType : byte + { + Unknown = 0, + Zero = 1, + One = 2, + MinusOne = 3, + ScaledInteger = 4, + Double = 5, + Other + } + + + /// + /// Serialize this object using the passed writer in compact BAML binary format. + /// + /// + /// This is called ONLY from the Parser and is not a general public method. + /// +#if !PBTCOMPILER + [FriendAccessAllowed] // Built into Core, also used by Framework. +#endif + internal static bool SerializePoint3D(BinaryWriter writer, string stringValues) + { +#if PBTCOMPILER + List point3Ds = ParseThreeDoublesCollection(stringValues, TypeConverterHelper.InvariantEnglishUS); + ThreeDoublesMarkup curPoint; +#else + Point3DCollection point3Ds = Point3DCollection.Parse( stringValues ) ; + Point3D curPoint ; +#endif + + // Write out the size. + writer.Write( ( uint ) point3Ds.Count ) ; + + // Write out the doubles. + for ( int i = 0; i < point3Ds.Count ; i ++ ) + { + curPoint = point3Ds[i] ; + + WriteDouble( writer, curPoint.X); + WriteDouble( writer, curPoint.Y); + WriteDouble( writer, curPoint.Z); + } + + return true ; + } + + /// + /// Serialize this object using the passed writer in compact BAML binary format. + /// + /// + /// This is called ONLY from the Parser and is not a general public method. + /// +#if !PBTCOMPILER + [FriendAccessAllowed] // Built into Core, also used by Framework. +#endif + internal static bool SerializeVector3D(BinaryWriter writer, string stringValues) + { +#if PBTCOMPILER + List points = ParseThreeDoublesCollection(stringValues, TypeConverterHelper.InvariantEnglishUS); + ThreeDoublesMarkup curPoint; +#else + Vector3DCollection points = Vector3DCollection.Parse( stringValues ) ; + Vector3D curPoint ; +#endif + + // Write out the size. + writer.Write( ( uint ) points.Count ) ; + + // Write out the doubles. + for ( int i = 0; i < points.Count ; i ++ ) + { + curPoint = points[ i ] ; + + WriteDouble( writer, curPoint.X); + WriteDouble( writer, curPoint.Y); + WriteDouble( writer, curPoint.Z); + } + + return true ; + } + + /// + /// Serialize this object using the passed writer in compact BAML binary format. + /// + /// + /// This is called ONLY from the Parser and is not a general public method. + /// +#if !PBTCOMPILER + [FriendAccessAllowed] // Built into Core, also used by Framework. +#endif + internal static bool SerializePoint(BinaryWriter writer, string stringValue) + { +#if PBTCOMPILER + List points = ParsePointCollection(stringValue, TypeConverterHelper.InvariantEnglishUS); + Point curPoint; +#else + PointCollection points = PointCollection.Parse( stringValue ) ; + Point curPoint ; +#endif + + // Write out the size. + writer.Write( ( uint ) points.Count ) ; + + // Write out the doubles. + for ( int i = 0; i < points.Count ; i ++ ) + { + curPoint = points[ i ] ; + + WriteDouble( writer, curPoint.X); + WriteDouble( writer, curPoint.Y); + } + + return true ; + } + + private const double scaleFactor = 1000000 ; // approx == 2^20 + private const double inverseScaleFactor = 0.000001 ; // approx = 1 / 2^20 + + // + // Write a double into our internal binary format + // + // + // The format is : + // ( <4 bytes for scaledinteger> | < 8 bytes for double> ) + // + internal static void WriteDouble( BinaryWriter writer, Double value ) + { + if ( value == 0.0 ) + { + writer.Write( (byte) SerializationFloatType.Zero ) ; + } + else if ( value == 1.0 ) + { + writer.Write( (byte) SerializationFloatType.One ) ; + } + else if ( value == -1.0 ) + { + writer.Write( (byte) SerializationFloatType.MinusOne ) ; + } + else + { + int intValue = 0 ; + + if ( CanConvertToInteger( value, ref intValue ) ) + { + writer.Write( (byte) SerializationFloatType.ScaledInteger ) ; + writer.Write( intValue ) ; + } + else + { + writer.Write( (byte) SerializationFloatType.Double ) ; + writer.Write( value ) ; + } + } + } + +#if !PBTCOMPILER + // + // Read a double from our internal binary format. + // We assume that the binary reader is at the start of a byte. + // + internal static double ReadDouble( BinaryReader reader ) + { + SerializationFloatType type = ( SerializationFloatType ) reader.ReadByte(); + + switch( type ) + { + case SerializationFloatType.Zero : + return 0.0 ; + + case SerializationFloatType.One : + return 1.0 ; + + case SerializationFloatType.MinusOne : + return -1.0 ; + + case SerializationFloatType.ScaledInteger : + return ReadScaledInteger( reader ); + + case SerializationFloatType.Double : + return reader.ReadDouble(); + + default: + throw new ArgumentException(SR.Get(SRID.FloatUnknownBamlType)); + } + + } + + internal static double ReadScaledInteger(BinaryReader reader ) + { + double value = (double) reader.ReadInt32(); + value = value * inverseScaleFactor ; + + return value ; + } + +#endif + +#if PBTCOMPILER + + + /// + /// Parse - returns an instance converted from the provided string. + /// string with Point3DCollection data + /// IFormatprovider for processing string + /// + private static List ParseThreeDoublesCollection(string source, IFormatProvider formatProvider) + { + TokenizerHelper th = new TokenizerHelper(source, formatProvider); + + + List resource = new List( source.Length/ 8 ) ; // SWAG the length of the collection. + + ThreeDoublesMarkup value; + + while (th.NextToken()) + { + value = new ThreeDoublesMarkup( + Convert.ToDouble(th.GetCurrentToken(), formatProvider), + Convert.ToDouble(th.NextTokenRequired(), formatProvider), + Convert.ToDouble(th.NextTokenRequired(), formatProvider)); + + resource.Add(value); + } + + return resource; + } + + /// + /// Parse - returns an instance converted from the provided string. + /// string with Point3DCollection data + /// IFormatprovider for processing string + /// + private static List ParsePointCollection(string source, IFormatProvider formatProvider) + { + TokenizerHelper th = new TokenizerHelper(source, formatProvider); + + List resource = new List(source.Length/ 8 ); // SWAG the length of the collection. + + Point value; + + while (th.NextToken()) + { + value = new Point( + Convert.ToDouble(th.GetCurrentToken(), formatProvider), + Convert.ToDouble(th.NextTokenRequired(), formatProvider) ); + + resource.Add(value); + } + + return resource; + } +#endif + + // + // Can we convert this double to a "scaled integer" + // + // We multiply by approx 2^20 - see if the result is either + // - greater than maxInt + // - if there is a non-numeric integer remaining + // + // as a result this routine will convert doubles with six-digits precision between +/- 2048 + // + internal static bool CanConvertToInteger( Double doubleValue , ref int intValue ) + { + double scaledValue ; + double scaledInteger ; + + scaledValue = doubleValue * scaleFactor ; + scaledInteger = Math.Floor( scaledValue ) ; + + if ( !( scaledInteger <= Int32.MaxValue ) // equivalent to scaledInteger > MaxValue, but take care of NaN. + || + !( scaledInteger >= Int32.MinValue ) ) // equivalent to scaledInteger < Minvalue but take care of NaN. + { + return false ; + } + else if ( ( scaledValue - scaledInteger ) > Double.Epsilon ) + { + return false ; + } + else + { + intValue = (int) scaledValue ; + + return true ; + } + } + + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/README.md b/src/Microsoft.DotNet.Wpf/src/PresentationCore/README.md new file mode 100644 index 00000000000..8c9fe3c1dba --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/README.md @@ -0,0 +1,2 @@ +Note: + Until PresentationCore is open-sourced, the files under this folder should be modified only with careful coordination with the WPF team. \ No newline at end of file diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/LocalizationCategory.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/LocalizationCategory.cs new file mode 100644 index 00000000000..1ba47ef6860 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/LocalizationCategory.cs @@ -0,0 +1,127 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: LocalizationCategory enum used by LocalizabilityAttribute +// +//--------------------------------------------------------------------------- + +#if PBTCOMPILER +namespace MS.Internal.Globalization +#else +namespace System.Windows +#endif +{ + /// + /// the category of the string values of each localizable resource + /// + // NOTE: Enum values must be made in sync with the enum parsing logic in + // Framework/MS/Internal/Globalization/LocalizationComments.cs +#if PBTCOMPILER + internal enum LocalizationCategory +#else + public enum LocalizationCategory +#endif + { + /// + /// None. For items that don't need to have a category + /// + None = 0, + + + //--------------------------------- + // Well known types + //--------------------------------- + /// + /// DecriptiveText. Use it for long piece of text + /// + Text, + + /// + /// TitleText. Use it for one line of text + /// + Title, + + /// + /// LabelText. Use it for short text in labling controls. + /// + Label, + + + /// + /// Button. For Button control and similar classes + /// + Button, + + /// + /// CheckBox. For CheckBox, CheckBoxItem and similar classes + /// + CheckBox, + + /// + /// ComboBox. For ComboBox, ComboBoxItem and similar classes + /// + ComboBox, + + /// + /// ListBox. For ListBox, ListBoxItem and similar classes + /// + ListBox, + + /// + /// Menu. For Menu, MenuItem and similar classes + /// + Menu, + + /// + /// RadioButton. For RadioButton, RadioButtonList and similar classes + /// + RadioButton, + + /// + /// ToolTip. For tool tip control and similar classes + /// + ToolTip, + + /// + /// Hyperlink. For hyperlink and similar classes + /// + Hyperlink , + + /// + /// TextFlow. For text panel and panels that can contain text. + /// + TextFlow, + + /// + /// Xml data. + /// + XmlData, + + /// + /// Font related data, font name, font size, etc. + /// + Font, + + //--------------------------------- + // Special types + //--------------------------------- + + /// + /// The category inherits from the parent node. + /// + Inherit, + + /// + /// "Ignore" indicates that value in baml should be treated as if it did not exsit in baml. + /// + Ignore, + + /// + /// "NeverLocalize" means that content is not localized. Content includes the subtree. + /// + NeverLocalize, + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Knowncolors.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Knowncolors.cs new file mode 100644 index 00000000000..216b8df10f1 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Knowncolors.cs @@ -0,0 +1,2267 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +using System.Windows.Media; +using MS.Internal; +using System.Collections.Generic; + +using System; + +namespace System.Windows.Media +#endif +{ + /// Enum containing handles to all known colors + /// Since the first element is 0, second is 1, etc, we can use this to index + /// directly into an array + internal enum KnownColor : uint + { + // We've reserved the value "1" as unknown. If for some odd reason "1" is added to the + // list, redefined UnknownColor + + AliceBlue = 0xFFF0F8FF, + AntiqueWhite = 0xFFFAEBD7, + Aqua = 0xFF00FFFF, + Aquamarine = 0xFF7FFFD4, + Azure = 0xFFF0FFFF, + Beige = 0xFFF5F5DC, + Bisque = 0xFFFFE4C4, + Black = 0xFF000000, + BlanchedAlmond = 0xFFFFEBCD, + Blue = 0xFF0000FF, + BlueViolet = 0xFF8A2BE2, + Brown = 0xFFA52A2A, + BurlyWood = 0xFFDEB887, + CadetBlue = 0xFF5F9EA0, + Chartreuse = 0xFF7FFF00, + Chocolate = 0xFFD2691E, + Coral = 0xFFFF7F50, + CornflowerBlue = 0xFF6495ED, + Cornsilk = 0xFFFFF8DC, + Crimson = 0xFFDC143C, + Cyan = 0xFF00FFFF, + DarkBlue = 0xFF00008B, + DarkCyan = 0xFF008B8B, + DarkGoldenrod = 0xFFB8860B, + DarkGray = 0xFFA9A9A9, + DarkGreen = 0xFF006400, + DarkKhaki = 0xFFBDB76B, + DarkMagenta = 0xFF8B008B, + DarkOliveGreen = 0xFF556B2F, + DarkOrange = 0xFFFF8C00, + DarkOrchid = 0xFF9932CC, + DarkRed = 0xFF8B0000, + DarkSalmon = 0xFFE9967A, + DarkSeaGreen = 0xFF8FBC8F, + DarkSlateBlue = 0xFF483D8B, + DarkSlateGray = 0xFF2F4F4F, + DarkTurquoise = 0xFF00CED1, + DarkViolet = 0xFF9400D3, + DeepPink = 0xFFFF1493, + DeepSkyBlue = 0xFF00BFFF, + DimGray = 0xFF696969, + DodgerBlue = 0xFF1E90FF, + Firebrick = 0xFFB22222, + FloralWhite = 0xFFFFFAF0, + ForestGreen = 0xFF228B22, + Fuchsia = 0xFFFF00FF, + Gainsboro = 0xFFDCDCDC, + GhostWhite = 0xFFF8F8FF, + Gold = 0xFFFFD700, + Goldenrod = 0xFFDAA520, + Gray = 0xFF808080, + Green = 0xFF008000, + GreenYellow = 0xFFADFF2F, + Honeydew = 0xFFF0FFF0, + HotPink = 0xFFFF69B4, + IndianRed = 0xFFCD5C5C, + Indigo = 0xFF4B0082, + Ivory = 0xFFFFFFF0, + Khaki = 0xFFF0E68C, + Lavender = 0xFFE6E6FA, + LavenderBlush = 0xFFFFF0F5, + LawnGreen = 0xFF7CFC00, + LemonChiffon = 0xFFFFFACD, + LightBlue = 0xFFADD8E6, + LightCoral = 0xFFF08080, + LightCyan = 0xFFE0FFFF, + LightGoldenrodYellow = 0xFFFAFAD2, + LightGreen = 0xFF90EE90, + LightGray = 0xFFD3D3D3, + LightPink = 0xFFFFB6C1, + LightSalmon = 0xFFFFA07A, + LightSeaGreen = 0xFF20B2AA, + LightSkyBlue = 0xFF87CEFA, + LightSlateGray = 0xFF778899, + LightSteelBlue = 0xFFB0C4DE, + LightYellow = 0xFFFFFFE0, + Lime = 0xFF00FF00, + LimeGreen = 0xFF32CD32, + Linen = 0xFFFAF0E6, + Magenta = 0xFFFF00FF, + Maroon = 0xFF800000, + MediumAquamarine = 0xFF66CDAA, + MediumBlue = 0xFF0000CD, + MediumOrchid = 0xFFBA55D3, + MediumPurple = 0xFF9370DB, + MediumSeaGreen = 0xFF3CB371, + MediumSlateBlue = 0xFF7B68EE, + MediumSpringGreen = 0xFF00FA9A, + MediumTurquoise = 0xFF48D1CC, + MediumVioletRed = 0xFFC71585, + MidnightBlue = 0xFF191970, + MintCream = 0xFFF5FFFA, + MistyRose = 0xFFFFE4E1, + Moccasin = 0xFFFFE4B5, + NavajoWhite = 0xFFFFDEAD, + Navy = 0xFF000080, + OldLace = 0xFFFDF5E6, + Olive = 0xFF808000, + OliveDrab = 0xFF6B8E23, + Orange = 0xFFFFA500, + OrangeRed = 0xFFFF4500, + Orchid = 0xFFDA70D6, + PaleGoldenrod = 0xFFEEE8AA, + PaleGreen = 0xFF98FB98, + PaleTurquoise = 0xFFAFEEEE, + PaleVioletRed = 0xFFDB7093, + PapayaWhip = 0xFFFFEFD5, + PeachPuff = 0xFFFFDAB9, + Peru = 0xFFCD853F, + Pink = 0xFFFFC0CB, + Plum = 0xFFDDA0DD, + PowderBlue = 0xFFB0E0E6, + Purple = 0xFF800080, + Red = 0xFFFF0000, + RosyBrown = 0xFFBC8F8F, + RoyalBlue = 0xFF4169E1, + SaddleBrown = 0xFF8B4513, + Salmon = 0xFFFA8072, + SandyBrown = 0xFFF4A460, + SeaGreen = 0xFF2E8B57, + SeaShell = 0xFFFFF5EE, + Sienna = 0xFFA0522D, + Silver = 0xFFC0C0C0, + SkyBlue = 0xFF87CEEB, + SlateBlue = 0xFF6A5ACD, + SlateGray = 0xFF708090, + Snow = 0xFFFFFAFA, + SpringGreen = 0xFF00FF7F, + SteelBlue = 0xFF4682B4, + Tan = 0xFFD2B48C, + Teal = 0xFF008080, + Thistle = 0xFFD8BFD8, + Tomato = 0xFFFF6347, + Transparent = 0x00FFFFFF, + Turquoise = 0xFF40E0D0, + Violet = 0xFFEE82EE, + Wheat = 0xFFF5DEB3, + White = 0xFFFFFFFF, + WhiteSmoke = 0xFFF5F5F5, + Yellow = 0xFFFFFF00, + YellowGreen = 0xFF9ACD32, + UnknownColor = 0x00000001 + } + + internal static class KnownColors + { +#if !PBTCOMPILER + + static KnownColors() + { + Array knownColorValues = Enum.GetValues(typeof(KnownColor)); + foreach (KnownColor colorValue in knownColorValues) + { + string aRGBString = String.Format("#{0,8:X8}", (uint)colorValue); + s_knownArgbColors[aRGBString] = colorValue; + } + } + + /// Return the solid color brush from a color string. If there's no match, null + public static SolidColorBrush ColorStringToKnownBrush(string s) + { + if (null != s) + { + KnownColor result = ColorStringToKnownColor(s); + + // If the result is UnknownColor, that means this string wasn't found + if (result != KnownColor.UnknownColor) + { + // Otherwise, return the appropriate SolidColorBrush + return SolidColorBrushFromUint((uint)result); + } + } + return null; + } + + public static bool IsKnownSolidColorBrush(SolidColorBrush scp) + { + lock(s_solidColorBrushCache) + { + return s_solidColorBrushCache.ContainsValue(scp); + } + } + + public static SolidColorBrush SolidColorBrushFromUint(uint argb) + { + SolidColorBrush scp = null; + + lock(s_solidColorBrushCache) + { + // Attempt to retrieve the color. If it fails create it. + if (!s_solidColorBrushCache.TryGetValue(argb, out scp)) + { + scp = new SolidColorBrush(Color.FromUInt32(argb)); + scp.Freeze(); + s_solidColorBrushCache[argb] = scp; + } +#if DEBUG + else + { + s_count++; + } +#endif + } + + return scp; + } + + static internal string MatchColor(string colorString, out bool isKnownColor, out bool isNumericColor, out bool isContextColor, out bool isScRgbColor) + { + + string trimmedString = colorString.Trim(); + + if (((trimmedString.Length == 4) || + (trimmedString.Length == 5) || + (trimmedString.Length == 7) || + (trimmedString.Length == 9)) && + (trimmedString[0] == '#')) + { + isNumericColor = true; + isScRgbColor = false; + isKnownColor = false; + isContextColor = false; + return trimmedString; + } + else + isNumericColor = false; + + if ((trimmedString.StartsWith("sc#", StringComparison.Ordinal) == true)) + { + isNumericColor = false; + isScRgbColor = true; + isKnownColor = false; + isContextColor = false; + } + else + { + isScRgbColor = false; + } + + if ((trimmedString.StartsWith(Parsers.s_ContextColor, StringComparison.OrdinalIgnoreCase) == true)) + { + isContextColor = true; + isScRgbColor = false; + isKnownColor = false; + return trimmedString; + } + else + { + isContextColor = false; + isKnownColor = true; + } + + return trimmedString; + } +#endif + + /// Return the KnownColor from a color string. If there's no match, KnownColor.UnknownColor + internal static KnownColor ColorStringToKnownColor(string colorString) + { + if (null != colorString) + { + // We use invariant culture because we don't globalize our color names + string colorUpper = colorString.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + // Use String.Equals because it does explicit equality + // StartsWith/EndsWith are culture sensitive and are 4-7 times slower than Equals + + switch (colorUpper.Length) + { + case 3: + if (colorUpper.Equals("RED")) return KnownColor.Red; + if (colorUpper.Equals("TAN")) return KnownColor.Tan; + break; + case 4: + switch(colorUpper[0]) + { + case 'A': + if (colorUpper.Equals("AQUA")) return KnownColor.Aqua; + break; + case 'B': + if (colorUpper.Equals("BLUE")) return KnownColor.Blue; + break; + case 'C': + if (colorUpper.Equals("CYAN")) return KnownColor.Cyan; + break; + case 'G': + if (colorUpper.Equals("GOLD")) return KnownColor.Gold; + if (colorUpper.Equals("GRAY")) return KnownColor.Gray; + break; + case 'L': + if (colorUpper.Equals("LIME")) return KnownColor.Lime; + break; + case 'N': + if (colorUpper.Equals("NAVY")) return KnownColor.Navy; + break; + case 'P': + if (colorUpper.Equals("PERU")) return KnownColor.Peru; + if (colorUpper.Equals("PINK")) return KnownColor.Pink; + if (colorUpper.Equals("PLUM")) return KnownColor.Plum; + break; + case 'S': + if (colorUpper.Equals("SNOW")) return KnownColor.Snow; + break; + case 'T': + if (colorUpper.Equals("TEAL")) return KnownColor.Teal; + break; + } + break; + case 5: + switch(colorUpper[0]) + { + case 'A': + if (colorUpper.Equals("AZURE")) return KnownColor.Azure; + break; + case 'B': + if (colorUpper.Equals("BEIGE")) return KnownColor.Beige; + if (colorUpper.Equals("BLACK")) return KnownColor.Black; + if (colorUpper.Equals("BROWN")) return KnownColor.Brown; + break; + case 'C': + if (colorUpper.Equals("CORAL")) return KnownColor.Coral; + break; + case 'G': + if (colorUpper.Equals("GREEN")) return KnownColor.Green; + break; + case 'I': + if (colorUpper.Equals("IVORY")) return KnownColor.Ivory; + break; + case 'K': + if (colorUpper.Equals("KHAKI")) return KnownColor.Khaki; + break; + case 'L': + if (colorUpper.Equals("LINEN")) return KnownColor.Linen; + break; + case 'O': + if (colorUpper.Equals("OLIVE")) return KnownColor.Olive; + break; + case 'W': + if (colorUpper.Equals("WHEAT")) return KnownColor.Wheat; + if (colorUpper.Equals("WHITE")) return KnownColor.White; + break; + } + break; + case 6: + switch(colorUpper[0]) + { + case 'B': + if (colorUpper.Equals("BISQUE")) return KnownColor.Bisque; + break; + case 'I': + if (colorUpper.Equals("INDIGO")) return KnownColor.Indigo; + break; + case 'M': + if (colorUpper.Equals("MAROON")) return KnownColor.Maroon; + break; + case 'O': + if (colorUpper.Equals("ORANGE")) return KnownColor.Orange; + if (colorUpper.Equals("ORCHID")) return KnownColor.Orchid; + break; + case 'P': + if (colorUpper.Equals("PURPLE")) return KnownColor.Purple; + break; + case 'S': + if (colorUpper.Equals("SALMON")) return KnownColor.Salmon; + if (colorUpper.Equals("SIENNA")) return KnownColor.Sienna; + if (colorUpper.Equals("SILVER")) return KnownColor.Silver; + break; + case 'T': + if (colorUpper.Equals("TOMATO")) return KnownColor.Tomato; + break; + case 'V': + if (colorUpper.Equals("VIOLET")) return KnownColor.Violet; + break; + case 'Y': + if (colorUpper.Equals("YELLOW")) return KnownColor.Yellow; + break; + } + break; + case 7: + switch(colorUpper[0]) + { + case 'C': + if (colorUpper.Equals("CRIMSON")) return KnownColor.Crimson; + break; + case 'D': + if (colorUpper.Equals("DARKRED")) return KnownColor.DarkRed; + if (colorUpper.Equals("DIMGRAY")) return KnownColor.DimGray; + break; + case 'F': + if (colorUpper.Equals("FUCHSIA")) return KnownColor.Fuchsia; + break; + case 'H': + if (colorUpper.Equals("HOTPINK")) return KnownColor.HotPink; + break; + case 'M': + if (colorUpper.Equals("MAGENTA")) return KnownColor.Magenta; + break; + case 'O': + if (colorUpper.Equals("OLDLACE")) return KnownColor.OldLace; + break; + case 'S': + if (colorUpper.Equals("SKYBLUE")) return KnownColor.SkyBlue; + break; + case 'T': + if (colorUpper.Equals("THISTLE")) return KnownColor.Thistle; + break; + } + break; + case 8: + switch(colorUpper[0]) + { + case 'C': + if (colorUpper.Equals("CORNSILK")) return KnownColor.Cornsilk; + break; + case 'D': + if (colorUpper.Equals("DARKBLUE")) return KnownColor.DarkBlue; + if (colorUpper.Equals("DARKCYAN")) return KnownColor.DarkCyan; + if (colorUpper.Equals("DARKGRAY")) return KnownColor.DarkGray; + if (colorUpper.Equals("DEEPPINK")) return KnownColor.DeepPink; + break; + case 'H': + if (colorUpper.Equals("HONEYDEW")) return KnownColor.Honeydew; + break; + case 'L': + if (colorUpper.Equals("LAVENDER")) return KnownColor.Lavender; + break; + case 'M': + if (colorUpper.Equals("MOCCASIN")) return KnownColor.Moccasin; + break; + case 'S': + if (colorUpper.Equals("SEAGREEN")) return KnownColor.SeaGreen; + if (colorUpper.Equals("SEASHELL")) return KnownColor.SeaShell; + break; + } + break; + case 9: + switch(colorUpper[0]) + { + case 'A': + if (colorUpper.Equals("ALICEBLUE")) return KnownColor.AliceBlue; + break; + case 'B': + if (colorUpper.Equals("BURLYWOOD")) return KnownColor.BurlyWood; + break; + case 'C': + if (colorUpper.Equals("CADETBLUE")) return KnownColor.CadetBlue; + if (colorUpper.Equals("CHOCOLATE")) return KnownColor.Chocolate; + break; + case 'D': + if (colorUpper.Equals("DARKGREEN")) return KnownColor.DarkGreen; + if (colorUpper.Equals("DARKKHAKI")) return KnownColor.DarkKhaki; + break; + case 'F': + if (colorUpper.Equals("FIREBRICK")) return KnownColor.Firebrick; + break; + case 'G': + if (colorUpper.Equals("GAINSBORO")) return KnownColor.Gainsboro; + if (colorUpper.Equals("GOLDENROD")) return KnownColor.Goldenrod; + break; + case 'I': + if (colorUpper.Equals("INDIANRED")) return KnownColor.IndianRed; + break; + case 'L': + if (colorUpper.Equals("LAWNGREEN")) return KnownColor.LawnGreen; + if (colorUpper.Equals("LIGHTBLUE")) return KnownColor.LightBlue; + if (colorUpper.Equals("LIGHTCYAN")) return KnownColor.LightCyan; + if (colorUpper.Equals("LIGHTGRAY")) return KnownColor.LightGray; + if (colorUpper.Equals("LIGHTPINK")) return KnownColor.LightPink; + if (colorUpper.Equals("LIMEGREEN")) return KnownColor.LimeGreen; + break; + case 'M': + if (colorUpper.Equals("MINTCREAM")) return KnownColor.MintCream; + if (colorUpper.Equals("MISTYROSE")) return KnownColor.MistyRose; + break; + case 'O': + if (colorUpper.Equals("OLIVEDRAB")) return KnownColor.OliveDrab; + if (colorUpper.Equals("ORANGERED")) return KnownColor.OrangeRed; + break; + case 'P': + if (colorUpper.Equals("PALEGREEN")) return KnownColor.PaleGreen; + if (colorUpper.Equals("PEACHPUFF")) return KnownColor.PeachPuff; + break; + case 'R': + if (colorUpper.Equals("ROSYBROWN")) return KnownColor.RosyBrown; + if (colorUpper.Equals("ROYALBLUE")) return KnownColor.RoyalBlue; + break; + case 'S': + if (colorUpper.Equals("SLATEBLUE")) return KnownColor.SlateBlue; + if (colorUpper.Equals("SLATEGRAY")) return KnownColor.SlateGray; + if (colorUpper.Equals("STEELBLUE")) return KnownColor.SteelBlue; + break; + case 'T': + if (colorUpper.Equals("TURQUOISE")) return KnownColor.Turquoise; + break; + } + break; + case 10: + switch(colorUpper[0]) + { + case 'A': + if (colorUpper.Equals("AQUAMARINE")) return KnownColor.Aquamarine; + break; + case 'B': + if (colorUpper.Equals("BLUEVIOLET")) return KnownColor.BlueViolet; + break; + case 'C': + if (colorUpper.Equals("CHARTREUSE")) return KnownColor.Chartreuse; + break; + case 'D': + if (colorUpper.Equals("DARKORANGE")) return KnownColor.DarkOrange; + if (colorUpper.Equals("DARKORCHID")) return KnownColor.DarkOrchid; + if (colorUpper.Equals("DARKSALMON")) return KnownColor.DarkSalmon; + if (colorUpper.Equals("DARKVIOLET")) return KnownColor.DarkViolet; + if (colorUpper.Equals("DODGERBLUE")) return KnownColor.DodgerBlue; + break; + case 'G': + if (colorUpper.Equals("GHOSTWHITE")) return KnownColor.GhostWhite; + break; + case 'L': + if (colorUpper.Equals("LIGHTCORAL")) return KnownColor.LightCoral; + if (colorUpper.Equals("LIGHTGREEN")) return KnownColor.LightGreen; + break; + case 'M': + if (colorUpper.Equals("MEDIUMBLUE")) return KnownColor.MediumBlue; + break; + case 'P': + if (colorUpper.Equals("PAPAYAWHIP")) return KnownColor.PapayaWhip; + if (colorUpper.Equals("POWDERBLUE")) return KnownColor.PowderBlue; + break; + case 'S': + if (colorUpper.Equals("SANDYBROWN")) return KnownColor.SandyBrown; + break; + case 'W': + if (colorUpper.Equals("WHITESMOKE")) return KnownColor.WhiteSmoke; + break; + } + break; + case 11: + switch(colorUpper[0]) + { + case 'D': + if (colorUpper.Equals("DARKMAGENTA")) return KnownColor.DarkMagenta; + if (colorUpper.Equals("DEEPSKYBLUE")) return KnownColor.DeepSkyBlue; + break; + case 'F': + if (colorUpper.Equals("FLORALWHITE")) return KnownColor.FloralWhite; + if (colorUpper.Equals("FORESTGREEN")) return KnownColor.ForestGreen; + break; + case 'G': + if (colorUpper.Equals("GREENYELLOW")) return KnownColor.GreenYellow; + break; + case 'L': + if (colorUpper.Equals("LIGHTSALMON")) return KnownColor.LightSalmon; + if (colorUpper.Equals("LIGHTYELLOW")) return KnownColor.LightYellow; + break; + case 'N': + if (colorUpper.Equals("NAVAJOWHITE")) return KnownColor.NavajoWhite; + break; + case 'S': + if (colorUpper.Equals("SADDLEBROWN")) return KnownColor.SaddleBrown; + if (colorUpper.Equals("SPRINGGREEN")) return KnownColor.SpringGreen; + break; + case 'T': + if (colorUpper.Equals("TRANSPARENT")) return KnownColor.Transparent; + break; + case 'Y': + if (colorUpper.Equals("YELLOWGREEN")) return KnownColor.YellowGreen; + break; + } + break; + case 12: + switch(colorUpper[0]) + { + case 'A': + if (colorUpper.Equals("ANTIQUEWHITE")) return KnownColor.AntiqueWhite; + break; + case 'D': + if (colorUpper.Equals("DARKSEAGREEN")) return KnownColor.DarkSeaGreen; + break; + case 'L': + if (colorUpper.Equals("LIGHTSKYBLUE")) return KnownColor.LightSkyBlue; + if (colorUpper.Equals("LEMONCHIFFON")) return KnownColor.LemonChiffon; + break; + case 'M': + if (colorUpper.Equals("MEDIUMORCHID")) return KnownColor.MediumOrchid; + if (colorUpper.Equals("MEDIUMPURPLE")) return KnownColor.MediumPurple; + if (colorUpper.Equals("MIDNIGHTBLUE")) return KnownColor.MidnightBlue; + break; + } + break; + case 13: + switch(colorUpper[0]) + { + case 'D': + if (colorUpper.Equals("DARKSLATEBLUE")) return KnownColor.DarkSlateBlue; + if (colorUpper.Equals("DARKSLATEGRAY")) return KnownColor.DarkSlateGray; + if (colorUpper.Equals("DARKGOLDENROD")) return KnownColor.DarkGoldenrod; + if (colorUpper.Equals("DARKTURQUOISE")) return KnownColor.DarkTurquoise; + break; + case 'L': + if (colorUpper.Equals("LIGHTSEAGREEN")) return KnownColor.LightSeaGreen; + if (colorUpper.Equals("LAVENDERBLUSH")) return KnownColor.LavenderBlush; + break; + case 'P': + if (colorUpper.Equals("PALEGOLDENROD")) return KnownColor.PaleGoldenrod; + if (colorUpper.Equals("PALETURQUOISE")) return KnownColor.PaleTurquoise; + if (colorUpper.Equals("PALEVIOLETRED")) return KnownColor.PaleVioletRed; + break; + } + break; + case 14: + switch(colorUpper[0]) + { + case 'B': + if (colorUpper.Equals("BLANCHEDALMOND")) return KnownColor.BlanchedAlmond; + break; + case 'C': + if (colorUpper.Equals("CORNFLOWERBLUE")) return KnownColor.CornflowerBlue; + break; + case 'D': + if (colorUpper.Equals("DARKOLIVEGREEN")) return KnownColor.DarkOliveGreen; + break; + case 'L': + if (colorUpper.Equals("LIGHTSLATEGRAY")) return KnownColor.LightSlateGray; + if (colorUpper.Equals("LIGHTSTEELBLUE")) return KnownColor.LightSteelBlue; + break; + case 'M': + if (colorUpper.Equals("MEDIUMSEAGREEN")) return KnownColor.MediumSeaGreen; + break; + } + break; + case 15: + if (colorUpper.Equals("MEDIUMSLATEBLUE")) return KnownColor.MediumSlateBlue; + if (colorUpper.Equals("MEDIUMTURQUOISE")) return KnownColor.MediumTurquoise; + if (colorUpper.Equals("MEDIUMVIOLETRED")) return KnownColor.MediumVioletRed; + break; + case 16: + if (colorUpper.Equals("MEDIUMAQUAMARINE")) return KnownColor.MediumAquamarine; + break; + case 17: + if (colorUpper.Equals("MEDIUMSPRINGGREEN")) return KnownColor.MediumSpringGreen; + break; + case 20: + if (colorUpper.Equals("LIGHTGOLDENRODYELLOW")) return KnownColor.LightGoldenrodYellow; + break; + } + } + // colorString was null or not found + return KnownColor.UnknownColor; + } + +#if !PBTCOMPILER + internal static KnownColor ArgbStringToKnownColor(string argbString) + { + string argbUpper = argbString.Trim().ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + KnownColor color; + if (s_knownArgbColors.TryGetValue(argbUpper, out color)) + return color; + + return KnownColor.UnknownColor; + } +#if DEBUG + private static int s_count = 0; +#endif + + private static Dictionary s_solidColorBrushCache = new Dictionary(); + private static Dictionary s_knownArgbColors = new Dictionary(); +#endif + } + +#if !PBTCOMPILER + /// + /// Colors - A collection of well-known Colors + /// + public sealed class Colors + { + #region Constructors + + // Colors only has static members, so it shouldn't be constructable. + private Colors() + { + } + + #endregion Constructors + + #region static Known Colors + + /// + /// Well-known color: AliceBlue + /// + public static Color AliceBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.AliceBlue); + } + } + + /// + /// Well-known color: AntiqueWhite + /// + public static Color AntiqueWhite + { + get + { + return Color.FromUInt32((uint)KnownColor.AntiqueWhite); + } + } + + /// + /// Well-known color: Aqua + /// + public static Color Aqua + { + get + { + return Color.FromUInt32((uint)KnownColor.Aqua); + } + } + + /// + /// Well-known color: Aquamarine + /// + public static Color Aquamarine + { + get + { + return Color.FromUInt32((uint)KnownColor.Aquamarine); + } + } + + /// + /// Well-known color: Azure + /// + public static Color Azure + { + get + { + return Color.FromUInt32((uint)KnownColor.Azure); + } + } + + /// + /// Well-known color: Beige + /// + public static Color Beige + { + get + { + return Color.FromUInt32((uint)KnownColor.Beige); + } + } + + /// + /// Well-known color: Bisque + /// + public static Color Bisque + { + get + { + return Color.FromUInt32((uint)KnownColor.Bisque); + } + } + + /// + /// Well-known color: Black + /// + public static Color Black + { + get + { + return Color.FromUInt32((uint)KnownColor.Black); + } + } + + /// + /// Well-known color: BlanchedAlmond + /// + public static Color BlanchedAlmond + { + get + { + return Color.FromUInt32((uint)KnownColor.BlanchedAlmond); + } + } + + /// + /// Well-known color: Blue + /// + public static Color Blue + { + get + { + return Color.FromUInt32((uint)KnownColor.Blue); + } + } + + /// + /// Well-known color: BlueViolet + /// + public static Color BlueViolet + { + get + { + return Color.FromUInt32((uint)KnownColor.BlueViolet); + } + } + + /// + /// Well-known color: Brown + /// + public static Color Brown + { + get + { + return Color.FromUInt32((uint)KnownColor.Brown); + } + } + + /// + /// Well-known color: BurlyWood + /// + public static Color BurlyWood + { + get + { + return Color.FromUInt32((uint)KnownColor.BurlyWood); + } + } + + /// + /// Well-known color: CadetBlue + /// + public static Color CadetBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.CadetBlue); + } + } + + /// + /// Well-known color: Chartreuse + /// + public static Color Chartreuse + { + get + { + return Color.FromUInt32((uint)KnownColor.Chartreuse); + } + } + + /// + /// Well-known color: Chocolate + /// + public static Color Chocolate + { + get + { + return Color.FromUInt32((uint)KnownColor.Chocolate); + } + } + + /// + /// Well-known color: Coral + /// + public static Color Coral + { + get + { + return Color.FromUInt32((uint)KnownColor.Coral); + } + } + + /// + /// Well-known color: CornflowerBlue + /// + public static Color CornflowerBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.CornflowerBlue); + } + } + + /// + /// Well-known color: Cornsilk + /// + public static Color Cornsilk + { + get + { + return Color.FromUInt32((uint)KnownColor.Cornsilk); + } + } + + /// + /// Well-known color: Crimson + /// + public static Color Crimson + { + get + { + return Color.FromUInt32((uint)KnownColor.Crimson); + } + } + + /// + /// Well-known color: Cyan + /// + public static Color Cyan + { + get + { + return Color.FromUInt32((uint)KnownColor.Cyan); + } + } + + /// + /// Well-known color: DarkBlue + /// + public static Color DarkBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkBlue); + } + } + + /// + /// Well-known color: DarkCyan + /// + public static Color DarkCyan + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkCyan); + } + } + + /// + /// Well-known color: DarkGoldenrod + /// + public static Color DarkGoldenrod + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkGoldenrod); + } + } + + /// + /// Well-known color: DarkGray + /// + public static Color DarkGray + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkGray); + } + } + + /// + /// Well-known color: DarkGreen + /// + public static Color DarkGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkGreen); + } + } + + /// + /// Well-known color: DarkKhaki + /// + public static Color DarkKhaki + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkKhaki); + } + } + + /// + /// Well-known color: DarkMagenta + /// + public static Color DarkMagenta + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkMagenta); + } + } + + /// + /// Well-known color: DarkOliveGreen + /// + public static Color DarkOliveGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkOliveGreen); + } + } + + /// + /// Well-known color: DarkOrange + /// + public static Color DarkOrange + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkOrange); + } + } + + /// + /// Well-known color: DarkOrchid + /// + public static Color DarkOrchid + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkOrchid); + } + } + + /// + /// Well-known color: DarkRed + /// + public static Color DarkRed + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkRed); + } + } + + /// + /// Well-known color: DarkSalmon + /// + public static Color DarkSalmon + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkSalmon); + } + } + + /// + /// Well-known color: DarkSeaGreen + /// + public static Color DarkSeaGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkSeaGreen); + } + } + + /// + /// Well-known color: DarkSlateBlue + /// + public static Color DarkSlateBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkSlateBlue); + } + } + + /// + /// Well-known color: DarkSlateGray + /// + public static Color DarkSlateGray + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkSlateGray); + } + } + + /// + /// Well-known color: DarkTurquoise + /// + public static Color DarkTurquoise + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkTurquoise); + } + } + + /// + /// Well-known color: DarkViolet + /// + public static Color DarkViolet + { + get + { + return Color.FromUInt32((uint)KnownColor.DarkViolet); + } + } + + /// + /// Well-known color: DeepPink + /// + public static Color DeepPink + { + get + { + return Color.FromUInt32((uint)KnownColor.DeepPink); + } + } + + /// + /// Well-known color: DeepSkyBlue + /// + public static Color DeepSkyBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.DeepSkyBlue); + } + } + + /// + /// Well-known color: DimGray + /// + public static Color DimGray + { + get + { + return Color.FromUInt32((uint)KnownColor.DimGray); + } + } + + /// + /// Well-known color: DodgerBlue + /// + public static Color DodgerBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.DodgerBlue); + } + } + + /// + /// Well-known color: Firebrick + /// + public static Color Firebrick + { + get + { + return Color.FromUInt32((uint)KnownColor.Firebrick); + } + } + + /// + /// Well-known color: FloralWhite + /// + public static Color FloralWhite + { + get + { + return Color.FromUInt32((uint)KnownColor.FloralWhite); + } + } + + /// + /// Well-known color: ForestGreen + /// + public static Color ForestGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.ForestGreen); + } + } + + /// + /// Well-known color: Fuchsia + /// + public static Color Fuchsia + { + get + { + return Color.FromUInt32((uint)KnownColor.Fuchsia); + } + } + + /// + /// Well-known color: Gainsboro + /// + public static Color Gainsboro + { + get + { + return Color.FromUInt32((uint)KnownColor.Gainsboro); + } + } + + /// + /// Well-known color: GhostWhite + /// + public static Color GhostWhite + { + get + { + return Color.FromUInt32((uint)KnownColor.GhostWhite); + } + } + + /// + /// Well-known color: Gold + /// + public static Color Gold + { + get + { + return Color.FromUInt32((uint)KnownColor.Gold); + } + } + + /// + /// Well-known color: Goldenrod + /// + public static Color Goldenrod + { + get + { + return Color.FromUInt32((uint)KnownColor.Goldenrod); + } + } + + /// + /// Well-known color: Gray + /// + public static Color Gray + { + get + { + return Color.FromUInt32((uint)KnownColor.Gray); + } + } + + /// + /// Well-known color: Green + /// + public static Color Green + { + get + { + return Color.FromUInt32((uint)KnownColor.Green); + } + } + + /// + /// Well-known color: GreenYellow + /// + public static Color GreenYellow + { + get + { + return Color.FromUInt32((uint)KnownColor.GreenYellow); + } + } + + /// + /// Well-known color: Honeydew + /// + public static Color Honeydew + { + get + { + return Color.FromUInt32((uint)KnownColor.Honeydew); + } + } + + /// + /// Well-known color: HotPink + /// + public static Color HotPink + { + get + { + return Color.FromUInt32((uint)KnownColor.HotPink); + } + } + + /// + /// Well-known color: IndianRed + /// + public static Color IndianRed + { + get + { + return Color.FromUInt32((uint)KnownColor.IndianRed); + } + } + + /// + /// Well-known color: Indigo + /// + public static Color Indigo + { + get + { + return Color.FromUInt32((uint)KnownColor.Indigo); + } + } + + /// + /// Well-known color: Ivory + /// + public static Color Ivory + { + get + { + return Color.FromUInt32((uint)KnownColor.Ivory); + } + } + + /// + /// Well-known color: Khaki + /// + public static Color Khaki + { + get + { + return Color.FromUInt32((uint)KnownColor.Khaki); + } + } + + /// + /// Well-known color: Lavender + /// + public static Color Lavender + { + get + { + return Color.FromUInt32((uint)KnownColor.Lavender); + } + } + + /// + /// Well-known color: LavenderBlush + /// + public static Color LavenderBlush + { + get + { + return Color.FromUInt32((uint)KnownColor.LavenderBlush); + } + } + + /// + /// Well-known color: LawnGreen + /// + public static Color LawnGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.LawnGreen); + } + } + + /// + /// Well-known color: LemonChiffon + /// + public static Color LemonChiffon + { + get + { + return Color.FromUInt32((uint)KnownColor.LemonChiffon); + } + } + + /// + /// Well-known color: LightBlue + /// + public static Color LightBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.LightBlue); + } + } + + /// + /// Well-known color: LightCoral + /// + public static Color LightCoral + { + get + { + return Color.FromUInt32((uint)KnownColor.LightCoral); + } + } + + /// + /// Well-known color: LightCyan + /// + public static Color LightCyan + { + get + { + return Color.FromUInt32((uint)KnownColor.LightCyan); + } + } + + /// + /// Well-known color: LightGoldenrodYellow + /// + public static Color LightGoldenrodYellow + { + get + { + return Color.FromUInt32((uint)KnownColor.LightGoldenrodYellow); + } + } + + /// + /// Well-known color: LightGray + /// + public static Color LightGray + { + get + { + return Color.FromUInt32((uint)KnownColor.LightGray); + } + } + + /// + /// Well-known color: LightGreen + /// + public static Color LightGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.LightGreen); + } + } + + /// + /// Well-known color: LightPink + /// + public static Color LightPink + { + get + { + return Color.FromUInt32((uint)KnownColor.LightPink); + } + } + + /// + /// Well-known color: LightSalmon + /// + public static Color LightSalmon + { + get + { + return Color.FromUInt32((uint)KnownColor.LightSalmon); + } + } + + /// + /// Well-known color: LightSeaGreen + /// + public static Color LightSeaGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.LightSeaGreen); + } + } + + /// + /// Well-known color: LightSkyBlue + /// + public static Color LightSkyBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.LightSkyBlue); + } + } + + /// + /// Well-known color: LightSlateGray + /// + public static Color LightSlateGray + { + get + { + return Color.FromUInt32((uint)KnownColor.LightSlateGray); + } + } + + /// + /// Well-known color: LightSteelBlue + /// + public static Color LightSteelBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.LightSteelBlue); + } + } + + /// + /// Well-known color: LightYellow + /// + public static Color LightYellow + { + get + { + return Color.FromUInt32((uint)KnownColor.LightYellow); + } + } + + /// + /// Well-known color: Lime + /// + public static Color Lime + { + get + { + return Color.FromUInt32((uint)KnownColor.Lime); + } + } + + /// + /// Well-known color: LimeGreen + /// + public static Color LimeGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.LimeGreen); + } + } + + /// + /// Well-known color: Linen + /// + public static Color Linen + { + get + { + return Color.FromUInt32((uint)KnownColor.Linen); + } + } + + /// + /// Well-known color: Magenta + /// + public static Color Magenta + { + get + { + return Color.FromUInt32((uint)KnownColor.Magenta); + } + } + + /// + /// Well-known color: Maroon + /// + public static Color Maroon + { + get + { + return Color.FromUInt32((uint)KnownColor.Maroon); + } + } + + /// + /// Well-known color: MediumAquamarine + /// + public static Color MediumAquamarine + { + get + { + return Color.FromUInt32((uint)KnownColor.MediumAquamarine); + } + } + + /// + /// Well-known color: MediumBlue + /// + public static Color MediumBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.MediumBlue); + } + } + + /// + /// Well-known color: MediumOrchid + /// + public static Color MediumOrchid + { + get + { + return Color.FromUInt32((uint)KnownColor.MediumOrchid); + } + } + + /// + /// Well-known color: MediumPurple + /// + public static Color MediumPurple + { + get + { + return Color.FromUInt32((uint)KnownColor.MediumPurple); + } + } + + /// + /// Well-known color: MediumSeaGreen + /// + public static Color MediumSeaGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.MediumSeaGreen); + } + } + + /// + /// Well-known color: MediumSlateBlue + /// + public static Color MediumSlateBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.MediumSlateBlue); + } + } + + /// + /// Well-known color: MediumSpringGreen + /// + public static Color MediumSpringGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.MediumSpringGreen); + } + } + + /// + /// Well-known color: MediumTurquoise + /// + public static Color MediumTurquoise + { + get + { + return Color.FromUInt32((uint)KnownColor.MediumTurquoise); + } + } + + /// + /// Well-known color: MediumVioletRed + /// + public static Color MediumVioletRed + { + get + { + return Color.FromUInt32((uint)KnownColor.MediumVioletRed); + } + } + + /// + /// Well-known color: MidnightBlue + /// + public static Color MidnightBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.MidnightBlue); + } + } + + /// + /// Well-known color: MintCream + /// + public static Color MintCream + { + get + { + return Color.FromUInt32((uint)KnownColor.MintCream); + } + } + + /// + /// Well-known color: MistyRose + /// + public static Color MistyRose + { + get + { + return Color.FromUInt32((uint)KnownColor.MistyRose); + } + } + + /// + /// Well-known color: Moccasin + /// + public static Color Moccasin + { + get + { + return Color.FromUInt32((uint)KnownColor.Moccasin); + } + } + + /// + /// Well-known color: NavajoWhite + /// + public static Color NavajoWhite + { + get + { + return Color.FromUInt32((uint)KnownColor.NavajoWhite); + } + } + + /// + /// Well-known color: Navy + /// + public static Color Navy + { + get + { + return Color.FromUInt32((uint)KnownColor.Navy); + } + } + + /// + /// Well-known color: OldLace + /// + public static Color OldLace + { + get + { + return Color.FromUInt32((uint)KnownColor.OldLace); + } + } + + /// + /// Well-known color: Olive + /// + public static Color Olive + { + get + { + return Color.FromUInt32((uint)KnownColor.Olive); + } + } + + /// + /// Well-known color: OliveDrab + /// + public static Color OliveDrab + { + get + { + return Color.FromUInt32((uint)KnownColor.OliveDrab); + } + } + + /// + /// Well-known color: Orange + /// + public static Color Orange + { + get + { + return Color.FromUInt32((uint)KnownColor.Orange); + } + } + + /// + /// Well-known color: OrangeRed + /// + public static Color OrangeRed + { + get + { + return Color.FromUInt32((uint)KnownColor.OrangeRed); + } + } + + /// + /// Well-known color: Orchid + /// + public static Color Orchid + { + get + { + return Color.FromUInt32((uint)KnownColor.Orchid); + } + } + + /// + /// Well-known color: PaleGoldenrod + /// + public static Color PaleGoldenrod + { + get + { + return Color.FromUInt32((uint)KnownColor.PaleGoldenrod); + } + } + + /// + /// Well-known color: PaleGreen + /// + public static Color PaleGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.PaleGreen); + } + } + + /// + /// Well-known color: PaleTurquoise + /// + public static Color PaleTurquoise + { + get + { + return Color.FromUInt32((uint)KnownColor.PaleTurquoise); + } + } + + /// + /// Well-known color: PaleVioletRed + /// + public static Color PaleVioletRed + { + get + { + return Color.FromUInt32((uint)KnownColor.PaleVioletRed); + } + } + + /// + /// Well-known color: PapayaWhip + /// + public static Color PapayaWhip + { + get + { + return Color.FromUInt32((uint)KnownColor.PapayaWhip); + } + } + + /// + /// Well-known color: PeachPuff + /// + public static Color PeachPuff + { + get + { + return Color.FromUInt32((uint)KnownColor.PeachPuff); + } + } + + /// + /// Well-known color: Peru + /// + public static Color Peru + { + get + { + return Color.FromUInt32((uint)KnownColor.Peru); + } + } + + /// + /// Well-known color: Pink + /// + public static Color Pink + { + get + { + return Color.FromUInt32((uint)KnownColor.Pink); + } + } + + /// + /// Well-known color: Plum + /// + public static Color Plum + { + get + { + return Color.FromUInt32((uint)KnownColor.Plum); + } + } + + /// + /// Well-known color: PowderBlue + /// + public static Color PowderBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.PowderBlue); + } + } + + /// + /// Well-known color: Purple + /// + public static Color Purple + { + get + { + return Color.FromUInt32((uint)KnownColor.Purple); + } + } + + /// + /// Well-known color: Red + /// + public static Color Red + { + get + { + return Color.FromUInt32((uint)KnownColor.Red); + } + } + + /// + /// Well-known color: RosyBrown + /// + public static Color RosyBrown + { + get + { + return Color.FromUInt32((uint)KnownColor.RosyBrown); + } + } + + /// + /// Well-known color: RoyalBlue + /// + public static Color RoyalBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.RoyalBlue); + } + } + + /// + /// Well-known color: SaddleBrown + /// + public static Color SaddleBrown + { + get + { + return Color.FromUInt32((uint)KnownColor.SaddleBrown); + } + } + + /// + /// Well-known color: Salmon + /// + public static Color Salmon + { + get + { + return Color.FromUInt32((uint)KnownColor.Salmon); + } + } + + /// + /// Well-known color: SandyBrown + /// + public static Color SandyBrown + { + get + { + return Color.FromUInt32((uint)KnownColor.SandyBrown); + } + } + + /// + /// Well-known color: SeaGreen + /// + public static Color SeaGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.SeaGreen); + } + } + + /// + /// Well-known color: SeaShell + /// + public static Color SeaShell + { + get + { + return Color.FromUInt32((uint)KnownColor.SeaShell); + } + } + + /// + /// Well-known color: Sienna + /// + public static Color Sienna + { + get + { + return Color.FromUInt32((uint)KnownColor.Sienna); + } + } + + /// + /// Well-known color: Silver + /// + public static Color Silver + { + get + { + return Color.FromUInt32((uint)KnownColor.Silver); + } + } + + /// + /// Well-known color: SkyBlue + /// + public static Color SkyBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.SkyBlue); + } + } + + /// + /// Well-known color: SlateBlue + /// + public static Color SlateBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.SlateBlue); + } + } + + /// + /// Well-known color: SlateGray + /// + public static Color SlateGray + { + get + { + return Color.FromUInt32((uint)KnownColor.SlateGray); + } + } + + /// + /// Well-known color: Snow + /// + public static Color Snow + { + get + { + return Color.FromUInt32((uint)KnownColor.Snow); + } + } + + /// + /// Well-known color: SpringGreen + /// + public static Color SpringGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.SpringGreen); + } + } + + /// + /// Well-known color: SteelBlue + /// + public static Color SteelBlue + { + get + { + return Color.FromUInt32((uint)KnownColor.SteelBlue); + } + } + + /// + /// Well-known color: Tan + /// + public static Color Tan + { + get + { + return Color.FromUInt32((uint)KnownColor.Tan); + } + } + + /// + /// Well-known color: Teal + /// + public static Color Teal + { + get + { + return Color.FromUInt32((uint)KnownColor.Teal); + } + } + + /// + /// Well-known color: Thistle + /// + public static Color Thistle + { + get + { + return Color.FromUInt32((uint)KnownColor.Thistle); + } + } + + /// + /// Well-known color: Tomato + /// + public static Color Tomato + { + get + { + return Color.FromUInt32((uint)KnownColor.Tomato); + } + } + + /// + /// Well-known color: Transparent + /// + public static Color Transparent + { + get + { + return Color.FromUInt32((uint)KnownColor.Transparent); + } + } + + /// + /// Well-known color: Turquoise + /// + public static Color Turquoise + { + get + { + return Color.FromUInt32((uint)KnownColor.Turquoise); + } + } + + /// + /// Well-known color: Violet + /// + public static Color Violet + { + get + { + return Color.FromUInt32((uint)KnownColor.Violet); + } + } + + /// + /// Well-known color: Wheat + /// + public static Color Wheat + { + get + { + return Color.FromUInt32((uint)KnownColor.Wheat); + } + } + + /// + /// Well-known color: White + /// + public static Color White + { + get + { + return Color.FromUInt32((uint)KnownColor.White); + } + } + + /// + /// Well-known color: WhiteSmoke + /// + public static Color WhiteSmoke + { + get + { + return Color.FromUInt32((uint)KnownColor.WhiteSmoke); + } + } + + /// + /// Well-known color: Yellow + /// + public static Color Yellow + { + get + { + return Color.FromUInt32((uint)KnownColor.Yellow); + } + } + + /// + /// Well-known color: YellowGreen + /// + public static Color YellowGreen + { + get + { + return Color.FromUInt32((uint)KnownColor.YellowGreen); + } + } + + #endregion static Known Colors + } +#endif +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/ParsersCommon.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/ParsersCommon.cs new file mode 100644 index 00000000000..2e9261c9bb6 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/ParsersCommon.cs @@ -0,0 +1,727 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//------------------------------------------------------------------------------ +// +// Synopsis: Implements class Parsers for internal use of type converters +// +// This file contains all the code that is shared between PresentationBuildTasks and PresentationCore +// +// Changes to this file will likely result in a compiler update. +// +//------------------------------------------------------------------------------ +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Diagnostics; +using MS.Internal; +using System.ComponentModel; +using System.Globalization; +using System.IO; + + +#if PRESENTATION_CORE + +using System.Windows.Media; +using System.Windows.Media.Media3D; +using System.Windows.Media.Animation; +using System.Windows.Media.Imaging; +using System.Windows; + +using SR=MS.Internal.PresentationCore.SR; +using SRID=MS.Internal.PresentationCore.SRID; +using MS.Internal.Media; +using TypeConverterHelper = System.Windows.Markup.TypeConverterHelper; + +namespace MS.Internal + +#elif PBTCOMPILER + +using MS.Utility ; +using MS.Internal.Markup; +using TypeConverterHelper = MS.Internal.Markup.TypeConverterHelper; + +namespace MS.Internal.Markup + +#endif +{ + internal static partial class Parsers + { + + +#if !PBTCOMPILER + internal static object DeserializeStreamGeometry( BinaryReader reader ) + { + StreamGeometry geometry = new StreamGeometry(); + + using (StreamGeometryContext context = geometry.Open()) + { + ParserStreamGeometryContext.Deserialize( reader, context, geometry ); + } + geometry.Freeze(); + + return geometry; + } +#endif + + internal static void PathMinilanguageToBinary( BinaryWriter bw, string stringValue ) + { + ParserStreamGeometryContext context = new ParserStreamGeometryContext( bw ); +#if PRESENTATION_CORE + FillRule fillRule = FillRule.EvenOdd ; +#else + bool fillRule = false ; +#endif + ParseStringToStreamGeometryContext(context, stringValue, TypeConverterHelper.InvariantEnglishUS, ref fillRule); + context.SetFillRule( fillRule ); + + context.MarkEOF(); + } + + /// + /// Parse a PathGeometry string. + /// The PathGeometry syntax is the same as the PathFigureCollection syntax except that it + /// may start with a "wsp*Fwsp*(0|1)" which indicate the winding mode (F0 is EvenOdd while + /// F1 is NonZero). + /// + +#if !PBTCOMPILER + internal static Geometry ParseGeometry( + string pathString, + IFormatProvider formatProvider) + { + FillRule fillRule = FillRule.EvenOdd ; + StreamGeometry geometry = new StreamGeometry(); + StreamGeometryContext context = geometry.Open(); + + ParseStringToStreamGeometryContext( context, pathString, formatProvider , ref fillRule ) ; + + geometry.FillRule = fillRule ; + geometry.Freeze(); + + return geometry; + } +#endif + // + // Given a mini-language representation of a Geometry - write it to the + // supplied streamgeometrycontext + // + + private static void ParseStringToStreamGeometryContext ( + StreamGeometryContext context, + string pathString, + IFormatProvider formatProvider, +#if PRESENTATION_CORE + ref FillRule fillRule +#else + ref bool fillRule +#endif + ) + { + using ( context ) + { + // Check to ensure that there's something to parse + if (pathString != null) + { + int curIndex = 0; + + // skip any leading space + while ((curIndex < pathString.Length) && Char.IsWhiteSpace(pathString, curIndex)) + { + curIndex++; + } + + // Is there anything to look at? + if (curIndex < pathString.Length) + { + // If so, we only care if the first non-WhiteSpace char encountered is 'F' + if (pathString[curIndex] == 'F') + { + curIndex++; + + // Since we found 'F' the next non-WhiteSpace char must be 0 or 1 - look for it. + while ((curIndex < pathString.Length) && Char.IsWhiteSpace(pathString, curIndex)) + { + curIndex++; + } + + // If we ran out of text, this is an error, because 'F' cannot be specified without 0 or 1 + // Also, if the next token isn't 0 or 1, this too is illegal + if ((curIndex == pathString.Length) || + ((pathString[curIndex] != '0') && + (pathString[curIndex] != '1'))) + { + throw new FormatException(SR.Get(SRID.Parsers_IllegalToken)); + } + +#if PRESENTATION_CORE + fillRule = pathString[curIndex] == '0' ? FillRule.EvenOdd : FillRule.Nonzero; +#else + fillRule = pathString[curIndex] != '0' ; + +#endif + + // Increment curIndex to point to the next char + curIndex++; + } + } + + AbbreviatedGeometryParser parser = new AbbreviatedGeometryParser(); + + parser.ParseToGeometryContext(context, pathString, curIndex); + } + } + } + } + + /// + /// Parser for XAML abbreviated geometry. + /// SVG path spec is closely followed http://www.w3.org/TR/SVG11/paths.html + /// 3/23/2006, new parser for performance (fyuan) + /// + sealed internal class AbbreviatedGeometryParser + { + const bool AllowSign = true; + const bool AllowComma = true; + const bool IsFilled = true; + const bool IsClosed = true; + const bool IsStroked = true; + const bool IsSmoothJoin = true; + + IFormatProvider _formatProvider; + + string _pathString; // Input string to be parsed + int _pathLength; + int _curIndex; // Location to read next character from + bool _figureStarted; // StartFigure is effective + + Point _lastStart; // Last figure starting point + Point _lastPoint; // Last point + Point _secondLastPoint; // The point before last point + + char _token; // Non whitespace character returned by ReadToken + + StreamGeometryContext _context; + + /// + /// Throw unexpected token exception + /// + private void ThrowBadToken() + { + throw new System.FormatException(SR.Get(SRID.Parser_UnexpectedToken, _pathString, _curIndex - 1)); + } + + bool More() + { + return _curIndex < _pathLength; + } + + // Skip white space, one comma if allowed + private bool SkipWhiteSpace(bool allowComma) + { + bool commaMet = false; + + while (More()) + { + char ch = _pathString[_curIndex]; + + switch (ch) + { + case ' ' : + case '\n': + case '\r': + case '\t': // SVG whitespace + break; + + case ',': + if (allowComma) + { + commaMet = true; + allowComma = false; // one comma only + } + else + { + ThrowBadToken(); + } + break; + + default: + // Avoid calling IsWhiteSpace for ch in (' ' .. 'z'] + if (((ch >' ') && (ch <= 'z')) || ! Char.IsWhiteSpace(ch)) + { + return commaMet; + } + break; + } + + _curIndex ++; + } + + return commaMet; + } + + /// + /// Read the next non whitespace character + /// + /// True if not end of string + private bool ReadToken() + { + SkipWhiteSpace(!AllowComma); + + // Check for end of string + if (More()) + { + _token = _pathString[_curIndex ++]; + + return true; + } + else + { + return false; + } + } + + private bool IsNumber(bool allowComma) + { + bool commaMet = SkipWhiteSpace(allowComma); + + if (More()) + { + _token = _pathString[_curIndex]; + + // Valid start of a number + if ((_token == '.') || (_token == '-') || (_token == '+') || ((_token >= '0') && (_token <= '9')) + || (_token == 'I') // Infinity + || (_token == 'N')) // NaN + { + return true; + } + } + + if (commaMet) // Only allowed between numbers + { + ThrowBadToken(); + } + + return false; + } + + void SkipDigits(bool signAllowed) + { + // Allow for a sign + if (signAllowed && More() && ((_pathString[_curIndex] == '-') || _pathString[_curIndex] == '+')) + { + _curIndex++; + } + + while (More() && (_pathString[_curIndex] >= '0') && (_pathString[_curIndex] <= '9')) + { + _curIndex ++; + } + } + +// +// /// +// /// See if the current token matches the string s. If so, advance and +// /// return true. Else, return false. +// /// +// bool TryAdvance(string s) +// { +// Debug.Assert(s.Length != 0); +// +// bool match = false; +// if (More() && _pathString[_currentIndex] == s[0]) +// { +// // +// // Don't bother reading subsequent characters, as the CLR parser will +// // do this for us later. +// // +// _currentIndex = Math.Min(_currentIndex + s.Length, _pathLength); +// +// match = true; +// } +// +// return match; +// } +// + + /// + /// Read a floating point number + /// + /// + double ReadNumber(bool allowComma) + { + if (!IsNumber(allowComma)) + { + ThrowBadToken(); + } + + bool simple = true; + int start = _curIndex; + + // + // Allow for a sign + // + // There are numbers that cannot be preceded with a sign, for instance, -NaN, but it's + // fine to ignore that at this point, since the CLR parser will catch this later. + // + if (More() && ((_pathString[_curIndex] == '-') || _pathString[_curIndex] == '+')) + { + _curIndex ++; + } + + // Check for Infinity (or -Infinity). + if (More() && (_pathString[_curIndex] == 'I')) + { + // + // Don't bother reading the characters, as the CLR parser will + // do this for us later. + // + _curIndex = Math.Min(_curIndex+8, _pathLength); // "Infinity" has 8 characters + simple = false; + } + // Check for NaN + else if (More() && (_pathString[_curIndex] == 'N')) + { + // + // Don't bother reading the characters, as the CLR parser will + // do this for us later. + // + _curIndex = Math.Min(_curIndex+3, _pathLength); // "NaN" has 3 characters + simple = false; + } + else + { + SkipDigits(! AllowSign); + + // Optional period, followed by more digits + if (More() && (_pathString[_curIndex] == '.')) + { + simple = false; + _curIndex ++; + SkipDigits(! AllowSign); + } + + // Exponent + if (More() && ((_pathString[_curIndex] == 'E') || (_pathString[_curIndex] == 'e'))) + { + simple = false; + _curIndex ++; + SkipDigits(AllowSign); + } + } + + if (simple && (_curIndex <= (start + 8))) // 32-bit integer + { + int sign = 1; + + if (_pathString[start] == '+') + { + start ++; + } + else if (_pathString[start] == '-') + { + start ++; + sign = -1; + } + + int value = 0; + + while (start < _curIndex) + { + value = value * 10 + (_pathString[start] - '0'); + start ++; + } + + return value * sign; + } + else + { + string subString = _pathString.Substring(start, _curIndex - start); + + try + { + return System.Convert.ToDouble(subString, _formatProvider); + } + catch (FormatException except) + { + throw new System.FormatException(SR.Get(SRID.Parser_UnexpectedToken, _pathString, start), except); + } + } + } + + /// + /// Read a bool: 1 or 0 + /// + /// + bool ReadBool() + { + SkipWhiteSpace(AllowComma); + + if (More()) + { + _token = _pathString[_curIndex ++]; + + if (_token == '0') + { + return false; + } + else if (_token == '1') + { + return true; + } + } + + ThrowBadToken(); + + return false; + } + + /// + /// Read a relative point + /// + /// + private Point ReadPoint(char cmd, bool allowcomma) + { + double x = ReadNumber(allowcomma); + double y = ReadNumber(AllowComma); + + if (cmd >= 'a') // 'A' < 'a'. lower case for relative + { + x += _lastPoint.X; + y += _lastPoint.Y; + } + + return new Point(x, y); + } + + /// + /// Reflect _secondLastPoint over _lastPoint to get a new point for smooth curve + /// + /// + private Point Reflect() + { + return new Point(2 * _lastPoint.X - _secondLastPoint.X, + 2 * _lastPoint.Y - _secondLastPoint.Y); + } + + private void EnsureFigure() + { + if (!_figureStarted) + { + _context.BeginFigure(_lastStart, IsFilled, ! IsClosed); + _figureStarted = true; + } + } + + /// + /// Parse a PathFigureCollection string + /// + internal void ParseToGeometryContext( + StreamGeometryContext context, + string pathString, + int startIndex) + { + // We really should throw an ArgumentNullException here for context and pathString. + + // From original code + // This is only used in call to Double.Parse + _formatProvider = System.Globalization.CultureInfo.InvariantCulture; + + _context = context; + _pathString = pathString; + _pathLength = pathString.Length; + _curIndex = startIndex; + + _secondLastPoint = new Point(0, 0); + _lastPoint = new Point(0, 0); + _lastStart = new Point(0, 0); + + _figureStarted = false; + + bool first = true; + + char last_cmd = ' '; + + while (ReadToken()) // Empty path is allowed in XAML + { + char cmd = _token; + + if (first) + { + if ((cmd != 'M') && (cmd != 'm')) // Path starts with M|m + { + ThrowBadToken(); + } + + first = false; + } + + switch (cmd) + { + case 'm': case 'M': + // XAML allows multiple points after M/m + _lastPoint = ReadPoint(cmd, ! AllowComma); + + context.BeginFigure(_lastPoint, IsFilled, ! IsClosed); + _figureStarted = true; + _lastStart = _lastPoint; + last_cmd = 'M'; + + while (IsNumber(AllowComma)) + { + _lastPoint = ReadPoint(cmd, ! AllowComma); + + context.LineTo(_lastPoint, IsStroked, ! IsSmoothJoin); + last_cmd = 'L'; + } + break; + + case 'l': case 'L': + case 'h': case 'H': + case 'v': case 'V': + EnsureFigure(); + + do + { + switch (cmd) + { + case 'l': _lastPoint = ReadPoint(cmd, ! AllowComma); break; + case 'L': _lastPoint = ReadPoint(cmd, ! AllowComma); break; + case 'h': _lastPoint.X += ReadNumber(! AllowComma); break; + case 'H': _lastPoint.X = ReadNumber(! AllowComma); break; + case 'v': _lastPoint.Y += ReadNumber(! AllowComma); break; + case 'V': _lastPoint.Y = ReadNumber(! AllowComma); break; + } + + context.LineTo(_lastPoint, IsStroked, ! IsSmoothJoin); + } + while (IsNumber(AllowComma)); + + last_cmd = 'L'; + break; + + case 'c': case 'C': // cubic Bezier + case 's': case 'S': // smooth cublic Bezier + EnsureFigure(); + + do + { + Point p; + + if ((cmd == 's') || (cmd == 'S')) + { + if (last_cmd == 'C') + { + p = Reflect(); + } + else + { + p = _lastPoint; + } + + _secondLastPoint = ReadPoint(cmd, ! AllowComma); + } + else + { + p = ReadPoint(cmd, ! AllowComma); + + _secondLastPoint = ReadPoint(cmd, AllowComma); + } + + _lastPoint = ReadPoint(cmd, AllowComma); + + context.BezierTo(p, _secondLastPoint, _lastPoint, IsStroked, ! IsSmoothJoin); + + last_cmd = 'C'; + } + while (IsNumber(AllowComma)); + + break; + + case 'q': case 'Q': // quadratic Bezier + case 't': case 'T': // smooth quadratic Bezier + EnsureFigure(); + + do + { + if ((cmd == 't') || (cmd == 'T')) + { + if (last_cmd == 'Q') + { + _secondLastPoint = Reflect(); + } + else + { + _secondLastPoint = _lastPoint; + } + + _lastPoint = ReadPoint(cmd, ! AllowComma); + } + else + { + _secondLastPoint = ReadPoint(cmd, ! AllowComma); + _lastPoint = ReadPoint(cmd, AllowComma); + } + + context.QuadraticBezierTo(_secondLastPoint, _lastPoint, IsStroked, ! IsSmoothJoin); + + last_cmd = 'Q'; + } + while (IsNumber(AllowComma)); + + break; + + case 'a': case 'A': + EnsureFigure(); + + do + { + // A 3,4 5, 0, 0, 6,7 + double w = ReadNumber(! AllowComma); + double h = ReadNumber(AllowComma); + double rotation = ReadNumber(AllowComma); + bool large = ReadBool(); + bool sweep = ReadBool(); + + _lastPoint = ReadPoint(cmd, AllowComma); + + context.ArcTo( + _lastPoint, + new Size(w, h), + rotation, + large, +#if PBTCOMPILER + sweep, +#else + sweep ? SweepDirection.Clockwise : SweepDirection.Counterclockwise, +#endif + IsStroked, + ! IsSmoothJoin + ); + } + while (IsNumber(AllowComma)); + + last_cmd = 'A'; + break; + + case 'z': + case 'Z': + EnsureFigure(); + context.SetClosedState(IsClosed); + + _figureStarted = false; + last_cmd = 'Z'; + + _lastPoint = _lastStart; // Set reference point to be first point of current figure + break; + + default: + ThrowBadToken(); + break; + } + } + } + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/StreamGeometryContext.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/StreamGeometryContext.cs new file mode 100644 index 00000000000..fd316a0fd97 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/StreamGeometryContext.cs @@ -0,0 +1,162 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// This class is used by the StreamGeometry class to generate an inlined, +// flattened geometry stream. +// +//--------------------------------------------------------------------------- + +using MS.Internal; + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Security; +using System.Security.Permissions; + + +#if !PBTCOMPILER +using System.Runtime.InteropServices; +using System.Windows.Threading; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Media.Composition; +using System.Windows.Media.Effects; +using System.Windows.Media.Imaging; +using System.Windows.Media.Media3D; +using System.Diagnostics; +using SR=MS.Internal.PresentationCore.SR; +using SRID=MS.Internal.PresentationCore.SRID; + +using MS.Internal.PresentationCore; + +namespace System.Windows.Media + +#elif PBTCOMPILER + +using MS.Internal.Markup; + + +namespace MS.Internal.Markup +#endif +{ + + /// + /// StreamGeometryContext + /// +#if ! PBTCOMPILER + public abstract class StreamGeometryContext : DispatcherObject, IDisposable +#else + internal abstract class StreamGeometryContext : IDisposable +#endif + { + #region Constructors + + /// + /// This constructor exists to prevent external derivation + /// + internal StreamGeometryContext() + { + } + + #endregion Constructors + + #region IDisposable + + void IDisposable.Dispose() + { +#if ! PBTCOMPILER + VerifyAccess(); +#endif + DisposeCore(); + GC.SuppressFinalize(this); + } + + #endregion IDisposable + + #region Public Methods + + /// + /// Closes the StreamContext and flushes the content. + /// Afterwards the StreamContext can not be used anymore. + /// This call does not require all Push calls to have been Popped. + /// + /// + /// This call is illegal if this object has already been closed or disposed. + /// + public virtual void Close() + { + DisposeCore(); + } + + + /// + /// BeginFigure - Start a new figure. + /// + public abstract void BeginFigure(Point startPoint, bool isFilled, bool isClosed); + + /// + /// LineTo - append a LineTo to the current figure. + /// + public abstract void LineTo(Point point, bool isStroked, bool isSmoothJoin); + + /// + /// QuadraticBezierTo - append a QuadraticBezierTo to the current figure. + /// + public abstract void QuadraticBezierTo(Point point1, Point point2, bool isStroked, bool isSmoothJoin); + + /// + /// BezierTo - apply a BezierTo to the current figure. + /// + public abstract void BezierTo(Point point1, Point point2, Point point3, bool isStroked, bool isSmoothJoin); + + /// + /// PolyLineTo - append a PolyLineTo to the current figure. + /// + public abstract void PolyLineTo(IList points, bool isStroked, bool isSmoothJoin); + + /// + /// PolyQuadraticBezierTo - append a PolyQuadraticBezierTo to the current figure. + /// + public abstract void PolyQuadraticBezierTo(IList points, bool isStroked, bool isSmoothJoin); + + /// + /// PolyBezierTo - append a PolyBezierTo to the current figure. + /// + public abstract void PolyBezierTo(IList points, bool isStroked, bool isSmoothJoin); + + /// + /// ArcTo - append an ArcTo to the current figure. + /// + + // Special case this one. Bringing in sweep direction requires code-gen changes. + // +#if !PBTCOMPILER + public abstract void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked, bool isSmoothJoin); +#else + public abstract void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, bool sweepDirection, bool isStroked, bool isSmoothJoin); +#endif + + #endregion Public Methods + + /// + /// This is the same as the Close call: + /// Closes the Context and flushes the content. + /// Afterwards the Context can not be used anymore. + /// This call does not require all Push calls to have been Popped. + /// + /// + /// This call is illegal if this object has already been closed or disposed. + /// + internal virtual void DisposeCore() {} + + /// + /// SetClosedState - Sets the current closed state of the figure. + /// + internal abstract void SetClosedState(bool closed); + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Modifiability.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Modifiability.cs new file mode 100644 index 00000000000..275f23c3570 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Modifiability.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: Modifiability enum used by LocalizabilityAttribute +// +//--------------------------------------------------------------------------- + +#if PBTCOMPILER +namespace MS.Internal.Globalization +#else +namespace System.Windows +#endif +{ + /// + /// Modifiability of the attribute's targeted value in baml + /// + // Less restrictive value has a higher numeric value + // NOTE: Enum values must be made in sync with the enum parsing logic in + // Framework/MS/Internal/Globalization/LocalizationComments.cs +#if PBTCOMPILER + internal enum Modifiability +#else + public enum Modifiability +#endif + { + /// + /// Targeted value is not modifiable by localizers. + /// + Unmodifiable = 0, + + /// + /// Targeted value is modifiable by localizers. + /// + Modifiable = 1, + + /// + /// Targeted value's modifiability inherits from the the parent nodes. + /// + Inherit = 2, + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Readability.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Readability.cs new file mode 100644 index 00000000000..d8771dfcbd8 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Readability.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: Readability enum used by LocalizabilityAttribute +// +//--------------------------------------------------------------------------- + +#if PBTCOMPILER +namespace MS.Internal.Globalization +#else +namespace System.Windows +#endif +{ + /// + /// Readability of the attribute's targeted value in Baml + /// + // Less restrictive value has a higher numeric value + // NOTE: Enum values must be made in sync with the enum parsing logic in + // Framework/MS/Internal/Globalization/LocalizationComments.cs +#if PBTCOMPILER + internal enum Readability +#else + public enum Readability +#endif + { + /// + /// Targeted value is not readable. + /// + Unreadable = 0, + + /// + /// Targeted value is readable text. + /// + Readable = 1, + + /// + /// Targeted value's readability inherites from parent nodes. + /// + Inherit = 2, + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Globalization/LocalizationComments.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Globalization/LocalizationComments.cs new file mode 100644 index 00000000000..1f8859306bb --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Globalization/LocalizationComments.cs @@ -0,0 +1,461 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: Localization comments related class +// +//--------------------------------------------------------------------------- +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections.Generic; + +#if !PBTCOMPILER +using System.Windows; +#endif + +using MS.Utility; + +// Disabling 1634 and 1691: +// In order to avoid generating warnings about unknown message numbers and +// unknown pragmas when compiling C# source code with the C# compiler, +// you need to disable warnings 1634 and 1691. (Presharp Documentation) +#pragma warning disable 1634, 1691 + +namespace MS.Internal.Globalization +{ + /// + /// Note: the class name and property name must be kept in sync'ed with + /// Framework\System\Windows\Localization.cs file. + /// Compiler checks for them by literal string comparisons. + /// + internal static class LocComments + { + /// + /// Helper function to determine whether this is the Localization.Attribute attached proeprty + /// + /// type name + /// property name + internal static bool IsLocLocalizabilityProperty(string type, string property) + { + return "Attributes" == property + && "System.Windows.Localization" == type; + + } + + /// + /// Helper function to determind whether this is the Localization.Comments attached proeprty + /// + /// type name + /// property name + internal static bool IsLocCommentsProperty(string type, string property) + { + return "Comments" == property + && "System.Windows.Localization" == type; + } + + /// + /// Helper function to parse the Localization.Attributes value into multiple pairs + /// + /// content of Localization.Attributes + internal static PropertyComment[] ParsePropertyLocalizabilityAttributes(string input) + { + PropertyComment[] pairs = ParsePropertyComments(input); + + if (pairs != null) + { + for (int i = 0; i < pairs.Length; i++) + { + pairs[i].Value = LookupAndSetLocalizabilityAttribute((string) pairs[i].Value); + } + } + + return pairs; + } + + /// + /// Helper function to parse the Localization.Comments value into multiple pairs + /// + /// content of Localization.Comments + internal static PropertyComment[] ParsePropertyComments(string input) + { + // + // Localization comments consist of repeating "[PropertyName]([Value])" + // e.g. $Content (abc) FontSize(def) + // + if (input == null) return null; + + List tokens = new List(8); + StringBuilder tokenBuffer = new StringBuilder(); + PropertyComment currentPair = new PropertyComment(); + bool escaped = false; + + for (int i = 0; i < input.Length; i++) + { + if (currentPair.PropertyName == null) + { + // parsing "PropertyName" section + if (Char.IsWhiteSpace(input[i]) && !escaped) + { + if (tokenBuffer.Length > 0) + { + // terminate the PropertyName by an unesacped whitespace + currentPair.PropertyName = tokenBuffer.ToString(); + tokenBuffer = new StringBuilder(); + } + + // else ignore whitespace at the beginning of the PropertyName name + } + else + { + if (input[i] == CommentStart && !escaped) + { + if (i > 0) + { + // terminate the PropertyName by an unescaped CommentStart char + currentPair.PropertyName = tokenBuffer.ToString(); + tokenBuffer = new StringBuilder(); + i--; // put back this char and continue + } + else + { + + // can't begin with unescaped comment start char. + throw new FormatException(SR.Get(SRID.InvalidLocCommentTarget, input)); + } + } + else if (input[i] == EscapeChar && !escaped) + { + escaped = true; + } + else + { + tokenBuffer.Append(input[i]); + escaped = false; + } + } + } + else + { + // parsing the "Value" part + if (tokenBuffer.Length == 0) + { + if (input[i] == CommentStart && !escaped) + { + // comment must begin with unescaped CommentStart + tokenBuffer.Append(input[i]); + escaped = false; + } + else if (!Char.IsWhiteSpace(input[i])) + { + // else, only white space is allows before an unescaped comment start char + throw new FormatException(SR.Get(SRID.InvalidLocCommentValue, currentPair.PropertyName, input)); + } + } + else + { + // inside the comment + if (input[i] == CommentEnd) + { + if (!escaped) + { + // terminated by unescaped Comment + currentPair.Value = tokenBuffer.ToString().Substring(1); + tokens.Add(currentPair); + tokenBuffer = new StringBuilder(); + currentPair = new PropertyComment(); + } + else + { + // continue on escaped end char + tokenBuffer.Append(input[i]); + escaped = false; + } + } + else if (input[i] == CommentStart && !escaped) + { + // throw if there is unescape start in comment + throw new FormatException(SR.Get(SRID.InvalidLocCommentValue, currentPair.PropertyName, input)); + } + else + { + // comment + if (input[i] == EscapeChar && !escaped) + { + escaped = true; + } + else + { + tokenBuffer.Append(input[i]); + escaped = false; + } + } + } + } + } + + if (currentPair.PropertyName != null || tokenBuffer.Length != 0) + { + // unmatched PropertyName and Value pair + throw new FormatException(SR.Get(SRID.UnmatchedLocComment, input)); + } + + return tokens.ToArray(); + } + + //------------------------------ + // Private methods + //------------------------------ + private static LocalizabilityGroup LookupAndSetLocalizabilityAttribute(string input) + { + // + // For Localization.Attributes, values are seperated by spaces, e.g. + // $Content (Modifiable Readable) + // We are breaking the content and convert it to corresponding enum values. + // + LocalizabilityGroup attributeGroup = new LocalizabilityGroup(); + + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < input.Length; i ++) + { + if (Char.IsWhiteSpace(input[i])) + { + if (builder.Length > 0) + { + ParseLocalizabilityString( + builder.ToString(), + attributeGroup + ); + + builder = new StringBuilder(); + } + } + else + { + builder.Append(input[i]); + } + } + + if (builder.Length > 0) + { + ParseLocalizabilityString( + builder.ToString(), + attributeGroup + ); + } + + return attributeGroup; + } + + private static void ParseLocalizabilityString( + string value, + LocalizabilityGroup attributeGroup + ) + { + int enumValue; + if (ReadabilityIndexTable.TryGet(value, out enumValue)) + { + attributeGroup.Readability = (Readability) enumValue; + return; + } + + if (ModifiabilityIndexTable.TryGet(value, out enumValue)) + { + attributeGroup.Modifiability = (Modifiability) enumValue; + return; + } + + if (LocalizationCategoryIndexTable.TryGet(value, out enumValue)) + { + attributeGroup.Category = (LocalizationCategory) enumValue; + return; + } + + throw new FormatException(SR.Get(SRID.InvalidLocalizabilityValue, value)); + } + + + private const char CommentStart = '('; + private const char CommentEnd = ')'; + private const char EscapeChar = '\\'; + + // loc comments file recognized element + internal const string LocDocumentRoot = "LocalizableAssembly"; + internal const string LocResourcesElement = "LocalizableFile"; + internal const string LocCommentsElement = "LocalizationDirectives"; + internal const string LocFileNameAttribute = "Name"; + internal const string LocCommentIDAttribute = "Uid"; + internal const string LocCommentsAttribute = "Comments"; + internal const string LocLocalizabilityAttribute = "Attributes"; + + // + // Tables that map the enum string names into their enum indices. + // Each index table contains the list of enum names in the exact + // order of their enum indices. They must be consistent with the enum + // declarations in core. + // + private static EnumNameIndexTable ReadabilityIndexTable = new EnumNameIndexTable( + "Readability.", + new string[] { + "Unreadable", + "Readable", + "Inherit" + } + ); + + private static EnumNameIndexTable ModifiabilityIndexTable = new EnumNameIndexTable( + "Modifiability.", + new string[] { + "Unmodifiable", + "Modifiable", + "Inherit" + } + ); + + private static EnumNameIndexTable LocalizationCategoryIndexTable = new EnumNameIndexTable( + "LocalizationCategory.", + new string[] { + "None", + "Text", + "Title", + "Label", + "Button", + "CheckBox", + "ComboBox", + "ListBox", + "Menu", + "RadioButton", + "ToolTip", + "Hyperlink", + "TextFlow", + "XmlData", + "Font", + "Inherit", + "Ignore", + "NeverLocalize" + } + ); + + /// + /// A simple table that maps a enum name into its enum index. The string can be + /// the enum value's name by itself or preceeded by the enum's prefix to reduce + /// ambiguity. + /// + private class EnumNameIndexTable + { + private string _enumPrefix; + private string[] _enumNames; + + internal EnumNameIndexTable( + string enumPrefix, + string[] enumNames + ) + { + Debug.Assert(enumPrefix != null && enumNames != null); + _enumPrefix = enumPrefix; + _enumNames = enumNames; + } + + internal bool TryGet(string enumName, out int enumIndex) + { + enumIndex = 0; + if (enumName.StartsWith(_enumPrefix , StringComparison.Ordinal)) + { + // get the real enum name after the prefix. + enumName = enumName.Substring(_enumPrefix.Length); + } + + for (int i = 0; i < _enumNames.Length; i++) + { + if (string.Compare(enumName, _enumNames[i], StringComparison.Ordinal) == 0) + { + enumIndex = i; + return true; + } + } + return false; + } + } + + } + + internal class PropertyComment + { + string _target; + object _value; + + internal PropertyComment() {} + + internal string PropertyName + { + get { return _target; } + set { _target = value; } + } + + internal object Value + { + get { return _value;} + set { _value = value;} + } + } + + internal class LocalizabilityGroup + { + private const int InvalidValue = -1; + + internal Modifiability Modifiability; + internal Readability Readability; + internal LocalizationCategory Category; + + internal LocalizabilityGroup() + { + Modifiability = (Modifiability) InvalidValue; + Readability = (Readability) InvalidValue; + Category = (LocalizationCategory) InvalidValue; + } + +#if !PBTCOMPILER + // Helper to override a localizability attribute. Not needed for compiler + internal LocalizabilityAttribute Override(LocalizabilityAttribute attribute) + { + Modifiability modifiability = attribute.Modifiability; + Readability readability = attribute.Readability; + LocalizationCategory category = attribute.Category; + + bool overridden = false; + if (((int) Modifiability)!= InvalidValue) + { + modifiability = Modifiability; + overridden = true; + } + + if (((int) Readability) != InvalidValue) + { + readability = Readability; + overridden = true; + } + + if (((int) Category) != InvalidValue) + { + category = Category; + overridden = true; + } + + if (overridden) + { + attribute = new LocalizabilityAttribute(category); + attribute.Modifiability = modifiability; + attribute.Readability = readability; + } + + return attribute; + } +#endif + } +} + + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/README.md b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/README.md new file mode 100644 index 00000000000..0cec3857cbe --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/README.md @@ -0,0 +1,2 @@ +Note: + Until PresentationFramework is open-sourced, the files under this folder should be modified only with careful coordination with the WPF team. \ No newline at end of file diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/AttributeData.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/AttributeData.cs new file mode 100644 index 00000000000..17dc648b305 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/AttributeData.cs @@ -0,0 +1,171 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/***************************************************************************\ +* +* Purpose: AttributeContext and *AttributeData +* +\***************************************************************************/ + +using System; +using System.Xml; +using System.Xml.Serialization; +using System.IO; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Reflection; +using System.Globalization; +using MS.Utility; +using System.Collections.Specialized; +using Microsoft.Win32; +using System.Runtime.InteropServices; +using MS.Internal; + +// Disabling 1634 and 1691: +// In order to avoid generating warnings about unknown message numbers and +// unknown pragmas when compiling C# source code with the C# compiler, +// you need to disable warnings 1634 and 1691. (Presharp Documentation) +#pragma warning disable 1634, 1691 + +#if !PBTCOMPILER + +using System.Windows; +using System.Windows.Documents; +using System.Windows.Media; +using System.Windows.Shapes; + +#endif + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + /// + /// Enumeration for different Attribute Context values. + /// + internal enum AttributeContext + { + Unknown, + Property, + RoutedEvent, + ClrEvent, + Code, + } + + #region CompactSyntaxData + + // Class to cache attribute information relating to compact syntax properties, + // so that they can be expanded into complex notation after processing all the + // 'regular' properties. + internal class AttributeData : DefAttributeData + { + internal AttributeData( + string targetAssemblyName, + string targetFullName, + Type targetType, + string args, + Type declaringType, + string propertyName, + object info, + Type serializerType, + int lineNumber, + int linePosition, + int depth, + string targetNamespaceUri, + short extensionTypeId, + bool isValueNestedExtension, + bool isValueTypeExtension, + bool isSimple) : + base(targetAssemblyName, targetFullName, targetType, args, declaringType, + targetNamespaceUri, lineNumber, linePosition, depth, isSimple) + { + PropertyName = propertyName; + SerializerType = serializerType; + ExtensionTypeId = extensionTypeId; + IsValueNestedExtension = isValueNestedExtension; + IsValueTypeExtension = isValueTypeExtension; + Info = info; + } + + internal string PropertyName; // Name of this property. + internal Type SerializerType; // Type of serializer (if any) + internal short ExtensionTypeId; // TypeId of a simple ME when it is the value of a property. + internal bool IsValueNestedExtension; // True if the value of a simple ME is another simple ME. + internal bool IsValueTypeExtension; // True if the value of a simple ME is a TypeExtension. + internal object Info; // DependencyProperty or MethodInfo or ClrInfo associated with property to set. + + internal bool IsTypeExtension + { + get + { + return ExtensionTypeId == (short)KnownElements.TypeExtension; + } + } + + internal bool IsStaticExtension + { + get + { + return ExtensionTypeId == (short)KnownElements.StaticExtension; + } + } + } + + // Class to cache attribute information relating to complex def attribute + // syntax properties, so that they can be expanded into complex notation + // after processing all the 'regular' properties. + internal class DefAttributeData + { + internal DefAttributeData( + string targetAssemblyName, + string targetFullName, + Type targetType, + string args, + Type declaringType, + string targetNamespaceUri, + int lineNumber, + int linePosition, + int depth, + bool isSimple) + { + TargetType = targetType; + DeclaringType = declaringType; + TargetFullName = targetFullName; + TargetAssemblyName = targetAssemblyName; + Args = args; + TargetNamespaceUri = targetNamespaceUri; + LineNumber = lineNumber; + LinePosition = linePosition; + Depth = depth; + IsSimple = isSimple; + } + + internal Type TargetType; // Target type + internal Type DeclaringType; // Type where Attribute is declared + internal string TargetFullName; // Full string name of target type + internal string TargetAssemblyName; // Assembly name where TargetType is defined + internal string Args; // arguments with *typename() stripped off + internal string TargetNamespaceUri; // xmlns namespace uri of the TargetType ME that owns propertyName. + internal int LineNumber; // Line for this attribute + internal int LinePosition; // Position for this attribute + internal int Depth; // Xml element depth of start of attribute + internal bool IsSimple; // True if the attribute is a simple property + + internal bool IsUnknownExtension + { + get + { + return TargetType == typeof(MarkupExtensionParser.UnknownMarkupExtension); + } + } + } + + #endregion CompactSyntaxData + +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlBinaryWriter.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlBinaryWriter.cs new file mode 100644 index 00000000000..b2cf9a3e1c5 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlBinaryWriter.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/***************************************************************************\ +* +* Purpose: Subclass BinaryWriter. +* +\***************************************************************************/ + +using System; +using System.IO; +using System.Text; + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + + internal class BamlBinaryWriter: BinaryWriter + { + public BamlBinaryWriter(Stream stream, Encoding code) + :base(stream, code) + { + } + + public new void Write7BitEncodedInt(int value) + { + base.Write7BitEncodedInt(value); + } + + public static int SizeOf7bitEncodedSize(int size) + { + const int _7bits = 0x7F; + const int _14bits = ( _7bits << 7) | _7bits; + const int _21bits = (_14bits << 7) | _7bits; + const int _28bits = (_21bits << 7) | _7bits; + + if (0 == (size & ~_7bits)) + return 1; + if (0 == (size & ~_14bits)) + return 2; + if (0 == (size & ~_21bits)) + return 3; + if (0 == (size & ~_28bits)) + return 4; + return 5; + } + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlMapTable.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlMapTable.cs new file mode 100644 index 00000000000..31274bbea59 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlMapTable.cs @@ -0,0 +1,1985 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/***************************************************************************\ +* +* Purpose: Used to Keep track of Id to Object mappings in a BAML file. +* +\***************************************************************************/ + +using System; +using System.Xml; +using System.IO; +using System.Globalization; +using System.Text; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Diagnostics; +using System.Reflection; + +using MS.Utility; +using MS.Internal; + +#if PBTCOMPILER +using MS.Internal.Markup; +#else +using System.Windows; +using System.Windows.Threading; + +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Media.Animation; +using System.Windows.Media.Media3D; +using System.Windows.Markup; +using System.Windows.Shapes; +using System.Security; +using System.Security.Permissions; +using MS.Internal.PresentationFramework; + +#endif + +// Disabling 1634 and 1691: +// In order to avoid generating warnings about unknown message numbers and +// unknown pragmas when compiling C# source code with the C# compiler, +// you need to disable warnings 1634 and 1691. (Presharp Documentation) +#pragma warning disable 1634, 1691 + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + // Used to read/write mapping Baml Ids + // to Assembly, types, namespaces, etc. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlMapTable + { + // Welcome to the world of "known types". + // Known Types are used to bypass the cost of reflection for the + // types introduced by the system. + +#region Constructor + + static BamlMapTable() + { + // Setup the assembly record for the known types of controls + KnownAssemblyInfoRecord = new BamlAssemblyInfoRecord(); + KnownAssemblyInfoRecord.AssemblyId = -1; + KnownAssemblyInfoRecord.Assembly = ReflectionHelper.LoadAssembly(_frameworkAssembly, string.Empty); + KnownAssemblyInfoRecord.AssemblyFullName = KnownAssemblyInfoRecord.Assembly.FullName; + } + + internal BamlMapTable(XamlTypeMapper xamlTypeMapper) + { + Debug.Assert(null != xamlTypeMapper); + + _xamlTypeMapper = xamlTypeMapper; + } + +#endregion Constructor + +#region KnownTypes + +#if !PBTCOMPILER + // Creates an instance of a known type given the inverse of the known type ID. (which + // is the negative short value of the KnownElements enum) + internal object CreateKnownTypeFromId(short id) + { + if (id < 0) + { + return KnownTypes.CreateKnownElement((KnownElements)(-id)); + } + + return null; + } +#endif + // Returns known Type given the inverse of the known type ID (which + // is the negative short value of the KnownElements enum) + internal static Type GetKnownTypeFromId(short id) + { + if (id < 0) + { + return KnownTypes.Types[-id]; + } + + return null; + } + + // Binary search through the KnowElements.Types[] table. + // KE.Types[] is lazily loaded so the act of searching will load some types. + // but this is considered better (memory wise) than having a seperate table. + internal static short GetKnownTypeIdFromName( + string assemblyFullName, + string clrNamespace, + string typeShortName) + { + if (typeShortName == string.Empty) + { + return 0; + } + + int high = (int)KnownElements.MaxElement - 1; + int low = 1; + + while (low <= high) + { + int probe = (high+low) / 2; + Type probeType = KnownTypes.Types[probe]; + int cmp = String.CompareOrdinal(typeShortName, probeType.Name); + if (cmp == 0) + { + // Found a potential match. Now compare the namespaces & assembly to be sure +#if !PBTCOMPILER + if (probeType.Namespace == clrNamespace + && + probeType.Assembly.FullName == assemblyFullName ) +#else + if (probeType.Namespace == clrNamespace) +#endif + { + return (short) -probe; + } + else + { + return 0; + } + } + + if (cmp < 0) // typeName < probeType.Name + { + high = probe - 1; + } + else + { + Debug.Assert(cmp > 0); + low = probe + 1; + } + } + return 0; + } + + // Return the ID from the type-to-KnownElements for the passed Type + internal static short GetKnownTypeIdFromType(Type type) + { + if (type == null) + { + return 0; + } + + return GetKnownTypeIdFromName(type.Assembly.FullName, type.Namespace, type.Name); + } + + // Search through the known strings for a match to the passed string. + // Return the string's index in the table if found. + private static Int16 GetKnownStringIdFromName(string stringValue) + { + int end = _knownStrings.Length; + // Indicies are one based, even though the _knownStrings array is + // zero based. So the first element in the _knownStrings array is null + for (int i = 1; i < end; i++) + { + if (_knownStrings[i] == stringValue) + { + return (short) -i; + } + } + + // return 0 if it is not a known string. + return 0; + } +#endregion KnownTypes + +#region KnownConverters + + // Known Converters are used to avoid the cost of reflecting for + // custom attributes on commonly used TypeConverters at load time. + +#if !PBTCOMPILER + // Returns the ID of the known TypeConverter for a given object type. If there is no known + // converter, return KnownElements.UnknownElement. + internal static KnownElements GetKnownTypeConverterIdFromType(Type type) + { + KnownElements tcId; + if (ReflectionHelper.IsNullableType(type)) + { + tcId = KnownElements.NullableConverter; + } + else if (type == typeof(System.Type)) + { + tcId = KnownElements.TypeTypeConverter; + } + else + { + short idNumber = GetKnownTypeIdFromType(type); + + if (idNumber < 0) + { + tcId = KnownTypes.GetKnownTypeConverterId((KnownElements)(-idNumber)); + } + else + { + tcId = KnownElements.UnknownElement; + } + } + + return tcId; + } + + // Returns the known TypeConverter for a given object type. If there is no known + // converter, return null. + internal TypeConverter GetKnownConverterFromType(Type type) + { + KnownElements tcId = GetKnownTypeConverterIdFromType(type); + + TypeConverter converter; + if (tcId != KnownElements.UnknownElement) + { + converter = GetConverterFromId((short)-(short)tcId, type, null); + } + else + { + converter = null; + } + + return converter; + } + + // Returns the known TypeConverter for a given object type. If there is no known + // converter, return null. This is a static version of the previous + // method for use when there is no parser context available. + internal static TypeConverter GetKnownConverterFromType_NoCache(Type type) + { + KnownElements typeId = GetKnownTypeConverterIdFromType(type); + + TypeConverter tc; + // The EnumConverter and NullableConverter need to be created specially, since + // they need the type of the Enum or Nullable in their constructor. + switch (typeId) + { + case KnownElements.EnumConverter: + Debug.Assert(type.IsEnum); + tc = new System.ComponentModel.EnumConverter(type); + break; + + case KnownElements.NullableConverter: + Debug.Assert(ReflectionHelper.IsNullableType(type)); + tc = new System.ComponentModel.NullableConverter(type); + break; + + case KnownElements.UnknownElement: + tc = null; + break; + + default: + tc = KnownTypes.CreateKnownElement(typeId) as TypeConverter; + break; + } + + return tc; + } +#endif + + // Returns the known converter type for a given object type. If there is no known + // converter, return null. + internal Type GetKnownConverterTypeFromType(Type type) + { +#if PBTCOMPILER + // Need to handle Nullable types specially as they require a ctor that + // takes the underlying type, but at compile time we only need to know the Type + // of the Converter and not an actual instance of it. + // Need to handle URI types specially since we can't reflect for their TypeConverter + // in the ReflectionOnly Load (ROL) context. + if (ReflectionHelper.IsNullableType(type)) + { + return typeof(NullableConverter); + } + // The param 'type' will be in the ROL context while any typeof types will resolve against + // the real type that is loaded with PBT. So we need to first get the ROL type from the real + // type before doing the check. + else if (type == ReflectionHelper.GetSystemType(typeof(Uri))) + { + return typeof(UriTypeConverter); + } + else +#endif + if (type == typeof(System.Type)) + { + return typeof(TypeTypeConverter); + } + + short idNumber = GetKnownTypeIdFromType(type); + if (idNumber == 0) + { + return null; + } + + KnownElements id = (KnownElements)(-idNumber); + + KnownElements tcId = KnownTypes.GetKnownTypeConverterId(id); + if (tcId == KnownElements.UnknownElement) + { + return null; + } + + return KnownTypes.Types[(int)tcId]; + } + + // Return the known converter type for the given property and property owner. + // Return null if there is no property level converter. In that case, the type + // level converter is normally used by calling GetKnownConverterTypeFromType() + private static Type GetKnownConverterTypeFromPropName( + Type propOwnerType, + string propName) + { + short idNumber = GetKnownTypeIdFromType(propOwnerType); + if (idNumber == 0) + { + return null; + } + + KnownElements id = (KnownElements)(-idNumber); + + KnownElements converterId = KnownTypes.GetKnownTypeConverterIdForProperty(id, propName); + if (converterId == KnownElements.UnknownElement) + { + return null; + } + + return KnownTypes.Types[(int)converterId]; + } + +#endregion KnownConverters + +#region Methods + +#if !PBTCOMPILER + // This is called when a parse is begun when the very first baml record is + // processed. If the BamlMapTable already contains data, then this means + // it is being re-used for multiple parses. In this case set the _reusingMapTable + // flag and make certain that the ObjectHashTable is populated before clearing + // the existing assembly, type and property lists for the next parse. + internal void Initialize() + { + if (AttributeIdMap.Count > 0 || TypeIdMap.Count > 0) + { + _reusingMapTable = true; + // Populate the ObjectHashTable here only after the first parse has + // completed and the second is about to begin. This is done so that + // a single parse does not pay the price of having the hash table, and + // the second through 'n' parses are added as they are read in. + if (ObjectHashTable.Count == 0) + { + // Loop through attributes. We only care about having CLR properties in + // the hash table. DependencyProperties are already cached by the framework. + for (int i=0; i= 0) + { + return false; + } + + if (-id == (short)KnownElements.Style || + + -id == (short)KnownElements.FrameworkTemplate || + -id == (short)KnownElements.ControlTemplate || + -id == (short)KnownElements.DataTemplate || + -id == (short)KnownElements.HierarchicalDataTemplate || + -id == (short)KnownElements.ItemsPanelTemplate) + { + return true; + } + + return false; + } + + // Return a type info record for a type identified by the passed ID. If the + // ID is negative, then this is a known type, so manufacture a BamlTypeInfoRecord + // for it. + internal BamlTypeInfoRecord GetTypeInfoFromId(short id) + { + // If the id is less than 0, it is a known type that lives in the + // known assembly, so manufacture a type info record for it. + if (id < 0) + { + // For some types, we create a TypeInfo record with serializer information. For + // all other types, we create a regular TypeInfo record. + // NOTE: When serializers are publically extensible, then this should be + // reflected for as part of the KnownElementsInitializer. + BamlTypeInfoRecord info; + if (-id == (short)KnownElements.Style) + { + info = new BamlTypeInfoWithSerializerRecord(); + ((BamlTypeInfoWithSerializerRecord)info).SerializerTypeId = + -(int) KnownElements.XamlStyleSerializer; + ((BamlTypeInfoWithSerializerRecord)info).SerializerType = + KnownTypes.Types[(int)KnownElements.XamlStyleSerializer]; + info.AssemblyId = -1; + } + else if (-id == (short)KnownElements.ControlTemplate || + -id == (short)KnownElements.DataTemplate || + -id == (short)KnownElements.HierarchicalDataTemplate || + -id == (short)KnownElements.ItemsPanelTemplate) + { + info = new BamlTypeInfoWithSerializerRecord(); + ((BamlTypeInfoWithSerializerRecord)info).SerializerTypeId = + -(int) KnownElements.XamlTemplateSerializer; + ((BamlTypeInfoWithSerializerRecord)info).SerializerType = + KnownTypes.Types[(int)KnownElements.XamlTemplateSerializer]; + info.AssemblyId = -1; + } + else + { + // Search the Assembly table to see if this type has a match. If not, then + // we know that it is a known assembly for an Avalon known type. We have to do + // this since some of the known types are not avalon types, such as Bool, Object, + // Double, and others... + info = new BamlTypeInfoRecord(); + info.AssemblyId = GetAssemblyIdForType(KnownTypes.Types[-id]); + } + + info.TypeId = id; + info.Type = KnownTypes.Types[-id]; + info.TypeFullName = info.Type.FullName; + return info; + } + else + { + return (BamlTypeInfoRecord) TypeIdMap[id]; + } + } + + // Search the Assembly table to see if this type has a match. If not, then + // we know that it is a known assembly for an Avalon known type. We have to do + // this since some of the known types are not avalon types, such as Bool, Object, + // Double, and others... + private short GetAssemblyIdForType(Type t) + { + string assemblyName = t.Assembly.FullName; + for (int i=0; i= 0, "Known Property Id must be a DependencyProperty."); + + BamlAttributeInfoRecord attributeInfo = GetAttributeInfoFromIdWithOwnerType(attributeId); + if (attributeInfo != null && attributeInfo.OwnerType != null) + { + // Update the CLR propInfo into the AttributeInfoRecord. + XamlTypeMapper.UpdateClrPropertyInfo(attributeInfo.OwnerType, attributeInfo); + // Get the property Type from the Info. + propType = attributeInfo.GetPropertyType(); + } + else + { + propName = string.Empty; + } + + if (propType == null) + { + if (propName == null) + { + propName = attributeInfo.OwnerType.FullName + "." + attributeInfo.Name; + } + + ThrowException(SRID.ParserNoPropType, propName); + } + else + { + propName = attributeInfo.Name; + } + + return propType; + } + + internal DependencyProperty GetDependencyPropertyValueFromId(short memberId, string memberName, out Type declaringType) + { + declaringType = null; + DependencyProperty dp = null; + + if (memberName == null) + { + Debug.Assert(memberId < 0); + KnownProperties knownId = (KnownProperties)(-memberId); + if (knownId < KnownProperties.MaxDependencyProperty + || knownId == KnownProperties.Run_Text) + { + dp = KnownTypes.GetKnownDependencyPropertyFromId(knownId); + } + } + else + { + declaringType = GetTypeFromId(memberId); + dp = DependencyProperty.FromName(memberName, declaringType); + } + + return dp; + } + + // Finds a DependencyProperty from the Known tables or attribInfo + internal DependencyProperty GetDependencyPropertyValueFromId(short memberId) + { + DependencyProperty dp = null; + if (memberId < 0) + { + KnownProperties knownId = (KnownProperties)(-memberId); + if (knownId < KnownProperties.MaxDependencyProperty) + { + dp = KnownTypes.GetKnownDependencyPropertyFromId(knownId); + } + } + + if (dp == null) + { + string name; + short ownerTypeId; + BamlAttributeUsage attributeUsage; + + GetAttributeInfoFromId(memberId, + out ownerTypeId, + out name, + out attributeUsage); + Type declaringType = GetTypeFromId(ownerTypeId); + dp = DependencyProperty.FromName(name, declaringType); + } + + return dp; + } + + internal DependencyProperty GetDependencyProperty(int id) + { + if (id < 0) + { + return KnownTypes.GetKnownDependencyPropertyFromId((KnownProperties)(-id)); + } + else + { + BamlAttributeInfoRecord attribInfo = (BamlAttributeInfoRecord)AttributeIdMap[id]; + return GetDependencyProperty(attribInfo); + } + } + + // Return the DependencyProperty given an attribute info record. The DP + // is cached in the info record. + internal DependencyProperty GetDependencyProperty(BamlAttributeInfoRecord bamlAttributeInfoRecord) + { + if ((null == bamlAttributeInfoRecord.DP) && (null == bamlAttributeInfoRecord.PropInfo)) + { + // This will update the record + GetAttributeOwnerType(bamlAttributeInfoRecord); + + if (null != bamlAttributeInfoRecord.OwnerType) + { + bamlAttributeInfoRecord.DP = DependencyProperty.FromName( + bamlAttributeInfoRecord.Name, + bamlAttributeInfoRecord.OwnerType); + } + } + + return bamlAttributeInfoRecord.DP; + } + + // Return the RoutedEvent given an attribute info record. The RoutedEvent + // is cached in the info record. + internal RoutedEvent GetRoutedEvent(BamlAttributeInfoRecord bamlAttributeInfoRecord) + { + if (null == bamlAttributeInfoRecord.Event) + { + Type ownerType = GetAttributeOwnerType(bamlAttributeInfoRecord); + + if (null != ownerType) + { + bamlAttributeInfoRecord.Event = XamlTypeMapper.RoutedEventFromName(bamlAttributeInfoRecord.Name,ownerType); + } + } + + return bamlAttributeInfoRecord.Event; + } + +#endif + + internal short GetAttributeOrTypeId(BinaryWriter binaryWriter, Type declaringType, string memberName, out short typeId) + { + short propertyId = 0; + if (!GetTypeInfoId(binaryWriter, + declaringType.Assembly.FullName, + declaringType.FullName, + out typeId)) + { + typeId = AddTypeInfoMap(binaryWriter, + declaringType.Assembly.FullName, + declaringType.FullName, + declaringType, + string.Empty, + string.Empty); + } + else if (typeId < 0) + { + // Only known types will have known properties + propertyId = (short)-KnownTypes.GetKnownPropertyAttributeId((KnownElements)(-typeId), memberName); + } + + return propertyId; + } + + // Return an assembly info record for the assembly identified by the passed ID + internal BamlAssemblyInfoRecord GetAssemblyInfoFromId(short id) + { + // If the id is -1, then it is in the known assembly where all of + // the Avalon controls are defined. In that + // case return the known assembly info record. + if (id == -1) + { + return KnownAssemblyInfoRecord; + } + else + { + return (BamlAssemblyInfoRecord)AssemblyIdMap[id]; + } + } + + // Return the Assembly from the passed Assembly info record. This is cached in + // the info record. + private Assembly GetAssemblyFromAssemblyInfo(BamlAssemblyInfoRecord assemblyInfoRecord) + { + if (null == assemblyInfoRecord.Assembly) + { + string path = XamlTypeMapper.AssemblyPathFor(assemblyInfoRecord.AssemblyFullName); + assemblyInfoRecord.Assembly = ReflectionHelper.LoadAssembly(assemblyInfoRecord.AssemblyFullName, path); + } + + return assemblyInfoRecord.Assembly; + } + + // assembly maps + // mapping of ids to Assembly Names and Assembly reference + // create an entry for every referenced assembly passed in on compile + // in case no tags reference it at compile but do at Load we won't need + // to be given this information again. + + internal BamlAssemblyInfoRecord AddAssemblyMap( + BinaryWriter binaryWriter, + string assemblyFullName) + { + Debug.Assert(assemblyFullName.Length != 0, "empty assembly"); + + AssemblyInfoKey key = new AssemblyInfoKey(); + key.AssemblyFullName = assemblyFullName; + + BamlAssemblyInfoRecord bamlAssemblyInfoRecord = + (BamlAssemblyInfoRecord) GetHashTableData(key); + + if (null == bamlAssemblyInfoRecord) + { + bamlAssemblyInfoRecord = new BamlAssemblyInfoRecord(); + bamlAssemblyInfoRecord.AssemblyFullName = assemblyFullName; + +#if PBTCOMPILER + try + { + if (bamlAssemblyInfoRecord.Assembly == null) + { + // Load the assembly so that we can get the Assembly.FullName to store in Baml. + // This will ensure that we are we use the same assembly during compilation and loading. + GetAssemblyFromAssemblyInfo(bamlAssemblyInfoRecord); + if (bamlAssemblyInfoRecord.Assembly != null && + bamlAssemblyInfoRecord.Assembly.FullName != assemblyFullName) + { + // Given name is a partial name for the assembly + + // Add AssemblyInfo for the full name of the assembly and add a cache entry + // for the same record against the partial name. Note that there is no need + // to write a Baml record for the partial assembly name + bamlAssemblyInfoRecord = AddAssemblyMap(binaryWriter, bamlAssemblyInfoRecord.Assembly.FullName); + + ObjectHashTable.Add(key, bamlAssemblyInfoRecord); + + // Records written out the Baml must have a legitimate Assembly ID + Debug.Assert(bamlAssemblyInfoRecord.AssemblyId >= 0); + + return bamlAssemblyInfoRecord; + } + else + { + // Given name is the full name for the assembly. Simply add a cache entry for + // the record and write it out to Baml. + } + } + } + catch(Exception e) + { + if (CriticalExceptions.IsCriticalException(e)) + { + throw; + } + + // It is possible that the we are writing out a record for the very same assembly + // that is being built on compilation. Hence the assembly may not get loaded. + } +#endif + + // review, could be a race condition here. + bamlAssemblyInfoRecord.AssemblyId = (short) AssemblyIdMap.Add(bamlAssemblyInfoRecord); + + ObjectHashTable.Add(key,bamlAssemblyInfoRecord); + + // Write to BAML + bamlAssemblyInfoRecord.Write(binaryWriter); + } + else if (bamlAssemblyInfoRecord.AssemblyId == -1) + { + // This is the case when EnsureAssemblyRecord has cached the AssemblyInfo but hasn't + // written it out to Baml. This now needs to be written out to Baml. + + Debug.Assert( + bamlAssemblyInfoRecord.Assembly != null && + bamlAssemblyInfoRecord.Assembly.FullName == bamlAssemblyInfoRecord.AssemblyFullName); + + // review, could be a race condition here. + bamlAssemblyInfoRecord.AssemblyId = (short) AssemblyIdMap.Add(bamlAssemblyInfoRecord); + + // Write to BAML + bamlAssemblyInfoRecord.Write(binaryWriter); + } + + // Records written out the Baml must have a legitimate Assembly ID + Debug.Assert(bamlAssemblyInfoRecord.AssemblyId >= 0); + + return bamlAssemblyInfoRecord; + } + +#if !PBTCOMPILER + // Add an already-loaded assembly record to the map table. These are generally + // appended to the end. If we specify an existing slot in the table, make + // sure we are not overwriting existing data. + internal void LoadAssemblyInfoRecord(BamlAssemblyInfoRecord record) + { + Debug.Assert(AssemblyIdMap.Count == record.AssemblyId || + record.AssemblyFullName == + ((BamlAssemblyInfoRecord)AssemblyIdMap[record.AssemblyId]).AssemblyFullName); + + if (AssemblyIdMap.Count == record.AssemblyId) + { + AssemblyIdMap.Add(record); + } + } +#endif + + /// + /// Ensure we have an assembly record for this assembly + /// + internal void EnsureAssemblyRecord(Assembly asm) + { + string fullName = asm.FullName; + BamlAssemblyInfoRecord record = ObjectHashTable[fullName] as BamlAssemblyInfoRecord; + + // If we don't have an assembly record for this assembly yet it is most likely + // because it is an assembly that is part of the default namespace and was not defined + // using a mapping PI. In that case, add an assembly record to the object cache and + // populate it with the required data. Note that it DOES NOT have a valid AssemblyId + // and this is not written out the the baml stream. + if (record == null ) + { + record = new BamlAssemblyInfoRecord(); + record.AssemblyFullName = fullName; + record.Assembly = asm; + ObjectHashTable[fullName] = record; + } + + } + + // Return the hash table key used for a type info record with the given + // assembly name and type full name. The type full name must include + // the entire clr namespace. + private TypeInfoKey GetTypeInfoKey( + string assemblyFullName, + string typeFullName) + { + TypeInfoKey key = new TypeInfoKey(); + key.DeclaringAssembly = assemblyFullName; + key.TypeFullName = typeFullName; + return key; + } + + // Given an assembly name and a type name, see if there is a known fixed type + // that corresponds to this, or if we have already added a type info record for + // this type. If so, set the returned id and answer true. Otherwise answer false. + internal bool GetTypeInfoId( + BinaryWriter binaryWriter, + string assemblyFullName, + string typeFullName, + out short typeId) + { + int dotIndex = typeFullName.LastIndexOf(".", StringComparison.Ordinal); + string typeShortName; + string typeClrNamespace; + if (dotIndex >= 0) + { + typeShortName = typeFullName.Substring(dotIndex+1); + typeClrNamespace = typeFullName.Substring(0, dotIndex); + } + else + { + typeShortName = typeFullName; + typeClrNamespace = string.Empty; + } + typeId = GetKnownTypeIdFromName(assemblyFullName, typeClrNamespace, typeShortName); + + if (typeId < 0) + { + return true; + } + + TypeInfoKey key = GetTypeInfoKey(assemblyFullName, typeFullName); + + BamlTypeInfoRecord bamlTypeInfoRecord = (BamlTypeInfoRecord) GetHashTableData(key); + + if (bamlTypeInfoRecord == null) + { + return false; + } + else + { + typeId = bamlTypeInfoRecord.TypeId; + return true; + } + } + + + // Return the Type ID for the passed typeFullName by creating a new record and adding + // it to the type info hashtable. A BamlTypeInfoRecord is created if there is no serializer + // for this type, and a BamlTypeInfoWithSerializerRecord is created if there is a serializer. + internal short AddTypeInfoMap(BinaryWriter binaryWriter, + string assemblyFullName, + string typeFullName, + Type elementType, + string serializerAssemblyFullName, + string serializerTypeFullName) + { + TypeInfoKey key = GetTypeInfoKey(assemblyFullName, typeFullName); + BamlTypeInfoRecord bamlTypeInfoRecord; + + // Create either a normal TypeInfo record, or a TypeInfoWithSerializer record, depending + // on whether or not there is a serializer for this type. + if (serializerTypeFullName == string.Empty) + { + bamlTypeInfoRecord = new BamlTypeInfoRecord(); + } + else + { + bamlTypeInfoRecord = new BamlTypeInfoWithSerializerRecord(); + short serializerTypeId; + // If we do not already have a type record for the serializer associated with + // this type, then recurse and write out the serializer assembly and type first. + if (!GetTypeInfoId(binaryWriter, serializerAssemblyFullName, serializerTypeFullName, out serializerTypeId)) + { + serializerTypeId = AddTypeInfoMap(binaryWriter, serializerAssemblyFullName, + serializerTypeFullName, null, + string.Empty, string.Empty); + } + ((BamlTypeInfoWithSerializerRecord)bamlTypeInfoRecord).SerializerTypeId = serializerTypeId; + } + + bamlTypeInfoRecord.TypeFullName = typeFullName; + + // get id for assembly + BamlAssemblyInfoRecord bamlAssemblyInfoRecord = AddAssemblyMap(binaryWriter, assemblyFullName); + bamlTypeInfoRecord.AssemblyId = bamlAssemblyInfoRecord.AssemblyId; + + bamlTypeInfoRecord.IsInternalType = (elementType != null && ReflectionHelper.IsInternalType(elementType)); + + // review, could be a race condition here. + bamlTypeInfoRecord.TypeId = (short) TypeIdMap.Add(bamlTypeInfoRecord); + + // add to the hash + ObjectHashTable.Add(key,bamlTypeInfoRecord); + + // Write to BAML + bamlTypeInfoRecord.Write(binaryWriter); + + return bamlTypeInfoRecord.TypeId; + } + +#if !PBTCOMPILER + // Add an already-loaded type info record to the map table. This can + // only be appended to the end of the existing map. If it is the same + // as an existing record, ensure we're not trying to overwrite something. + internal void LoadTypeInfoRecord(BamlTypeInfoRecord record) + { + Debug.Assert(TypeIdMap.Count == record.TypeId || + record.TypeFullName == + ((BamlTypeInfoRecord)TypeIdMap[record.TypeId]).TypeFullName); + + if (TypeIdMap.Count == record.TypeId) + { + TypeIdMap.Add(record); + } + } +#endif + + // Return the key to use when inserting or extracting attribute information + // from the object cache. + internal object GetAttributeInfoKey ( + string ownerTypeName, + string attributeName) + { + Debug.Assert(ownerTypeName != null); + Debug.Assert(attributeName != null); + return ownerTypeName + "." + attributeName; + } + + // Return the attribute info record that corresponds to the passed type and field name. + // If one does not already exist, then create a new one. This can involve first creating + // a type info record that corresponds to the owner type and the attribute type. + // This method also checks if the attributeType is custom serializable or convertible. + internal short AddAttributeInfoMap( + BinaryWriter binaryWriter, + string assemblyFullName, // Name of assembly for owning or declaring type + string typeFullName, // Type name of object that owns or declares this attribute + Type owningType, // Actual type of the object the owns or declares this attribute + string fieldName, // Name of the attribute + Type attributeType, // Type of the attribute or property itself; not its owner type + BamlAttributeUsage attributeUsage) // Special flags for how this attribute is used. + { + BamlAttributeInfoRecord record; + return AddAttributeInfoMap(binaryWriter, assemblyFullName, typeFullName, owningType, fieldName, attributeType, attributeUsage, out record); + } + + internal short AddAttributeInfoMap( + BinaryWriter binaryWriter, + string assemblyFullName, // Name of assembly for owning or declaring type + string typeFullName, // Type name of object that owns or declares this attribute + Type owningType, // Actual type of the object the owns or declares this attribute + string fieldName, // Name of the attribute + Type attributeType, // Type of the attribute or property itself; not its owner type + BamlAttributeUsage attributeUsage, // Special flags for how this attribute is used. + out BamlAttributeInfoRecord bamlAttributeInfoRecord) // Record if not a known DP + { + short typeId; + // If we do not already have a type record for the type associated with + // this attribute, then recurse and write out the TypeInfo first. + if (!GetTypeInfoId(binaryWriter, assemblyFullName, typeFullName, out typeId)) + { + // Get id for Type that owns or has this attribute declared on it. This is + // refered to in the attribute info record and is also part of the key for + // seeing if we already have an attribute info record for this attribute. + Type serializerType = XamlTypeMapper.GetXamlSerializerForType(owningType); + string serializerTypeAssemblyName = serializerType == null ? + string.Empty : serializerType.Assembly.FullName; + string serializerTypeName = serializerType == null ? + string.Empty : serializerType.FullName; + + typeId = AddTypeInfoMap(binaryWriter, assemblyFullName, typeFullName, + owningType, serializerTypeAssemblyName, + serializerTypeName); + } + else if (typeId < 0) + { + // Only known types will have known properties + short attributeId = (short)-KnownTypes.GetKnownPropertyAttributeId((KnownElements)(-typeId), fieldName); + if (attributeId < 0) + { + // The property is known and doesn't need a record created. + bamlAttributeInfoRecord = null; + return attributeId; + } + } + + object key = GetAttributeInfoKey(typeFullName, fieldName); + + bamlAttributeInfoRecord = (BamlAttributeInfoRecord)GetHashTableData(key); + if (null == bamlAttributeInfoRecord) + { + // The property is new and needs a record created. + bamlAttributeInfoRecord = new BamlAttributeInfoRecord(); + + bamlAttributeInfoRecord.Name = fieldName; + bamlAttributeInfoRecord.OwnerTypeId = typeId; + + bamlAttributeInfoRecord.AttributeId = (short)AttributeIdMap.Add(bamlAttributeInfoRecord); + bamlAttributeInfoRecord.AttributeUsage = attributeUsage; + + // add to the hash + ObjectHashTable.Add(key, bamlAttributeInfoRecord); + + // Write to BAML + bamlAttributeInfoRecord.Write(binaryWriter); + } + + return bamlAttributeInfoRecord.AttributeId; + } + + // Set flags saying whether this attribute supports custom serialization or type conversion, + // based on whether the attribute type has a serializer or a type converter. + // returns true if a serialiazer was found, else if a converter or nothing was found, returns false. + internal bool GetCustomSerializerOrConverter( + BinaryWriter binaryWriter, + Type ownerType, // Type of object that owns or declares this attribute + Type attributeType, // Type of the attribute or property itself; not its owner type + object piOrMi, // PropertyInfo or AttachedPropertySetter corresponding to the attribute + string fieldName, // Name of the property + out short converterOrSerializerTypeId, + out Type converterOrSerializerType) + { + converterOrSerializerType = null; + converterOrSerializerTypeId = 0; + + if (!ShouldBypassCustomCheck(ownerType, attributeType)) + { + converterOrSerializerType = GetCustomSerializer(attributeType, out converterOrSerializerTypeId); + + // NOTE: We do not want to check for custom converters when the property is + // known to be custom serializable or it is a complex property. + if (converterOrSerializerType != null) + { + return true; + } + + converterOrSerializerType = GetCustomConverter(piOrMi, ownerType, fieldName, attributeType); + + // Enum prop values are custom serilized if there is no custom convertor for them. + // This needs to be done here as GetCustomSerilaizer() does not do this in order to + // give precedence to custom TypeConverters first. + if (converterOrSerializerType == null && attributeType.IsEnum) + { + converterOrSerializerTypeId = (short)KnownElements.EnumConverter; + converterOrSerializerType = KnownTypes.Types[(int)converterOrSerializerTypeId]; + return true; + } + + // If we found a custom serializer or a type converter then we need to write it out to Baml + if (converterOrSerializerType != null) + { + string converterOrSerializerTypeFullName = converterOrSerializerType.FullName; + + EnsureAssemblyRecord(converterOrSerializerType.Assembly); + + // If we do not already have a type record for the type associated with with the serializer or + // type converter for this attribute, then recurse and write out the TypeInfo first. + // NOTE: Known types will get filtered out here. + if (!GetTypeInfoId(binaryWriter, converterOrSerializerType.Assembly.FullName, + converterOrSerializerTypeFullName, out converterOrSerializerTypeId)) + { + // Get id for the converter or serializer type. + converterOrSerializerTypeId = AddTypeInfoMap(binaryWriter, + converterOrSerializerType.Assembly.FullName, + converterOrSerializerTypeFullName, + null, string.Empty, string.Empty); + } + } + } + + return false; + } + + // Given a string value, see if there is a known fixed string value + // that corresponds to this, or if we have already added a string info record for + // this value. If so, set the returned id and answer true. Otherwise answer false. + internal bool GetStringInfoId( + string stringValue, + out Int16 stringId) + { + stringId = GetKnownStringIdFromName(stringValue); + + if (stringId < 0) + { + return true; + } + + BamlStringInfoRecord bamlStringInfoRecord = (BamlStringInfoRecord) GetHashTableData(stringValue); + + if (bamlStringInfoRecord == null) + { + return false; + } + else + { + stringId = bamlStringInfoRecord.StringId; + return true; + } + } + + // String table Map + // This adds a new BamlStringInfoRecord to the string table for + // a given string. This should NOT be called if the string already + // is in the string table and in the known objects hash table. + internal Int16 AddStringInfoMap( + BinaryWriter binaryWriter, + string stringValue) + { + Debug.Assert(GetHashTableData(stringValue) == null, + "Already have this String in the BamlMapTable string table"); + + BamlStringInfoRecord stringInfo = new BamlStringInfoRecord(); + stringInfo.StringId = (short)StringIdMap.Add(stringInfo); + stringInfo.Value = stringValue; + + // add to the hash + ObjectHashTable.Add(stringValue, stringInfo); + + // Write to BAML + stringInfo.Write(binaryWriter); + + // return the string id + return stringInfo.StringId; + } + + // Returns an Id for a static property or field member whose Type could be + // a known SystemResourceKey or DepenencyProperty or other custom value. + internal short GetStaticMemberId(BinaryWriter binaryWriter, + ParserContext pc, + short extensionTypeId, + string memberValue, + Type defaultTargetType) + { + short memberId = 0; + Type targetType = null; + string memberName = null; + + switch (extensionTypeId) + { + case (short)KnownElements.StaticExtension: + + targetType = XamlTypeMapper.GetTargetTypeAndMember(memberValue, pc, true, out memberName); + Debug.Assert(targetType != null && memberName != null); + + MemberInfo memberInfo = XamlTypeMapper.GetStaticMemberInfo(targetType, memberName, false); + if (memberInfo is PropertyInfo) + { + // see if the value is a static SystemResourceKey property from the themes + memberId = SystemResourceKey.GetBamlIdBasedOnSystemResourceKeyId(targetType, memberName); + } + + break; + + case (short)KnownElements.TemplateBindingExtension: + targetType = XamlTypeMapper.GetDependencyPropertyOwnerAndName(memberValue, + pc, + defaultTargetType, + out memberName); + break; + } + + if (memberId == 0) + { + // if not a known member, add it to the attributeInfo Map. + // This will automatically account for known DPs. + memberId = AddAttributeInfoMap(binaryWriter, + targetType.Assembly.FullName, + targetType.FullName, + targetType, + memberName, + null, + BamlAttributeUsage.Default); + } + + return memberId; + } + + // Particular attributes do need to be tested for custom serialization + // or type conversion. This method checks for those. + private bool ShouldBypassCustomCheck( + Type declaringType, // Type of object that owns or declares this attribute + Type attributeType) // Type of the attribute or property itself; not its owner type + { + // declaringType could be null/empty for some Style properties such as PropertyPath/Value/Target. + if (declaringType == null) + { + return true; + } + + // attributeType could be null for IList/IDictionary/Array complex properties or for events + if (attributeType == null) + { + return true; + } + + return false; + } + + // Returns a TypeConverter for a property. + private Type GetCustomConverter( + object piOrMi, // PropertyInfo or AttachedPropertySetter for the attribute + Type ownerType, // Type of object that owns or declares this attribute + string fieldName, // Name of the attribute + Type attributeType) // Type of the attribute or property itself; not its owner type + { + // Check for known per property type converter + Type converterType = GetKnownConverterTypeFromPropName(ownerType, fieldName); + if (converterType != null) + { + return converterType; + } + + // Reflect for per property type converter , but skip if WinFx props + Assembly ownerAsm = ownerType.Assembly; +#if PBTCOMPILER + if (XamlTypeMapper.AssemblyPF != ownerAsm && + XamlTypeMapper.AssemblyPC != ownerAsm && + XamlTypeMapper.AssemblyWB != ownerAsm) +#else + if (!ownerAsm.FullName.StartsWith("PresentationFramework", StringComparison.OrdinalIgnoreCase) && + !ownerAsm.FullName.StartsWith("PresentationCore", StringComparison.OrdinalIgnoreCase) && + !ownerAsm.FullName.StartsWith("WindowsBase", StringComparison.OrdinalIgnoreCase)) +#endif + { + converterType = XamlTypeMapper.GetPropertyConverterType(attributeType, piOrMi); + if (converterType != null) + { + return converterType; + } + } + + // If we haven't found a per-property converter, look for the converter + // for the attribute's type. + converterType = XamlTypeMapper.GetTypeConverterType(attributeType); + + return converterType; + } + + // Returns a custom serializer Type & Id that is used to more + // efficiently store the value of a "type" instance in binary format + private Type GetCustomSerializer( + Type type, + out short converterOrSerializerTypeId) + { + int index; + + // Check for known custom serializable types + if (type == typeof(Boolean)) + { + index = (int)KnownElements.BooleanConverter; + } + else if (type == KnownTypes.Types[(int)KnownElements.DependencyProperty]) + { + index = (int)KnownElements.DependencyPropertyConverter; + } + else + { + index = XamlTypeMapper.GetCustomBamlSerializerIdForType(type); + if (index == 0) + { + converterOrSerializerTypeId = 0; + return null; + } + } + + converterOrSerializerTypeId = (short)index; + return KnownTypes.Types[index]; + } + +#if !PBTCOMPILER + // Helper method to throw an Exception. + void ThrowException(string id, string parameter) + { + ApplicationException bamlException = new ApplicationException( + SR.Get(id, parameter)); + throw bamlException; + } + + // Add an already-loaded type info record to the map table. This is generally + // appended as the baml file is being built. If we are loading an attribute + // into an already set up map table, just ensure that we don't try to overwrite + // an existing record something different. + internal void LoadAttributeInfoRecord(BamlAttributeInfoRecord record) + { + Debug.Assert(AttributeIdMap.Count == record.AttributeId || + record.Name == + ((BamlAttributeInfoRecord)AttributeIdMap[record.AttributeId]).Name); + + if (AttributeIdMap.Count == record.AttributeId) + { + AttributeIdMap.Add(record); + } + } + + // Add an already-loaded String info record to the map table. This is generally + // appended as the baml file is being built. If we are loading a string + // into an already set up map table, just ensure that we don't try to overwrite + // an existing record something different. + internal void LoadStringInfoRecord(BamlStringInfoRecord record) + { + Debug.Assert(StringIdMap.Count == record.StringId || + record.Value == + ((BamlStringInfoRecord)StringIdMap[record.StringId]).Value); + + if (StringIdMap.Count == record.StringId) + { + StringIdMap.Add(record); + } + } +#endif + + // returns the items if found in the hash table + // if no item is found null is returned. + internal Object GetHashTableData(object key) + { + return ObjectHashTable[key]; + } + +#if !PBTCOMPILER + // Add item to the hash table. Only do this if the map table + // is being re-used for multiple parses. Otherwise the hash table + // data is of no use for a single parse. + internal void AddHashTableData(object key, object data) + { + if (_reusingMapTable) + { + ObjectHashTable[key] = data; + } + } +#endif + +#if !PBTCOMPILER + internal BamlMapTable Clone() + { + BamlMapTable table = new BamlMapTable(_xamlTypeMapper); + + table._objectHashTable = (Hashtable)_objectHashTable.Clone(); + table._assemblyIdToInfo = (ArrayList)_assemblyIdToInfo.Clone(); + table._typeIdToInfo = (ArrayList)_typeIdToInfo.Clone(); + table._attributeIdToInfo = (ArrayList)_attributeIdToInfo.Clone(); + table._stringIdToInfo = (ArrayList)_stringIdToInfo.Clone(); + return table; + } + + private TypeConverter GetConverterFromCache(short typeId) + { + TypeConverter tc = null; + if (_converterCache != null) + { + tc = _converterCache[typeId] as TypeConverter; + } + + return tc; + } + + private TypeConverter GetConverterFromCache(Type type) + { + TypeConverter tc = null; + if (_converterCache != null) + { + tc = _converterCache[type] as TypeConverter; + } + + return tc; + } + + internal void ClearConverterCache() + { + // clear the Type converterCache to reduce survived memory allocs + if (_converterCache != null) + { + _converterCache.Clear(); + _converterCache = null; + } + } +#endif + +#endregion Methods + +#region Properties + + private Hashtable ObjectHashTable + { + get {return _objectHashTable;} + } + + private ArrayList AssemblyIdMap + { + get { return _assemblyIdToInfo; } + } + + private ArrayList TypeIdMap + { + get { return _typeIdToInfo; } + } + + private ArrayList AttributeIdMap + { + get { return _attributeIdToInfo; } + } + + private ArrayList StringIdMap + { + get { return _stringIdToInfo; } + } + + internal XamlTypeMapper XamlTypeMapper + { + get { return _xamlTypeMapper; } + +#if !PBTCOMPILER + set { _xamlTypeMapper = value; } +#endif + } + + // Return true if this map table has been sealed, meaning it contains a complete + // set of attribute information for a particular baml file. +#if !PBTCOMPILER + private Hashtable ConverterCache + { + get + { + if (_converterCache == null) + { + _converterCache = new Hashtable(); + } + + return _converterCache; + } + } +#endif + + #endregion Properties + + + #region Data + + private const string _coreAssembly = "PresentationCore"; + private const string _frameworkAssembly = "PresentationFramework"; + private static BamlAssemblyInfoRecord KnownAssemblyInfoRecord; + + private static string[] _knownStrings = + { + null, + "Name", + "Uid", + }; + + internal static short NameStringId = -1; // Known index of "Name" + internal static short UidStringId = -2; // Known index of "Uid" + internal static string NameString = "Name"; // Now used during Style serialization + + // currently one Hastable for everything, when do perf + // see if any advantage in breaking up or searching + // by PropId, etc. instead of Hash. Hash is only used on compile + // so leave null so Load doesn't take the hit. + Hashtable _objectHashTable = new Hashtable(); + + ArrayList _assemblyIdToInfo = new ArrayList(1); // arrayList of Assemblies + ArrayList _typeIdToInfo = new ArrayList(0); // arrayList of class Types + ArrayList _attributeIdToInfo = new ArrayList(10); // arrayList of Attribute Ids + ArrayList _stringIdToInfo = new ArrayList(1); // arrayList of String Info + + // XamlTypeMapper associated with this map table. There is always a one-to-one correspondence. + XamlTypeMapper _xamlTypeMapper; + +#if !PBTCOMPILER + // Temporary cache of Known Type Converters for each baml reading session. + Hashtable _converterCache = null; +#endif + +#if !PBTCOMPILER + // True if this instance of the BamlMapTable is being reused between + // different parses. This is done to maintain the ObjectHashTable so that + // less reflection is done for types and properties. + bool _reusingMapTable = false; +#endif + +#endregion Data + + } + + // Key object for hash table of assemblies. This is keyed by assembly full name. + internal struct AssemblyInfoKey + { + internal string AssemblyFullName; + + /// + /// Determines if the passed in struct is equal to this struct. + /// Two keys will be equal if they both have equal assembly names. + /// + public override bool Equals(object o) + { + if (o is AssemblyInfoKey) + { + AssemblyInfoKey key = (AssemblyInfoKey)o; + + return ((key.AssemblyFullName != null) ? + key.AssemblyFullName.Equals(this.AssemblyFullName) : + (this.AssemblyFullName == null)); + } + else + { + return false; + } + } + + /// + /// Forward to .Equals + /// + public static bool operator ==(AssemblyInfoKey key1, AssemblyInfoKey key2) + { + return key1.Equals(key2); + } + + /// + /// Forward to .Equals + /// + public static bool operator !=(AssemblyInfoKey key1, AssemblyInfoKey key2) + { + return !(key1.Equals(key2)); + } + + /// + /// Serves as a hash function for using this in a hashtable. + /// + public override int GetHashCode() + { + return ((AssemblyFullName != null) ? AssemblyFullName.GetHashCode() : 0); + } + + /// + /// Return string representation of this key + /// + public override string ToString() + { + return AssemblyFullName; + } + + } + + + // Key object for hash table of types. This is keyed by assembly and + // type full name. + internal struct TypeInfoKey + { + internal string DeclaringAssembly; + internal string TypeFullName; + + /// + /// Determines if the passed in struct is equal to this struct. + /// Two keys will be equal if they both have equal assembly and names. + /// + public override bool Equals(object o) + { + if (o is TypeInfoKey) + { + TypeInfoKey key = (TypeInfoKey)o; + + return ((key.DeclaringAssembly != null) ? + key.DeclaringAssembly.Equals(this.DeclaringAssembly) : + (this.DeclaringAssembly == null)) && + ((key.TypeFullName != null) ? + key.TypeFullName.Equals(this.TypeFullName) : + (this.TypeFullName == null)); + } + else + { + return false; + } + } + + /// + /// Forward to .Equals + /// + public static bool operator ==(TypeInfoKey key1, TypeInfoKey key2) + { + return key1.Equals(key2); + } + + /// + /// Forward to .Equals + /// + public static bool operator !=(TypeInfoKey key1, TypeInfoKey key2) + { + return !(key1.Equals(key2)); + } + + /// + /// Serves as a hash function for using this in a hashtable. + /// + public override int GetHashCode() + { + return ((DeclaringAssembly != null) ? DeclaringAssembly.GetHashCode() : 0) ^ + ((TypeFullName != null) ? TypeFullName.GetHashCode() : 0); + } + + /// + /// Return string representation of this key + /// + public override string ToString() + { + StringBuilder strBuilder = new StringBuilder(256); + strBuilder.Append("TypeInfoKey: Assembly="); + strBuilder.Append((DeclaringAssembly != null) ? DeclaringAssembly : "null"); + strBuilder.Append(" Type="); + strBuilder.Append((TypeFullName != null) ? TypeFullName : "null"); + return strBuilder.ToString(); + } + + } + + +} + + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecordHelper.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecordHelper.cs new file mode 100644 index 00000000000..5d0b08bf80b --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecordHelper.cs @@ -0,0 +1,137 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics; + + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +using System.Windows; +namespace System.Windows.Markup +#endif +{ + // Helper functions for baml records + + static internal class BamlRecordHelper + { +#if !PBTCOMPILER + // + // This method checks to see if the baml record type is one of the records used + // to build up the map table, e.g. type information. + // + static internal bool IsMapTableRecordType( BamlRecordType bamlRecordType ) + { + switch( bamlRecordType ) + { + case BamlRecordType.PIMapping: + case BamlRecordType.AssemblyInfo: + case BamlRecordType.TypeInfo: + case BamlRecordType.TypeSerializerInfo: + case BamlRecordType.AttributeInfo: + case BamlRecordType.StringInfo: + return true; + + default: + return false; + } + } + + internal static bool IsDebugBamlRecordType(BamlRecordType recordType) + { + if ( recordType == BamlRecordType.LineNumberAndPosition + || recordType == BamlRecordType.LinePosition ) + { + return true; + } + return false; + } + + // Does the given Baml Record have a Debug Baml Record in its Next link. + internal static bool HasDebugExtensionRecord(bool isDebugBamlStream, BamlRecord bamlRecord) + { + if (isDebugBamlStream && (bamlRecord.Next != null)) + { + if (IsDebugBamlRecordType(bamlRecord.Next.RecordType)) + { + return true; + } + } + return false; + } +#endif + + internal static bool DoesRecordTypeHaveDebugExtension(BamlRecordType recordType) + { + switch(recordType) + { + case BamlRecordType.ElementStart: + case BamlRecordType.ElementEnd: + case BamlRecordType.Property: + case BamlRecordType.PropertyComplexStart: + case BamlRecordType.PropertyArrayStart: + case BamlRecordType.PropertyIListStart: + case BamlRecordType.PropertyIDictionaryStart: + case BamlRecordType.XmlnsProperty: + case BamlRecordType.PIMapping: + case BamlRecordType.PropertyTypeReference: + case BamlRecordType.PropertyWithExtension: + case BamlRecordType.PropertyWithConverter: + case BamlRecordType.KeyElementStart: + case BamlRecordType.ConnectionId: + case BamlRecordType.ContentProperty: + case BamlRecordType.StaticResourceStart: + case BamlRecordType.PresentationOptionsAttribute: + return true; + + case BamlRecordType.DocumentStart: + case BamlRecordType.DocumentEnd: // End record + case BamlRecordType.PropertyCustom: // The "custom" size of this is a problem + case BamlRecordType.PropertyComplexEnd: // End record + case BamlRecordType.PropertyArrayEnd: // End record + case BamlRecordType.PropertyIListEnd: // End record + case BamlRecordType.PropertyIDictionaryEnd: // End record + case BamlRecordType.LiteralContent: // Not needed + case BamlRecordType.Text: // Not needed + case BamlRecordType.TextWithConverter: // Not common enough + case BamlRecordType.RoutedEvent: // Not common enough + case BamlRecordType.ClrEvent: // Not common enough + case BamlRecordType.XmlAttribute: // Not common enough + case BamlRecordType.ProcessingInstruction: // Not common enough + case BamlRecordType.Comment: // Not common enough + case BamlRecordType.DefTag: // Not common enough + case BamlRecordType.DefAttribute: // Not common enough + case BamlRecordType.EndAttributes: // Not common enough + case BamlRecordType.AssemblyInfo: // Info records (in general) don't advance file position + case BamlRecordType.TypeInfo: // Info records (in general) don't advance file position + case BamlRecordType.TypeSerializerInfo: // Not common enough + case BamlRecordType.AttributeInfo: // Info records (in general) don't advance file position + case BamlRecordType.StringInfo: // Info records (in general) don't advance file position + case BamlRecordType.PropertyStringReference: // Not common enough + case BamlRecordType.DeferableContentStart: // This would complicate Deferable Content Size + case BamlRecordType.ConstructorParametersStart: // Not Needed + case BamlRecordType.ConstructorParametersEnd: // End record + case BamlRecordType.ConstructorParameterType: // Not Needed + case BamlRecordType.NamedElementStart: // Not common enough + case BamlRecordType.TextWithId: // Not Needed + case BamlRecordType.LineNumberAndPosition: // This would become recursive + case BamlRecordType.LinePosition: // This would become recursive + case BamlRecordType.DefAttributeKeyString: + case BamlRecordType.DefAttributeKeyType: + case BamlRecordType.KeyElementEnd: + case BamlRecordType.StaticResourceEnd: + case BamlRecordType.StaticResourceId: + case BamlRecordType.OptimizedStaticResource: + case BamlRecordType.PropertyWithStaticResourceId: + return false; + + default: + Debug.Assert(false, "Unhandled case in DoesRecordTypeHaveDebugExtension"); + return false; + } + } + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecordWriter.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecordWriter.cs new file mode 100644 index 00000000000..10c4b9b5e3e --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecordWriter.cs @@ -0,0 +1,1955 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/***************************************************************************\ +* +* Purpose: Helper class for writing BAML records +* +\***************************************************************************/ + +using System; +using System.Xml; +using System.IO; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; + +using System.Diagnostics; +using System.Reflection; + +using MS.Utility; + +#if !PBTCOMPILER + +using System.Windows; +using System.Windows.Threading; + +#endif + +#if PBTCOMPILER +using System.Globalization; + +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + + /// + /// Class for writing baml to a stream from XamlParser calls + /// + internal class BamlRecordWriter + { +#region Constructor + + /// + /// Constructor that allows defer loading feature to be enabled, even + /// for non-compile cases. + /// + public BamlRecordWriter( + Stream stream, + ParserContext parserContext, + bool deferLoadingSupport) + { + _bamlStream = stream; + _xamlTypeMapper = parserContext.XamlTypeMapper; + _deferLoadingSupport = deferLoadingSupport; + _bamlMapTable = parserContext.MapTable; + _parserContext = parserContext; + + _debugBamlStream = false; + _lineNumber = -1; + _linePosition = -1; + + _bamlBinaryWriter = new BamlBinaryWriter(stream,new System.Text.UTF8Encoding()); + _bamlRecordManager = new BamlRecordManager(); + } + +#endregion Constructor + +#region Methods + + + // Called by BamlRecordWriter records to persist a record. + internal virtual void WriteBamlRecord( + BamlRecord bamlRecord, + int lineNumber, + int linePosition) + { + try + { + bamlRecord.Write(BinaryWriter); + + if(DebugBamlStream) + { + if(BamlRecordHelper.DoesRecordTypeHaveDebugExtension(bamlRecord.RecordType)) + { + WriteDebugExtensionRecord(lineNumber, linePosition); + } + } + } + catch (XamlParseException e) + { + _xamlTypeMapper.ThrowExceptionWithLine(e.Message, e.InnerException); + } + } + + // Indicates if ParentNodes should be updated. + // This is only used when loading compiled baml so can have node information + internal virtual bool UpdateParentNodes + { + get + { + return true; + } + } + +#if !PBTCOMPILER + // review - this needs to check that setparseMode is called only + // once and only on the Root tag. + internal void SetParseMode(XamlParseMode xamlParseMode) + { + // only update if we are allowed to update the parent nodes + if (UpdateParentNodes) + { + // update the parseMode in the StartRecord. + if (xamlParseMode == XamlParseMode.Asynchronous) + { + Debug.Assert(null != DocumentStartRecord); + if (null != DocumentStartRecord) + { + DocumentStartRecord.LoadAsync = true; + DocumentStartRecord.UpdateWrite(BinaryWriter); + } + } + } + } +#endif + + // Sets the number of Records that can be read at a time + // in async mode. Main use is for debugging. + internal virtual void SetMaxAsyncRecords(int maxAsyncRecords) + { + // only update if we are allowed to update the parent nodes + if (UpdateParentNodes) + { + + Debug.Assert(null != DocumentStartRecord); + if (null != DocumentStartRecord) + { + DocumentStartRecord.MaxAsyncRecords = maxAsyncRecords; + DocumentStartRecord.UpdateWrite(BinaryWriter); + } + } + } + +#region Record Writing + +#region Debug Record Writing + + public bool DebugBamlStream + { + get { return _debugBamlStream; } +#if PBTCOMPILER + set { _debugBamlStream = value; } +#endif + } + + internal BamlLineAndPositionRecord LineAndPositionRecord + { + get + { + if(_bamlLineAndPositionRecord == null) + { + _bamlLineAndPositionRecord = new BamlLineAndPositionRecord(); + } + return _bamlLineAndPositionRecord; + } + } + + internal BamlLinePositionRecord LinePositionRecord + { + get + { + if(_bamlLinePositionRecord == null) + { + _bamlLinePositionRecord = new BamlLinePositionRecord(); + } + return _bamlLinePositionRecord; + } + } + + internal void WriteDebugExtensionRecord(int lineNumber, int linePosition) + { + // if the Linenumber has changed then the Position had also. + // So write out a record with both Line and Position. + if(lineNumber != _lineNumber) + { + BamlLineAndPositionRecord rec = LineAndPositionRecord; + _lineNumber = lineNumber; + rec.LineNumber = (uint)lineNumber; + + _linePosition = linePosition; + rec.LinePosition = (uint)linePosition; + + rec.Write(BinaryWriter); + } + // if the Line has NOT changed but the position has then + // write a smaller record with just the position. + else if(linePosition != _linePosition) + { + _linePosition = linePosition; + BamlLinePositionRecord rec = LinePositionRecord; + rec.LinePosition = (uint)linePosition; + rec.Write(BinaryWriter); + } + // if neither has changed then don't waste space and + // don't write a record. + } + +#endregion Debug Record Writing + + // called to start writing the BAML + internal void WriteDocumentStart(XamlDocumentStartNode xamlDocumentNode) + { + // Always put a Version Block before the Document Start record. + BamlVersionHeader bamlVersion = new BamlVersionHeader(); + bamlVersion.WriteVersion(BinaryWriter); + + DocumentStartRecord = (BamlDocumentStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DocumentStart); + DocumentStartRecord.DebugBaml = DebugBamlStream; + + // go ahead and write initial values to the Stream, will back fill. + // the rootElement. + WriteBamlRecord(DocumentStartRecord, xamlDocumentNode.LineNumber, + xamlDocumentNode.LinePosition); + + BamlRecordManager.ReleaseWriteRecord(DocumentStartRecord); + } + + // called when BAML is completely written + internal void WriteDocumentEnd(XamlDocumentEndNode xamlDocumentEndNode) + { + // write end of document record + BamlDocumentEndRecord endDocument = + (BamlDocumentEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DocumentEnd); + + WriteBamlRecord(endDocument, xamlDocumentEndNode.LineNumber, + xamlDocumentEndNode.LinePosition); + + BamlRecordManager.ReleaseWriteRecord(endDocument); + + // should be done now and evertying fully initialized. + } + + internal void WriteConnectionId(Int32 connectionId) + { + BamlConnectionIdRecord bamlCxnId = + (BamlConnectionIdRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.ConnectionId); + + bamlCxnId.ConnectionId = connectionId; + WriteAndReleaseRecord(bamlCxnId, null); + } + + // following are for writing to the BAML + // Somewhat mimics XMLTextWriter + internal void WriteElementStart(XamlElementStartNode xamlElementNode) + { + // initialize the element and add to the stack + BamlElementStartRecord bamlElement = + (BamlElementStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.ElementStart); + + // If we do not already have a type record for the type of this element, + // then add a new TypeInfo record to the map table. + short typeId; + if (!MapTable.GetTypeInfoId(BinaryWriter, + xamlElementNode.AssemblyName, + xamlElementNode.TypeFullName, + out typeId)) + { + string serializerAssemblyName = string.Empty; + if (xamlElementNode.SerializerType != null) + { + serializerAssemblyName = xamlElementNode.SerializerType.Assembly.FullName; + } + typeId = MapTable.AddTypeInfoMap(BinaryWriter, + xamlElementNode.AssemblyName, + xamlElementNode.TypeFullName, + xamlElementNode.ElementType, + serializerAssemblyName, + xamlElementNode.SerializerTypeFullName); + } + bamlElement.TypeId = typeId; + bamlElement.CreateUsingTypeConverter = xamlElementNode.CreateUsingTypeConverter; + bamlElement.IsInjected = xamlElementNode.IsInjected; + + // Check if the element we are about to write supports deferable content. + // If so, then we have to queue up all the baml records that are contained + // within this element and extract key information (if this is a dictionary). + // At the end tag, the queued records will be written in an optimal order + // and offsets inserted to permit fast runtime indexing of content. + if (_deferLoadingSupport && _deferElementDepth > 0) + { + _deferElementDepth++; + + if (InStaticResourceSection) + { + // Gather all the BamlRecords within the StaticResource section + _staticResourceElementDepth++; + _staticResourceRecordList.Add(new ValueDeferRecord(bamlElement, xamlElementNode.LineNumber, xamlElementNode.LinePosition)); + } + else if (CollectingValues && KnownTypes.Types[(int)KnownElements.StaticResourceExtension] == xamlElementNode.ElementType) + { + // Mark the beginning of a StaticResource section + _staticResourceElementDepth = 1; + _staticResourceRecordList = new List(5); + _staticResourceRecordList.Add(new ValueDeferRecord(bamlElement, xamlElementNode.LineNumber, xamlElementNode.LinePosition)); + } + else + { + // Detect that we are within a DynamicResource Section. + if (InDynamicResourceSection) + { + _dynamicResourceElementDepth++; + } + else if (CollectingValues && KnownTypes.Types[(int)KnownElements.DynamicResourceExtension] == xamlElementNode.ElementType) + { + _dynamicResourceElementDepth = 1; + } + + ValueDeferRecord deferRecord = new ValueDeferRecord(bamlElement, + xamlElementNode.LineNumber, + xamlElementNode.LinePosition); + + if(_deferComplexPropertyDepth > 0) + { + // If we are in the middle of a complex property specified for a defered + // type, we need to append to the _deferElement array. + _deferElement.Add(deferRecord); + } + else if (_deferElementDepth == 2) + { + // If this element is directly below the dictionary root, then put a + // placeholder record in the key collection. If this is not filled + // in before we reach the end of this element's scope, then we don't + // have a key, and that's an error. + + _deferKeys.Add(new KeyDeferRecord(xamlElementNode.LineNumber, + xamlElementNode.LinePosition)); + + // Remember that this element record is for the start of a value, + // so that the offset in the associated key record should be set + // when this record is actually written out to the baml stream. + deferRecord.UpdateOffset = true; + _deferValues.Add(deferRecord); + } + else if (_deferKeyCollecting) + { + // Don't allow a bind or resource reference in a deferable key, since this + // causes problems for resolution. Multi-pass or recursive key resolution + // would be needed to robustly support this feature. + if (typeof(String).IsAssignableFrom(xamlElementNode.ElementType) || + KnownTypes.Types[(int)KnownElements.StaticExtension].IsAssignableFrom(xamlElementNode.ElementType) || + KnownTypes.Types[(int)KnownElements.TypeExtension].IsAssignableFrom(xamlElementNode.ElementType)) + { + ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]).RecordList.Add(deferRecord); + } + else + { + XamlParser.ThrowException(SRID.ParserBadKey, + xamlElementNode.TypeFullName, + xamlElementNode.LineNumber, + xamlElementNode.LinePosition); + } + + } + else + { + _deferValues.Add(deferRecord); + } + } + } + else if (_deferLoadingSupport && KnownTypes.Types[(int)KnownElements.ResourceDictionary].IsAssignableFrom(xamlElementNode.ElementType)) + { + _deferElementDepth = 1; + _deferEndOfStartReached = false; + _deferElement = new ArrayList(2); + _deferKeys = new ArrayList(10); + _deferValues = new ArrayList(100); + + _deferElement.Add(new ValueDeferRecord(bamlElement, + xamlElementNode.LineNumber, + xamlElementNode.LinePosition)); + } + + else + { + WriteBamlRecord(bamlElement, xamlElementNode.LineNumber, + xamlElementNode.LinePosition); + + BamlRecordManager.ReleaseWriteRecord(bamlElement); + } + } + + // The end of an element has been reached, so write out the end indication + internal void WriteElementEnd(XamlElementEndNode xamlElementEndNode) + { + BamlElementEndRecord bamlElementEnd = + (BamlElementEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.ElementEnd); + + // Check if we're queuing up deferable content. If so and we're at the + // end tag for that content, now is the time to actually write everything + // to the baml stream and rewrite in the file locations for the values + // sections. + if (_deferLoadingSupport && _deferElementDepth > 0 && _deferElementDepth-- == 1) + { + WriteDeferableContent(xamlElementEndNode); + + // Clear all defer related instance data + Debug.Assert(_deferElementDepth == 0); + Debug.Assert(_deferComplexPropertyDepth == 0); + Debug.Assert(_staticResourceElementDepth == 0); + Debug.Assert(_dynamicResourceElementDepth == 0); + Debug.Assert(_staticResourceRecordList == null); + _deferKeys = null; + _deferValues = null; + _deferElement = null; + } + else + { + WriteAndReleaseRecord(bamlElementEnd, xamlElementEndNode); + + if (_deferLoadingSupport && _staticResourceElementDepth > 0 && _staticResourceElementDepth-- == 1) + { + // This marks the end of a StaticResource section + + // Process the StaticResourceRecordList that we + // have been gathering this far + WriteStaticResource(); + + // Cleanup the list after processing + Debug.Assert(_staticResourceElementDepth == 0); + _staticResourceRecordList = null; + } + else if (_deferLoadingSupport && _dynamicResourceElementDepth > 0 && _dynamicResourceElementDepth-- == 1) + { + // We have now exited the dynamic resource section + } + } + + // we've come to the end of the element. + } + + // The end of the start tag has been reached. For compile cases, check + // if we are accumulating a deferable block of records. + internal void WriteEndAttributes(XamlEndAttributesNode xamlEndAttributesNode) + { + if (_deferLoadingSupport && _deferElementDepth > 0) + { + _deferEndOfStartReached = true; + } + } + + // Write a literal content blob to BAML + internal void WriteLiteralContent(XamlLiteralContentNode xamlLiteralContentNode) + { + // initialize the element and add to the stack + BamlLiteralContentRecord bamlLiteralContent = + (BamlLiteralContentRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.LiteralContent); + bamlLiteralContent.Value = xamlLiteralContentNode.Content; + + WriteAndReleaseRecord(bamlLiteralContent, xamlLiteralContentNode); + } + + // Write an x:Key="value" where value has been resolved to a Type object + // at compile or parse time. This means less reflection at runtime. + internal void WriteDefAttributeKeyType(XamlDefAttributeKeyTypeNode xamlDefNode) + { + Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section"); + + // If we do not already have a type record for the type of this key, + // then add a new TypeInfo record to the map table. + short typeId; + if (!MapTable.GetTypeInfoId(BinaryWriter, + xamlDefNode.AssemblyName, + xamlDefNode.Value, + out typeId)) + { + typeId = MapTable.AddTypeInfoMap(BinaryWriter, + xamlDefNode.AssemblyName, + xamlDefNode.Value, + xamlDefNode.ValueType, + string.Empty, + string.Empty); + } + + + BamlDefAttributeKeyTypeRecord bamlDefRecord = BamlRecordManager.GetWriteRecord( + BamlRecordType.DefAttributeKeyType) + as BamlDefAttributeKeyTypeRecord; + + bamlDefRecord.TypeId = typeId; + ((IBamlDictionaryKey)bamlDefRecord).KeyObject = xamlDefNode.ValueType; + + // If we are currently parsing a deferable content section then store it + // in the keys collection. + if (_deferLoadingSupport && + _deferElementDepth == 2) + { + KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]); + + TransferOldSharedData(keyRecord.Record as IBamlDictionaryKey, bamlDefRecord as IBamlDictionaryKey); + keyRecord.Record = bamlDefRecord; + + keyRecord.LineNumber = xamlDefNode.LineNumber; + keyRecord.LinePosition = xamlDefNode.LinePosition; + return; + } + + if (_deferLoadingSupport && _deferElementDepth > 0) + { + _deferValues.Add(new ValueDeferRecord(bamlDefRecord, + xamlDefNode.LineNumber, + xamlDefNode.LinePosition)); + } + else + { + WriteBamlRecord(bamlDefRecord, xamlDefNode.LineNumber, + xamlDefNode.LinePosition); + + BamlRecordManager.ReleaseWriteRecord(bamlDefRecord); + } + } + + private void TransferOldSharedData(IBamlDictionaryKey oldRecord, IBamlDictionaryKey newRecord) + { + if ((oldRecord != null) && (newRecord != null)) + { + newRecord.Shared = oldRecord.Shared; + newRecord.SharedSet = oldRecord.SharedSet; + } + } + + private IBamlDictionaryKey FindBamlDictionaryKey(KeyDeferRecord record) + { + if (record != null) + { + if (record.RecordList != null) + { + for (int i = 0; i < record.RecordList.Count; i++) + { + ValueDeferRecord valueDeferRecord = (ValueDeferRecord)record.RecordList[i]; + IBamlDictionaryKey dictionaryKey = valueDeferRecord.Record as IBamlDictionaryKey; + if (dictionaryKey != null) + { + return dictionaryKey; + } + } + } + + return record.Record as IBamlDictionaryKey; + } + + return null; + } + + // Write a x:attribute="value" record. One typical use of this is + // to specify the key to use when inserting the current object into + // a Dictionary, but there can be other uses also + internal void WriteDefAttribute(XamlDefAttributeNode xamlDefNode) + { + + // If we are currently parsing a deferable content section, then check + // to see if we have a dictionary key value here. If so, then store it + // in the keys collection. + if (_deferLoadingSupport && + _deferElementDepth == 2 && + xamlDefNode.Name == XamlReaderHelper.DefinitionName) + { + Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section"); + + // Note that if we get to here the assumption is that the value of the Name + // attribute is *NOT* a MarkupExtension. A MarkupExtension would cause + // WriteKeyElementStart being called. + KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]); + BamlDefAttributeKeyStringRecord defKeyRecord = keyRecord.Record as BamlDefAttributeKeyStringRecord; + if (defKeyRecord == null) + { + defKeyRecord = + (BamlDefAttributeKeyStringRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DefAttributeKeyString); + TransferOldSharedData(keyRecord.Record as IBamlDictionaryKey, defKeyRecord as IBamlDictionaryKey); + keyRecord.Record = defKeyRecord; + } + + // Store the string value in the string table, since there will mostly be a + // [Static/Dynamic]Resource referring to it and we can combine the storage + // for both these string into a single StringInfoRecord. + short valueId; + if (!MapTable.GetStringInfoId(xamlDefNode.Value, + out valueId)) + { + valueId = MapTable.AddStringInfoMap(BinaryWriter, + xamlDefNode.Value); + } + + defKeyRecord.Value = xamlDefNode.Value; + defKeyRecord.ValueId = valueId; + + keyRecord.LineNumber = xamlDefNode.LineNumber; + keyRecord.LinePosition = xamlDefNode.LinePosition; + return; + } + else if (_deferLoadingSupport && + _deferElementDepth == 2 && + xamlDefNode.Name == XamlReaderHelper.DefinitionShared) + { + Debug.Assert(!InStaticResourceSection, "We do not support x:Shared within a StaticResource Section"); + + // NOTE: This does not properly handle MarkupExtensions.... + KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]); + + IBamlDictionaryKey defKeyRecord = FindBamlDictionaryKey(keyRecord); + if (defKeyRecord == null) + { + BamlDefAttributeKeyStringRecord defStringKeyRecord = + (BamlDefAttributeKeyStringRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DefAttributeKeyString); + keyRecord.Record = defStringKeyRecord; + defKeyRecord = (IBamlDictionaryKey)defStringKeyRecord; + } + + defKeyRecord.Shared = Boolean.Parse(xamlDefNode.Value); + defKeyRecord.SharedSet = true; + keyRecord.LineNumber = xamlDefNode.LineNumber; + keyRecord.LinePosition = xamlDefNode.LinePosition; + return; + } + + // Add definition attribute record. Store the attribute name in the string table, since + // the names are likely to be repeated. + short stringId; + if (!MapTable.GetStringInfoId(xamlDefNode.Name, + out stringId)) + { + stringId = MapTable.AddStringInfoMap(BinaryWriter, + xamlDefNode.Name); + } + + BamlDefAttributeRecord defRecord = + (BamlDefAttributeRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DefAttribute); + + defRecord.Value = xamlDefNode.Value; + defRecord.Name = xamlDefNode.Name; + defRecord.AttributeUsage = xamlDefNode.AttributeUsage; + defRecord.NameId = stringId; + + WriteAndReleaseRecord(defRecord, xamlDefNode); + } + + // Attributes used to specify WPF-specific parsing options + internal void WritePresentationOptionsAttribute(XamlPresentationOptionsAttributeNode xamlPresentationOptionsNode) + { + // Add definition attribute record. Store the attribute name in the string table, since + // the names are likely to be repeated. + short stringId; + if (!MapTable.GetStringInfoId(xamlPresentationOptionsNode.Name, + out stringId)) + { + stringId = MapTable.AddStringInfoMap(BinaryWriter, + xamlPresentationOptionsNode.Name); + } + + BamlPresentationOptionsAttributeRecord attributeRecord = + (BamlPresentationOptionsAttributeRecord) BamlRecordManager.GetWriteRecord( + BamlRecordType.PresentationOptionsAttribute); + + attributeRecord.Value = xamlPresentationOptionsNode.Value; + attributeRecord.Name = xamlPresentationOptionsNode.Name; + attributeRecord.NameId = stringId; + + WriteAndReleaseRecord(attributeRecord, xamlPresentationOptionsNode); + } + + + // The current element contains xmlns combinations we want scoped in case + // InnerXAML is done at runtime. + internal void WriteNamespacePrefix(XamlXmlnsPropertyNode xamlXmlnsPropertyNode) + { + BamlXmlnsPropertyRecord xmlnsRecord = + (BamlXmlnsPropertyRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.XmlnsProperty); + + xmlnsRecord.Prefix = xamlXmlnsPropertyNode.Prefix; + xmlnsRecord.XmlNamespace = xamlXmlnsPropertyNode.XmlNamespace; + +#if PBTCOMPILER + + // + // Get a list of Assemblies that contain XmlnsDefinitionAttribute for the + // specific XmlNamespace. Add the relevant assemblies into MapTable. + // + + if (xamlXmlnsPropertyNode.XmlNamespace.StartsWith(XamlReaderHelper.MappingProtocol, StringComparison.Ordinal) == false) + { + NamespaceMapEntry[] nsMapEntry = _xamlTypeMapper.GetNamespaceMapEntries(xamlXmlnsPropertyNode.XmlNamespace); + + if (nsMapEntry != null && nsMapEntry.Length > 0) + { + ArrayList asmList = new ArrayList(); + for (int i = 0; i < nsMapEntry.Length; i++) + { + string asmName = nsMapEntry[i].AssemblyName; + + if (!asmList.Contains(asmName)) + { + asmList.Add(asmName); + } + } + + if (asmList.Count > 0) + { + short[] assemblyIds = new short[asmList.Count]; + + for (int i = 0; i < asmList.Count; i++) + { + BamlAssemblyInfoRecord bamlAssemblyInfoRecord = MapTable.AddAssemblyMap(BinaryWriter, (string)asmList[i]); + + assemblyIds[i] = bamlAssemblyInfoRecord.AssemblyId; + } + + xmlnsRecord.AssemblyIds = assemblyIds; + } + } + } + +#endif + + + // NOTE: If we are defining a new namespace prefix in the value object's + // start record, AND using that prefix in x:Key, then we have a + // problem, since the x:Key keys are hoisted out before this + // record in the baml stream.... I don't have a solution for + // this yet, but this isn't an issue for theme files... + WriteAndReleaseRecord(xmlnsRecord, xamlXmlnsPropertyNode); + } + + // Write a xml to clr namespace mapping record + internal void WritePIMapping(XamlPIMappingNode xamlPIMappingNode) + { + BamlPIMappingRecord piMappingRecord = + (BamlPIMappingRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PIMapping); + + BamlAssemblyInfoRecord bamlAssemblyInfoRecord = MapTable.AddAssemblyMap(BinaryWriter, + xamlPIMappingNode.AssemblyName); + + piMappingRecord.XmlNamespace = xamlPIMappingNode.XmlNamespace; + piMappingRecord.ClrNamespace = xamlPIMappingNode.ClrNamespace; + piMappingRecord.AssemblyId = bamlAssemblyInfoRecord.AssemblyId; + + WriteBamlRecord(piMappingRecord, xamlPIMappingNode.LineNumber, + xamlPIMappingNode.LinePosition); + + BamlRecordManager.ReleaseWriteRecord(piMappingRecord); + } + + // Write the start of a complex property + internal void WritePropertyComplexStart(XamlPropertyComplexStartNode + xamlComplexPropertyNode) + { + // review same as property + flag, combine code + BamlPropertyComplexStartRecord bamlComplexProperty = + (BamlPropertyComplexStartRecord) BamlRecordManager.GetWriteRecord( + BamlRecordType.PropertyComplexStart); + + bamlComplexProperty.AttributeId = + MapTable.AddAttributeInfoMap(BinaryWriter, + xamlComplexPropertyNode.AssemblyName, + xamlComplexPropertyNode.TypeFullName, + xamlComplexPropertyNode.PropDeclaringType, + xamlComplexPropertyNode.PropName, + xamlComplexPropertyNode.PropValidType, + BamlAttributeUsage.Default); + + WriteAndReleaseRecord(bamlComplexProperty, xamlComplexPropertyNode); + } + + // Write the end of a complex property + internal void WritePropertyComplexEnd( + XamlPropertyComplexEndNode xamlPropertyComplexEnd) + { + BamlPropertyComplexEndRecord endPropertyRecord = + (BamlPropertyComplexEndRecord) BamlRecordManager.GetWriteRecord( + BamlRecordType.PropertyComplexEnd); + + WriteAndReleaseRecord(endPropertyRecord, xamlPropertyComplexEnd); + } + + // Write the start of a def attribute element used as the key in an + // IDictionary + public void WriteKeyElementStart( + XamlElementStartNode xamlKeyElementNode) + { + Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section"); + + // Don't allow a bind or resource reference in a key element, since this + // causes problems for resolution. Multi-pass or recursive key resolution + // would be needed to robustly support this feature. + if (!typeof(String).IsAssignableFrom(xamlKeyElementNode.ElementType) && + !KnownTypes.Types[(int)KnownElements.StaticExtension].IsAssignableFrom(xamlKeyElementNode.ElementType) && + !KnownTypes.Types[(int)KnownElements.TypeExtension].IsAssignableFrom(xamlKeyElementNode.ElementType) && + !KnownTypes.Types[(int)KnownElements.ResourceKey].IsAssignableFrom(xamlKeyElementNode.ElementType)) + { + XamlParser.ThrowException(SRID.ParserBadKey, + xamlKeyElementNode.TypeFullName, + xamlKeyElementNode.LineNumber, + xamlKeyElementNode.LinePosition); + } + + // initialize the element and add to the stack + BamlKeyElementStartRecord bamlElement = + (BamlKeyElementStartRecord) BamlRecordManager.GetWriteRecord( + BamlRecordType.KeyElementStart); + + // If we do not already have a type record for the type of this element, + // then add a new TypeInfo record to the map table. + short typeId; + if (!MapTable.GetTypeInfoId(BinaryWriter, + xamlKeyElementNode.AssemblyName, + xamlKeyElementNode.TypeFullName, + out typeId)) + { + string serializerAssemblyName = string.Empty; + if (xamlKeyElementNode.SerializerType != null) + { + serializerAssemblyName = xamlKeyElementNode.SerializerType.Assembly.FullName; + } + typeId = MapTable.AddTypeInfoMap(BinaryWriter, + xamlKeyElementNode.AssemblyName, + xamlKeyElementNode.TypeFullName, + xamlKeyElementNode.ElementType, + serializerAssemblyName, + xamlKeyElementNode.SerializerTypeFullName); + } + bamlElement.TypeId = typeId; + + // Check if the element we are about to write supports deferable content. + // If so, then we have to queue up all the baml records that are contained + // within this element and use this as a key (if this is a dictionary). + // At the end tag, the queued records will be written in an optimal order + // and offsets inserted to permit fast runtime indexing of content. + if (_deferLoadingSupport && _deferElementDepth == 2) + { + _deferElementDepth++; + _deferKeyCollecting = true; + + KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]); + keyRecord.RecordList = new ArrayList(5); + + Debug.Assert(keyRecord.RecordList.Count == 0, "Should have empty record list"); + keyRecord.RecordList.Add(new ValueDeferRecord(bamlElement, + xamlKeyElementNode.LineNumber, + xamlKeyElementNode.LinePosition)); + + if (keyRecord.Record != null) + { + TransferOldSharedData(keyRecord.Record as IBamlDictionaryKey, bamlElement as IBamlDictionaryKey); + keyRecord.Record = null; + } + + keyRecord.LineNumber = xamlKeyElementNode.LineNumber; + keyRecord.LinePosition = xamlKeyElementNode.LinePosition; + return; + } + else + { + WriteAndReleaseRecord(bamlElement, xamlKeyElementNode); + } + } + + // Write the end of a def attribute tree section used as the key + // in an IDictionary + internal void WriteKeyElementEnd( + XamlElementEndNode xamlKeyElementEnd) + { + Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section"); + + BamlKeyElementEndRecord endRecord = + (BamlKeyElementEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.KeyElementEnd); + + WriteAndReleaseRecord(endRecord, xamlKeyElementEnd); + + if (_deferLoadingSupport && _deferKeyCollecting) + { + _deferKeyCollecting = false; + _deferElementDepth--; + Debug.Assert(_deferElementDepth == 2); + } + } + +#if PBTCOMPILER + /// + /// Write the constructor parameter that has been resolved to a Type + /// + internal void WriteConstructorParameterType( + XamlConstructorParameterTypeNode xamlConstructorParameterTypeNode) + { + // If we do not already have a type record for the type of this property, + // then add a new TypeInfo record to the map table. + short typeId; + if (!MapTable.GetTypeInfoId(BinaryWriter, + xamlConstructorParameterTypeNode.ValueTypeAssemblyName, + xamlConstructorParameterTypeNode.ValueTypeFullName, + out typeId)) + { + typeId = MapTable.AddTypeInfoMap(BinaryWriter, + xamlConstructorParameterTypeNode.ValueTypeAssemblyName, + xamlConstructorParameterTypeNode.ValueTypeFullName, + xamlConstructorParameterTypeNode.ValueElementType, + string.Empty, + string.Empty); + } + + + BamlConstructorParameterTypeRecord bamlConstructor = BamlRecordManager.GetWriteRecord( + BamlRecordType.ConstructorParameterType) + as BamlConstructorParameterTypeRecord; + bamlConstructor.TypeId = typeId; + + WriteAndReleaseRecord(bamlConstructor, xamlConstructorParameterTypeNode); + } +#endif + + /// + /// Write the start of a constructor parameter section + /// + internal void WriteConstructorParametersStart( + XamlConstructorParametersStartNode xamlConstructorParametersStartNode) + { + // Create a new baml record + BamlConstructorParametersStartRecord startRecord = + (BamlConstructorParametersStartRecord) BamlRecordManager.GetWriteRecord( + BamlRecordType.ConstructorParametersStart); + + WriteAndReleaseRecord(startRecord, xamlConstructorParametersStartNode); + } + + /// + /// Write the end of a constructor parameter section + /// + internal void WriteConstructorParametersEnd( + XamlConstructorParametersEndNode xamlConstructorParametersEndNode) + { + // Create a new baml record + BamlConstructorParametersEndRecord startRecord = + (BamlConstructorParametersEndRecord) BamlRecordManager.GetWriteRecord( + BamlRecordType.ConstructorParametersEnd); + + WriteAndReleaseRecord(startRecord, xamlConstructorParametersEndNode); + } + + internal virtual void WriteContentProperty(XamlContentPropertyNode xamlContentPropertyNode) + { + BamlContentPropertyRecord bamlContentPropertyRecord = + (BamlContentPropertyRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.ContentProperty); + + bamlContentPropertyRecord.AttributeId = + MapTable.AddAttributeInfoMap(BinaryWriter, + xamlContentPropertyNode.AssemblyName, + xamlContentPropertyNode.TypeFullName, + xamlContentPropertyNode.PropDeclaringType, + xamlContentPropertyNode.PropName, + xamlContentPropertyNode.PropValidType, + BamlAttributeUsage.Default); + + WriteAndReleaseRecord(bamlContentPropertyRecord, xamlContentPropertyNode); + } + + // Write a property baml record. If the type of this property supports + // custom serialization or type conversion, then write out a special property + // record. Otherwise write out a 'normal' record, which will cause type + // converter resolution to happen at load time. + + + internal virtual void WriteProperty(XamlPropertyNode xamlProperty) + { + short attributeId = + MapTable.AddAttributeInfoMap(BinaryWriter, + xamlProperty.AssemblyName, + xamlProperty.TypeFullName, + xamlProperty.PropDeclaringType, + xamlProperty.PropName, + xamlProperty.PropValidType, + xamlProperty.AttributeUsage); + + if (xamlProperty.AssemblyName != string.Empty && xamlProperty.TypeFullName != string.Empty) + { + short converterOrSerializerTypeId; + Type converterOrSerializerType; + bool isCustomSerializer = MapTable.GetCustomSerializerOrConverter( + BinaryWriter, + xamlProperty.ValueDeclaringType, + xamlProperty.ValuePropertyType, + xamlProperty.ValuePropertyMember, + xamlProperty.ValuePropertyName, + out converterOrSerializerTypeId, + out converterOrSerializerType); + + if (converterOrSerializerType != null) + { + if (isCustomSerializer) + { + BamlPropertyCustomWriteInfoRecord bamlPropertyCustom = + (BamlPropertyCustomWriteInfoRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyCustom); + bamlPropertyCustom.AttributeId = attributeId; + bamlPropertyCustom.Value = xamlProperty.Value; + bamlPropertyCustom.ValueType = xamlProperty.ValuePropertyType; + bamlPropertyCustom.SerializerTypeId = converterOrSerializerTypeId; + bamlPropertyCustom.SerializerType = converterOrSerializerType; + bamlPropertyCustom.TypeContext = TypeConvertContext; + if (converterOrSerializerTypeId == (short)KnownElements.DependencyPropertyConverter) + { + // if ValueId\MemberName have alredy been resolved, just write it out. + if (xamlProperty.HasValueId) + { + bamlPropertyCustom.ValueId = xamlProperty.ValueId; + bamlPropertyCustom.ValueMemberName = xamlProperty.MemberName; + } + else + { + // else try to resolve the DP value of this property now + string dpName; + + // get the ownerType and name of the DP value + Type ownerType = _xamlTypeMapper.GetDependencyPropertyOwnerAndName(xamlProperty.Value, + ParserContext, + xamlProperty.DefaultTargetType, + out dpName); + short typeId; + + // get the known property Id or TypeId of the owner of the DP value + short propertyId = MapTable.GetAttributeOrTypeId(BinaryWriter, + ownerType, + dpName, + out typeId); + + // write it out as appropriate. + if (propertyId < 0) + { + bamlPropertyCustom.ValueId = propertyId; + bamlPropertyCustom.ValueMemberName = null; + } + else + { + bamlPropertyCustom.ValueId = typeId; + bamlPropertyCustom.ValueMemberName = dpName; + } + } + } + + WriteAndReleaseRecord(bamlPropertyCustom, xamlProperty); + } + else + { + BamlPropertyWithConverterRecord bamlPropertyWithConverter = (BamlPropertyWithConverterRecord)BamlRecordManager.GetWriteRecord( + BamlRecordType.PropertyWithConverter); + bamlPropertyWithConverter.AttributeId = attributeId; + bamlPropertyWithConverter.Value = xamlProperty.Value; + bamlPropertyWithConverter.ConverterTypeId = converterOrSerializerTypeId; + WriteAndReleaseRecord(bamlPropertyWithConverter, xamlProperty); + } + + return; + } + } + + BaseWriteProperty(xamlProperty); + } + + internal virtual void WritePropertyWithExtension(XamlPropertyWithExtensionNode xamlPropertyNode) + { + short valueId = 0; + short extensionTypeId = xamlPropertyNode.ExtensionTypeId; + bool isValueTypeExtension = false; + bool isValueStaticExtension = false; + Debug.Assert(extensionTypeId != (short)KnownElements.TypeExtension); + + // if the extension is a DynamicResourceExtension or a StaticResourceExtension + // dig in to see if its param is a simple extension or just a string. + if ((extensionTypeId == (short)KnownElements.DynamicResourceExtension) || + (extensionTypeId == (short)KnownElements.StaticResourceExtension)) + { + // if the value is a simple nested extension + if (xamlPropertyNode.IsValueNestedExtension) + { + // Yes, see if it is a TypeExtension or StaticExtension + if (xamlPropertyNode.IsValueTypeExtension) + { + // nested TypeExtension value + Type typeValue = _xamlTypeMapper.GetTypeFromBaseString(xamlPropertyNode.Value, + ParserContext, + true); + Debug.Assert(typeValue != null); + if (!MapTable.GetTypeInfoId(BinaryWriter, + typeValue.Assembly.FullName, + typeValue.FullName, + out valueId)) + { + valueId = MapTable.AddTypeInfoMap(BinaryWriter, + typeValue.Assembly.FullName, + typeValue.FullName, + typeValue, + string.Empty, + string.Empty); + } + + isValueTypeExtension = true; + } + else + { + // nested StaticExtension value + valueId = MapTable.GetStaticMemberId(BinaryWriter, + ParserContext, + (short)KnownElements.StaticExtension, + xamlPropertyNode.Value, + xamlPropertyNode.DefaultTargetType); + + isValueStaticExtension = true; + } + } + else + { + // No, it is a string value. + // Store the string value in the string table, since these records + // are already used as the key for a [Static/Dynamic]Resource. + if (!MapTable.GetStringInfoId(xamlPropertyNode.Value, out valueId)) + { + valueId = MapTable.AddStringInfoMap(BinaryWriter, xamlPropertyNode.Value); + } + } + } + else + { + // toplevel StaticExtension or TemplateBindingExtension value + valueId = MapTable.GetStaticMemberId(BinaryWriter, + ParserContext, + extensionTypeId, + xamlPropertyNode.Value, + xamlPropertyNode.DefaultTargetType); + } + + short attributeId = MapTable.AddAttributeInfoMap(BinaryWriter, + xamlPropertyNode.AssemblyName, + xamlPropertyNode.TypeFullName, + xamlPropertyNode.PropDeclaringType, + xamlPropertyNode.PropName, + xamlPropertyNode.PropValidType, + BamlAttributeUsage.Default); + + if (_deferLoadingSupport && _deferElementDepth > 0 && CollectingValues && + extensionTypeId == (short)KnownElements.StaticResourceExtension) + { + // If we are currently processing a StaticResourceExtension + // within a deferable content section then the information in + // the xamlPropertyNode is distributed among two separate + // BamlRecords viz. BamlOptimizedStaticResourceRecord which + // belongs in the header of the deferred section and a + // BamlPropertyWithStaticResourceIdRecord which is an inline + // place holder for the same. + + + // Create and populate the BamlOptimizedStaticResourceRecord that + // is stored in the header of the deferred section. + + BamlOptimizedStaticResourceRecord bamlOptimizedStaticResource = + (BamlOptimizedStaticResourceRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.OptimizedStaticResource); + + bamlOptimizedStaticResource.IsValueTypeExtension = isValueTypeExtension; + bamlOptimizedStaticResource.IsValueStaticExtension = isValueStaticExtension; + bamlOptimizedStaticResource.ValueId = valueId; + + _staticResourceRecordList = new List(1); + _staticResourceRecordList.Add(new ValueDeferRecord( + bamlOptimizedStaticResource, + xamlPropertyNode.LineNumber, + xamlPropertyNode.LinePosition)); + + // Add the current StaticResource to the list on the current key record + KeyDeferRecord keyDeferRecord = ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]); + keyDeferRecord.StaticResourceRecordList.Add(_staticResourceRecordList); + + // Write a PropertyWithStaticResourceId to the values collection + BamlPropertyWithStaticResourceIdRecord bamlPropertyWithStaticResourceId = + (BamlPropertyWithStaticResourceIdRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyWithStaticResourceId); + + bamlPropertyWithStaticResourceId.AttributeId = attributeId; + bamlPropertyWithStaticResourceId.StaticResourceId = (short)(keyDeferRecord.StaticResourceRecordList.Count-1); + + _deferValues.Add(new ValueDeferRecord( + bamlPropertyWithStaticResourceId, + xamlPropertyNode.LineNumber, + xamlPropertyNode.LinePosition)); + + _staticResourceRecordList = null; + } + else + { + BamlPropertyWithExtensionRecord bamlPropertyWithExtension = + (BamlPropertyWithExtensionRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyWithExtension); + + bamlPropertyWithExtension.AttributeId = attributeId; + bamlPropertyWithExtension.ExtensionTypeId = extensionTypeId; + bamlPropertyWithExtension.IsValueTypeExtension = isValueTypeExtension; + bamlPropertyWithExtension.IsValueStaticExtension = isValueStaticExtension; + bamlPropertyWithExtension.ValueId = valueId; + + WriteAndReleaseRecord(bamlPropertyWithExtension, xamlPropertyNode); + } + } + + // Write a property baml record for a property that is of type 'Type'. This means + // that the baml record contains a typeid reference for a type which was resolved at + // compile time. + internal virtual void WritePropertyWithType(XamlPropertyWithTypeNode xamlPropertyWithType) + { + short attributeId = + MapTable.AddAttributeInfoMap(BinaryWriter, + xamlPropertyWithType.AssemblyName, + xamlPropertyWithType.TypeFullName, + xamlPropertyWithType.PropDeclaringType, + xamlPropertyWithType.PropName, + xamlPropertyWithType.PropValidType, + BamlAttributeUsage.Default); + + // If we do not already have a type record for the type of this property, + // then add a new TypeInfo record to the map table. + short typeId; + if (!MapTable.GetTypeInfoId(BinaryWriter, + xamlPropertyWithType.ValueTypeAssemblyName, + xamlPropertyWithType.ValueTypeFullName, + out typeId)) + { + typeId = MapTable.AddTypeInfoMap(BinaryWriter, + xamlPropertyWithType.ValueTypeAssemblyName, + xamlPropertyWithType.ValueTypeFullName, + xamlPropertyWithType.ValueElementType, + xamlPropertyWithType.ValueSerializerTypeAssemblyName, + xamlPropertyWithType.ValueSerializerTypeFullName); + } + + BamlPropertyTypeReferenceRecord bamlProperty = BamlRecordManager.GetWriteRecord( + BamlRecordType.PropertyTypeReference) as BamlPropertyTypeReferenceRecord; + + bamlProperty.AttributeId = attributeId; + bamlProperty.TypeId = typeId; + + WriteAndReleaseRecord(bamlProperty, xamlPropertyWithType); + } + + // Write out property to BAML record, with the property value as a string. + // This is used if the value cannot stream itself out directly, or if we + // are creating a tree directly and not storing BAML to a file. + internal void BaseWriteProperty(XamlPropertyNode xamlProperty) + { + short attributeId = + MapTable.AddAttributeInfoMap(BinaryWriter, + xamlProperty.AssemblyName, + xamlProperty.TypeFullName, + xamlProperty.PropDeclaringType, + xamlProperty.PropName, + xamlProperty.PropValidType, + xamlProperty.AttributeUsage); + + BamlPropertyRecord bamlClrProperty = + (BamlPropertyRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.Property); + bamlClrProperty.AttributeId = attributeId; + bamlClrProperty.Value = xamlProperty.Value; + WriteAndReleaseRecord(bamlClrProperty, xamlProperty); + } + + internal void WriteClrEvent(XamlClrEventNode xamlClrEventNode) + { + // This should have been overridden by AC to catch the CLR event case before + // this point is reached. If not it means we have a designer which + // should have been given the pertinent information, so keep this as a placeholder, + // but don't do anything now. + } + + // Write the start of an array property + internal void WritePropertyArrayStart( + XamlPropertyArrayStartNode xamlPropertyArrayStartNode) + { + // initialize the element and add to the stack + BamlPropertyArrayStartRecord bamlPropertyArrayStart = + (BamlPropertyArrayStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyArrayStart); + + bamlPropertyArrayStart.AttributeId = + MapTable.AddAttributeInfoMap(BinaryWriter, + xamlPropertyArrayStartNode.AssemblyName, + xamlPropertyArrayStartNode.TypeFullName, + xamlPropertyArrayStartNode.PropDeclaringType, + xamlPropertyArrayStartNode.PropName, + null, + BamlAttributeUsage.Default); + + WriteAndReleaseRecord(bamlPropertyArrayStart, xamlPropertyArrayStartNode); + } + + // Write the end of an array property + internal virtual void WritePropertyArrayEnd( + XamlPropertyArrayEndNode xamlPropertyArrayEndNode) + { + // initialize the element and add to the stack + BamlPropertyArrayEndRecord bamlPropertyArrayEndRecord = + (BamlPropertyArrayEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyArrayEnd); + + WriteAndReleaseRecord(bamlPropertyArrayEndRecord, xamlPropertyArrayEndNode); + } + + // Write the start of a complex property that implements IList + internal void WritePropertyIListStart( + XamlPropertyIListStartNode xamlPropertyIListStart) + { + // initialize the element and add to the stack + BamlPropertyIListStartRecord bamlPropertyIListStart = + (BamlPropertyIListStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIListStart); + + bamlPropertyIListStart.AttributeId = + MapTable.AddAttributeInfoMap(BinaryWriter, + xamlPropertyIListStart.AssemblyName, + xamlPropertyIListStart.TypeFullName, + xamlPropertyIListStart.PropDeclaringType, + xamlPropertyIListStart.PropName, + null, + BamlAttributeUsage.Default); + + WriteAndReleaseRecord(bamlPropertyIListStart, xamlPropertyIListStart); + } + + // Write the end of a complex property that implements IList + internal virtual void WritePropertyIListEnd( + XamlPropertyIListEndNode xamlPropertyIListEndNode) + { + // initialize the element and add to the stack + BamlPropertyIListEndRecord bamlPropertyIListEndRecord = + (BamlPropertyIListEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIListEnd); + + WriteAndReleaseRecord(bamlPropertyIListEndRecord, xamlPropertyIListEndNode); + } + + // Write the start of a complex property that implements IDictionary + internal void WritePropertyIDictionaryStart( + XamlPropertyIDictionaryStartNode xamlPropertyIDictionaryStartNode) + { + // initialize the element and add to the stack + BamlPropertyIDictionaryStartRecord bamlPropertyIDictionaryStart = + (BamlPropertyIDictionaryStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIDictionaryStart); + + bamlPropertyIDictionaryStart.AttributeId = + MapTable.AddAttributeInfoMap(BinaryWriter, + xamlPropertyIDictionaryStartNode.AssemblyName, + xamlPropertyIDictionaryStartNode.TypeFullName, + xamlPropertyIDictionaryStartNode.PropDeclaringType, + xamlPropertyIDictionaryStartNode.PropName, + null, + BamlAttributeUsage.Default); + + WriteAndReleaseRecord(bamlPropertyIDictionaryStart, xamlPropertyIDictionaryStartNode); + } + + // Write the end of a complex property that implements IDictionary + internal virtual void WritePropertyIDictionaryEnd( + XamlPropertyIDictionaryEndNode xamlPropertyIDictionaryEndNode) + { + // initialize the element and add to the stack + BamlPropertyIDictionaryEndRecord bamlPropertyIDictionaryEndRecord = + (BamlPropertyIDictionaryEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIDictionaryEnd); + + WriteAndReleaseRecord(bamlPropertyIDictionaryEndRecord, xamlPropertyIDictionaryEndNode); + } + +#if !PBTCOMPILER + + // Write a routed event record + internal void WriteRoutedEvent(XamlRoutedEventNode xamlRoutedEventNode) + { + BamlRoutedEventRecord bamlEvent = + (BamlRoutedEventRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.RoutedEvent); + + BamlAttributeInfoRecord bamlAttributeInfoRecord; + MapTable.AddAttributeInfoMap(BinaryWriter, + xamlRoutedEventNode.AssemblyName, + xamlRoutedEventNode.TypeFullName, + null, + xamlRoutedEventNode.EventName, + null, + BamlAttributeUsage.Default, + out bamlAttributeInfoRecord); + + bamlAttributeInfoRecord.Event = xamlRoutedEventNode.Event; // set the table value + + bamlEvent.AttributeId = bamlAttributeInfoRecord.AttributeId; + bamlEvent.Value = xamlRoutedEventNode.Value; + + WriteAndReleaseRecord(bamlEvent, xamlRoutedEventNode); + } + +#endif + + // Write text content to baml + internal void WriteText(XamlTextNode xamlTextNode) + { + BamlTextRecord bamlText; + if (xamlTextNode.ConverterType == null) + { + if (!InStaticResourceSection && !InDynamicResourceSection) + { + bamlText = (BamlTextRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.Text); + } + else + { + bamlText = (BamlTextWithIdRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.TextWithId); + + // Store the string value in the string table, since these records + // are often used as the key for a [Static/Dynamic]Resource. + short valueId; + if (!MapTable.GetStringInfoId(xamlTextNode.Text, + out valueId)) + { + valueId = MapTable.AddStringInfoMap(BinaryWriter, + xamlTextNode.Text); + } + + ((BamlTextWithIdRecord)bamlText).ValueId = valueId; + } + } + else + { + bamlText = (BamlTextWithConverterRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.TextWithConverter); + + short typeId; + string converterAssemblyFullName = xamlTextNode.ConverterType.Assembly.FullName; + string converterTypeFullName = xamlTextNode.ConverterType.FullName; + + // If we do not already have a type record for the type of this converter, + // then add a new TypeInfo record to the map table. + if (!MapTable.GetTypeInfoId(BinaryWriter, converterAssemblyFullName, + converterTypeFullName, + out typeId)) + { + typeId = MapTable.AddTypeInfoMap(BinaryWriter, + converterAssemblyFullName, + converterTypeFullName, + xamlTextNode.ConverterType, + string.Empty, + string.Empty); + } + ((BamlTextWithConverterRecord)bamlText).ConverterTypeId = typeId; + } + + bamlText.Value = xamlTextNode.Text; + + // up the parent node count, wait to update until endElement. + + // add text to the Tree. + WriteAndReleaseRecord(bamlText, xamlTextNode); + } + + // Helper to write out the baml record, with line numbers obtained from + // the associated xaml node. + private void WriteAndReleaseRecord( + BamlRecord bamlRecord, + XamlNode xamlNode) + { + int lineNumber = xamlNode != null ? xamlNode.LineNumber : 0; + int linePosition = xamlNode != null ? xamlNode.LinePosition : 0; + + // If we are currently parsing a deferable content section, then queue + // up the records for later writing + if (_deferLoadingSupport && _deferElementDepth > 0) + { + if (InStaticResourceSection) + { + // Gather all the BamlRecords within the StaticResource section + _staticResourceRecordList.Add(new ValueDeferRecord(bamlRecord, lineNumber, linePosition)); + } + else + { + ValueDeferRecord deferRec = new ValueDeferRecord(bamlRecord, + lineNumber, + linePosition); + if (_deferEndOfStartReached) + { + // If we are starting/ending a complex property, and we are at the same + // depth as the defered element, then track a mode so that we write to + // the _deferElement array instead of the key/value arrays. + if(_deferElementDepth == 1 && xamlNode is XamlPropertyComplexStartNode) + { + _deferComplexPropertyDepth++; + } + + if(_deferComplexPropertyDepth > 0) + { + _deferElement.Add(deferRec); + + if(_deferElementDepth == 1 && xamlNode is XamlPropertyComplexEndNode) + { + _deferComplexPropertyDepth--; + } + } + else if (_deferKeyCollecting) + { + ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]).RecordList.Add(deferRec); + } + else + { + _deferValues.Add(deferRec); + } + } + else + { + _deferElement.Add(deferRec); + } + } + } + else + { + WriteBamlRecord(bamlRecord, + lineNumber, + linePosition); + + BamlRecordManager.ReleaseWriteRecord(bamlRecord); + } + } + + // We've reached the end tag of a deferable content section. Write out + // the following information, in order: + // 1) Start record for deferable content element, and any properties + // that are set on that element + // 2) All keys for keyed content (if this is a dictionary) + // 3) All value sections. If this is a dictionary, then go back + // and update the positions in the key records to point to the value + // 4) End record for the deferable content element. + private void WriteDeferableContent(XamlElementEndNode xamlNode) + { + // 1) Write Start record and all property information for the start tag + for (int h = 0; h<_deferElement.Count; h++) + { + ValueDeferRecord deferRecord = (ValueDeferRecord)_deferElement[h]; + WriteBamlRecord(deferRecord.Record, + deferRecord.LineNumber, + deferRecord.LinePosition); + } + + // Find where the deferable content starts, which is after the end + // of the start tag for the deferable element, and insert a deferable + // block start record here. + BamlDeferableContentStartRecord bamlDeferableContentStart = + (BamlDeferableContentStartRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.DeferableContentStart); + WriteBamlRecord(bamlDeferableContentStart, + xamlNode.LineNumber, + xamlNode.LinePosition); + Int64 endOfStart = BinaryWriter.Seek(0, SeekOrigin.Current); + + // 2) Write key collection + for (int i = 0; i<_deferKeys.Count; i++) + { + KeyDeferRecord keyRecord = (KeyDeferRecord)_deferKeys[i]; + // If we don't have a Record stored here, then we didn't find a key + // for this dictionary entry. In that case, throw an exception. + // Otherwise loop through the records if there is a collection, or + // write out the single record if it is a simple key. + // NOTE: Make sure to check the List before the individual record because + // the list of records takes precedence over a single record. It is + // possible for a single record to be stored first, and then later a + // Key Element in complex property is found which overrides the + // original key value. + if (keyRecord.RecordList != null && + keyRecord.RecordList.Count > 0) + { + for (int j = 0; j < keyRecord.RecordList.Count; j++) + { + ValueDeferRecord keyValueRec = (ValueDeferRecord)keyRecord.RecordList[j]; + WriteBamlRecord(keyValueRec.Record, + keyValueRec.LineNumber, + keyValueRec.LinePosition); + } + } + else + { + if (keyRecord.Record == null) + { + XamlParser.ThrowException(SRID.ParserNoDictionaryKey, + keyRecord.LineNumber, + keyRecord.LinePosition); + } + else + { + WriteBamlRecord(keyRecord.Record, + keyRecord.LineNumber, + keyRecord.LinePosition); + } + } + + // Write out the BamlRecords for all the StaticResources belonging to this key + List> staticResourceRecordList = keyRecord.StaticResourceRecordList; + if (staticResourceRecordList.Count > 0) + { + // Iterate through each one of the StaticResources in the list + for (int j=0; j srRecords = staticResourceRecordList[j]; + for (int k=0; k 0) + { + ValueDeferRecord elementDeferRec = (ValueDeferRecord)(deferKeyRecord.RecordList[0]); + keyRecord = (IBamlDictionaryKey)elementDeferRec.Record; + } + else + { + keyRecord = (IBamlDictionaryKey)deferKeyRecord.Record; + } + Debug.Assert(keyRecord != null, "Unknown key record type in defer load dictionary"); + if (keyRecord != null) + { + keyRecord.UpdateValuePosition((Int32)(position-endOfKeys), BinaryWriter); + } + } + WriteBamlRecord(deferRecord.Record, + deferRecord.LineNumber, + deferRecord.LinePosition); + } + + Debug.Assert(keyIndex == _deferKeys.Count, + "Number of keys and values don't match"); + + // 4) Write end record and update the content size in start record + Int64 startOfEnd = BinaryWriter.Seek(0, SeekOrigin.Current); + bamlDeferableContentStart.UpdateContentSize((Int32)(startOfEnd - endOfStart), + BinaryWriter); + + BamlElementEndRecord bamlElementEnd = + (BamlElementEndRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.ElementEnd); + WriteBamlRecord(bamlElementEnd, + xamlNode.LineNumber, + xamlNode.LinePosition); + + BamlRecordManager.ReleaseWriteRecord(bamlElementEnd); + + } + + /// + /// This method is responsible for processing and writing out the StaticResource + /// records that we have been gathering this far to DeferredContent + /// + private void WriteStaticResource() + { + Debug.Assert(_deferElementDepth > 0 && CollectingValues, + "Special processing of StaticResources happens only when collecting values within a deferred section"); + + // Replace the first record in the list with the StaticResource start record + ValueDeferRecord valueDeferRecord = _staticResourceRecordList[0]; + int lineNumber = valueDeferRecord.LineNumber; + int linePosition = valueDeferRecord.LinePosition; + + Debug.Assert(valueDeferRecord.Record != null && + valueDeferRecord.Record.RecordType == BamlRecordType.ElementStart && + ((BamlElementStartRecord)valueDeferRecord.Record).TypeId == BamlMapTable.GetKnownTypeIdFromType(KnownTypes.Types[(int)KnownElements.StaticResourceExtension]), + "The first record in the list must be the ElementStart record for the StaticResourceExtension tag"); + + BamlStaticResourceStartRecord bamlStaticResourceStart = + (BamlStaticResourceStartRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.StaticResourceStart); + bamlStaticResourceStart.TypeId = ((BamlElementStartRecord)valueDeferRecord.Record).TypeId; + valueDeferRecord.Record = bamlStaticResourceStart; + + // Replace last record in the list with the StaticResource end record + valueDeferRecord = _staticResourceRecordList[_staticResourceRecordList.Count-1]; + Debug.Assert(valueDeferRecord.Record != null && valueDeferRecord.Record.RecordType == BamlRecordType.ElementEnd, + "The last record in the list must be the ElementEnd record for the StaticResourceExtension tag"); + + BamlStaticResourceEndRecord bamlStaticResourceEnd = + (BamlStaticResourceEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.StaticResourceEnd); + valueDeferRecord.Record = bamlStaticResourceEnd; + + // Add the current StaticResource to the list on the current key record + KeyDeferRecord keyDeferRecord = ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]); + keyDeferRecord.StaticResourceRecordList.Add(_staticResourceRecordList); + + // Write a StaticResourceId to the values collection + BamlStaticResourceIdRecord bamlStaticResourceId = + (BamlStaticResourceIdRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.StaticResourceId); + bamlStaticResourceId.StaticResourceId = (short)(keyDeferRecord.StaticResourceRecordList.Count-1); + + _deferValues.Add(new ValueDeferRecord(bamlStaticResourceId, lineNumber, linePosition)); + } + +#endregion Record Writing + +#endregion Methods + +#region Private Classes + + // DeferRecord contains information about a BamlRecord or list of + // BamlRecords that has not been written to the baml stream yet + // because we are processing a deferable content element. + private class DeferRecord + { + internal DeferRecord ( + int lineNumber, + int linePosition) + { + _lineNumber = lineNumber; + _linePosition = linePosition; + } + + internal int LineNumber + { + get { return _lineNumber; } + set { _lineNumber = value; } + } + + internal int LinePosition + { + get { return _linePosition; } + set { _linePosition = value; } + } + + private int _lineNumber; + private int _linePosition; + + } + + private class ValueDeferRecord : DeferRecord + { + internal ValueDeferRecord ( + BamlRecord record, + int lineNumber, + int linePosition) : base(lineNumber, linePosition) + { + _record = record; + _updateOffset = false; + } + + internal BamlRecord Record + { + get { return _record; } + set { _record = value; } + } + + internal bool UpdateOffset + { + get { return _updateOffset; } + set { _updateOffset = value; } + } + + private bool _updateOffset; + private BamlRecord _record; + } + + private class KeyDeferRecord : DeferRecord + { + internal KeyDeferRecord ( + int lineNumber, + int linePosition) : base(lineNumber, linePosition) + { + } + + internal BamlRecord Record + { + get { return _record; } + set { _record = value; } + } + + internal ArrayList RecordList + { + get { return _recordList; } + set { _recordList = value; } + } + + internal List> StaticResourceRecordList + { + get + { + if (_staticResourceRecordList == null) + { + _staticResourceRecordList = new List>(1); + } + + return _staticResourceRecordList; + } + } + + private BamlRecord _record; + private ArrayList _recordList; + private List> _staticResourceRecordList; + } + +#endregion Private Classes + +#region Properties + +#if PBTCOMPILER + + internal bool InDeferLoadedSection + { + get { return _deferElementDepth > 0; } + } + +#endif + + /// + /// returns stream that BamlRecordWriter is writing Baml records to + /// + /// + public Stream BamlStream + { + get { return _bamlStream; } + } + + internal BamlBinaryWriter BinaryWriter + { + get { return _bamlBinaryWriter; } + } + + internal BamlMapTable MapTable + { + get { return _bamlMapTable ; } + } + + internal ParserContext ParserContext + { + get { return _parserContext ; } + } + + internal virtual BamlRecordManager BamlRecordManager + { + get { return _bamlRecordManager; } + } + + BamlDocumentStartRecord DocumentStartRecord + { + get { return _startDocumentRecord; } + set { _startDocumentRecord = value; } + } + + private bool CollectingValues + { + get { return _deferEndOfStartReached && !_deferKeyCollecting && _deferComplexPropertyDepth <= 0; } + } + + // ITypeDescriptorContext used when running type convertors on serializable + // DP values. + ITypeDescriptorContext TypeConvertContext + { + get + { +#if !PBTCOMPILER // Don't run type converters for compilation + if (null == _typeConvertContext) + { + _typeConvertContext = new TypeConvertContext(_parserContext); + } + + return _typeConvertContext; +#else + _typeConvertContext = null; + return _typeConvertContext; +#endif + } + } + + /// + /// Are we currently processing a StaticResource section? + /// + private bool InStaticResourceSection + { + get { return _staticResourceElementDepth > 0; } + } + + /// + /// Are we currently processing a DynamicResource section? + /// + private bool InDynamicResourceSection + { + get { return _dynamicResourceElementDepth > 0; } + } + +#endregion Properties + + +#region Data + XamlTypeMapper _xamlTypeMapper; + Stream _bamlStream; + BamlBinaryWriter _bamlBinaryWriter; + + BamlDocumentStartRecord _startDocumentRecord; + ParserContext _parserContext; + BamlMapTable _bamlMapTable; + BamlRecordManager _bamlRecordManager; + ITypeDescriptorContext _typeConvertContext; + + bool _deferLoadingSupport; // true if defer load of ResourceDictionary + // is enabled. + int _deferElementDepth = 0; + + // True if we are processing a defered content element and we have reached the end + // end of the start record for the element. At this point all properties for that + // element have been collected. + bool _deferEndOfStartReached = false; + + // How deep are we in a complex property of a defered type? + int _deferComplexPropertyDepth = 0; + + // True if we are processing a defered content block and we are collecting all the + // baml records that make up a single key for the keys section of defered content + bool _deferKeyCollecting = false; + + // List of keys for a defered content section. Each item is a KeyDeferRecord + ArrayList _deferKeys; + + // List of values for a defered content section. Each item is a ValueDeferRecord + ArrayList _deferValues; // Values in the dictionary + + // List of properties set on an element that is the root of a defered content + // section. Each item is a ValueDeferRecord. + ArrayList _deferElement; // Start tag and properties + // of deferable content + + short _staticResourceElementDepth = 0; // Used to identify the StaticResource EndRecord + + short _dynamicResourceElementDepth = 0; // Used to identify the DynamicResource EndRecord + + List _staticResourceRecordList; // List of BamlRecords between the start and end of a StaticResource definition (both ends inclusive). + + bool _debugBamlStream; + int _lineNumber; + int _linePosition; + BamlLineAndPositionRecord _bamlLineAndPositionRecord; + BamlLinePositionRecord _bamlLinePositionRecord; + +#endregion Data + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecords.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecords.cs new file mode 100644 index 00000000000..03a0f4ca5d8 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecords.cs @@ -0,0 +1,5540 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/***************************************************************************\ +* +* Purpose: Contains implementation for specific BamlRecords +* +\***************************************************************************/ +using System; +using System.Xml; +using System.IO; +using System.Text; +using System.Collections.Generic; +using System.Collections; +using System.Globalization; +using System.ComponentModel; +using System.Security.Permissions; +using System.Diagnostics; +using System.Reflection; +using System.Collections.Specialized; +using MS.Internal.IO.Packaging.CompoundFile; + +#if !PBTCOMPILER +using System.Windows; +using System.Windows.Media; +using System.Windows.Threading; + +using MS.Internal.PresentationFramework; // SafeSecurityHelper +#endif + +using System.Runtime.InteropServices; +using MS.Utility; +using MS.Internal; + +// Disabling 1634 and 1691: +// In order to avoid generating warnings about unknown message numbers and +// unknown pragmas when compiling C# source code with the C# compiler, +// you need to disable warnings 1634 and 1691. (Presharp Documentation) +#pragma warning disable 1634, 1691 + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + // Types of records. Note that this is a superset of XamlNodeTypes + internal enum BamlRecordType : byte + { + /// + /// Unknown Node + /// + // !!BamlRecordManager class relies on Unknown = 0 for initialization + Unknown = 0, + + /// + /// Start Document Node + /// + DocumentStart, // 1 + + /// + /// End Document Node + /// + DocumentEnd, // 2 + + /// + /// Start Element Node, which may be a CLR object or a DependencyObject + /// + ElementStart, // 3 + + /// + /// End Element Node + /// + ElementEnd, // 4 + + /// + /// Property Node, which may be a CLR property or a DependencyProperty + /// + Property, // 5 + + /// + /// Binary serialization of a property + /// + PropertyCustom, // 6 + + /// + /// Complex Property Node + /// + PropertyComplexStart, // 7 + + /// + /// End Complex Property Node + /// + PropertyComplexEnd, // 8 + + /// + /// Start Array Property Node + /// + PropertyArrayStart, // 9 + + /// + /// End Array Property Node + /// + PropertyArrayEnd, // 10 + + /// + /// Star IList Property Node + /// + PropertyIListStart, // 11 + + /// + /// End PropertyIListStart Node + /// + PropertyIListEnd, // 12 + + /// + /// Start IDictionary Property Node + /// + PropertyIDictionaryStart, // 13 + + /// + /// End IDictionary Property Node + /// + PropertyIDictionaryEnd, // 14 + + /// + /// LiteralContent Node + /// + LiteralContent, // 15 + + /// + /// Text Node + /// + Text, // 16 + + /// + /// Text that has an associated custom typeconverter + /// + TextWithConverter, // 17 + + /// + /// RoutedEventNode + /// + RoutedEvent, // 18 + + /// + /// ClrEvent Node + /// + ClrEvent, // 19 + + /// + /// XmlnsProperty Node + /// + XmlnsProperty, // 20 + + /// + /// XmlAttribute Node + /// + XmlAttribute, // 21 + + /// + /// Processing Intstruction Node + /// + ProcessingInstruction, // 22 + + /// + /// Comment Node + /// + Comment, // 23 + + /// + /// DefTag Node + /// + DefTag, // 24 + + /// + /// x:name="value" attribute. One typical use of this + /// attribute is to define a key to use when inserting an item into an IDictionary + /// + DefAttribute, // 25 + + /// + /// EndAttributes Node + /// + EndAttributes, // 26 + + /// + /// PI xml - clr namespace mapping + /// + PIMapping, // 27 + + /// + /// Assembly information + /// + AssemblyInfo, // 28 + + /// + /// Type information + /// + TypeInfo, // 29 + + /// + /// Type information for a Type that has an associated custom serializer + /// + TypeSerializerInfo, // 30 + + /// + /// Attribute (eg - properties and events) information + /// + AttributeInfo, // 31 + + /// + /// Resource information + /// + StringInfo, // 32 + + /// + /// Property Resource Reference + /// + PropertyStringReference, // 33 + + /// + /// Record for setting a property to a Type reference. This is used for + /// properties that are of type "Type" + /// + PropertyTypeReference, // 34 + + /// + /// Property that has a simple MarkupExtension value. + /// + PropertyWithExtension, // 35 + + /// + /// Property that has an associated custom typeconverter + /// + PropertyWithConverter, // 36 + + /// + /// Start a deferable content block + /// + DeferableContentStart, // 37 + + /// + /// x:name="value" attribute when used within a defer load + /// dictionary. These keys are hoisted to the front of the dictionary when + /// written to baml. + /// + DefAttributeKeyString, // 38 + + /// + /// Implied key that is a Type attribute when used within a defer load + /// dictionary. These keys are hoisted to the front of the dictionary when + /// written to baml. + /// + DefAttributeKeyType, // 39 + + /// + /// This marks the start of an element tree that is used as the key in + /// an IDictionary. + /// + KeyElementStart, // 40 + + + /// + /// This marks the end of an element tree that is used as the key in + /// an IDictionary. + /// + KeyElementEnd, // 41 + + /// + /// Record marks the start of a section containing constructor parameters + /// + ConstructorParametersStart, // 42 + + /// + /// Record marks the end of a section containing constructor parameters + /// + ConstructorParametersEnd, // 43 + + /// + /// Constructor parameter that has been resolved to a Type. + /// + ConstructorParameterType, // 44 + + /// + /// Record that has info about which event or id to connect to in an object tree. + /// + ConnectionId, // 45 + + /// + /// Record that set the conntent property context for the element + /// + ContentProperty, // 46 + + /// + /// ElementStartRecord that also carries an element name. + /// + NamedElementStart, // 47 + + /// + /// Start of StaticResourceExtension within the header of a deferred section. + /// + StaticResourceStart, // 48 + + /// + /// End of a StaticResourceExtension within the header of a deferred section. + /// + StaticResourceEnd, // 49 + + /// + /// BamlRecord that carries an identifier for a StaticResourceExtension + /// within the header of a deferred section. + /// + StaticResourceId, // 50 + + /// + /// This is a TextRecord that holds an Id for the String value it represents. + /// + TextWithId, // 51 + + /// + /// PresentationOptions:Freeze="value" attribute. Used for ignorable + /// WPF-specific parsing options + /// + PresentationOptionsAttribute, // 52 + + /// + /// Debugging information record that holds the source XAML linenumber. + /// + LineNumberAndPosition, // 53 + + /// + /// Debugging information record that holds the source XAML line position. + /// + LinePosition, // 54 + + /// + /// OptimizedStaticResourceExtension within the header of a deferred section. + /// + OptimizedStaticResource, // 55 + + /// + /// BamlPropertyRecord that carries an identifier for a StaticResourceExtension + /// within the header of a deferred section. + /// + PropertyWithStaticResourceId, // 56 + + /// + /// Placeholder to mark last record + /// + LastRecordType + } + + /// + /// Some attributes have special usages or cause additional actions when they + /// are set on an element. This can be have some other effects + /// such as setting the xml:lang or xml:space values in the parser context. + /// The PropertyUsage describes addition effects or usage for this property. + /// + internal enum BamlAttributeUsage : short + { + /// A regular property that has no other use + Default = 0, + + /// A property that has xml:lang information + XmlLang, + + /// A property that has xml:space information + XmlSpace, + + /// A property that has the RuntimeIdProperty information + RuntimeName, + } + + // This class handles allocation, read and write management of baml records. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlRecordManager + { +#if !PBTCOMPILER + // Genericaly load and create the proper class. + // This method assumes the seek pointer has already moved passed the recordType + // field and is at the RecordSize or record contents (depending on record). + // This method is used so the caller can first read the type of record, and expects + // to get back the entire record, or nothing (for async support). + internal BamlRecord ReadNextRecord( + BinaryReader bamlBinaryReader, + long bytesAvailable, + BamlRecordType recordType) + { + BamlRecord bamlRecord; // = null + + // Create the proper BamlRecord based on the recordType. The assembly, + // type and attribute records are created every time, since they are + // used by the BamlMapTable. The other records are re-used, so they + // are created once and cached. + switch(recordType) + { + case BamlRecordType.AssemblyInfo: + bamlRecord = new BamlAssemblyInfoRecord(); + break; + case BamlRecordType.TypeInfo: + bamlRecord = new BamlTypeInfoRecord(); + break; + case BamlRecordType.TypeSerializerInfo: + bamlRecord = new BamlTypeInfoWithSerializerRecord(); + break; + case BamlRecordType.AttributeInfo: + bamlRecord = new BamlAttributeInfoRecord(); + break; + case BamlRecordType.StringInfo: + bamlRecord = new BamlStringInfoRecord(); + break; + case BamlRecordType.DefAttributeKeyString: + bamlRecord = new BamlDefAttributeKeyStringRecord(); + break; + case BamlRecordType.DefAttributeKeyType: + bamlRecord = new BamlDefAttributeKeyTypeRecord(); + break; + case BamlRecordType.KeyElementStart: + bamlRecord = new BamlKeyElementStartRecord(); + break; + + default: + + // Get the current record from the cache. If there's nothing there yet, + // or if what is there is pinned, then create one. Note that records in the + // read cache are implicitly recycled, and records in the write cache are explicitly + // recycled (i.e., there's a ReleaseWriteRecord, but no ReleaseReadRecord). + + bamlRecord = _readCache[(int)recordType]; + if (null == bamlRecord || bamlRecord.IsPinned ) + { + bamlRecord = _readCache[(int)recordType] = AllocateRecord(recordType); + } + + break; + } + + bamlRecord.Next = null; + + if (null != bamlRecord) + { + // If LoadRecordSize indicates it can determine the record size + // and has determined that there is enough content to load the + // entire record, then continue. + if (bamlRecord.LoadRecordSize(bamlBinaryReader, bytesAvailable) && + bytesAvailable >= bamlRecord.RecordSize) + { + bamlRecord.LoadRecordData(bamlBinaryReader); + } + else + { + bamlRecord = null; + } + } + + return bamlRecord; + } + + /// + /// Return the object if it should be treated as IAddChild, otherwise return null + /// + static internal IAddChild AsIAddChild(object obj) + { + IAddChild iac = obj as IAddChildInternal; + return iac; + } +#endif + + /// + /// True if type should be treated as IAddChild + /// + static internal bool TreatAsIAddChild(Type parentObjectType) + { + return (KnownTypes.Types[(int)KnownElements.IAddChildInternal].IsAssignableFrom( parentObjectType )); + } + + static internal BamlRecordType GetPropertyStartRecordType(Type propertyType, bool propertyCanWrite) + { + BamlRecordType recordType; + if (propertyType.IsArray) + { + recordType = BamlRecordType.PropertyArrayStart; + } +#if PBTCOMPILER + else if (ReflectionHelper.GetMscorlibType(typeof(IDictionary)).IsAssignableFrom(propertyType)) + { + recordType = BamlRecordType.PropertyIDictionaryStart; + } + else if (ReflectionHelper.GetMscorlibType(typeof(IList)).IsAssignableFrom(propertyType) || + BamlRecordManager.TreatAsIAddChild(propertyType) || + (ReflectionHelper.GetMscorlibType(typeof(IEnumerable)).IsAssignableFrom(propertyType) && !propertyCanWrite)) +#else + else if (typeof(IDictionary).IsAssignableFrom(propertyType)) + { + recordType = BamlRecordType.PropertyIDictionaryStart; + } + else if ((typeof(IList).IsAssignableFrom(propertyType) || + BamlRecordManager.TreatAsIAddChild(propertyType) || + (typeof(IEnumerable).IsAssignableFrom(propertyType) && !propertyCanWrite))) +#endif + { + // we're a list if: + // 1) the property type is an IList. + // 2) the property type is an IAddChild (internal). + // 3) the property type is an IEnumerable and read-only and the parent is an IAddChild (internal). + // for the third case, we can't check the parent until run-time. + recordType = BamlRecordType.PropertyIListStart; + } + else + { + recordType = BamlRecordType.PropertyComplexStart; + } + + return recordType; + } + +#if !PBTCOMPILER + internal BamlRecord CloneRecord(BamlRecord record) + { + BamlRecord newRecord; + + switch (record.RecordType) + { + case BamlRecordType.ElementStart: + if (record is BamlNamedElementStartRecord) + { + newRecord= new BamlNamedElementStartRecord(); + } + else + { + newRecord = new BamlElementStartRecord(); + } + break; + + case BamlRecordType.PropertyCustom: + if (record is BamlPropertyCustomWriteInfoRecord) + { + newRecord = new BamlPropertyCustomWriteInfoRecord(); + } + else + { + newRecord = new BamlPropertyCustomRecord(); + } + break; + + default: + newRecord = AllocateRecord(record.RecordType); + break; + } + + record.Copy(newRecord); + + return newRecord; + } +#endif + + // Helper function to create a BamlRecord from a BamlRecordType + private BamlRecord AllocateWriteRecord(BamlRecordType recordType) + { + BamlRecord record; + + switch (recordType) + { + case BamlRecordType.PropertyCustom: + record = new BamlPropertyCustomWriteInfoRecord(); + break; + + default: + record = AllocateRecord(recordType); + break; + } + + return record; + } + + // Helper function to create a BamlRecord from a BamlRecordType + private BamlRecord AllocateRecord(BamlRecordType recordType) + { + BamlRecord record; + + switch(recordType) + { + case BamlRecordType.DocumentStart: + record = new BamlDocumentStartRecord(); + break; + case BamlRecordType.DocumentEnd: + record = new BamlDocumentEndRecord(); + break; + case BamlRecordType.ConnectionId: + record = new BamlConnectionIdRecord(); + break; + case BamlRecordType.ElementStart: + record = new BamlElementStartRecord(); + break; + case BamlRecordType.ElementEnd: + record = new BamlElementEndRecord(); + break; + case BamlRecordType.DeferableContentStart: + record = new BamlDeferableContentStartRecord(); + break; + case BamlRecordType.DefAttributeKeyString: + record = new BamlDefAttributeKeyStringRecord(); + break; + case BamlRecordType.DefAttributeKeyType: + record = new BamlDefAttributeKeyTypeRecord(); + break; + case BamlRecordType.LiteralContent: + record = new BamlLiteralContentRecord(); + break; + case BamlRecordType.Property: + record = new BamlPropertyRecord(); + break; + case BamlRecordType.PropertyWithConverter: + record = new BamlPropertyWithConverterRecord(); + break; + case BamlRecordType.PropertyStringReference: + record = new BamlPropertyStringReferenceRecord(); + break; + case BamlRecordType.PropertyTypeReference: + record = new BamlPropertyTypeReferenceRecord(); + break; + case BamlRecordType.PropertyWithExtension: + record = new BamlPropertyWithExtensionRecord(); + break; + case BamlRecordType.PropertyCustom: + record = new BamlPropertyCustomRecord(); + break; + case BamlRecordType.PropertyComplexStart: + record = new BamlPropertyComplexStartRecord(); + break; + case BamlRecordType.PropertyComplexEnd: + record = new BamlPropertyComplexEndRecord(); + break; + case BamlRecordType.RoutedEvent: + record = new BamlRoutedEventRecord(); + break; + case BamlRecordType.PropertyArrayStart: + record = new BamlPropertyArrayStartRecord(); + break; + case BamlRecordType.PropertyArrayEnd: + record = new BamlPropertyArrayEndRecord(); + break; + case BamlRecordType.PropertyIListStart: + record = new BamlPropertyIListStartRecord(); + break; + case BamlRecordType.PropertyIListEnd: + record = new BamlPropertyIListEndRecord(); + break; + case BamlRecordType.PropertyIDictionaryStart: + record = new BamlPropertyIDictionaryStartRecord(); + break; + case BamlRecordType.PropertyIDictionaryEnd: + record = new BamlPropertyIDictionaryEndRecord(); + break; + case BamlRecordType.Text: + record = new BamlTextRecord(); + break; + case BamlRecordType.TextWithConverter: + record = new BamlTextWithConverterRecord(); + break; + case BamlRecordType.TextWithId: + record = new BamlTextWithIdRecord(); + break; + case BamlRecordType.XmlnsProperty: + record = new BamlXmlnsPropertyRecord(); + break; + case BamlRecordType.PIMapping: + record = new BamlPIMappingRecord(); + break; + case BamlRecordType.DefAttribute: + record = new BamlDefAttributeRecord(); + break; + case BamlRecordType.PresentationOptionsAttribute: + record = new BamlPresentationOptionsAttributeRecord(); + break; + case BamlRecordType.KeyElementStart: + record = new BamlKeyElementStartRecord(); + break; + case BamlRecordType.KeyElementEnd: + record = new BamlKeyElementEndRecord(); + break; + case BamlRecordType.ConstructorParametersStart: + record = new BamlConstructorParametersStartRecord(); + break; + case BamlRecordType.ConstructorParametersEnd: + record = new BamlConstructorParametersEndRecord(); + break; + case BamlRecordType.ConstructorParameterType: + record = new BamlConstructorParameterTypeRecord(); + break; + case BamlRecordType.ContentProperty: + record = new BamlContentPropertyRecord(); + break; + case BamlRecordType.AssemblyInfo: + case BamlRecordType.TypeInfo: + case BamlRecordType.TypeSerializerInfo: + case BamlRecordType.AttributeInfo: + case BamlRecordType.StringInfo: + Debug.Assert(false,"Assembly, Type and Attribute records are not cached, so don't ask for one."); + record = null; + break; + case BamlRecordType.StaticResourceStart: + record = new BamlStaticResourceStartRecord(); + break; + case BamlRecordType.StaticResourceEnd: + record = new BamlStaticResourceEndRecord(); + break; + case BamlRecordType.StaticResourceId: + record = new BamlStaticResourceIdRecord(); + break; + case BamlRecordType.LineNumberAndPosition: + record = new BamlLineAndPositionRecord(); + break; + case BamlRecordType.LinePosition: + record = new BamlLinePositionRecord(); + break; + case BamlRecordType.OptimizedStaticResource: + record = new BamlOptimizedStaticResourceRecord(); + break; + case BamlRecordType.PropertyWithStaticResourceId: + record = new BamlPropertyWithStaticResourceIdRecord(); + break; + default: + Debug.Assert(false,"Unknown RecordType"); + record = null; + break; + } + + return record; + } + + // This should only be called from BamlRecordWriter -- it gets a record from the record + // cache that must be freed with ReleaseRecord before GetRecord is called again. + internal BamlRecord GetWriteRecord(BamlRecordType recordType) + { + // Create the cache of records used in writing, on demand + + if( _writeCache == null ) + { + _writeCache = new BamlRecord[(int)BamlRecordType.LastRecordType]; + } + + BamlRecord record = _writeCache[(int)recordType]; + if (null == record) + { + record = AllocateWriteRecord(recordType); + } + else + { + _writeCache[(int)recordType] = null; + } + + // It is important to set RecordSize for variable size records + // to a negative number to indicate that it has not been set yet. + // Fixed size records should ignore this set. + record.RecordSize = -1; + return record; + } + + + //+--------------------------------------------------------------------------------------------- + // + // ReleaseWriteRecord + // + // Frees a record originally claimed with GetWriteRecord. Note that records in the + // read cache are implicitly recycled, and records in the write cache are explicitly + // recycled (i.e., there's a ReleaseWriteRecord, but no ReleaseReadRecord). + // + //+--------------------------------------------------------------------------------------------- + + internal void ReleaseWriteRecord(BamlRecord record) + { + // Put the write record back into the cache, if we're allowed to recycle it. + + if( !record.IsPinned ) + { + Debug.Assert(null == _writeCache[(int)record.RecordType]); + if (null != _writeCache[(int)record.RecordType]) + { + // This is really an internal error. + throw new InvalidOperationException(SR.Get(SRID.ParserMultiBamls)); + } + _writeCache[(int)record.RecordType] = record; + } + } + + + // Cache of BamlRecords, used during read, to avoid lots of records from being + // created. If a record gets pinned (BamlRecord.IsPinned gets set), it is not re-used. + + #if !PBTCOMPILER + BamlRecord[] _readCache = new BamlRecord[(int)BamlRecordType.LastRecordType]; + #endif + + // Cache of BamlRecords, used during write, also to avoid lots of records + // from being created. + + BamlRecord[] _writeCache = null; //new BamlRecord[(int)BamlRecordType.LastRecordType]; + + } + + // The base of all baml records. This gives a fixed size record that contains + // line number information used for generating error messages. Note that the + // line number information is not currently written out to the baml stream. + internal abstract class BamlRecord + { + + #region Methods + +#if !PBTCOMPILER + // If there are enough bytes available, load the record size from the + // binary reader. For fixed size records that derive from BamlRecord, + // there is no size field in the baml file, so this always succeeds. + internal virtual bool LoadRecordSize( + BinaryReader bamlBinaryReader, + long bytesAvailable) + { + return true; + } + + // Load record data. This does not include the record type, or the + // size field, which are loaded separately. If the subclass has no + // specific data to load, then don't override this. + internal virtual void LoadRecordData(BinaryReader bamlBinaryReader) + { + } +#endif + + // Writes data at the current position seek pointer points + // to byte after the end of record when done. + internal virtual void Write(BinaryWriter bamlBinaryWriter) + { + // BamlRecords may be used without a stream, so if you attempt to write when there + // isn't a writer, just ignore it. + if (bamlBinaryWriter == null) + { + return; + } + + // Baml records always start with record type + bamlBinaryWriter.Write((byte) RecordType); + + // IMPORTANT: The RecordType is the last thing written before calling + // WriteRecordData. Some records assume the record type is located + // directly before the current stream location and may change it, so + // don't change where the record type is written in the stream!!! + // Paint is one example of a DP object that will seek back to change + // the record type if it is unable to serialize itself. + WriteRecordData(bamlBinaryWriter); + } + + // Write contents of the record, excluding size (if any) and record type. + // If the subclass has no specific data to write out, don't override this. + internal virtual void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + } + + +#endregion Methods + +#region Properties + + // Actual size of the complete BamlRecord (excluding RecordType) in bytes. + // Currently limited to 2 gigabytes. Default size is 0 bytes of data. + // Subclasses must override if they have a different size. + internal virtual Int32 RecordSize + { + get { return 0; } + set { Debug.Assert (value == -1, "Setting fixed record to an invalid size"); } + } + + // Identifies the type off BAML record. This is used when casting to + // a BamlRecord subclass. All subclasses **MUST** override this. + internal virtual BamlRecordType RecordType + { + get + { + Debug.Assert(false, "Must override RecordType"); + return BamlRecordType.Unknown; + } + } + + +#if !PBTCOMPILER + // Next Record pointer - used in BamlObjectFactory + internal BamlRecord Next + { + get { return _nextRecord; } + set { _nextRecord = value ; } + } +#endif + + // The BamlRecorManager keeps a cache of baml records and tries to reuse them automatically. + // To keep a record from being cached, it can be pinned. For correct pinning we keep a + // pin count. To save working set, we only have two bits for the reference count. + // So if the reference count reaches three the record becomes permanently pinned. + + internal bool IsPinned + { + get + { + return PinnedCount > 0; + } + + } + + // (See comment on IsPinned.) + internal int PinnedCount + { + get + { + return _flags[_pinnedFlagSection]; + } + + set + { + Debug.Assert( value <= 3 && value >= 0 ); + _flags[_pinnedFlagSection] = value; + } + } + + // (See comment on IsPinned.) + internal void Pin() + { + if( PinnedCount < 3 ) + { + ++PinnedCount; + } + } + +#if !PBTCOMPILER + // (See comment on IsPinned.) + internal void Unpin() + { + if( PinnedCount < 3 ) + { + --PinnedCount; + } + } + + internal virtual void Copy(BamlRecord record) + { + record._flags = _flags; + record._nextRecord = _nextRecord; + } + +#endif + + + +#endregion Properties + +#region Data + + // Internal flags for efficient storage + // NOTE: bits here are used by sub-classes also. + // This BitVector32 field is shared by subclasses to save working set. Sharing flags like this + // is easier in e.g. FrameworkElement, where the class hierarchy is linear, but can be bug-prone otherwise. To make the + // code less fragile, each class abstractly provides it's last section to subclasses(LastFlagsSection), which they can + // use in their call to CreateSection. + + internal BitVector32 _flags; + + // Allocate space in _flags. + + private static BitVector32.Section _pinnedFlagSection = BitVector32.CreateSection( 3 /* Allocates two bits to store values up to 3 */ ); + + // This provides subclasses with a referece section to create their own section. + internal static BitVector32.Section LastFlagsSection + { + get { return _pinnedFlagSection; } + } + + +#if !PBTCOMPILER + private BamlRecord _nextRecord = null; +#endif + + + // Size of the record type field in the baml file. + internal const int RecordTypeFieldLength = 1; + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, "{0}", RecordType); + } + + protected static string GetTypeName(int typeId) + { + string typeName = typeId.ToString(CultureInfo.InvariantCulture); + if(typeId < 0) + { + KnownElements elm = (KnownElements)(-typeId); + typeName = elm.ToString(); + } + return typeName; + } + + + // This helper checks for records that indicate that you're out of + // an element start, and into it's "content" (in the xml sense). + // We have to infer this, because unlike Xml, Baml doesn't provide + // an end-attributes record. + + internal static bool IsContentRecord( BamlRecordType bamlRecordType ) + { + return bamlRecordType == BamlRecordType.PropertyComplexStart + || + bamlRecordType == BamlRecordType.PropertyArrayStart + || + bamlRecordType == BamlRecordType.PropertyIListStart + || + bamlRecordType == BamlRecordType.PropertyIDictionaryStart + || + bamlRecordType == BamlRecordType.Text; + + } + +#endif + +#endregion Data + } + + // An abstract base class for records that record their size as part of the + // baml stream. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal abstract class BamlVariableSizedRecord : BamlRecord + { + #region Methods + +#if !PBTCOMPILER + // If there are enough bytes available, load the record size from the + // binary reader. The default action is to load the 4 byte size from + // the reader, if there are at least 4 bytes available. + internal override bool LoadRecordSize( + BinaryReader bamlBinaryReader, + long bytesAvailable) + { + int recordSize; + bool loadedSize = LoadVariableRecordSize(bamlBinaryReader, bytesAvailable, out recordSize); + if (loadedSize) + { + RecordSize = recordSize; + } + return loadedSize; + } + + // If there are enough bytes available, load the record size from the + // binary reader. The default action is to load the 4 byte size from + // the reader, if there are at least 4 bytes available. + internal static bool LoadVariableRecordSize( + BinaryReader bamlBinaryReader, + long bytesAvailable, + out int recordSize) + { + if (bytesAvailable >= MaxRecordSizeFieldLength) + { + recordSize = ((BamlBinaryReader)bamlBinaryReader).Read7BitEncodedInt(); + return true; + } + else + { + recordSize = -1; + return false; + } + } +#endif + + protected int ComputeSizeOfVariableLengthRecord(long start, long end) + { + int size = (Int32)(end - start); + int sizeOfSize = BamlBinaryWriter.SizeOf7bitEncodedSize(size); + sizeOfSize = BamlBinaryWriter.SizeOf7bitEncodedSize(sizeOfSize+size); + return (sizeOfSize+size); + } + + // Writes data at the current position seek pointer points + // to byte after the end of record when done. + internal override void Write(BinaryWriter bamlBinaryWriter) + { + // BamlRecords may be used without a stream, so if you attempt to write when there + // isn't a writer, just ignore it. + if (bamlBinaryWriter == null) + { + return; + } + + + // Baml records always start with record type + bamlBinaryWriter.Write((byte) RecordType); + + // Remember the file location of this baml record. This + // is needed if we have to come back later to update the sync mode. + // IMPORTANT: The RecordType is the last thing written before calling + // WriteRecordData. Some records assume the record type is located + // directly before the current stream location and may change it, so + // don't change where the record type is written in the stream!!! + // Paint is one example of a DP object that will seek back to change + // the record type if it is unable to serialize itself. + + // Write just the data, this is just to measure the size. + long startSeekPosition = bamlBinaryWriter.Seek(0,SeekOrigin.Current); + WriteRecordData(bamlBinaryWriter); + long endSeekPosition = bamlBinaryWriter.Seek(0,SeekOrigin.Current); + + Debug.Assert(RecordSize < 0); + RecordSize = ComputeSizeOfVariableLengthRecord(startSeekPosition, endSeekPosition); + + // seek back to the begining, this time write the size, then the data. + bamlBinaryWriter.Seek((int)startSeekPosition, SeekOrigin.Begin); + WriteRecordSize(bamlBinaryWriter); + WriteRecordData(bamlBinaryWriter); + } + + // Write the size of this record. The default action is to write the 4 byte + // size, which may be overwritten later once WriteRecordData has been called. + internal void WriteRecordSize(BinaryWriter bamlBinaryWriter) + { + ((BamlBinaryWriter)bamlBinaryWriter).Write7BitEncodedInt(RecordSize); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlVariableSizedRecord newRecord = (BamlVariableSizedRecord)record; + newRecord._recordSize = _recordSize; + } +#endif + +#endregion Methods + +#region Properties + + // Actual size of the complete BamlRecord in bytes. Currently + // limited to 2 gigabytes. + internal override Int32 RecordSize + { + get { return _recordSize; } + set { _recordSize = value; } + } + + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return BamlRecord.LastFlagsSection; } + } + + +#endregion Properties + +#region Data + + // Size of the RecordSize field in the baml file. This must be in + // sync the type type of _recordSize below. + internal const int MaxRecordSizeFieldLength = 4; + + Int32 _recordSize = -1; // we use a 7 bit encoded variable size + +#endregion Data + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlXmlnsPropertyRecord : BamlVariableSizedRecord + { + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + Prefix = bamlBinaryReader.ReadString(); + XmlNamespace = bamlBinaryReader.ReadString(); + + short count = bamlBinaryReader.ReadInt16(); + + if (count > 0) + { + AssemblyIds = new short[count]; + + for (short i = 0; i < count; i++) + { + AssemblyIds[i] = bamlBinaryReader.ReadInt16(); + } + } + else + { + AssemblyIds = null; + } + + } +#endif + + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(Prefix); + bamlBinaryWriter.Write(XmlNamespace); + + // Write the AssemblyIds which contain XmlnsDefinitionAttribute + // for this xmlns Uri. + // The format should be CountN Id1 Id2 ... IdN + // + short count = 0; + + if (AssemblyIds != null && AssemblyIds.Length > 0) + { + count = (short) AssemblyIds.Length; + } + + bamlBinaryWriter.Write(count); + + if (count > 0) + { + for (short i = 0; i < count; i++) + { + bamlBinaryWriter.Write(AssemblyIds[i]); + } + } + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlXmlnsPropertyRecord newRecord = (BamlXmlnsPropertyRecord)record; + newRecord._prefix = _prefix; + newRecord._xmlNamespace = _xmlNamespace; + newRecord._assemblyIds = _assemblyIds; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.XmlnsProperty; } + } + + internal string Prefix + { + get { return _prefix; } + set {_prefix = value; } + } + + internal string XmlNamespace + { + get { return _xmlNamespace; } + set { _xmlNamespace = value; } + } + + internal short[] AssemblyIds + { + get { return _assemblyIds; } + set { _assemblyIds = value; } + } + +#endregion Properties + +#region Data + + string _prefix; + string _xmlNamespace; + short[] _assemblyIds; + +#endregion Data + + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPIMappingRecord : BamlVariableSizedRecord + { + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + XmlNamespace = bamlBinaryReader.ReadString(); + ClrNamespace = bamlBinaryReader.ReadString(); + AssemblyId = bamlBinaryReader.ReadInt16(); + } +#endif + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + // write out an int for record size but we'll go back and fill + bamlBinaryWriter.Write(XmlNamespace); + bamlBinaryWriter.Write(ClrNamespace); + bamlBinaryWriter.Write(AssemblyId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPIMappingRecord newRecord = (BamlPIMappingRecord)record; + newRecord._xmlns = _xmlns; + newRecord._clrns = _clrns; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PIMapping; } + } + + internal string XmlNamespace + { + get { return _xmlns; } + set {_xmlns = value; } + } + + internal string ClrNamespace + { + get { return _clrns; } + set { _clrns = value; } + } + + internal short AssemblyId + { + + get + { + short value = (short) _flags[_assemblyIdLowSection]; + value |= (short) (_flags[_assemblyIdHighSection] << 8); + + return value; + } + + set + { + _flags[_assemblyIdLowSection] = (short) (value & 0xff); + _flags[_assemblyIdHighSection] = (short) ((value & 0xff00) >> 8); + } + + } + + // Allocate space in _flags. + // BitVector32 doesn't support 16 bit sections, so we have to break + // it up into 2 sections. + + private static BitVector32.Section _assemblyIdLowSection + = BitVector32.CreateSection( (short)0xff, BamlVariableSizedRecord.LastFlagsSection ); + + private static BitVector32.Section _assemblyIdHighSection + = BitVector32.CreateSection( (short)0xff, _assemblyIdLowSection ); + +#if !PBTCOMPILER + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _assemblyIdHighSection; } + } +#endif + + + +#endregion Properties + +#region Data + string _xmlns; + string _clrns; +#endregion Data + + } + + // Common base class for variables sized records that contain a string value + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal abstract class BamlStringValueRecord : BamlVariableSizedRecord + { + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + Value = bamlBinaryReader.ReadString(); + } +#endif + + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(Value); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlStringValueRecord newRecord = (BamlStringValueRecord)record; + newRecord._value = _value; + } +#endif + +#endregion Methods + +#region Properties + + internal string Value + { + get { return _value; } + set { _value = value; } + } + +#endregion Properties + +#region Data + string _value; +#endregion Data + + } + + // Common methods for baml records that serve as keys in a dictionary. + internal interface IBamlDictionaryKey + { + // Update the pointer to the Value that was written out when WriteRecordData + // was first called. + void UpdateValuePosition( + Int32 newPosition, + BinaryWriter bamlBinaryWriter); + + // Relative stream position in the baml stream where the value associated + // with this key starts. It is relative to the end of the keys section, + // or the start of the values section. + Int32 ValuePosition { get; set; } + + // The actual key object used in the dictionary. This may be a string, + // field, type or other object. + object KeyObject { get; set; } + + // Position in the stream where ValuePosition was written. This is needed + // when updating the ValuePosition. + Int64 ValuePositionPosition { get; set; } + + // True if the value associated with this key is shared. + bool Shared { get; set; } + + // Whether Shared was set. + bool SharedSet { get; set; } + +#if !PBTCOMPILER + object[] StaticResourceValues {get; set;} +#endif + } + + // Common interface implemented by BamlRecords that + // use optimized storage for MarkupExtensions. + internal interface IOptimizedMarkupExtension + { + short ExtensionTypeId + { + get; + } + + short ValueId + { + get; + } + + bool IsValueTypeExtension + { + get; + } + + bool IsValueStaticExtension + { + get; + } + } + + // BamlRecord use in a defer loaded dictionary as the key for adding a value. + // The value is a type that is refered to using a TypeID + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlDefAttributeKeyTypeRecord : BamlElementStartRecord, IBamlDictionaryKey + { + internal BamlDefAttributeKeyTypeRecord() + { + Pin(); // Don't allow this record to be recycled in the read cache. + } + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + base.LoadRecordData(bamlBinaryReader); + _valuePosition = bamlBinaryReader.ReadInt32(); + ((IBamlDictionaryKey)this).Shared = bamlBinaryReader.ReadBoolean(); + ((IBamlDictionaryKey)this).SharedSet = bamlBinaryReader.ReadBoolean(); + } +#endif + + // Write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + base.WriteRecordData(bamlBinaryWriter); + _valuePositionPosition = bamlBinaryWriter.Seek(0, SeekOrigin.Current); + bamlBinaryWriter.Write(_valuePosition); + bamlBinaryWriter.Write(((IBamlDictionaryKey)this).Shared); + bamlBinaryWriter.Write(((IBamlDictionaryKey)this).SharedSet); + } + + // Update the pointer to the Value that was written out when WriteRecordData + // was first called. At that time the true position was probably not known, + // so it is written out later. Be certain to leave the passed writer pointing + // to the same location it was at when this call was made. + void IBamlDictionaryKey.UpdateValuePosition( + Int32 newPosition, + BinaryWriter bamlBinaryWriter) + { + Debug.Assert(_valuePositionPosition != -1, + "Must call WriteRecordData before updating position"); + + // Use relative positions to reduce the possibility of truncation, + // since Seek takes a 32 bit int, but position is a 64 bit int. + Int64 existingPosition = bamlBinaryWriter.Seek(0, SeekOrigin.Current); + Int32 deltaPosition = (Int32)(_valuePositionPosition-existingPosition); + + bamlBinaryWriter.Seek(deltaPosition, SeekOrigin.Current); + bamlBinaryWriter.Write(newPosition); + bamlBinaryWriter.Seek(-ValuePositionSize-deltaPosition, SeekOrigin.Current); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlDefAttributeKeyTypeRecord newRecord = (BamlDefAttributeKeyTypeRecord)record; + newRecord._valuePosition = _valuePosition; + newRecord._valuePositionPosition = _valuePositionPosition; + newRecord._keyObject = _keyObject; + newRecord._staticResourceValues = _staticResourceValues; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.DefAttributeKeyType; } + } + + // Relative stream position in the baml stream where the value associated + // with this key starts. It is relative to the end of the keys section, + // or the start of the values section. + Int32 IBamlDictionaryKey.ValuePosition + { + get { return _valuePosition; } + set { _valuePosition = value; } + } + + // The actual key used in the defer loaded dictionary. For this type of + // record the key is a Type that is obtained at runtime from the base + // classes TypeId + object IBamlDictionaryKey.KeyObject + { + get { return _keyObject; } + set { _keyObject = value; } + } + + // Position in the stream where ValuePosition was written. This is needed + // when updating the ValuePosition. + Int64 IBamlDictionaryKey.ValuePositionPosition + { + get { return _valuePositionPosition; } + set { _valuePositionPosition = value; } + } + + // True if the value associated with this key is shared. + bool IBamlDictionaryKey.Shared + { + get + { + return _flags[_sharedSection] == 1 ? true : false; + } + + set + { + _flags[_sharedSection] = value ? 1 : 0; + } + } + + // Whether Shared was set + bool IBamlDictionaryKey.SharedSet + { + get + { + return _flags[_sharedSetSection] == 1 ? true : false; + } + + set + { + _flags[_sharedSetSection] = value ? 1 : 0; + } + } + +#if !PBTCOMPILER + object[] IBamlDictionaryKey.StaticResourceValues + { + get { return _staticResourceValues; } + set { _staticResourceValues = value; } + } +#endif + + + // Allocate space in _flags. + + private static BitVector32.Section _sharedSection + = BitVector32.CreateSection( 1, BamlElementStartRecord.LastFlagsSection ); + + private static BitVector32.Section _sharedSetSection + = BitVector32.CreateSection( 1, _sharedSection ); + +#if !PBTCOMPILER + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _sharedSetSection; } + } +#endif + + + +#endregion Properties + +#region Data + + // Size in bytes of the ValuePosition field written out to baml. This + // must be in sync with the size of _valuePosition below. + internal const Int32 ValuePositionSize = 4; + + // Relative position in the stream where the value associated with this key starts + Int32 _valuePosition; + + // Position in the stream where ValuePosition was written. This is needed + // when updating the ValuePosition. + Int64 _valuePositionPosition = -1; + + // Actual object key used by a dictionary. This is a Type object + object _keyObject = null; + +#if !PBTCOMPILER + object[] _staticResourceValues; +#endif + +#endregion Data + } + + + // BamlRecord for x:Key attribute when used in a defer loaded dictionary + // as the key for adding a value. The value is stored as a string. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlDefAttributeKeyStringRecord : BamlStringValueRecord, IBamlDictionaryKey + { + internal BamlDefAttributeKeyStringRecord() + { + Pin(); // Don't allow this record to be recycled in the read cache. + } + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + ValueId = bamlBinaryReader.ReadInt16(); + _valuePosition = bamlBinaryReader.ReadInt32(); + ((IBamlDictionaryKey)this).Shared = bamlBinaryReader.ReadBoolean(); + ((IBamlDictionaryKey)this).SharedSet = bamlBinaryReader.ReadBoolean(); + _keyObject = null; + } +#endif + + // Write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(ValueId); + _valuePositionPosition = bamlBinaryWriter.Seek(0, SeekOrigin.Current); + bamlBinaryWriter.Write(_valuePosition); + bamlBinaryWriter.Write(((IBamlDictionaryKey)this).Shared); + bamlBinaryWriter.Write(((IBamlDictionaryKey)this).SharedSet); + } + + // Update the pointer to the Value that was written out when WriteRecordData + // was first called. At that time the true position was probably not known, + // so it is written out later. Be certain to leave the passed writer pointing + // to the same location it was at when this call was made. + void IBamlDictionaryKey.UpdateValuePosition( + Int32 newPosition, + BinaryWriter bamlBinaryWriter) + { + Debug.Assert(_valuePositionPosition != -1, + "Must call WriteRecordData before updating position"); + + // Use relative positions to reduce the possibility of truncation, + // since Seek takes a 32 bit int, but position is a 64 bit int. + Int64 existingPosition = bamlBinaryWriter.Seek(0, SeekOrigin.Current); + Int32 deltaPosition = (Int32)(_valuePositionPosition-existingPosition); + + bamlBinaryWriter.Seek(deltaPosition, SeekOrigin.Current); + bamlBinaryWriter.Write(newPosition); + bamlBinaryWriter.Seek(-ValuePositionSize-deltaPosition, SeekOrigin.Current); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlDefAttributeKeyStringRecord newRecord = (BamlDefAttributeKeyStringRecord)record; + newRecord._valuePosition = _valuePosition; + newRecord._valuePositionPosition = _valuePositionPosition; + newRecord._keyObject = _keyObject; + newRecord._valueId = _valueId; + newRecord._staticResourceValues = _staticResourceValues; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.DefAttributeKeyString; } + } + + // Relative stream position in the baml stream where the value associated + // with this key starts. It is relative to the end of the keys section, + // or the start of the values section. + Int32 IBamlDictionaryKey.ValuePosition + { + get { return _valuePosition; } + set { _valuePosition = value; } + } + + // True if the value associated with this key is shared. + bool IBamlDictionaryKey.Shared + { + get + { + return _flags[_sharedSection] == 1 ? true : false; + } + + set + { + _flags[_sharedSection] = value ? 1 : 0; + } + + } + + // Whether Shared was set + bool IBamlDictionaryKey.SharedSet + { + get + { + return _flags[_sharedSetSection] == 1 ? true : false; + } + + set + { + _flags[_sharedSetSection] = value ? 1 : 0; + } + + } + + // Allocate space in _flags. + + private static BitVector32.Section _sharedSection + = BitVector32.CreateSection( 1, BamlStringValueRecord.LastFlagsSection ); + + private static BitVector32.Section _sharedSetSection + = BitVector32.CreateSection( 1, _sharedSection ); + +#if !PBTCOMPILER + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _sharedSetSection; } + } +#endif + + + // The following are NOT written out to BAML but are cached at runtime + + // The string value translated into a key object. The string may represent + // a type, field, or other object that can be translated into an object using + // using the Mapper. + object IBamlDictionaryKey.KeyObject + { + get { return _keyObject; } + set { _keyObject = value; } + } + + // Position in the stream where ValuePosition was written. This is needed + // when updating the ValuePosition. + Int64 IBamlDictionaryKey.ValuePositionPosition + { + get { return _valuePositionPosition; } + set { _valuePositionPosition = value; } + } + + internal Int16 ValueId + { + get { return _valueId; } + set { _valueId = value; } + } + + +#if !PBTCOMPILER + object[] IBamlDictionaryKey.StaticResourceValues + { + get { return _staticResourceValues; } + set { _staticResourceValues = value; } + } +#endif + +#endregion Properties + +#region Data + + // Size in bytes of the ValuePosition field written out to baml. This + // must be in sync with the size of _valuePosition below. + internal const Int32 ValuePositionSize = 4; + + // Relative position in the stream where the value associated with this key starts + Int32 _valuePosition; + + // Position in the stream where ValuePosition was written. This is needed + // when updating the ValuePosition. + Int64 _valuePositionPosition = -1; + + // Actual object key used by a dictionary. This is the Value string + // after conversion. + object _keyObject = null; + + Int16 _valueId; + +#if !PBTCOMPILER + object[] _staticResourceValues; +#endif + +#endregion Data + } + + // BamlRecord for x:Whatever attribute + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlDefAttributeRecord : BamlStringValueRecord + { + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + Value = bamlBinaryReader.ReadString(); + NameId = bamlBinaryReader.ReadInt16(); + Name = null; + } +#endif + + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(Value); + bamlBinaryWriter.Write(NameId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlDefAttributeRecord newRecord = (BamlDefAttributeRecord)record; + newRecord._name = _name; + newRecord._nameId = _nameId; + newRecord._attributeUsage = _attributeUsage; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.DefAttribute; } + } + + // The following is written out the baml file. + + internal Int16 NameId + { + get { return _nameId; } + set { _nameId = value; } + } + + // The following are cached locally, but not written to baml. + + internal string Name + { +#if !PBTCOMPILER + get { return _name; } +#endif + set { _name = value; } + } + + // Some attributes have special usage, such as setting the XmlLang and XmlSpace + // strings in the parser context. This is flagged with this property + internal BamlAttributeUsage AttributeUsage + { +#if !PBTCOMPILER + get { return _attributeUsage; } +#endif + set { _attributeUsage = value; } + } + +#endregion Properties + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} nameId({1}) is '{2}' usage={3}", + RecordType, NameId, Name, AttributeUsage); + } +#endif + +#region Data + string _name; + Int16 _nameId; + BamlAttributeUsage _attributeUsage; +#endregion Data + + } + + // BamlRecord for PresentationOptions:Whatever attribute + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPresentationOptionsAttributeRecord : BamlStringValueRecord + { + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + Value = bamlBinaryReader.ReadString(); + NameId = bamlBinaryReader.ReadInt16(); + Name = null; + } +#endif + + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(Value); + bamlBinaryWriter.Write(NameId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPresentationOptionsAttributeRecord newRecord = (BamlPresentationOptionsAttributeRecord)record; + newRecord._name = _name; + newRecord._nameId = _nameId; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PresentationOptionsAttribute; } + } + + // The following is written out the baml file. + + internal Int16 NameId + { + get { return _nameId; } + set { _nameId = value; } + } + + // The following are cached locally, but not written to baml. + + internal string Name + { +#if !PBTCOMPILER + get { return _name; } +#endif + set { _name = value; } + } + +#endregion Properties + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} nameId({1}) is '{2}' ", + RecordType, NameId, Name); + } +#endif + +#region Data + string _name; + Int16 _nameId; +#endregion Data + + } + + // + // BamlPropertyComplexStartRecord is for Complex DependencyProperty declarations + // in markup, where the actual type and value is determined by subsequent records. + // + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyComplexStartRecord : BamlRecord + { + +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AttributeId = bamlBinaryReader.ReadInt16(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(AttributeId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPropertyComplexStartRecord newRecord = (BamlPropertyComplexStartRecord)record; + newRecord._attributeId = _attributeId; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyComplexStart; } + } + + internal short AttributeId + { + get { return _attributeId; } + set { _attributeId = value; } + } + + internal override Int32 RecordSize + { + get { return 2; } + set { Debug.Assert (value == -1, "Wrong size set for complex prop record"); } + } + +#endregion Properties + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} attr({1})", + RecordType, _attributeId); + } +#endif + +#region Data + short _attributeId = -1; +#endregion Data + + } + + // + // BamlPropertyStringReferenceRecord is for Property values that are written + // out as references into the string table. + // + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyStringReferenceRecord : BamlPropertyComplexStartRecord + { + #region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AttributeId = bamlBinaryReader.ReadInt16(); + StringId = bamlBinaryReader.ReadInt16(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(AttributeId); + bamlBinaryWriter.Write(StringId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPropertyStringReferenceRecord newRecord = (BamlPropertyStringReferenceRecord)record; + newRecord._stringId = _stringId; + } +#endif + + #endregion Methods + + #region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyStringReference; } + } + + internal short StringId + { + get { return _stringId; } +#if !PBTCOMPILER + set { _stringId = value; } +#endif + } + + internal override Int32 RecordSize + { + get { return 4; } + set { Debug.Assert (value == -1, "Wrong size set for complex prop record"); } + } + + #endregion Properties + + #region Data + short _stringId = 0; + + #endregion Data + } + + // + // BamlPropertyTypeReferenceRecord is for Property values that are written + // out as references into the type table. So the property value is a 'Type' object. + // + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyTypeReferenceRecord : BamlPropertyComplexStartRecord + { + #region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AttributeId = bamlBinaryReader.ReadInt16(); + TypeId = bamlBinaryReader.ReadInt16(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(AttributeId); + bamlBinaryWriter.Write(TypeId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPropertyTypeReferenceRecord newRecord = (BamlPropertyTypeReferenceRecord)record; + newRecord._typeId = _typeId; + } +#endif + + #endregion Methods + + #region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyTypeReference; } + } + + internal short TypeId + { + get { return _typeId; } + set { _typeId = value; } + } + + internal override Int32 RecordSize + { + get { return 4; } + set { Debug.Assert (value == -1, "Wrong size set for complex prop record"); } + } + + #endregion Properties + + #region Data + short _typeId = 0; + #endregion Data + } + + // + // BamlPropertyWithConverterRecord information for property with custom type converter + // + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyWithConverterRecord : BamlPropertyRecord + { + #region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + base.LoadRecordData(bamlBinaryReader); + ConverterTypeId = bamlBinaryReader.ReadInt16(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + base.WriteRecordData(bamlBinaryWriter); + bamlBinaryWriter.Write(ConverterTypeId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPropertyWithConverterRecord newRecord = (BamlPropertyWithConverterRecord)record; + newRecord._converterTypeId = _converterTypeId; + } +#endif + + #endregion Methods + + #region Properties + + // The following are stored in the baml stream + + // ID of this type converter. Referenced in other baml records where a + // Type is needed. + internal short ConverterTypeId + { + get { return _converterTypeId; } + set { _converterTypeId = value; } + } + + // Additional properties not stored in the baml stream + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyWithConverter; } + } + + #endregion Properties + + #region Data + + short _converterTypeId = 0; + + #endregion Data + } + + // + // BamlPropertyRecord is for DependencyProperty values that are written + // out as strings. + // + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyRecord : BamlStringValueRecord + { + +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AttributeId = bamlBinaryReader.ReadInt16(); + Value = bamlBinaryReader.ReadString(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(AttributeId); + bamlBinaryWriter.Write(Value); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPropertyRecord newRecord = (BamlPropertyRecord)record; + newRecord._attributeId = _attributeId; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.Property; } + } + + internal short AttributeId + { + get { return _attributeId; } + set { _attributeId = value; } + } + +#endregion Properties + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} attr({1}) <== '{2}'", + RecordType, _attributeId, Value); + } +#endif + +#region Data + short _attributeId = -1; +#endregion Data + + + } + + // + // BamlPropertyWithExtensionRecord is for property values that are Markup extensions + // with a single param member that are written out as attributeIds. + // + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyWithExtensionRecord : BamlRecord, IOptimizedMarkupExtension + { + #region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AttributeId = bamlBinaryReader.ReadInt16(); + short extensionTypeId = bamlBinaryReader.ReadInt16(); + ValueId = bamlBinaryReader.ReadInt16(); + + // The upper 4 bits of the ExtensionTypeId are used as flags + _extensionTypeId = (short)(extensionTypeId & ExtensionIdMask); + IsValueTypeExtension = (extensionTypeId & TypeExtensionValueMask) == TypeExtensionValueMask; + IsValueStaticExtension = (extensionTypeId & StaticExtensionValueMask) == StaticExtensionValueMask; + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(AttributeId); + short extensionTypeId = ExtensionTypeId; + if (IsValueTypeExtension) + { + extensionTypeId |= TypeExtensionValueMask; + } + else if (IsValueStaticExtension) + { + extensionTypeId |= StaticExtensionValueMask; + } + bamlBinaryWriter.Write(extensionTypeId); + bamlBinaryWriter.Write(ValueId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPropertyWithExtensionRecord newRecord = (BamlPropertyWithExtensionRecord)record; + newRecord._attributeId = _attributeId; + newRecord._extensionTypeId = _extensionTypeId; + newRecord._valueId = _valueId; + } +#endif + + #endregion Methods + + #region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyWithExtension; } + } + + // Id of the property whose value is the simple ME + internal short AttributeId + { + get { return _attributeId; } + set { _attributeId = value; } + } + + // KnownElement Id of the MarkupExtension + public short ExtensionTypeId + { + get { return _extensionTypeId; } + set + { + // we shouldn't ever be intruding on the flags portion of the ExtensionTypeId + Debug.Assert(value <= ExtensionIdMask); + _extensionTypeId = value; + } + } + + // For StaticExtension: AttributeId of a member + // For TemplateBindingExtension: AttributeId of a DependencyProperty + // For a DynamicResourceExtension: + // StringId if the value is a string + // TypeId if the value is a TypeExtension + // AttributeId of the member if the value is a StaticExtension + public short ValueId + { + get { return _valueId; } + set { _valueId = value; } + } + + internal override Int32 RecordSize + { + get { return 6; } + set { Debug.Assert(value == -1, "Wrong size set for complex prop record"); } + } + + // For DynamicResourceExtension, if the value is itself a simple TypeExtension + public bool IsValueTypeExtension + { + get { return _flags[_isValueTypeExtensionSection] == 1 ? true : false; } + set { _flags[_isValueTypeExtensionSection] = value ? 1 : 0; } + } + + // For DynamicResourceExtension, if the value is itself a simple StaticExtension + public bool IsValueStaticExtension + { + get { return _flags[_isValueStaticExtensionSection] == 1 ? true : false; } + set { _flags[_isValueStaticExtensionSection] = value ? 1 : 0; } + } + + // Allocate space in _flags. + private static BitVector32.Section _isValueTypeExtensionSection + = BitVector32.CreateSection(1, BamlRecord.LastFlagsSection); + + private static BitVector32.Section _isValueStaticExtensionSection + = BitVector32.CreateSection(1, _isValueTypeExtensionSection); + +#if !PBTCOMPILER + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _isValueStaticExtensionSection; } + } + + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} attr({1}) extn({2}) valueId({3})", + RecordType, _attributeId, _extensionTypeId, _valueId); + } +#endif + + #endregion Properties + + #region Data + short _attributeId = -1; + short _extensionTypeId = 0; + short _valueId = 0; + + private static readonly short ExtensionIdMask = 0x0FFF; + private static readonly short TypeExtensionValueMask = 0x4000; + private static readonly short StaticExtensionValueMask = 0x2000; + #endregion Data + } + + // + // BamlPropertyCustomWriteInfoRecord is for DependencyProperty values that support + // custom Avalon serialization. The property value objects write directly onto + // the BAML stream in whatever format they understand. This record is used only + // during BAML write time. + // + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyCustomWriteInfoRecord : BamlPropertyCustomRecord + { + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + int writePositionStart = (int)bamlBinaryWriter.Seek(0, SeekOrigin.Current); + short serializerTypeId = SerializerTypeId; + + bamlBinaryWriter.Write(AttributeId); + if (serializerTypeId == (short)KnownElements.DependencyPropertyConverter) + { + // There is no need to actually use a real Converter here since we already have the + // DP value as an AttributeInfoId. + + // if ValueMemberName exists then remember that the ValueId is a TypeId of the + // type that declares ValueMemberName, so that it can be resolved correctly at + // load time. + if (ValueMemberName != null) + { + bamlBinaryWriter.Write((short)(serializerTypeId | TypeIdValueMask)); + } + else + { + bamlBinaryWriter.Write(serializerTypeId); + } + + // if ValueMemberName does not exist, ValueId is a KnownProperty Id + // else it is a TypeId of the declaring type. + bamlBinaryWriter.Write(ValueId); + + // Write out the ValueMemberName if it exists + if (ValueMemberName != null) + { + bamlBinaryWriter.Write(ValueMemberName); + } + + return; + } + + bamlBinaryWriter.Write(serializerTypeId); + + bool converted = false; + + // If we have an enum or a bool, do conversion to custom binary data here, + // since we do not have a serializer associated with these types. + if (ValueType != null && ValueType.IsEnum) + { + uint uintValue = 0; + string [] enumValues = Value.Split(new Char[] { ',' }); + + // if the Enum is a flag, then resolve each flag value in the enum value string. + foreach (string enumValue in enumValues) + { + FieldInfo enumField = ValueType.GetField(enumValue.Trim(), BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase); + if (enumField != null) + { + // get the raw va;ue of the enum field and convert to a uint. + object rawEnumValue = enumField.GetRawConstantValue(); + uintValue += (uint)Convert.ChangeType(rawEnumValue, typeof(uint), TypeConverterHelper.InvariantEnglishUS); + converted = true; + } + else + { + converted = false; + break; + } + } + + if (converted) + { + bamlBinaryWriter.Write(uintValue); + } + } + else if (ValueType == typeof(Boolean)) + { + TypeConverter boolConverter = TypeDescriptor.GetConverter(typeof(Boolean)); + object convertedValue = boolConverter.ConvertFromString(TypeContext, TypeConverterHelper.InvariantEnglishUS, Value); + bamlBinaryWriter.Write((byte)Convert.ChangeType(convertedValue, typeof(byte), TypeConverterHelper.InvariantEnglishUS)); + converted = true; + } + else if (SerializerType == typeof(XamlBrushSerializer)) + { + XamlSerializer serializer = new XamlBrushSerializer(); + + // If we custom serialize this particular value at this point, then see + // if it can convert. + // NOTE: This is sensitive to changes in the BamlRecordWriter and + // BamlRecordManager code and must be kept in sync with them... + converted = serializer.ConvertStringToCustomBinary(bamlBinaryWriter, Value); + } + else if (SerializerType == typeof(XamlPoint3DCollectionSerializer)) + { + XamlSerializer serializer = new XamlPoint3DCollectionSerializer(); + + // If we custom serialize this particular value at this point, then see + // if it can convert. + // NOTE: This is sensitive to changes in the BamlRecordWriter and + // BamlRecordManager code and must be kept in sync with them... + converted = serializer.ConvertStringToCustomBinary(bamlBinaryWriter, Value); + } + else if (SerializerType == typeof(XamlVector3DCollectionSerializer)) + { + XamlSerializer serializer = new XamlVector3DCollectionSerializer(); + + // If we custom serialize this particular value at this point, then see + // if it can convert. + // NOTE: This is sensitive to changes in the BamlRecordWriter and + // BamlRecordManager code and must be kept in sync with them... + converted = serializer.ConvertStringToCustomBinary(bamlBinaryWriter, Value); + } + else if (SerializerType == typeof(XamlPointCollectionSerializer)) + { + XamlSerializer serializer = new XamlPointCollectionSerializer(); + + // If we custom serialize this particular value at this point, then see + // if it can convert. + // NOTE: This is sensitive to changes in the BamlRecordWriter and + // BamlRecordManager code and must be kept in sync with them... + converted = serializer.ConvertStringToCustomBinary(bamlBinaryWriter, Value); + } + else if (SerializerType == typeof(XamlInt32CollectionSerializer)) + { + XamlSerializer serializer = new XamlInt32CollectionSerializer(); + + // If we custom serialize this particular value at this point, then see + // if it can convert. + // NOTE: This is sensitive to changes in the BamlRecordWriter and + // BamlRecordManager code and must be kept in sync with them... + converted = serializer.ConvertStringToCustomBinary(bamlBinaryWriter, Value); + } + else if (SerializerType == typeof(XamlPathDataSerializer)) + { + XamlSerializer serializer = new XamlPathDataSerializer(); + + // If we custom serialize this particular value at this point, then see + // if it can convert. + // NOTE: This is sensitive to changes in the BamlRecordWriter and + // BamlRecordManager code and must be kept in sync with them... + converted = serializer.ConvertStringToCustomBinary(bamlBinaryWriter, Value); + } + + if (!converted) + { + throw new XamlParseException(SR.Get(SRID.ParserBadString, Value, ValueType.Name)); + } + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPropertyCustomWriteInfoRecord newRecord = (BamlPropertyCustomWriteInfoRecord)record; + newRecord._valueId = _valueId; + newRecord._valueType = _valueType; + newRecord._value = _value; + newRecord._valueMemberName = _valueMemberName; + newRecord._serializerType = _serializerType; + newRecord._typeContext = _typeContext; + } +#endif + + // The KnownProperty Id of the Value, if it is a property and can be converted into one, + // or the TypeId of the owner of the property value + internal short ValueId + { + get { return _valueId; } + set { _valueId = value; } + } + + // If ValueId is a TypeId, then this holds the name of the member. + internal string ValueMemberName + { + get { return _valueMemberName; } + set { _valueMemberName = value; } + } + + // The following properties are NOT written to the BAML stream. + + // Type of this property + internal Type ValueType + { + get { return _valueType; } + set { _valueType = value; } + } + + // The string Value of the property. + internal string Value + { + get { return _value; } + set { _value = value; } + } + + // Type of the XamlSerializer associated with this property. Null + // if this type is custom serialized by the parser itself. + internal Type SerializerType + { + get { return _serializerType; } + set { _serializerType = value; } + } + + // Context used for type conversion of built in types. + internal ITypeDescriptorContext TypeContext + { + get { return _typeContext; } + set { _typeContext = value; } + } + + short _valueId; + Type _valueType; + string _value; + string _valueMemberName; + Type _serializerType; + ITypeDescriptorContext _typeContext; + } + + // + // BamlPropertyCustomRecord is for DependencyProperty values that support + // custom Avalon serialization. This record is used only during BAML load. + // The property value objects are read directly from the BAML stream by the + // custom binary serializer for the property. + // + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyCustomRecord : BamlVariableSizedRecord + { +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AttributeId = bamlBinaryReader.ReadInt16(); + short serializerTypeId = bamlBinaryReader.ReadInt16(); + + IsValueTypeId = (serializerTypeId & TypeIdValueMask) == TypeIdValueMask; + if (IsValueTypeId) + { + serializerTypeId &= (short)(~TypeIdValueMask); + } + + SerializerTypeId = serializerTypeId; + + ValueObjectSet = false; + IsRawEnumValueSet = false; + _valueObject = null; + + // ValueObject and ValueObject are not set until BamlRecordReader.ReadPropertyCustomRecord + // because the Mapper is needed for custom DPs + + // NOTE: above may no longer true, so this could be potentially changed to be in sync with + // other record. Needs more investigation. + } + + // Read the binary data using the passed reader and use that to set the ValueObject. + internal object GetCustomValue(BinaryReader reader, Type propertyType, short serializerId, BamlRecordReader bamlRecordReader) + { + Debug.Assert(!ValueObjectSet); + + // Handle enums and bools here directly. + // Otherwise call the known custom serializers directly. + switch (serializerId) + { + case (short)KnownElements.EnumConverter: + + uint enumBits; + if (_valueObject == null) + { + // if no raw value has been read in yet, read it now + // from the baml stream. + enumBits = reader.ReadUInt32(); + } + else + { + // raw value has been read in earlier, so try to resolve into + // an actual enum value now. + enumBits = (uint)_valueObject; + } + + if (propertyType.IsEnum) + { + // property Type is an enum, so raw value can be resolved now. + _valueObject = Enum.ToObject(propertyType, enumBits); + ValueObjectSet = true; + IsRawEnumValueSet = false; + } + else + { + // property Type is not available yet, so raw value cannot + // be resolved now. Store it and try later. + _valueObject = enumBits; + ValueObjectSet = false; + IsRawEnumValueSet = true; + } + + return _valueObject; + + case (short)KnownElements.BooleanConverter: + + byte boolByte = reader.ReadByte(); + _valueObject = boolByte == 1; + break; + + case (short)KnownElements.XamlBrushSerializer: + + // Don't bother creating a XamlBrushSerializer instance & calling ConvertCustomBinaryToObject + // on it since that just calls SCB directly liek below. This saves big on perf. + _valueObject = SolidColorBrush.DeserializeFrom(reader, bamlRecordReader.TypeConvertContext); + break; + + case (short)KnownElements.XamlPathDataSerializer: + + _valueObject = XamlPathDataSerializer.StaticConvertCustomBinaryToObject(reader); + break; + + case (short)KnownElements.XamlPoint3DCollectionSerializer: + + _valueObject = XamlPoint3DCollectionSerializer.StaticConvertCustomBinaryToObject(reader); + break; + + case (short)KnownElements.XamlVector3DCollectionSerializer: + + _valueObject = XamlVector3DCollectionSerializer.StaticConvertCustomBinaryToObject(reader); + break; + + case (short)KnownElements.XamlPointCollectionSerializer: + + _valueObject = XamlPointCollectionSerializer.StaticConvertCustomBinaryToObject(reader); + break; + + case (short)KnownElements.XamlInt32CollectionSerializer: + + _valueObject = XamlInt32CollectionSerializer.StaticConvertCustomBinaryToObject(reader); + break; + + default: + Debug.Assert (false, "Unknown custom serializer"); + return null; + } + + ValueObjectSet = true; + return _valueObject; + } + + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPropertyCustomRecord newRecord = (BamlPropertyCustomRecord)record; + newRecord._valueObject = _valueObject; + newRecord._attributeId = _attributeId; + newRecord._serializerTypeId = _serializerTypeId; + } + +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyCustom; } + } + + internal short AttributeId + { + get { return _attributeId; } + set { _attributeId = value; } + } + + // ID of this serializer type. Referenced in other baml records where a + // Type is needed. + internal short SerializerTypeId + { + get { return _serializerTypeId; } + set { _serializerTypeId = value; } + } + + // The following properties are NOT written to the BAML stream. + +#if !PBTCOMPILER + // Value of the converted object. + internal object ValueObject + { + get { return _valueObject; } + set { _valueObject = value; } + } + + // Return true if GetCustomValue has been called, indicating that + // a conversion from binary custom data to a ValueObject has occurred. + internal bool ValueObjectSet + { + get { return _flags[_isValueSetSection] == 1 ? true : false; } + set { _flags[_isValueSetSection] = value ? 1 : 0; } + } + + internal bool IsValueTypeId + { + get { return _flags[_isValueTypeIdSection] == 1 ? true : false; } + set { _flags[_isValueTypeIdSection] = value ? 1 : 0; } + } + + // true if only the raw value of enum has been read as it cannot yet be + // converted into an enum as the Type is not available yet. + internal bool IsRawEnumValueSet + { + get { return _flags[_isRawEnumValueSetSection] == 1 ? true : false; } + set { _flags[_isRawEnumValueSetSection] = value ? 1 : 0; } + } + + object _valueObject; + + // Allocate space in _flags. + private static BitVector32.Section _isValueSetSection + = BitVector32.CreateSection(1, BamlVariableSizedRecord.LastFlagsSection); + + // Allocate space in _flags. + private static BitVector32.Section _isValueTypeIdSection + = BitVector32.CreateSection(1, _isValueSetSection); + + // Allocate space in _flags. + private static BitVector32.Section _isRawEnumValueSetSection + = BitVector32.CreateSection(1, _isValueTypeIdSection); + + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _isRawEnumValueSetSection; } + } +#endif + +#endregion Properties + +#region Data + + internal static readonly short TypeIdValueMask = 0x4000; + + short _attributeId = 0; + short _serializerTypeId = 0; + +#endregion Data + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyArrayEndRecord : BamlRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyArrayEnd; } + } + +#endregion Properties + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlConstructorParametersStartRecord : BamlRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.ConstructorParametersStart; } + } + +#endregion Properties + + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlConstructorParametersEndRecord : BamlRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.ConstructorParametersEnd; } + } + +#endregion Properties + + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlConstructorParameterTypeRecord : BamlRecord + { + #region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + TypeId = bamlBinaryReader.ReadInt16(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(TypeId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlConstructorParameterTypeRecord newRecord = (BamlConstructorParameterTypeRecord)record; + newRecord._typeId = _typeId; + } +#endif + + #endregion Methods + + #region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.ConstructorParameterType; } + } + + internal short TypeId + { + get { return _typeId; } + set { _typeId = value; } + } + + internal override Int32 RecordSize + { + get { return 2; } + set { Debug.Assert (value == -1, "Wrong size set for complex prop record"); } + } + + #endregion Properties + + #region Data + short _typeId = 0; + #endregion Data + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyIListEndRecord : BamlRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyIListEnd; } + } + +#endregion Properties + + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyIDictionaryEndRecord : BamlRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyIDictionaryEnd; } + } + +#endregion Properties + + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyComplexEndRecord : BamlRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyComplexEnd; } + } + +#endregion Properties + + } + + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyArrayStartRecord : BamlPropertyComplexStartRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyArrayStart; } + } + +#endregion Properties + + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyIListStartRecord : BamlPropertyComplexStartRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyIListStart; } + } + +#endregion Properties + + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlPropertyIDictionaryStartRecord : BamlPropertyComplexStartRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyIDictionaryStart; } + } + +#endregion Properties + + } + + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlRoutedEventRecord : BamlStringValueRecord + { + +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AttributeId = bamlBinaryReader.ReadInt16(); + Value = bamlBinaryReader.ReadString(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(AttributeId); + bamlBinaryWriter.Write(Value); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlRoutedEventRecord newRecord = (BamlRoutedEventRecord)record; + newRecord._attributeId = _attributeId; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.RoutedEvent; } + } + + internal short AttributeId + { + get { return _attributeId; } +#if !PBTCOMPILER + set { _attributeId = value; } +#endif + } + +#endregion Properties + +#region Data + + short _attributeId = -1; + +#endregion Data + } + + + // A section of literal content. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlLiteralContentRecord : BamlStringValueRecord + { + +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + Value = bamlBinaryReader.ReadString(); + + // TODO - peterost - Why are these stored? They aren't needed and + // should be removed with an M8 breaking change, and + // then remove this method. + Int32 _lineNumber = bamlBinaryReader.ReadInt32(); + Int32 _linePosition = bamlBinaryReader.ReadInt32(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(Value); + + // TODO - peterost - Why are these stored? They aren't needed and + // should be removed with an M8 breaking change, and + // then remove this method. + bamlBinaryWriter.Write((Int32)0); + bamlBinaryWriter.Write((Int32)0); + } + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.LiteralContent; } + } + +#endregion Properties + + } + + // An record for the connection id that the (Style)BamlRecordReader uses to + // hookup an ID or event on any element in the object tree or Style visual tree. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlConnectionIdRecord : BamlRecord + { +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + ConnectionId = bamlBinaryReader.ReadInt32(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(ConnectionId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlConnectionIdRecord newRecord = (BamlConnectionIdRecord)record; + newRecord._connectionId = _connectionId; + } +#endif + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.ConnectionId; } + } + + // Id of the type of this object + internal Int32 ConnectionId + { + get { return _connectionId; } + set { _connectionId = value; } + } + + internal override Int32 RecordSize + { + get { return 4; } + set { Debug.Assert(value == -1, "Wrong size set for element record"); } + } + + Int32 _connectionId = -1; + } + + // An object record in the object tree. This can be a CLR + // object or a DependencyObject. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlElementStartRecord : BamlRecord + { + +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + TypeId = bamlBinaryReader.ReadInt16(); + byte flags = bamlBinaryReader.ReadByte(); + CreateUsingTypeConverter = (flags & 1) != 0; + IsInjected = (flags & 2) != 0; + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(TypeId); + byte flags = (byte)((CreateUsingTypeConverter ? 1 : 0) | (IsInjected ? 2 : 0)); + bamlBinaryWriter.Write(flags); + } + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.ElementStart; } + } + + // Id of the type of this object + internal short TypeId + { + + get + { + short value = (short) _flags[_typeIdLowSection]; + value |= (short) (_flags[_typeIdHighSection] << 8); + + return value; + } + + set + { + _flags[_typeIdLowSection] = (short) (value & 0xff); + _flags[_typeIdHighSection] = (short) ((value & 0xff00) >> 8); + } + + + } + + // Whether this object instance is expected to be created via TypeConverter + internal bool CreateUsingTypeConverter + { + get + { + return _flags[_useTypeConverter] == 1 ? true : false; + } + + set + { + _flags[_useTypeConverter] = value ? 1 : 0; + } + } + + // Whether this element start record is just an injected tag that should not be processed + internal bool IsInjected + { + get + { + return _flags[_isInjected] == 1 ? true : false; + } + + set + { + _flags[_isInjected] = value ? 1 : 0; + } + } + + internal override Int32 RecordSize + { + get { return 3; } + set { Debug.Assert(value == -1, "Wrong size set for element record"); } + } + +#endregion Properties + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} typeId={1}", + RecordType, GetTypeName(TypeId)); + } +#endif + + + // Allocate space in _flags. + // BitVector32 doesn't support 16 bit sections, so we have to break + // it up into 2 sections. + + private static BitVector32.Section _typeIdLowSection + = BitVector32.CreateSection( (short)0xff, BamlRecord.LastFlagsSection ); + + private static BitVector32.Section _typeIdHighSection + = BitVector32.CreateSection( (short)0xff, _typeIdLowSection ); + + private static BitVector32.Section _useTypeConverter + = BitVector32.CreateSection( 1, _typeIdHighSection ); + + private static BitVector32.Section _isInjected + = BitVector32.CreateSection( 1, _useTypeConverter ); + + + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _isInjected; } + } + } + + + + //+---------------------------------------------------------------------------------------------------------------- + // + // BamlNamedElementStartRecord + // + // This is a BamlElementStartRecord that also carries an element name. + // + // This is currently internal, used only for templates. The original intent for this record was that + // it become the new design for named objects; any object with an x:Name set, would have that name + // incorporated into the element start record. But that design did not happen, instead the + // property attribute are re-ordered such that the name always immediately follows the element + // start record. So this should be removed, and the template code updated accordingly. (And in fact, + // the template design should be updated so as not to be reliant on naming, as that is too fragile.) + // + //+---------------------------------------------------------------------------------------------------------------- +#if !PBTCOMPILER + internal class BamlNamedElementStartRecord : BamlElementStartRecord + { + +#region Methods + + #if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + TypeId = bamlBinaryReader.ReadInt16(); + RuntimeName = bamlBinaryReader.ReadString(); + } + #endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(TypeId); + + if( RuntimeName != null ) + { + bamlBinaryWriter.Write(RuntimeName); + } + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlNamedElementStartRecord newRecord = (BamlNamedElementStartRecord)record; + newRecord._isTemplateChild = _isTemplateChild; + newRecord._runtimeName = _runtimeName; + } +#endif + +#endregion Methods + +#region Properties + + internal string RuntimeName + { + get { return _runtimeName; } + set { _runtimeName = value; } + } + + // This flag is used by templates to indicate that an ElementStart + // record is for an object that will be a template child. We had to add + // this to allow some validation during template application. This isn't + // a good solution, because we shouldn't have this record understanding + // template children. But the long-term plan is to break the template design + // away from a dependence on names, at which point this whole BamlNamedElementStartRecord + // will go away. + private bool _isTemplateChild = false; + internal bool IsTemplateChild + { + get { return _isTemplateChild; } + set { _isTemplateChild = value; } + } + +#endregion Properties + + +#region Data + + // Id of the type of this object + string _runtimeName = null; + +#endregion Data + } +#endif + + // Marks a block that has deferable content. This record contains the size + // of the deferable section, excluding the start and end records themselves. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlDeferableContentStartRecord : BamlRecord + { +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + ContentSize = bamlBinaryReader.ReadInt32(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + _contentSizePosition = bamlBinaryWriter.Seek(0, SeekOrigin.Current); + bamlBinaryWriter.Write(ContentSize); + } + + // Update the size of the content contained between the end of the start + // record and the beginning of the end record. The size of the content is + // usually not known when the start record is written out. + internal void UpdateContentSize( + Int32 contentSize, + BinaryWriter bamlBinaryWriter) + { + Debug.Assert(_contentSizePosition != -1, + "Must call WriteRecordData before updating content size"); + + // Use relative positions to reduce the possibility of truncation, + // since Seek takes a 32 bit int, but position is a 64 bit int. + Int64 existingPosition = bamlBinaryWriter.Seek(0, SeekOrigin.Current); + Int32 deltaPosition = (Int32)(_contentSizePosition-existingPosition); + + bamlBinaryWriter.Seek(deltaPosition, SeekOrigin.Current); + bamlBinaryWriter.Write(contentSize); + bamlBinaryWriter.Seek((int)(-ContentSizeSize-deltaPosition), SeekOrigin.Current); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlDeferableContentStartRecord newRecord = (BamlDeferableContentStartRecord)record; + newRecord._contentSize = _contentSize; + newRecord._contentSizePosition = _contentSizePosition; + newRecord._valuesBuffer = _valuesBuffer; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.DeferableContentStart; } + } + + internal Int32 ContentSize + { + get { return _contentSize; } +#if !PBTCOMPILER + set { _contentSize = value; } +#endif + } + + internal override Int32 RecordSize + { + get { return 4; } + set { Debug.Assert(value == -1, "Wrong size set for element record"); } + } + +#if !PBTCOMPILER + + /// + /// For the case of a ResourceDictionary inside template content, we read + /// the dictionary values into a byte array while creating the template + /// content. Later during template instantiation when the dictionary instance + /// is created we use this buffer to create a memory stream so that the + /// ResourceDictionary can use it to RealizeDeferredContent. This is required + /// because at template instantiation time we do not have a stream to work with. + /// The reader operates on a linked list of BamlRecords. + /// + internal byte[] ValuesBuffer + { + get { return _valuesBuffer; } + set { _valuesBuffer = value; } + } +#endif + +#endregion Properties + + +#region Data + + // Size of the ContentSize field written out to the baml stream. This + // must be kept in sync with the size of the _contentSize field. + const Int64 ContentSizeSize = 4; + + // Size of the content between the end of the start record and the + // beginning of the end record for this element. + Int32 _contentSize = - 1; + + // Absolute position in the stream where ContentSize is written. + Int64 _contentSizePosition = -1; + +#if !PBTCOMPILER + + byte[] _valuesBuffer; + +#endif + +#endregion Data + } + + //+---------------------------------------------------------------------------------------------------------------- + // + // BamlStaticResourceStartRecord + // + // This record marks the start of a StaticResourceExtension within the header for a deferred section. + // + //+---------------------------------------------------------------------------------------------------------------- + + internal class BamlStaticResourceStartRecord : BamlElementStartRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.StaticResourceStart; } + } + +#endregion Properties + + } + + //+---------------------------------------------------------------------------------------------------------------- + // + // BamlStaticResourceEndRecord + // + // This record marks the end of a StaticResourceExtension within the header for a deferred section. + // + //+---------------------------------------------------------------------------------------------------------------- + + internal class BamlStaticResourceEndRecord : BamlElementEndRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.StaticResourceEnd; } + } + +#endregion Properties + + } + + //+---------------------------------------------------------------------------------------------------------------- + // + // BamlOptimizedStaticResourceRecord + // + // This record represents an optimized StaticResourceExtension within the header for a deferred section. + // + //+---------------------------------------------------------------------------------------------------------------- + + internal class BamlOptimizedStaticResourceRecord : BamlRecord, IOptimizedMarkupExtension + { + +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + byte flags = bamlBinaryReader.ReadByte(); + ValueId = bamlBinaryReader.ReadInt16(); + + IsValueTypeExtension = (flags & TypeExtensionValueMask) != 0; + IsValueStaticExtension = (flags & StaticExtensionValueMask) != 0; + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + byte flags = 0; + if (IsValueTypeExtension) + { + flags |= TypeExtensionValueMask; + } + else if (IsValueStaticExtension) + { + flags |= StaticExtensionValueMask; + } + bamlBinaryWriter.Write(flags); + bamlBinaryWriter.Write(ValueId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlOptimizedStaticResourceRecord newRecord = (BamlOptimizedStaticResourceRecord)record; + newRecord._valueId = _valueId; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.OptimizedStaticResource; } + } + + public short ExtensionTypeId + { + get { return (short)KnownElements.StaticResourceExtension; } + } + + // StringId if the value is a string + // TypeId if the value is a TypeExtension + // AttributeId of the member if the value is a StaticExtension + public short ValueId + { + get { return _valueId; } + set { _valueId = value; } + } + + internal override Int32 RecordSize + { + get { return 3; } + set { Debug.Assert(value == -1, "Wrong size set for complex prop record"); } + } + + // If the value is itself a simple TypeExtension + public bool IsValueTypeExtension + { + get { return _flags[_isValueTypeExtensionSection] == 1 ? true : false; } + set { _flags[_isValueTypeExtensionSection] = value ? 1 : 0; } + } + + // If the value is itself a simple StaticExtension + public bool IsValueStaticExtension + { + get { return _flags[_isValueStaticExtensionSection] == 1 ? true : false; } + set { _flags[_isValueStaticExtensionSection] = value ? 1 : 0; } + } + +#endregion Properties + +#region Data + + short _valueId = 0; + + private static readonly byte TypeExtensionValueMask = 0x01; + private static readonly byte StaticExtensionValueMask = 0x02; + + // Allocate space in _flags. + private static BitVector32.Section _isValueTypeExtensionSection + = BitVector32.CreateSection(1, BamlRecord.LastFlagsSection); + + private static BitVector32.Section _isValueStaticExtensionSection + = BitVector32.CreateSection(1, _isValueTypeExtensionSection); + + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _isValueStaticExtensionSection; } + } + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} extn(StaticResourceExtension) valueId({1})", + RecordType, _valueId); + } +#endif + +#endregion Data + + + } + + //+---------------------------------------------------------------------------------------------------------------- + // + // BamlStaticResourceIdRecord + // + // This BamlRecord is an identifier for a StaticResourceExtension within the header for a deferred section. + // + //+---------------------------------------------------------------------------------------------------------------- + + internal class BamlStaticResourceIdRecord : BamlRecord + { + +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + StaticResourceId = bamlBinaryReader.ReadInt16(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(StaticResourceId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlStaticResourceIdRecord newRecord = (BamlStaticResourceIdRecord)record; + newRecord._staticResourceId = _staticResourceId; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.StaticResourceId; } + } + + internal override Int32 RecordSize + { + get { return 2; } + set { Debug.Assert(value == -1, "Wrong size set for complex prop record"); } + } + + internal short StaticResourceId + { + get { return _staticResourceId; } + set { _staticResourceId = value; } + } + +#endregion Properties + + +#region Data + + short _staticResourceId = -1; + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} staticResourceId({1})", + RecordType, StaticResourceId); + } +#endif + + +#endregion Data + + } + + //+---------------------------------------------------------------------------------------------------------------- + // + // BamlPropertyWithStaticResourceIdRecord + // + // This BamlRecord represents a BamlPropertyRecord with a StaticResourceId as place holder for + // a StaticResourceExtension within a deferred section. + // + //+---------------------------------------------------------------------------------------------------------------- + + internal class BamlPropertyWithStaticResourceIdRecord : BamlStaticResourceIdRecord + { + +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AttributeId = bamlBinaryReader.ReadInt16(); + StaticResourceId = bamlBinaryReader.ReadInt16(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(AttributeId); + bamlBinaryWriter.Write(StaticResourceId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlPropertyWithStaticResourceIdRecord newRecord = (BamlPropertyWithStaticResourceIdRecord)record; + newRecord._attributeId = _attributeId; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.PropertyWithStaticResourceId; } + } + + internal override Int32 RecordSize + { + get { return 4; } + set { Debug.Assert(value == -1, "Wrong size set for complex prop record"); } + } + + // Id of the property whose value is the simple SR + internal short AttributeId + { + get { return _attributeId; } + set { _attributeId = value; } + } + +#endregion Properties + +#region Data + + short _attributeId = -1; + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} attr({1}) staticResourceId({2})", + RecordType, AttributeId, StaticResourceId); + } +#endif + +#endregion Data + + } + + + // Text content between the begin and end tag of an element. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlTextRecord : BamlStringValueRecord + { +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.Text; } + } + +#endregion Properties + } + + // This is a text record within a [Static/Dynamic]ResourceExtension. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlTextWithIdRecord : BamlTextRecord + { +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + ValueId = bamlBinaryReader.ReadInt16(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(ValueId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlTextWithIdRecord newRecord = (BamlTextWithIdRecord)record; + newRecord._valueId = _valueId; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.TextWithId; } + } + + internal Int16 ValueId + { + get { return _valueId; } + set { _valueId = value; } + } + +#endregion Properties + +#region Data + Int16 _valueId; +#endregion Data + } + + // Text content between the begin and end tag of an element that will be parsed using a type converter. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlTextWithConverterRecord : BamlTextRecord + { +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + base.LoadRecordData(bamlBinaryReader); + ConverterTypeId = bamlBinaryReader.ReadInt16(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + base.WriteRecordData(bamlBinaryWriter); + bamlBinaryWriter.Write(ConverterTypeId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlTextWithConverterRecord newRecord = (BamlTextWithConverterRecord)record; + newRecord._converterTypeId = _converterTypeId; + } +#endif + +#endregion Methods + +#region Properties + + // The following are stored in the baml stream + + // ID of this type converter. Referenced in other baml records where a + // Type is needed. + internal short ConverterTypeId + { + get { return _converterTypeId; } + set { _converterTypeId = value; } + } + + // Additional properties not stored in the baml stream + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.TextWithConverter; } + } + +#endregion Properties + +#region Data + + short _converterTypeId = 0; + +#endregion Data + + } + + // Marks the start of a Baml document. This must always be the first + // record in a BAML stream. It contains version information, and other + // document wide directives. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlDocumentStartRecord : BamlRecord + { +#region Methods + + // Writes data at the current position. The seek pointer points + // to byte after the end of record when done. + internal override void Write(BinaryWriter bamlBinaryWriter) + { + // Remember the file location of this baml record. This + // is needed if we have to come back later to update the sync mode. + if (FilePos == -1 && bamlBinaryWriter != null) + { + FilePos = bamlBinaryWriter.Seek(0,SeekOrigin.Current); + } + + base.Write(bamlBinaryWriter); + } + + // Adjust seeks pointer to this Record and updates the data. + // Then sets seek pointer pack to original. + // NOTE: This will ONLY work for file sizes under 2 gig. This is + // not a problem for current useage, since this is mostly used + // when updating LoadAsync attribute on the DocumentStart record, + // which is usually set on the first element in the xaml file. + internal virtual void UpdateWrite(BinaryWriter bamlBinaryWriter) + { + // default implementation, class should override if + // wants to optimize to only update dirty data. + long currentPosiition = bamlBinaryWriter.Seek(0,SeekOrigin.Current); + + // seek to original record position. + + Debug.Assert(FilePos != -1,"UpdateWrite called but Write Never was"); + + // Note: This only works for files up to 2 gig in length. + // This is not a new restriction, but it should be + // fixed to work with larger files... + bamlBinaryWriter.Seek((int)FilePos,SeekOrigin.Begin); + Write(bamlBinaryWriter); + bamlBinaryWriter.Seek( (int) currentPosiition,SeekOrigin.Begin); + } + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + LoadAsync = bamlBinaryReader.ReadBoolean(); + MaxAsyncRecords = bamlBinaryReader.ReadInt32(); + DebugBaml = bamlBinaryReader.ReadBoolean(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(LoadAsync); + bamlBinaryWriter.Write(MaxAsyncRecords); + bamlBinaryWriter.Write(DebugBaml); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlDocumentStartRecord newRecord = (BamlDocumentStartRecord)record; + newRecord._maxAsyncRecords = _maxAsyncRecords; + newRecord._loadAsync = _loadAsync; + newRecord._filePos = _filePos; + newRecord._debugBaml = _debugBaml; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.DocumentStart; } + } + + internal bool LoadAsync + { + get { return _loadAsync; } +#if !PBTCOMPILER + set { _loadAsync = value; } +#endif + } + + internal int MaxAsyncRecords + { + get { return _maxAsyncRecords; } + set { _maxAsyncRecords = value; } + } + + // Position in the baml file stream + internal long FilePos + { + get { return _filePos; } + set { _filePos = value; } + } + + // Are there Debug Baml Records in this Baml Stream + internal bool DebugBaml + { + get { return _debugBaml; } + set { _debugBaml = value; } + } + +#endregion Properties + +#region Data + int _maxAsyncRecords = -1; + bool _loadAsync = false; + long _filePos = -1; + bool _debugBaml = false; +#endregion Data + } + + // This marks the end tag of an element + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlElementEndRecord : BamlRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.ElementEnd; } + } + +#endregion Properties + + } + + // This marks the start tag of an element being used as the key for an IDictionary + internal class BamlKeyElementStartRecord : BamlDefAttributeKeyTypeRecord, IBamlDictionaryKey + { + internal BamlKeyElementStartRecord() + { + Pin(); // Don't allow this record to be recycled in the read cache. + } + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.KeyElementStart; } + } + +#endregion Properties + + } + + // This marks the end tag of an element being used as the key for an IDictionary + internal class BamlKeyElementEndRecord : BamlElementEndRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.KeyElementEnd; } + } + +#endregion Properties + + } + + // This marks the end of the baml stream, or document. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlDocumentEndRecord : BamlRecord + { + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.DocumentEnd; } + } + +#endregion Properties + + } + + // The following records are used internally in the baml stream to + // define attribute (eg - property), type and assembly information + // for records that follow later on in the stream. They are never + // publically exposed + + // Information about an assembly where a type is defined + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlAssemblyInfoRecord : BamlVariableSizedRecord + { + internal BamlAssemblyInfoRecord() + { + Pin(); // Don't allow this record to be recycled in the read cache. + AssemblyId = -1; + } + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AssemblyId = bamlBinaryReader.ReadInt16(); + AssemblyFullName = bamlBinaryReader.ReadString(); + } +#endif + + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + // write out an int for record size but we'll go back and fill + bamlBinaryWriter.Write(AssemblyId); + bamlBinaryWriter.Write(AssemblyFullName); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlAssemblyInfoRecord newRecord = (BamlAssemblyInfoRecord)record; + newRecord._assemblyFullName = _assemblyFullName; + newRecord._assembly = _assembly; + } +#endif + +#endregion Methods + +#region Properties + + // The following are stored in the baml stream + + // ID of this assembly + internal short AssemblyId + { + + get + { + short value = (short) _flags[_assemblyIdLowSection]; + value |= (short) (_flags[_assemblyIdHighSection] << 8); + + return value; + } + + set + { + _flags[_assemblyIdLowSection] = (short) (value & 0xff); + _flags[_assemblyIdHighSection] = (short) ((value & 0xff00) >> 8); + } + + } + + // Allocate space in _flags. + // BitVector32 doesn't support 16 bit sections, so we have to break + // it up into 2 sections. + + private static BitVector32.Section _assemblyIdLowSection + = BitVector32.CreateSection( (short)0xff, BamlVariableSizedRecord.LastFlagsSection ); + + private static BitVector32.Section _assemblyIdHighSection + = BitVector32.CreateSection( (short)0xff, _assemblyIdLowSection ); + +#if !PBTCOMPILER + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _assemblyIdHighSection; } + } +#endif + + // Full name of this assembly, excluding any suffix. This has + // the format "AssemblyName, Version, Culture, PublicKeyToken" when we + // have a true full name. Sometimes we aren't given the full assembly + // name, in which case the full name is the same as the short name. + internal string AssemblyFullName + { + get { return _assemblyFullName; } + set { _assemblyFullName = value; } + } + + // The following are not part of the BAML stream + + // Identify type of record + internal override BamlRecordType RecordType + { + get { return BamlRecordType.AssemblyInfo; } + } + + // The actual loaded assembly + internal Assembly Assembly + { + get { return _assembly; } + set { _assembly = value; } + } + + +#endregion Properties + + +#region Data + + string _assemblyFullName; + Assembly _assembly; + +#endregion Data + } + + // Information about a type for an element, object or property + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlTypeInfoRecord : BamlVariableSizedRecord + { + internal BamlTypeInfoRecord() + { + Pin(); // Don't allow this record to be recycled in the read cache. + TypeId = -1; + } + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + TypeId = bamlBinaryReader.ReadInt16(); + AssemblyId = bamlBinaryReader.ReadInt16(); + TypeFullName = bamlBinaryReader.ReadString(); + + // Note that the upper 4 bits of the AssemblyId are used for flags + _typeInfoFlags = (TypeInfoFlags)(AssemblyId >> 12); + _assemblyId &= 0x0FFF; + } +#endif + + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + // write out an int for record size but we'll go back and fill + bamlBinaryWriter.Write(TypeId); + // Note that the upper 4 bits of the AssemblyId are used for flags + bamlBinaryWriter.Write((short)(((ushort)AssemblyId) | (((ushort)_typeInfoFlags) << 12))); + bamlBinaryWriter.Write(TypeFullName); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlTypeInfoRecord newRecord = (BamlTypeInfoRecord)record; + newRecord._typeInfoFlags = _typeInfoFlags; + newRecord._assemblyId = _assemblyId; + newRecord._typeFullName = _typeFullName; + newRecord._type = _type; + } +#endif + +#endregion Methods + +#region Properties + + // The following are stored in the baml stream + + // ID of this type. Refenced in other baml records where a + // Type is needed. + internal short TypeId + { + + get + { + short value = (short) _flags[_typeIdLowSection]; + value |= (short) (_flags[_typeIdHighSection] << 8); + + return value; + } + + set + { + _flags[_typeIdLowSection] = (short) (value & 0xff); + _flags[_typeIdHighSection] = (short) ((value & 0xff00) >> 8); + } + + + } + + // Assembly id of the assembly where this type is defined. + // NOTE: This is always positive in BAML files, but can be set + // to -1 for known types when created programmatically. + internal short AssemblyId + { + get { return _assemblyId; } + set + { + // Make sure we don't intrude on the Flags portion of the assembly ID + if (_assemblyId > 0x0FFF) + { + throw new XamlParseException(SR.Get(SRID.ParserTooManyAssemblies)); + } + _assemblyId = value; + } + } + + // Fully qualified name of type, including namespace + internal string TypeFullName + { + get { return _typeFullName; } + set { _typeFullName = value; } + } + + // Additional properties not stored in the baml stream + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.TypeInfo; } + } + +#if !PBTCOMPILER + // Actual type. Filled in here when xaml is used to create + // a tree, and the token reader knows the type + internal Type Type + { + get { return _type; } + set { _type = value; } + } + + // Extract the namespace from the type full name and return + // it. We are assuming here that the type full name has a single + // classname at the end and we are not refering to a nested class... + internal string ClrNamespace + { + get + { + int periodIndex = _typeFullName.LastIndexOf('.'); + return periodIndex > 0 ? + _typeFullName.Substring(0, periodIndex) : + string.Empty; + } + } +#endif + + // True if there is a serializer associated with this type + internal virtual bool HasSerializer + { + get { return false; } + } + + internal bool IsInternalType + { +#if !PBTCOMPILER + get + { + return ((_typeInfoFlags & TypeInfoFlags.Internal) == TypeInfoFlags.Internal); + } +#endif + + set + { + // Don't allow resetting to false (i.e. converting back top public if + // it becomes non-public, for added safety. + if (value) + { + _typeInfoFlags |= TypeInfoFlags.Internal; + } + } + } + +#endregion Properties + +#region Data + + // Allocate space in _flags. + // BitVector32 doesn't support 16 bit sections, so we have to break + // it up into 2 sections. + + private static BitVector32.Section _typeIdLowSection + = BitVector32.CreateSection( (short)0xff, BamlVariableSizedRecord.LastFlagsSection ); + + private static BitVector32.Section _typeIdHighSection + = BitVector32.CreateSection( (short)0xff, _typeIdLowSection ); + +#if !PBTCOMPILER + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _typeIdHighSection; } + } +#endif + + + // Flags contained in TypeInfo that give additional information + // about the type that is determined at compile time. + [Flags] + private enum TypeInfoFlags : byte + { + Internal = 0x1, + UnusedTwo = 0x2, + UnusedThree = 0x4, + } + + TypeInfoFlags _typeInfoFlags = 0; + short _assemblyId = -1; + string _typeFullName; +#if !PBTCOMPILER + Type _type; +#endif + +#endregion Data + + + } + + // Type info record for a type that has a custom serializer associated with it. + // This gives the serializer type that will be used when deserializing this type + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlTypeInfoWithSerializerRecord : BamlTypeInfoRecord + { + internal BamlTypeInfoWithSerializerRecord() + { + Pin(); // Don't allow this record to be recycled in the read cache. + } + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + base.LoadRecordData(bamlBinaryReader); + SerializerTypeId = bamlBinaryReader.ReadInt16(); + } +#endif + + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + base.WriteRecordData(bamlBinaryWriter); + bamlBinaryWriter.Write(SerializerTypeId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlTypeInfoWithSerializerRecord newRecord = (BamlTypeInfoWithSerializerRecord)record; + newRecord._serializerTypeId = _serializerTypeId; + newRecord._serializerType = _serializerType; + } +#endif + +#endregion Methods + +#region Properties + + // The following are stored in the baml stream + + // ID of this type. Refenced in other baml records where a + // Type is needed. + internal short SerializerTypeId + { + get { return _serializerTypeId; } + set { _serializerTypeId = value; } + } + + // Additional properties not stored in the baml stream + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.TypeSerializerInfo; } + } + +#if !PBTCOMPILER + // Actual type of associated serializer. Filled in here when xaml is used to create + // a tree, and the token reader knows the type of the serializer, or + // when we are reading the baml file and have determined the + // serializer type. + internal Type SerializerType + { + get { return _serializerType; } + set { _serializerType = value; } + } +#endif + + // True if there is a serializer associated with this type. A serializer + // will never be the first type object in a baml file, so its type ID will + // never be 0. Any other ID indicates we have a serializer. + internal override bool HasSerializer + { + get + { + Debug.Assert( SerializerTypeId != 0 ); + return true; + } + } + +#endregion Properties + +#region Data + + short _serializerTypeId = 0; +#if !PBTCOMPILER + Type _serializerType; +#endif + +#endregion Data + + } + + // Used for mapping properties and events to an owner type, given the + // name of the attribute. Note that Attribute is used for historical + // reasons and for similarities to Xml attributes. For us attributes + // are just properties and events. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlAttributeInfoRecord : BamlVariableSizedRecord + { + internal BamlAttributeInfoRecord() + { + Pin(); // Don't allow this record to be recycled in the read cache. + AttributeUsage = BamlAttributeUsage.Default; + } + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AttributeId = bamlBinaryReader.ReadInt16(); + OwnerTypeId = bamlBinaryReader.ReadInt16(); + AttributeUsage = (BamlAttributeUsage)bamlBinaryReader.ReadByte(); + Name = bamlBinaryReader.ReadString(); + } +#endif + + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + // write out an int for record size but we'll go back and fill + bamlBinaryWriter.Write(AttributeId); + bamlBinaryWriter.Write(OwnerTypeId); + bamlBinaryWriter.Write((Byte)AttributeUsage); + bamlBinaryWriter.Write(Name); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlAttributeInfoRecord newRecord = (BamlAttributeInfoRecord)record; + newRecord._ownerId = _ownerId; + newRecord._attributeId = _attributeId; + newRecord._name = _name; + newRecord._ownerType = _ownerType; + newRecord._Event = _Event; + newRecord._dp = _dp; + newRecord._ei = _ei; + newRecord._pi = _pi; + newRecord._smi = _smi; + newRecord._gmi = _gmi; + newRecord._dpOrMiOrPi = _dpOrMiOrPi; + } +#endif + +#endregion Methods + +#region Properties + + // The following 3 properties are stored in the Baml file and are read and + // written by the BamlRecordReader and BamlXamlNodeWriter + + internal short OwnerTypeId + { + get { return _ownerId; } + set { _ownerId = value; } + } + + internal short AttributeId + { + set { _attributeId = value; } + get { return _attributeId; } + } + + internal string Name + { + get { return _name; } + set { _name = value; } + } + + // The following properties are derived at runtime from the above 3 properties using + // the Mapper. Which are set depends on the attribute and the context in which it is + // used. + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.AttributeInfo; } + } + +#if !PBTCOMPILER + // Return type of property. Note that this uses the same logic as + // Mapper.GetPropertyType but uses the cached values of DP, PropInfo + // and AttachedPropertySetter. + internal Type GetPropertyType() + { + Type validType = null; + DependencyProperty dp = DP; + if (dp == null) + { + MethodInfo methodInfo = AttachedPropertySetter; + if (methodInfo == null) + { + PropertyInfo propInfo = PropInfo; + validType = propInfo.PropertyType; + } + else + { + ParameterInfo[] paramInfo = methodInfo.GetParameters(); + validType = paramInfo[1].ParameterType; + } + } + else + { + validType = dp.PropertyType; + } + return validType; + } +#endif + + /// + /// Set the PropertyMember, which can is assumed to be a MethodInfo for + /// the static setter method for a DP or a PropertyInfo for the clr property + /// + /// + /// The possibility of having multiple member info cached for an attribute is when a + /// dependency property that does not belong to the default namespace is used in once + /// in a once with a namespace prefix and once without it. When it has a namespace + /// prefix we correctly find the dependency property for it. However when it does not + /// have a namespace prefix it the parser tries to look it up in the default namespace + /// and falls back to using the clr wrapper's property info for it instead. Another + /// scenario that requires caching more than one property info is when a dependency + /// property has both a static settor and a clr wrapper. + /// + internal void SetPropertyMember (object propertyMember) + { + Debug.Assert((propertyMember is MethodInfo) || (propertyMember is PropertyInfo) + || (KnownTypes.Types[(int)KnownElements.DependencyProperty].IsAssignableFrom(propertyMember.GetType())), + "Cache can hold either a MethodInfo and/or a PropertyInfo and/or a DependencyProperty for a given attribute"); + + if (PropertyMember == null) + { + PropertyMember = propertyMember; + } + else + { + // Cache a additional MemberInfo for the given attribute + object[] arr = PropertyMember as object[]; + if (arr == null) + { + arr = new object[3]; + arr[0] = PropertyMember; + arr[1] = propertyMember; + } + else + { + Debug.Assert(arr.Length == 3 && arr[0] != null && arr[1] != null); + arr[2] = propertyMember; + } + } + } + + /// + /// Return the PropertyMember, which can is assumed to be a MethodInfo for + /// the static setter method for a DP or a PropertyInfo for the clr property + /// + /// + /// The possibility of having multiple member info cached for an attribute is when a + /// dependency property that does not belong to the default namespace is used in once + /// in a once with a namespace prefix and once without it. When it has a namespace + /// prefix we correctly find the dependency property for it. However when it does not + /// have a namespace prefix it the parser tries to look it up in the default namespace + /// and falls back to using the clr wrapper's property info for it instead. Another + /// scenario that requires caching more than one property info is when a dependency + /// property has both a static settor and a clr wrapper. + /// + internal object GetPropertyMember(bool onlyPropInfo) + { + if (PropertyMember == null || + PropertyMember is MemberInfo || + KnownTypes.Types[(int)KnownElements.DependencyProperty].IsAssignableFrom(PropertyMember.GetType( )) ) + { + if (onlyPropInfo) + { +#if PBTCOMPILER + return PropertyMember as PropertyInfo; +#else + return PropInfo; +#endif + } + else + { + return PropertyMember; + } + } + else + { + // The attribute has multiple member info. Choose which one to return. + object[] arr = (object[])PropertyMember; + Debug.Assert(arr.Length == 3 && arr[0] != null && arr[1] != null); + + // If someone queries any MemberInfo for the given attribute then we return the + // first member info cached for it. If they are looking specifically for a + // PropertyInfo we try and find them one. + if (onlyPropInfo) + { + if (arr[0] is PropertyInfo) + { + return (PropertyInfo)arr[0]; + } + else if (arr[1] is PropertyInfo) + { + return (PropertyInfo)arr[1]; + } + else + { + return arr[2] as PropertyInfo; + } + } + else + { + return arr[0]; + } + } + } + + // Cached value of the DependencyProperty, MethodInfo for the static setter + // method, or the PropertyInfo for a given property. If this is an + // event, then this is null. + internal object PropertyMember + { + get { return _dpOrMiOrPi; } + set { _dpOrMiOrPi = value; } + } + +#if !PBTCOMPILER + + // The cached type of the owner or declarer of this property + internal Type OwnerType + { + get { return _ownerType; } + set { _ownerType = value; } + } + + // Cached value of the routed event id, if this attribute is for a + // routed event. If not a routed event, this is null. + internal RoutedEvent Event + { + get { return _Event; } + set { _Event = value; } + } + + // Cached value of DP, if available + internal DependencyProperty DP + { + get + { + if (null != _dp) + return _dp; + else + return _dpOrMiOrPi as DependencyProperty; + } + set + { + _dp = value; + if (_dp != null) + { + // Release the other copy of the string + _name = _dp.Name; + } + } + } + + // Cached value of static property setter method info, if available + internal MethodInfo AttachedPropertySetter + { + get + { + return _smi; + } + + set + { + _smi = value; + } + } + + // Cached value of static property getter method info, if available + internal MethodInfo AttachedPropertyGetter + { + get + { + return _gmi; + } + + set + { + _gmi = value; + } + } + + // Cached value of EventInfo, if available + internal EventInfo EventInfo + { + get { return _ei; } + set { _ei = value; } + } + + // Cached value of PropertyInfo, if available + internal PropertyInfo PropInfo + { + get + { + return _pi; + } + set { _pi = value; } + } + + internal bool IsInternal + { + get + { + return _flags[_isInternalSection] == 1 ? true : false; + } + + set + { + _flags[_isInternalSection] = value ? 1 : 0; + } + } +#endif + + // Some attributes have special usage, such as setting the XmlLang and XmlSpace + // strings in the parser context. This is flagged with this property + internal BamlAttributeUsage AttributeUsage + { + get + { + return (BamlAttributeUsage) _flags[_attributeUsageSection]; + } + + set + { + _flags[_attributeUsageSection] = (int) value; + } + } + + + // Allocate space in _flags. + + private static BitVector32.Section _isInternalSection + = BitVector32.CreateSection( 1, BamlVariableSizedRecord.LastFlagsSection ); + + private static BitVector32.Section _attributeUsageSection + = BitVector32.CreateSection( 3, _isInternalSection ); + +#if !PBTCOMPILER + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _attributeUsageSection; } + } +#endif + +#endregion Properties + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} owner={1} attr({2}) is '{3}'", + RecordType, GetTypeName(OwnerTypeId), AttributeId, _name); + } +#endif + +#region Data + + short _ownerId; + short _attributeId; + string _name; + +#if !PBTCOMPILER + Type _ownerType = null; + RoutedEvent _Event = null; + DependencyProperty _dp = null; + EventInfo _ei = null; + PropertyInfo _pi = null; + MethodInfo _smi = null; + MethodInfo _gmi = null; +#endif + + object _dpOrMiOrPi = null; // MethodInfo, PropertyInfo or DependencyProperty + +#endregion Data + } + + // Information about a String that is an entry in the String table. + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlStringInfoRecord : BamlVariableSizedRecord + { + internal BamlStringInfoRecord() + { + Pin(); // Don't allow this record to be recycled in the read cache. + StringId = -1; + } + +#region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + StringId = bamlBinaryReader.ReadInt16(); + Value = bamlBinaryReader.ReadString(); + } +#endif + + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + // write out an int for string Id + bamlBinaryWriter.Write(StringId); + bamlBinaryWriter.Write(Value); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlStringInfoRecord newRecord = (BamlStringInfoRecord)record; + newRecord._value = _value; + } +#endif + +#endregion Methods + +#region Properties + // Resource Identifier pointing to the StringTable Entry + internal short StringId + { + get + { + short value = (short) _flags[_stringIdLowSection]; + value |= (short) (_flags[_stringIdHighSection] << 8); + + return value; + } + + set + { + _flags[_stringIdLowSection] = (short) (value & 0xff); + _flags[_stringIdHighSection] = (short) ((value & 0xff00) >> 8); + } + } + + // Resource String + internal string Value + { + get { return _value; } + set { _value = value; } + } + + // Additional properties not stored in the baml stream + internal override BamlRecordType RecordType + { + get { return BamlRecordType.StringInfo; } + } + + // True if there is a serializer associated with this type + internal virtual bool HasSerializer + { + get { return false; } + } +#endregion Properties + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} stringId({1}='{2}'", + RecordType, StringId, _value); + } +#endif + +#region Data + + + // Allocate space in _flags. + // BitVector32 doesn't support 16 bit sections, so we have to break + // it up into 2 sections. + + private static BitVector32.Section _stringIdLowSection + = BitVector32.CreateSection( (short)0xff, BamlVariableSizedRecord.LastFlagsSection ); + + private static BitVector32.Section _stringIdHighSection + = BitVector32.CreateSection( (short)0xff, _stringIdLowSection ); + +#if !PBTCOMPILER + // This provides subclasses with a referece section to create their own section. + internal new static BitVector32.Section LastFlagsSection + { + get { return _stringIdHighSection; } + } +#endif + + string _value ; +#endregion Data + } + + // Sets the content property context for an element + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlContentPropertyRecord : BamlRecord + { + #region Methods + +#if !PBTCOMPILER + // LoadRecord specific data + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + AttributeId = bamlBinaryReader.ReadInt16(); + } +#endif + + // write record specific Data. + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + // write out an int for attribute Id + bamlBinaryWriter.Write(AttributeId); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlContentPropertyRecord newRecord = (BamlContentPropertyRecord)record; + newRecord._attributeId = _attributeId; + } +#endif + + #endregion Methods + + #region Properties + // Id of the property being set as the context + internal short AttributeId + { + get { return _attributeId; } + set { _attributeId = value; } + } + + // Additional properties not stored in the baml stream + internal override BamlRecordType RecordType + { + get { return BamlRecordType.ContentProperty; } + } + + // True if there is a serializer associated with this type + internal virtual bool HasSerializer + { + get { return false; } + } + #endregion Properties + + #region Data + short _attributeId = -1; + #endregion Data + } + + + // Debugging Linenumber record. Linenumber from the XAML + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlLineAndPositionRecord : BamlRecord + { + +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + LineNumber = (uint) bamlBinaryReader.ReadInt32(); + LinePosition = (uint) bamlBinaryReader.ReadInt32(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(LineNumber); + bamlBinaryWriter.Write(LinePosition); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlLineAndPositionRecord newRecord = (BamlLineAndPositionRecord)record; + newRecord._lineNumber = _lineNumber; + newRecord._linePosition = _linePosition; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.LineNumberAndPosition; } + } + + // Id of the type of this object + internal uint LineNumber + { + get { return _lineNumber; } + set { _lineNumber = value; } + } + + internal uint LinePosition + { + get { return _linePosition; } + set { _linePosition = value; } + } + + internal override Int32 RecordSize + { + get { return 8; } + } + + uint _lineNumber; + uint _linePosition; + +#endregion Properties + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} LineNum={1} Pos={2}", RecordType, LineNumber, LinePosition); + } +#endif + } + + + // Debugging Line Position record. Line Position from the XAML + // + // This code should always be transparent. Meaning you should never add + // SecurityCritical to this section of the code. + // + internal class BamlLinePositionRecord : BamlRecord + { + +#region Methods + +#if !PBTCOMPILER + internal override void LoadRecordData(BinaryReader bamlBinaryReader) + { + LinePosition = (uint) bamlBinaryReader.ReadInt32(); + } +#endif + + internal override void WriteRecordData(BinaryWriter bamlBinaryWriter) + { + bamlBinaryWriter.Write(LinePosition); + } + +#if !PBTCOMPILER + internal override void Copy(BamlRecord record) + { + base.Copy(record); + + BamlLinePositionRecord newRecord = (BamlLinePositionRecord)record; + newRecord._linePosition = _linePosition; + } +#endif + +#endregion Methods + +#region Properties + + internal override BamlRecordType RecordType + { + get { return BamlRecordType.LinePosition; } + } + + internal uint LinePosition + { + get { return _linePosition; } + set { _linePosition = value; } + } + + internal override Int32 RecordSize + { + get { return 4; } + } + + uint _linePosition; + +#endregion Properties + +#if !PBTCOMPILER + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "{0} LinePos={1}", RecordType, LinePosition); + } +#endif + } + + +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlVersionHeader.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlVersionHeader.cs new file mode 100644 index 00000000000..2dc5453cb06 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlVersionHeader.cs @@ -0,0 +1,122 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Globalization; +using System.Diagnostics; + +using MS.Internal.IO.Packaging.CompoundFile; + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + internal class BamlVersionHeader + { + // The current BAML record version. This is incremented whenever + // the BAML format changes + // Baml Format Breaking Changes should change this. + + internal static readonly VersionPair BamlWriterVersion; + + static BamlVersionHeader() + { + // Initialize the Version number this way so that it can be + // seen in the Lutz Reflector. + BamlWriterVersion = new VersionPair(0, 96); + } + + public BamlVersionHeader() + { + _bamlVersion = new FormatVersion("MSBAML", BamlWriterVersion); + } + + public FormatVersion BamlVersion + { + get { return _bamlVersion; } +#if !PBTCOMPILER + set { _bamlVersion = value; } +#endif + } + + + // This is used by Async loading to measure if the whole record is present + static public int BinarySerializationSize + { + get + { + // Unicode "MSBAML" = 12 + // + 4 bytes length header = 12 + 4 = 16 + // + 3*(16bit MinorVer + 16bit MajorVer) = 16+(3*(2+2))= 28 + // For product stability the size of this data structure + // shouldn't change anyway. + return 28; + } + } + + +#if !PBTCOMPILER + internal void LoadVersion(BinaryReader bamlBinaryReader) + { +#if DEBUG + long posStart = bamlBinaryReader.BaseStream.Position; +#endif + + BamlVersion = FormatVersion.LoadFromStream(bamlBinaryReader.BaseStream); + +#if DEBUG + long posEnd = bamlBinaryReader.BaseStream.Position; + Debug.Assert((posEnd-posStart) == BamlVersionHeader.BinarySerializationSize, + "Incorrect Baml Version Header Size"); +#endif + + // We're assuming that only major versions are significant for compatibility, + // so if we have a major version in the file that is higher than that in + // the code, we can't read it. + if (BamlVersion.ReaderVersion != BamlWriterVersion) + { + throw new InvalidOperationException(SR.Get(SRID.ParserBamlVersion, + (BamlVersion.ReaderVersion.Major.ToString(CultureInfo.CurrentCulture) + "." + + BamlVersion.ReaderVersion.Minor.ToString(CultureInfo.CurrentCulture)), + (BamlWriterVersion.Major.ToString(CultureInfo.CurrentCulture) + "." + + BamlWriterVersion.Minor.ToString(CultureInfo.CurrentCulture)))); + } + } +#endif + + + internal void WriteVersion(BinaryWriter bamlBinaryWriter) + { +#if DEBUG + long posStart = bamlBinaryWriter.BaseStream.Position; +#endif + BamlVersion.SaveToStream(bamlBinaryWriter.BaseStream); + +#if DEBUG + long posEnd = bamlBinaryWriter.BaseStream.Position; + if(-1 == posStart) + { + long length = bamlBinaryWriter.BaseStream.Length; + Debug.Assert(length == BamlVersionHeader.BinarySerializationSize, + "Incorrect Baml Version Header Size"); + } + else + { + Debug.Assert((posEnd-posStart) == BamlVersionHeader.BinarySerializationSize, + "Incorrect Baml Version Header Size"); + } +#endif + + } + + FormatVersion _bamlVersion; + } +} + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/KnownTypes.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/KnownTypes.cs new file mode 100644 index 00000000000..08c8d1bf9ce --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/KnownTypes.cs @@ -0,0 +1,6311 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: +// Definition of known types in PresentationFramework.dll and +// PresentationCore.dll and WindowsBase.dll +// +// THIS FILE HAS BEEN AUTOMATICALLY GENERATED. +// (See generator code in wcp\tools\KnownTypes\KnownTypesInitializer.cs) +// +// If you are REMOVING or RENAMING an EXISTING TYPE, then a build error has sent +// you here because this file no longer compiles. +// The MINIMAL REQUIRED steps are: +// you have renamed or removed in Framework, Core or Base +// 2) Update BamlWriterVersion in BamlVersionHeader.cs, incrementing the second number +// 3) Build the WCP compiler. To do that; (on FRE) build from wcp\build. +// When it tells you the WCP compiler has changed, install it in the root +// To do that: cd \nt\tools and run UpdateWcpCompiler. +// (Don't forget to check in this compiler updates with your WCP changes) +// 4) Build from wcp. (FRE or CHK) Make certain that wcp builds cleanly. +// 5) Don't forget to check in compiler updates in the root Tools directory +// Note: There is no need to regenerate from the tool in this case. +// +// IF you are ADDING NEW TYPES, or you want the new name of a RENAMED TYPE to showup: +// The OPTIONAL or ADDITIONAL steps (to use perf optimization for your type) are: +// 1) Build the dll(s) that define the new types +// 2) Update BamlWriterVersion in BamlVersionHeader.cs, incrementing the second number +// 3) (On FRE build) Run wcp\tools\buildscripts\UpdateKnownTypes.cmd +// Or more directly you can run: KnownTypesInitializer.exe +// Note: You may see other new types that have been have added since the last time +// this file was generated. +// 4) Build the WCP compiler. To do that; (on FRE) build from wcp\build. +// When it tells you the WCP compiler has changed, install it in the root +// To do that: cd \nt\tools and run UpdateWcpCompiler. +// (Don't forget to check in this compiler updates with your WCP changes) +// 5) (FRE or CHK) Rebuild everything under wcp to pick up the KnownTypes changes +// 6) Don't forget to check in compiler updates in the root Tools directory +// +// This file is shared by PresentationFramework.dll and PresentaionBuildTasks.dll. +// +// The code marked with #if PBTCOMPILER is compiled into PresentationBuildTasks.dll. +// The code marked with #if !PBTCOMPILER is compiled into PresenationFramework.dll +// The code without #if flag will be compiled into both dlls. +// +//--------------------------------------------------------------------------- + +using System; +using System.Collections; +using System.ComponentModel; // TypeConverters +using System.Diagnostics; +using System.Globalization; // CultureInfo KnownType +using System.Reflection; +using MS.Utility; + +// Disabling 1634 and 1691: +// In order to avoid generating warnings about unknown message numbers and +// unknown pragmas when compiling C# source code with the C# compiler, +// you need to disable warnings 1634 and 1691. (Presharp Documentation) +#pragma warning disable 1634, 1691 + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + // This enum specifies the TypeIds we use for know types in BAML + // The baml files contains the negative of these values + internal enum KnownElements : short + { + UnknownElement = 0, + AccessText, + AdornedElementPlaceholder, + Adorner, + AdornerDecorator, + AdornerLayer, + AffineTransform3D, + AmbientLight, + AnchoredBlock, + Animatable, + AnimationClock, + AnimationTimeline, + Application, + ArcSegment, + ArrayExtension, + AxisAngleRotation3D, + BaseIListConverter, + BeginStoryboard, + BevelBitmapEffect, + BezierSegment, + Binding, + BindingBase, + BindingExpression, + BindingExpressionBase, + BindingListCollectionView, + BitmapDecoder, + BitmapEffect, + BitmapEffectCollection, + BitmapEffectGroup, + BitmapEffectInput, + BitmapEncoder, + BitmapFrame, + BitmapImage, + BitmapMetadata, + BitmapPalette, + BitmapSource, + Block, + BlockUIContainer, + BlurBitmapEffect, + BmpBitmapDecoder, + BmpBitmapEncoder, + Bold, + BoolIListConverter, + Boolean, + BooleanAnimationBase, + BooleanAnimationUsingKeyFrames, + BooleanConverter, + BooleanKeyFrame, + BooleanKeyFrameCollection, + BooleanToVisibilityConverter, + Border, + BorderGapMaskConverter, + Brush, + BrushConverter, + BulletDecorator, + Button, + ButtonBase, + Byte, + ByteAnimation, + ByteAnimationBase, + ByteAnimationUsingKeyFrames, + ByteConverter, + ByteKeyFrame, + ByteKeyFrameCollection, + CachedBitmap, + Camera, + Canvas, + Char, + CharAnimationBase, + CharAnimationUsingKeyFrames, + CharConverter, + CharIListConverter, + CharKeyFrame, + CharKeyFrameCollection, + CheckBox, + Clock, + ClockController, + ClockGroup, + CollectionContainer, + CollectionView, + CollectionViewSource, + Color, + ColorAnimation, + ColorAnimationBase, + ColorAnimationUsingKeyFrames, + ColorConvertedBitmap, + ColorConvertedBitmapExtension, + ColorConverter, + ColorKeyFrame, + ColorKeyFrameCollection, + ColumnDefinition, + CombinedGeometry, + ComboBox, + ComboBoxItem, + CommandConverter, + ComponentResourceKey, + ComponentResourceKeyConverter, + CompositionTarget, + Condition, + ContainerVisual, + ContentControl, + ContentElement, + ContentPresenter, + ContentPropertyAttribute, + ContentWrapperAttribute, + ContextMenu, + ContextMenuService, + Control, + ControlTemplate, + ControllableStoryboardAction, + CornerRadius, + CornerRadiusConverter, + CroppedBitmap, + CultureInfo, + CultureInfoConverter, + CultureInfoIetfLanguageTagConverter, + Cursor, + CursorConverter, + DashStyle, + DataChangedEventManager, + DataTemplate, + DataTemplateKey, + DataTrigger, + DateTime, + DateTimeConverter, + DateTimeConverter2, + Decimal, + DecimalAnimation, + DecimalAnimationBase, + DecimalAnimationUsingKeyFrames, + DecimalConverter, + DecimalKeyFrame, + DecimalKeyFrameCollection, + Decorator, + DefinitionBase, + DependencyObject, + DependencyProperty, + DependencyPropertyConverter, + DialogResultConverter, + DiffuseMaterial, + DirectionalLight, + DiscreteBooleanKeyFrame, + DiscreteByteKeyFrame, + DiscreteCharKeyFrame, + DiscreteColorKeyFrame, + DiscreteDecimalKeyFrame, + DiscreteDoubleKeyFrame, + DiscreteInt16KeyFrame, + DiscreteInt32KeyFrame, + DiscreteInt64KeyFrame, + DiscreteMatrixKeyFrame, + DiscreteObjectKeyFrame, + DiscretePoint3DKeyFrame, + DiscretePointKeyFrame, + DiscreteQuaternionKeyFrame, + DiscreteRectKeyFrame, + DiscreteRotation3DKeyFrame, + DiscreteSingleKeyFrame, + DiscreteSizeKeyFrame, + DiscreteStringKeyFrame, + DiscreteThicknessKeyFrame, + DiscreteVector3DKeyFrame, + DiscreteVectorKeyFrame, + DockPanel, + DocumentPageView, + DocumentReference, + DocumentViewer, + DocumentViewerBase, + Double, + DoubleAnimation, + DoubleAnimationBase, + DoubleAnimationUsingKeyFrames, + DoubleAnimationUsingPath, + DoubleCollection, + DoubleCollectionConverter, + DoubleConverter, + DoubleIListConverter, + DoubleKeyFrame, + DoubleKeyFrameCollection, + Drawing, + DrawingBrush, + DrawingCollection, + DrawingContext, + DrawingGroup, + DrawingImage, + DrawingVisual, + DropShadowBitmapEffect, + Duration, + DurationConverter, + DynamicResourceExtension, + DynamicResourceExtensionConverter, + Ellipse, + EllipseGeometry, + EmbossBitmapEffect, + EmissiveMaterial, + EnumConverter, + EventManager, + EventSetter, + EventTrigger, + Expander, + Expression, + ExpressionConverter, + Figure, + FigureLength, + FigureLengthConverter, + FixedDocument, + FixedDocumentSequence, + FixedPage, + Floater, + FlowDocument, + FlowDocumentPageViewer, + FlowDocumentReader, + FlowDocumentScrollViewer, + FocusManager, + FontFamily, + FontFamilyConverter, + FontSizeConverter, + FontStretch, + FontStretchConverter, + FontStyle, + FontStyleConverter, + FontWeight, + FontWeightConverter, + FormatConvertedBitmap, + Frame, + FrameworkContentElement, + FrameworkElement, + FrameworkElementFactory, + FrameworkPropertyMetadata, + FrameworkPropertyMetadataOptions, + FrameworkRichTextComposition, + FrameworkTemplate, + FrameworkTextComposition, + Freezable, + GeneralTransform, + GeneralTransformCollection, + GeneralTransformGroup, + Geometry, + Geometry3D, + GeometryCollection, + GeometryConverter, + GeometryDrawing, + GeometryGroup, + GeometryModel3D, + GestureRecognizer, + GifBitmapDecoder, + GifBitmapEncoder, + GlyphRun, + GlyphRunDrawing, + GlyphTypeface, + Glyphs, + GradientBrush, + GradientStop, + GradientStopCollection, + Grid, + GridLength, + GridLengthConverter, + GridSplitter, + GridView, + GridViewColumn, + GridViewColumnHeader, + GridViewHeaderRowPresenter, + GridViewRowPresenter, + GridViewRowPresenterBase, + GroupBox, + GroupItem, + Guid, + GuidConverter, + GuidelineSet, + HeaderedContentControl, + HeaderedItemsControl, + HierarchicalDataTemplate, + HostVisual, + Hyperlink, + IAddChild, + IAddChildInternal, + ICommand, + IComponentConnector, + INameScope, + IStyleConnector, + IconBitmapDecoder, + Image, + ImageBrush, + ImageDrawing, + ImageMetadata, + ImageSource, + ImageSourceConverter, + InPlaceBitmapMetadataWriter, + InkCanvas, + InkPresenter, + Inline, + InlineCollection, + InlineUIContainer, + InputBinding, + InputDevice, + InputLanguageManager, + InputManager, + InputMethod, + InputScope, + InputScopeConverter, + InputScopeName, + InputScopeNameConverter, + Int16, + Int16Animation, + Int16AnimationBase, + Int16AnimationUsingKeyFrames, + Int16Converter, + Int16KeyFrame, + Int16KeyFrameCollection, + Int32, + Int32Animation, + Int32AnimationBase, + Int32AnimationUsingKeyFrames, + Int32Collection, + Int32CollectionConverter, + Int32Converter, + Int32KeyFrame, + Int32KeyFrameCollection, + Int32Rect, + Int32RectConverter, + Int64, + Int64Animation, + Int64AnimationBase, + Int64AnimationUsingKeyFrames, + Int64Converter, + Int64KeyFrame, + Int64KeyFrameCollection, + Italic, + ItemCollection, + ItemsControl, + ItemsPanelTemplate, + ItemsPresenter, + JournalEntry, + JournalEntryListConverter, + JournalEntryUnifiedViewConverter, + JpegBitmapDecoder, + JpegBitmapEncoder, + KeyBinding, + KeyConverter, + KeyGesture, + KeyGestureConverter, + KeySpline, + KeySplineConverter, + KeyTime, + KeyTimeConverter, + KeyboardDevice, + Label, + LateBoundBitmapDecoder, + LengthConverter, + Light, + Line, + LineBreak, + LineGeometry, + LineSegment, + LinearByteKeyFrame, + LinearColorKeyFrame, + LinearDecimalKeyFrame, + LinearDoubleKeyFrame, + LinearGradientBrush, + LinearInt16KeyFrame, + LinearInt32KeyFrame, + LinearInt64KeyFrame, + LinearPoint3DKeyFrame, + LinearPointKeyFrame, + LinearQuaternionKeyFrame, + LinearRectKeyFrame, + LinearRotation3DKeyFrame, + LinearSingleKeyFrame, + LinearSizeKeyFrame, + LinearThicknessKeyFrame, + LinearVector3DKeyFrame, + LinearVectorKeyFrame, + List, + ListBox, + ListBoxItem, + ListCollectionView, + ListItem, + ListView, + ListViewItem, + Localization, + LostFocusEventManager, + MarkupExtension, + Material, + MaterialCollection, + MaterialGroup, + Matrix, + Matrix3D, + Matrix3DConverter, + MatrixAnimationBase, + MatrixAnimationUsingKeyFrames, + MatrixAnimationUsingPath, + MatrixCamera, + MatrixConverter, + MatrixKeyFrame, + MatrixKeyFrameCollection, + MatrixTransform, + MatrixTransform3D, + MediaClock, + MediaElement, + MediaPlayer, + MediaTimeline, + Menu, + MenuBase, + MenuItem, + MenuScrollingVisibilityConverter, + MeshGeometry3D, + Model3D, + Model3DCollection, + Model3DGroup, + ModelVisual3D, + ModifierKeysConverter, + MouseActionConverter, + MouseBinding, + MouseDevice, + MouseGesture, + MouseGestureConverter, + MultiBinding, + MultiBindingExpression, + MultiDataTrigger, + MultiTrigger, + NameScope, + NavigationWindow, + NullExtension, + NullableBoolConverter, + NullableConverter, + NumberSubstitution, + Object, + ObjectAnimationBase, + ObjectAnimationUsingKeyFrames, + ObjectDataProvider, + ObjectKeyFrame, + ObjectKeyFrameCollection, + OrthographicCamera, + OuterGlowBitmapEffect, + Page, + PageContent, + PageFunctionBase, + Panel, + Paragraph, + ParallelTimeline, + ParserContext, + PasswordBox, + Path, + PathFigure, + PathFigureCollection, + PathFigureCollectionConverter, + PathGeometry, + PathSegment, + PathSegmentCollection, + PauseStoryboard, + Pen, + PerspectiveCamera, + PixelFormat, + PixelFormatConverter, + PngBitmapDecoder, + PngBitmapEncoder, + Point, + Point3D, + Point3DAnimation, + Point3DAnimationBase, + Point3DAnimationUsingKeyFrames, + Point3DCollection, + Point3DCollectionConverter, + Point3DConverter, + Point3DKeyFrame, + Point3DKeyFrameCollection, + Point4D, + Point4DConverter, + PointAnimation, + PointAnimationBase, + PointAnimationUsingKeyFrames, + PointAnimationUsingPath, + PointCollection, + PointCollectionConverter, + PointConverter, + PointIListConverter, + PointKeyFrame, + PointKeyFrameCollection, + PointLight, + PointLightBase, + PolyBezierSegment, + PolyLineSegment, + PolyQuadraticBezierSegment, + Polygon, + Polyline, + Popup, + PresentationSource, + PriorityBinding, + PriorityBindingExpression, + ProgressBar, + ProjectionCamera, + PropertyPath, + PropertyPathConverter, + QuadraticBezierSegment, + Quaternion, + QuaternionAnimation, + QuaternionAnimationBase, + QuaternionAnimationUsingKeyFrames, + QuaternionConverter, + QuaternionKeyFrame, + QuaternionKeyFrameCollection, + QuaternionRotation3D, + RadialGradientBrush, + RadioButton, + RangeBase, + Rect, + Rect3D, + Rect3DConverter, + RectAnimation, + RectAnimationBase, + RectAnimationUsingKeyFrames, + RectConverter, + RectKeyFrame, + RectKeyFrameCollection, + Rectangle, + RectangleGeometry, + RelativeSource, + RemoveStoryboard, + RenderOptions, + RenderTargetBitmap, + RepeatBehavior, + RepeatBehaviorConverter, + RepeatButton, + ResizeGrip, + ResourceDictionary, + ResourceKey, + ResumeStoryboard, + RichTextBox, + RotateTransform, + RotateTransform3D, + Rotation3D, + Rotation3DAnimation, + Rotation3DAnimationBase, + Rotation3DAnimationUsingKeyFrames, + Rotation3DKeyFrame, + Rotation3DKeyFrameCollection, + RoutedCommand, + RoutedEvent, + RoutedEventConverter, + RoutedUICommand, + RoutingStrategy, + RowDefinition, + Run, + RuntimeNamePropertyAttribute, + SByte, + SByteConverter, + ScaleTransform, + ScaleTransform3D, + ScrollBar, + ScrollContentPresenter, + ScrollViewer, + Section, + SeekStoryboard, + Selector, + Separator, + SetStoryboardSpeedRatio, + Setter, + SetterBase, + Shape, + Single, + SingleAnimation, + SingleAnimationBase, + SingleAnimationUsingKeyFrames, + SingleConverter, + SingleKeyFrame, + SingleKeyFrameCollection, + Size, + Size3D, + Size3DConverter, + SizeAnimation, + SizeAnimationBase, + SizeAnimationUsingKeyFrames, + SizeConverter, + SizeKeyFrame, + SizeKeyFrameCollection, + SkewTransform, + SkipStoryboardToFill, + Slider, + SolidColorBrush, + SoundPlayerAction, + Span, + SpecularMaterial, + SpellCheck, + SplineByteKeyFrame, + SplineColorKeyFrame, + SplineDecimalKeyFrame, + SplineDoubleKeyFrame, + SplineInt16KeyFrame, + SplineInt32KeyFrame, + SplineInt64KeyFrame, + SplinePoint3DKeyFrame, + SplinePointKeyFrame, + SplineQuaternionKeyFrame, + SplineRectKeyFrame, + SplineRotation3DKeyFrame, + SplineSingleKeyFrame, + SplineSizeKeyFrame, + SplineThicknessKeyFrame, + SplineVector3DKeyFrame, + SplineVectorKeyFrame, + SpotLight, + StackPanel, + StaticExtension, + StaticResourceExtension, + StatusBar, + StatusBarItem, + StickyNoteControl, + StopStoryboard, + Storyboard, + StreamGeometry, + StreamGeometryContext, + StreamResourceInfo, + String, + StringAnimationBase, + StringAnimationUsingKeyFrames, + StringConverter, + StringKeyFrame, + StringKeyFrameCollection, + StrokeCollection, + StrokeCollectionConverter, + Style, + Stylus, + StylusDevice, + TabControl, + TabItem, + TabPanel, + Table, + TableCell, + TableColumn, + TableRow, + TableRowGroup, + TabletDevice, + TemplateBindingExpression, + TemplateBindingExpressionConverter, + TemplateBindingExtension, + TemplateBindingExtensionConverter, + TemplateKey, + TemplateKeyConverter, + TextBlock, + TextBox, + TextBoxBase, + TextComposition, + TextCompositionManager, + TextDecoration, + TextDecorationCollection, + TextDecorationCollectionConverter, + TextEffect, + TextEffectCollection, + TextElement, + TextSearch, + ThemeDictionaryExtension, + Thickness, + ThicknessAnimation, + ThicknessAnimationBase, + ThicknessAnimationUsingKeyFrames, + ThicknessConverter, + ThicknessKeyFrame, + ThicknessKeyFrameCollection, + Thumb, + TickBar, + TiffBitmapDecoder, + TiffBitmapEncoder, + TileBrush, + TimeSpan, + TimeSpanConverter, + Timeline, + TimelineCollection, + TimelineGroup, + ToggleButton, + ToolBar, + ToolBarOverflowPanel, + ToolBarPanel, + ToolBarTray, + ToolTip, + ToolTipService, + Track, + Transform, + Transform3D, + Transform3DCollection, + Transform3DGroup, + TransformCollection, + TransformConverter, + TransformGroup, + TransformedBitmap, + TranslateTransform, + TranslateTransform3D, + TreeView, + TreeViewItem, + Trigger, + TriggerAction, + TriggerBase, + TypeExtension, + TypeTypeConverter, + Typography, + UIElement, + UInt16, + UInt16Converter, + UInt32, + UInt32Converter, + UInt64, + UInt64Converter, + UShortIListConverter, + Underline, + UniformGrid, + Uri, + UriTypeConverter, + UserControl, + Validation, + Vector, + Vector3D, + Vector3DAnimation, + Vector3DAnimationBase, + Vector3DAnimationUsingKeyFrames, + Vector3DCollection, + Vector3DCollectionConverter, + Vector3DConverter, + Vector3DKeyFrame, + Vector3DKeyFrameCollection, + VectorAnimation, + VectorAnimationBase, + VectorAnimationUsingKeyFrames, + VectorCollection, + VectorCollectionConverter, + VectorConverter, + VectorKeyFrame, + VectorKeyFrameCollection, + VideoDrawing, + ViewBase, + Viewbox, + Viewport3D, + Viewport3DVisual, + VirtualizingPanel, + VirtualizingStackPanel, + Visual, + Visual3D, + VisualBrush, + VisualTarget, + WeakEventManager, + WhitespaceSignificantCollectionAttribute, + Window, + WmpBitmapDecoder, + WmpBitmapEncoder, + WrapPanel, + WriteableBitmap, + XamlBrushSerializer, + XamlInt32CollectionSerializer, + XamlPathDataSerializer, + XamlPoint3DCollectionSerializer, + XamlPointCollectionSerializer, + XamlReader, + XamlStyleSerializer, + XamlTemplateSerializer, + XamlVector3DCollectionSerializer, + XamlWriter, + XmlDataProvider, + XmlLangPropertyAttribute, + XmlLanguage, + XmlLanguageConverter, + XmlNamespaceMapping, + ZoomPercentageConverter, + MaxElement + } + + // This enum specifies the IDs we use for known CLR and DP Properties in BAML. + // The baml files contains the negative of these values. + internal enum KnownProperties : short + { + UnknownProperty = 0, + AccessText_Text, + BeginStoryboard_Storyboard, + BitmapEffectGroup_Children, + Border_Background, + Border_BorderBrush, + Border_BorderThickness, + ButtonBase_Command, + ButtonBase_CommandParameter, + ButtonBase_CommandTarget, + ButtonBase_IsPressed, + ColumnDefinition_MaxWidth, + ColumnDefinition_MinWidth, + ColumnDefinition_Width, + ContentControl_Content, + ContentControl_ContentTemplate, + ContentControl_ContentTemplateSelector, + ContentControl_HasContent, + ContentElement_Focusable, + ContentPresenter_Content, + ContentPresenter_ContentSource, + ContentPresenter_ContentTemplate, + ContentPresenter_ContentTemplateSelector, + ContentPresenter_RecognizesAccessKey, + Control_Background, + Control_BorderBrush, + Control_BorderThickness, + Control_FontFamily, + Control_FontSize, + Control_FontStretch, + Control_FontStyle, + Control_FontWeight, + Control_Foreground, + Control_HorizontalContentAlignment, + Control_IsTabStop, + Control_Padding, + Control_TabIndex, + Control_Template, + Control_VerticalContentAlignment, + DockPanel_Dock, + DockPanel_LastChildFill, + DocumentViewerBase_Document, + DrawingGroup_Children, + FlowDocumentReader_Document, + FlowDocumentScrollViewer_Document, + FrameworkContentElement_Style, + FrameworkElement_FlowDirection, + FrameworkElement_Height, + FrameworkElement_HorizontalAlignment, + FrameworkElement_Margin, + FrameworkElement_MaxHeight, + FrameworkElement_MaxWidth, + FrameworkElement_MinHeight, + FrameworkElement_MinWidth, + FrameworkElement_Name, + FrameworkElement_Style, + FrameworkElement_VerticalAlignment, + FrameworkElement_Width, + GeneralTransformGroup_Children, + GeometryGroup_Children, + GradientBrush_GradientStops, + Grid_Column, + Grid_ColumnSpan, + Grid_Row, + Grid_RowSpan, + GridViewColumn_Header, + HeaderedContentControl_HasHeader, + HeaderedContentControl_Header, + HeaderedContentControl_HeaderTemplate, + HeaderedContentControl_HeaderTemplateSelector, + HeaderedItemsControl_HasHeader, + HeaderedItemsControl_Header, + HeaderedItemsControl_HeaderTemplate, + HeaderedItemsControl_HeaderTemplateSelector, + Hyperlink_NavigateUri, + Image_Source, + Image_Stretch, + ItemsControl_ItemContainerStyle, + ItemsControl_ItemContainerStyleSelector, + ItemsControl_ItemTemplate, + ItemsControl_ItemTemplateSelector, + ItemsControl_ItemsPanel, + ItemsControl_ItemsSource, + MaterialGroup_Children, + Model3DGroup_Children, + Page_Content, + Panel_Background, + Path_Data, + PathFigure_Segments, + PathGeometry_Figures, + Popup_Child, + Popup_IsOpen, + Popup_Placement, + Popup_PopupAnimation, + RowDefinition_Height, + RowDefinition_MaxHeight, + RowDefinition_MinHeight, + ScrollViewer_CanContentScroll, + ScrollViewer_HorizontalScrollBarVisibility, + ScrollViewer_VerticalScrollBarVisibility, + Shape_Fill, + Shape_Stroke, + Shape_StrokeThickness, + TextBlock_Background, + TextBlock_FontFamily, + TextBlock_FontSize, + TextBlock_FontStretch, + TextBlock_FontStyle, + TextBlock_FontWeight, + TextBlock_Foreground, + TextBlock_Text, + TextBlock_TextDecorations, + TextBlock_TextTrimming, + TextBlock_TextWrapping, + TextBox_Text, + TextElement_Background, + TextElement_FontFamily, + TextElement_FontSize, + TextElement_FontStretch, + TextElement_FontStyle, + TextElement_FontWeight, + TextElement_Foreground, + TimelineGroup_Children, + Track_IsDirectionReversed, + Track_Maximum, + Track_Minimum, + Track_Orientation, + Track_Value, + Track_ViewportSize, + Transform3DGroup_Children, + TransformGroup_Children, + UIElement_ClipToBounds, + UIElement_Focusable, + UIElement_IsEnabled, + UIElement_RenderTransform, + UIElement_Visibility, + Viewport3D_Children, + MaxDependencyProperty, + AdornedElementPlaceholder_Child, + AdornerDecorator_Child, + AnchoredBlock_Blocks, + ArrayExtension_Items, + BlockUIContainer_Child, + Bold_Inlines, + BooleanAnimationUsingKeyFrames_KeyFrames, + Border_Child, + BulletDecorator_Child, + Button_Content, + ButtonBase_Content, + ByteAnimationUsingKeyFrames_KeyFrames, + Canvas_Children, + CharAnimationUsingKeyFrames_KeyFrames, + CheckBox_Content, + ColorAnimationUsingKeyFrames_KeyFrames, + ComboBox_Items, + ComboBoxItem_Content, + ContextMenu_Items, + ControlTemplate_VisualTree, + DataTemplate_VisualTree, + DataTrigger_Setters, + DecimalAnimationUsingKeyFrames_KeyFrames, + Decorator_Child, + DockPanel_Children, + DocumentViewer_Document, + DoubleAnimationUsingKeyFrames_KeyFrames, + EventTrigger_Actions, + Expander_Content, + Figure_Blocks, + FixedDocument_Pages, + FixedDocumentSequence_References, + FixedPage_Children, + Floater_Blocks, + FlowDocument_Blocks, + FlowDocumentPageViewer_Document, + FrameworkTemplate_VisualTree, + Grid_Children, + GridView_Columns, + GridViewColumnHeader_Content, + GroupBox_Content, + GroupItem_Content, + HeaderedContentControl_Content, + HeaderedItemsControl_Items, + HierarchicalDataTemplate_VisualTree, + Hyperlink_Inlines, + InkCanvas_Children, + InkPresenter_Child, + InlineUIContainer_Child, + InputScopeName_NameValue, + Int16AnimationUsingKeyFrames_KeyFrames, + Int32AnimationUsingKeyFrames_KeyFrames, + Int64AnimationUsingKeyFrames_KeyFrames, + Italic_Inlines, + ItemsControl_Items, + ItemsPanelTemplate_VisualTree, + Label_Content, + LinearGradientBrush_GradientStops, + List_ListItems, + ListBox_Items, + ListBoxItem_Content, + ListItem_Blocks, + ListView_Items, + ListViewItem_Content, + MatrixAnimationUsingKeyFrames_KeyFrames, + Menu_Items, + MenuBase_Items, + MenuItem_Items, + ModelVisual3D_Children, + MultiBinding_Bindings, + MultiDataTrigger_Setters, + MultiTrigger_Setters, + ObjectAnimationUsingKeyFrames_KeyFrames, + PageContent_Child, + PageFunctionBase_Content, + Panel_Children, + Paragraph_Inlines, + ParallelTimeline_Children, + Point3DAnimationUsingKeyFrames_KeyFrames, + PointAnimationUsingKeyFrames_KeyFrames, + PriorityBinding_Bindings, + QuaternionAnimationUsingKeyFrames_KeyFrames, + RadialGradientBrush_GradientStops, + RadioButton_Content, + RectAnimationUsingKeyFrames_KeyFrames, + RepeatButton_Content, + RichTextBox_Document, + Rotation3DAnimationUsingKeyFrames_KeyFrames, + Run_Text, + ScrollViewer_Content, + Section_Blocks, + Selector_Items, + SingleAnimationUsingKeyFrames_KeyFrames, + SizeAnimationUsingKeyFrames_KeyFrames, + Span_Inlines, + StackPanel_Children, + StatusBar_Items, + StatusBarItem_Content, + Storyboard_Children, + StringAnimationUsingKeyFrames_KeyFrames, + Style_Setters, + TabControl_Items, + TabItem_Content, + TabPanel_Children, + Table_RowGroups, + TableCell_Blocks, + TableRow_Cells, + TableRowGroup_Rows, + TextBlock_Inlines, + ThicknessAnimationUsingKeyFrames_KeyFrames, + ToggleButton_Content, + ToolBar_Items, + ToolBarOverflowPanel_Children, + ToolBarPanel_Children, + ToolBarTray_ToolBars, + ToolTip_Content, + TreeView_Items, + TreeViewItem_Items, + Trigger_Setters, + Underline_Inlines, + UniformGrid_Children, + UserControl_Content, + Vector3DAnimationUsingKeyFrames_KeyFrames, + VectorAnimationUsingKeyFrames_KeyFrames, + Viewbox_Child, + Viewport3DVisual_Children, + VirtualizingPanel_Children, + VirtualizingStackPanel_Children, + Window_Content, + WrapPanel_Children, + XmlDataProvider_XmlSerializer, + MaxProperty, + } + +#if !BAMLDASM + internal static partial class KnownTypes + { +#if !PBTCOMPILER + // Code compiled into PresentationFramework.dll + + // Initialize known object types + internal static object CreateKnownElement(KnownElements knownElement) + { + object o = null; + switch (knownElement) + { + case KnownElements.AccessText: o = new System.Windows.Controls.AccessText(); break; + case KnownElements.AdornedElementPlaceholder: o = new System.Windows.Controls.AdornedElementPlaceholder(); break; + case KnownElements.AdornerDecorator: o = new System.Windows.Documents.AdornerDecorator(); break; + case KnownElements.AmbientLight: o = new System.Windows.Media.Media3D.AmbientLight(); break; + case KnownElements.Application: o = new System.Windows.Application(); break; + case KnownElements.ArcSegment: o = new System.Windows.Media.ArcSegment(); break; + case KnownElements.ArrayExtension: o = new System.Windows.Markup.ArrayExtension(); break; + case KnownElements.AxisAngleRotation3D: o = new System.Windows.Media.Media3D.AxisAngleRotation3D(); break; + case KnownElements.BeginStoryboard: o = new System.Windows.Media.Animation.BeginStoryboard(); break; + case KnownElements.BevelBitmapEffect: o = new System.Windows.Media.Effects.BevelBitmapEffect(); break; + case KnownElements.BezierSegment: o = new System.Windows.Media.BezierSegment(); break; + case KnownElements.Binding: o = new System.Windows.Data.Binding(); break; + case KnownElements.BitmapEffectCollection: o = new System.Windows.Media.Effects.BitmapEffectCollection(); break; + case KnownElements.BitmapEffectGroup: o = new System.Windows.Media.Effects.BitmapEffectGroup(); break; + case KnownElements.BitmapEffectInput: o = new System.Windows.Media.Effects.BitmapEffectInput(); break; + case KnownElements.BitmapImage: o = new System.Windows.Media.Imaging.BitmapImage(); break; + case KnownElements.BlockUIContainer: o = new System.Windows.Documents.BlockUIContainer(); break; + case KnownElements.BlurBitmapEffect: o = new System.Windows.Media.Effects.BlurBitmapEffect(); break; + case KnownElements.BmpBitmapEncoder: o = new System.Windows.Media.Imaging.BmpBitmapEncoder(); break; + case KnownElements.Bold: o = new System.Windows.Documents.Bold(); break; + case KnownElements.BoolIListConverter: o = new System.Windows.Media.Converters.BoolIListConverter(); break; + case KnownElements.BooleanAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.BooleanAnimationUsingKeyFrames(); break; + case KnownElements.BooleanConverter: o = new System.ComponentModel.BooleanConverter(); break; + case KnownElements.BooleanKeyFrameCollection: o = new System.Windows.Media.Animation.BooleanKeyFrameCollection(); break; + case KnownElements.BooleanToVisibilityConverter: o = new System.Windows.Controls.BooleanToVisibilityConverter(); break; + case KnownElements.Border: o = new System.Windows.Controls.Border(); break; + case KnownElements.BorderGapMaskConverter: o = new System.Windows.Controls.BorderGapMaskConverter(); break; + case KnownElements.BrushConverter: o = new System.Windows.Media.BrushConverter(); break; + case KnownElements.BulletDecorator: o = new System.Windows.Controls.Primitives.BulletDecorator(); break; + case KnownElements.Button: o = new System.Windows.Controls.Button(); break; + case KnownElements.ByteAnimation: o = new System.Windows.Media.Animation.ByteAnimation(); break; + case KnownElements.ByteAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.ByteAnimationUsingKeyFrames(); break; + case KnownElements.ByteConverter: o = new System.ComponentModel.ByteConverter(); break; + case KnownElements.ByteKeyFrameCollection: o = new System.Windows.Media.Animation.ByteKeyFrameCollection(); break; + case KnownElements.Canvas: o = new System.Windows.Controls.Canvas(); break; + case KnownElements.CharAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.CharAnimationUsingKeyFrames(); break; + case KnownElements.CharConverter: o = new System.ComponentModel.CharConverter(); break; + case KnownElements.CharIListConverter: o = new System.Windows.Media.Converters.CharIListConverter(); break; + case KnownElements.CharKeyFrameCollection: o = new System.Windows.Media.Animation.CharKeyFrameCollection(); break; + case KnownElements.CheckBox: o = new System.Windows.Controls.CheckBox(); break; + case KnownElements.CollectionContainer: o = new System.Windows.Data.CollectionContainer(); break; + case KnownElements.CollectionViewSource: o = new System.Windows.Data.CollectionViewSource(); break; + case KnownElements.Color: o = new System.Windows.Media.Color(); break; + case KnownElements.ColorAnimation: o = new System.Windows.Media.Animation.ColorAnimation(); break; + case KnownElements.ColorAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.ColorAnimationUsingKeyFrames(); break; + case KnownElements.ColorConvertedBitmap: o = new System.Windows.Media.Imaging.ColorConvertedBitmap(); break; + case KnownElements.ColorConvertedBitmapExtension: o = new System.Windows.ColorConvertedBitmapExtension(); break; + case KnownElements.ColorConverter: o = new System.Windows.Media.ColorConverter(); break; + case KnownElements.ColorKeyFrameCollection: o = new System.Windows.Media.Animation.ColorKeyFrameCollection(); break; + case KnownElements.ColumnDefinition: o = new System.Windows.Controls.ColumnDefinition(); break; + case KnownElements.CombinedGeometry: o = new System.Windows.Media.CombinedGeometry(); break; + case KnownElements.ComboBox: o = new System.Windows.Controls.ComboBox(); break; + case KnownElements.ComboBoxItem: o = new System.Windows.Controls.ComboBoxItem(); break; + case KnownElements.CommandConverter: o = new System.Windows.Input.CommandConverter(); break; + case KnownElements.ComponentResourceKey: o = new System.Windows.ComponentResourceKey(); break; + case KnownElements.ComponentResourceKeyConverter: o = new System.Windows.Markup.ComponentResourceKeyConverter(); break; + case KnownElements.Condition: o = new System.Windows.Condition(); break; + case KnownElements.ContainerVisual: o = new System.Windows.Media.ContainerVisual(); break; + case KnownElements.ContentControl: o = new System.Windows.Controls.ContentControl(); break; + case KnownElements.ContentElement: o = new System.Windows.ContentElement(); break; + case KnownElements.ContentPresenter: o = new System.Windows.Controls.ContentPresenter(); break; + case KnownElements.ContextMenu: o = new System.Windows.Controls.ContextMenu(); break; + case KnownElements.Control: o = new System.Windows.Controls.Control(); break; + case KnownElements.ControlTemplate: o = new System.Windows.Controls.ControlTemplate(); break; + case KnownElements.CornerRadius: o = new System.Windows.CornerRadius(); break; + case KnownElements.CornerRadiusConverter: o = new System.Windows.CornerRadiusConverter(); break; + case KnownElements.CroppedBitmap: o = new System.Windows.Media.Imaging.CroppedBitmap(); break; + case KnownElements.CultureInfoConverter: o = new System.ComponentModel.CultureInfoConverter(); break; + case KnownElements.CultureInfoIetfLanguageTagConverter: o = new System.Windows.CultureInfoIetfLanguageTagConverter(); break; + case KnownElements.CursorConverter: o = new System.Windows.Input.CursorConverter(); break; + case KnownElements.DashStyle: o = new System.Windows.Media.DashStyle(); break; + case KnownElements.DataTemplate: o = new System.Windows.DataTemplate(); break; + case KnownElements.DataTemplateKey: o = new System.Windows.DataTemplateKey(); break; + case KnownElements.DataTrigger: o = new System.Windows.DataTrigger(); break; + case KnownElements.DateTimeConverter: o = new System.ComponentModel.DateTimeConverter(); break; + case KnownElements.DateTimeConverter2: o = new System.Windows.Markup.DateTimeConverter2(); break; + case KnownElements.DecimalAnimation: o = new System.Windows.Media.Animation.DecimalAnimation(); break; + case KnownElements.DecimalAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.DecimalAnimationUsingKeyFrames(); break; + case KnownElements.DecimalConverter: o = new System.ComponentModel.DecimalConverter(); break; + case KnownElements.DecimalKeyFrameCollection: o = new System.Windows.Media.Animation.DecimalKeyFrameCollection(); break; + case KnownElements.Decorator: o = new System.Windows.Controls.Decorator(); break; + case KnownElements.DependencyObject: o = new System.Windows.DependencyObject(); break; + case KnownElements.DependencyPropertyConverter: o = new System.Windows.Markup.DependencyPropertyConverter(); break; + case KnownElements.DialogResultConverter: o = new System.Windows.DialogResultConverter(); break; + case KnownElements.DiffuseMaterial: o = new System.Windows.Media.Media3D.DiffuseMaterial(); break; + case KnownElements.DirectionalLight: o = new System.Windows.Media.Media3D.DirectionalLight(); break; + case KnownElements.DiscreteBooleanKeyFrame: o = new System.Windows.Media.Animation.DiscreteBooleanKeyFrame(); break; + case KnownElements.DiscreteByteKeyFrame: o = new System.Windows.Media.Animation.DiscreteByteKeyFrame(); break; + case KnownElements.DiscreteCharKeyFrame: o = new System.Windows.Media.Animation.DiscreteCharKeyFrame(); break; + case KnownElements.DiscreteColorKeyFrame: o = new System.Windows.Media.Animation.DiscreteColorKeyFrame(); break; + case KnownElements.DiscreteDecimalKeyFrame: o = new System.Windows.Media.Animation.DiscreteDecimalKeyFrame(); break; + case KnownElements.DiscreteDoubleKeyFrame: o = new System.Windows.Media.Animation.DiscreteDoubleKeyFrame(); break; + case KnownElements.DiscreteInt16KeyFrame: o = new System.Windows.Media.Animation.DiscreteInt16KeyFrame(); break; + case KnownElements.DiscreteInt32KeyFrame: o = new System.Windows.Media.Animation.DiscreteInt32KeyFrame(); break; + case KnownElements.DiscreteInt64KeyFrame: o = new System.Windows.Media.Animation.DiscreteInt64KeyFrame(); break; + case KnownElements.DiscreteMatrixKeyFrame: o = new System.Windows.Media.Animation.DiscreteMatrixKeyFrame(); break; + case KnownElements.DiscreteObjectKeyFrame: o = new System.Windows.Media.Animation.DiscreteObjectKeyFrame(); break; + case KnownElements.DiscretePoint3DKeyFrame: o = new System.Windows.Media.Animation.DiscretePoint3DKeyFrame(); break; + case KnownElements.DiscretePointKeyFrame: o = new System.Windows.Media.Animation.DiscretePointKeyFrame(); break; + case KnownElements.DiscreteQuaternionKeyFrame: o = new System.Windows.Media.Animation.DiscreteQuaternionKeyFrame(); break; + case KnownElements.DiscreteRectKeyFrame: o = new System.Windows.Media.Animation.DiscreteRectKeyFrame(); break; + case KnownElements.DiscreteRotation3DKeyFrame: o = new System.Windows.Media.Animation.DiscreteRotation3DKeyFrame(); break; + case KnownElements.DiscreteSingleKeyFrame: o = new System.Windows.Media.Animation.DiscreteSingleKeyFrame(); break; + case KnownElements.DiscreteSizeKeyFrame: o = new System.Windows.Media.Animation.DiscreteSizeKeyFrame(); break; + case KnownElements.DiscreteStringKeyFrame: o = new System.Windows.Media.Animation.DiscreteStringKeyFrame(); break; + case KnownElements.DiscreteThicknessKeyFrame: o = new System.Windows.Media.Animation.DiscreteThicknessKeyFrame(); break; + case KnownElements.DiscreteVector3DKeyFrame: o = new System.Windows.Media.Animation.DiscreteVector3DKeyFrame(); break; + case KnownElements.DiscreteVectorKeyFrame: o = new System.Windows.Media.Animation.DiscreteVectorKeyFrame(); break; + case KnownElements.DockPanel: o = new System.Windows.Controls.DockPanel(); break; + case KnownElements.DocumentPageView: o = new System.Windows.Controls.Primitives.DocumentPageView(); break; + case KnownElements.DocumentReference: o = new System.Windows.Documents.DocumentReference(); break; + case KnownElements.DocumentViewer: o = new System.Windows.Controls.DocumentViewer(); break; + case KnownElements.DoubleAnimation: o = new System.Windows.Media.Animation.DoubleAnimation(); break; + case KnownElements.DoubleAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.DoubleAnimationUsingKeyFrames(); break; + case KnownElements.DoubleAnimationUsingPath: o = new System.Windows.Media.Animation.DoubleAnimationUsingPath(); break; + case KnownElements.DoubleCollection: o = new System.Windows.Media.DoubleCollection(); break; + case KnownElements.DoubleCollectionConverter: o = new System.Windows.Media.DoubleCollectionConverter(); break; + case KnownElements.DoubleConverter: o = new System.ComponentModel.DoubleConverter(); break; + case KnownElements.DoubleIListConverter: o = new System.Windows.Media.Converters.DoubleIListConverter(); break; + case KnownElements.DoubleKeyFrameCollection: o = new System.Windows.Media.Animation.DoubleKeyFrameCollection(); break; + case KnownElements.DrawingBrush: o = new System.Windows.Media.DrawingBrush(); break; + case KnownElements.DrawingCollection: o = new System.Windows.Media.DrawingCollection(); break; + case KnownElements.DrawingGroup: o = new System.Windows.Media.DrawingGroup(); break; + case KnownElements.DrawingImage: o = new System.Windows.Media.DrawingImage(); break; + case KnownElements.DrawingVisual: o = new System.Windows.Media.DrawingVisual(); break; + case KnownElements.DropShadowBitmapEffect: o = new System.Windows.Media.Effects.DropShadowBitmapEffect(); break; + case KnownElements.Duration: o = new System.Windows.Duration(); break; + case KnownElements.DurationConverter: o = new System.Windows.DurationConverter(); break; + case KnownElements.DynamicResourceExtension: o = new System.Windows.DynamicResourceExtension(); break; + case KnownElements.DynamicResourceExtensionConverter: o = new System.Windows.DynamicResourceExtensionConverter(); break; + case KnownElements.Ellipse: o = new System.Windows.Shapes.Ellipse(); break; + case KnownElements.EllipseGeometry: o = new System.Windows.Media.EllipseGeometry(); break; + case KnownElements.EmbossBitmapEffect: o = new System.Windows.Media.Effects.EmbossBitmapEffect(); break; + case KnownElements.EmissiveMaterial: o = new System.Windows.Media.Media3D.EmissiveMaterial(); break; + case KnownElements.EventSetter: o = new System.Windows.EventSetter(); break; + case KnownElements.EventTrigger: o = new System.Windows.EventTrigger(); break; + case KnownElements.Expander: o = new System.Windows.Controls.Expander(); break; + case KnownElements.ExpressionConverter: o = new System.Windows.ExpressionConverter(); break; + case KnownElements.Figure: o = new System.Windows.Documents.Figure(); break; + case KnownElements.FigureLength: o = new System.Windows.FigureLength(); break; + case KnownElements.FigureLengthConverter: o = new System.Windows.FigureLengthConverter(); break; + case KnownElements.FixedDocument: o = new System.Windows.Documents.FixedDocument(); break; + case KnownElements.FixedDocumentSequence: o = new System.Windows.Documents.FixedDocumentSequence(); break; + case KnownElements.FixedPage: o = new System.Windows.Documents.FixedPage(); break; + case KnownElements.Floater: o = new System.Windows.Documents.Floater(); break; + case KnownElements.FlowDocument: o = new System.Windows.Documents.FlowDocument(); break; + case KnownElements.FlowDocumentPageViewer: o = new System.Windows.Controls.FlowDocumentPageViewer(); break; + case KnownElements.FlowDocumentReader: o = new System.Windows.Controls.FlowDocumentReader(); break; + case KnownElements.FlowDocumentScrollViewer: o = new System.Windows.Controls.FlowDocumentScrollViewer(); break; + case KnownElements.FontFamily: o = new System.Windows.Media.FontFamily(); break; + case KnownElements.FontFamilyConverter: o = new System.Windows.Media.FontFamilyConverter(); break; + case KnownElements.FontSizeConverter: o = new System.Windows.FontSizeConverter(); break; + case KnownElements.FontStretch: o = new System.Windows.FontStretch(); break; + case KnownElements.FontStretchConverter: o = new System.Windows.FontStretchConverter(); break; + case KnownElements.FontStyle: o = new System.Windows.FontStyle(); break; + case KnownElements.FontStyleConverter: o = new System.Windows.FontStyleConverter(); break; + case KnownElements.FontWeight: o = new System.Windows.FontWeight(); break; + case KnownElements.FontWeightConverter: o = new System.Windows.FontWeightConverter(); break; + case KnownElements.FormatConvertedBitmap: o = new System.Windows.Media.Imaging.FormatConvertedBitmap(); break; + case KnownElements.Frame: o = new System.Windows.Controls.Frame(); break; + case KnownElements.FrameworkContentElement: o = new System.Windows.FrameworkContentElement(); break; + case KnownElements.FrameworkElement: o = new System.Windows.FrameworkElement(); break; + case KnownElements.FrameworkElementFactory: o = new System.Windows.FrameworkElementFactory(); break; + case KnownElements.FrameworkPropertyMetadata: o = new System.Windows.FrameworkPropertyMetadata(); break; + case KnownElements.GeneralTransformCollection: o = new System.Windows.Media.GeneralTransformCollection(); break; + case KnownElements.GeneralTransformGroup: o = new System.Windows.Media.GeneralTransformGroup(); break; + case KnownElements.GeometryCollection: o = new System.Windows.Media.GeometryCollection(); break; + case KnownElements.GeometryConverter: o = new System.Windows.Media.GeometryConverter(); break; + case KnownElements.GeometryDrawing: o = new System.Windows.Media.GeometryDrawing(); break; + case KnownElements.GeometryGroup: o = new System.Windows.Media.GeometryGroup(); break; + case KnownElements.GeometryModel3D: o = new System.Windows.Media.Media3D.GeometryModel3D(); break; + case KnownElements.GestureRecognizer: o = new System.Windows.Ink.GestureRecognizer(); break; + case KnownElements.GifBitmapEncoder: o = new System.Windows.Media.Imaging.GifBitmapEncoder(); break; + case KnownElements.GlyphRun: o = new System.Windows.Media.GlyphRun(); break; + case KnownElements.GlyphRunDrawing: o = new System.Windows.Media.GlyphRunDrawing(); break; + case KnownElements.GlyphTypeface: o = new System.Windows.Media.GlyphTypeface(); break; + case KnownElements.Glyphs: o = new System.Windows.Documents.Glyphs(); break; + case KnownElements.GradientStop: o = new System.Windows.Media.GradientStop(); break; + case KnownElements.GradientStopCollection: o = new System.Windows.Media.GradientStopCollection(); break; + case KnownElements.Grid: o = new System.Windows.Controls.Grid(); break; + case KnownElements.GridLength: o = new System.Windows.GridLength(); break; + case KnownElements.GridLengthConverter: o = new System.Windows.GridLengthConverter(); break; + case KnownElements.GridSplitter: o = new System.Windows.Controls.GridSplitter(); break; + case KnownElements.GridView: o = new System.Windows.Controls.GridView(); break; + case KnownElements.GridViewColumn: o = new System.Windows.Controls.GridViewColumn(); break; + case KnownElements.GridViewColumnHeader: o = new System.Windows.Controls.GridViewColumnHeader(); break; + case KnownElements.GridViewHeaderRowPresenter: o = new System.Windows.Controls.GridViewHeaderRowPresenter(); break; + case KnownElements.GridViewRowPresenter: o = new System.Windows.Controls.GridViewRowPresenter(); break; + case KnownElements.GroupBox: o = new System.Windows.Controls.GroupBox(); break; + case KnownElements.GroupItem: o = new System.Windows.Controls.GroupItem(); break; + case KnownElements.GuidConverter: o = new System.ComponentModel.GuidConverter(); break; + case KnownElements.GuidelineSet: o = new System.Windows.Media.GuidelineSet(); break; + case KnownElements.HeaderedContentControl: o = new System.Windows.Controls.HeaderedContentControl(); break; + case KnownElements.HeaderedItemsControl: o = new System.Windows.Controls.HeaderedItemsControl(); break; + case KnownElements.HierarchicalDataTemplate: o = new System.Windows.HierarchicalDataTemplate(); break; + case KnownElements.HostVisual: o = new System.Windows.Media.HostVisual(); break; + case KnownElements.Hyperlink: o = new System.Windows.Documents.Hyperlink(); break; + case KnownElements.Image: o = new System.Windows.Controls.Image(); break; + case KnownElements.ImageBrush: o = new System.Windows.Media.ImageBrush(); break; + case KnownElements.ImageDrawing: o = new System.Windows.Media.ImageDrawing(); break; + case KnownElements.ImageSourceConverter: o = new System.Windows.Media.ImageSourceConverter(); break; + case KnownElements.InkCanvas: o = new System.Windows.Controls.InkCanvas(); break; + case KnownElements.InkPresenter: o = new System.Windows.Controls.InkPresenter(); break; + case KnownElements.InlineUIContainer: o = new System.Windows.Documents.InlineUIContainer(); break; + case KnownElements.InputScope: o = new System.Windows.Input.InputScope(); break; + case KnownElements.InputScopeConverter: o = new System.Windows.Input.InputScopeConverter(); break; + case KnownElements.InputScopeName: o = new System.Windows.Input.InputScopeName(); break; + case KnownElements.InputScopeNameConverter: o = new System.Windows.Input.InputScopeNameConverter(); break; + case KnownElements.Int16Animation: o = new System.Windows.Media.Animation.Int16Animation(); break; + case KnownElements.Int16AnimationUsingKeyFrames: o = new System.Windows.Media.Animation.Int16AnimationUsingKeyFrames(); break; + case KnownElements.Int16Converter: o = new System.ComponentModel.Int16Converter(); break; + case KnownElements.Int16KeyFrameCollection: o = new System.Windows.Media.Animation.Int16KeyFrameCollection(); break; + case KnownElements.Int32Animation: o = new System.Windows.Media.Animation.Int32Animation(); break; + case KnownElements.Int32AnimationUsingKeyFrames: o = new System.Windows.Media.Animation.Int32AnimationUsingKeyFrames(); break; + case KnownElements.Int32Collection: o = new System.Windows.Media.Int32Collection(); break; + case KnownElements.Int32CollectionConverter: o = new System.Windows.Media.Int32CollectionConverter(); break; + case KnownElements.Int32Converter: o = new System.ComponentModel.Int32Converter(); break; + case KnownElements.Int32KeyFrameCollection: o = new System.Windows.Media.Animation.Int32KeyFrameCollection(); break; + case KnownElements.Int32Rect: o = new System.Windows.Int32Rect(); break; + case KnownElements.Int32RectConverter: o = new System.Windows.Int32RectConverter(); break; + case KnownElements.Int64Animation: o = new System.Windows.Media.Animation.Int64Animation(); break; + case KnownElements.Int64AnimationUsingKeyFrames: o = new System.Windows.Media.Animation.Int64AnimationUsingKeyFrames(); break; + case KnownElements.Int64Converter: o = new System.ComponentModel.Int64Converter(); break; + case KnownElements.Int64KeyFrameCollection: o = new System.Windows.Media.Animation.Int64KeyFrameCollection(); break; + case KnownElements.Italic: o = new System.Windows.Documents.Italic(); break; + case KnownElements.ItemsControl: o = new System.Windows.Controls.ItemsControl(); break; + case KnownElements.ItemsPanelTemplate: o = new System.Windows.Controls.ItemsPanelTemplate(); break; + case KnownElements.ItemsPresenter: o = new System.Windows.Controls.ItemsPresenter(); break; + case KnownElements.JournalEntryListConverter: o = new System.Windows.Navigation.JournalEntryListConverter(); break; + case KnownElements.JournalEntryUnifiedViewConverter: o = new System.Windows.Navigation.JournalEntryUnifiedViewConverter(); break; + case KnownElements.JpegBitmapEncoder: o = new System.Windows.Media.Imaging.JpegBitmapEncoder(); break; + case KnownElements.KeyBinding: o = new System.Windows.Input.KeyBinding(); break; + case KnownElements.KeyConverter: o = new System.Windows.Input.KeyConverter(); break; + case KnownElements.KeyGestureConverter: o = new System.Windows.Input.KeyGestureConverter(); break; + case KnownElements.KeySpline: o = new System.Windows.Media.Animation.KeySpline(); break; + case KnownElements.KeySplineConverter: o = new System.Windows.KeySplineConverter(); break; + case KnownElements.KeyTime: o = new System.Windows.Media.Animation.KeyTime(); break; + case KnownElements.KeyTimeConverter: o = new System.Windows.KeyTimeConverter(); break; + case KnownElements.Label: o = new System.Windows.Controls.Label(); break; + case KnownElements.LengthConverter: o = new System.Windows.LengthConverter(); break; + case KnownElements.Line: o = new System.Windows.Shapes.Line(); break; + case KnownElements.LineBreak: o = new System.Windows.Documents.LineBreak(); break; + case KnownElements.LineGeometry: o = new System.Windows.Media.LineGeometry(); break; + case KnownElements.LineSegment: o = new System.Windows.Media.LineSegment(); break; + case KnownElements.LinearByteKeyFrame: o = new System.Windows.Media.Animation.LinearByteKeyFrame(); break; + case KnownElements.LinearColorKeyFrame: o = new System.Windows.Media.Animation.LinearColorKeyFrame(); break; + case KnownElements.LinearDecimalKeyFrame: o = new System.Windows.Media.Animation.LinearDecimalKeyFrame(); break; + case KnownElements.LinearDoubleKeyFrame: o = new System.Windows.Media.Animation.LinearDoubleKeyFrame(); break; + case KnownElements.LinearGradientBrush: o = new System.Windows.Media.LinearGradientBrush(); break; + case KnownElements.LinearInt16KeyFrame: o = new System.Windows.Media.Animation.LinearInt16KeyFrame(); break; + case KnownElements.LinearInt32KeyFrame: o = new System.Windows.Media.Animation.LinearInt32KeyFrame(); break; + case KnownElements.LinearInt64KeyFrame: o = new System.Windows.Media.Animation.LinearInt64KeyFrame(); break; + case KnownElements.LinearPoint3DKeyFrame: o = new System.Windows.Media.Animation.LinearPoint3DKeyFrame(); break; + case KnownElements.LinearPointKeyFrame: o = new System.Windows.Media.Animation.LinearPointKeyFrame(); break; + case KnownElements.LinearQuaternionKeyFrame: o = new System.Windows.Media.Animation.LinearQuaternionKeyFrame(); break; + case KnownElements.LinearRectKeyFrame: o = new System.Windows.Media.Animation.LinearRectKeyFrame(); break; + case KnownElements.LinearRotation3DKeyFrame: o = new System.Windows.Media.Animation.LinearRotation3DKeyFrame(); break; + case KnownElements.LinearSingleKeyFrame: o = new System.Windows.Media.Animation.LinearSingleKeyFrame(); break; + case KnownElements.LinearSizeKeyFrame: o = new System.Windows.Media.Animation.LinearSizeKeyFrame(); break; + case KnownElements.LinearThicknessKeyFrame: o = new System.Windows.Media.Animation.LinearThicknessKeyFrame(); break; + case KnownElements.LinearVector3DKeyFrame: o = new System.Windows.Media.Animation.LinearVector3DKeyFrame(); break; + case KnownElements.LinearVectorKeyFrame: o = new System.Windows.Media.Animation.LinearVectorKeyFrame(); break; + case KnownElements.List: o = new System.Windows.Documents.List(); break; + case KnownElements.ListBox: o = new System.Windows.Controls.ListBox(); break; + case KnownElements.ListBoxItem: o = new System.Windows.Controls.ListBoxItem(); break; + case KnownElements.ListItem: o = new System.Windows.Documents.ListItem(); break; + case KnownElements.ListView: o = new System.Windows.Controls.ListView(); break; + case KnownElements.ListViewItem: o = new System.Windows.Controls.ListViewItem(); break; + case KnownElements.MaterialCollection: o = new System.Windows.Media.Media3D.MaterialCollection(); break; + case KnownElements.MaterialGroup: o = new System.Windows.Media.Media3D.MaterialGroup(); break; + case KnownElements.Matrix: o = new System.Windows.Media.Matrix(); break; + case KnownElements.Matrix3D: o = new System.Windows.Media.Media3D.Matrix3D(); break; + case KnownElements.Matrix3DConverter: o = new System.Windows.Media.Media3D.Matrix3DConverter(); break; + case KnownElements.MatrixAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.MatrixAnimationUsingKeyFrames(); break; + case KnownElements.MatrixAnimationUsingPath: o = new System.Windows.Media.Animation.MatrixAnimationUsingPath(); break; + case KnownElements.MatrixCamera: o = new System.Windows.Media.Media3D.MatrixCamera(); break; + case KnownElements.MatrixConverter: o = new System.Windows.Media.MatrixConverter(); break; + case KnownElements.MatrixKeyFrameCollection: o = new System.Windows.Media.Animation.MatrixKeyFrameCollection(); break; + case KnownElements.MatrixTransform: o = new System.Windows.Media.MatrixTransform(); break; + case KnownElements.MatrixTransform3D: o = new System.Windows.Media.Media3D.MatrixTransform3D(); break; + case KnownElements.MediaElement: o = new System.Windows.Controls.MediaElement(); break; + case KnownElements.MediaPlayer: o = new System.Windows.Media.MediaPlayer(); break; + case KnownElements.MediaTimeline: o = new System.Windows.Media.MediaTimeline(); break; + case KnownElements.Menu: o = new System.Windows.Controls.Menu(); break; + case KnownElements.MenuItem: o = new System.Windows.Controls.MenuItem(); break; + case KnownElements.MenuScrollingVisibilityConverter: o = new System.Windows.Controls.MenuScrollingVisibilityConverter(); break; + case KnownElements.MeshGeometry3D: o = new System.Windows.Media.Media3D.MeshGeometry3D(); break; + case KnownElements.Model3DCollection: o = new System.Windows.Media.Media3D.Model3DCollection(); break; + case KnownElements.Model3DGroup: o = new System.Windows.Media.Media3D.Model3DGroup(); break; + case KnownElements.ModelVisual3D: o = new System.Windows.Media.Media3D.ModelVisual3D(); break; + case KnownElements.ModifierKeysConverter: o = new System.Windows.Input.ModifierKeysConverter(); break; + case KnownElements.MouseActionConverter: o = new System.Windows.Input.MouseActionConverter(); break; + case KnownElements.MouseBinding: o = new System.Windows.Input.MouseBinding(); break; + case KnownElements.MouseGesture: o = new System.Windows.Input.MouseGesture(); break; + case KnownElements.MouseGestureConverter: o = new System.Windows.Input.MouseGestureConverter(); break; + case KnownElements.MultiBinding: o = new System.Windows.Data.MultiBinding(); break; + case KnownElements.MultiDataTrigger: o = new System.Windows.MultiDataTrigger(); break; + case KnownElements.MultiTrigger: o = new System.Windows.MultiTrigger(); break; + case KnownElements.NameScope: o = new System.Windows.NameScope(); break; + case KnownElements.NavigationWindow: o = new System.Windows.Navigation.NavigationWindow(); break; + case KnownElements.NullExtension: o = new System.Windows.Markup.NullExtension(); break; + case KnownElements.NullableBoolConverter: o = new System.Windows.NullableBoolConverter(); break; + case KnownElements.NumberSubstitution: o = new System.Windows.Media.NumberSubstitution(); break; + case KnownElements.Object: o = new System.Object(); break; + case KnownElements.ObjectAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames(); break; + case KnownElements.ObjectDataProvider: o = new System.Windows.Data.ObjectDataProvider(); break; + case KnownElements.ObjectKeyFrameCollection: o = new System.Windows.Media.Animation.ObjectKeyFrameCollection(); break; + case KnownElements.OrthographicCamera: o = new System.Windows.Media.Media3D.OrthographicCamera(); break; + case KnownElements.OuterGlowBitmapEffect: o = new System.Windows.Media.Effects.OuterGlowBitmapEffect(); break; + case KnownElements.Page: o = new System.Windows.Controls.Page(); break; + case KnownElements.PageContent: o = new System.Windows.Documents.PageContent(); break; + case KnownElements.Paragraph: o = new System.Windows.Documents.Paragraph(); break; + case KnownElements.ParallelTimeline: o = new System.Windows.Media.Animation.ParallelTimeline(); break; + case KnownElements.ParserContext: o = new System.Windows.Markup.ParserContext(); break; + case KnownElements.PasswordBox: o = new System.Windows.Controls.PasswordBox(); break; + case KnownElements.Path: o = new System.Windows.Shapes.Path(); break; + case KnownElements.PathFigure: o = new System.Windows.Media.PathFigure(); break; + case KnownElements.PathFigureCollection: o = new System.Windows.Media.PathFigureCollection(); break; + case KnownElements.PathFigureCollectionConverter: o = new System.Windows.Media.PathFigureCollectionConverter(); break; + case KnownElements.PathGeometry: o = new System.Windows.Media.PathGeometry(); break; + case KnownElements.PathSegmentCollection: o = new System.Windows.Media.PathSegmentCollection(); break; + case KnownElements.PauseStoryboard: o = new System.Windows.Media.Animation.PauseStoryboard(); break; + case KnownElements.Pen: o = new System.Windows.Media.Pen(); break; + case KnownElements.PerspectiveCamera: o = new System.Windows.Media.Media3D.PerspectiveCamera(); break; + case KnownElements.PixelFormat: o = new System.Windows.Media.PixelFormat(); break; + case KnownElements.PixelFormatConverter: o = new System.Windows.Media.PixelFormatConverter(); break; + case KnownElements.PngBitmapEncoder: o = new System.Windows.Media.Imaging.PngBitmapEncoder(); break; + case KnownElements.Point: o = new System.Windows.Point(); break; + case KnownElements.Point3D: o = new System.Windows.Media.Media3D.Point3D(); break; + case KnownElements.Point3DAnimation: o = new System.Windows.Media.Animation.Point3DAnimation(); break; + case KnownElements.Point3DAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.Point3DAnimationUsingKeyFrames(); break; + case KnownElements.Point3DCollection: o = new System.Windows.Media.Media3D.Point3DCollection(); break; + case KnownElements.Point3DCollectionConverter: o = new System.Windows.Media.Media3D.Point3DCollectionConverter(); break; + case KnownElements.Point3DConverter: o = new System.Windows.Media.Media3D.Point3DConverter(); break; + case KnownElements.Point3DKeyFrameCollection: o = new System.Windows.Media.Animation.Point3DKeyFrameCollection(); break; + case KnownElements.Point4D: o = new System.Windows.Media.Media3D.Point4D(); break; + case KnownElements.Point4DConverter: o = new System.Windows.Media.Media3D.Point4DConverter(); break; + case KnownElements.PointAnimation: o = new System.Windows.Media.Animation.PointAnimation(); break; + case KnownElements.PointAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.PointAnimationUsingKeyFrames(); break; + case KnownElements.PointAnimationUsingPath: o = new System.Windows.Media.Animation.PointAnimationUsingPath(); break; + case KnownElements.PointCollection: o = new System.Windows.Media.PointCollection(); break; + case KnownElements.PointCollectionConverter: o = new System.Windows.Media.PointCollectionConverter(); break; + case KnownElements.PointConverter: o = new System.Windows.PointConverter(); break; + case KnownElements.PointIListConverter: o = new System.Windows.Media.Converters.PointIListConverter(); break; + case KnownElements.PointKeyFrameCollection: o = new System.Windows.Media.Animation.PointKeyFrameCollection(); break; + case KnownElements.PointLight: o = new System.Windows.Media.Media3D.PointLight(); break; + case KnownElements.PolyBezierSegment: o = new System.Windows.Media.PolyBezierSegment(); break; + case KnownElements.PolyLineSegment: o = new System.Windows.Media.PolyLineSegment(); break; + case KnownElements.PolyQuadraticBezierSegment: o = new System.Windows.Media.PolyQuadraticBezierSegment(); break; + case KnownElements.Polygon: o = new System.Windows.Shapes.Polygon(); break; + case KnownElements.Polyline: o = new System.Windows.Shapes.Polyline(); break; + case KnownElements.Popup: o = new System.Windows.Controls.Primitives.Popup(); break; + case KnownElements.PriorityBinding: o = new System.Windows.Data.PriorityBinding(); break; + case KnownElements.ProgressBar: o = new System.Windows.Controls.ProgressBar(); break; + case KnownElements.PropertyPathConverter: o = new System.Windows.PropertyPathConverter(); break; + case KnownElements.QuadraticBezierSegment: o = new System.Windows.Media.QuadraticBezierSegment(); break; + case KnownElements.Quaternion: o = new System.Windows.Media.Media3D.Quaternion(); break; + case KnownElements.QuaternionAnimation: o = new System.Windows.Media.Animation.QuaternionAnimation(); break; + case KnownElements.QuaternionAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.QuaternionAnimationUsingKeyFrames(); break; + case KnownElements.QuaternionConverter: o = new System.Windows.Media.Media3D.QuaternionConverter(); break; + case KnownElements.QuaternionKeyFrameCollection: o = new System.Windows.Media.Animation.QuaternionKeyFrameCollection(); break; + case KnownElements.QuaternionRotation3D: o = new System.Windows.Media.Media3D.QuaternionRotation3D(); break; + case KnownElements.RadialGradientBrush: o = new System.Windows.Media.RadialGradientBrush(); break; + case KnownElements.RadioButton: o = new System.Windows.Controls.RadioButton(); break; + case KnownElements.Rect: o = new System.Windows.Rect(); break; + case KnownElements.Rect3D: o = new System.Windows.Media.Media3D.Rect3D(); break; + case KnownElements.Rect3DConverter: o = new System.Windows.Media.Media3D.Rect3DConverter(); break; + case KnownElements.RectAnimation: o = new System.Windows.Media.Animation.RectAnimation(); break; + case KnownElements.RectAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.RectAnimationUsingKeyFrames(); break; + case KnownElements.RectConverter: o = new System.Windows.RectConverter(); break; + case KnownElements.RectKeyFrameCollection: o = new System.Windows.Media.Animation.RectKeyFrameCollection(); break; + case KnownElements.Rectangle: o = new System.Windows.Shapes.Rectangle(); break; + case KnownElements.RectangleGeometry: o = new System.Windows.Media.RectangleGeometry(); break; + case KnownElements.RelativeSource: o = new System.Windows.Data.RelativeSource(); break; + case KnownElements.RemoveStoryboard: o = new System.Windows.Media.Animation.RemoveStoryboard(); break; + case KnownElements.RepeatBehavior: o = new System.Windows.Media.Animation.RepeatBehavior(); break; + case KnownElements.RepeatBehaviorConverter: o = new System.Windows.Media.Animation.RepeatBehaviorConverter(); break; + case KnownElements.RepeatButton: o = new System.Windows.Controls.Primitives.RepeatButton(); break; + case KnownElements.ResizeGrip: o = new System.Windows.Controls.Primitives.ResizeGrip(); break; + case KnownElements.ResourceDictionary: o = new System.Windows.ResourceDictionary(); break; + case KnownElements.ResumeStoryboard: o = new System.Windows.Media.Animation.ResumeStoryboard(); break; + case KnownElements.RichTextBox: o = new System.Windows.Controls.RichTextBox(); break; + case KnownElements.RotateTransform: o = new System.Windows.Media.RotateTransform(); break; + case KnownElements.RotateTransform3D: o = new System.Windows.Media.Media3D.RotateTransform3D(); break; + case KnownElements.Rotation3DAnimation: o = new System.Windows.Media.Animation.Rotation3DAnimation(); break; + case KnownElements.Rotation3DAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.Rotation3DAnimationUsingKeyFrames(); break; + case KnownElements.Rotation3DKeyFrameCollection: o = new System.Windows.Media.Animation.Rotation3DKeyFrameCollection(); break; + case KnownElements.RoutedCommand: o = new System.Windows.Input.RoutedCommand(); break; + case KnownElements.RoutedEventConverter: o = new System.Windows.Markup.RoutedEventConverter(); break; + case KnownElements.RoutedUICommand: o = new System.Windows.Input.RoutedUICommand(); break; + case KnownElements.RowDefinition: o = new System.Windows.Controls.RowDefinition(); break; + case KnownElements.Run: o = new System.Windows.Documents.Run(); break; + case KnownElements.SByteConverter: o = new System.ComponentModel.SByteConverter(); break; + case KnownElements.ScaleTransform: o = new System.Windows.Media.ScaleTransform(); break; + case KnownElements.ScaleTransform3D: o = new System.Windows.Media.Media3D.ScaleTransform3D(); break; + case KnownElements.ScrollBar: o = new System.Windows.Controls.Primitives.ScrollBar(); break; + case KnownElements.ScrollContentPresenter: o = new System.Windows.Controls.ScrollContentPresenter(); break; + case KnownElements.ScrollViewer: o = new System.Windows.Controls.ScrollViewer(); break; + case KnownElements.Section: o = new System.Windows.Documents.Section(); break; + case KnownElements.SeekStoryboard: o = new System.Windows.Media.Animation.SeekStoryboard(); break; + case KnownElements.Separator: o = new System.Windows.Controls.Separator(); break; + case KnownElements.SetStoryboardSpeedRatio: o = new System.Windows.Media.Animation.SetStoryboardSpeedRatio(); break; + case KnownElements.Setter: o = new System.Windows.Setter(); break; + case KnownElements.SingleAnimation: o = new System.Windows.Media.Animation.SingleAnimation(); break; + case KnownElements.SingleAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.SingleAnimationUsingKeyFrames(); break; + case KnownElements.SingleConverter: o = new System.ComponentModel.SingleConverter(); break; + case KnownElements.SingleKeyFrameCollection: o = new System.Windows.Media.Animation.SingleKeyFrameCollection(); break; + case KnownElements.Size: o = new System.Windows.Size(); break; + case KnownElements.Size3D: o = new System.Windows.Media.Media3D.Size3D(); break; + case KnownElements.Size3DConverter: o = new System.Windows.Media.Media3D.Size3DConverter(); break; + case KnownElements.SizeAnimation: o = new System.Windows.Media.Animation.SizeAnimation(); break; + case KnownElements.SizeAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.SizeAnimationUsingKeyFrames(); break; + case KnownElements.SizeConverter: o = new System.Windows.SizeConverter(); break; + case KnownElements.SizeKeyFrameCollection: o = new System.Windows.Media.Animation.SizeKeyFrameCollection(); break; + case KnownElements.SkewTransform: o = new System.Windows.Media.SkewTransform(); break; + case KnownElements.SkipStoryboardToFill: o = new System.Windows.Media.Animation.SkipStoryboardToFill(); break; + case KnownElements.Slider: o = new System.Windows.Controls.Slider(); break; + case KnownElements.SolidColorBrush: o = new System.Windows.Media.SolidColorBrush(); break; + case KnownElements.SoundPlayerAction: o = new System.Windows.Controls.SoundPlayerAction(); break; + case KnownElements.Span: o = new System.Windows.Documents.Span(); break; + case KnownElements.SpecularMaterial: o = new System.Windows.Media.Media3D.SpecularMaterial(); break; + case KnownElements.SplineByteKeyFrame: o = new System.Windows.Media.Animation.SplineByteKeyFrame(); break; + case KnownElements.SplineColorKeyFrame: o = new System.Windows.Media.Animation.SplineColorKeyFrame(); break; + case KnownElements.SplineDecimalKeyFrame: o = new System.Windows.Media.Animation.SplineDecimalKeyFrame(); break; + case KnownElements.SplineDoubleKeyFrame: o = new System.Windows.Media.Animation.SplineDoubleKeyFrame(); break; + case KnownElements.SplineInt16KeyFrame: o = new System.Windows.Media.Animation.SplineInt16KeyFrame(); break; + case KnownElements.SplineInt32KeyFrame: o = new System.Windows.Media.Animation.SplineInt32KeyFrame(); break; + case KnownElements.SplineInt64KeyFrame: o = new System.Windows.Media.Animation.SplineInt64KeyFrame(); break; + case KnownElements.SplinePoint3DKeyFrame: o = new System.Windows.Media.Animation.SplinePoint3DKeyFrame(); break; + case KnownElements.SplinePointKeyFrame: o = new System.Windows.Media.Animation.SplinePointKeyFrame(); break; + case KnownElements.SplineQuaternionKeyFrame: o = new System.Windows.Media.Animation.SplineQuaternionKeyFrame(); break; + case KnownElements.SplineRectKeyFrame: o = new System.Windows.Media.Animation.SplineRectKeyFrame(); break; + case KnownElements.SplineRotation3DKeyFrame: o = new System.Windows.Media.Animation.SplineRotation3DKeyFrame(); break; + case KnownElements.SplineSingleKeyFrame: o = new System.Windows.Media.Animation.SplineSingleKeyFrame(); break; + case KnownElements.SplineSizeKeyFrame: o = new System.Windows.Media.Animation.SplineSizeKeyFrame(); break; + case KnownElements.SplineThicknessKeyFrame: o = new System.Windows.Media.Animation.SplineThicknessKeyFrame(); break; + case KnownElements.SplineVector3DKeyFrame: o = new System.Windows.Media.Animation.SplineVector3DKeyFrame(); break; + case KnownElements.SplineVectorKeyFrame: o = new System.Windows.Media.Animation.SplineVectorKeyFrame(); break; + case KnownElements.SpotLight: o = new System.Windows.Media.Media3D.SpotLight(); break; + case KnownElements.StackPanel: o = new System.Windows.Controls.StackPanel(); break; + case KnownElements.StaticExtension: o = new System.Windows.Markup.StaticExtension(); break; + case KnownElements.StaticResourceExtension: o = new System.Windows.StaticResourceExtension(); break; + case KnownElements.StatusBar: o = new System.Windows.Controls.Primitives.StatusBar(); break; + case KnownElements.StatusBarItem: o = new System.Windows.Controls.Primitives.StatusBarItem(); break; + case KnownElements.StopStoryboard: o = new System.Windows.Media.Animation.StopStoryboard(); break; + case KnownElements.Storyboard: o = new System.Windows.Media.Animation.Storyboard(); break; + case KnownElements.StreamGeometry: o = new System.Windows.Media.StreamGeometry(); break; + case KnownElements.StreamResourceInfo: o = new System.Windows.Resources.StreamResourceInfo(); break; + case KnownElements.StringAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.StringAnimationUsingKeyFrames(); break; + case KnownElements.StringConverter: o = new System.ComponentModel.StringConverter(); break; + case KnownElements.StringKeyFrameCollection: o = new System.Windows.Media.Animation.StringKeyFrameCollection(); break; + case KnownElements.StrokeCollection: o = new System.Windows.Ink.StrokeCollection(); break; + case KnownElements.StrokeCollectionConverter: o = new System.Windows.StrokeCollectionConverter(); break; + case KnownElements.Style: o = new System.Windows.Style(); break; + case KnownElements.TabControl: o = new System.Windows.Controls.TabControl(); break; + case KnownElements.TabItem: o = new System.Windows.Controls.TabItem(); break; + case KnownElements.TabPanel: o = new System.Windows.Controls.Primitives.TabPanel(); break; + case KnownElements.Table: o = new System.Windows.Documents.Table(); break; + case KnownElements.TableCell: o = new System.Windows.Documents.TableCell(); break; + case KnownElements.TableColumn: o = new System.Windows.Documents.TableColumn(); break; + case KnownElements.TableRow: o = new System.Windows.Documents.TableRow(); break; + case KnownElements.TableRowGroup: o = new System.Windows.Documents.TableRowGroup(); break; + case KnownElements.TemplateBindingExpressionConverter: o = new System.Windows.TemplateBindingExpressionConverter(); break; + case KnownElements.TemplateBindingExtension: o = new System.Windows.TemplateBindingExtension(); break; + case KnownElements.TemplateBindingExtensionConverter: o = new System.Windows.TemplateBindingExtensionConverter(); break; + case KnownElements.TemplateKeyConverter: o = new System.Windows.Markup.TemplateKeyConverter(); break; + case KnownElements.TextBlock: o = new System.Windows.Controls.TextBlock(); break; + case KnownElements.TextBox: o = new System.Windows.Controls.TextBox(); break; + case KnownElements.TextDecoration: o = new System.Windows.TextDecoration(); break; + case KnownElements.TextDecorationCollection: o = new System.Windows.TextDecorationCollection(); break; + case KnownElements.TextDecorationCollectionConverter: o = new System.Windows.TextDecorationCollectionConverter(); break; + case KnownElements.TextEffect: o = new System.Windows.Media.TextEffect(); break; + case KnownElements.TextEffectCollection: o = new System.Windows.Media.TextEffectCollection(); break; + case KnownElements.ThemeDictionaryExtension: o = new System.Windows.ThemeDictionaryExtension(); break; + case KnownElements.Thickness: o = new System.Windows.Thickness(); break; + case KnownElements.ThicknessAnimation: o = new System.Windows.Media.Animation.ThicknessAnimation(); break; + case KnownElements.ThicknessAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.ThicknessAnimationUsingKeyFrames(); break; + case KnownElements.ThicknessConverter: o = new System.Windows.ThicknessConverter(); break; + case KnownElements.ThicknessKeyFrameCollection: o = new System.Windows.Media.Animation.ThicknessKeyFrameCollection(); break; + case KnownElements.Thumb: o = new System.Windows.Controls.Primitives.Thumb(); break; + case KnownElements.TickBar: o = new System.Windows.Controls.Primitives.TickBar(); break; + case KnownElements.TiffBitmapEncoder: o = new System.Windows.Media.Imaging.TiffBitmapEncoder(); break; + case KnownElements.TimeSpanConverter: o = new System.ComponentModel.TimeSpanConverter(); break; + case KnownElements.TimelineCollection: o = new System.Windows.Media.Animation.TimelineCollection(); break; + case KnownElements.ToggleButton: o = new System.Windows.Controls.Primitives.ToggleButton(); break; + case KnownElements.ToolBar: o = new System.Windows.Controls.ToolBar(); break; + case KnownElements.ToolBarOverflowPanel: o = new System.Windows.Controls.Primitives.ToolBarOverflowPanel(); break; + case KnownElements.ToolBarPanel: o = new System.Windows.Controls.Primitives.ToolBarPanel(); break; + case KnownElements.ToolBarTray: o = new System.Windows.Controls.ToolBarTray(); break; + case KnownElements.ToolTip: o = new System.Windows.Controls.ToolTip(); break; + case KnownElements.Track: o = new System.Windows.Controls.Primitives.Track(); break; + case KnownElements.Transform3DCollection: o = new System.Windows.Media.Media3D.Transform3DCollection(); break; + case KnownElements.Transform3DGroup: o = new System.Windows.Media.Media3D.Transform3DGroup(); break; + case KnownElements.TransformCollection: o = new System.Windows.Media.TransformCollection(); break; + case KnownElements.TransformConverter: o = new System.Windows.Media.TransformConverter(); break; + case KnownElements.TransformGroup: o = new System.Windows.Media.TransformGroup(); break; + case KnownElements.TransformedBitmap: o = new System.Windows.Media.Imaging.TransformedBitmap(); break; + case KnownElements.TranslateTransform: o = new System.Windows.Media.TranslateTransform(); break; + case KnownElements.TranslateTransform3D: o = new System.Windows.Media.Media3D.TranslateTransform3D(); break; + case KnownElements.TreeView: o = new System.Windows.Controls.TreeView(); break; + case KnownElements.TreeViewItem: o = new System.Windows.Controls.TreeViewItem(); break; + case KnownElements.Trigger: o = new System.Windows.Trigger(); break; + case KnownElements.TypeExtension: o = new System.Windows.Markup.TypeExtension(); break; + case KnownElements.TypeTypeConverter: o = new System.Windows.Markup.TypeTypeConverter(); break; + case KnownElements.UIElement: o = new System.Windows.UIElement(); break; + case KnownElements.UInt16Converter: o = new System.ComponentModel.UInt16Converter(); break; + case KnownElements.UInt32Converter: o = new System.ComponentModel.UInt32Converter(); break; + case KnownElements.UInt64Converter: o = new System.ComponentModel.UInt64Converter(); break; + case KnownElements.UShortIListConverter: o = new System.Windows.Media.Converters.UShortIListConverter(); break; + case KnownElements.Underline: o = new System.Windows.Documents.Underline(); break; + case KnownElements.UniformGrid: o = new System.Windows.Controls.Primitives.UniformGrid(); break; + case KnownElements.UriTypeConverter: o = new System.UriTypeConverter(); break; + case KnownElements.UserControl: o = new System.Windows.Controls.UserControl(); break; + case KnownElements.Vector: o = new System.Windows.Vector(); break; + case KnownElements.Vector3D: o = new System.Windows.Media.Media3D.Vector3D(); break; + case KnownElements.Vector3DAnimation: o = new System.Windows.Media.Animation.Vector3DAnimation(); break; + case KnownElements.Vector3DAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.Vector3DAnimationUsingKeyFrames(); break; + case KnownElements.Vector3DCollection: o = new System.Windows.Media.Media3D.Vector3DCollection(); break; + case KnownElements.Vector3DCollectionConverter: o = new System.Windows.Media.Media3D.Vector3DCollectionConverter(); break; + case KnownElements.Vector3DConverter: o = new System.Windows.Media.Media3D.Vector3DConverter(); break; + case KnownElements.Vector3DKeyFrameCollection: o = new System.Windows.Media.Animation.Vector3DKeyFrameCollection(); break; + case KnownElements.VectorAnimation: o = new System.Windows.Media.Animation.VectorAnimation(); break; + case KnownElements.VectorAnimationUsingKeyFrames: o = new System.Windows.Media.Animation.VectorAnimationUsingKeyFrames(); break; + case KnownElements.VectorCollection: o = new System.Windows.Media.VectorCollection(); break; + case KnownElements.VectorCollectionConverter: o = new System.Windows.Media.VectorCollectionConverter(); break; + case KnownElements.VectorConverter: o = new System.Windows.VectorConverter(); break; + case KnownElements.VectorKeyFrameCollection: o = new System.Windows.Media.Animation.VectorKeyFrameCollection(); break; + case KnownElements.VideoDrawing: o = new System.Windows.Media.VideoDrawing(); break; + case KnownElements.Viewbox: o = new System.Windows.Controls.Viewbox(); break; + case KnownElements.Viewport3D: o = new System.Windows.Controls.Viewport3D(); break; + case KnownElements.Viewport3DVisual: o = new System.Windows.Media.Media3D.Viewport3DVisual(); break; + case KnownElements.VirtualizingStackPanel: o = new System.Windows.Controls.VirtualizingStackPanel(); break; + case KnownElements.VisualBrush: o = new System.Windows.Media.VisualBrush(); break; + case KnownElements.Window: o = new System.Windows.Window(); break; + case KnownElements.WmpBitmapEncoder: o = new System.Windows.Media.Imaging.WmpBitmapEncoder(); break; + case KnownElements.WrapPanel: o = new System.Windows.Controls.WrapPanel(); break; + case KnownElements.XamlBrushSerializer: o = new System.Windows.Markup.XamlBrushSerializer(); break; + case KnownElements.XamlInt32CollectionSerializer: o = new System.Windows.Markup.XamlInt32CollectionSerializer(); break; + case KnownElements.XamlPathDataSerializer: o = new System.Windows.Markup.XamlPathDataSerializer(); break; + case KnownElements.XamlPoint3DCollectionSerializer: o = new System.Windows.Markup.XamlPoint3DCollectionSerializer(); break; + case KnownElements.XamlPointCollectionSerializer: o = new System.Windows.Markup.XamlPointCollectionSerializer(); break; + case KnownElements.XamlStyleSerializer: o = new System.Windows.Markup.XamlStyleSerializer(); break; + case KnownElements.XamlTemplateSerializer: o = new System.Windows.Markup.XamlTemplateSerializer(); break; + case KnownElements.XamlVector3DCollectionSerializer: o = new System.Windows.Markup.XamlVector3DCollectionSerializer(); break; + case KnownElements.XmlDataProvider: o = new System.Windows.Data.XmlDataProvider(); break; + case KnownElements.XmlLanguageConverter: o = new System.Windows.Markup.XmlLanguageConverter(); break; + case KnownElements.XmlNamespaceMapping: o = new System.Windows.Data.XmlNamespaceMapping(); break; + case KnownElements.ZoomPercentageConverter: o = new System.Windows.Documents.ZoomPercentageConverter(); break; + } + return o; + } + + internal static DependencyProperty GetKnownDependencyPropertyFromId(KnownProperties knownProperty) + { + switch (knownProperty) + { + case KnownProperties.AccessText_Text: + return System.Windows.Controls.AccessText.TextProperty; + case KnownProperties.BeginStoryboard_Storyboard: + return System.Windows.Media.Animation.BeginStoryboard.StoryboardProperty; + case KnownProperties.BitmapEffectGroup_Children: + return System.Windows.Media.Effects.BitmapEffectGroup.ChildrenProperty; + case KnownProperties.Border_Background: + return System.Windows.Controls.Border.BackgroundProperty; + case KnownProperties.Border_BorderBrush: + return System.Windows.Controls.Border.BorderBrushProperty; + case KnownProperties.Border_BorderThickness: + return System.Windows.Controls.Border.BorderThicknessProperty; + case KnownProperties.ButtonBase_Command: + return System.Windows.Controls.Primitives.ButtonBase.CommandProperty; + case KnownProperties.ButtonBase_CommandParameter: + return System.Windows.Controls.Primitives.ButtonBase.CommandParameterProperty; + case KnownProperties.ButtonBase_CommandTarget: + return System.Windows.Controls.Primitives.ButtonBase.CommandTargetProperty; + case KnownProperties.ButtonBase_IsPressed: + return System.Windows.Controls.Primitives.ButtonBase.IsPressedProperty; + case KnownProperties.ColumnDefinition_MaxWidth: + return System.Windows.Controls.ColumnDefinition.MaxWidthProperty; + case KnownProperties.ColumnDefinition_MinWidth: + return System.Windows.Controls.ColumnDefinition.MinWidthProperty; + case KnownProperties.ColumnDefinition_Width: + return System.Windows.Controls.ColumnDefinition.WidthProperty; + case KnownProperties.ContentControl_Content: + return System.Windows.Controls.ContentControl.ContentProperty; + case KnownProperties.ContentControl_ContentTemplate: + return System.Windows.Controls.ContentControl.ContentTemplateProperty; + case KnownProperties.ContentControl_ContentTemplateSelector: + return System.Windows.Controls.ContentControl.ContentTemplateSelectorProperty; + case KnownProperties.ContentControl_HasContent: + return System.Windows.Controls.ContentControl.HasContentProperty; + case KnownProperties.ContentElement_Focusable: + return System.Windows.ContentElement.FocusableProperty; + case KnownProperties.ContentPresenter_Content: + return System.Windows.Controls.ContentPresenter.ContentProperty; + case KnownProperties.ContentPresenter_ContentSource: + return System.Windows.Controls.ContentPresenter.ContentSourceProperty; + case KnownProperties.ContentPresenter_ContentTemplate: + return System.Windows.Controls.ContentPresenter.ContentTemplateProperty; + case KnownProperties.ContentPresenter_ContentTemplateSelector: + return System.Windows.Controls.ContentPresenter.ContentTemplateSelectorProperty; + case KnownProperties.ContentPresenter_RecognizesAccessKey: + return System.Windows.Controls.ContentPresenter.RecognizesAccessKeyProperty; + case KnownProperties.Control_Background: + return System.Windows.Controls.Control.BackgroundProperty; + case KnownProperties.Control_BorderBrush: + return System.Windows.Controls.Control.BorderBrushProperty; + case KnownProperties.Control_BorderThickness: + return System.Windows.Controls.Control.BorderThicknessProperty; + case KnownProperties.Control_FontFamily: + return System.Windows.Controls.Control.FontFamilyProperty; + case KnownProperties.Control_FontSize: + return System.Windows.Controls.Control.FontSizeProperty; + case KnownProperties.Control_FontStretch: + return System.Windows.Controls.Control.FontStretchProperty; + case KnownProperties.Control_FontStyle: + return System.Windows.Controls.Control.FontStyleProperty; + case KnownProperties.Control_FontWeight: + return System.Windows.Controls.Control.FontWeightProperty; + case KnownProperties.Control_Foreground: + return System.Windows.Controls.Control.ForegroundProperty; + case KnownProperties.Control_HorizontalContentAlignment: + return System.Windows.Controls.Control.HorizontalContentAlignmentProperty; + case KnownProperties.Control_IsTabStop: + return System.Windows.Controls.Control.IsTabStopProperty; + case KnownProperties.Control_Padding: + return System.Windows.Controls.Control.PaddingProperty; + case KnownProperties.Control_TabIndex: + return System.Windows.Controls.Control.TabIndexProperty; + case KnownProperties.Control_Template: + return System.Windows.Controls.Control.TemplateProperty; + case KnownProperties.Control_VerticalContentAlignment: + return System.Windows.Controls.Control.VerticalContentAlignmentProperty; + case KnownProperties.DockPanel_Dock: + return System.Windows.Controls.DockPanel.DockProperty; + case KnownProperties.DockPanel_LastChildFill: + return System.Windows.Controls.DockPanel.LastChildFillProperty; + case KnownProperties.DocumentViewerBase_Document: + return System.Windows.Controls.Primitives.DocumentViewerBase.DocumentProperty; + case KnownProperties.DrawingGroup_Children: + return System.Windows.Media.DrawingGroup.ChildrenProperty; + case KnownProperties.FlowDocumentReader_Document: + return System.Windows.Controls.FlowDocumentReader.DocumentProperty; + case KnownProperties.FlowDocumentScrollViewer_Document: + return System.Windows.Controls.FlowDocumentScrollViewer.DocumentProperty; + case KnownProperties.FrameworkContentElement_Style: + return System.Windows.FrameworkContentElement.StyleProperty; + case KnownProperties.FrameworkElement_FlowDirection: + return System.Windows.FrameworkElement.FlowDirectionProperty; + case KnownProperties.FrameworkElement_Height: + return System.Windows.FrameworkElement.HeightProperty; + case KnownProperties.FrameworkElement_HorizontalAlignment: + return System.Windows.FrameworkElement.HorizontalAlignmentProperty; + case KnownProperties.FrameworkElement_Margin: + return System.Windows.FrameworkElement.MarginProperty; + case KnownProperties.FrameworkElement_MaxHeight: + return System.Windows.FrameworkElement.MaxHeightProperty; + case KnownProperties.FrameworkElement_MaxWidth: + return System.Windows.FrameworkElement.MaxWidthProperty; + case KnownProperties.FrameworkElement_MinHeight: + return System.Windows.FrameworkElement.MinHeightProperty; + case KnownProperties.FrameworkElement_MinWidth: + return System.Windows.FrameworkElement.MinWidthProperty; + case KnownProperties.FrameworkElement_Name: + return System.Windows.FrameworkElement.NameProperty; + case KnownProperties.FrameworkElement_Style: + return System.Windows.FrameworkElement.StyleProperty; + case KnownProperties.FrameworkElement_VerticalAlignment: + return System.Windows.FrameworkElement.VerticalAlignmentProperty; + case KnownProperties.FrameworkElement_Width: + return System.Windows.FrameworkElement.WidthProperty; + case KnownProperties.GeneralTransformGroup_Children: + return System.Windows.Media.GeneralTransformGroup.ChildrenProperty; + case KnownProperties.GeometryGroup_Children: + return System.Windows.Media.GeometryGroup.ChildrenProperty; + case KnownProperties.GradientBrush_GradientStops: + return System.Windows.Media.GradientBrush.GradientStopsProperty; + case KnownProperties.Grid_Column: + return System.Windows.Controls.Grid.ColumnProperty; + case KnownProperties.Grid_ColumnSpan: + return System.Windows.Controls.Grid.ColumnSpanProperty; + case KnownProperties.Grid_Row: + return System.Windows.Controls.Grid.RowProperty; + case KnownProperties.Grid_RowSpan: + return System.Windows.Controls.Grid.RowSpanProperty; + case KnownProperties.GridViewColumn_Header: + return System.Windows.Controls.GridViewColumn.HeaderProperty; + case KnownProperties.HeaderedContentControl_HasHeader: + return System.Windows.Controls.HeaderedContentControl.HasHeaderProperty; + case KnownProperties.HeaderedContentControl_Header: + return System.Windows.Controls.HeaderedContentControl.HeaderProperty; + case KnownProperties.HeaderedContentControl_HeaderTemplate: + return System.Windows.Controls.HeaderedContentControl.HeaderTemplateProperty; + case KnownProperties.HeaderedContentControl_HeaderTemplateSelector: + return System.Windows.Controls.HeaderedContentControl.HeaderTemplateSelectorProperty; + case KnownProperties.HeaderedItemsControl_HasHeader: + return System.Windows.Controls.HeaderedItemsControl.HasHeaderProperty; + case KnownProperties.HeaderedItemsControl_Header: + return System.Windows.Controls.HeaderedItemsControl.HeaderProperty; + case KnownProperties.HeaderedItemsControl_HeaderTemplate: + return System.Windows.Controls.HeaderedItemsControl.HeaderTemplateProperty; + case KnownProperties.HeaderedItemsControl_HeaderTemplateSelector: + return System.Windows.Controls.HeaderedItemsControl.HeaderTemplateSelectorProperty; + case KnownProperties.Hyperlink_NavigateUri: + return System.Windows.Documents.Hyperlink.NavigateUriProperty; + case KnownProperties.Image_Source: + return System.Windows.Controls.Image.SourceProperty; + case KnownProperties.Image_Stretch: + return System.Windows.Controls.Image.StretchProperty; + case KnownProperties.ItemsControl_ItemContainerStyle: + return System.Windows.Controls.ItemsControl.ItemContainerStyleProperty; + case KnownProperties.ItemsControl_ItemContainerStyleSelector: + return System.Windows.Controls.ItemsControl.ItemContainerStyleSelectorProperty; + case KnownProperties.ItemsControl_ItemTemplate: + return System.Windows.Controls.ItemsControl.ItemTemplateProperty; + case KnownProperties.ItemsControl_ItemTemplateSelector: + return System.Windows.Controls.ItemsControl.ItemTemplateSelectorProperty; + case KnownProperties.ItemsControl_ItemsPanel: + return System.Windows.Controls.ItemsControl.ItemsPanelProperty; + case KnownProperties.ItemsControl_ItemsSource: + return System.Windows.Controls.ItemsControl.ItemsSourceProperty; + case KnownProperties.MaterialGroup_Children: + return System.Windows.Media.Media3D.MaterialGroup.ChildrenProperty; + case KnownProperties.Model3DGroup_Children: + return System.Windows.Media.Media3D.Model3DGroup.ChildrenProperty; + case KnownProperties.Page_Content: + return System.Windows.Controls.Page.ContentProperty; + case KnownProperties.Panel_Background: + return System.Windows.Controls.Panel.BackgroundProperty; + case KnownProperties.Path_Data: + return System.Windows.Shapes.Path.DataProperty; + case KnownProperties.PathFigure_Segments: + return System.Windows.Media.PathFigure.SegmentsProperty; + case KnownProperties.PathGeometry_Figures: + return System.Windows.Media.PathGeometry.FiguresProperty; + case KnownProperties.Popup_Child: + return System.Windows.Controls.Primitives.Popup.ChildProperty; + case KnownProperties.Popup_IsOpen: + return System.Windows.Controls.Primitives.Popup.IsOpenProperty; + case KnownProperties.Popup_Placement: + return System.Windows.Controls.Primitives.Popup.PlacementProperty; + case KnownProperties.Popup_PopupAnimation: + return System.Windows.Controls.Primitives.Popup.PopupAnimationProperty; + case KnownProperties.RowDefinition_Height: + return System.Windows.Controls.RowDefinition.HeightProperty; + case KnownProperties.RowDefinition_MaxHeight: + return System.Windows.Controls.RowDefinition.MaxHeightProperty; + case KnownProperties.RowDefinition_MinHeight: + return System.Windows.Controls.RowDefinition.MinHeightProperty; + case KnownProperties.Run_Text: + return System.Windows.Documents.Run.TextProperty; + case KnownProperties.ScrollViewer_CanContentScroll: + return System.Windows.Controls.ScrollViewer.CanContentScrollProperty; + case KnownProperties.ScrollViewer_HorizontalScrollBarVisibility: + return System.Windows.Controls.ScrollViewer.HorizontalScrollBarVisibilityProperty; + case KnownProperties.ScrollViewer_VerticalScrollBarVisibility: + return System.Windows.Controls.ScrollViewer.VerticalScrollBarVisibilityProperty; + case KnownProperties.Shape_Fill: + return System.Windows.Shapes.Shape.FillProperty; + case KnownProperties.Shape_Stroke: + return System.Windows.Shapes.Shape.StrokeProperty; + case KnownProperties.Shape_StrokeThickness: + return System.Windows.Shapes.Shape.StrokeThicknessProperty; + case KnownProperties.TextBlock_Background: + return System.Windows.Controls.TextBlock.BackgroundProperty; + case KnownProperties.TextBlock_FontFamily: + return System.Windows.Controls.TextBlock.FontFamilyProperty; + case KnownProperties.TextBlock_FontSize: + return System.Windows.Controls.TextBlock.FontSizeProperty; + case KnownProperties.TextBlock_FontStretch: + return System.Windows.Controls.TextBlock.FontStretchProperty; + case KnownProperties.TextBlock_FontStyle: + return System.Windows.Controls.TextBlock.FontStyleProperty; + case KnownProperties.TextBlock_FontWeight: + return System.Windows.Controls.TextBlock.FontWeightProperty; + case KnownProperties.TextBlock_Foreground: + return System.Windows.Controls.TextBlock.ForegroundProperty; + case KnownProperties.TextBlock_Text: + return System.Windows.Controls.TextBlock.TextProperty; + case KnownProperties.TextBlock_TextDecorations: + return System.Windows.Controls.TextBlock.TextDecorationsProperty; + case KnownProperties.TextBlock_TextTrimming: + return System.Windows.Controls.TextBlock.TextTrimmingProperty; + case KnownProperties.TextBlock_TextWrapping: + return System.Windows.Controls.TextBlock.TextWrappingProperty; + case KnownProperties.TextBox_Text: + return System.Windows.Controls.TextBox.TextProperty; + case KnownProperties.TextElement_Background: + return System.Windows.Documents.TextElement.BackgroundProperty; + case KnownProperties.TextElement_FontFamily: + return System.Windows.Documents.TextElement.FontFamilyProperty; + case KnownProperties.TextElement_FontSize: + return System.Windows.Documents.TextElement.FontSizeProperty; + case KnownProperties.TextElement_FontStretch: + return System.Windows.Documents.TextElement.FontStretchProperty; + case KnownProperties.TextElement_FontStyle: + return System.Windows.Documents.TextElement.FontStyleProperty; + case KnownProperties.TextElement_FontWeight: + return System.Windows.Documents.TextElement.FontWeightProperty; + case KnownProperties.TextElement_Foreground: + return System.Windows.Documents.TextElement.ForegroundProperty; + case KnownProperties.TimelineGroup_Children: + return System.Windows.Media.Animation.TimelineGroup.ChildrenProperty; + case KnownProperties.Track_IsDirectionReversed: + return System.Windows.Controls.Primitives.Track.IsDirectionReversedProperty; + case KnownProperties.Track_Maximum: + return System.Windows.Controls.Primitives.Track.MaximumProperty; + case KnownProperties.Track_Minimum: + return System.Windows.Controls.Primitives.Track.MinimumProperty; + case KnownProperties.Track_Orientation: + return System.Windows.Controls.Primitives.Track.OrientationProperty; + case KnownProperties.Track_Value: + return System.Windows.Controls.Primitives.Track.ValueProperty; + case KnownProperties.Track_ViewportSize: + return System.Windows.Controls.Primitives.Track.ViewportSizeProperty; + case KnownProperties.Transform3DGroup_Children: + return System.Windows.Media.Media3D.Transform3DGroup.ChildrenProperty; + case KnownProperties.TransformGroup_Children: + return System.Windows.Media.TransformGroup.ChildrenProperty; + case KnownProperties.UIElement_ClipToBounds: + return System.Windows.UIElement.ClipToBoundsProperty; + case KnownProperties.UIElement_Focusable: + return System.Windows.UIElement.FocusableProperty; + case KnownProperties.UIElement_IsEnabled: + return System.Windows.UIElement.IsEnabledProperty; + case KnownProperties.UIElement_RenderTransform: + return System.Windows.UIElement.RenderTransformProperty; + case KnownProperties.UIElement_Visibility: + return System.Windows.UIElement.VisibilityProperty; + case KnownProperties.Viewport3D_Children: + return System.Windows.Controls.Viewport3D.ChildrenProperty; + } + return null; + } + + internal static KnownElements GetKnownElementFromKnownCommonProperty(KnownProperties knownProperty) + { + switch (knownProperty) + { + case KnownProperties.AccessText_Text: + return KnownElements.AccessText; + case KnownProperties.AdornedElementPlaceholder_Child: + return KnownElements.AdornedElementPlaceholder; + case KnownProperties.AdornerDecorator_Child: + return KnownElements.AdornerDecorator; + case KnownProperties.AnchoredBlock_Blocks: + return KnownElements.AnchoredBlock; + case KnownProperties.ArrayExtension_Items: + return KnownElements.ArrayExtension; + case KnownProperties.BeginStoryboard_Storyboard: + return KnownElements.BeginStoryboard; + case KnownProperties.BitmapEffectGroup_Children: + return KnownElements.BitmapEffectGroup; + case KnownProperties.BlockUIContainer_Child: + return KnownElements.BlockUIContainer; + case KnownProperties.Bold_Inlines: + return KnownElements.Bold; + case KnownProperties.BooleanAnimationUsingKeyFrames_KeyFrames: + return KnownElements.BooleanAnimationUsingKeyFrames; + case KnownProperties.Border_Background: + case KnownProperties.Border_BorderBrush: + case KnownProperties.Border_BorderThickness: + case KnownProperties.Border_Child: + return KnownElements.Border; + case KnownProperties.BulletDecorator_Child: + return KnownElements.BulletDecorator; + case KnownProperties.Button_Content: + return KnownElements.Button; + case KnownProperties.ButtonBase_Command: + case KnownProperties.ButtonBase_CommandParameter: + case KnownProperties.ButtonBase_CommandTarget: + case KnownProperties.ButtonBase_Content: + case KnownProperties.ButtonBase_IsPressed: + return KnownElements.ButtonBase; + case KnownProperties.ByteAnimationUsingKeyFrames_KeyFrames: + return KnownElements.ByteAnimationUsingKeyFrames; + case KnownProperties.Canvas_Children: + return KnownElements.Canvas; + case KnownProperties.CharAnimationUsingKeyFrames_KeyFrames: + return KnownElements.CharAnimationUsingKeyFrames; + case KnownProperties.CheckBox_Content: + return KnownElements.CheckBox; + case KnownProperties.ColorAnimationUsingKeyFrames_KeyFrames: + return KnownElements.ColorAnimationUsingKeyFrames; + case KnownProperties.ColumnDefinition_MaxWidth: + case KnownProperties.ColumnDefinition_MinWidth: + case KnownProperties.ColumnDefinition_Width: + return KnownElements.ColumnDefinition; + case KnownProperties.ComboBox_Items: + return KnownElements.ComboBox; + case KnownProperties.ComboBoxItem_Content: + return KnownElements.ComboBoxItem; + case KnownProperties.ContentControl_Content: + case KnownProperties.ContentControl_ContentTemplate: + case KnownProperties.ContentControl_ContentTemplateSelector: + case KnownProperties.ContentControl_HasContent: + return KnownElements.ContentControl; + case KnownProperties.ContentElement_Focusable: + return KnownElements.ContentElement; + case KnownProperties.ContentPresenter_Content: + case KnownProperties.ContentPresenter_ContentSource: + case KnownProperties.ContentPresenter_ContentTemplate: + case KnownProperties.ContentPresenter_ContentTemplateSelector: + case KnownProperties.ContentPresenter_RecognizesAccessKey: + return KnownElements.ContentPresenter; + case KnownProperties.ContextMenu_Items: + return KnownElements.ContextMenu; + case KnownProperties.Control_Background: + case KnownProperties.Control_BorderBrush: + case KnownProperties.Control_BorderThickness: + case KnownProperties.Control_FontFamily: + case KnownProperties.Control_FontSize: + case KnownProperties.Control_FontStretch: + case KnownProperties.Control_FontStyle: + case KnownProperties.Control_FontWeight: + case KnownProperties.Control_Foreground: + case KnownProperties.Control_HorizontalContentAlignment: + case KnownProperties.Control_IsTabStop: + case KnownProperties.Control_Padding: + case KnownProperties.Control_TabIndex: + case KnownProperties.Control_Template: + case KnownProperties.Control_VerticalContentAlignment: + return KnownElements.Control; + case KnownProperties.ControlTemplate_VisualTree: + return KnownElements.ControlTemplate; + case KnownProperties.DataTemplate_VisualTree: + return KnownElements.DataTemplate; + case KnownProperties.DataTrigger_Setters: + return KnownElements.DataTrigger; + case KnownProperties.DecimalAnimationUsingKeyFrames_KeyFrames: + return KnownElements.DecimalAnimationUsingKeyFrames; + case KnownProperties.Decorator_Child: + return KnownElements.Decorator; + case KnownProperties.DockPanel_Children: + case KnownProperties.DockPanel_Dock: + case KnownProperties.DockPanel_LastChildFill: + return KnownElements.DockPanel; + case KnownProperties.DocumentViewer_Document: + return KnownElements.DocumentViewer; + case KnownProperties.DocumentViewerBase_Document: + return KnownElements.DocumentViewerBase; + case KnownProperties.DoubleAnimationUsingKeyFrames_KeyFrames: + return KnownElements.DoubleAnimationUsingKeyFrames; + case KnownProperties.DrawingGroup_Children: + return KnownElements.DrawingGroup; + case KnownProperties.EventTrigger_Actions: + return KnownElements.EventTrigger; + case KnownProperties.Expander_Content: + return KnownElements.Expander; + case KnownProperties.Figure_Blocks: + return KnownElements.Figure; + case KnownProperties.FixedDocument_Pages: + return KnownElements.FixedDocument; + case KnownProperties.FixedDocumentSequence_References: + return KnownElements.FixedDocumentSequence; + case KnownProperties.FixedPage_Children: + return KnownElements.FixedPage; + case KnownProperties.Floater_Blocks: + return KnownElements.Floater; + case KnownProperties.FlowDocument_Blocks: + return KnownElements.FlowDocument; + case KnownProperties.FlowDocumentPageViewer_Document: + return KnownElements.FlowDocumentPageViewer; + case KnownProperties.FlowDocumentReader_Document: + return KnownElements.FlowDocumentReader; + case KnownProperties.FlowDocumentScrollViewer_Document: + return KnownElements.FlowDocumentScrollViewer; + case KnownProperties.FrameworkContentElement_Style: + return KnownElements.FrameworkContentElement; + case KnownProperties.FrameworkElement_FlowDirection: + case KnownProperties.FrameworkElement_Height: + case KnownProperties.FrameworkElement_HorizontalAlignment: + case KnownProperties.FrameworkElement_Margin: + case KnownProperties.FrameworkElement_MaxHeight: + case KnownProperties.FrameworkElement_MaxWidth: + case KnownProperties.FrameworkElement_MinHeight: + case KnownProperties.FrameworkElement_MinWidth: + case KnownProperties.FrameworkElement_Name: + case KnownProperties.FrameworkElement_Style: + case KnownProperties.FrameworkElement_VerticalAlignment: + case KnownProperties.FrameworkElement_Width: + return KnownElements.FrameworkElement; + case KnownProperties.FrameworkTemplate_VisualTree: + return KnownElements.FrameworkTemplate; + case KnownProperties.GeneralTransformGroup_Children: + return KnownElements.GeneralTransformGroup; + case KnownProperties.GeometryGroup_Children: + return KnownElements.GeometryGroup; + case KnownProperties.GradientBrush_GradientStops: + return KnownElements.GradientBrush; + case KnownProperties.Grid_Children: + case KnownProperties.Grid_Column: + case KnownProperties.Grid_ColumnSpan: + case KnownProperties.Grid_Row: + case KnownProperties.Grid_RowSpan: + return KnownElements.Grid; + case KnownProperties.GridView_Columns: + return KnownElements.GridView; + case KnownProperties.GridViewColumn_Header: + return KnownElements.GridViewColumn; + case KnownProperties.GridViewColumnHeader_Content: + return KnownElements.GridViewColumnHeader; + case KnownProperties.GroupBox_Content: + return KnownElements.GroupBox; + case KnownProperties.GroupItem_Content: + return KnownElements.GroupItem; + case KnownProperties.HeaderedContentControl_Content: + case KnownProperties.HeaderedContentControl_HasHeader: + case KnownProperties.HeaderedContentControl_Header: + case KnownProperties.HeaderedContentControl_HeaderTemplate: + case KnownProperties.HeaderedContentControl_HeaderTemplateSelector: + return KnownElements.HeaderedContentControl; + case KnownProperties.HeaderedItemsControl_HasHeader: + case KnownProperties.HeaderedItemsControl_Header: + case KnownProperties.HeaderedItemsControl_HeaderTemplate: + case KnownProperties.HeaderedItemsControl_HeaderTemplateSelector: + case KnownProperties.HeaderedItemsControl_Items: + return KnownElements.HeaderedItemsControl; + case KnownProperties.HierarchicalDataTemplate_VisualTree: + return KnownElements.HierarchicalDataTemplate; + case KnownProperties.Hyperlink_Inlines: + case KnownProperties.Hyperlink_NavigateUri: + return KnownElements.Hyperlink; + case KnownProperties.Image_Source: + case KnownProperties.Image_Stretch: + return KnownElements.Image; + case KnownProperties.InkCanvas_Children: + return KnownElements.InkCanvas; + case KnownProperties.InkPresenter_Child: + return KnownElements.InkPresenter; + case KnownProperties.InlineUIContainer_Child: + return KnownElements.InlineUIContainer; + case KnownProperties.InputScopeName_NameValue: + return KnownElements.InputScopeName; + case KnownProperties.Int16AnimationUsingKeyFrames_KeyFrames: + return KnownElements.Int16AnimationUsingKeyFrames; + case KnownProperties.Int32AnimationUsingKeyFrames_KeyFrames: + return KnownElements.Int32AnimationUsingKeyFrames; + case KnownProperties.Int64AnimationUsingKeyFrames_KeyFrames: + return KnownElements.Int64AnimationUsingKeyFrames; + case KnownProperties.Italic_Inlines: + return KnownElements.Italic; + case KnownProperties.ItemsControl_ItemContainerStyle: + case KnownProperties.ItemsControl_ItemContainerStyleSelector: + case KnownProperties.ItemsControl_ItemTemplate: + case KnownProperties.ItemsControl_ItemTemplateSelector: + case KnownProperties.ItemsControl_Items: + case KnownProperties.ItemsControl_ItemsPanel: + case KnownProperties.ItemsControl_ItemsSource: + return KnownElements.ItemsControl; + case KnownProperties.ItemsPanelTemplate_VisualTree: + return KnownElements.ItemsPanelTemplate; + case KnownProperties.Label_Content: + return KnownElements.Label; + case KnownProperties.LinearGradientBrush_GradientStops: + return KnownElements.LinearGradientBrush; + case KnownProperties.List_ListItems: + return KnownElements.List; + case KnownProperties.ListBox_Items: + return KnownElements.ListBox; + case KnownProperties.ListBoxItem_Content: + return KnownElements.ListBoxItem; + case KnownProperties.ListItem_Blocks: + return KnownElements.ListItem; + case KnownProperties.ListView_Items: + return KnownElements.ListView; + case KnownProperties.ListViewItem_Content: + return KnownElements.ListViewItem; + case KnownProperties.MaterialGroup_Children: + return KnownElements.MaterialGroup; + case KnownProperties.MatrixAnimationUsingKeyFrames_KeyFrames: + return KnownElements.MatrixAnimationUsingKeyFrames; + case KnownProperties.Menu_Items: + return KnownElements.Menu; + case KnownProperties.MenuBase_Items: + return KnownElements.MenuBase; + case KnownProperties.MenuItem_Items: + return KnownElements.MenuItem; + case KnownProperties.Model3DGroup_Children: + return KnownElements.Model3DGroup; + case KnownProperties.ModelVisual3D_Children: + return KnownElements.ModelVisual3D; + case KnownProperties.MultiBinding_Bindings: + return KnownElements.MultiBinding; + case KnownProperties.MultiDataTrigger_Setters: + return KnownElements.MultiDataTrigger; + case KnownProperties.MultiTrigger_Setters: + return KnownElements.MultiTrigger; + case KnownProperties.ObjectAnimationUsingKeyFrames_KeyFrames: + return KnownElements.ObjectAnimationUsingKeyFrames; + case KnownProperties.Page_Content: + return KnownElements.Page; + case KnownProperties.PageContent_Child: + return KnownElements.PageContent; + case KnownProperties.PageFunctionBase_Content: + return KnownElements.PageFunctionBase; + case KnownProperties.Panel_Background: + case KnownProperties.Panel_Children: + return KnownElements.Panel; + case KnownProperties.Paragraph_Inlines: + return KnownElements.Paragraph; + case KnownProperties.ParallelTimeline_Children: + return KnownElements.ParallelTimeline; + case KnownProperties.Path_Data: + return KnownElements.Path; + case KnownProperties.PathFigure_Segments: + return KnownElements.PathFigure; + case KnownProperties.PathGeometry_Figures: + return KnownElements.PathGeometry; + case KnownProperties.Point3DAnimationUsingKeyFrames_KeyFrames: + return KnownElements.Point3DAnimationUsingKeyFrames; + case KnownProperties.PointAnimationUsingKeyFrames_KeyFrames: + return KnownElements.PointAnimationUsingKeyFrames; + case KnownProperties.Popup_Child: + case KnownProperties.Popup_IsOpen: + case KnownProperties.Popup_Placement: + case KnownProperties.Popup_PopupAnimation: + return KnownElements.Popup; + case KnownProperties.PriorityBinding_Bindings: + return KnownElements.PriorityBinding; + case KnownProperties.QuaternionAnimationUsingKeyFrames_KeyFrames: + return KnownElements.QuaternionAnimationUsingKeyFrames; + case KnownProperties.RadialGradientBrush_GradientStops: + return KnownElements.RadialGradientBrush; + case KnownProperties.RadioButton_Content: + return KnownElements.RadioButton; + case KnownProperties.RectAnimationUsingKeyFrames_KeyFrames: + return KnownElements.RectAnimationUsingKeyFrames; + case KnownProperties.RepeatButton_Content: + return KnownElements.RepeatButton; + case KnownProperties.RichTextBox_Document: + return KnownElements.RichTextBox; + case KnownProperties.Rotation3DAnimationUsingKeyFrames_KeyFrames: + return KnownElements.Rotation3DAnimationUsingKeyFrames; + case KnownProperties.RowDefinition_Height: + case KnownProperties.RowDefinition_MaxHeight: + case KnownProperties.RowDefinition_MinHeight: + return KnownElements.RowDefinition; + case KnownProperties.Run_Text: + return KnownElements.Run; + case KnownProperties.ScrollViewer_CanContentScroll: + case KnownProperties.ScrollViewer_Content: + case KnownProperties.ScrollViewer_HorizontalScrollBarVisibility: + case KnownProperties.ScrollViewer_VerticalScrollBarVisibility: + return KnownElements.ScrollViewer; + case KnownProperties.Section_Blocks: + return KnownElements.Section; + case KnownProperties.Selector_Items: + return KnownElements.Selector; + case KnownProperties.Shape_Fill: + case KnownProperties.Shape_Stroke: + case KnownProperties.Shape_StrokeThickness: + return KnownElements.Shape; + case KnownProperties.SingleAnimationUsingKeyFrames_KeyFrames: + return KnownElements.SingleAnimationUsingKeyFrames; + case KnownProperties.SizeAnimationUsingKeyFrames_KeyFrames: + return KnownElements.SizeAnimationUsingKeyFrames; + case KnownProperties.Span_Inlines: + return KnownElements.Span; + case KnownProperties.StackPanel_Children: + return KnownElements.StackPanel; + case KnownProperties.StatusBar_Items: + return KnownElements.StatusBar; + case KnownProperties.StatusBarItem_Content: + return KnownElements.StatusBarItem; + case KnownProperties.Storyboard_Children: + return KnownElements.Storyboard; + case KnownProperties.StringAnimationUsingKeyFrames_KeyFrames: + return KnownElements.StringAnimationUsingKeyFrames; + case KnownProperties.Style_Setters: + return KnownElements.Style; + case KnownProperties.TabControl_Items: + return KnownElements.TabControl; + case KnownProperties.TabItem_Content: + return KnownElements.TabItem; + case KnownProperties.TabPanel_Children: + return KnownElements.TabPanel; + case KnownProperties.Table_RowGroups: + return KnownElements.Table; + case KnownProperties.TableCell_Blocks: + return KnownElements.TableCell; + case KnownProperties.TableRow_Cells: + return KnownElements.TableRow; + case KnownProperties.TableRowGroup_Rows: + return KnownElements.TableRowGroup; + case KnownProperties.TextBlock_Background: + case KnownProperties.TextBlock_FontFamily: + case KnownProperties.TextBlock_FontSize: + case KnownProperties.TextBlock_FontStretch: + case KnownProperties.TextBlock_FontStyle: + case KnownProperties.TextBlock_FontWeight: + case KnownProperties.TextBlock_Foreground: + case KnownProperties.TextBlock_Inlines: + case KnownProperties.TextBlock_Text: + case KnownProperties.TextBlock_TextDecorations: + case KnownProperties.TextBlock_TextTrimming: + case KnownProperties.TextBlock_TextWrapping: + return KnownElements.TextBlock; + case KnownProperties.TextBox_Text: + return KnownElements.TextBox; + case KnownProperties.TextElement_Background: + case KnownProperties.TextElement_FontFamily: + case KnownProperties.TextElement_FontSize: + case KnownProperties.TextElement_FontStretch: + case KnownProperties.TextElement_FontStyle: + case KnownProperties.TextElement_FontWeight: + case KnownProperties.TextElement_Foreground: + return KnownElements.TextElement; + case KnownProperties.ThicknessAnimationUsingKeyFrames_KeyFrames: + return KnownElements.ThicknessAnimationUsingKeyFrames; + case KnownProperties.TimelineGroup_Children: + return KnownElements.TimelineGroup; + case KnownProperties.ToggleButton_Content: + return KnownElements.ToggleButton; + case KnownProperties.ToolBar_Items: + return KnownElements.ToolBar; + case KnownProperties.ToolBarOverflowPanel_Children: + return KnownElements.ToolBarOverflowPanel; + case KnownProperties.ToolBarPanel_Children: + return KnownElements.ToolBarPanel; + case KnownProperties.ToolBarTray_ToolBars: + return KnownElements.ToolBarTray; + case KnownProperties.ToolTip_Content: + return KnownElements.ToolTip; + case KnownProperties.Track_IsDirectionReversed: + case KnownProperties.Track_Maximum: + case KnownProperties.Track_Minimum: + case KnownProperties.Track_Orientation: + case KnownProperties.Track_Value: + case KnownProperties.Track_ViewportSize: + return KnownElements.Track; + case KnownProperties.Transform3DGroup_Children: + return KnownElements.Transform3DGroup; + case KnownProperties.TransformGroup_Children: + return KnownElements.TransformGroup; + case KnownProperties.TreeView_Items: + return KnownElements.TreeView; + case KnownProperties.TreeViewItem_Items: + return KnownElements.TreeViewItem; + case KnownProperties.Trigger_Setters: + return KnownElements.Trigger; + case KnownProperties.UIElement_ClipToBounds: + case KnownProperties.UIElement_Focusable: + case KnownProperties.UIElement_IsEnabled: + case KnownProperties.UIElement_RenderTransform: + case KnownProperties.UIElement_Visibility: + return KnownElements.UIElement; + case KnownProperties.Underline_Inlines: + return KnownElements.Underline; + case KnownProperties.UniformGrid_Children: + return KnownElements.UniformGrid; + case KnownProperties.UserControl_Content: + return KnownElements.UserControl; + case KnownProperties.Vector3DAnimationUsingKeyFrames_KeyFrames: + return KnownElements.Vector3DAnimationUsingKeyFrames; + case KnownProperties.VectorAnimationUsingKeyFrames_KeyFrames: + return KnownElements.VectorAnimationUsingKeyFrames; + case KnownProperties.Viewbox_Child: + return KnownElements.Viewbox; + case KnownProperties.Viewport3D_Children: + return KnownElements.Viewport3D; + case KnownProperties.Viewport3DVisual_Children: + return KnownElements.Viewport3DVisual; + case KnownProperties.VirtualizingPanel_Children: + return KnownElements.VirtualizingPanel; + case KnownProperties.VirtualizingStackPanel_Children: + return KnownElements.VirtualizingStackPanel; + case KnownProperties.Window_Content: + return KnownElements.Window; + case KnownProperties.WrapPanel_Children: + return KnownElements.WrapPanel; + case KnownProperties.XmlDataProvider_XmlSerializer: + return KnownElements.XmlDataProvider; + } + return KnownElements.UnknownElement; + } + + // This code 'knows' that all non-DP (clr) KnownProperties are + // also Content Properties. As long as that is true there is no + // need for a second string table, and we can just cross reference. + internal static string GetKnownClrPropertyNameFromId(KnownProperties knownProperty) + { + KnownElements knownElement = GetKnownElementFromKnownCommonProperty(knownProperty); + string name = GetContentPropertyName(knownElement); + return name; + } + + // Returns IList interface of the Content Property for the given Element. + // WARNING can return null if no CPA is defined on the Element, or the CPA does implement IList. + internal static IList GetCollectionForCPA(object o, KnownElements knownElement) + { + // We don't cache because we return the IList of the given object. + switch(knownElement) + { + // Panel.Children + case KnownElements.Canvas: + case KnownElements.DockPanel: + case KnownElements.Grid: + case KnownElements.Panel: + case KnownElements.StackPanel: + case KnownElements.TabPanel: + case KnownElements.ToolBarOverflowPanel: + case KnownElements.ToolBarPanel: + case KnownElements.UniformGrid: + case KnownElements.VirtualizingPanel: + case KnownElements.VirtualizingStackPanel: + case KnownElements.WrapPanel: + return (o as System.Windows.Controls.Panel).Children; + + // ItemsControl.Items + case KnownElements.ComboBox: + case KnownElements.ContextMenu: + case KnownElements.HeaderedItemsControl: + case KnownElements.ItemsControl: + case KnownElements.ListBox: + case KnownElements.ListView: + case KnownElements.Menu: + case KnownElements.MenuBase: + case KnownElements.MenuItem: + case KnownElements.Selector: + case KnownElements.StatusBar: + case KnownElements.TabControl: + case KnownElements.ToolBar: + case KnownElements.TreeView: + case KnownElements.TreeViewItem: + return (o as System.Windows.Controls.ItemsControl).Items; + + // Span.Inlines + case KnownElements.Bold: + case KnownElements.Hyperlink: + case KnownElements.Italic: + case KnownElements.Span: + case KnownElements.Underline: + return (o as System.Windows.Documents.Span).Inlines; + + // AnchoredBlock.Blocks + case KnownElements.AnchoredBlock: + case KnownElements.Figure: + case KnownElements.Floater: + return (o as System.Windows.Documents.AnchoredBlock).Blocks; + + // GradientBrush.GradientStops + case KnownElements.GradientBrush: + case KnownElements.LinearGradientBrush: + case KnownElements.RadialGradientBrush: + return (o as System.Windows.Media.GradientBrush).GradientStops; + + // TimelineGroup.Children + case KnownElements.ParallelTimeline: + case KnownElements.Storyboard: + case KnownElements.TimelineGroup: + return (o as System.Windows.Media.Animation.TimelineGroup).Children; + + // Other + case KnownElements.BitmapEffectGroup: return (o as System.Windows.Media.Effects.BitmapEffectGroup).Children; + case KnownElements.BooleanAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.BooleanAnimationUsingKeyFrames).KeyFrames; + case KnownElements.ByteAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.ByteAnimationUsingKeyFrames).KeyFrames; + case KnownElements.CharAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.CharAnimationUsingKeyFrames).KeyFrames; + case KnownElements.ColorAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.ColorAnimationUsingKeyFrames).KeyFrames; + case KnownElements.DataTrigger: return (o as System.Windows.DataTrigger).Setters; + case KnownElements.DecimalAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.DecimalAnimationUsingKeyFrames).KeyFrames; + case KnownElements.DoubleAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.DoubleAnimationUsingKeyFrames).KeyFrames; + case KnownElements.DrawingGroup: return (o as System.Windows.Media.DrawingGroup).Children; + case KnownElements.EventTrigger: return (o as System.Windows.EventTrigger).Actions; + case KnownElements.FixedPage: return (o as System.Windows.Documents.FixedPage).Children; + case KnownElements.FlowDocument: return (o as System.Windows.Documents.FlowDocument).Blocks; + case KnownElements.GeneralTransformGroup: return (o as System.Windows.Media.GeneralTransformGroup).Children; + case KnownElements.GeometryGroup: return (o as System.Windows.Media.GeometryGroup).Children; + case KnownElements.GridView: return (o as System.Windows.Controls.GridView).Columns; + case KnownElements.InkCanvas: return (o as System.Windows.Controls.InkCanvas).Children; + case KnownElements.Int16AnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.Int16AnimationUsingKeyFrames).KeyFrames; + case KnownElements.Int32AnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.Int32AnimationUsingKeyFrames).KeyFrames; + case KnownElements.Int64AnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.Int64AnimationUsingKeyFrames).KeyFrames; + case KnownElements.List: return (o as System.Windows.Documents.List).ListItems; + case KnownElements.ListItem: return (o as System.Windows.Documents.ListItem).Blocks; + case KnownElements.MaterialGroup: return (o as System.Windows.Media.Media3D.MaterialGroup).Children; + case KnownElements.MatrixAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.MatrixAnimationUsingKeyFrames).KeyFrames; + case KnownElements.Model3DGroup: return (o as System.Windows.Media.Media3D.Model3DGroup).Children; + case KnownElements.ModelVisual3D: return (o as System.Windows.Media.Media3D.ModelVisual3D).Children; + case KnownElements.MultiBinding: return (o as System.Windows.Data.MultiBinding).Bindings; + case KnownElements.MultiDataTrigger: return (o as System.Windows.MultiDataTrigger).Setters; + case KnownElements.MultiTrigger: return (o as System.Windows.MultiTrigger).Setters; + case KnownElements.ObjectAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames).KeyFrames; + case KnownElements.Paragraph: return (o as System.Windows.Documents.Paragraph).Inlines; + case KnownElements.PathFigure: return (o as System.Windows.Media.PathFigure).Segments; + case KnownElements.PathGeometry: return (o as System.Windows.Media.PathGeometry).Figures; + case KnownElements.Point3DAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.Point3DAnimationUsingKeyFrames).KeyFrames; + case KnownElements.PointAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.PointAnimationUsingKeyFrames).KeyFrames; + case KnownElements.PriorityBinding: return (o as System.Windows.Data.PriorityBinding).Bindings; + case KnownElements.QuaternionAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.QuaternionAnimationUsingKeyFrames).KeyFrames; + case KnownElements.RectAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.RectAnimationUsingKeyFrames).KeyFrames; + case KnownElements.Rotation3DAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.Rotation3DAnimationUsingKeyFrames).KeyFrames; + case KnownElements.Section: return (o as System.Windows.Documents.Section).Blocks; + case KnownElements.SingleAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.SingleAnimationUsingKeyFrames).KeyFrames; + case KnownElements.SizeAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.SizeAnimationUsingKeyFrames).KeyFrames; + case KnownElements.StringAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.StringAnimationUsingKeyFrames).KeyFrames; + case KnownElements.Style: return (o as System.Windows.Style).Setters; + case KnownElements.Table: return (o as System.Windows.Documents.Table).RowGroups; + case KnownElements.TableCell: return (o as System.Windows.Documents.TableCell).Blocks; + case KnownElements.TableRow: return (o as System.Windows.Documents.TableRow).Cells; + case KnownElements.TableRowGroup: return (o as System.Windows.Documents.TableRowGroup).Rows; + case KnownElements.TextBlock: return (o as System.Windows.Controls.TextBlock).Inlines; + case KnownElements.ThicknessAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.ThicknessAnimationUsingKeyFrames).KeyFrames; + case KnownElements.ToolBarTray: return (o as System.Windows.Controls.ToolBarTray).ToolBars; + case KnownElements.Transform3DGroup: return (o as System.Windows.Media.Media3D.Transform3DGroup).Children; + case KnownElements.TransformGroup: return (o as System.Windows.Media.TransformGroup).Children; + case KnownElements.Trigger: return (o as System.Windows.Trigger).Setters; + case KnownElements.Vector3DAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.Vector3DAnimationUsingKeyFrames).KeyFrames; + case KnownElements.VectorAnimationUsingKeyFrames: return (o as System.Windows.Media.Animation.VectorAnimationUsingKeyFrames).KeyFrames; + case KnownElements.Viewport3D: return (o as System.Windows.Controls.Viewport3D).Children; + case KnownElements.Viewport3DVisual: return (o as System.Windows.Media.Media3D.Viewport3DVisual).Children; + } + return null; + } +#endif // #if !PBTCOMPILER + + // Indicate if a collection type can accept strings. E.g. DoubleCollection cannot + // accept strings, because it is an ICollection. But UIElementCollection does + // accept strings, because it is just IList. + + internal static bool CanCollectionTypeAcceptStrings(KnownElements knownElement) + { + + switch(knownElement) + { + case KnownElements.BitmapEffectCollection: + case KnownElements.DoubleCollection: + case KnownElements.DrawingCollection: + case KnownElements.GeneralTransformCollection: + case KnownElements.GeometryCollection: + case KnownElements.GradientStopCollection: + case KnownElements.Int32Collection: + case KnownElements.MaterialCollection: + case KnownElements.Model3DCollection: + case KnownElements.PathFigureCollection: + case KnownElements.PathSegmentCollection: + case KnownElements.Point3DCollection: + case KnownElements.PointCollection: + case KnownElements.StrokeCollection: + case KnownElements.TextDecorationCollection: + case KnownElements.TextEffectCollection: + case KnownElements.TimelineCollection: + case KnownElements.Transform3DCollection: + case KnownElements.TransformCollection: + case KnownElements.Vector3DCollection: + case KnownElements.VectorCollection: + + return false; + } + return true; + } + + internal static string GetContentPropertyName(KnownElements knownElement) + { + string name=null; + + switch(knownElement) + { + case KnownElements.EventTrigger: + name = "Actions"; + break; + case KnownElements.MultiBinding: + case KnownElements.PriorityBinding: + name = "Bindings"; + break; + case KnownElements.AnchoredBlock: + case KnownElements.Figure: + case KnownElements.Floater: + case KnownElements.FlowDocument: + case KnownElements.ListItem: + case KnownElements.Section: + case KnownElements.TableCell: + name = "Blocks"; + break; + case KnownElements.TableRow: + name = "Cells"; + break; + case KnownElements.AdornedElementPlaceholder: + case KnownElements.AdornerDecorator: + case KnownElements.BlockUIContainer: + case KnownElements.Border: + case KnownElements.BulletDecorator: + case KnownElements.Decorator: + case KnownElements.InkPresenter: + case KnownElements.InlineUIContainer: + case KnownElements.PageContent: + case KnownElements.Popup: + case KnownElements.Viewbox: + name = "Child"; + break; + case KnownElements.BitmapEffectGroup: + case KnownElements.Canvas: + case KnownElements.DockPanel: + case KnownElements.DrawingGroup: + case KnownElements.FixedPage: + case KnownElements.GeneralTransformGroup: + case KnownElements.GeometryGroup: + case KnownElements.Grid: + case KnownElements.InkCanvas: + case KnownElements.MaterialGroup: + case KnownElements.Model3DGroup: + case KnownElements.ModelVisual3D: + case KnownElements.Panel: + case KnownElements.ParallelTimeline: + case KnownElements.StackPanel: + case KnownElements.Storyboard: + case KnownElements.TabPanel: + case KnownElements.TimelineGroup: + case KnownElements.ToolBarOverflowPanel: + case KnownElements.ToolBarPanel: + case KnownElements.Transform3DGroup: + case KnownElements.TransformGroup: + case KnownElements.UniformGrid: + case KnownElements.Viewport3D: + case KnownElements.Viewport3DVisual: + case KnownElements.VirtualizingPanel: + case KnownElements.VirtualizingStackPanel: + case KnownElements.WrapPanel: + name = "Children"; + break; + case KnownElements.GridView: + name = "Columns"; + break; + case KnownElements.Button: + case KnownElements.ButtonBase: + case KnownElements.CheckBox: + case KnownElements.ComboBoxItem: + case KnownElements.ContentControl: + case KnownElements.Expander: + case KnownElements.GridViewColumnHeader: + case KnownElements.GroupBox: + case KnownElements.GroupItem: + case KnownElements.HeaderedContentControl: + case KnownElements.Label: + case KnownElements.ListBoxItem: + case KnownElements.ListViewItem: + case KnownElements.Page: + case KnownElements.PageFunctionBase: + case KnownElements.RadioButton: + case KnownElements.RepeatButton: + case KnownElements.ScrollViewer: + case KnownElements.StatusBarItem: + case KnownElements.TabItem: + case KnownElements.ToggleButton: + case KnownElements.ToolTip: + case KnownElements.UserControl: + case KnownElements.Window: + name = "Content"; + break; + case KnownElements.DocumentViewer: + case KnownElements.DocumentViewerBase: + case KnownElements.FlowDocumentPageViewer: + case KnownElements.FlowDocumentReader: + case KnownElements.FlowDocumentScrollViewer: + case KnownElements.RichTextBox: + name = "Document"; + break; + case KnownElements.PathGeometry: + name = "Figures"; + break; + case KnownElements.GradientBrush: + case KnownElements.LinearGradientBrush: + case KnownElements.RadialGradientBrush: + name = "GradientStops"; + break; + case KnownElements.GridViewColumn: + name = "Header"; + break; + case KnownElements.Bold: + case KnownElements.Hyperlink: + case KnownElements.Italic: + case KnownElements.Paragraph: + case KnownElements.Span: + case KnownElements.TextBlock: + case KnownElements.Underline: + name = "Inlines"; + break; + case KnownElements.ArrayExtension: + case KnownElements.ComboBox: + case KnownElements.ContextMenu: + case KnownElements.HeaderedItemsControl: + case KnownElements.ItemsControl: + case KnownElements.ListBox: + case KnownElements.ListView: + case KnownElements.Menu: + case KnownElements.MenuBase: + case KnownElements.MenuItem: + case KnownElements.Selector: + case KnownElements.StatusBar: + case KnownElements.TabControl: + case KnownElements.ToolBar: + case KnownElements.TreeView: + case KnownElements.TreeViewItem: + name = "Items"; + break; + case KnownElements.BooleanAnimationUsingKeyFrames: + case KnownElements.ByteAnimationUsingKeyFrames: + case KnownElements.CharAnimationUsingKeyFrames: + case KnownElements.ColorAnimationUsingKeyFrames: + case KnownElements.DecimalAnimationUsingKeyFrames: + case KnownElements.DoubleAnimationUsingKeyFrames: + case KnownElements.Int16AnimationUsingKeyFrames: + case KnownElements.Int32AnimationUsingKeyFrames: + case KnownElements.Int64AnimationUsingKeyFrames: + case KnownElements.MatrixAnimationUsingKeyFrames: + case KnownElements.ObjectAnimationUsingKeyFrames: + case KnownElements.Point3DAnimationUsingKeyFrames: + case KnownElements.PointAnimationUsingKeyFrames: + case KnownElements.QuaternionAnimationUsingKeyFrames: + case KnownElements.RectAnimationUsingKeyFrames: + case KnownElements.Rotation3DAnimationUsingKeyFrames: + case KnownElements.SingleAnimationUsingKeyFrames: + case KnownElements.SizeAnimationUsingKeyFrames: + case KnownElements.StringAnimationUsingKeyFrames: + case KnownElements.ThicknessAnimationUsingKeyFrames: + case KnownElements.Vector3DAnimationUsingKeyFrames: + case KnownElements.VectorAnimationUsingKeyFrames: + name = "KeyFrames"; + break; + case KnownElements.List: + name = "ListItems"; + break; + case KnownElements.InputScopeName: + name = "NameValue"; + break; + case KnownElements.FixedDocument: + name = "Pages"; + break; + case KnownElements.FixedDocumentSequence: + name = "References"; + break; + case KnownElements.Table: + name = "RowGroups"; + break; + case KnownElements.TableRowGroup: + name = "Rows"; + break; + case KnownElements.PathFigure: + name = "Segments"; + break; + case KnownElements.DataTrigger: + case KnownElements.MultiDataTrigger: + case KnownElements.MultiTrigger: + case KnownElements.Style: + case KnownElements.Trigger: + name = "Setters"; + break; + case KnownElements.BeginStoryboard: + name = "Storyboard"; + break; + case KnownElements.AccessText: + case KnownElements.Run: + case KnownElements.TextBox: + name = "Text"; + break; + case KnownElements.ToolBarTray: + name = "ToolBars"; + break; + case KnownElements.ControlTemplate: + case KnownElements.DataTemplate: + case KnownElements.FrameworkTemplate: + case KnownElements.HierarchicalDataTemplate: + case KnownElements.ItemsPanelTemplate: + name = "VisualTree"; + break; + case KnownElements.XmlDataProvider: + name = "XmlSerializer"; + break; + } + return name; + } + + internal static short GetKnownPropertyAttributeId(KnownElements typeID, string fieldName) + { + switch (typeID) + { + case KnownElements.AccessText: + if (String.CompareOrdinal(fieldName, "Text") == 0) + return (short)KnownProperties.AccessText_Text; + break; + case KnownElements.AdornedElementPlaceholder: + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.AdornedElementPlaceholder_Child; + break; + case KnownElements.AdornerDecorator: + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.AdornerDecorator_Child; + break; + case KnownElements.AnchoredBlock: + if (String.CompareOrdinal(fieldName, "Blocks") == 0) + return (short)KnownProperties.AnchoredBlock_Blocks; + break; + case KnownElements.ArrayExtension: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.ArrayExtension_Items; + break; + case KnownElements.BeginStoryboard: + if (String.CompareOrdinal(fieldName, "Storyboard") == 0) + return (short)KnownProperties.BeginStoryboard_Storyboard; + break; + case KnownElements.BitmapEffectGroup: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.BitmapEffectGroup_Children; + break; + case KnownElements.BlockUIContainer: + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.BlockUIContainer_Child; + break; + case KnownElements.Bold: + if (String.CompareOrdinal(fieldName, "Inlines") == 0) + return (short)KnownProperties.Bold_Inlines; + break; + case KnownElements.BooleanAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.BooleanAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Border: + if (String.CompareOrdinal(fieldName, "Background") == 0) + return (short)KnownProperties.Border_Background; + if (String.CompareOrdinal(fieldName, "BorderBrush") == 0) + return (short)KnownProperties.Border_BorderBrush; + if (String.CompareOrdinal(fieldName, "BorderThickness") == 0) + return (short)KnownProperties.Border_BorderThickness; + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.Border_Child; + break; + case KnownElements.BulletDecorator: + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.BulletDecorator_Child; + break; + case KnownElements.Button: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.Button_Content; + break; + case KnownElements.ButtonBase: + if (String.CompareOrdinal(fieldName, "Command") == 0) + return (short)KnownProperties.ButtonBase_Command; + if (String.CompareOrdinal(fieldName, "CommandParameter") == 0) + return (short)KnownProperties.ButtonBase_CommandParameter; + if (String.CompareOrdinal(fieldName, "CommandTarget") == 0) + return (short)KnownProperties.ButtonBase_CommandTarget; + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.ButtonBase_Content; + if (String.CompareOrdinal(fieldName, "IsPressed") == 0) + return (short)KnownProperties.ButtonBase_IsPressed; + break; + case KnownElements.ByteAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.ByteAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Canvas: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.Canvas_Children; + break; + case KnownElements.CharAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.CharAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.CheckBox: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.CheckBox_Content; + break; + case KnownElements.ColorAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.ColorAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.ColumnDefinition: + if (String.CompareOrdinal(fieldName, "MaxWidth") == 0) + return (short)KnownProperties.ColumnDefinition_MaxWidth; + if (String.CompareOrdinal(fieldName, "MinWidth") == 0) + return (short)KnownProperties.ColumnDefinition_MinWidth; + if (String.CompareOrdinal(fieldName, "Width") == 0) + return (short)KnownProperties.ColumnDefinition_Width; + break; + case KnownElements.ComboBox: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.ComboBox_Items; + break; + case KnownElements.ComboBoxItem: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.ComboBoxItem_Content; + break; + case KnownElements.ContentControl: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.ContentControl_Content; + if (String.CompareOrdinal(fieldName, "ContentTemplate") == 0) + return (short)KnownProperties.ContentControl_ContentTemplate; + if (String.CompareOrdinal(fieldName, "ContentTemplateSelector") == 0) + return (short)KnownProperties.ContentControl_ContentTemplateSelector; + if (String.CompareOrdinal(fieldName, "HasContent") == 0) + return (short)KnownProperties.ContentControl_HasContent; + break; + case KnownElements.ContentElement: + if (String.CompareOrdinal(fieldName, "Focusable") == 0) + return (short)KnownProperties.ContentElement_Focusable; + break; + case KnownElements.ContentPresenter: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.ContentPresenter_Content; + if (String.CompareOrdinal(fieldName, "ContentSource") == 0) + return (short)KnownProperties.ContentPresenter_ContentSource; + if (String.CompareOrdinal(fieldName, "ContentTemplate") == 0) + return (short)KnownProperties.ContentPresenter_ContentTemplate; + if (String.CompareOrdinal(fieldName, "ContentTemplateSelector") == 0) + return (short)KnownProperties.ContentPresenter_ContentTemplateSelector; + if (String.CompareOrdinal(fieldName, "RecognizesAccessKey") == 0) + return (short)KnownProperties.ContentPresenter_RecognizesAccessKey; + break; + case KnownElements.ContextMenu: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.ContextMenu_Items; + break; + case KnownElements.Control: + if (String.CompareOrdinal(fieldName, "Background") == 0) + return (short)KnownProperties.Control_Background; + if (String.CompareOrdinal(fieldName, "BorderBrush") == 0) + return (short)KnownProperties.Control_BorderBrush; + if (String.CompareOrdinal(fieldName, "BorderThickness") == 0) + return (short)KnownProperties.Control_BorderThickness; + if (String.CompareOrdinal(fieldName, "FontFamily") == 0) + return (short)KnownProperties.Control_FontFamily; + if (String.CompareOrdinal(fieldName, "FontSize") == 0) + return (short)KnownProperties.Control_FontSize; + if (String.CompareOrdinal(fieldName, "FontStretch") == 0) + return (short)KnownProperties.Control_FontStretch; + if (String.CompareOrdinal(fieldName, "FontStyle") == 0) + return (short)KnownProperties.Control_FontStyle; + if (String.CompareOrdinal(fieldName, "FontWeight") == 0) + return (short)KnownProperties.Control_FontWeight; + if (String.CompareOrdinal(fieldName, "Foreground") == 0) + return (short)KnownProperties.Control_Foreground; + if (String.CompareOrdinal(fieldName, "HorizontalContentAlignment") == 0) + return (short)KnownProperties.Control_HorizontalContentAlignment; + if (String.CompareOrdinal(fieldName, "IsTabStop") == 0) + return (short)KnownProperties.Control_IsTabStop; + if (String.CompareOrdinal(fieldName, "Padding") == 0) + return (short)KnownProperties.Control_Padding; + if (String.CompareOrdinal(fieldName, "TabIndex") == 0) + return (short)KnownProperties.Control_TabIndex; + if (String.CompareOrdinal(fieldName, "Template") == 0) + return (short)KnownProperties.Control_Template; + if (String.CompareOrdinal(fieldName, "VerticalContentAlignment") == 0) + return (short)KnownProperties.Control_VerticalContentAlignment; + break; + case KnownElements.ControlTemplate: + if (String.CompareOrdinal(fieldName, "VisualTree") == 0) + return (short)KnownProperties.ControlTemplate_VisualTree; + break; + case KnownElements.DataTemplate: + if (String.CompareOrdinal(fieldName, "VisualTree") == 0) + return (short)KnownProperties.DataTemplate_VisualTree; + break; + case KnownElements.DataTrigger: + if (String.CompareOrdinal(fieldName, "Setters") == 0) + return (short)KnownProperties.DataTrigger_Setters; + break; + case KnownElements.DecimalAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.DecimalAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Decorator: + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.Decorator_Child; + break; + case KnownElements.DockPanel: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.DockPanel_Children; + if (String.CompareOrdinal(fieldName, "Dock") == 0) + return (short)KnownProperties.DockPanel_Dock; + if (String.CompareOrdinal(fieldName, "LastChildFill") == 0) + return (short)KnownProperties.DockPanel_LastChildFill; + break; + case KnownElements.DocumentViewer: + if (String.CompareOrdinal(fieldName, "Document") == 0) + return (short)KnownProperties.DocumentViewer_Document; + break; + case KnownElements.DocumentViewerBase: + if (String.CompareOrdinal(fieldName, "Document") == 0) + return (short)KnownProperties.DocumentViewerBase_Document; + break; + case KnownElements.DoubleAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.DoubleAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.DrawingGroup: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.DrawingGroup_Children; + break; + case KnownElements.EventTrigger: + if (String.CompareOrdinal(fieldName, "Actions") == 0) + return (short)KnownProperties.EventTrigger_Actions; + break; + case KnownElements.Expander: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.Expander_Content; + break; + case KnownElements.Figure: + if (String.CompareOrdinal(fieldName, "Blocks") == 0) + return (short)KnownProperties.Figure_Blocks; + break; + case KnownElements.FixedDocument: + if (String.CompareOrdinal(fieldName, "Pages") == 0) + return (short)KnownProperties.FixedDocument_Pages; + break; + case KnownElements.FixedDocumentSequence: + if (String.CompareOrdinal(fieldName, "References") == 0) + return (short)KnownProperties.FixedDocumentSequence_References; + break; + case KnownElements.FixedPage: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.FixedPage_Children; + break; + case KnownElements.Floater: + if (String.CompareOrdinal(fieldName, "Blocks") == 0) + return (short)KnownProperties.Floater_Blocks; + break; + case KnownElements.FlowDocument: + if (String.CompareOrdinal(fieldName, "Blocks") == 0) + return (short)KnownProperties.FlowDocument_Blocks; + break; + case KnownElements.FlowDocumentPageViewer: + if (String.CompareOrdinal(fieldName, "Document") == 0) + return (short)KnownProperties.FlowDocumentPageViewer_Document; + break; + case KnownElements.FlowDocumentReader: + if (String.CompareOrdinal(fieldName, "Document") == 0) + return (short)KnownProperties.FlowDocumentReader_Document; + break; + case KnownElements.FlowDocumentScrollViewer: + if (String.CompareOrdinal(fieldName, "Document") == 0) + return (short)KnownProperties.FlowDocumentScrollViewer_Document; + break; + case KnownElements.FrameworkContentElement: + if (String.CompareOrdinal(fieldName, "Style") == 0) + return (short)KnownProperties.FrameworkContentElement_Style; + break; + case KnownElements.FrameworkElement: + if (String.CompareOrdinal(fieldName, "FlowDirection") == 0) + return (short)KnownProperties.FrameworkElement_FlowDirection; + if (String.CompareOrdinal(fieldName, "Height") == 0) + return (short)KnownProperties.FrameworkElement_Height; + if (String.CompareOrdinal(fieldName, "HorizontalAlignment") == 0) + return (short)KnownProperties.FrameworkElement_HorizontalAlignment; + if (String.CompareOrdinal(fieldName, "Margin") == 0) + return (short)KnownProperties.FrameworkElement_Margin; + if (String.CompareOrdinal(fieldName, "MaxHeight") == 0) + return (short)KnownProperties.FrameworkElement_MaxHeight; + if (String.CompareOrdinal(fieldName, "MaxWidth") == 0) + return (short)KnownProperties.FrameworkElement_MaxWidth; + if (String.CompareOrdinal(fieldName, "MinHeight") == 0) + return (short)KnownProperties.FrameworkElement_MinHeight; + if (String.CompareOrdinal(fieldName, "MinWidth") == 0) + return (short)KnownProperties.FrameworkElement_MinWidth; + if (String.CompareOrdinal(fieldName, "Name") == 0) + return (short)KnownProperties.FrameworkElement_Name; + if (String.CompareOrdinal(fieldName, "Style") == 0) + return (short)KnownProperties.FrameworkElement_Style; + if (String.CompareOrdinal(fieldName, "VerticalAlignment") == 0) + return (short)KnownProperties.FrameworkElement_VerticalAlignment; + if (String.CompareOrdinal(fieldName, "Width") == 0) + return (short)KnownProperties.FrameworkElement_Width; + break; + case KnownElements.FrameworkTemplate: + if (String.CompareOrdinal(fieldName, "VisualTree") == 0) + return (short)KnownProperties.FrameworkTemplate_VisualTree; + break; + case KnownElements.GeneralTransformGroup: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.GeneralTransformGroup_Children; + break; + case KnownElements.GeometryGroup: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.GeometryGroup_Children; + break; + case KnownElements.GradientBrush: + if (String.CompareOrdinal(fieldName, "GradientStops") == 0) + return (short)KnownProperties.GradientBrush_GradientStops; + break; + case KnownElements.Grid: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.Grid_Children; + if (String.CompareOrdinal(fieldName, "Column") == 0) + return (short)KnownProperties.Grid_Column; + if (String.CompareOrdinal(fieldName, "ColumnSpan") == 0) + return (short)KnownProperties.Grid_ColumnSpan; + if (String.CompareOrdinal(fieldName, "Row") == 0) + return (short)KnownProperties.Grid_Row; + if (String.CompareOrdinal(fieldName, "RowSpan") == 0) + return (short)KnownProperties.Grid_RowSpan; + break; + case KnownElements.GridView: + if (String.CompareOrdinal(fieldName, "Columns") == 0) + return (short)KnownProperties.GridView_Columns; + break; + case KnownElements.GridViewColumn: + if (String.CompareOrdinal(fieldName, "Header") == 0) + return (short)KnownProperties.GridViewColumn_Header; + break; + case KnownElements.GridViewColumnHeader: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.GridViewColumnHeader_Content; + break; + case KnownElements.GroupBox: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.GroupBox_Content; + break; + case KnownElements.GroupItem: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.GroupItem_Content; + break; + case KnownElements.HeaderedContentControl: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.HeaderedContentControl_Content; + if (String.CompareOrdinal(fieldName, "HasHeader") == 0) + return (short)KnownProperties.HeaderedContentControl_HasHeader; + if (String.CompareOrdinal(fieldName, "Header") == 0) + return (short)KnownProperties.HeaderedContentControl_Header; + if (String.CompareOrdinal(fieldName, "HeaderTemplate") == 0) + return (short)KnownProperties.HeaderedContentControl_HeaderTemplate; + if (String.CompareOrdinal(fieldName, "HeaderTemplateSelector") == 0) + return (short)KnownProperties.HeaderedContentControl_HeaderTemplateSelector; + break; + case KnownElements.HeaderedItemsControl: + if (String.CompareOrdinal(fieldName, "HasHeader") == 0) + return (short)KnownProperties.HeaderedItemsControl_HasHeader; + if (String.CompareOrdinal(fieldName, "Header") == 0) + return (short)KnownProperties.HeaderedItemsControl_Header; + if (String.CompareOrdinal(fieldName, "HeaderTemplate") == 0) + return (short)KnownProperties.HeaderedItemsControl_HeaderTemplate; + if (String.CompareOrdinal(fieldName, "HeaderTemplateSelector") == 0) + return (short)KnownProperties.HeaderedItemsControl_HeaderTemplateSelector; + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.HeaderedItemsControl_Items; + break; + case KnownElements.HierarchicalDataTemplate: + if (String.CompareOrdinal(fieldName, "VisualTree") == 0) + return (short)KnownProperties.HierarchicalDataTemplate_VisualTree; + break; + case KnownElements.Hyperlink: + if (String.CompareOrdinal(fieldName, "Inlines") == 0) + return (short)KnownProperties.Hyperlink_Inlines; + if (String.CompareOrdinal(fieldName, "NavigateUri") == 0) + return (short)KnownProperties.Hyperlink_NavigateUri; + break; + case KnownElements.Image: + if (String.CompareOrdinal(fieldName, "Source") == 0) + return (short)KnownProperties.Image_Source; + if (String.CompareOrdinal(fieldName, "Stretch") == 0) + return (short)KnownProperties.Image_Stretch; + break; + case KnownElements.InkCanvas: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.InkCanvas_Children; + break; + case KnownElements.InkPresenter: + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.InkPresenter_Child; + break; + case KnownElements.InlineUIContainer: + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.InlineUIContainer_Child; + break; + case KnownElements.InputScopeName: + if (String.CompareOrdinal(fieldName, "NameValue") == 0) + return (short)KnownProperties.InputScopeName_NameValue; + break; + case KnownElements.Int16AnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.Int16AnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Int32AnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.Int32AnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Int64AnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.Int64AnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Italic: + if (String.CompareOrdinal(fieldName, "Inlines") == 0) + return (short)KnownProperties.Italic_Inlines; + break; + case KnownElements.ItemsControl: + if (String.CompareOrdinal(fieldName, "ItemContainerStyle") == 0) + return (short)KnownProperties.ItemsControl_ItemContainerStyle; + if (String.CompareOrdinal(fieldName, "ItemContainerStyleSelector") == 0) + return (short)KnownProperties.ItemsControl_ItemContainerStyleSelector; + if (String.CompareOrdinal(fieldName, "ItemTemplate") == 0) + return (short)KnownProperties.ItemsControl_ItemTemplate; + if (String.CompareOrdinal(fieldName, "ItemTemplateSelector") == 0) + return (short)KnownProperties.ItemsControl_ItemTemplateSelector; + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.ItemsControl_Items; + if (String.CompareOrdinal(fieldName, "ItemsPanel") == 0) + return (short)KnownProperties.ItemsControl_ItemsPanel; + if (String.CompareOrdinal(fieldName, "ItemsSource") == 0) + return (short)KnownProperties.ItemsControl_ItemsSource; + break; + case KnownElements.ItemsPanelTemplate: + if (String.CompareOrdinal(fieldName, "VisualTree") == 0) + return (short)KnownProperties.ItemsPanelTemplate_VisualTree; + break; + case KnownElements.Label: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.Label_Content; + break; + case KnownElements.LinearGradientBrush: + if (String.CompareOrdinal(fieldName, "GradientStops") == 0) + return (short)KnownProperties.LinearGradientBrush_GradientStops; + break; + case KnownElements.List: + if (String.CompareOrdinal(fieldName, "ListItems") == 0) + return (short)KnownProperties.List_ListItems; + break; + case KnownElements.ListBox: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.ListBox_Items; + break; + case KnownElements.ListBoxItem: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.ListBoxItem_Content; + break; + case KnownElements.ListItem: + if (String.CompareOrdinal(fieldName, "Blocks") == 0) + return (short)KnownProperties.ListItem_Blocks; + break; + case KnownElements.ListView: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.ListView_Items; + break; + case KnownElements.ListViewItem: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.ListViewItem_Content; + break; + case KnownElements.MaterialGroup: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.MaterialGroup_Children; + break; + case KnownElements.MatrixAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.MatrixAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Menu: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.Menu_Items; + break; + case KnownElements.MenuBase: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.MenuBase_Items; + break; + case KnownElements.MenuItem: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.MenuItem_Items; + break; + case KnownElements.Model3DGroup: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.Model3DGroup_Children; + break; + case KnownElements.ModelVisual3D: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.ModelVisual3D_Children; + break; + case KnownElements.MultiBinding: + if (String.CompareOrdinal(fieldName, "Bindings") == 0) + return (short)KnownProperties.MultiBinding_Bindings; + break; + case KnownElements.MultiDataTrigger: + if (String.CompareOrdinal(fieldName, "Setters") == 0) + return (short)KnownProperties.MultiDataTrigger_Setters; + break; + case KnownElements.MultiTrigger: + if (String.CompareOrdinal(fieldName, "Setters") == 0) + return (short)KnownProperties.MultiTrigger_Setters; + break; + case KnownElements.ObjectAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.ObjectAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Page: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.Page_Content; + break; + case KnownElements.PageContent: + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.PageContent_Child; + break; + case KnownElements.PageFunctionBase: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.PageFunctionBase_Content; + break; + case KnownElements.Panel: + if (String.CompareOrdinal(fieldName, "Background") == 0) + return (short)KnownProperties.Panel_Background; + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.Panel_Children; + break; + case KnownElements.Paragraph: + if (String.CompareOrdinal(fieldName, "Inlines") == 0) + return (short)KnownProperties.Paragraph_Inlines; + break; + case KnownElements.ParallelTimeline: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.ParallelTimeline_Children; + break; + case KnownElements.Path: + if (String.CompareOrdinal(fieldName, "Data") == 0) + return (short)KnownProperties.Path_Data; + break; + case KnownElements.PathFigure: + if (String.CompareOrdinal(fieldName, "Segments") == 0) + return (short)KnownProperties.PathFigure_Segments; + break; + case KnownElements.PathGeometry: + if (String.CompareOrdinal(fieldName, "Figures") == 0) + return (short)KnownProperties.PathGeometry_Figures; + break; + case KnownElements.Point3DAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.Point3DAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.PointAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.PointAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Popup: + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.Popup_Child; + if (String.CompareOrdinal(fieldName, "IsOpen") == 0) + return (short)KnownProperties.Popup_IsOpen; + if (String.CompareOrdinal(fieldName, "Placement") == 0) + return (short)KnownProperties.Popup_Placement; + if (String.CompareOrdinal(fieldName, "PopupAnimation") == 0) + return (short)KnownProperties.Popup_PopupAnimation; + break; + case KnownElements.PriorityBinding: + if (String.CompareOrdinal(fieldName, "Bindings") == 0) + return (short)KnownProperties.PriorityBinding_Bindings; + break; + case KnownElements.QuaternionAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.QuaternionAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.RadialGradientBrush: + if (String.CompareOrdinal(fieldName, "GradientStops") == 0) + return (short)KnownProperties.RadialGradientBrush_GradientStops; + break; + case KnownElements.RadioButton: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.RadioButton_Content; + break; + case KnownElements.RectAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.RectAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.RepeatButton: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.RepeatButton_Content; + break; + case KnownElements.RichTextBox: + if (String.CompareOrdinal(fieldName, "Document") == 0) + return (short)KnownProperties.RichTextBox_Document; + break; + case KnownElements.Rotation3DAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.Rotation3DAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.RowDefinition: + if (String.CompareOrdinal(fieldName, "Height") == 0) + return (short)KnownProperties.RowDefinition_Height; + if (String.CompareOrdinal(fieldName, "MaxHeight") == 0) + return (short)KnownProperties.RowDefinition_MaxHeight; + if (String.CompareOrdinal(fieldName, "MinHeight") == 0) + return (short)KnownProperties.RowDefinition_MinHeight; + break; + case KnownElements.Run: + if (String.CompareOrdinal(fieldName, "Text") == 0) + return (short)KnownProperties.Run_Text; + break; + case KnownElements.ScrollViewer: + if (String.CompareOrdinal(fieldName, "CanContentScroll") == 0) + return (short)KnownProperties.ScrollViewer_CanContentScroll; + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.ScrollViewer_Content; + if (String.CompareOrdinal(fieldName, "HorizontalScrollBarVisibility") == 0) + return (short)KnownProperties.ScrollViewer_HorizontalScrollBarVisibility; + if (String.CompareOrdinal(fieldName, "VerticalScrollBarVisibility") == 0) + return (short)KnownProperties.ScrollViewer_VerticalScrollBarVisibility; + break; + case KnownElements.Section: + if (String.CompareOrdinal(fieldName, "Blocks") == 0) + return (short)KnownProperties.Section_Blocks; + break; + case KnownElements.Selector: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.Selector_Items; + break; + case KnownElements.Shape: + if (String.CompareOrdinal(fieldName, "Fill") == 0) + return (short)KnownProperties.Shape_Fill; + if (String.CompareOrdinal(fieldName, "Stroke") == 0) + return (short)KnownProperties.Shape_Stroke; + if (String.CompareOrdinal(fieldName, "StrokeThickness") == 0) + return (short)KnownProperties.Shape_StrokeThickness; + break; + case KnownElements.SingleAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.SingleAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.SizeAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.SizeAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Span: + if (String.CompareOrdinal(fieldName, "Inlines") == 0) + return (short)KnownProperties.Span_Inlines; + break; + case KnownElements.StackPanel: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.StackPanel_Children; + break; + case KnownElements.StatusBar: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.StatusBar_Items; + break; + case KnownElements.StatusBarItem: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.StatusBarItem_Content; + break; + case KnownElements.Storyboard: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.Storyboard_Children; + break; + case KnownElements.StringAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.StringAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Style: + if (String.CompareOrdinal(fieldName, "Setters") == 0) + return (short)KnownProperties.Style_Setters; + break; + case KnownElements.TabControl: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.TabControl_Items; + break; + case KnownElements.TabItem: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.TabItem_Content; + break; + case KnownElements.TabPanel: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.TabPanel_Children; + break; + case KnownElements.Table: + if (String.CompareOrdinal(fieldName, "RowGroups") == 0) + return (short)KnownProperties.Table_RowGroups; + break; + case KnownElements.TableCell: + if (String.CompareOrdinal(fieldName, "Blocks") == 0) + return (short)KnownProperties.TableCell_Blocks; + break; + case KnownElements.TableRow: + if (String.CompareOrdinal(fieldName, "Cells") == 0) + return (short)KnownProperties.TableRow_Cells; + break; + case KnownElements.TableRowGroup: + if (String.CompareOrdinal(fieldName, "Rows") == 0) + return (short)KnownProperties.TableRowGroup_Rows; + break; + case KnownElements.TextBlock: + if (String.CompareOrdinal(fieldName, "Background") == 0) + return (short)KnownProperties.TextBlock_Background; + if (String.CompareOrdinal(fieldName, "FontFamily") == 0) + return (short)KnownProperties.TextBlock_FontFamily; + if (String.CompareOrdinal(fieldName, "FontSize") == 0) + return (short)KnownProperties.TextBlock_FontSize; + if (String.CompareOrdinal(fieldName, "FontStretch") == 0) + return (short)KnownProperties.TextBlock_FontStretch; + if (String.CompareOrdinal(fieldName, "FontStyle") == 0) + return (short)KnownProperties.TextBlock_FontStyle; + if (String.CompareOrdinal(fieldName, "FontWeight") == 0) + return (short)KnownProperties.TextBlock_FontWeight; + if (String.CompareOrdinal(fieldName, "Foreground") == 0) + return (short)KnownProperties.TextBlock_Foreground; + if (String.CompareOrdinal(fieldName, "Inlines") == 0) + return (short)KnownProperties.TextBlock_Inlines; + if (String.CompareOrdinal(fieldName, "Text") == 0) + return (short)KnownProperties.TextBlock_Text; + if (String.CompareOrdinal(fieldName, "TextDecorations") == 0) + return (short)KnownProperties.TextBlock_TextDecorations; + if (String.CompareOrdinal(fieldName, "TextTrimming") == 0) + return (short)KnownProperties.TextBlock_TextTrimming; + if (String.CompareOrdinal(fieldName, "TextWrapping") == 0) + return (short)KnownProperties.TextBlock_TextWrapping; + break; + case KnownElements.TextBox: + if (String.CompareOrdinal(fieldName, "Text") == 0) + return (short)KnownProperties.TextBox_Text; + break; + case KnownElements.TextElement: + if (String.CompareOrdinal(fieldName, "Background") == 0) + return (short)KnownProperties.TextElement_Background; + if (String.CompareOrdinal(fieldName, "FontFamily") == 0) + return (short)KnownProperties.TextElement_FontFamily; + if (String.CompareOrdinal(fieldName, "FontSize") == 0) + return (short)KnownProperties.TextElement_FontSize; + if (String.CompareOrdinal(fieldName, "FontStretch") == 0) + return (short)KnownProperties.TextElement_FontStretch; + if (String.CompareOrdinal(fieldName, "FontStyle") == 0) + return (short)KnownProperties.TextElement_FontStyle; + if (String.CompareOrdinal(fieldName, "FontWeight") == 0) + return (short)KnownProperties.TextElement_FontWeight; + if (String.CompareOrdinal(fieldName, "Foreground") == 0) + return (short)KnownProperties.TextElement_Foreground; + break; + case KnownElements.ThicknessAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.ThicknessAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.TimelineGroup: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.TimelineGroup_Children; + break; + case KnownElements.ToggleButton: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.ToggleButton_Content; + break; + case KnownElements.ToolBar: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.ToolBar_Items; + break; + case KnownElements.ToolBarOverflowPanel: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.ToolBarOverflowPanel_Children; + break; + case KnownElements.ToolBarPanel: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.ToolBarPanel_Children; + break; + case KnownElements.ToolBarTray: + if (String.CompareOrdinal(fieldName, "ToolBars") == 0) + return (short)KnownProperties.ToolBarTray_ToolBars; + break; + case KnownElements.ToolTip: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.ToolTip_Content; + break; + case KnownElements.Track: + if (String.CompareOrdinal(fieldName, "IsDirectionReversed") == 0) + return (short)KnownProperties.Track_IsDirectionReversed; + if (String.CompareOrdinal(fieldName, "Maximum") == 0) + return (short)KnownProperties.Track_Maximum; + if (String.CompareOrdinal(fieldName, "Minimum") == 0) + return (short)KnownProperties.Track_Minimum; + if (String.CompareOrdinal(fieldName, "Orientation") == 0) + return (short)KnownProperties.Track_Orientation; + if (String.CompareOrdinal(fieldName, "Value") == 0) + return (short)KnownProperties.Track_Value; + if (String.CompareOrdinal(fieldName, "ViewportSize") == 0) + return (short)KnownProperties.Track_ViewportSize; + break; + case KnownElements.Transform3DGroup: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.Transform3DGroup_Children; + break; + case KnownElements.TransformGroup: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.TransformGroup_Children; + break; + case KnownElements.TreeView: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.TreeView_Items; + break; + case KnownElements.TreeViewItem: + if (String.CompareOrdinal(fieldName, "Items") == 0) + return (short)KnownProperties.TreeViewItem_Items; + break; + case KnownElements.Trigger: + if (String.CompareOrdinal(fieldName, "Setters") == 0) + return (short)KnownProperties.Trigger_Setters; + break; + case KnownElements.UIElement: + if (String.CompareOrdinal(fieldName, "ClipToBounds") == 0) + return (short)KnownProperties.UIElement_ClipToBounds; + if (String.CompareOrdinal(fieldName, "Focusable") == 0) + return (short)KnownProperties.UIElement_Focusable; + if (String.CompareOrdinal(fieldName, "IsEnabled") == 0) + return (short)KnownProperties.UIElement_IsEnabled; + if (String.CompareOrdinal(fieldName, "RenderTransform") == 0) + return (short)KnownProperties.UIElement_RenderTransform; + if (String.CompareOrdinal(fieldName, "Visibility") == 0) + return (short)KnownProperties.UIElement_Visibility; + break; + case KnownElements.Underline: + if (String.CompareOrdinal(fieldName, "Inlines") == 0) + return (short)KnownProperties.Underline_Inlines; + break; + case KnownElements.UniformGrid: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.UniformGrid_Children; + break; + case KnownElements.UserControl: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.UserControl_Content; + break; + case KnownElements.Vector3DAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.Vector3DAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.VectorAnimationUsingKeyFrames: + if (String.CompareOrdinal(fieldName, "KeyFrames") == 0) + return (short)KnownProperties.VectorAnimationUsingKeyFrames_KeyFrames; + break; + case KnownElements.Viewbox: + if (String.CompareOrdinal(fieldName, "Child") == 0) + return (short)KnownProperties.Viewbox_Child; + break; + case KnownElements.Viewport3D: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.Viewport3D_Children; + break; + case KnownElements.Viewport3DVisual: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.Viewport3DVisual_Children; + break; + case KnownElements.VirtualizingPanel: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.VirtualizingPanel_Children; + break; + case KnownElements.VirtualizingStackPanel: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.VirtualizingStackPanel_Children; + break; + case KnownElements.Window: + if (String.CompareOrdinal(fieldName, "Content") == 0) + return (short)KnownProperties.Window_Content; + break; + case KnownElements.WrapPanel: + if (String.CompareOrdinal(fieldName, "Children") == 0) + return (short)KnownProperties.WrapPanel_Children; + break; + case KnownElements.XmlDataProvider: + if (String.CompareOrdinal(fieldName, "XmlSerializer") == 0) + return (short)KnownProperties.XmlDataProvider_XmlSerializer; + break; + } + return 0; + } + + private static bool IsStandardLengthProp(string propName) + { + return (String.CompareOrdinal(propName, "Width") == 0 || + String.CompareOrdinal(propName, "MinWidth") == 0 || + String.CompareOrdinal(propName, "MaxWidth") == 0 || + String.CompareOrdinal(propName, "Height") == 0 || + String.CompareOrdinal(propName, "MinHeight") == 0 || + String.CompareOrdinal(propName, "MaxHeight") == 0); + } + + // Look for a converter type that is associated with a known type. + // Return KnownElements.UnknownElements if not found. + internal static KnownElements GetKnownTypeConverterId(KnownElements knownElement) + { + KnownElements converterId = KnownElements.UnknownElement; + switch (knownElement) + { + case KnownElements.ComponentResourceKey: converterId = KnownElements.ComponentResourceKeyConverter; break; + case KnownElements.CornerRadius: converterId = KnownElements.CornerRadiusConverter; break; + case KnownElements.BindingExpressionBase: converterId = KnownElements.ExpressionConverter; break; + case KnownElements.BindingExpression: converterId = KnownElements.ExpressionConverter; break; + case KnownElements.MultiBindingExpression: converterId = KnownElements.ExpressionConverter; break; + case KnownElements.PriorityBindingExpression: converterId = KnownElements.ExpressionConverter; break; + case KnownElements.TemplateKey: converterId = KnownElements.TemplateKeyConverter; break; + case KnownElements.DataTemplateKey: converterId = KnownElements.TemplateKeyConverter; break; + case KnownElements.DynamicResourceExtension: converterId = KnownElements.DynamicResourceExtensionConverter; break; + case KnownElements.FigureLength: converterId = KnownElements.FigureLengthConverter; break; + case KnownElements.GridLength: converterId = KnownElements.GridLengthConverter; break; + case KnownElements.PropertyPath: converterId = KnownElements.PropertyPathConverter; break; + case KnownElements.TemplateBindingExpression: converterId = KnownElements.TemplateBindingExpressionConverter; break; + case KnownElements.TemplateBindingExtension: converterId = KnownElements.TemplateBindingExtensionConverter; break; + case KnownElements.Thickness: converterId = KnownElements.ThicknessConverter; break; + case KnownElements.Duration: converterId = KnownElements.DurationConverter; break; + case KnownElements.FontStyle: converterId = KnownElements.FontStyleConverter; break; + case KnownElements.FontStretch: converterId = KnownElements.FontStretchConverter; break; + case KnownElements.FontWeight: converterId = KnownElements.FontWeightConverter; break; + case KnownElements.RoutedEvent: converterId = KnownElements.RoutedEventConverter; break; + case KnownElements.TextDecorationCollection: converterId = KnownElements.TextDecorationCollectionConverter; break; + case KnownElements.StrokeCollection: converterId = KnownElements.StrokeCollectionConverter; break; + case KnownElements.ICommand: converterId = KnownElements.CommandConverter; break; + case KnownElements.KeyGesture: converterId = KnownElements.KeyGestureConverter; break; + case KnownElements.MouseGesture: converterId = KnownElements.MouseGestureConverter; break; + case KnownElements.RoutedCommand: converterId = KnownElements.CommandConverter; break; + case KnownElements.RoutedUICommand: converterId = KnownElements.CommandConverter; break; + case KnownElements.Cursor: converterId = KnownElements.CursorConverter; break; + case KnownElements.InputScope: converterId = KnownElements.InputScopeConverter; break; + case KnownElements.InputScopeName: converterId = KnownElements.InputScopeNameConverter; break; + case KnownElements.KeySpline: converterId = KnownElements.KeySplineConverter; break; + case KnownElements.KeyTime: converterId = KnownElements.KeyTimeConverter; break; + case KnownElements.RepeatBehavior: converterId = KnownElements.RepeatBehaviorConverter; break; + case KnownElements.Brush: converterId = KnownElements.BrushConverter; break; + case KnownElements.Color: converterId = KnownElements.ColorConverter; break; + case KnownElements.Geometry: converterId = KnownElements.GeometryConverter; break; + case KnownElements.CombinedGeometry: converterId = KnownElements.GeometryConverter; break; + case KnownElements.TileBrush: converterId = KnownElements.BrushConverter; break; + case KnownElements.DrawingBrush: converterId = KnownElements.BrushConverter; break; + case KnownElements.ImageSource: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.DrawingImage: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.EllipseGeometry: converterId = KnownElements.GeometryConverter; break; + case KnownElements.FontFamily: converterId = KnownElements.FontFamilyConverter; break; + case KnownElements.DoubleCollection: converterId = KnownElements.DoubleCollectionConverter; break; + case KnownElements.GeometryGroup: converterId = KnownElements.GeometryConverter; break; + case KnownElements.GradientBrush: converterId = KnownElements.BrushConverter; break; + case KnownElements.ImageBrush: converterId = KnownElements.BrushConverter; break; + case KnownElements.Int32Collection: converterId = KnownElements.Int32CollectionConverter; break; + case KnownElements.LinearGradientBrush: converterId = KnownElements.BrushConverter; break; + case KnownElements.LineGeometry: converterId = KnownElements.GeometryConverter; break; + case KnownElements.Transform: converterId = KnownElements.TransformConverter; break; + case KnownElements.MatrixTransform: converterId = KnownElements.TransformConverter; break; + case KnownElements.PathFigureCollection: converterId = KnownElements.PathFigureCollectionConverter; break; + case KnownElements.PathGeometry: converterId = KnownElements.GeometryConverter; break; + case KnownElements.PointCollection: converterId = KnownElements.PointCollectionConverter; break; + case KnownElements.RadialGradientBrush: converterId = KnownElements.BrushConverter; break; + case KnownElements.RectangleGeometry: converterId = KnownElements.GeometryConverter; break; + case KnownElements.RotateTransform: converterId = KnownElements.TransformConverter; break; + case KnownElements.ScaleTransform: converterId = KnownElements.TransformConverter; break; + case KnownElements.SkewTransform: converterId = KnownElements.TransformConverter; break; + case KnownElements.SolidColorBrush: converterId = KnownElements.BrushConverter; break; + case KnownElements.StreamGeometry: converterId = KnownElements.GeometryConverter; break; + case KnownElements.TransformGroup: converterId = KnownElements.TransformConverter; break; + case KnownElements.TranslateTransform: converterId = KnownElements.TransformConverter; break; + case KnownElements.VectorCollection: converterId = KnownElements.VectorCollectionConverter; break; + case KnownElements.VisualBrush: converterId = KnownElements.BrushConverter; break; + case KnownElements.BitmapSource: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.BitmapFrame: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.BitmapImage: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.CachedBitmap: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.ColorConvertedBitmap: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.CroppedBitmap: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.FormatConvertedBitmap: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.RenderTargetBitmap: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.TransformedBitmap: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.WriteableBitmap: converterId = KnownElements.ImageSourceConverter; break; + case KnownElements.PixelFormat: converterId = KnownElements.PixelFormatConverter; break; + case KnownElements.Matrix3D: converterId = KnownElements.Matrix3DConverter; break; + case KnownElements.Point3D: converterId = KnownElements.Point3DConverter; break; + case KnownElements.Point3DCollection: converterId = KnownElements.Point3DCollectionConverter; break; + case KnownElements.Vector3DCollection: converterId = KnownElements.Vector3DCollectionConverter; break; + case KnownElements.Point4D: converterId = KnownElements.Point4DConverter; break; + case KnownElements.Quaternion: converterId = KnownElements.QuaternionConverter; break; + case KnownElements.Rect3D: converterId = KnownElements.Rect3DConverter; break; + case KnownElements.Size3D: converterId = KnownElements.Size3DConverter; break; + case KnownElements.Vector3D: converterId = KnownElements.Vector3DConverter; break; + case KnownElements.XmlLanguage: converterId = KnownElements.XmlLanguageConverter; break; + case KnownElements.Point: converterId = KnownElements.PointConverter; break; + case KnownElements.Size: converterId = KnownElements.SizeConverter; break; + case KnownElements.Vector: converterId = KnownElements.VectorConverter; break; + case KnownElements.Rect: converterId = KnownElements.RectConverter; break; + case KnownElements.Matrix: converterId = KnownElements.MatrixConverter; break; + case KnownElements.DependencyProperty: converterId = KnownElements.DependencyPropertyConverter; break; + case KnownElements.Expression: converterId = KnownElements.ExpressionConverter; break; + case KnownElements.Int32Rect: converterId = KnownElements.Int32RectConverter; break; + case KnownElements.Boolean: converterId = KnownElements.BooleanConverter; break; + case KnownElements.Int16: converterId = KnownElements.Int16Converter; break; + case KnownElements.Int32: converterId = KnownElements.Int32Converter; break; + case KnownElements.Int64: converterId = KnownElements.Int64Converter; break; + case KnownElements.UInt16: converterId = KnownElements.UInt16Converter; break; + case KnownElements.UInt32: converterId = KnownElements.UInt32Converter; break; + case KnownElements.UInt64: converterId = KnownElements.UInt64Converter; break; + case KnownElements.Single: converterId = KnownElements.SingleConverter; break; + case KnownElements.Double: converterId = KnownElements.DoubleConverter; break; + case KnownElements.Object: converterId = KnownElements.StringConverter; break; + case KnownElements.String: converterId = KnownElements.StringConverter; break; + case KnownElements.Byte: converterId = KnownElements.ByteConverter; break; + case KnownElements.SByte: converterId = KnownElements.SByteConverter; break; + case KnownElements.Char: converterId = KnownElements.CharConverter; break; + case KnownElements.Decimal: converterId = KnownElements.DecimalConverter; break; + case KnownElements.TimeSpan: converterId = KnownElements.TimeSpanConverter; break; + case KnownElements.Guid: converterId = KnownElements.GuidConverter; break; + case KnownElements.DateTime: converterId = KnownElements.DateTimeConverter2; break; + case KnownElements.Uri: converterId = KnownElements.UriTypeConverter; break; + case KnownElements.CultureInfo: converterId = KnownElements.CultureInfoConverter; break; + } + return converterId; + } + + // Look for a converter type that is associated with a known type. + // Return KnownElements.UnknownElements if not found. + internal static KnownElements GetKnownTypeConverterIdForProperty( + KnownElements id, + string propName) + { + KnownElements converterId = KnownElements.UnknownElement; + switch (id) + { + case KnownElements.ColumnDefinition: + if (String.CompareOrdinal(propName, "MinWidth") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "MaxWidth") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.RowDefinition: + if (String.CompareOrdinal(propName, "MinHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "MaxHeight") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.FrameworkElement: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Adorner: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Shape: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "StrokeThickness") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Panel: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Canvas: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Left") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Top") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Right") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Bottom") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Control: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ContentControl: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Window: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Top") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Left") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "DialogResult") == 0) + converterId = KnownElements.DialogResultConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.NavigationWindow: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Top") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Left") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "DialogResult") == 0) + converterId = KnownElements.DialogResultConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.CollectionView: + if (String.CompareOrdinal(propName, "Culture") == 0) + converterId = KnownElements.CultureInfoIetfLanguageTagConverter; + break; + case KnownElements.StickyNoteControl: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ItemsControl: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.MenuBase: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ContextMenu: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "HorizontalOffset") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "VerticalOffset") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.HeaderedItemsControl: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.MenuItem: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.FlowDocumentScrollViewer: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.DocumentViewerBase: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.FlowDocumentPageViewer: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.AccessText: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + else if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.AdornedElementPlaceholder: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Decorator: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Border: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.ButtonBase: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Button: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ToggleButton: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "IsChecked") == 0) + converterId = KnownElements.NullableBoolConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.CheckBox: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "IsChecked") == 0) + converterId = KnownElements.NullableBoolConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Selector: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "IsSynchronizedWithCurrentItem") == 0) + converterId = KnownElements.NullableBoolConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ComboBox: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "MaxDropDownHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "IsSynchronizedWithCurrentItem") == 0) + converterId = KnownElements.NullableBoolConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ListBoxItem: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ComboBoxItem: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ContentPresenter: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.ContextMenuService: + if (String.CompareOrdinal(propName, "HorizontalOffset") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "VerticalOffset") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.DockPanel: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.DocumentViewer: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.HeaderedContentControl: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Expander: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.FlowDocumentReader: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Frame: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Grid: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.GridViewColumn: + if (String.CompareOrdinal(propName, "Width") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.GridViewColumnHeader: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.GridViewRowPresenterBase: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.GridViewHeaderRowPresenter: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.GridViewRowPresenter: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Thumb: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.GridSplitter: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.GroupBox: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.GroupItem: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Image: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.InkCanvas: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Top") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Bottom") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Left") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Right") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.InkPresenter: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.ItemCollection: + if (String.CompareOrdinal(propName, "Culture") == 0) + converterId = KnownElements.CultureInfoIetfLanguageTagConverter; + break; + case KnownElements.ItemsPresenter: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Label: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ListBox: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "IsSynchronizedWithCurrentItem") == 0) + converterId = KnownElements.NullableBoolConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ListView: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "IsSynchronizedWithCurrentItem") == 0) + converterId = KnownElements.NullableBoolConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ListViewItem: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.MediaElement: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Menu: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Page: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.PasswordBox: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.BulletDecorator: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.DocumentPageView: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Popup: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "HorizontalOffset") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "VerticalOffset") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.RangeBase: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.RepeatButton: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ResizeGrip: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ScrollBar: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ScrollContentPresenter: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.StatusBar: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.StatusBarItem: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.TabPanel: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.TextBoxBase: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.TickBar: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.ToolBarOverflowPanel: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.StackPanel: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.ToolBarPanel: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Track: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.UniformGrid: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.ProgressBar: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.RadioButton: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "IsChecked") == 0) + converterId = KnownElements.NullableBoolConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.RichTextBox: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ScrollViewer: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Separator: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Slider: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.TabControl: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "IsSynchronizedWithCurrentItem") == 0) + converterId = KnownElements.NullableBoolConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.TabItem: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.TextBlock: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + else if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.TextBox: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ToolBar: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ToolBarTray: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.ToolTip: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "HorizontalOffset") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "VerticalOffset") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ToolTipService: + if (String.CompareOrdinal(propName, "HorizontalOffset") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "VerticalOffset") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.TreeView: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.TreeViewItem: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.UserControl: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Viewbox: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Viewport3D: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.VirtualizingPanel: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.VirtualizingStackPanel: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.WrapPanel: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "ItemWidth") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "ItemHeight") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Binding: + if (String.CompareOrdinal(propName, "ConverterCulture") == 0) + converterId = KnownElements.CultureInfoIetfLanguageTagConverter; + break; + case KnownElements.BindingListCollectionView: + if (String.CompareOrdinal(propName, "Culture") == 0) + converterId = KnownElements.CultureInfoIetfLanguageTagConverter; + break; + case KnownElements.CollectionViewSource: + if (String.CompareOrdinal(propName, "Culture") == 0) + converterId = KnownElements.CultureInfoIetfLanguageTagConverter; + break; + case KnownElements.ListCollectionView: + if (String.CompareOrdinal(propName, "Culture") == 0) + converterId = KnownElements.CultureInfoIetfLanguageTagConverter; + break; + case KnownElements.MultiBinding: + if (String.CompareOrdinal(propName, "ConverterCulture") == 0) + converterId = KnownElements.CultureInfoIetfLanguageTagConverter; + break; + case KnownElements.AdornerDecorator: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.AdornerLayer: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.TextElement: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Inline: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.AnchoredBlock: + if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Block: + if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.BlockUIContainer: + if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Span: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Bold: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.DocumentReference: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Figure: + if (String.CompareOrdinal(propName, "HorizontalOffset") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "VerticalOffset") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.FixedPage: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Left") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Top") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Right") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Bottom") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Floater: + if (String.CompareOrdinal(propName, "Width") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.FlowDocument: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + else if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "ColumnWidth") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "ColumnGap") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "ColumnRuleWidth") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "PageWidth") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "MinPageWidth") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "MaxPageWidth") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "PageHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "MinPageHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "MaxPageHeight") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Glyphs: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontRenderingEmSize") == 0) + converterId = KnownElements.FontSizeConverter; + else if (String.CompareOrdinal(propName, "OriginX") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "OriginY") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Hyperlink: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.InlineUIContainer: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Italic: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.LineBreak: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.List: + if (String.CompareOrdinal(propName, "MarkerOffset") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.ListItem: + if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.PageContent: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Paragraph: + if (String.CompareOrdinal(propName, "TextIndent") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Run: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Section: + if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Table: + if (String.CompareOrdinal(propName, "CellSpacing") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.TableCell: + if (String.CompareOrdinal(propName, "LineHeight") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.TableRow: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.TableRowGroup: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Underline: + if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.PageFunctionBase: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "FontSize") == 0) + converterId = KnownElements.FontSizeConverter; + break; + case KnownElements.Ellipse: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "StrokeThickness") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Line: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "X1") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Y1") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "X2") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "Y2") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "StrokeThickness") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Path: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "StrokeThickness") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Polygon: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "StrokeThickness") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Polyline: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "StrokeThickness") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.Rectangle: + if (IsStandardLengthProp(propName)) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "RadiusX") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "RadiusY") == 0) + converterId = KnownElements.LengthConverter; + else if (String.CompareOrdinal(propName, "StrokeThickness") == 0) + converterId = KnownElements.LengthConverter; + break; + case KnownElements.InputBinding: + if (String.CompareOrdinal(propName, "Command") == 0) + converterId = KnownElements.CommandConverter; + break; + case KnownElements.KeyBinding: + if (String.CompareOrdinal(propName, "Gesture") == 0) + converterId = KnownElements.KeyGestureConverter; + else if (String.CompareOrdinal(propName, "Command") == 0) + converterId = KnownElements.CommandConverter; + break; + case KnownElements.MouseBinding: + if (String.CompareOrdinal(propName, "Gesture") == 0) + converterId = KnownElements.MouseGestureConverter; + else if (String.CompareOrdinal(propName, "Command") == 0) + converterId = KnownElements.CommandConverter; + break; + case KnownElements.InputLanguageManager: + if (String.CompareOrdinal(propName, "CurrentInputLanguage") == 0) + converterId = KnownElements.CultureInfoIetfLanguageTagConverter; + else if (String.CompareOrdinal(propName, "InputLanguage") == 0) + converterId = KnownElements.CultureInfoIetfLanguageTagConverter; + break; + case KnownElements.GlyphRun: + if (String.CompareOrdinal(propName, "CaretStops") == 0) + converterId = KnownElements.BoolIListConverter; + else if (String.CompareOrdinal(propName, "ClusterMap") == 0) + converterId = KnownElements.UShortIListConverter; + else if (String.CompareOrdinal(propName, "Characters") == 0) + converterId = KnownElements.CharIListConverter; + else if (String.CompareOrdinal(propName, "GlyphIndices") == 0) + converterId = KnownElements.UShortIListConverter; + else if (String.CompareOrdinal(propName, "AdvanceWidths") == 0) + converterId = KnownElements.DoubleIListConverter; + else if (String.CompareOrdinal(propName, "GlyphOffsets") == 0) + converterId = KnownElements.PointIListConverter; + break; + case KnownElements.NumberSubstitution: + if (String.CompareOrdinal(propName, "CultureOverride") == 0) + converterId = KnownElements.CultureInfoIetfLanguageTagConverter; + break; + } + return converterId; + } + } + + // Index class for lazy initialization of KnownTypes on the Compiler path. + internal partial class TypeIndexer + { +#if PBTCOMPILER + private static bool _initialized = false; + private static Assembly _asmFramework; + private static Assembly _asmCore; + private static Assembly _asmBase; + + public void Initialize(Assembly asmFramework, Assembly asmCore, Assembly asmBase) + { + // Paramater validation + + Debug.Assert(asmFramework != null, "asmFramework must not be null"); + Debug.Assert(asmCore != null, "asmCore must not be null"); + Debug.Assert(asmBase != null, "asmBase must not be null"); + + if (!_initialized) + { + _asmFramework = asmFramework; + _asmCore = asmCore; + _asmBase = asmBase; + _initialized = true; + } + } + + // Initialize the Known WCP types from basic WCP assemblies + private Type InitializeOneType(KnownElements knownElement) + { + Type t = null; + switch(knownElement) + { + case KnownElements.FrameworkContentElement: t = _asmFramework.GetType("System.Windows.FrameworkContentElement"); break; + case KnownElements.DefinitionBase: t = _asmFramework.GetType("System.Windows.Controls.DefinitionBase"); break; + case KnownElements.ColumnDefinition: t = _asmFramework.GetType("System.Windows.Controls.ColumnDefinition"); break; + case KnownElements.RowDefinition: t = _asmFramework.GetType("System.Windows.Controls.RowDefinition"); break; + case KnownElements.FrameworkElement: t = _asmFramework.GetType("System.Windows.FrameworkElement"); break; + case KnownElements.Adorner: t = _asmFramework.GetType("System.Windows.Documents.Adorner"); break; + case KnownElements.Shape: t = _asmFramework.GetType("System.Windows.Shapes.Shape"); break; + case KnownElements.Panel: t = _asmFramework.GetType("System.Windows.Controls.Panel"); break; + case KnownElements.Canvas: t = _asmFramework.GetType("System.Windows.Controls.Canvas"); break; + case KnownElements.JournalEntry: t = _asmFramework.GetType("System.Windows.Navigation.JournalEntry"); break; + case KnownElements.Control: t = _asmFramework.GetType("System.Windows.Controls.Control"); break; + case KnownElements.ContentControl: t = _asmFramework.GetType("System.Windows.Controls.ContentControl"); break; + case KnownElements.Window: t = _asmFramework.GetType("System.Windows.Window"); break; + case KnownElements.NavigationWindow: t = _asmFramework.GetType("System.Windows.Navigation.NavigationWindow"); break; + case KnownElements.Application: t = _asmFramework.GetType("System.Windows.Application"); break; + case KnownElements.CollectionView: t = _asmFramework.GetType("System.Windows.Data.CollectionView"); break; + case KnownElements.StickyNoteControl: t = _asmFramework.GetType("System.Windows.Controls.StickyNoteControl"); break; + case KnownElements.ItemsControl: t = _asmFramework.GetType("System.Windows.Controls.ItemsControl"); break; + case KnownElements.MenuBase: t = _asmFramework.GetType("System.Windows.Controls.Primitives.MenuBase"); break; + case KnownElements.ContextMenu: t = _asmFramework.GetType("System.Windows.Controls.ContextMenu"); break; + case KnownElements.HeaderedItemsControl: t = _asmFramework.GetType("System.Windows.Controls.HeaderedItemsControl"); break; + case KnownElements.MenuItem: t = _asmFramework.GetType("System.Windows.Controls.MenuItem"); break; + case KnownElements.FlowDocumentScrollViewer: t = _asmFramework.GetType("System.Windows.Controls.FlowDocumentScrollViewer"); break; + case KnownElements.DocumentViewerBase: t = _asmFramework.GetType("System.Windows.Controls.Primitives.DocumentViewerBase"); break; + case KnownElements.FlowDocumentPageViewer: t = _asmFramework.GetType("System.Windows.Controls.FlowDocumentPageViewer"); break; + case KnownElements.ResourceKey: t = _asmFramework.GetType("System.Windows.ResourceKey"); break; + case KnownElements.ComponentResourceKey: t = _asmFramework.GetType("System.Windows.ComponentResourceKey"); break; + case KnownElements.FrameworkTemplate: t = _asmFramework.GetType("System.Windows.FrameworkTemplate"); break; + case KnownElements.ControlTemplate: t = _asmFramework.GetType("System.Windows.Controls.ControlTemplate"); break; + case KnownElements.AccessText: t = _asmFramework.GetType("System.Windows.Controls.AccessText"); break; + case KnownElements.AdornedElementPlaceholder: t = _asmFramework.GetType("System.Windows.Controls.AdornedElementPlaceholder"); break; + case KnownElements.BooleanToVisibilityConverter: t = _asmFramework.GetType("System.Windows.Controls.BooleanToVisibilityConverter"); break; + case KnownElements.Decorator: t = _asmFramework.GetType("System.Windows.Controls.Decorator"); break; + case KnownElements.Border: t = _asmFramework.GetType("System.Windows.Controls.Border"); break; + case KnownElements.BorderGapMaskConverter: t = _asmFramework.GetType("System.Windows.Controls.BorderGapMaskConverter"); break; + case KnownElements.ButtonBase: t = _asmFramework.GetType("System.Windows.Controls.Primitives.ButtonBase"); break; + case KnownElements.Button: t = _asmFramework.GetType("System.Windows.Controls.Button"); break; + case KnownElements.ToggleButton: t = _asmFramework.GetType("System.Windows.Controls.Primitives.ToggleButton"); break; + case KnownElements.CheckBox: t = _asmFramework.GetType("System.Windows.Controls.CheckBox"); break; + case KnownElements.Selector: t = _asmFramework.GetType("System.Windows.Controls.Primitives.Selector"); break; + case KnownElements.ComboBox: t = _asmFramework.GetType("System.Windows.Controls.ComboBox"); break; + case KnownElements.ListBoxItem: t = _asmFramework.GetType("System.Windows.Controls.ListBoxItem"); break; + case KnownElements.ComboBoxItem: t = _asmFramework.GetType("System.Windows.Controls.ComboBoxItem"); break; + case KnownElements.ContentPresenter: t = _asmFramework.GetType("System.Windows.Controls.ContentPresenter"); break; + case KnownElements.DataTemplate: t = _asmFramework.GetType("System.Windows.DataTemplate"); break; + case KnownElements.ContextMenuService: t = _asmFramework.GetType("System.Windows.Controls.ContextMenuService"); break; + case KnownElements.DockPanel: t = _asmFramework.GetType("System.Windows.Controls.DockPanel"); break; + case KnownElements.DocumentViewer: t = _asmFramework.GetType("System.Windows.Controls.DocumentViewer"); break; + case KnownElements.HeaderedContentControl: t = _asmFramework.GetType("System.Windows.Controls.HeaderedContentControl"); break; + case KnownElements.Expander: t = _asmFramework.GetType("System.Windows.Controls.Expander"); break; + case KnownElements.FlowDocumentReader: t = _asmFramework.GetType("System.Windows.Controls.FlowDocumentReader"); break; + case KnownElements.Frame: t = _asmFramework.GetType("System.Windows.Controls.Frame"); break; + case KnownElements.Grid: t = _asmFramework.GetType("System.Windows.Controls.Grid"); break; + case KnownElements.ViewBase: t = _asmFramework.GetType("System.Windows.Controls.ViewBase"); break; + case KnownElements.GridView: t = _asmFramework.GetType("System.Windows.Controls.GridView"); break; + case KnownElements.GridViewColumn: t = _asmFramework.GetType("System.Windows.Controls.GridViewColumn"); break; + case KnownElements.GridViewColumnHeader: t = _asmFramework.GetType("System.Windows.Controls.GridViewColumnHeader"); break; + case KnownElements.GridViewRowPresenterBase: t = _asmFramework.GetType("System.Windows.Controls.Primitives.GridViewRowPresenterBase"); break; + case KnownElements.GridViewHeaderRowPresenter: t = _asmFramework.GetType("System.Windows.Controls.GridViewHeaderRowPresenter"); break; + case KnownElements.GridViewRowPresenter: t = _asmFramework.GetType("System.Windows.Controls.GridViewRowPresenter"); break; + case KnownElements.Thumb: t = _asmFramework.GetType("System.Windows.Controls.Primitives.Thumb"); break; + case KnownElements.GridSplitter: t = _asmFramework.GetType("System.Windows.Controls.GridSplitter"); break; + case KnownElements.GroupBox: t = _asmFramework.GetType("System.Windows.Controls.GroupBox"); break; + case KnownElements.GroupItem: t = _asmFramework.GetType("System.Windows.Controls.GroupItem"); break; + case KnownElements.Image: t = _asmFramework.GetType("System.Windows.Controls.Image"); break; + case KnownElements.InkCanvas: t = _asmFramework.GetType("System.Windows.Controls.InkCanvas"); break; + case KnownElements.InkPresenter: t = _asmFramework.GetType("System.Windows.Controls.InkPresenter"); break; + case KnownElements.ItemCollection: t = _asmFramework.GetType("System.Windows.Controls.ItemCollection"); break; + case KnownElements.ItemsPanelTemplate: t = _asmFramework.GetType("System.Windows.Controls.ItemsPanelTemplate"); break; + case KnownElements.ItemsPresenter: t = _asmFramework.GetType("System.Windows.Controls.ItemsPresenter"); break; + case KnownElements.Label: t = _asmFramework.GetType("System.Windows.Controls.Label"); break; + case KnownElements.ListBox: t = _asmFramework.GetType("System.Windows.Controls.ListBox"); break; + case KnownElements.ListView: t = _asmFramework.GetType("System.Windows.Controls.ListView"); break; + case KnownElements.ListViewItem: t = _asmFramework.GetType("System.Windows.Controls.ListViewItem"); break; + case KnownElements.MediaElement: t = _asmFramework.GetType("System.Windows.Controls.MediaElement"); break; + case KnownElements.Menu: t = _asmFramework.GetType("System.Windows.Controls.Menu"); break; + case KnownElements.MenuScrollingVisibilityConverter: t = _asmFramework.GetType("System.Windows.Controls.MenuScrollingVisibilityConverter"); break; + case KnownElements.Page: t = _asmFramework.GetType("System.Windows.Controls.Page"); break; + case KnownElements.PasswordBox: t = _asmFramework.GetType("System.Windows.Controls.PasswordBox"); break; + case KnownElements.BulletDecorator: t = _asmFramework.GetType("System.Windows.Controls.Primitives.BulletDecorator"); break; + case KnownElements.DocumentPageView: t = _asmFramework.GetType("System.Windows.Controls.Primitives.DocumentPageView"); break; + case KnownElements.Popup: t = _asmFramework.GetType("System.Windows.Controls.Primitives.Popup"); break; + case KnownElements.RangeBase: t = _asmFramework.GetType("System.Windows.Controls.Primitives.RangeBase"); break; + case KnownElements.RepeatButton: t = _asmFramework.GetType("System.Windows.Controls.Primitives.RepeatButton"); break; + case KnownElements.ResizeGrip: t = _asmFramework.GetType("System.Windows.Controls.Primitives.ResizeGrip"); break; + case KnownElements.ScrollBar: t = _asmFramework.GetType("System.Windows.Controls.Primitives.ScrollBar"); break; + case KnownElements.ScrollContentPresenter: t = _asmFramework.GetType("System.Windows.Controls.ScrollContentPresenter"); break; + case KnownElements.StatusBar: t = _asmFramework.GetType("System.Windows.Controls.Primitives.StatusBar"); break; + case KnownElements.StatusBarItem: t = _asmFramework.GetType("System.Windows.Controls.Primitives.StatusBarItem"); break; + case KnownElements.TabPanel: t = _asmFramework.GetType("System.Windows.Controls.Primitives.TabPanel"); break; + case KnownElements.TextBoxBase: t = _asmFramework.GetType("System.Windows.Controls.Primitives.TextBoxBase"); break; + case KnownElements.TickBar: t = _asmFramework.GetType("System.Windows.Controls.Primitives.TickBar"); break; + case KnownElements.ToolBarOverflowPanel: t = _asmFramework.GetType("System.Windows.Controls.Primitives.ToolBarOverflowPanel"); break; + case KnownElements.StackPanel: t = _asmFramework.GetType("System.Windows.Controls.StackPanel"); break; + case KnownElements.ToolBarPanel: t = _asmFramework.GetType("System.Windows.Controls.Primitives.ToolBarPanel"); break; + case KnownElements.Track: t = _asmFramework.GetType("System.Windows.Controls.Primitives.Track"); break; + case KnownElements.UniformGrid: t = _asmFramework.GetType("System.Windows.Controls.Primitives.UniformGrid"); break; + case KnownElements.ProgressBar: t = _asmFramework.GetType("System.Windows.Controls.ProgressBar"); break; + case KnownElements.RadioButton: t = _asmFramework.GetType("System.Windows.Controls.RadioButton"); break; + case KnownElements.RichTextBox: t = _asmFramework.GetType("System.Windows.Controls.RichTextBox"); break; + case KnownElements.ScrollViewer: t = _asmFramework.GetType("System.Windows.Controls.ScrollViewer"); break; + case KnownElements.Separator: t = _asmFramework.GetType("System.Windows.Controls.Separator"); break; + case KnownElements.Slider: t = _asmFramework.GetType("System.Windows.Controls.Slider"); break; + case KnownElements.TriggerAction: t = _asmFramework.GetType("System.Windows.TriggerAction"); break; + case KnownElements.SoundPlayerAction: t = _asmFramework.GetType("System.Windows.Controls.SoundPlayerAction"); break; + case KnownElements.SpellCheck: t = _asmFramework.GetType("System.Windows.Controls.SpellCheck"); break; + case KnownElements.TabControl: t = _asmFramework.GetType("System.Windows.Controls.TabControl"); break; + case KnownElements.TabItem: t = _asmFramework.GetType("System.Windows.Controls.TabItem"); break; + case KnownElements.TextBlock: t = _asmFramework.GetType("System.Windows.Controls.TextBlock"); break; + case KnownElements.TextBox: t = _asmFramework.GetType("System.Windows.Controls.TextBox"); break; + case KnownElements.TextSearch: t = _asmFramework.GetType("System.Windows.Controls.TextSearch"); break; + case KnownElements.ToolBar: t = _asmFramework.GetType("System.Windows.Controls.ToolBar"); break; + case KnownElements.ToolBarTray: t = _asmFramework.GetType("System.Windows.Controls.ToolBarTray"); break; + case KnownElements.ToolTip: t = _asmFramework.GetType("System.Windows.Controls.ToolTip"); break; + case KnownElements.ToolTipService: t = _asmFramework.GetType("System.Windows.Controls.ToolTipService"); break; + case KnownElements.TreeView: t = _asmFramework.GetType("System.Windows.Controls.TreeView"); break; + case KnownElements.TreeViewItem: t = _asmFramework.GetType("System.Windows.Controls.TreeViewItem"); break; + case KnownElements.UserControl: t = _asmFramework.GetType("System.Windows.Controls.UserControl"); break; + case KnownElements.Validation: t = _asmFramework.GetType("System.Windows.Controls.Validation"); break; + case KnownElements.Viewbox: t = _asmFramework.GetType("System.Windows.Controls.Viewbox"); break; + case KnownElements.Viewport3D: t = _asmFramework.GetType("System.Windows.Controls.Viewport3D"); break; + case KnownElements.VirtualizingPanel: t = _asmFramework.GetType("System.Windows.Controls.VirtualizingPanel"); break; + case KnownElements.VirtualizingStackPanel: t = _asmFramework.GetType("System.Windows.Controls.VirtualizingStackPanel"); break; + case KnownElements.WrapPanel: t = _asmFramework.GetType("System.Windows.Controls.WrapPanel"); break; + case KnownElements.CornerRadius: t = _asmFramework.GetType("System.Windows.CornerRadius"); break; + case KnownElements.CornerRadiusConverter: t = _asmFramework.GetType("System.Windows.CornerRadiusConverter"); break; + case KnownElements.BindingBase: t = _asmFramework.GetType("System.Windows.Data.BindingBase"); break; + case KnownElements.Binding: t = _asmFramework.GetType("System.Windows.Data.Binding"); break; + case KnownElements.BindingExpressionBase: t = _asmFramework.GetType("System.Windows.Data.BindingExpressionBase"); break; + case KnownElements.BindingExpression: t = _asmFramework.GetType("System.Windows.Data.BindingExpression"); break; + case KnownElements.BindingListCollectionView: t = _asmFramework.GetType("System.Windows.Data.BindingListCollectionView"); break; + case KnownElements.CollectionContainer: t = _asmFramework.GetType("System.Windows.Data.CollectionContainer"); break; + case KnownElements.CollectionViewSource: t = _asmFramework.GetType("System.Windows.Data.CollectionViewSource"); break; + case KnownElements.DataChangedEventManager: t = _asmFramework.GetType("System.Windows.Data.DataChangedEventManager"); break; + case KnownElements.ListCollectionView: t = _asmFramework.GetType("System.Windows.Data.ListCollectionView"); break; + case KnownElements.MultiBinding: t = _asmFramework.GetType("System.Windows.Data.MultiBinding"); break; + case KnownElements.MultiBindingExpression: t = _asmFramework.GetType("System.Windows.Data.MultiBindingExpression"); break; + case KnownElements.ObjectDataProvider: t = _asmFramework.GetType("System.Windows.Data.ObjectDataProvider"); break; + case KnownElements.PriorityBinding: t = _asmFramework.GetType("System.Windows.Data.PriorityBinding"); break; + case KnownElements.PriorityBindingExpression: t = _asmFramework.GetType("System.Windows.Data.PriorityBindingExpression"); break; + case KnownElements.RelativeSource: t = _asmFramework.GetType("System.Windows.Data.RelativeSource"); break; + case KnownElements.XmlDataProvider: t = _asmFramework.GetType("System.Windows.Data.XmlDataProvider"); break; + case KnownElements.XmlNamespaceMapping: t = _asmFramework.GetType("System.Windows.Data.XmlNamespaceMapping"); break; + case KnownElements.TemplateKey: t = _asmFramework.GetType("System.Windows.TemplateKey"); break; + case KnownElements.DataTemplateKey: t = _asmFramework.GetType("System.Windows.DataTemplateKey"); break; + case KnownElements.TriggerBase: t = _asmFramework.GetType("System.Windows.TriggerBase"); break; + case KnownElements.DataTrigger: t = _asmFramework.GetType("System.Windows.DataTrigger"); break; + case KnownElements.DialogResultConverter: t = _asmFramework.GetType("System.Windows.DialogResultConverter"); break; + case KnownElements.AdornerDecorator: t = _asmFramework.GetType("System.Windows.Documents.AdornerDecorator"); break; + case KnownElements.AdornerLayer: t = _asmFramework.GetType("System.Windows.Documents.AdornerLayer"); break; + case KnownElements.TextElement: t = _asmFramework.GetType("System.Windows.Documents.TextElement"); break; + case KnownElements.Inline: t = _asmFramework.GetType("System.Windows.Documents.Inline"); break; + case KnownElements.AnchoredBlock: t = _asmFramework.GetType("System.Windows.Documents.AnchoredBlock"); break; + case KnownElements.Block: t = _asmFramework.GetType("System.Windows.Documents.Block"); break; + case KnownElements.BlockUIContainer: t = _asmFramework.GetType("System.Windows.Documents.BlockUIContainer"); break; + case KnownElements.Span: t = _asmFramework.GetType("System.Windows.Documents.Span"); break; + case KnownElements.Bold: t = _asmFramework.GetType("System.Windows.Documents.Bold"); break; + case KnownElements.DocumentReference: t = _asmFramework.GetType("System.Windows.Documents.DocumentReference"); break; + case KnownElements.FixedDocumentSequence: t = _asmFramework.GetType("System.Windows.Documents.FixedDocumentSequence"); break; + case KnownElements.Figure: t = _asmFramework.GetType("System.Windows.Documents.Figure"); break; + case KnownElements.FixedDocument: t = _asmFramework.GetType("System.Windows.Documents.FixedDocument"); break; + case KnownElements.FixedPage: t = _asmFramework.GetType("System.Windows.Documents.FixedPage"); break; + case KnownElements.Floater: t = _asmFramework.GetType("System.Windows.Documents.Floater"); break; + case KnownElements.FlowDocument: t = _asmFramework.GetType("System.Windows.Documents.FlowDocument"); break; + case KnownElements.FrameworkTextComposition: t = _asmFramework.GetType("System.Windows.Documents.FrameworkTextComposition"); break; + case KnownElements.FrameworkRichTextComposition: t = _asmFramework.GetType("System.Windows.Documents.FrameworkRichTextComposition"); break; + case KnownElements.Glyphs: t = _asmFramework.GetType("System.Windows.Documents.Glyphs"); break; + case KnownElements.Hyperlink: t = _asmFramework.GetType("System.Windows.Documents.Hyperlink"); break; + case KnownElements.InlineUIContainer: t = _asmFramework.GetType("System.Windows.Documents.InlineUIContainer"); break; + case KnownElements.Italic: t = _asmFramework.GetType("System.Windows.Documents.Italic"); break; + case KnownElements.LineBreak: t = _asmFramework.GetType("System.Windows.Documents.LineBreak"); break; + case KnownElements.List: t = _asmFramework.GetType("System.Windows.Documents.List"); break; + case KnownElements.ListItem: t = _asmFramework.GetType("System.Windows.Documents.ListItem"); break; + case KnownElements.PageContent: t = _asmFramework.GetType("System.Windows.Documents.PageContent"); break; + case KnownElements.Paragraph: t = _asmFramework.GetType("System.Windows.Documents.Paragraph"); break; + case KnownElements.Run: t = _asmFramework.GetType("System.Windows.Documents.Run"); break; + case KnownElements.Section: t = _asmFramework.GetType("System.Windows.Documents.Section"); break; + case KnownElements.Table: t = _asmFramework.GetType("System.Windows.Documents.Table"); break; + case KnownElements.TableCell: t = _asmFramework.GetType("System.Windows.Documents.TableCell"); break; + case KnownElements.TableColumn: t = _asmFramework.GetType("System.Windows.Documents.TableColumn"); break; + case KnownElements.TableRow: t = _asmFramework.GetType("System.Windows.Documents.TableRow"); break; + case KnownElements.TableRowGroup: t = _asmFramework.GetType("System.Windows.Documents.TableRowGroup"); break; + case KnownElements.Typography: t = _asmFramework.GetType("System.Windows.Documents.Typography"); break; + case KnownElements.Underline: t = _asmFramework.GetType("System.Windows.Documents.Underline"); break; + case KnownElements.ZoomPercentageConverter: t = _asmFramework.GetType("System.Windows.Documents.ZoomPercentageConverter"); break; + case KnownElements.DynamicResourceExtension: t = _asmFramework.GetType("System.Windows.DynamicResourceExtension"); break; + case KnownElements.DynamicResourceExtensionConverter: t = _asmFramework.GetType("System.Windows.DynamicResourceExtensionConverter"); break; + case KnownElements.SetterBase: t = _asmFramework.GetType("System.Windows.SetterBase"); break; + case KnownElements.EventSetter: t = _asmFramework.GetType("System.Windows.EventSetter"); break; + case KnownElements.EventTrigger: t = _asmFramework.GetType("System.Windows.EventTrigger"); break; + case KnownElements.FigureLength: t = _asmFramework.GetType("System.Windows.FigureLength"); break; + case KnownElements.FigureLengthConverter: t = _asmFramework.GetType("System.Windows.FigureLengthConverter"); break; + case KnownElements.FontSizeConverter: t = _asmFramework.GetType("System.Windows.FontSizeConverter"); break; + case KnownElements.GridLength: t = _asmFramework.GetType("System.Windows.GridLength"); break; + case KnownElements.GridLengthConverter: t = _asmFramework.GetType("System.Windows.GridLengthConverter"); break; + case KnownElements.HierarchicalDataTemplate: t = _asmFramework.GetType("System.Windows.HierarchicalDataTemplate"); break; + case KnownElements.LengthConverter: t = _asmFramework.GetType("System.Windows.LengthConverter"); break; + case KnownElements.Localization: t = _asmFramework.GetType("System.Windows.Localization"); break; + case KnownElements.LostFocusEventManager: t = _asmFramework.GetType("System.Windows.LostFocusEventManager"); break; + case KnownElements.BeginStoryboard: t = _asmFramework.GetType("System.Windows.Media.Animation.BeginStoryboard"); break; + case KnownElements.ControllableStoryboardAction: t = _asmFramework.GetType("System.Windows.Media.Animation.ControllableStoryboardAction"); break; + case KnownElements.PauseStoryboard: t = _asmFramework.GetType("System.Windows.Media.Animation.PauseStoryboard"); break; + case KnownElements.RemoveStoryboard: t = _asmFramework.GetType("System.Windows.Media.Animation.RemoveStoryboard"); break; + case KnownElements.ResumeStoryboard: t = _asmFramework.GetType("System.Windows.Media.Animation.ResumeStoryboard"); break; + case KnownElements.SeekStoryboard: t = _asmFramework.GetType("System.Windows.Media.Animation.SeekStoryboard"); break; + case KnownElements.SetStoryboardSpeedRatio: t = _asmFramework.GetType("System.Windows.Media.Animation.SetStoryboardSpeedRatio"); break; + case KnownElements.SkipStoryboardToFill: t = _asmFramework.GetType("System.Windows.Media.Animation.SkipStoryboardToFill"); break; + case KnownElements.StopStoryboard: t = _asmFramework.GetType("System.Windows.Media.Animation.StopStoryboard"); break; + case KnownElements.Storyboard: t = _asmFramework.GetType("System.Windows.Media.Animation.Storyboard"); break; + case KnownElements.ThicknessKeyFrame: t = _asmFramework.GetType("System.Windows.Media.Animation.ThicknessKeyFrame"); break; + case KnownElements.DiscreteThicknessKeyFrame: t = _asmFramework.GetType("System.Windows.Media.Animation.DiscreteThicknessKeyFrame"); break; + case KnownElements.LinearThicknessKeyFrame: t = _asmFramework.GetType("System.Windows.Media.Animation.LinearThicknessKeyFrame"); break; + case KnownElements.SplineThicknessKeyFrame: t = _asmFramework.GetType("System.Windows.Media.Animation.SplineThicknessKeyFrame"); break; + case KnownElements.ThicknessAnimationBase: t = _asmFramework.GetType("System.Windows.Media.Animation.ThicknessAnimationBase"); break; + case KnownElements.ThicknessAnimation: t = _asmFramework.GetType("System.Windows.Media.Animation.ThicknessAnimation"); break; + case KnownElements.ThicknessAnimationUsingKeyFrames: t = _asmFramework.GetType("System.Windows.Media.Animation.ThicknessAnimationUsingKeyFrames"); break; + case KnownElements.ThicknessKeyFrameCollection: t = _asmFramework.GetType("System.Windows.Media.Animation.ThicknessKeyFrameCollection"); break; + case KnownElements.MultiDataTrigger: t = _asmFramework.GetType("System.Windows.MultiDataTrigger"); break; + case KnownElements.MultiTrigger: t = _asmFramework.GetType("System.Windows.MultiTrigger"); break; + case KnownElements.NameScope: t = _asmFramework.GetType("System.Windows.NameScope"); break; + case KnownElements.JournalEntryListConverter: t = _asmFramework.GetType("System.Windows.Navigation.JournalEntryListConverter"); break; + case KnownElements.JournalEntryUnifiedViewConverter: t = _asmFramework.GetType("System.Windows.Navigation.JournalEntryUnifiedViewConverter"); break; + case KnownElements.PageFunctionBase: t = _asmFramework.GetType("System.Windows.Navigation.PageFunctionBase"); break; + case KnownElements.NullableBoolConverter: t = _asmFramework.GetType("System.Windows.NullableBoolConverter"); break; + case KnownElements.PropertyPath: t = _asmFramework.GetType("System.Windows.PropertyPath"); break; + case KnownElements.PropertyPathConverter: t = _asmFramework.GetType("System.Windows.PropertyPathConverter"); break; + case KnownElements.ResourceDictionary: t = _asmFramework.GetType("System.Windows.ResourceDictionary"); break; + case KnownElements.ColorConvertedBitmapExtension: t = _asmFramework.GetType("System.Windows.ColorConvertedBitmapExtension"); break; + case KnownElements.StaticResourceExtension: t = _asmFramework.GetType("System.Windows.StaticResourceExtension"); break; + case KnownElements.Setter: t = _asmFramework.GetType("System.Windows.Setter"); break; + case KnownElements.Ellipse: t = _asmFramework.GetType("System.Windows.Shapes.Ellipse"); break; + case KnownElements.Line: t = _asmFramework.GetType("System.Windows.Shapes.Line"); break; + case KnownElements.Path: t = _asmFramework.GetType("System.Windows.Shapes.Path"); break; + case KnownElements.Polygon: t = _asmFramework.GetType("System.Windows.Shapes.Polygon"); break; + case KnownElements.Polyline: t = _asmFramework.GetType("System.Windows.Shapes.Polyline"); break; + case KnownElements.Rectangle: t = _asmFramework.GetType("System.Windows.Shapes.Rectangle"); break; + case KnownElements.Style: t = _asmFramework.GetType("System.Windows.Style"); break; + case KnownElements.TemplateBindingExpression: t = _asmFramework.GetType("System.Windows.TemplateBindingExpression"); break; + case KnownElements.TemplateBindingExpressionConverter: t = _asmFramework.GetType("System.Windows.TemplateBindingExpressionConverter"); break; + case KnownElements.TemplateBindingExtension: t = _asmFramework.GetType("System.Windows.TemplateBindingExtension"); break; + case KnownElements.TemplateBindingExtensionConverter: t = _asmFramework.GetType("System.Windows.TemplateBindingExtensionConverter"); break; + case KnownElements.ThemeDictionaryExtension: t = _asmFramework.GetType("System.Windows.ThemeDictionaryExtension"); break; + case KnownElements.Thickness: t = _asmFramework.GetType("System.Windows.Thickness"); break; + case KnownElements.ThicknessConverter: t = _asmFramework.GetType("System.Windows.ThicknessConverter"); break; + case KnownElements.Trigger: t = _asmFramework.GetType("System.Windows.Trigger"); break; + case KnownElements.BaseIListConverter: t = _asmCore.GetType("System.Windows.Media.Converters.BaseIListConverter"); break; + case KnownElements.DoubleIListConverter: t = _asmCore.GetType("System.Windows.Media.Converters.DoubleIListConverter"); break; + case KnownElements.UShortIListConverter: t = _asmCore.GetType("System.Windows.Media.Converters.UShortIListConverter"); break; + case KnownElements.BoolIListConverter: t = _asmCore.GetType("System.Windows.Media.Converters.BoolIListConverter"); break; + case KnownElements.PointIListConverter: t = _asmCore.GetType("System.Windows.Media.Converters.PointIListConverter"); break; + case KnownElements.CharIListConverter: t = _asmCore.GetType("System.Windows.Media.Converters.CharIListConverter"); break; + case KnownElements.Visual: t = _asmCore.GetType("System.Windows.Media.Visual"); break; + case KnownElements.ContainerVisual: t = _asmCore.GetType("System.Windows.Media.ContainerVisual"); break; + case KnownElements.DrawingVisual: t = _asmCore.GetType("System.Windows.Media.DrawingVisual"); break; + case KnownElements.StreamGeometryContext: t = _asmCore.GetType("System.Windows.Media.StreamGeometryContext"); break; + case KnownElements.Animatable: t = _asmCore.GetType("System.Windows.Media.Animation.Animatable"); break; + case KnownElements.GeneralTransform: t = _asmCore.GetType("System.Windows.Media.GeneralTransform"); break; + case KnownElements.ContentElement: t = _asmCore.GetType("System.Windows.ContentElement"); break; + case KnownElements.CultureInfoIetfLanguageTagConverter: t = _asmCore.GetType("System.Windows.CultureInfoIetfLanguageTagConverter"); break; + case KnownElements.Duration: t = _asmCore.GetType("System.Windows.Duration"); break; + case KnownElements.DurationConverter: t = _asmCore.GetType("System.Windows.DurationConverter"); break; + case KnownElements.FontStyle: t = _asmCore.GetType("System.Windows.FontStyle"); break; + case KnownElements.FontStyleConverter: t = _asmCore.GetType("System.Windows.FontStyleConverter"); break; + case KnownElements.FontStretch: t = _asmCore.GetType("System.Windows.FontStretch"); break; + case KnownElements.FontStretchConverter: t = _asmCore.GetType("System.Windows.FontStretchConverter"); break; + case KnownElements.FontWeight: t = _asmCore.GetType("System.Windows.FontWeight"); break; + case KnownElements.FontWeightConverter: t = _asmCore.GetType("System.Windows.FontWeightConverter"); break; + case KnownElements.UIElement: t = _asmCore.GetType("System.Windows.UIElement"); break; + case KnownElements.Visual3D: t = _asmCore.GetType("System.Windows.Media.Media3D.Visual3D"); break; + case KnownElements.RoutedEvent: t = _asmCore.GetType("System.Windows.RoutedEvent"); break; + case KnownElements.TextDecoration: t = _asmCore.GetType("System.Windows.TextDecoration"); break; + case KnownElements.TextDecorationCollection: t = _asmCore.GetType("System.Windows.TextDecorationCollection"); break; + case KnownElements.TextDecorationCollectionConverter: t = _asmCore.GetType("System.Windows.TextDecorationCollectionConverter"); break; + case KnownElements.GestureRecognizer: t = _asmCore.GetType("System.Windows.Ink.GestureRecognizer"); break; + case KnownElements.StrokeCollection: t = _asmCore.GetType("System.Windows.Ink.StrokeCollection"); break; + case KnownElements.StrokeCollectionConverter: t = _asmCore.GetType("System.Windows.StrokeCollectionConverter"); break; + case KnownElements.InputDevice: t = _asmCore.GetType("System.Windows.Input.InputDevice"); break; + case KnownElements.ICommand: t = _asmCore.GetType("System.Windows.Input.ICommand"); break; + case KnownElements.InputBinding: t = _asmCore.GetType("System.Windows.Input.InputBinding"); break; + case KnownElements.KeyBinding: t = _asmCore.GetType("System.Windows.Input.KeyBinding"); break; + case KnownElements.KeyGesture: t = _asmCore.GetType("System.Windows.Input.KeyGesture"); break; + case KnownElements.KeyGestureConverter: t = _asmCore.GetType("System.Windows.Input.KeyGestureConverter"); break; + case KnownElements.MouseActionConverter: t = _asmCore.GetType("System.Windows.Input.MouseActionConverter"); break; + case KnownElements.MouseBinding: t = _asmCore.GetType("System.Windows.Input.MouseBinding"); break; + case KnownElements.MouseGesture: t = _asmCore.GetType("System.Windows.Input.MouseGesture"); break; + case KnownElements.MouseGestureConverter: t = _asmCore.GetType("System.Windows.Input.MouseGestureConverter"); break; + case KnownElements.RoutedCommand: t = _asmCore.GetType("System.Windows.Input.RoutedCommand"); break; + case KnownElements.RoutedUICommand: t = _asmCore.GetType("System.Windows.Input.RoutedUICommand"); break; + case KnownElements.Cursor: t = _asmCore.GetType("System.Windows.Input.Cursor"); break; + case KnownElements.CursorConverter: t = _asmCore.GetType("System.Windows.Input.CursorConverter"); break; + case KnownElements.TextComposition: t = _asmCore.GetType("System.Windows.Input.TextComposition"); break; + case KnownElements.FocusManager: t = _asmCore.GetType("System.Windows.Input.FocusManager"); break; + case KnownElements.InputLanguageManager: t = _asmCore.GetType("System.Windows.Input.InputLanguageManager"); break; + case KnownElements.InputManager: t = _asmCore.GetType("System.Windows.Input.InputManager"); break; + case KnownElements.InputMethod: t = _asmCore.GetType("System.Windows.Input.InputMethod"); break; + case KnownElements.InputScope: t = _asmCore.GetType("System.Windows.Input.InputScope"); break; + case KnownElements.InputScopeName: t = _asmCore.GetType("System.Windows.Input.InputScopeName"); break; + case KnownElements.InputScopeConverter: t = _asmCore.GetType("System.Windows.Input.InputScopeConverter"); break; + case KnownElements.InputScopeNameConverter: t = _asmCore.GetType("System.Windows.Input.InputScopeNameConverter"); break; + case KnownElements.KeyboardDevice: t = _asmCore.GetType("System.Windows.Input.KeyboardDevice"); break; + case KnownElements.MouseDevice: t = _asmCore.GetType("System.Windows.Input.MouseDevice"); break; + case KnownElements.HostVisual: t = _asmCore.GetType("System.Windows.Media.HostVisual"); break; + case KnownElements.Stylus: t = _asmCore.GetType("System.Windows.Input.Stylus"); break; + case KnownElements.StylusDevice: t = _asmCore.GetType("System.Windows.Input.StylusDevice"); break; + case KnownElements.TabletDevice: t = _asmCore.GetType("System.Windows.Input.TabletDevice"); break; + case KnownElements.TextCompositionManager: t = _asmCore.GetType("System.Windows.Input.TextCompositionManager"); break; + case KnownElements.CompositionTarget: t = _asmCore.GetType("System.Windows.Media.CompositionTarget"); break; + case KnownElements.PresentationSource: t = _asmCore.GetType("System.Windows.PresentationSource"); break; + case KnownElements.Clock: t = _asmCore.GetType("System.Windows.Media.Animation.Clock"); break; + case KnownElements.AnimationClock: t = _asmCore.GetType("System.Windows.Media.Animation.AnimationClock"); break; + case KnownElements.Timeline: t = _asmCore.GetType("System.Windows.Media.Animation.Timeline"); break; + case KnownElements.AnimationTimeline: t = _asmCore.GetType("System.Windows.Media.Animation.AnimationTimeline"); break; + case KnownElements.ClockController: t = _asmCore.GetType("System.Windows.Media.Animation.ClockController"); break; + case KnownElements.ClockGroup: t = _asmCore.GetType("System.Windows.Media.Animation.ClockGroup"); break; + case KnownElements.DoubleAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.DoubleAnimationBase"); break; + case KnownElements.DoubleAnimationUsingPath: t = _asmCore.GetType("System.Windows.Media.Animation.DoubleAnimationUsingPath"); break; + case KnownElements.BooleanAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.BooleanAnimationBase"); break; + case KnownElements.BooleanAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.BooleanAnimationUsingKeyFrames"); break; + case KnownElements.BooleanKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.BooleanKeyFrameCollection"); break; + case KnownElements.ByteAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.ByteAnimationBase"); break; + case KnownElements.ByteAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.ByteAnimation"); break; + case KnownElements.ByteAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.ByteAnimationUsingKeyFrames"); break; + case KnownElements.ByteKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.ByteKeyFrameCollection"); break; + case KnownElements.CharAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.CharAnimationBase"); break; + case KnownElements.CharAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.CharAnimationUsingKeyFrames"); break; + case KnownElements.CharKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.CharKeyFrameCollection"); break; + case KnownElements.ColorAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.ColorAnimationBase"); break; + case KnownElements.ColorAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.ColorAnimation"); break; + case KnownElements.ColorAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.ColorAnimationUsingKeyFrames"); break; + case KnownElements.ColorKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.ColorKeyFrameCollection"); break; + case KnownElements.DecimalAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.DecimalAnimationBase"); break; + case KnownElements.DecimalAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.DecimalAnimation"); break; + case KnownElements.DecimalAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.DecimalAnimationUsingKeyFrames"); break; + case KnownElements.DecimalKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.DecimalKeyFrameCollection"); break; + case KnownElements.BooleanKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.BooleanKeyFrame"); break; + case KnownElements.DiscreteBooleanKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteBooleanKeyFrame"); break; + case KnownElements.ByteKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.ByteKeyFrame"); break; + case KnownElements.DiscreteByteKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteByteKeyFrame"); break; + case KnownElements.CharKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.CharKeyFrame"); break; + case KnownElements.DiscreteCharKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteCharKeyFrame"); break; + case KnownElements.ColorKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.ColorKeyFrame"); break; + case KnownElements.DiscreteColorKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteColorKeyFrame"); break; + case KnownElements.DecimalKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DecimalKeyFrame"); break; + case KnownElements.DiscreteDecimalKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteDecimalKeyFrame"); break; + case KnownElements.DoubleKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DoubleKeyFrame"); break; + case KnownElements.DiscreteDoubleKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteDoubleKeyFrame"); break; + case KnownElements.Int16KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.Int16KeyFrame"); break; + case KnownElements.DiscreteInt16KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteInt16KeyFrame"); break; + case KnownElements.Int32KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.Int32KeyFrame"); break; + case KnownElements.DiscreteInt32KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteInt32KeyFrame"); break; + case KnownElements.Int64KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.Int64KeyFrame"); break; + case KnownElements.DiscreteInt64KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteInt64KeyFrame"); break; + case KnownElements.MatrixKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.MatrixKeyFrame"); break; + case KnownElements.DiscreteMatrixKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteMatrixKeyFrame"); break; + case KnownElements.ObjectKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.ObjectKeyFrame"); break; + case KnownElements.DiscreteObjectKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteObjectKeyFrame"); break; + case KnownElements.PointKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.PointKeyFrame"); break; + case KnownElements.DiscretePointKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscretePointKeyFrame"); break; + case KnownElements.Point3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.Point3DKeyFrame"); break; + case KnownElements.DiscretePoint3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscretePoint3DKeyFrame"); break; + case KnownElements.QuaternionKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.QuaternionKeyFrame"); break; + case KnownElements.DiscreteQuaternionKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteQuaternionKeyFrame"); break; + case KnownElements.Rotation3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.Rotation3DKeyFrame"); break; + case KnownElements.DiscreteRotation3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteRotation3DKeyFrame"); break; + case KnownElements.RectKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.RectKeyFrame"); break; + case KnownElements.DiscreteRectKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteRectKeyFrame"); break; + case KnownElements.SingleKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SingleKeyFrame"); break; + case KnownElements.DiscreteSingleKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteSingleKeyFrame"); break; + case KnownElements.SizeKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SizeKeyFrame"); break; + case KnownElements.DiscreteSizeKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteSizeKeyFrame"); break; + case KnownElements.StringKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.StringKeyFrame"); break; + case KnownElements.DiscreteStringKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteStringKeyFrame"); break; + case KnownElements.VectorKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.VectorKeyFrame"); break; + case KnownElements.DiscreteVectorKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteVectorKeyFrame"); break; + case KnownElements.Vector3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.Vector3DKeyFrame"); break; + case KnownElements.DiscreteVector3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.DiscreteVector3DKeyFrame"); break; + case KnownElements.DoubleAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.DoubleAnimation"); break; + case KnownElements.DoubleAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.DoubleAnimationUsingKeyFrames"); break; + case KnownElements.DoubleKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.DoubleKeyFrameCollection"); break; + case KnownElements.Int16AnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.Int16AnimationBase"); break; + case KnownElements.Int16Animation: t = _asmCore.GetType("System.Windows.Media.Animation.Int16Animation"); break; + case KnownElements.Int16AnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.Int16AnimationUsingKeyFrames"); break; + case KnownElements.Int16KeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.Int16KeyFrameCollection"); break; + case KnownElements.Int32AnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.Int32AnimationBase"); break; + case KnownElements.Int32Animation: t = _asmCore.GetType("System.Windows.Media.Animation.Int32Animation"); break; + case KnownElements.Int32AnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.Int32AnimationUsingKeyFrames"); break; + case KnownElements.Int32KeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.Int32KeyFrameCollection"); break; + case KnownElements.Int64AnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.Int64AnimationBase"); break; + case KnownElements.Int64Animation: t = _asmCore.GetType("System.Windows.Media.Animation.Int64Animation"); break; + case KnownElements.Int64AnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.Int64AnimationUsingKeyFrames"); break; + case KnownElements.Int64KeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.Int64KeyFrameCollection"); break; + case KnownElements.LinearByteKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearByteKeyFrame"); break; + case KnownElements.LinearColorKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearColorKeyFrame"); break; + case KnownElements.LinearDecimalKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearDecimalKeyFrame"); break; + case KnownElements.LinearDoubleKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearDoubleKeyFrame"); break; + case KnownElements.LinearInt16KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearInt16KeyFrame"); break; + case KnownElements.LinearInt32KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearInt32KeyFrame"); break; + case KnownElements.LinearInt64KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearInt64KeyFrame"); break; + case KnownElements.LinearPointKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearPointKeyFrame"); break; + case KnownElements.LinearPoint3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearPoint3DKeyFrame"); break; + case KnownElements.LinearQuaternionKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearQuaternionKeyFrame"); break; + case KnownElements.LinearRotation3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearRotation3DKeyFrame"); break; + case KnownElements.LinearRectKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearRectKeyFrame"); break; + case KnownElements.LinearSingleKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearSingleKeyFrame"); break; + case KnownElements.LinearSizeKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearSizeKeyFrame"); break; + case KnownElements.LinearVectorKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearVectorKeyFrame"); break; + case KnownElements.LinearVector3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.LinearVector3DKeyFrame"); break; + case KnownElements.MatrixAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.MatrixAnimationBase"); break; + case KnownElements.MatrixAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.MatrixAnimationUsingKeyFrames"); break; + case KnownElements.MatrixKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.MatrixKeyFrameCollection"); break; + case KnownElements.ObjectAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.ObjectAnimationBase"); break; + case KnownElements.ObjectAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames"); break; + case KnownElements.ObjectKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.ObjectKeyFrameCollection"); break; + case KnownElements.TimelineGroup: t = _asmCore.GetType("System.Windows.Media.Animation.TimelineGroup"); break; + case KnownElements.ParallelTimeline: t = _asmCore.GetType("System.Windows.Media.Animation.ParallelTimeline"); break; + case KnownElements.Point3DAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.Point3DAnimationBase"); break; + case KnownElements.Point3DAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.Point3DAnimation"); break; + case KnownElements.Point3DAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.Point3DAnimationUsingKeyFrames"); break; + case KnownElements.Point3DKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.Point3DKeyFrameCollection"); break; + case KnownElements.PointAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.PointAnimationBase"); break; + case KnownElements.PointAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.PointAnimation"); break; + case KnownElements.PointAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.PointAnimationUsingKeyFrames"); break; + case KnownElements.PointKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.PointKeyFrameCollection"); break; + case KnownElements.QuaternionAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.QuaternionAnimationBase"); break; + case KnownElements.QuaternionAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.QuaternionAnimation"); break; + case KnownElements.QuaternionAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.QuaternionAnimationUsingKeyFrames"); break; + case KnownElements.QuaternionKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.QuaternionKeyFrameCollection"); break; + case KnownElements.RectAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.RectAnimationBase"); break; + case KnownElements.RectAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.RectAnimation"); break; + case KnownElements.RectAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.RectAnimationUsingKeyFrames"); break; + case KnownElements.RectKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.RectKeyFrameCollection"); break; + case KnownElements.Rotation3DAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.Rotation3DAnimationBase"); break; + case KnownElements.Rotation3DAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.Rotation3DAnimation"); break; + case KnownElements.Rotation3DAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.Rotation3DAnimationUsingKeyFrames"); break; + case KnownElements.Rotation3DKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.Rotation3DKeyFrameCollection"); break; + case KnownElements.SingleAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.SingleAnimationBase"); break; + case KnownElements.SingleAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.SingleAnimation"); break; + case KnownElements.SingleAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.SingleAnimationUsingKeyFrames"); break; + case KnownElements.SingleKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.SingleKeyFrameCollection"); break; + case KnownElements.SizeAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.SizeAnimationBase"); break; + case KnownElements.SizeAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.SizeAnimation"); break; + case KnownElements.SizeAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.SizeAnimationUsingKeyFrames"); break; + case KnownElements.SizeKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.SizeKeyFrameCollection"); break; + case KnownElements.SplineByteKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineByteKeyFrame"); break; + case KnownElements.SplineColorKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineColorKeyFrame"); break; + case KnownElements.SplineDecimalKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineDecimalKeyFrame"); break; + case KnownElements.SplineDoubleKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineDoubleKeyFrame"); break; + case KnownElements.SplineInt16KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineInt16KeyFrame"); break; + case KnownElements.SplineInt32KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineInt32KeyFrame"); break; + case KnownElements.SplineInt64KeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineInt64KeyFrame"); break; + case KnownElements.SplinePointKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplinePointKeyFrame"); break; + case KnownElements.SplinePoint3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplinePoint3DKeyFrame"); break; + case KnownElements.SplineQuaternionKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineQuaternionKeyFrame"); break; + case KnownElements.SplineRotation3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineRotation3DKeyFrame"); break; + case KnownElements.SplineRectKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineRectKeyFrame"); break; + case KnownElements.SplineSingleKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineSingleKeyFrame"); break; + case KnownElements.SplineSizeKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineSizeKeyFrame"); break; + case KnownElements.SplineVectorKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineVectorKeyFrame"); break; + case KnownElements.SplineVector3DKeyFrame: t = _asmCore.GetType("System.Windows.Media.Animation.SplineVector3DKeyFrame"); break; + case KnownElements.StringAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.StringAnimationBase"); break; + case KnownElements.StringAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.StringAnimationUsingKeyFrames"); break; + case KnownElements.StringKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.StringKeyFrameCollection"); break; + case KnownElements.TimelineCollection: t = _asmCore.GetType("System.Windows.Media.Animation.TimelineCollection"); break; + case KnownElements.Vector3DAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.Vector3DAnimationBase"); break; + case KnownElements.Vector3DAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.Vector3DAnimation"); break; + case KnownElements.Vector3DAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.Vector3DAnimationUsingKeyFrames"); break; + case KnownElements.Vector3DKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.Vector3DKeyFrameCollection"); break; + case KnownElements.VectorAnimationBase: t = _asmCore.GetType("System.Windows.Media.Animation.VectorAnimationBase"); break; + case KnownElements.VectorAnimation: t = _asmCore.GetType("System.Windows.Media.Animation.VectorAnimation"); break; + case KnownElements.VectorAnimationUsingKeyFrames: t = _asmCore.GetType("System.Windows.Media.Animation.VectorAnimationUsingKeyFrames"); break; + case KnownElements.VectorKeyFrameCollection: t = _asmCore.GetType("System.Windows.Media.Animation.VectorKeyFrameCollection"); break; + case KnownElements.KeySpline: t = _asmCore.GetType("System.Windows.Media.Animation.KeySpline"); break; + case KnownElements.KeySplineConverter: t = _asmCore.GetType("System.Windows.KeySplineConverter"); break; + case KnownElements.KeyTime: t = _asmCore.GetType("System.Windows.Media.Animation.KeyTime"); break; + case KnownElements.KeyTimeConverter: t = _asmCore.GetType("System.Windows.KeyTimeConverter"); break; + case KnownElements.MatrixAnimationUsingPath: t = _asmCore.GetType("System.Windows.Media.Animation.MatrixAnimationUsingPath"); break; + case KnownElements.PointAnimationUsingPath: t = _asmCore.GetType("System.Windows.Media.Animation.PointAnimationUsingPath"); break; + case KnownElements.RepeatBehavior: t = _asmCore.GetType("System.Windows.Media.Animation.RepeatBehavior"); break; + case KnownElements.RepeatBehaviorConverter: t = _asmCore.GetType("System.Windows.Media.Animation.RepeatBehaviorConverter"); break; + case KnownElements.PathSegment: t = _asmCore.GetType("System.Windows.Media.PathSegment"); break; + case KnownElements.ArcSegment: t = _asmCore.GetType("System.Windows.Media.ArcSegment"); break; + case KnownElements.BezierSegment: t = _asmCore.GetType("System.Windows.Media.BezierSegment"); break; + case KnownElements.DrawingContext: t = _asmCore.GetType("System.Windows.Media.DrawingContext"); break; + case KnownElements.Brush: t = _asmCore.GetType("System.Windows.Media.Brush"); break; + case KnownElements.Color: t = _asmCore.GetType("System.Windows.Media.Color"); break; + case KnownElements.ColorConverter: t = _asmCore.GetType("System.Windows.Media.ColorConverter"); break; + case KnownElements.Geometry: t = _asmCore.GetType("System.Windows.Media.Geometry"); break; + case KnownElements.CombinedGeometry: t = _asmCore.GetType("System.Windows.Media.CombinedGeometry"); break; + case KnownElements.DashStyle: t = _asmCore.GetType("System.Windows.Media.DashStyle"); break; + case KnownElements.Drawing: t = _asmCore.GetType("System.Windows.Media.Drawing"); break; + case KnownElements.TileBrush: t = _asmCore.GetType("System.Windows.Media.TileBrush"); break; + case KnownElements.DrawingBrush: t = _asmCore.GetType("System.Windows.Media.DrawingBrush"); break; + case KnownElements.DrawingCollection: t = _asmCore.GetType("System.Windows.Media.DrawingCollection"); break; + case KnownElements.DrawingGroup: t = _asmCore.GetType("System.Windows.Media.DrawingGroup"); break; + case KnownElements.ImageSource: t = _asmCore.GetType("System.Windows.Media.ImageSource"); break; + case KnownElements.DrawingImage: t = _asmCore.GetType("System.Windows.Media.DrawingImage"); break; + case KnownElements.BitmapEffect: t = _asmCore.GetType("System.Windows.Media.Effects.BitmapEffect"); break; + case KnownElements.BitmapEffectGroup: t = _asmCore.GetType("System.Windows.Media.Effects.BitmapEffectGroup"); break; + case KnownElements.BitmapEffectInput: t = _asmCore.GetType("System.Windows.Media.Effects.BitmapEffectInput"); break; + case KnownElements.BevelBitmapEffect: t = _asmCore.GetType("System.Windows.Media.Effects.BevelBitmapEffect"); break; + case KnownElements.BlurBitmapEffect: t = _asmCore.GetType("System.Windows.Media.Effects.BlurBitmapEffect"); break; + case KnownElements.DropShadowBitmapEffect: t = _asmCore.GetType("System.Windows.Media.Effects.DropShadowBitmapEffect"); break; + case KnownElements.EmbossBitmapEffect: t = _asmCore.GetType("System.Windows.Media.Effects.EmbossBitmapEffect"); break; + case KnownElements.OuterGlowBitmapEffect: t = _asmCore.GetType("System.Windows.Media.Effects.OuterGlowBitmapEffect"); break; + case KnownElements.BitmapEffectCollection: t = _asmCore.GetType("System.Windows.Media.Effects.BitmapEffectCollection"); break; + case KnownElements.EllipseGeometry: t = _asmCore.GetType("System.Windows.Media.EllipseGeometry"); break; + case KnownElements.FontFamily: t = _asmCore.GetType("System.Windows.Media.FontFamily"); break; + case KnownElements.FontFamilyConverter: t = _asmCore.GetType("System.Windows.Media.FontFamilyConverter"); break; + case KnownElements.GeneralTransformGroup: t = _asmCore.GetType("System.Windows.Media.GeneralTransformGroup"); break; + case KnownElements.BrushConverter: t = _asmCore.GetType("System.Windows.Media.BrushConverter"); break; + case KnownElements.DoubleCollection: t = _asmCore.GetType("System.Windows.Media.DoubleCollection"); break; + case KnownElements.DoubleCollectionConverter: t = _asmCore.GetType("System.Windows.Media.DoubleCollectionConverter"); break; + case KnownElements.GeneralTransformCollection: t = _asmCore.GetType("System.Windows.Media.GeneralTransformCollection"); break; + case KnownElements.GeometryCollection: t = _asmCore.GetType("System.Windows.Media.GeometryCollection"); break; + case KnownElements.GeometryConverter: t = _asmCore.GetType("System.Windows.Media.GeometryConverter"); break; + case KnownElements.GeometryDrawing: t = _asmCore.GetType("System.Windows.Media.GeometryDrawing"); break; + case KnownElements.GeometryGroup: t = _asmCore.GetType("System.Windows.Media.GeometryGroup"); break; + case KnownElements.GlyphRunDrawing: t = _asmCore.GetType("System.Windows.Media.GlyphRunDrawing"); break; + case KnownElements.GradientBrush: t = _asmCore.GetType("System.Windows.Media.GradientBrush"); break; + case KnownElements.GradientStop: t = _asmCore.GetType("System.Windows.Media.GradientStop"); break; + case KnownElements.GradientStopCollection: t = _asmCore.GetType("System.Windows.Media.GradientStopCollection"); break; + case KnownElements.ImageBrush: t = _asmCore.GetType("System.Windows.Media.ImageBrush"); break; + case KnownElements.ImageDrawing: t = _asmCore.GetType("System.Windows.Media.ImageDrawing"); break; + case KnownElements.Int32Collection: t = _asmCore.GetType("System.Windows.Media.Int32Collection"); break; + case KnownElements.Int32CollectionConverter: t = _asmCore.GetType("System.Windows.Media.Int32CollectionConverter"); break; + case KnownElements.LinearGradientBrush: t = _asmCore.GetType("System.Windows.Media.LinearGradientBrush"); break; + case KnownElements.LineGeometry: t = _asmCore.GetType("System.Windows.Media.LineGeometry"); break; + case KnownElements.LineSegment: t = _asmCore.GetType("System.Windows.Media.LineSegment"); break; + case KnownElements.Transform: t = _asmCore.GetType("System.Windows.Media.Transform"); break; + case KnownElements.MatrixTransform: t = _asmCore.GetType("System.Windows.Media.MatrixTransform"); break; + case KnownElements.MediaTimeline: t = _asmCore.GetType("System.Windows.Media.MediaTimeline"); break; + case KnownElements.PathFigure: t = _asmCore.GetType("System.Windows.Media.PathFigure"); break; + case KnownElements.PathFigureCollection: t = _asmCore.GetType("System.Windows.Media.PathFigureCollection"); break; + case KnownElements.PathFigureCollectionConverter: t = _asmCore.GetType("System.Windows.Media.PathFigureCollectionConverter"); break; + case KnownElements.PathGeometry: t = _asmCore.GetType("System.Windows.Media.PathGeometry"); break; + case KnownElements.PathSegmentCollection: t = _asmCore.GetType("System.Windows.Media.PathSegmentCollection"); break; + case KnownElements.Pen: t = _asmCore.GetType("System.Windows.Media.Pen"); break; + case KnownElements.PointCollection: t = _asmCore.GetType("System.Windows.Media.PointCollection"); break; + case KnownElements.PointCollectionConverter: t = _asmCore.GetType("System.Windows.Media.PointCollectionConverter"); break; + case KnownElements.PolyBezierSegment: t = _asmCore.GetType("System.Windows.Media.PolyBezierSegment"); break; + case KnownElements.PolyLineSegment: t = _asmCore.GetType("System.Windows.Media.PolyLineSegment"); break; + case KnownElements.PolyQuadraticBezierSegment: t = _asmCore.GetType("System.Windows.Media.PolyQuadraticBezierSegment"); break; + case KnownElements.QuadraticBezierSegment: t = _asmCore.GetType("System.Windows.Media.QuadraticBezierSegment"); break; + case KnownElements.RadialGradientBrush: t = _asmCore.GetType("System.Windows.Media.RadialGradientBrush"); break; + case KnownElements.RectangleGeometry: t = _asmCore.GetType("System.Windows.Media.RectangleGeometry"); break; + case KnownElements.RotateTransform: t = _asmCore.GetType("System.Windows.Media.RotateTransform"); break; + case KnownElements.ScaleTransform: t = _asmCore.GetType("System.Windows.Media.ScaleTransform"); break; + case KnownElements.SkewTransform: t = _asmCore.GetType("System.Windows.Media.SkewTransform"); break; + case KnownElements.SolidColorBrush: t = _asmCore.GetType("System.Windows.Media.SolidColorBrush"); break; + case KnownElements.StreamGeometry: t = _asmCore.GetType("System.Windows.Media.StreamGeometry"); break; + case KnownElements.TextEffect: t = _asmCore.GetType("System.Windows.Media.TextEffect"); break; + case KnownElements.TextEffectCollection: t = _asmCore.GetType("System.Windows.Media.TextEffectCollection"); break; + case KnownElements.TransformCollection: t = _asmCore.GetType("System.Windows.Media.TransformCollection"); break; + case KnownElements.TransformConverter: t = _asmCore.GetType("System.Windows.Media.TransformConverter"); break; + case KnownElements.TransformGroup: t = _asmCore.GetType("System.Windows.Media.TransformGroup"); break; + case KnownElements.TranslateTransform: t = _asmCore.GetType("System.Windows.Media.TranslateTransform"); break; + case KnownElements.VectorCollection: t = _asmCore.GetType("System.Windows.Media.VectorCollection"); break; + case KnownElements.VectorCollectionConverter: t = _asmCore.GetType("System.Windows.Media.VectorCollectionConverter"); break; + case KnownElements.VisualBrush: t = _asmCore.GetType("System.Windows.Media.VisualBrush"); break; + case KnownElements.VideoDrawing: t = _asmCore.GetType("System.Windows.Media.VideoDrawing"); break; + case KnownElements.GuidelineSet: t = _asmCore.GetType("System.Windows.Media.GuidelineSet"); break; + case KnownElements.GlyphRun: t = _asmCore.GetType("System.Windows.Media.GlyphRun"); break; + case KnownElements.GlyphTypeface: t = _asmCore.GetType("System.Windows.Media.GlyphTypeface"); break; + case KnownElements.ImageMetadata: t = _asmCore.GetType("System.Windows.Media.ImageMetadata"); break; + case KnownElements.ImageSourceConverter: t = _asmCore.GetType("System.Windows.Media.ImageSourceConverter"); break; + case KnownElements.BitmapDecoder: t = _asmCore.GetType("System.Windows.Media.Imaging.BitmapDecoder"); break; + case KnownElements.BitmapEncoder: t = _asmCore.GetType("System.Windows.Media.Imaging.BitmapEncoder"); break; + case KnownElements.BmpBitmapDecoder: t = _asmCore.GetType("System.Windows.Media.Imaging.BmpBitmapDecoder"); break; + case KnownElements.BmpBitmapEncoder: t = _asmCore.GetType("System.Windows.Media.Imaging.BmpBitmapEncoder"); break; + case KnownElements.BitmapSource: t = _asmCore.GetType("System.Windows.Media.Imaging.BitmapSource"); break; + case KnownElements.BitmapFrame: t = _asmCore.GetType("System.Windows.Media.Imaging.BitmapFrame"); break; + case KnownElements.BitmapMetadata: t = _asmCore.GetType("System.Windows.Media.Imaging.BitmapMetadata"); break; + case KnownElements.BitmapPalette: t = _asmCore.GetType("System.Windows.Media.Imaging.BitmapPalette"); break; + case KnownElements.BitmapImage: t = _asmCore.GetType("System.Windows.Media.Imaging.BitmapImage"); break; + case KnownElements.CachedBitmap: t = _asmCore.GetType("System.Windows.Media.Imaging.CachedBitmap"); break; + case KnownElements.ColorConvertedBitmap: t = _asmCore.GetType("System.Windows.Media.Imaging.ColorConvertedBitmap"); break; + case KnownElements.CroppedBitmap: t = _asmCore.GetType("System.Windows.Media.Imaging.CroppedBitmap"); break; + case KnownElements.FormatConvertedBitmap: t = _asmCore.GetType("System.Windows.Media.Imaging.FormatConvertedBitmap"); break; + case KnownElements.GifBitmapDecoder: t = _asmCore.GetType("System.Windows.Media.Imaging.GifBitmapDecoder"); break; + case KnownElements.GifBitmapEncoder: t = _asmCore.GetType("System.Windows.Media.Imaging.GifBitmapEncoder"); break; + case KnownElements.IconBitmapDecoder: t = _asmCore.GetType("System.Windows.Media.Imaging.IconBitmapDecoder"); break; + case KnownElements.InPlaceBitmapMetadataWriter: t = _asmCore.GetType("System.Windows.Media.Imaging.InPlaceBitmapMetadataWriter"); break; + case KnownElements.LateBoundBitmapDecoder: t = _asmCore.GetType("System.Windows.Media.Imaging.LateBoundBitmapDecoder"); break; + case KnownElements.JpegBitmapDecoder: t = _asmCore.GetType("System.Windows.Media.Imaging.JpegBitmapDecoder"); break; + case KnownElements.JpegBitmapEncoder: t = _asmCore.GetType("System.Windows.Media.Imaging.JpegBitmapEncoder"); break; + case KnownElements.PngBitmapDecoder: t = _asmCore.GetType("System.Windows.Media.Imaging.PngBitmapDecoder"); break; + case KnownElements.PngBitmapEncoder: t = _asmCore.GetType("System.Windows.Media.Imaging.PngBitmapEncoder"); break; + case KnownElements.RenderTargetBitmap: t = _asmCore.GetType("System.Windows.Media.Imaging.RenderTargetBitmap"); break; + case KnownElements.TiffBitmapDecoder: t = _asmCore.GetType("System.Windows.Media.Imaging.TiffBitmapDecoder"); break; + case KnownElements.TiffBitmapEncoder: t = _asmCore.GetType("System.Windows.Media.Imaging.TiffBitmapEncoder"); break; + case KnownElements.WmpBitmapDecoder: t = _asmCore.GetType("System.Windows.Media.Imaging.WmpBitmapDecoder"); break; + case KnownElements.WmpBitmapEncoder: t = _asmCore.GetType("System.Windows.Media.Imaging.WmpBitmapEncoder"); break; + case KnownElements.TransformedBitmap: t = _asmCore.GetType("System.Windows.Media.Imaging.TransformedBitmap"); break; + case KnownElements.WriteableBitmap: t = _asmCore.GetType("System.Windows.Media.Imaging.WriteableBitmap"); break; + case KnownElements.MediaClock: t = _asmCore.GetType("System.Windows.Media.MediaClock"); break; + case KnownElements.MediaPlayer: t = _asmCore.GetType("System.Windows.Media.MediaPlayer"); break; + case KnownElements.PixelFormat: t = _asmCore.GetType("System.Windows.Media.PixelFormat"); break; + case KnownElements.PixelFormatConverter: t = _asmCore.GetType("System.Windows.Media.PixelFormatConverter"); break; + case KnownElements.RenderOptions: t = _asmCore.GetType("System.Windows.Media.RenderOptions"); break; + case KnownElements.NumberSubstitution: t = _asmCore.GetType("System.Windows.Media.NumberSubstitution"); break; + case KnownElements.VisualTarget: t = _asmCore.GetType("System.Windows.Media.VisualTarget"); break; + case KnownElements.Transform3D: t = _asmCore.GetType("System.Windows.Media.Media3D.Transform3D"); break; + case KnownElements.AffineTransform3D: t = _asmCore.GetType("System.Windows.Media.Media3D.AffineTransform3D"); break; + case KnownElements.Model3D: t = _asmCore.GetType("System.Windows.Media.Media3D.Model3D"); break; + case KnownElements.Light: t = _asmCore.GetType("System.Windows.Media.Media3D.Light"); break; + case KnownElements.AmbientLight: t = _asmCore.GetType("System.Windows.Media.Media3D.AmbientLight"); break; + case KnownElements.Rotation3D: t = _asmCore.GetType("System.Windows.Media.Media3D.Rotation3D"); break; + case KnownElements.AxisAngleRotation3D: t = _asmCore.GetType("System.Windows.Media.Media3D.AxisAngleRotation3D"); break; + case KnownElements.Camera: t = _asmCore.GetType("System.Windows.Media.Media3D.Camera"); break; + case KnownElements.Material: t = _asmCore.GetType("System.Windows.Media.Media3D.Material"); break; + case KnownElements.DiffuseMaterial: t = _asmCore.GetType("System.Windows.Media.Media3D.DiffuseMaterial"); break; + case KnownElements.DirectionalLight: t = _asmCore.GetType("System.Windows.Media.Media3D.DirectionalLight"); break; + case KnownElements.EmissiveMaterial: t = _asmCore.GetType("System.Windows.Media.Media3D.EmissiveMaterial"); break; + case KnownElements.Geometry3D: t = _asmCore.GetType("System.Windows.Media.Media3D.Geometry3D"); break; + case KnownElements.GeometryModel3D: t = _asmCore.GetType("System.Windows.Media.Media3D.GeometryModel3D"); break; + case KnownElements.MaterialGroup: t = _asmCore.GetType("System.Windows.Media.Media3D.MaterialGroup"); break; + case KnownElements.Matrix3D: t = _asmCore.GetType("System.Windows.Media.Media3D.Matrix3D"); break; + case KnownElements.MatrixCamera: t = _asmCore.GetType("System.Windows.Media.Media3D.MatrixCamera"); break; + case KnownElements.MatrixTransform3D: t = _asmCore.GetType("System.Windows.Media.Media3D.MatrixTransform3D"); break; + case KnownElements.MeshGeometry3D: t = _asmCore.GetType("System.Windows.Media.Media3D.MeshGeometry3D"); break; + case KnownElements.Model3DGroup: t = _asmCore.GetType("System.Windows.Media.Media3D.Model3DGroup"); break; + case KnownElements.ModelVisual3D: t = _asmCore.GetType("System.Windows.Media.Media3D.ModelVisual3D"); break; + case KnownElements.Point3D: t = _asmCore.GetType("System.Windows.Media.Media3D.Point3D"); break; + case KnownElements.Point3DCollection: t = _asmCore.GetType("System.Windows.Media.Media3D.Point3DCollection"); break; + case KnownElements.Vector3DCollection: t = _asmCore.GetType("System.Windows.Media.Media3D.Vector3DCollection"); break; + case KnownElements.Point4D: t = _asmCore.GetType("System.Windows.Media.Media3D.Point4D"); break; + case KnownElements.PointLightBase: t = _asmCore.GetType("System.Windows.Media.Media3D.PointLightBase"); break; + case KnownElements.PointLight: t = _asmCore.GetType("System.Windows.Media.Media3D.PointLight"); break; + case KnownElements.ProjectionCamera: t = _asmCore.GetType("System.Windows.Media.Media3D.ProjectionCamera"); break; + case KnownElements.OrthographicCamera: t = _asmCore.GetType("System.Windows.Media.Media3D.OrthographicCamera"); break; + case KnownElements.PerspectiveCamera: t = _asmCore.GetType("System.Windows.Media.Media3D.PerspectiveCamera"); break; + case KnownElements.Quaternion: t = _asmCore.GetType("System.Windows.Media.Media3D.Quaternion"); break; + case KnownElements.QuaternionRotation3D: t = _asmCore.GetType("System.Windows.Media.Media3D.QuaternionRotation3D"); break; + case KnownElements.Rect3D: t = _asmCore.GetType("System.Windows.Media.Media3D.Rect3D"); break; + case KnownElements.RotateTransform3D: t = _asmCore.GetType("System.Windows.Media.Media3D.RotateTransform3D"); break; + case KnownElements.ScaleTransform3D: t = _asmCore.GetType("System.Windows.Media.Media3D.ScaleTransform3D"); break; + case KnownElements.Size3D: t = _asmCore.GetType("System.Windows.Media.Media3D.Size3D"); break; + case KnownElements.SpecularMaterial: t = _asmCore.GetType("System.Windows.Media.Media3D.SpecularMaterial"); break; + case KnownElements.SpotLight: t = _asmCore.GetType("System.Windows.Media.Media3D.SpotLight"); break; + case KnownElements.Transform3DGroup: t = _asmCore.GetType("System.Windows.Media.Media3D.Transform3DGroup"); break; + case KnownElements.TranslateTransform3D: t = _asmCore.GetType("System.Windows.Media.Media3D.TranslateTransform3D"); break; + case KnownElements.Vector3D: t = _asmCore.GetType("System.Windows.Media.Media3D.Vector3D"); break; + case KnownElements.Viewport3DVisual: t = _asmCore.GetType("System.Windows.Media.Media3D.Viewport3DVisual"); break; + case KnownElements.MaterialCollection: t = _asmCore.GetType("System.Windows.Media.Media3D.MaterialCollection"); break; + case KnownElements.Matrix3DConverter: t = _asmCore.GetType("System.Windows.Media.Media3D.Matrix3DConverter"); break; + case KnownElements.Model3DCollection: t = _asmCore.GetType("System.Windows.Media.Media3D.Model3DCollection"); break; + case KnownElements.Point3DConverter: t = _asmCore.GetType("System.Windows.Media.Media3D.Point3DConverter"); break; + case KnownElements.Point3DCollectionConverter: t = _asmCore.GetType("System.Windows.Media.Media3D.Point3DCollectionConverter"); break; + case KnownElements.Point4DConverter: t = _asmCore.GetType("System.Windows.Media.Media3D.Point4DConverter"); break; + case KnownElements.QuaternionConverter: t = _asmCore.GetType("System.Windows.Media.Media3D.QuaternionConverter"); break; + case KnownElements.Rect3DConverter: t = _asmCore.GetType("System.Windows.Media.Media3D.Rect3DConverter"); break; + case KnownElements.Size3DConverter: t = _asmCore.GetType("System.Windows.Media.Media3D.Size3DConverter"); break; + case KnownElements.Transform3DCollection: t = _asmCore.GetType("System.Windows.Media.Media3D.Transform3DCollection"); break; + case KnownElements.Vector3DConverter: t = _asmCore.GetType("System.Windows.Media.Media3D.Vector3DConverter"); break; + case KnownElements.Vector3DCollectionConverter: t = _asmCore.GetType("System.Windows.Media.Media3D.Vector3DCollectionConverter"); break; + case KnownElements.XmlLanguage: t = _asmCore.GetType("System.Windows.Markup.XmlLanguage"); break; + case KnownElements.XmlLanguageConverter: t = _asmCore.GetType("System.Windows.Markup.XmlLanguageConverter"); break; + case KnownElements.Point: t = _asmBase.GetType("System.Windows.Point"); break; + case KnownElements.Size: t = _asmBase.GetType("System.Windows.Size"); break; + case KnownElements.Vector: t = _asmBase.GetType("System.Windows.Vector"); break; + case KnownElements.Rect: t = _asmBase.GetType("System.Windows.Rect"); break; + case KnownElements.Matrix: t = _asmBase.GetType("System.Windows.Media.Matrix"); break; + case KnownElements.DependencyProperty: t = _asmBase.GetType("System.Windows.DependencyProperty"); break; + case KnownElements.DependencyObject: t = _asmBase.GetType("System.Windows.DependencyObject"); break; + case KnownElements.Expression: t = _asmBase.GetType("System.Windows.Expression"); break; + case KnownElements.Freezable: t = _asmBase.GetType("System.Windows.Freezable"); break; + case KnownElements.WeakEventManager: t = _asmBase.GetType("System.Windows.WeakEventManager"); break; + case KnownElements.Int32Rect: t = _asmBase.GetType("System.Windows.Int32Rect"); break; + case KnownElements.ExpressionConverter: t = _asmBase.GetType("System.Windows.ExpressionConverter"); break; + case KnownElements.Int32RectConverter: t = _asmBase.GetType("System.Windows.Int32RectConverter"); break; + case KnownElements.PointConverter: t = _asmBase.GetType("System.Windows.PointConverter"); break; + case KnownElements.RectConverter: t = _asmBase.GetType("System.Windows.RectConverter"); break; + case KnownElements.SizeConverter: t = _asmBase.GetType("System.Windows.SizeConverter"); break; + case KnownElements.VectorConverter: t = _asmBase.GetType("System.Windows.VectorConverter"); break; + case KnownElements.KeyConverter: t = _asmBase.GetType("System.Windows.Input.KeyConverter"); break; + case KnownElements.MatrixConverter: t = _asmBase.GetType("System.Windows.Media.MatrixConverter"); break; + case KnownElements.MarkupExtension: t = _asmBase.GetType("System.Windows.Markup.MarkupExtension"); break; + case KnownElements.ModifierKeysConverter: t = _asmBase.GetType("System.Windows.Input.ModifierKeysConverter"); break; + case KnownElements.FrameworkPropertyMetadataOptions: t = _asmFramework.GetType("System.Windows.FrameworkPropertyMetadataOptions"); break; + case KnownElements.NullExtension: t = _asmFramework.GetType("System.Windows.Markup.NullExtension"); break; + case KnownElements.StaticExtension: t = _asmFramework.GetType("System.Windows.Markup.StaticExtension"); break; + case KnownElements.ArrayExtension: t = _asmFramework.GetType("System.Windows.Markup.ArrayExtension"); break; + case KnownElements.TypeExtension: t = _asmFramework.GetType("System.Windows.Markup.TypeExtension"); break; + case KnownElements.IStyleConnector: t = _asmFramework.GetType("System.Windows.Markup.IStyleConnector"); break; + case KnownElements.ParserContext: t = _asmFramework.GetType("System.Windows.Markup.ParserContext"); break; + case KnownElements.XamlReader: t = _asmFramework.GetType("System.Windows.Markup.XamlReader"); break; + case KnownElements.XamlWriter: t = _asmFramework.GetType("System.Windows.Markup.XamlWriter"); break; + case KnownElements.StreamResourceInfo: t = _asmFramework.GetType("System.Windows.Resources.StreamResourceInfo"); break; + case KnownElements.CommandConverter: t = _asmFramework.GetType("System.Windows.Input.CommandConverter"); break; + case KnownElements.DependencyPropertyConverter: t = _asmFramework.GetType("System.Windows.Markup.DependencyPropertyConverter"); break; + case KnownElements.ComponentResourceKeyConverter: t = _asmFramework.GetType("System.Windows.Markup.ComponentResourceKeyConverter"); break; + case KnownElements.TemplateKeyConverter: t = _asmFramework.GetType("System.Windows.Markup.TemplateKeyConverter"); break; + case KnownElements.RoutedEventConverter: t = _asmFramework.GetType("System.Windows.Markup.RoutedEventConverter"); break; + case KnownElements.FrameworkPropertyMetadata: t = _asmFramework.GetType("System.Windows.FrameworkPropertyMetadata"); break; + case KnownElements.Condition: t = _asmFramework.GetType("System.Windows.Condition"); break; + case KnownElements.FrameworkElementFactory: t = _asmFramework.GetType("System.Windows.FrameworkElementFactory"); break; + case KnownElements.IAddChild: t = _asmCore.GetType("System.Windows.Markup.IAddChild"); break; + case KnownElements.IAddChildInternal: t = _asmCore.GetType("System.Windows.Markup.IAddChildInternal"); break; + case KnownElements.RoutingStrategy: t = _asmCore.GetType("System.Windows.RoutingStrategy"); break; + case KnownElements.EventManager: t = _asmCore.GetType("System.Windows.EventManager"); break; + case KnownElements.XmlLangPropertyAttribute: t = _asmBase.GetType("System.Windows.Markup.XmlLangPropertyAttribute"); break; + case KnownElements.INameScope: t = _asmBase.GetType("System.Windows.Markup.INameScope"); break; + case KnownElements.IComponentConnector: t = _asmBase.GetType("System.Windows.Markup.IComponentConnector"); break; + case KnownElements.RuntimeNamePropertyAttribute: t = _asmBase.GetType("System.Windows.Markup.RuntimeNamePropertyAttribute"); break; + case KnownElements.ContentPropertyAttribute: t = _asmBase.GetType("System.Windows.Markup.ContentPropertyAttribute"); break; + case KnownElements.WhitespaceSignificantCollectionAttribute: t = _asmBase.GetType("System.Windows.Markup.WhitespaceSignificantCollectionAttribute"); break; + case KnownElements.ContentWrapperAttribute: t = _asmBase.GetType("System.Windows.Markup.ContentWrapperAttribute"); break; + case KnownElements.InlineCollection: t = _asmFramework.GetType("System.Windows.Documents.InlineCollection"); break; + case KnownElements.XamlStyleSerializer: t = typeof(XamlStyleSerializer); break; + case KnownElements.XamlTemplateSerializer: t = typeof(XamlTemplateSerializer); break; + case KnownElements.XamlBrushSerializer: t = typeof(XamlBrushSerializer); break; + case KnownElements.XamlPoint3DCollectionSerializer: t = typeof(XamlPoint3DCollectionSerializer); break; + case KnownElements.XamlVector3DCollectionSerializer: t = typeof(XamlVector3DCollectionSerializer); break; + case KnownElements.XamlPointCollectionSerializer: t = typeof(XamlPointCollectionSerializer); break; + case KnownElements.XamlInt32CollectionSerializer: t = typeof(XamlInt32CollectionSerializer); break; + case KnownElements.XamlPathDataSerializer: t = typeof(XamlPathDataSerializer); break; + case KnownElements.TypeTypeConverter: t = typeof(TypeTypeConverter); break; + case KnownElements.Boolean: t = typeof(Boolean); break; + case KnownElements.Int16: t = typeof(Int16); break; + case KnownElements.Int32: t = typeof(Int32); break; + case KnownElements.Int64: t = typeof(Int64); break; + case KnownElements.UInt16: t = typeof(UInt16); break; + case KnownElements.UInt32: t = typeof(UInt32); break; + case KnownElements.UInt64: t = typeof(UInt64); break; + case KnownElements.Single: t = typeof(Single); break; + case KnownElements.Double: t = typeof(Double); break; + case KnownElements.Object: t = typeof(Object); break; + case KnownElements.String: t = typeof(String); break; + case KnownElements.Byte: t = typeof(Byte); break; + case KnownElements.SByte: t = typeof(SByte); break; + case KnownElements.Char: t = typeof(Char); break; + case KnownElements.Decimal: t = typeof(Decimal); break; + case KnownElements.TimeSpan: t = typeof(TimeSpan); break; + case KnownElements.Guid: t = typeof(Guid); break; + case KnownElements.DateTime: t = typeof(DateTime); break; + case KnownElements.Uri: t = typeof(Uri); break; + case KnownElements.CultureInfo: t = typeof(CultureInfo); break; + case KnownElements.EnumConverter: t = typeof(EnumConverter); break; + case KnownElements.NullableConverter: t = typeof(NullableConverter); break; + case KnownElements.BooleanConverter: t = typeof(BooleanConverter); break; + case KnownElements.Int16Converter: t = typeof(Int16Converter); break; + case KnownElements.Int32Converter: t = typeof(Int32Converter); break; + case KnownElements.Int64Converter: t = typeof(Int64Converter); break; + case KnownElements.UInt16Converter: t = typeof(UInt16Converter); break; + case KnownElements.UInt32Converter: t = typeof(UInt32Converter); break; + case KnownElements.UInt64Converter: t = typeof(UInt64Converter); break; + case KnownElements.SingleConverter: t = typeof(SingleConverter); break; + case KnownElements.DoubleConverter: t = typeof(DoubleConverter); break; + case KnownElements.StringConverter: t = typeof(StringConverter); break; + case KnownElements.ByteConverter: t = typeof(ByteConverter); break; + case KnownElements.SByteConverter: t = typeof(SByteConverter); break; + case KnownElements.CharConverter: t = typeof(CharConverter); break; + case KnownElements.DecimalConverter: t = typeof(DecimalConverter); break; + case KnownElements.TimeSpanConverter: t = typeof(TimeSpanConverter); break; + case KnownElements.GuidConverter: t = typeof(GuidConverter); break; + case KnownElements.CultureInfoConverter: t = typeof(CultureInfoConverter); break; + case KnownElements.DateTimeConverter: t = typeof(DateTimeConverter); break; + case KnownElements.DateTimeConverter2: t = typeof(DateTimeConverter2); break; + case KnownElements.UriTypeConverter: t = typeof(UriTypeConverter); break; + } + + if(t == null) + { + MarkupCompiler.ThrowCompilerException(SRID.ParserInvalidKnownType, ((int)knownElement).ToString(CultureInfo.InvariantCulture), knownElement.ToString()); + } + return t; + } +#else + // Initialize the Known WCP types from basic WCP assemblies + private Type InitializeOneType(KnownElements knownElement) + { + Type t = null; + switch(knownElement) + { + case KnownElements.AccessText: t = typeof(System.Windows.Controls.AccessText); break; + case KnownElements.AdornedElementPlaceholder: t = typeof(System.Windows.Controls.AdornedElementPlaceholder); break; + case KnownElements.Adorner: t = typeof(System.Windows.Documents.Adorner); break; + case KnownElements.AdornerDecorator: t = typeof(System.Windows.Documents.AdornerDecorator); break; + case KnownElements.AdornerLayer: t = typeof(System.Windows.Documents.AdornerLayer); break; + case KnownElements.AffineTransform3D: t = typeof(System.Windows.Media.Media3D.AffineTransform3D); break; + case KnownElements.AmbientLight: t = typeof(System.Windows.Media.Media3D.AmbientLight); break; + case KnownElements.AnchoredBlock: t = typeof(System.Windows.Documents.AnchoredBlock); break; + case KnownElements.Animatable: t = typeof(System.Windows.Media.Animation.Animatable); break; + case KnownElements.AnimationClock: t = typeof(System.Windows.Media.Animation.AnimationClock); break; + case KnownElements.AnimationTimeline: t = typeof(System.Windows.Media.Animation.AnimationTimeline); break; + case KnownElements.Application: t = typeof(System.Windows.Application); break; + case KnownElements.ArcSegment: t = typeof(System.Windows.Media.ArcSegment); break; + case KnownElements.ArrayExtension: t = typeof(System.Windows.Markup.ArrayExtension); break; + case KnownElements.AxisAngleRotation3D: t = typeof(System.Windows.Media.Media3D.AxisAngleRotation3D); break; + case KnownElements.BaseIListConverter: t = typeof(System.Windows.Media.Converters.BaseIListConverter); break; + case KnownElements.BeginStoryboard: t = typeof(System.Windows.Media.Animation.BeginStoryboard); break; + case KnownElements.BevelBitmapEffect: t = typeof(System.Windows.Media.Effects.BevelBitmapEffect); break; + case KnownElements.BezierSegment: t = typeof(System.Windows.Media.BezierSegment); break; + case KnownElements.Binding: t = typeof(System.Windows.Data.Binding); break; + case KnownElements.BindingBase: t = typeof(System.Windows.Data.BindingBase); break; + case KnownElements.BindingExpression: t = typeof(System.Windows.Data.BindingExpression); break; + case KnownElements.BindingExpressionBase: t = typeof(System.Windows.Data.BindingExpressionBase); break; + case KnownElements.BindingListCollectionView: t = typeof(System.Windows.Data.BindingListCollectionView); break; + case KnownElements.BitmapDecoder: t = typeof(System.Windows.Media.Imaging.BitmapDecoder); break; + case KnownElements.BitmapEffect: t = typeof(System.Windows.Media.Effects.BitmapEffect); break; + case KnownElements.BitmapEffectCollection: t = typeof(System.Windows.Media.Effects.BitmapEffectCollection); break; + case KnownElements.BitmapEffectGroup: t = typeof(System.Windows.Media.Effects.BitmapEffectGroup); break; + case KnownElements.BitmapEffectInput: t = typeof(System.Windows.Media.Effects.BitmapEffectInput); break; + case KnownElements.BitmapEncoder: t = typeof(System.Windows.Media.Imaging.BitmapEncoder); break; + case KnownElements.BitmapFrame: t = typeof(System.Windows.Media.Imaging.BitmapFrame); break; + case KnownElements.BitmapImage: t = typeof(System.Windows.Media.Imaging.BitmapImage); break; + case KnownElements.BitmapMetadata: t = typeof(System.Windows.Media.Imaging.BitmapMetadata); break; + case KnownElements.BitmapPalette: t = typeof(System.Windows.Media.Imaging.BitmapPalette); break; + case KnownElements.BitmapSource: t = typeof(System.Windows.Media.Imaging.BitmapSource); break; + case KnownElements.Block: t = typeof(System.Windows.Documents.Block); break; + case KnownElements.BlockUIContainer: t = typeof(System.Windows.Documents.BlockUIContainer); break; + case KnownElements.BlurBitmapEffect: t = typeof(System.Windows.Media.Effects.BlurBitmapEffect); break; + case KnownElements.BmpBitmapDecoder: t = typeof(System.Windows.Media.Imaging.BmpBitmapDecoder); break; + case KnownElements.BmpBitmapEncoder: t = typeof(System.Windows.Media.Imaging.BmpBitmapEncoder); break; + case KnownElements.Bold: t = typeof(System.Windows.Documents.Bold); break; + case KnownElements.BoolIListConverter: t = typeof(System.Windows.Media.Converters.BoolIListConverter); break; + case KnownElements.Boolean: t = typeof(System.Boolean); break; + case KnownElements.BooleanAnimationBase: t = typeof(System.Windows.Media.Animation.BooleanAnimationBase); break; + case KnownElements.BooleanAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.BooleanAnimationUsingKeyFrames); break; + case KnownElements.BooleanConverter: t = typeof(System.ComponentModel.BooleanConverter); break; + case KnownElements.BooleanKeyFrame: t = typeof(System.Windows.Media.Animation.BooleanKeyFrame); break; + case KnownElements.BooleanKeyFrameCollection: t = typeof(System.Windows.Media.Animation.BooleanKeyFrameCollection); break; + case KnownElements.BooleanToVisibilityConverter: t = typeof(System.Windows.Controls.BooleanToVisibilityConverter); break; + case KnownElements.Border: t = typeof(System.Windows.Controls.Border); break; + case KnownElements.BorderGapMaskConverter: t = typeof(System.Windows.Controls.BorderGapMaskConverter); break; + case KnownElements.Brush: t = typeof(System.Windows.Media.Brush); break; + case KnownElements.BrushConverter: t = typeof(System.Windows.Media.BrushConverter); break; + case KnownElements.BulletDecorator: t = typeof(System.Windows.Controls.Primitives.BulletDecorator); break; + case KnownElements.Button: t = typeof(System.Windows.Controls.Button); break; + case KnownElements.ButtonBase: t = typeof(System.Windows.Controls.Primitives.ButtonBase); break; + case KnownElements.Byte: t = typeof(System.Byte); break; + case KnownElements.ByteAnimation: t = typeof(System.Windows.Media.Animation.ByteAnimation); break; + case KnownElements.ByteAnimationBase: t = typeof(System.Windows.Media.Animation.ByteAnimationBase); break; + case KnownElements.ByteAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.ByteAnimationUsingKeyFrames); break; + case KnownElements.ByteConverter: t = typeof(System.ComponentModel.ByteConverter); break; + case KnownElements.ByteKeyFrame: t = typeof(System.Windows.Media.Animation.ByteKeyFrame); break; + case KnownElements.ByteKeyFrameCollection: t = typeof(System.Windows.Media.Animation.ByteKeyFrameCollection); break; + case KnownElements.CachedBitmap: t = typeof(System.Windows.Media.Imaging.CachedBitmap); break; + case KnownElements.Camera: t = typeof(System.Windows.Media.Media3D.Camera); break; + case KnownElements.Canvas: t = typeof(System.Windows.Controls.Canvas); break; + case KnownElements.Char: t = typeof(System.Char); break; + case KnownElements.CharAnimationBase: t = typeof(System.Windows.Media.Animation.CharAnimationBase); break; + case KnownElements.CharAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.CharAnimationUsingKeyFrames); break; + case KnownElements.CharConverter: t = typeof(System.ComponentModel.CharConverter); break; + case KnownElements.CharIListConverter: t = typeof(System.Windows.Media.Converters.CharIListConverter); break; + case KnownElements.CharKeyFrame: t = typeof(System.Windows.Media.Animation.CharKeyFrame); break; + case KnownElements.CharKeyFrameCollection: t = typeof(System.Windows.Media.Animation.CharKeyFrameCollection); break; + case KnownElements.CheckBox: t = typeof(System.Windows.Controls.CheckBox); break; + case KnownElements.Clock: t = typeof(System.Windows.Media.Animation.Clock); break; + case KnownElements.ClockController: t = typeof(System.Windows.Media.Animation.ClockController); break; + case KnownElements.ClockGroup: t = typeof(System.Windows.Media.Animation.ClockGroup); break; + case KnownElements.CollectionContainer: t = typeof(System.Windows.Data.CollectionContainer); break; + case KnownElements.CollectionView: t = typeof(System.Windows.Data.CollectionView); break; + case KnownElements.CollectionViewSource: t = typeof(System.Windows.Data.CollectionViewSource); break; + case KnownElements.Color: t = typeof(System.Windows.Media.Color); break; + case KnownElements.ColorAnimation: t = typeof(System.Windows.Media.Animation.ColorAnimation); break; + case KnownElements.ColorAnimationBase: t = typeof(System.Windows.Media.Animation.ColorAnimationBase); break; + case KnownElements.ColorAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.ColorAnimationUsingKeyFrames); break; + case KnownElements.ColorConvertedBitmap: t = typeof(System.Windows.Media.Imaging.ColorConvertedBitmap); break; + case KnownElements.ColorConvertedBitmapExtension: t = typeof(System.Windows.ColorConvertedBitmapExtension); break; + case KnownElements.ColorConverter: t = typeof(System.Windows.Media.ColorConverter); break; + case KnownElements.ColorKeyFrame: t = typeof(System.Windows.Media.Animation.ColorKeyFrame); break; + case KnownElements.ColorKeyFrameCollection: t = typeof(System.Windows.Media.Animation.ColorKeyFrameCollection); break; + case KnownElements.ColumnDefinition: t = typeof(System.Windows.Controls.ColumnDefinition); break; + case KnownElements.CombinedGeometry: t = typeof(System.Windows.Media.CombinedGeometry); break; + case KnownElements.ComboBox: t = typeof(System.Windows.Controls.ComboBox); break; + case KnownElements.ComboBoxItem: t = typeof(System.Windows.Controls.ComboBoxItem); break; + case KnownElements.CommandConverter: t = typeof(System.Windows.Input.CommandConverter); break; + case KnownElements.ComponentResourceKey: t = typeof(System.Windows.ComponentResourceKey); break; + case KnownElements.ComponentResourceKeyConverter: t = typeof(System.Windows.Markup.ComponentResourceKeyConverter); break; + case KnownElements.CompositionTarget: t = typeof(System.Windows.Media.CompositionTarget); break; + case KnownElements.Condition: t = typeof(System.Windows.Condition); break; + case KnownElements.ContainerVisual: t = typeof(System.Windows.Media.ContainerVisual); break; + case KnownElements.ContentControl: t = typeof(System.Windows.Controls.ContentControl); break; + case KnownElements.ContentElement: t = typeof(System.Windows.ContentElement); break; + case KnownElements.ContentPresenter: t = typeof(System.Windows.Controls.ContentPresenter); break; + case KnownElements.ContentPropertyAttribute: t = typeof(System.Windows.Markup.ContentPropertyAttribute); break; + case KnownElements.ContentWrapperAttribute: t = typeof(System.Windows.Markup.ContentWrapperAttribute); break; + case KnownElements.ContextMenu: t = typeof(System.Windows.Controls.ContextMenu); break; + case KnownElements.ContextMenuService: t = typeof(System.Windows.Controls.ContextMenuService); break; + case KnownElements.Control: t = typeof(System.Windows.Controls.Control); break; + case KnownElements.ControlTemplate: t = typeof(System.Windows.Controls.ControlTemplate); break; + case KnownElements.ControllableStoryboardAction: t = typeof(System.Windows.Media.Animation.ControllableStoryboardAction); break; + case KnownElements.CornerRadius: t = typeof(System.Windows.CornerRadius); break; + case KnownElements.CornerRadiusConverter: t = typeof(System.Windows.CornerRadiusConverter); break; + case KnownElements.CroppedBitmap: t = typeof(System.Windows.Media.Imaging.CroppedBitmap); break; + case KnownElements.CultureInfo: t = typeof(System.Globalization.CultureInfo); break; + case KnownElements.CultureInfoConverter: t = typeof(System.ComponentModel.CultureInfoConverter); break; + case KnownElements.CultureInfoIetfLanguageTagConverter: t = typeof(System.Windows.CultureInfoIetfLanguageTagConverter); break; + case KnownElements.Cursor: t = typeof(System.Windows.Input.Cursor); break; + case KnownElements.CursorConverter: t = typeof(System.Windows.Input.CursorConverter); break; + case KnownElements.DashStyle: t = typeof(System.Windows.Media.DashStyle); break; + case KnownElements.DataChangedEventManager: t = typeof(System.Windows.Data.DataChangedEventManager); break; + case KnownElements.DataTemplate: t = typeof(System.Windows.DataTemplate); break; + case KnownElements.DataTemplateKey: t = typeof(System.Windows.DataTemplateKey); break; + case KnownElements.DataTrigger: t = typeof(System.Windows.DataTrigger); break; + case KnownElements.DateTime: t = typeof(System.DateTime); break; + case KnownElements.DateTimeConverter: t = typeof(System.ComponentModel.DateTimeConverter); break; + case KnownElements.DateTimeConverter2: t = typeof(System.Windows.Markup.DateTimeConverter2); break; + case KnownElements.Decimal: t = typeof(System.Decimal); break; + case KnownElements.DecimalAnimation: t = typeof(System.Windows.Media.Animation.DecimalAnimation); break; + case KnownElements.DecimalAnimationBase: t = typeof(System.Windows.Media.Animation.DecimalAnimationBase); break; + case KnownElements.DecimalAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.DecimalAnimationUsingKeyFrames); break; + case KnownElements.DecimalConverter: t = typeof(System.ComponentModel.DecimalConverter); break; + case KnownElements.DecimalKeyFrame: t = typeof(System.Windows.Media.Animation.DecimalKeyFrame); break; + case KnownElements.DecimalKeyFrameCollection: t = typeof(System.Windows.Media.Animation.DecimalKeyFrameCollection); break; + case KnownElements.Decorator: t = typeof(System.Windows.Controls.Decorator); break; + case KnownElements.DefinitionBase: t = typeof(System.Windows.Controls.DefinitionBase); break; + case KnownElements.DependencyObject: t = typeof(System.Windows.DependencyObject); break; + case KnownElements.DependencyProperty: t = typeof(System.Windows.DependencyProperty); break; + case KnownElements.DependencyPropertyConverter: t = typeof(System.Windows.Markup.DependencyPropertyConverter); break; + case KnownElements.DialogResultConverter: t = typeof(System.Windows.DialogResultConverter); break; + case KnownElements.DiffuseMaterial: t = typeof(System.Windows.Media.Media3D.DiffuseMaterial); break; + case KnownElements.DirectionalLight: t = typeof(System.Windows.Media.Media3D.DirectionalLight); break; + case KnownElements.DiscreteBooleanKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteBooleanKeyFrame); break; + case KnownElements.DiscreteByteKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteByteKeyFrame); break; + case KnownElements.DiscreteCharKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteCharKeyFrame); break; + case KnownElements.DiscreteColorKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteColorKeyFrame); break; + case KnownElements.DiscreteDecimalKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteDecimalKeyFrame); break; + case KnownElements.DiscreteDoubleKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteDoubleKeyFrame); break; + case KnownElements.DiscreteInt16KeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteInt16KeyFrame); break; + case KnownElements.DiscreteInt32KeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteInt32KeyFrame); break; + case KnownElements.DiscreteInt64KeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteInt64KeyFrame); break; + case KnownElements.DiscreteMatrixKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteMatrixKeyFrame); break; + case KnownElements.DiscreteObjectKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteObjectKeyFrame); break; + case KnownElements.DiscretePoint3DKeyFrame: t = typeof(System.Windows.Media.Animation.DiscretePoint3DKeyFrame); break; + case KnownElements.DiscretePointKeyFrame: t = typeof(System.Windows.Media.Animation.DiscretePointKeyFrame); break; + case KnownElements.DiscreteQuaternionKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteQuaternionKeyFrame); break; + case KnownElements.DiscreteRectKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteRectKeyFrame); break; + case KnownElements.DiscreteRotation3DKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteRotation3DKeyFrame); break; + case KnownElements.DiscreteSingleKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteSingleKeyFrame); break; + case KnownElements.DiscreteSizeKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteSizeKeyFrame); break; + case KnownElements.DiscreteStringKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteStringKeyFrame); break; + case KnownElements.DiscreteThicknessKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteThicknessKeyFrame); break; + case KnownElements.DiscreteVector3DKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteVector3DKeyFrame); break; + case KnownElements.DiscreteVectorKeyFrame: t = typeof(System.Windows.Media.Animation.DiscreteVectorKeyFrame); break; + case KnownElements.DockPanel: t = typeof(System.Windows.Controls.DockPanel); break; + case KnownElements.DocumentPageView: t = typeof(System.Windows.Controls.Primitives.DocumentPageView); break; + case KnownElements.DocumentReference: t = typeof(System.Windows.Documents.DocumentReference); break; + case KnownElements.DocumentViewer: t = typeof(System.Windows.Controls.DocumentViewer); break; + case KnownElements.DocumentViewerBase: t = typeof(System.Windows.Controls.Primitives.DocumentViewerBase); break; + case KnownElements.Double: t = typeof(System.Double); break; + case KnownElements.DoubleAnimation: t = typeof(System.Windows.Media.Animation.DoubleAnimation); break; + case KnownElements.DoubleAnimationBase: t = typeof(System.Windows.Media.Animation.DoubleAnimationBase); break; + case KnownElements.DoubleAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.DoubleAnimationUsingKeyFrames); break; + case KnownElements.DoubleAnimationUsingPath: t = typeof(System.Windows.Media.Animation.DoubleAnimationUsingPath); break; + case KnownElements.DoubleCollection: t = typeof(System.Windows.Media.DoubleCollection); break; + case KnownElements.DoubleCollectionConverter: t = typeof(System.Windows.Media.DoubleCollectionConverter); break; + case KnownElements.DoubleConverter: t = typeof(System.ComponentModel.DoubleConverter); break; + case KnownElements.DoubleIListConverter: t = typeof(System.Windows.Media.Converters.DoubleIListConverter); break; + case KnownElements.DoubleKeyFrame: t = typeof(System.Windows.Media.Animation.DoubleKeyFrame); break; + case KnownElements.DoubleKeyFrameCollection: t = typeof(System.Windows.Media.Animation.DoubleKeyFrameCollection); break; + case KnownElements.Drawing: t = typeof(System.Windows.Media.Drawing); break; + case KnownElements.DrawingBrush: t = typeof(System.Windows.Media.DrawingBrush); break; + case KnownElements.DrawingCollection: t = typeof(System.Windows.Media.DrawingCollection); break; + case KnownElements.DrawingContext: t = typeof(System.Windows.Media.DrawingContext); break; + case KnownElements.DrawingGroup: t = typeof(System.Windows.Media.DrawingGroup); break; + case KnownElements.DrawingImage: t = typeof(System.Windows.Media.DrawingImage); break; + case KnownElements.DrawingVisual: t = typeof(System.Windows.Media.DrawingVisual); break; + case KnownElements.DropShadowBitmapEffect: t = typeof(System.Windows.Media.Effects.DropShadowBitmapEffect); break; + case KnownElements.Duration: t = typeof(System.Windows.Duration); break; + case KnownElements.DurationConverter: t = typeof(System.Windows.DurationConverter); break; + case KnownElements.DynamicResourceExtension: t = typeof(System.Windows.DynamicResourceExtension); break; + case KnownElements.DynamicResourceExtensionConverter: t = typeof(System.Windows.DynamicResourceExtensionConverter); break; + case KnownElements.Ellipse: t = typeof(System.Windows.Shapes.Ellipse); break; + case KnownElements.EllipseGeometry: t = typeof(System.Windows.Media.EllipseGeometry); break; + case KnownElements.EmbossBitmapEffect: t = typeof(System.Windows.Media.Effects.EmbossBitmapEffect); break; + case KnownElements.EmissiveMaterial: t = typeof(System.Windows.Media.Media3D.EmissiveMaterial); break; + case KnownElements.EnumConverter: t = typeof(System.ComponentModel.EnumConverter); break; + case KnownElements.EventManager: t = typeof(System.Windows.EventManager); break; + case KnownElements.EventSetter: t = typeof(System.Windows.EventSetter); break; + case KnownElements.EventTrigger: t = typeof(System.Windows.EventTrigger); break; + case KnownElements.Expander: t = typeof(System.Windows.Controls.Expander); break; + case KnownElements.Expression: t = typeof(System.Windows.Expression); break; + case KnownElements.ExpressionConverter: t = typeof(System.Windows.ExpressionConverter); break; + case KnownElements.Figure: t = typeof(System.Windows.Documents.Figure); break; + case KnownElements.FigureLength: t = typeof(System.Windows.FigureLength); break; + case KnownElements.FigureLengthConverter: t = typeof(System.Windows.FigureLengthConverter); break; + case KnownElements.FixedDocument: t = typeof(System.Windows.Documents.FixedDocument); break; + case KnownElements.FixedDocumentSequence: t = typeof(System.Windows.Documents.FixedDocumentSequence); break; + case KnownElements.FixedPage: t = typeof(System.Windows.Documents.FixedPage); break; + case KnownElements.Floater: t = typeof(System.Windows.Documents.Floater); break; + case KnownElements.FlowDocument: t = typeof(System.Windows.Documents.FlowDocument); break; + case KnownElements.FlowDocumentPageViewer: t = typeof(System.Windows.Controls.FlowDocumentPageViewer); break; + case KnownElements.FlowDocumentReader: t = typeof(System.Windows.Controls.FlowDocumentReader); break; + case KnownElements.FlowDocumentScrollViewer: t = typeof(System.Windows.Controls.FlowDocumentScrollViewer); break; + case KnownElements.FocusManager: t = typeof(System.Windows.Input.FocusManager); break; + case KnownElements.FontFamily: t = typeof(System.Windows.Media.FontFamily); break; + case KnownElements.FontFamilyConverter: t = typeof(System.Windows.Media.FontFamilyConverter); break; + case KnownElements.FontSizeConverter: t = typeof(System.Windows.FontSizeConverter); break; + case KnownElements.FontStretch: t = typeof(System.Windows.FontStretch); break; + case KnownElements.FontStretchConverter: t = typeof(System.Windows.FontStretchConverter); break; + case KnownElements.FontStyle: t = typeof(System.Windows.FontStyle); break; + case KnownElements.FontStyleConverter: t = typeof(System.Windows.FontStyleConverter); break; + case KnownElements.FontWeight: t = typeof(System.Windows.FontWeight); break; + case KnownElements.FontWeightConverter: t = typeof(System.Windows.FontWeightConverter); break; + case KnownElements.FormatConvertedBitmap: t = typeof(System.Windows.Media.Imaging.FormatConvertedBitmap); break; + case KnownElements.Frame: t = typeof(System.Windows.Controls.Frame); break; + case KnownElements.FrameworkContentElement: t = typeof(System.Windows.FrameworkContentElement); break; + case KnownElements.FrameworkElement: t = typeof(System.Windows.FrameworkElement); break; + case KnownElements.FrameworkElementFactory: t = typeof(System.Windows.FrameworkElementFactory); break; + case KnownElements.FrameworkPropertyMetadata: t = typeof(System.Windows.FrameworkPropertyMetadata); break; + case KnownElements.FrameworkPropertyMetadataOptions: t = typeof(System.Windows.FrameworkPropertyMetadataOptions); break; + case KnownElements.FrameworkRichTextComposition: t = typeof(System.Windows.Documents.FrameworkRichTextComposition); break; + case KnownElements.FrameworkTemplate: t = typeof(System.Windows.FrameworkTemplate); break; + case KnownElements.FrameworkTextComposition: t = typeof(System.Windows.Documents.FrameworkTextComposition); break; + case KnownElements.Freezable: t = typeof(System.Windows.Freezable); break; + case KnownElements.GeneralTransform: t = typeof(System.Windows.Media.GeneralTransform); break; + case KnownElements.GeneralTransformCollection: t = typeof(System.Windows.Media.GeneralTransformCollection); break; + case KnownElements.GeneralTransformGroup: t = typeof(System.Windows.Media.GeneralTransformGroup); break; + case KnownElements.Geometry: t = typeof(System.Windows.Media.Geometry); break; + case KnownElements.Geometry3D: t = typeof(System.Windows.Media.Media3D.Geometry3D); break; + case KnownElements.GeometryCollection: t = typeof(System.Windows.Media.GeometryCollection); break; + case KnownElements.GeometryConverter: t = typeof(System.Windows.Media.GeometryConverter); break; + case KnownElements.GeometryDrawing: t = typeof(System.Windows.Media.GeometryDrawing); break; + case KnownElements.GeometryGroup: t = typeof(System.Windows.Media.GeometryGroup); break; + case KnownElements.GeometryModel3D: t = typeof(System.Windows.Media.Media3D.GeometryModel3D); break; + case KnownElements.GestureRecognizer: t = typeof(System.Windows.Ink.GestureRecognizer); break; + case KnownElements.GifBitmapDecoder: t = typeof(System.Windows.Media.Imaging.GifBitmapDecoder); break; + case KnownElements.GifBitmapEncoder: t = typeof(System.Windows.Media.Imaging.GifBitmapEncoder); break; + case KnownElements.GlyphRun: t = typeof(System.Windows.Media.GlyphRun); break; + case KnownElements.GlyphRunDrawing: t = typeof(System.Windows.Media.GlyphRunDrawing); break; + case KnownElements.GlyphTypeface: t = typeof(System.Windows.Media.GlyphTypeface); break; + case KnownElements.Glyphs: t = typeof(System.Windows.Documents.Glyphs); break; + case KnownElements.GradientBrush: t = typeof(System.Windows.Media.GradientBrush); break; + case KnownElements.GradientStop: t = typeof(System.Windows.Media.GradientStop); break; + case KnownElements.GradientStopCollection: t = typeof(System.Windows.Media.GradientStopCollection); break; + case KnownElements.Grid: t = typeof(System.Windows.Controls.Grid); break; + case KnownElements.GridLength: t = typeof(System.Windows.GridLength); break; + case KnownElements.GridLengthConverter: t = typeof(System.Windows.GridLengthConverter); break; + case KnownElements.GridSplitter: t = typeof(System.Windows.Controls.GridSplitter); break; + case KnownElements.GridView: t = typeof(System.Windows.Controls.GridView); break; + case KnownElements.GridViewColumn: t = typeof(System.Windows.Controls.GridViewColumn); break; + case KnownElements.GridViewColumnHeader: t = typeof(System.Windows.Controls.GridViewColumnHeader); break; + case KnownElements.GridViewHeaderRowPresenter: t = typeof(System.Windows.Controls.GridViewHeaderRowPresenter); break; + case KnownElements.GridViewRowPresenter: t = typeof(System.Windows.Controls.GridViewRowPresenter); break; + case KnownElements.GridViewRowPresenterBase: t = typeof(System.Windows.Controls.Primitives.GridViewRowPresenterBase); break; + case KnownElements.GroupBox: t = typeof(System.Windows.Controls.GroupBox); break; + case KnownElements.GroupItem: t = typeof(System.Windows.Controls.GroupItem); break; + case KnownElements.Guid: t = typeof(System.Guid); break; + case KnownElements.GuidConverter: t = typeof(System.ComponentModel.GuidConverter); break; + case KnownElements.GuidelineSet: t = typeof(System.Windows.Media.GuidelineSet); break; + case KnownElements.HeaderedContentControl: t = typeof(System.Windows.Controls.HeaderedContentControl); break; + case KnownElements.HeaderedItemsControl: t = typeof(System.Windows.Controls.HeaderedItemsControl); break; + case KnownElements.HierarchicalDataTemplate: t = typeof(System.Windows.HierarchicalDataTemplate); break; + case KnownElements.HostVisual: t = typeof(System.Windows.Media.HostVisual); break; + case KnownElements.Hyperlink: t = typeof(System.Windows.Documents.Hyperlink); break; + case KnownElements.IAddChild: t = typeof(System.Windows.Markup.IAddChild); break; + case KnownElements.IAddChildInternal: t = typeof(System.Windows.Markup.IAddChildInternal); break; + case KnownElements.ICommand: t = typeof(System.Windows.Input.ICommand); break; + case KnownElements.IComponentConnector: t = typeof(System.Windows.Markup.IComponentConnector); break; + case KnownElements.INameScope: t = typeof(System.Windows.Markup.INameScope); break; + case KnownElements.IStyleConnector: t = typeof(System.Windows.Markup.IStyleConnector); break; + case KnownElements.IconBitmapDecoder: t = typeof(System.Windows.Media.Imaging.IconBitmapDecoder); break; + case KnownElements.Image: t = typeof(System.Windows.Controls.Image); break; + case KnownElements.ImageBrush: t = typeof(System.Windows.Media.ImageBrush); break; + case KnownElements.ImageDrawing: t = typeof(System.Windows.Media.ImageDrawing); break; + case KnownElements.ImageMetadata: t = typeof(System.Windows.Media.ImageMetadata); break; + case KnownElements.ImageSource: t = typeof(System.Windows.Media.ImageSource); break; + case KnownElements.ImageSourceConverter: t = typeof(System.Windows.Media.ImageSourceConverter); break; + case KnownElements.InPlaceBitmapMetadataWriter: t = typeof(System.Windows.Media.Imaging.InPlaceBitmapMetadataWriter); break; + case KnownElements.InkCanvas: t = typeof(System.Windows.Controls.InkCanvas); break; + case KnownElements.InkPresenter: t = typeof(System.Windows.Controls.InkPresenter); break; + case KnownElements.Inline: t = typeof(System.Windows.Documents.Inline); break; + case KnownElements.InlineCollection: t = typeof(System.Windows.Documents.InlineCollection); break; + case KnownElements.InlineUIContainer: t = typeof(System.Windows.Documents.InlineUIContainer); break; + case KnownElements.InputBinding: t = typeof(System.Windows.Input.InputBinding); break; + case KnownElements.InputDevice: t = typeof(System.Windows.Input.InputDevice); break; + case KnownElements.InputLanguageManager: t = typeof(System.Windows.Input.InputLanguageManager); break; + case KnownElements.InputManager: t = typeof(System.Windows.Input.InputManager); break; + case KnownElements.InputMethod: t = typeof(System.Windows.Input.InputMethod); break; + case KnownElements.InputScope: t = typeof(System.Windows.Input.InputScope); break; + case KnownElements.InputScopeConverter: t = typeof(System.Windows.Input.InputScopeConverter); break; + case KnownElements.InputScopeName: t = typeof(System.Windows.Input.InputScopeName); break; + case KnownElements.InputScopeNameConverter: t = typeof(System.Windows.Input.InputScopeNameConverter); break; + case KnownElements.Int16: t = typeof(System.Int16); break; + case KnownElements.Int16Animation: t = typeof(System.Windows.Media.Animation.Int16Animation); break; + case KnownElements.Int16AnimationBase: t = typeof(System.Windows.Media.Animation.Int16AnimationBase); break; + case KnownElements.Int16AnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.Int16AnimationUsingKeyFrames); break; + case KnownElements.Int16Converter: t = typeof(System.ComponentModel.Int16Converter); break; + case KnownElements.Int16KeyFrame: t = typeof(System.Windows.Media.Animation.Int16KeyFrame); break; + case KnownElements.Int16KeyFrameCollection: t = typeof(System.Windows.Media.Animation.Int16KeyFrameCollection); break; + case KnownElements.Int32: t = typeof(System.Int32); break; + case KnownElements.Int32Animation: t = typeof(System.Windows.Media.Animation.Int32Animation); break; + case KnownElements.Int32AnimationBase: t = typeof(System.Windows.Media.Animation.Int32AnimationBase); break; + case KnownElements.Int32AnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.Int32AnimationUsingKeyFrames); break; + case KnownElements.Int32Collection: t = typeof(System.Windows.Media.Int32Collection); break; + case KnownElements.Int32CollectionConverter: t = typeof(System.Windows.Media.Int32CollectionConverter); break; + case KnownElements.Int32Converter: t = typeof(System.ComponentModel.Int32Converter); break; + case KnownElements.Int32KeyFrame: t = typeof(System.Windows.Media.Animation.Int32KeyFrame); break; + case KnownElements.Int32KeyFrameCollection: t = typeof(System.Windows.Media.Animation.Int32KeyFrameCollection); break; + case KnownElements.Int32Rect: t = typeof(System.Windows.Int32Rect); break; + case KnownElements.Int32RectConverter: t = typeof(System.Windows.Int32RectConverter); break; + case KnownElements.Int64: t = typeof(System.Int64); break; + case KnownElements.Int64Animation: t = typeof(System.Windows.Media.Animation.Int64Animation); break; + case KnownElements.Int64AnimationBase: t = typeof(System.Windows.Media.Animation.Int64AnimationBase); break; + case KnownElements.Int64AnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.Int64AnimationUsingKeyFrames); break; + case KnownElements.Int64Converter: t = typeof(System.ComponentModel.Int64Converter); break; + case KnownElements.Int64KeyFrame: t = typeof(System.Windows.Media.Animation.Int64KeyFrame); break; + case KnownElements.Int64KeyFrameCollection: t = typeof(System.Windows.Media.Animation.Int64KeyFrameCollection); break; + case KnownElements.Italic: t = typeof(System.Windows.Documents.Italic); break; + case KnownElements.ItemCollection: t = typeof(System.Windows.Controls.ItemCollection); break; + case KnownElements.ItemsControl: t = typeof(System.Windows.Controls.ItemsControl); break; + case KnownElements.ItemsPanelTemplate: t = typeof(System.Windows.Controls.ItemsPanelTemplate); break; + case KnownElements.ItemsPresenter: t = typeof(System.Windows.Controls.ItemsPresenter); break; + case KnownElements.JournalEntry: t = typeof(System.Windows.Navigation.JournalEntry); break; + case KnownElements.JournalEntryListConverter: t = typeof(System.Windows.Navigation.JournalEntryListConverter); break; + case KnownElements.JournalEntryUnifiedViewConverter: t = typeof(System.Windows.Navigation.JournalEntryUnifiedViewConverter); break; + case KnownElements.JpegBitmapDecoder: t = typeof(System.Windows.Media.Imaging.JpegBitmapDecoder); break; + case KnownElements.JpegBitmapEncoder: t = typeof(System.Windows.Media.Imaging.JpegBitmapEncoder); break; + case KnownElements.KeyBinding: t = typeof(System.Windows.Input.KeyBinding); break; + case KnownElements.KeyConverter: t = typeof(System.Windows.Input.KeyConverter); break; + case KnownElements.KeyGesture: t = typeof(System.Windows.Input.KeyGesture); break; + case KnownElements.KeyGestureConverter: t = typeof(System.Windows.Input.KeyGestureConverter); break; + case KnownElements.KeySpline: t = typeof(System.Windows.Media.Animation.KeySpline); break; + case KnownElements.KeySplineConverter: t = typeof(System.Windows.KeySplineConverter); break; + case KnownElements.KeyTime: t = typeof(System.Windows.Media.Animation.KeyTime); break; + case KnownElements.KeyTimeConverter: t = typeof(System.Windows.KeyTimeConverter); break; + case KnownElements.KeyboardDevice: t = typeof(System.Windows.Input.KeyboardDevice); break; + case KnownElements.Label: t = typeof(System.Windows.Controls.Label); break; + case KnownElements.LateBoundBitmapDecoder: t = typeof(System.Windows.Media.Imaging.LateBoundBitmapDecoder); break; + case KnownElements.LengthConverter: t = typeof(System.Windows.LengthConverter); break; + case KnownElements.Light: t = typeof(System.Windows.Media.Media3D.Light); break; + case KnownElements.Line: t = typeof(System.Windows.Shapes.Line); break; + case KnownElements.LineBreak: t = typeof(System.Windows.Documents.LineBreak); break; + case KnownElements.LineGeometry: t = typeof(System.Windows.Media.LineGeometry); break; + case KnownElements.LineSegment: t = typeof(System.Windows.Media.LineSegment); break; + case KnownElements.LinearByteKeyFrame: t = typeof(System.Windows.Media.Animation.LinearByteKeyFrame); break; + case KnownElements.LinearColorKeyFrame: t = typeof(System.Windows.Media.Animation.LinearColorKeyFrame); break; + case KnownElements.LinearDecimalKeyFrame: t = typeof(System.Windows.Media.Animation.LinearDecimalKeyFrame); break; + case KnownElements.LinearDoubleKeyFrame: t = typeof(System.Windows.Media.Animation.LinearDoubleKeyFrame); break; + case KnownElements.LinearGradientBrush: t = typeof(System.Windows.Media.LinearGradientBrush); break; + case KnownElements.LinearInt16KeyFrame: t = typeof(System.Windows.Media.Animation.LinearInt16KeyFrame); break; + case KnownElements.LinearInt32KeyFrame: t = typeof(System.Windows.Media.Animation.LinearInt32KeyFrame); break; + case KnownElements.LinearInt64KeyFrame: t = typeof(System.Windows.Media.Animation.LinearInt64KeyFrame); break; + case KnownElements.LinearPoint3DKeyFrame: t = typeof(System.Windows.Media.Animation.LinearPoint3DKeyFrame); break; + case KnownElements.LinearPointKeyFrame: t = typeof(System.Windows.Media.Animation.LinearPointKeyFrame); break; + case KnownElements.LinearQuaternionKeyFrame: t = typeof(System.Windows.Media.Animation.LinearQuaternionKeyFrame); break; + case KnownElements.LinearRectKeyFrame: t = typeof(System.Windows.Media.Animation.LinearRectKeyFrame); break; + case KnownElements.LinearRotation3DKeyFrame: t = typeof(System.Windows.Media.Animation.LinearRotation3DKeyFrame); break; + case KnownElements.LinearSingleKeyFrame: t = typeof(System.Windows.Media.Animation.LinearSingleKeyFrame); break; + case KnownElements.LinearSizeKeyFrame: t = typeof(System.Windows.Media.Animation.LinearSizeKeyFrame); break; + case KnownElements.LinearThicknessKeyFrame: t = typeof(System.Windows.Media.Animation.LinearThicknessKeyFrame); break; + case KnownElements.LinearVector3DKeyFrame: t = typeof(System.Windows.Media.Animation.LinearVector3DKeyFrame); break; + case KnownElements.LinearVectorKeyFrame: t = typeof(System.Windows.Media.Animation.LinearVectorKeyFrame); break; + case KnownElements.List: t = typeof(System.Windows.Documents.List); break; + case KnownElements.ListBox: t = typeof(System.Windows.Controls.ListBox); break; + case KnownElements.ListBoxItem: t = typeof(System.Windows.Controls.ListBoxItem); break; + case KnownElements.ListCollectionView: t = typeof(System.Windows.Data.ListCollectionView); break; + case KnownElements.ListItem: t = typeof(System.Windows.Documents.ListItem); break; + case KnownElements.ListView: t = typeof(System.Windows.Controls.ListView); break; + case KnownElements.ListViewItem: t = typeof(System.Windows.Controls.ListViewItem); break; + case KnownElements.Localization: t = typeof(System.Windows.Localization); break; + case KnownElements.LostFocusEventManager: t = typeof(System.Windows.LostFocusEventManager); break; + case KnownElements.MarkupExtension: t = typeof(System.Windows.Markup.MarkupExtension); break; + case KnownElements.Material: t = typeof(System.Windows.Media.Media3D.Material); break; + case KnownElements.MaterialCollection: t = typeof(System.Windows.Media.Media3D.MaterialCollection); break; + case KnownElements.MaterialGroup: t = typeof(System.Windows.Media.Media3D.MaterialGroup); break; + case KnownElements.Matrix: t = typeof(System.Windows.Media.Matrix); break; + case KnownElements.Matrix3D: t = typeof(System.Windows.Media.Media3D.Matrix3D); break; + case KnownElements.Matrix3DConverter: t = typeof(System.Windows.Media.Media3D.Matrix3DConverter); break; + case KnownElements.MatrixAnimationBase: t = typeof(System.Windows.Media.Animation.MatrixAnimationBase); break; + case KnownElements.MatrixAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.MatrixAnimationUsingKeyFrames); break; + case KnownElements.MatrixAnimationUsingPath: t = typeof(System.Windows.Media.Animation.MatrixAnimationUsingPath); break; + case KnownElements.MatrixCamera: t = typeof(System.Windows.Media.Media3D.MatrixCamera); break; + case KnownElements.MatrixConverter: t = typeof(System.Windows.Media.MatrixConverter); break; + case KnownElements.MatrixKeyFrame: t = typeof(System.Windows.Media.Animation.MatrixKeyFrame); break; + case KnownElements.MatrixKeyFrameCollection: t = typeof(System.Windows.Media.Animation.MatrixKeyFrameCollection); break; + case KnownElements.MatrixTransform: t = typeof(System.Windows.Media.MatrixTransform); break; + case KnownElements.MatrixTransform3D: t = typeof(System.Windows.Media.Media3D.MatrixTransform3D); break; + case KnownElements.MediaClock: t = typeof(System.Windows.Media.MediaClock); break; + case KnownElements.MediaElement: t = typeof(System.Windows.Controls.MediaElement); break; + case KnownElements.MediaPlayer: t = typeof(System.Windows.Media.MediaPlayer); break; + case KnownElements.MediaTimeline: t = typeof(System.Windows.Media.MediaTimeline); break; + case KnownElements.Menu: t = typeof(System.Windows.Controls.Menu); break; + case KnownElements.MenuBase: t = typeof(System.Windows.Controls.Primitives.MenuBase); break; + case KnownElements.MenuItem: t = typeof(System.Windows.Controls.MenuItem); break; + case KnownElements.MenuScrollingVisibilityConverter: t = typeof(System.Windows.Controls.MenuScrollingVisibilityConverter); break; + case KnownElements.MeshGeometry3D: t = typeof(System.Windows.Media.Media3D.MeshGeometry3D); break; + case KnownElements.Model3D: t = typeof(System.Windows.Media.Media3D.Model3D); break; + case KnownElements.Model3DCollection: t = typeof(System.Windows.Media.Media3D.Model3DCollection); break; + case KnownElements.Model3DGroup: t = typeof(System.Windows.Media.Media3D.Model3DGroup); break; + case KnownElements.ModelVisual3D: t = typeof(System.Windows.Media.Media3D.ModelVisual3D); break; + case KnownElements.ModifierKeysConverter: t = typeof(System.Windows.Input.ModifierKeysConverter); break; + case KnownElements.MouseActionConverter: t = typeof(System.Windows.Input.MouseActionConverter); break; + case KnownElements.MouseBinding: t = typeof(System.Windows.Input.MouseBinding); break; + case KnownElements.MouseDevice: t = typeof(System.Windows.Input.MouseDevice); break; + case KnownElements.MouseGesture: t = typeof(System.Windows.Input.MouseGesture); break; + case KnownElements.MouseGestureConverter: t = typeof(System.Windows.Input.MouseGestureConverter); break; + case KnownElements.MultiBinding: t = typeof(System.Windows.Data.MultiBinding); break; + case KnownElements.MultiBindingExpression: t = typeof(System.Windows.Data.MultiBindingExpression); break; + case KnownElements.MultiDataTrigger: t = typeof(System.Windows.MultiDataTrigger); break; + case KnownElements.MultiTrigger: t = typeof(System.Windows.MultiTrigger); break; + case KnownElements.NameScope: t = typeof(System.Windows.NameScope); break; + case KnownElements.NavigationWindow: t = typeof(System.Windows.Navigation.NavigationWindow); break; + case KnownElements.NullExtension: t = typeof(System.Windows.Markup.NullExtension); break; + case KnownElements.NullableBoolConverter: t = typeof(System.Windows.NullableBoolConverter); break; + case KnownElements.NullableConverter: t = typeof(System.ComponentModel.NullableConverter); break; + case KnownElements.NumberSubstitution: t = typeof(System.Windows.Media.NumberSubstitution); break; + case KnownElements.Object: t = typeof(System.Object); break; + case KnownElements.ObjectAnimationBase: t = typeof(System.Windows.Media.Animation.ObjectAnimationBase); break; + case KnownElements.ObjectAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames); break; + case KnownElements.ObjectDataProvider: t = typeof(System.Windows.Data.ObjectDataProvider); break; + case KnownElements.ObjectKeyFrame: t = typeof(System.Windows.Media.Animation.ObjectKeyFrame); break; + case KnownElements.ObjectKeyFrameCollection: t = typeof(System.Windows.Media.Animation.ObjectKeyFrameCollection); break; + case KnownElements.OrthographicCamera: t = typeof(System.Windows.Media.Media3D.OrthographicCamera); break; + case KnownElements.OuterGlowBitmapEffect: t = typeof(System.Windows.Media.Effects.OuterGlowBitmapEffect); break; + case KnownElements.Page: t = typeof(System.Windows.Controls.Page); break; + case KnownElements.PageContent: t = typeof(System.Windows.Documents.PageContent); break; + case KnownElements.PageFunctionBase: t = typeof(System.Windows.Navigation.PageFunctionBase); break; + case KnownElements.Panel: t = typeof(System.Windows.Controls.Panel); break; + case KnownElements.Paragraph: t = typeof(System.Windows.Documents.Paragraph); break; + case KnownElements.ParallelTimeline: t = typeof(System.Windows.Media.Animation.ParallelTimeline); break; + case KnownElements.ParserContext: t = typeof(System.Windows.Markup.ParserContext); break; + case KnownElements.PasswordBox: t = typeof(System.Windows.Controls.PasswordBox); break; + case KnownElements.Path: t = typeof(System.Windows.Shapes.Path); break; + case KnownElements.PathFigure: t = typeof(System.Windows.Media.PathFigure); break; + case KnownElements.PathFigureCollection: t = typeof(System.Windows.Media.PathFigureCollection); break; + case KnownElements.PathFigureCollectionConverter: t = typeof(System.Windows.Media.PathFigureCollectionConverter); break; + case KnownElements.PathGeometry: t = typeof(System.Windows.Media.PathGeometry); break; + case KnownElements.PathSegment: t = typeof(System.Windows.Media.PathSegment); break; + case KnownElements.PathSegmentCollection: t = typeof(System.Windows.Media.PathSegmentCollection); break; + case KnownElements.PauseStoryboard: t = typeof(System.Windows.Media.Animation.PauseStoryboard); break; + case KnownElements.Pen: t = typeof(System.Windows.Media.Pen); break; + case KnownElements.PerspectiveCamera: t = typeof(System.Windows.Media.Media3D.PerspectiveCamera); break; + case KnownElements.PixelFormat: t = typeof(System.Windows.Media.PixelFormat); break; + case KnownElements.PixelFormatConverter: t = typeof(System.Windows.Media.PixelFormatConverter); break; + case KnownElements.PngBitmapDecoder: t = typeof(System.Windows.Media.Imaging.PngBitmapDecoder); break; + case KnownElements.PngBitmapEncoder: t = typeof(System.Windows.Media.Imaging.PngBitmapEncoder); break; + case KnownElements.Point: t = typeof(System.Windows.Point); break; + case KnownElements.Point3D: t = typeof(System.Windows.Media.Media3D.Point3D); break; + case KnownElements.Point3DAnimation: t = typeof(System.Windows.Media.Animation.Point3DAnimation); break; + case KnownElements.Point3DAnimationBase: t = typeof(System.Windows.Media.Animation.Point3DAnimationBase); break; + case KnownElements.Point3DAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.Point3DAnimationUsingKeyFrames); break; + case KnownElements.Point3DCollection: t = typeof(System.Windows.Media.Media3D.Point3DCollection); break; + case KnownElements.Point3DCollectionConverter: t = typeof(System.Windows.Media.Media3D.Point3DCollectionConverter); break; + case KnownElements.Point3DConverter: t = typeof(System.Windows.Media.Media3D.Point3DConverter); break; + case KnownElements.Point3DKeyFrame: t = typeof(System.Windows.Media.Animation.Point3DKeyFrame); break; + case KnownElements.Point3DKeyFrameCollection: t = typeof(System.Windows.Media.Animation.Point3DKeyFrameCollection); break; + case KnownElements.Point4D: t = typeof(System.Windows.Media.Media3D.Point4D); break; + case KnownElements.Point4DConverter: t = typeof(System.Windows.Media.Media3D.Point4DConverter); break; + case KnownElements.PointAnimation: t = typeof(System.Windows.Media.Animation.PointAnimation); break; + case KnownElements.PointAnimationBase: t = typeof(System.Windows.Media.Animation.PointAnimationBase); break; + case KnownElements.PointAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.PointAnimationUsingKeyFrames); break; + case KnownElements.PointAnimationUsingPath: t = typeof(System.Windows.Media.Animation.PointAnimationUsingPath); break; + case KnownElements.PointCollection: t = typeof(System.Windows.Media.PointCollection); break; + case KnownElements.PointCollectionConverter: t = typeof(System.Windows.Media.PointCollectionConverter); break; + case KnownElements.PointConverter: t = typeof(System.Windows.PointConverter); break; + case KnownElements.PointIListConverter: t = typeof(System.Windows.Media.Converters.PointIListConverter); break; + case KnownElements.PointKeyFrame: t = typeof(System.Windows.Media.Animation.PointKeyFrame); break; + case KnownElements.PointKeyFrameCollection: t = typeof(System.Windows.Media.Animation.PointKeyFrameCollection); break; + case KnownElements.PointLight: t = typeof(System.Windows.Media.Media3D.PointLight); break; + case KnownElements.PointLightBase: t = typeof(System.Windows.Media.Media3D.PointLightBase); break; + case KnownElements.PolyBezierSegment: t = typeof(System.Windows.Media.PolyBezierSegment); break; + case KnownElements.PolyLineSegment: t = typeof(System.Windows.Media.PolyLineSegment); break; + case KnownElements.PolyQuadraticBezierSegment: t = typeof(System.Windows.Media.PolyQuadraticBezierSegment); break; + case KnownElements.Polygon: t = typeof(System.Windows.Shapes.Polygon); break; + case KnownElements.Polyline: t = typeof(System.Windows.Shapes.Polyline); break; + case KnownElements.Popup: t = typeof(System.Windows.Controls.Primitives.Popup); break; + case KnownElements.PresentationSource: t = typeof(System.Windows.PresentationSource); break; + case KnownElements.PriorityBinding: t = typeof(System.Windows.Data.PriorityBinding); break; + case KnownElements.PriorityBindingExpression: t = typeof(System.Windows.Data.PriorityBindingExpression); break; + case KnownElements.ProgressBar: t = typeof(System.Windows.Controls.ProgressBar); break; + case KnownElements.ProjectionCamera: t = typeof(System.Windows.Media.Media3D.ProjectionCamera); break; + case KnownElements.PropertyPath: t = typeof(System.Windows.PropertyPath); break; + case KnownElements.PropertyPathConverter: t = typeof(System.Windows.PropertyPathConverter); break; + case KnownElements.QuadraticBezierSegment: t = typeof(System.Windows.Media.QuadraticBezierSegment); break; + case KnownElements.Quaternion: t = typeof(System.Windows.Media.Media3D.Quaternion); break; + case KnownElements.QuaternionAnimation: t = typeof(System.Windows.Media.Animation.QuaternionAnimation); break; + case KnownElements.QuaternionAnimationBase: t = typeof(System.Windows.Media.Animation.QuaternionAnimationBase); break; + case KnownElements.QuaternionAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.QuaternionAnimationUsingKeyFrames); break; + case KnownElements.QuaternionConverter: t = typeof(System.Windows.Media.Media3D.QuaternionConverter); break; + case KnownElements.QuaternionKeyFrame: t = typeof(System.Windows.Media.Animation.QuaternionKeyFrame); break; + case KnownElements.QuaternionKeyFrameCollection: t = typeof(System.Windows.Media.Animation.QuaternionKeyFrameCollection); break; + case KnownElements.QuaternionRotation3D: t = typeof(System.Windows.Media.Media3D.QuaternionRotation3D); break; + case KnownElements.RadialGradientBrush: t = typeof(System.Windows.Media.RadialGradientBrush); break; + case KnownElements.RadioButton: t = typeof(System.Windows.Controls.RadioButton); break; + case KnownElements.RangeBase: t = typeof(System.Windows.Controls.Primitives.RangeBase); break; + case KnownElements.Rect: t = typeof(System.Windows.Rect); break; + case KnownElements.Rect3D: t = typeof(System.Windows.Media.Media3D.Rect3D); break; + case KnownElements.Rect3DConverter: t = typeof(System.Windows.Media.Media3D.Rect3DConverter); break; + case KnownElements.RectAnimation: t = typeof(System.Windows.Media.Animation.RectAnimation); break; + case KnownElements.RectAnimationBase: t = typeof(System.Windows.Media.Animation.RectAnimationBase); break; + case KnownElements.RectAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.RectAnimationUsingKeyFrames); break; + case KnownElements.RectConverter: t = typeof(System.Windows.RectConverter); break; + case KnownElements.RectKeyFrame: t = typeof(System.Windows.Media.Animation.RectKeyFrame); break; + case KnownElements.RectKeyFrameCollection: t = typeof(System.Windows.Media.Animation.RectKeyFrameCollection); break; + case KnownElements.Rectangle: t = typeof(System.Windows.Shapes.Rectangle); break; + case KnownElements.RectangleGeometry: t = typeof(System.Windows.Media.RectangleGeometry); break; + case KnownElements.RelativeSource: t = typeof(System.Windows.Data.RelativeSource); break; + case KnownElements.RemoveStoryboard: t = typeof(System.Windows.Media.Animation.RemoveStoryboard); break; + case KnownElements.RenderOptions: t = typeof(System.Windows.Media.RenderOptions); break; + case KnownElements.RenderTargetBitmap: t = typeof(System.Windows.Media.Imaging.RenderTargetBitmap); break; + case KnownElements.RepeatBehavior: t = typeof(System.Windows.Media.Animation.RepeatBehavior); break; + case KnownElements.RepeatBehaviorConverter: t = typeof(System.Windows.Media.Animation.RepeatBehaviorConverter); break; + case KnownElements.RepeatButton: t = typeof(System.Windows.Controls.Primitives.RepeatButton); break; + case KnownElements.ResizeGrip: t = typeof(System.Windows.Controls.Primitives.ResizeGrip); break; + case KnownElements.ResourceDictionary: t = typeof(System.Windows.ResourceDictionary); break; + case KnownElements.ResourceKey: t = typeof(System.Windows.ResourceKey); break; + case KnownElements.ResumeStoryboard: t = typeof(System.Windows.Media.Animation.ResumeStoryboard); break; + case KnownElements.RichTextBox: t = typeof(System.Windows.Controls.RichTextBox); break; + case KnownElements.RotateTransform: t = typeof(System.Windows.Media.RotateTransform); break; + case KnownElements.RotateTransform3D: t = typeof(System.Windows.Media.Media3D.RotateTransform3D); break; + case KnownElements.Rotation3D: t = typeof(System.Windows.Media.Media3D.Rotation3D); break; + case KnownElements.Rotation3DAnimation: t = typeof(System.Windows.Media.Animation.Rotation3DAnimation); break; + case KnownElements.Rotation3DAnimationBase: t = typeof(System.Windows.Media.Animation.Rotation3DAnimationBase); break; + case KnownElements.Rotation3DAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.Rotation3DAnimationUsingKeyFrames); break; + case KnownElements.Rotation3DKeyFrame: t = typeof(System.Windows.Media.Animation.Rotation3DKeyFrame); break; + case KnownElements.Rotation3DKeyFrameCollection: t = typeof(System.Windows.Media.Animation.Rotation3DKeyFrameCollection); break; + case KnownElements.RoutedCommand: t = typeof(System.Windows.Input.RoutedCommand); break; + case KnownElements.RoutedEvent: t = typeof(System.Windows.RoutedEvent); break; + case KnownElements.RoutedEventConverter: t = typeof(System.Windows.Markup.RoutedEventConverter); break; + case KnownElements.RoutedUICommand: t = typeof(System.Windows.Input.RoutedUICommand); break; + case KnownElements.RoutingStrategy: t = typeof(System.Windows.RoutingStrategy); break; + case KnownElements.RowDefinition: t = typeof(System.Windows.Controls.RowDefinition); break; + case KnownElements.Run: t = typeof(System.Windows.Documents.Run); break; + case KnownElements.RuntimeNamePropertyAttribute: t = typeof(System.Windows.Markup.RuntimeNamePropertyAttribute); break; + case KnownElements.SByte: t = typeof(System.SByte); break; + case KnownElements.SByteConverter: t = typeof(System.ComponentModel.SByteConverter); break; + case KnownElements.ScaleTransform: t = typeof(System.Windows.Media.ScaleTransform); break; + case KnownElements.ScaleTransform3D: t = typeof(System.Windows.Media.Media3D.ScaleTransform3D); break; + case KnownElements.ScrollBar: t = typeof(System.Windows.Controls.Primitives.ScrollBar); break; + case KnownElements.ScrollContentPresenter: t = typeof(System.Windows.Controls.ScrollContentPresenter); break; + case KnownElements.ScrollViewer: t = typeof(System.Windows.Controls.ScrollViewer); break; + case KnownElements.Section: t = typeof(System.Windows.Documents.Section); break; + case KnownElements.SeekStoryboard: t = typeof(System.Windows.Media.Animation.SeekStoryboard); break; + case KnownElements.Selector: t = typeof(System.Windows.Controls.Primitives.Selector); break; + case KnownElements.Separator: t = typeof(System.Windows.Controls.Separator); break; + case KnownElements.SetStoryboardSpeedRatio: t = typeof(System.Windows.Media.Animation.SetStoryboardSpeedRatio); break; + case KnownElements.Setter: t = typeof(System.Windows.Setter); break; + case KnownElements.SetterBase: t = typeof(System.Windows.SetterBase); break; + case KnownElements.Shape: t = typeof(System.Windows.Shapes.Shape); break; + case KnownElements.Single: t = typeof(System.Single); break; + case KnownElements.SingleAnimation: t = typeof(System.Windows.Media.Animation.SingleAnimation); break; + case KnownElements.SingleAnimationBase: t = typeof(System.Windows.Media.Animation.SingleAnimationBase); break; + case KnownElements.SingleAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.SingleAnimationUsingKeyFrames); break; + case KnownElements.SingleConverter: t = typeof(System.ComponentModel.SingleConverter); break; + case KnownElements.SingleKeyFrame: t = typeof(System.Windows.Media.Animation.SingleKeyFrame); break; + case KnownElements.SingleKeyFrameCollection: t = typeof(System.Windows.Media.Animation.SingleKeyFrameCollection); break; + case KnownElements.Size: t = typeof(System.Windows.Size); break; + case KnownElements.Size3D: t = typeof(System.Windows.Media.Media3D.Size3D); break; + case KnownElements.Size3DConverter: t = typeof(System.Windows.Media.Media3D.Size3DConverter); break; + case KnownElements.SizeAnimation: t = typeof(System.Windows.Media.Animation.SizeAnimation); break; + case KnownElements.SizeAnimationBase: t = typeof(System.Windows.Media.Animation.SizeAnimationBase); break; + case KnownElements.SizeAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.SizeAnimationUsingKeyFrames); break; + case KnownElements.SizeConverter: t = typeof(System.Windows.SizeConverter); break; + case KnownElements.SizeKeyFrame: t = typeof(System.Windows.Media.Animation.SizeKeyFrame); break; + case KnownElements.SizeKeyFrameCollection: t = typeof(System.Windows.Media.Animation.SizeKeyFrameCollection); break; + case KnownElements.SkewTransform: t = typeof(System.Windows.Media.SkewTransform); break; + case KnownElements.SkipStoryboardToFill: t = typeof(System.Windows.Media.Animation.SkipStoryboardToFill); break; + case KnownElements.Slider: t = typeof(System.Windows.Controls.Slider); break; + case KnownElements.SolidColorBrush: t = typeof(System.Windows.Media.SolidColorBrush); break; + case KnownElements.SoundPlayerAction: t = typeof(System.Windows.Controls.SoundPlayerAction); break; + case KnownElements.Span: t = typeof(System.Windows.Documents.Span); break; + case KnownElements.SpecularMaterial: t = typeof(System.Windows.Media.Media3D.SpecularMaterial); break; + case KnownElements.SpellCheck: t = typeof(System.Windows.Controls.SpellCheck); break; + case KnownElements.SplineByteKeyFrame: t = typeof(System.Windows.Media.Animation.SplineByteKeyFrame); break; + case KnownElements.SplineColorKeyFrame: t = typeof(System.Windows.Media.Animation.SplineColorKeyFrame); break; + case KnownElements.SplineDecimalKeyFrame: t = typeof(System.Windows.Media.Animation.SplineDecimalKeyFrame); break; + case KnownElements.SplineDoubleKeyFrame: t = typeof(System.Windows.Media.Animation.SplineDoubleKeyFrame); break; + case KnownElements.SplineInt16KeyFrame: t = typeof(System.Windows.Media.Animation.SplineInt16KeyFrame); break; + case KnownElements.SplineInt32KeyFrame: t = typeof(System.Windows.Media.Animation.SplineInt32KeyFrame); break; + case KnownElements.SplineInt64KeyFrame: t = typeof(System.Windows.Media.Animation.SplineInt64KeyFrame); break; + case KnownElements.SplinePoint3DKeyFrame: t = typeof(System.Windows.Media.Animation.SplinePoint3DKeyFrame); break; + case KnownElements.SplinePointKeyFrame: t = typeof(System.Windows.Media.Animation.SplinePointKeyFrame); break; + case KnownElements.SplineQuaternionKeyFrame: t = typeof(System.Windows.Media.Animation.SplineQuaternionKeyFrame); break; + case KnownElements.SplineRectKeyFrame: t = typeof(System.Windows.Media.Animation.SplineRectKeyFrame); break; + case KnownElements.SplineRotation3DKeyFrame: t = typeof(System.Windows.Media.Animation.SplineRotation3DKeyFrame); break; + case KnownElements.SplineSingleKeyFrame: t = typeof(System.Windows.Media.Animation.SplineSingleKeyFrame); break; + case KnownElements.SplineSizeKeyFrame: t = typeof(System.Windows.Media.Animation.SplineSizeKeyFrame); break; + case KnownElements.SplineThicknessKeyFrame: t = typeof(System.Windows.Media.Animation.SplineThicknessKeyFrame); break; + case KnownElements.SplineVector3DKeyFrame: t = typeof(System.Windows.Media.Animation.SplineVector3DKeyFrame); break; + case KnownElements.SplineVectorKeyFrame: t = typeof(System.Windows.Media.Animation.SplineVectorKeyFrame); break; + case KnownElements.SpotLight: t = typeof(System.Windows.Media.Media3D.SpotLight); break; + case KnownElements.StackPanel: t = typeof(System.Windows.Controls.StackPanel); break; + case KnownElements.StaticExtension: t = typeof(System.Windows.Markup.StaticExtension); break; + case KnownElements.StaticResourceExtension: t = typeof(System.Windows.StaticResourceExtension); break; + case KnownElements.StatusBar: t = typeof(System.Windows.Controls.Primitives.StatusBar); break; + case KnownElements.StatusBarItem: t = typeof(System.Windows.Controls.Primitives.StatusBarItem); break; + case KnownElements.StickyNoteControl: t = typeof(System.Windows.Controls.StickyNoteControl); break; + case KnownElements.StopStoryboard: t = typeof(System.Windows.Media.Animation.StopStoryboard); break; + case KnownElements.Storyboard: t = typeof(System.Windows.Media.Animation.Storyboard); break; + case KnownElements.StreamGeometry: t = typeof(System.Windows.Media.StreamGeometry); break; + case KnownElements.StreamGeometryContext: t = typeof(System.Windows.Media.StreamGeometryContext); break; + case KnownElements.StreamResourceInfo: t = typeof(System.Windows.Resources.StreamResourceInfo); break; + case KnownElements.String: t = typeof(System.String); break; + case KnownElements.StringAnimationBase: t = typeof(System.Windows.Media.Animation.StringAnimationBase); break; + case KnownElements.StringAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.StringAnimationUsingKeyFrames); break; + case KnownElements.StringConverter: t = typeof(System.ComponentModel.StringConverter); break; + case KnownElements.StringKeyFrame: t = typeof(System.Windows.Media.Animation.StringKeyFrame); break; + case KnownElements.StringKeyFrameCollection: t = typeof(System.Windows.Media.Animation.StringKeyFrameCollection); break; + case KnownElements.StrokeCollection: t = typeof(System.Windows.Ink.StrokeCollection); break; + case KnownElements.StrokeCollectionConverter: t = typeof(System.Windows.StrokeCollectionConverter); break; + case KnownElements.Style: t = typeof(System.Windows.Style); break; + case KnownElements.Stylus: t = typeof(System.Windows.Input.Stylus); break; + case KnownElements.StylusDevice: t = typeof(System.Windows.Input.StylusDevice); break; + case KnownElements.TabControl: t = typeof(System.Windows.Controls.TabControl); break; + case KnownElements.TabItem: t = typeof(System.Windows.Controls.TabItem); break; + case KnownElements.TabPanel: t = typeof(System.Windows.Controls.Primitives.TabPanel); break; + case KnownElements.Table: t = typeof(System.Windows.Documents.Table); break; + case KnownElements.TableCell: t = typeof(System.Windows.Documents.TableCell); break; + case KnownElements.TableColumn: t = typeof(System.Windows.Documents.TableColumn); break; + case KnownElements.TableRow: t = typeof(System.Windows.Documents.TableRow); break; + case KnownElements.TableRowGroup: t = typeof(System.Windows.Documents.TableRowGroup); break; + case KnownElements.TabletDevice: t = typeof(System.Windows.Input.TabletDevice); break; + case KnownElements.TemplateBindingExpression: t = typeof(System.Windows.TemplateBindingExpression); break; + case KnownElements.TemplateBindingExpressionConverter: t = typeof(System.Windows.TemplateBindingExpressionConverter); break; + case KnownElements.TemplateBindingExtension: t = typeof(System.Windows.TemplateBindingExtension); break; + case KnownElements.TemplateBindingExtensionConverter: t = typeof(System.Windows.TemplateBindingExtensionConverter); break; + case KnownElements.TemplateKey: t = typeof(System.Windows.TemplateKey); break; + case KnownElements.TemplateKeyConverter: t = typeof(System.Windows.Markup.TemplateKeyConverter); break; + case KnownElements.TextBlock: t = typeof(System.Windows.Controls.TextBlock); break; + case KnownElements.TextBox: t = typeof(System.Windows.Controls.TextBox); break; + case KnownElements.TextBoxBase: t = typeof(System.Windows.Controls.Primitives.TextBoxBase); break; + case KnownElements.TextComposition: t = typeof(System.Windows.Input.TextComposition); break; + case KnownElements.TextCompositionManager: t = typeof(System.Windows.Input.TextCompositionManager); break; + case KnownElements.TextDecoration: t = typeof(System.Windows.TextDecoration); break; + case KnownElements.TextDecorationCollection: t = typeof(System.Windows.TextDecorationCollection); break; + case KnownElements.TextDecorationCollectionConverter: t = typeof(System.Windows.TextDecorationCollectionConverter); break; + case KnownElements.TextEffect: t = typeof(System.Windows.Media.TextEffect); break; + case KnownElements.TextEffectCollection: t = typeof(System.Windows.Media.TextEffectCollection); break; + case KnownElements.TextElement: t = typeof(System.Windows.Documents.TextElement); break; + case KnownElements.TextSearch: t = typeof(System.Windows.Controls.TextSearch); break; + case KnownElements.ThemeDictionaryExtension: t = typeof(System.Windows.ThemeDictionaryExtension); break; + case KnownElements.Thickness: t = typeof(System.Windows.Thickness); break; + case KnownElements.ThicknessAnimation: t = typeof(System.Windows.Media.Animation.ThicknessAnimation); break; + case KnownElements.ThicknessAnimationBase: t = typeof(System.Windows.Media.Animation.ThicknessAnimationBase); break; + case KnownElements.ThicknessAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.ThicknessAnimationUsingKeyFrames); break; + case KnownElements.ThicknessConverter: t = typeof(System.Windows.ThicknessConverter); break; + case KnownElements.ThicknessKeyFrame: t = typeof(System.Windows.Media.Animation.ThicknessKeyFrame); break; + case KnownElements.ThicknessKeyFrameCollection: t = typeof(System.Windows.Media.Animation.ThicknessKeyFrameCollection); break; + case KnownElements.Thumb: t = typeof(System.Windows.Controls.Primitives.Thumb); break; + case KnownElements.TickBar: t = typeof(System.Windows.Controls.Primitives.TickBar); break; + case KnownElements.TiffBitmapDecoder: t = typeof(System.Windows.Media.Imaging.TiffBitmapDecoder); break; + case KnownElements.TiffBitmapEncoder: t = typeof(System.Windows.Media.Imaging.TiffBitmapEncoder); break; + case KnownElements.TileBrush: t = typeof(System.Windows.Media.TileBrush); break; + case KnownElements.TimeSpan: t = typeof(System.TimeSpan); break; + case KnownElements.TimeSpanConverter: t = typeof(System.ComponentModel.TimeSpanConverter); break; + case KnownElements.Timeline: t = typeof(System.Windows.Media.Animation.Timeline); break; + case KnownElements.TimelineCollection: t = typeof(System.Windows.Media.Animation.TimelineCollection); break; + case KnownElements.TimelineGroup: t = typeof(System.Windows.Media.Animation.TimelineGroup); break; + case KnownElements.ToggleButton: t = typeof(System.Windows.Controls.Primitives.ToggleButton); break; + case KnownElements.ToolBar: t = typeof(System.Windows.Controls.ToolBar); break; + case KnownElements.ToolBarOverflowPanel: t = typeof(System.Windows.Controls.Primitives.ToolBarOverflowPanel); break; + case KnownElements.ToolBarPanel: t = typeof(System.Windows.Controls.Primitives.ToolBarPanel); break; + case KnownElements.ToolBarTray: t = typeof(System.Windows.Controls.ToolBarTray); break; + case KnownElements.ToolTip: t = typeof(System.Windows.Controls.ToolTip); break; + case KnownElements.ToolTipService: t = typeof(System.Windows.Controls.ToolTipService); break; + case KnownElements.Track: t = typeof(System.Windows.Controls.Primitives.Track); break; + case KnownElements.Transform: t = typeof(System.Windows.Media.Transform); break; + case KnownElements.Transform3D: t = typeof(System.Windows.Media.Media3D.Transform3D); break; + case KnownElements.Transform3DCollection: t = typeof(System.Windows.Media.Media3D.Transform3DCollection); break; + case KnownElements.Transform3DGroup: t = typeof(System.Windows.Media.Media3D.Transform3DGroup); break; + case KnownElements.TransformCollection: t = typeof(System.Windows.Media.TransformCollection); break; + case KnownElements.TransformConverter: t = typeof(System.Windows.Media.TransformConverter); break; + case KnownElements.TransformGroup: t = typeof(System.Windows.Media.TransformGroup); break; + case KnownElements.TransformedBitmap: t = typeof(System.Windows.Media.Imaging.TransformedBitmap); break; + case KnownElements.TranslateTransform: t = typeof(System.Windows.Media.TranslateTransform); break; + case KnownElements.TranslateTransform3D: t = typeof(System.Windows.Media.Media3D.TranslateTransform3D); break; + case KnownElements.TreeView: t = typeof(System.Windows.Controls.TreeView); break; + case KnownElements.TreeViewItem: t = typeof(System.Windows.Controls.TreeViewItem); break; + case KnownElements.Trigger: t = typeof(System.Windows.Trigger); break; + case KnownElements.TriggerAction: t = typeof(System.Windows.TriggerAction); break; + case KnownElements.TriggerBase: t = typeof(System.Windows.TriggerBase); break; + case KnownElements.TypeExtension: t = typeof(System.Windows.Markup.TypeExtension); break; + case KnownElements.TypeTypeConverter: t = typeof(System.Windows.Markup.TypeTypeConverter); break; + case KnownElements.Typography: t = typeof(System.Windows.Documents.Typography); break; + case KnownElements.UIElement: t = typeof(System.Windows.UIElement); break; + case KnownElements.UInt16: t = typeof(System.UInt16); break; + case KnownElements.UInt16Converter: t = typeof(System.ComponentModel.UInt16Converter); break; + case KnownElements.UInt32: t = typeof(System.UInt32); break; + case KnownElements.UInt32Converter: t = typeof(System.ComponentModel.UInt32Converter); break; + case KnownElements.UInt64: t = typeof(System.UInt64); break; + case KnownElements.UInt64Converter: t = typeof(System.ComponentModel.UInt64Converter); break; + case KnownElements.UShortIListConverter: t = typeof(System.Windows.Media.Converters.UShortIListConverter); break; + case KnownElements.Underline: t = typeof(System.Windows.Documents.Underline); break; + case KnownElements.UniformGrid: t = typeof(System.Windows.Controls.Primitives.UniformGrid); break; + case KnownElements.Uri: t = typeof(System.Uri); break; + case KnownElements.UriTypeConverter: t = typeof(System.UriTypeConverter); break; + case KnownElements.UserControl: t = typeof(System.Windows.Controls.UserControl); break; + case KnownElements.Validation: t = typeof(System.Windows.Controls.Validation); break; + case KnownElements.Vector: t = typeof(System.Windows.Vector); break; + case KnownElements.Vector3D: t = typeof(System.Windows.Media.Media3D.Vector3D); break; + case KnownElements.Vector3DAnimation: t = typeof(System.Windows.Media.Animation.Vector3DAnimation); break; + case KnownElements.Vector3DAnimationBase: t = typeof(System.Windows.Media.Animation.Vector3DAnimationBase); break; + case KnownElements.Vector3DAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.Vector3DAnimationUsingKeyFrames); break; + case KnownElements.Vector3DCollection: t = typeof(System.Windows.Media.Media3D.Vector3DCollection); break; + case KnownElements.Vector3DCollectionConverter: t = typeof(System.Windows.Media.Media3D.Vector3DCollectionConverter); break; + case KnownElements.Vector3DConverter: t = typeof(System.Windows.Media.Media3D.Vector3DConverter); break; + case KnownElements.Vector3DKeyFrame: t = typeof(System.Windows.Media.Animation.Vector3DKeyFrame); break; + case KnownElements.Vector3DKeyFrameCollection: t = typeof(System.Windows.Media.Animation.Vector3DKeyFrameCollection); break; + case KnownElements.VectorAnimation: t = typeof(System.Windows.Media.Animation.VectorAnimation); break; + case KnownElements.VectorAnimationBase: t = typeof(System.Windows.Media.Animation.VectorAnimationBase); break; + case KnownElements.VectorAnimationUsingKeyFrames: t = typeof(System.Windows.Media.Animation.VectorAnimationUsingKeyFrames); break; + case KnownElements.VectorCollection: t = typeof(System.Windows.Media.VectorCollection); break; + case KnownElements.VectorCollectionConverter: t = typeof(System.Windows.Media.VectorCollectionConverter); break; + case KnownElements.VectorConverter: t = typeof(System.Windows.VectorConverter); break; + case KnownElements.VectorKeyFrame: t = typeof(System.Windows.Media.Animation.VectorKeyFrame); break; + case KnownElements.VectorKeyFrameCollection: t = typeof(System.Windows.Media.Animation.VectorKeyFrameCollection); break; + case KnownElements.VideoDrawing: t = typeof(System.Windows.Media.VideoDrawing); break; + case KnownElements.ViewBase: t = typeof(System.Windows.Controls.ViewBase); break; + case KnownElements.Viewbox: t = typeof(System.Windows.Controls.Viewbox); break; + case KnownElements.Viewport3D: t = typeof(System.Windows.Controls.Viewport3D); break; + case KnownElements.Viewport3DVisual: t = typeof(System.Windows.Media.Media3D.Viewport3DVisual); break; + case KnownElements.VirtualizingPanel: t = typeof(System.Windows.Controls.VirtualizingPanel); break; + case KnownElements.VirtualizingStackPanel: t = typeof(System.Windows.Controls.VirtualizingStackPanel); break; + case KnownElements.Visual: t = typeof(System.Windows.Media.Visual); break; + case KnownElements.Visual3D: t = typeof(System.Windows.Media.Media3D.Visual3D); break; + case KnownElements.VisualBrush: t = typeof(System.Windows.Media.VisualBrush); break; + case KnownElements.VisualTarget: t = typeof(System.Windows.Media.VisualTarget); break; + case KnownElements.WeakEventManager: t = typeof(System.Windows.WeakEventManager); break; + case KnownElements.WhitespaceSignificantCollectionAttribute: t = typeof(System.Windows.Markup.WhitespaceSignificantCollectionAttribute); break; + case KnownElements.Window: t = typeof(System.Windows.Window); break; + case KnownElements.WmpBitmapDecoder: t = typeof(System.Windows.Media.Imaging.WmpBitmapDecoder); break; + case KnownElements.WmpBitmapEncoder: t = typeof(System.Windows.Media.Imaging.WmpBitmapEncoder); break; + case KnownElements.WrapPanel: t = typeof(System.Windows.Controls.WrapPanel); break; + case KnownElements.WriteableBitmap: t = typeof(System.Windows.Media.Imaging.WriteableBitmap); break; + case KnownElements.XamlBrushSerializer: t = typeof(System.Windows.Markup.XamlBrushSerializer); break; + case KnownElements.XamlInt32CollectionSerializer: t = typeof(System.Windows.Markup.XamlInt32CollectionSerializer); break; + case KnownElements.XamlPathDataSerializer: t = typeof(System.Windows.Markup.XamlPathDataSerializer); break; + case KnownElements.XamlPoint3DCollectionSerializer: t = typeof(System.Windows.Markup.XamlPoint3DCollectionSerializer); break; + case KnownElements.XamlPointCollectionSerializer: t = typeof(System.Windows.Markup.XamlPointCollectionSerializer); break; + case KnownElements.XamlReader: t = typeof(System.Windows.Markup.XamlReader); break; + case KnownElements.XamlStyleSerializer: t = typeof(System.Windows.Markup.XamlStyleSerializer); break; + case KnownElements.XamlTemplateSerializer: t = typeof(System.Windows.Markup.XamlTemplateSerializer); break; + case KnownElements.XamlVector3DCollectionSerializer: t = typeof(System.Windows.Markup.XamlVector3DCollectionSerializer); break; + case KnownElements.XamlWriter: t = typeof(System.Windows.Markup.XamlWriter); break; + case KnownElements.XmlDataProvider: t = typeof(System.Windows.Data.XmlDataProvider); break; + case KnownElements.XmlLangPropertyAttribute: t = typeof(System.Windows.Markup.XmlLangPropertyAttribute); break; + case KnownElements.XmlLanguage: t = typeof(System.Windows.Markup.XmlLanguage); break; + case KnownElements.XmlLanguageConverter: t = typeof(System.Windows.Markup.XmlLanguageConverter); break; + case KnownElements.XmlNamespaceMapping: t = typeof(System.Windows.Data.XmlNamespaceMapping); break; + case KnownElements.ZoomPercentageConverter: t = typeof(System.Windows.Documents.ZoomPercentageConverter); break; + } + + return t; + } + +#endif // PBTCOMPILER else + } +#endif // !BAMLDASM +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/KnownTypesHelper.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/KnownTypesHelper.cs new file mode 100644 index 00000000000..bd33cfa93b7 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/KnownTypesHelper.cs @@ -0,0 +1,80 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Collections.Generic; +using System.Reflection; +using System.Diagnostics; + +// These are the non-generated parts of the KnownTypes and TypeIndexer classes + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + internal static partial class KnownTypes + { + // Keep Known WCP Types in a private array, accessed through an indexer + private static TypeIndexer _typeIndexer = new TypeIndexer((int)KnownElements.MaxElement); + internal static TypeIndexer Types + { + get + { + return _typeIndexer; + } + } + +#if PBTCOMPILER + internal static void InitializeKnownTypes(Assembly asmFramework, Assembly asmCore, Assembly asmBase) + { + _typeIndexer.Initialize(asmFramework, asmCore, asmBase); + } + + internal static void Clear() + { + _typeIndexer.Clear(); + } +#endif + } + + + + internal partial class TypeIndexer + { + public TypeIndexer(int size) + { + _typeTable =new Type[size]; + } + + public System.Type this[int index] + { + get + { + Type t = _typeTable[index]; + if (t == null) + { + t = InitializeOneType((KnownElements)index); + } + _typeTable[index] = t; + return t; + } + } + +#if PBTCOMPILER + internal void Clear() + { + _initialized = false; + _asmBase = null; + _asmCore = null; + _asmFramework = null; + Array.Clear(_typeTable, 0, _typeTable.Length); + } +#endif + + private Type[] _typeTable; + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/MarkupExtensionParser.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/MarkupExtensionParser.cs new file mode 100644 index 00000000000..0f8fe2b4041 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/MarkupExtensionParser.cs @@ -0,0 +1,1768 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Xml; +using System.IO; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Reflection; +using System.Threading; +using System.Globalization; +using System.Security; +using System.Security.Permissions; +using MS.Utility; +using System.Collections.Specialized; +using System.Runtime.InteropServices; +using MS.Internal.Xaml.Parser; + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + /// + /// MarkupExtension parsing helper that provides things like namespace lookups + /// and type resolution services. This is implemented by classes like XamlReaderHelper + /// and BamlWriter. + /// + internal interface IParserHelper + { + string LookupNamespace(string prefix); + + bool GetElementType( + bool extensionFirst, + string localName, + string namespaceURI, + ref string assemblyName, + ref string typeFullName, + ref Type baseType, + ref Type serializerType); + + bool CanResolveLocalAssemblies(); + } + + + /// + /// MarkupExtension parser class. + /// + internal class MarkupExtensionParser + { + + /// + /// Constructor. + /// + internal MarkupExtensionParser( + IParserHelper parserHelper, + ParserContext parserContext) + { + _parserHelper = parserHelper; + _parserContext = parserContext; + } + + /// + /// Return an intialized AttributeData structure if the attribute value adheres to the + /// format for MarkupExtensions. Otherwise return null. + /// + internal AttributeData IsMarkupExtensionAttribute( + Type declaringType, // Type where propIdName is declared + string propIdName, // Name of the property + ref string attrValue, + int lineNumber, + int linePosition, + int depth, + object info) // PropertyInfo or DependencyProperty or MethodInfo for the property + { + string typeName; + string args; + + if (!GetMarkupExtensionTypeAndArgs(ref attrValue, out typeName, out args)) + { + return null; + } + + return FillAttributeData(declaringType, propIdName, typeName, args, + attrValue, lineNumber, linePosition, depth, info); + } + + /// + /// Return an intialized DefAttributeData structure if the attribute value adheres to the + /// format for MarkupExtensions. Otherwise return null. + /// + internal DefAttributeData IsMarkupExtensionDefAttribute( + Type declaringType, + ref string attrValue, + int lineNumber, + int linePosition, + int depth) + { + string typeName; + string args; + + if (!GetMarkupExtensionTypeAndArgs(ref attrValue, out typeName, out args)) + { + return null; + } + + return FillDefAttributeData(declaringType, typeName, args, attrValue, + lineNumber, linePosition, depth); + + } + + /// + /// Applies some quick checks to see if an Attribute Value is a + /// Markup Extension. This is meant to be much cheaper than the full + /// parse. And this can return true even if the ME has some syntax errors. + /// + internal static bool LooksLikeAMarkupExtension(string attrValue) + { + if (attrValue.Length < 2) + return false; + if (attrValue[0] != '{') + return false; + if (attrValue[1] == '}') + return false; + + return true; + } + +#if !PBTCOMPILER + /// + /// Given a string that is to be treated as a literal string, check + /// to see if it might be mistaken for a markup extension and escape it + /// accordingly. + /// + /// + /// Prefixing the string with "{}" will tell GetMarkupExtensionTypeAndArgs() + /// that the remainder of the string is to be treated literally. + /// + internal static string AddEscapeToLiteralString( string literalString ) + { + string returnString = literalString; + if (!String.IsNullOrEmpty(returnString) && returnString[0] == '{') + { + returnString = "{}" + returnString; + } + + return returnString; + } +#endif + + // Returns an known markup extension that can have a simple value. Also returns the property + // name of the extension that can be used to set the value. This is used to strip it out of + // the args to get the simple value. + private KnownElements GetKnownExtensionFromType(Type extensionType, out string propName) + { + if (KnownTypes.Types[(int)KnownElements.TypeExtension] == extensionType) + { + propName = "TypeName"; + return KnownElements.TypeExtension; + } + else if (KnownTypes.Types[(int)KnownElements.StaticExtension] == extensionType) + { + propName = "Member"; + return KnownElements.StaticExtension; + } + else if (KnownTypes.Types[(int)KnownElements.TemplateBindingExtension] == extensionType) + { + propName = "Property"; + return KnownElements.TemplateBindingExtension; + } + else if (KnownTypes.Types[(int)KnownElements.DynamicResourceExtension] == extensionType) + { + propName = "ResourceKey"; + return KnownElements.DynamicResourceExtension; + } + else if (KnownTypes.Types[(int)KnownElements.StaticResourceExtension] == extensionType) + { + propName = "ResourceKey"; + return KnownElements.StaticResourceExtension; + } + propName = string.Empty; + return 0; + } + + /// + /// Determine if the argument string passed in can represent a valid + /// type in the format + /// prefix:Classname or + /// TypeName = prefix:Classname + /// If so, then change the args string to contain only prefix:Classname and + /// return true. Otherwise, return false. + /// + private bool IsSimpleTypeExtensionArgs( + Type extensionType, + int lineNumber, + int linePosition, + ref string args) + { + if (KnownTypes.Types[(int)KnownElements.TypeExtension] == extensionType) + { + return IsSimpleExtensionArgs(lineNumber, linePosition, "TypeName", ref args, extensionType); + } + + return false; + } + + /// + /// Determine if the argument string passed in can represent a valid + /// param for a MarkuPExtension in one of these formats: + /// prefix:Classname + /// TypeName = prefix:Classname (TypeExtension) + /// prefix:Classname.MemberName + /// Member = prefix:Classname.MemberName (StaticExtension) + /// Property = prefix:Classname.MemberName (TemplateBindingExtension) + /// {x:Type prefix:Classname} + /// {x:Static prefix:Classname.MemberName} + /// StringValue + /// ResourceKey = {x:Type prefix:Classname} (DynamicResourceExtension) + /// ResourceKey = {x:Static prefix:Classname.MemberName} (DynamicResourceExtension) + /// ResourceKey = StringValue (DynamicResourceExtension) + /// If so, then change the args string to contain only the raw value: + /// prefix:Classname or + /// prefix:Classname.MemberName or + /// StringValue + /// and return true. Otherwise, return false. + /// isValueNestedExtension = true, if the args value is itself a StaticExtension or TypeExtension. + /// isValueTypeExtension = true, if the args value is itself a TypeExtension. + /// valueExtensions only apply to DynamicResourceExtension. + /// + private bool IsSimpleExtension( + Type extensionType, + int lineNumber, + int linePosition, + int depth, + out short extensionTypeId, + out bool isValueNestedExtension, + out bool isValueTypeExtension, + ref string args) + { + bool isSimple = false; + string propName; + extensionTypeId = 0; + isValueNestedExtension = false; + isValueTypeExtension = false; + + // if we support optimizing for custom extensions, this can be generalized + // to use a converter\serializer Id for that extension. + KnownElements knownExtensionTypeId = GetKnownExtensionFromType(extensionType, out propName); + + if (knownExtensionTypeId != KnownElements.UnknownElement) + { + isSimple = IsSimpleExtensionArgs(lineNumber, linePosition, propName, ref args, extensionType); + } + + if (isSimple) + { + switch (knownExtensionTypeId) + { + case KnownElements.DynamicResourceExtension: + case KnownElements.StaticResourceExtension: + + if (LooksLikeAMarkupExtension(args)) + { + // if value may be a possible ME, see if it is a simple Type\StaticExtension. + // null is passed for propIdName to indicate this. + AttributeData nestedAttrData = IsMarkupExtensionAttribute(extensionType, + null, + ref args, + lineNumber, + linePosition, + depth, + null); + + isValueTypeExtension = nestedAttrData.IsTypeExtension; + isSimple = isValueTypeExtension || nestedAttrData.IsStaticExtension; + isValueNestedExtension = isSimple; + if (isSimple) + { + // if nested extension value is simple, take the simple args + args = nestedAttrData.Args; + } + else + { + // else restore the original args for normal processing + args += "}"; + } + } + + break; + } + + if (isSimple) + { + extensionTypeId = (short)knownExtensionTypeId; + } + } + + return isSimple; + } + + private bool IsSimpleExtensionArgs(int lineNumber, + int linePosition, + string propName, + ref string args, + Type targetType) + { + // We have a MarkupExtension, so process the argument string to determine + // if it is simple. Do this by tokenizing now and extracting the simple + // type string. + ArrayList tokens = TokenizeAttributes(args, lineNumber, linePosition, targetType); + if (tokens == null) + { + return false; + } + + if (tokens.Count == 1) + { + args = (String)tokens[0]; + return true; + } + + if (tokens.Count == 3 && + (string)tokens[0] == propName) + { + args = (String)tokens[2]; + return true; + } + + return false; + } + + /// + /// Parse the attrValue string into a typename and arguments. Return true if + /// they parse successfully. + /// + /// + /// Localization API also relys on this method to filter markup extensions, as they are not + /// localizable by default. + /// + internal static bool GetMarkupExtensionTypeAndArgs( + ref string attrValue, + out string typeName, + out string args) + { + int length = attrValue.Length; + typeName = string.Empty; + args = string.Empty; + + // MarkupExtensions MUST have '{' as the first character + if (length < 1 || attrValue[0] != '{') + { + return false; + } + + bool gotEscape = false; + StringBuilder stringBuilder = null; + int i = 1; + + for (; i + /// Fill the def attribute data structure with type and attribute string information. + /// Note that this is not for general def attributes, but only for the key attribute + /// used when storing items in an IDictionary. + ///
+ private DefAttributeData FillDefAttributeData( + Type declaringType, // Type where attribute is declared + string typename, + string args, + string attributeValue, + int lineNumber, + int linePosition, + int depth) + { + string namespaceURI; + string targetAssemblyName; + string targetFullName; + Type targetType; + Type serializerType; + bool isSimple = false; + + bool resolvedTag = GetExtensionType(typename, attributeValue, lineNumber, linePosition, + out namespaceURI, out targetAssemblyName, + out targetFullName, out targetType, out serializerType); + + if (resolvedTag) + { + isSimple = IsSimpleTypeExtensionArgs(targetType, + lineNumber, + linePosition, + ref args); + } + + return new DefAttributeData(targetAssemblyName, targetFullName, + targetType, args, declaringType, namespaceURI, + lineNumber, linePosition, depth, isSimple); + } + + // Fill the attribute data structure with type and attribute string information + private AttributeData FillAttributeData( + Type declaringType, // Type where propIdName is declared + string propIdName, // Name of the property + string typename, + string args, + string attributeValue, + int lineNumber, + int linePosition, + int depth, + object info) // PropertyInfo or DependencyProperty or MethodInfo for the property + { + string namespaceURI; + string targetAssemblyName; + string targetFullName; + Type targetType; + Type serializerType; + bool isSimple = false; + short extensionId = 0; + bool isValueNestedExtension = false; + bool isValueTypeExtension = false; + + bool resolvedTag = GetExtensionType(typename, attributeValue, lineNumber, linePosition, + out namespaceURI, out targetAssemblyName, + out targetFullName, out targetType, out serializerType); + + // propIdName is an empty string only for the case when args is a ctor param of a MarkupExtension + if (resolvedTag && propIdName != string.Empty) + { + if (propIdName == null) + { + // If propIdName is null, then we are looking for nested simple extensions and + // we allow only Type\StaticExtension. + if (KnownTypes.Types[(int)KnownElements.TypeExtension] == targetType) + { + isSimple = IsSimpleExtensionArgs(lineNumber, linePosition, "TypeName", ref args, targetType); + isValueNestedExtension = isSimple; + isValueTypeExtension = isSimple; + extensionId = (short)KnownElements.TypeExtension; + } + else if (KnownTypes.Types[(int)KnownElements.StaticExtension] == targetType) + { + isSimple = IsSimpleExtensionArgs(lineNumber, linePosition, "Member", ref args, targetType); + isValueNestedExtension = isSimple; + extensionId = (short)KnownElements.StaticExtension; + } + } + else + { + propIdName = propIdName.Trim(); + + isSimple = IsSimpleExtension(targetType, + lineNumber, + linePosition, + depth, + out extensionId, + out isValueNestedExtension, + out isValueTypeExtension, + ref args); + } + } + + return new AttributeData(targetAssemblyName, targetFullName, + targetType, args, declaringType, propIdName, info, + serializerType, lineNumber, linePosition, depth, namespaceURI, + extensionId, isValueNestedExtension, isValueTypeExtension, isSimple); + } + + private bool GetExtensionType( + string typename, + string attributeValue, + int lineNumber, + int linePosition, + out string namespaceURI, + out string targetAssemblyName, + out string targetFullName, + out Type targetType, + out Type serializerType) + { + targetAssemblyName = null; + targetFullName = null; + targetType = null; + serializerType = null; + + // lookup the type of the target + string fullname = typename; + string prefix = String.Empty; + int typeIndex = typename.IndexOf(':'); + if (typeIndex >= 0) + { + prefix = typename.Substring(0, typeIndex); + typename = typename.Substring(typeIndex + 1); + } + + namespaceURI = _parserHelper.LookupNamespace(prefix); + + bool resolvedTag = _parserHelper.GetElementType(true, typename, namespaceURI, + ref targetAssemblyName, ref targetFullName, ref targetType, ref serializerType); + + if (!resolvedTag) + { + if (_parserHelper.CanResolveLocalAssemblies()) + { + // if local assemblies can be resolved, but the type could not be resolved, then + // we need to throw an exception + ThrowException(SRID.ParserNotMarkupExtension, attributeValue, typename, + namespaceURI, lineNumber, linePosition); + } + else + { + // if local assemblies cannot yet be resolved, we record the data that we will need + // to write an unknown tag start, and note in the data that the type is an unknown + // markup extension. + targetFullName = fullname; + targetType = typeof(UnknownMarkupExtension); + } + } + else if (!KnownTypes.Types[(int)KnownElements.MarkupExtension].IsAssignableFrom(targetType)) + { + // if the type is not known, throw an exception + ThrowException(SRID.ParserNotMarkupExtension, attributeValue, typename, + namespaceURI, lineNumber, linePosition); + } + + return resolvedTag; + } + + /// + /// Fill the attribute data structure with type and attribute string information. + /// Note that this is for general properties and not def attributes. + /// + internal ArrayList CompileAttributes( + ArrayList markupExtensionList, + int startingDepth) + { + ArrayList xamlNodes = new ArrayList(markupExtensionList.Count * 5); + + for (int i = 0; i + /// Create nodes for a complex property that surrounds an element tree. + /// Note that this is for general properties and not def attributes. + ///
+ internal void CompileAttribute( + ArrayList xamlNodes, + AttributeData data) + { + // For MarkupExtension syntax, treat PropertyInfo as a CLR property, but MethodInfo + // and DependencyProperty as a DependencyProperty. Note that the MarkupCompiler + // will handle the case where a DependencyProperty callback is made if it gets + // a MethodInfo for the attached property setter. + string declaringTypeAssemblyName = data.DeclaringType.Assembly.FullName; + string declaringTypeFullName = data.DeclaringType.FullName; + + // Find the PropertyRecordType to use in this case + + Type propertyType; + bool propertyCanWrite; + XamlTypeMapper.GetPropertyType(data.Info, out propertyType, out propertyCanWrite); + BamlRecordType propertyRecordType = BamlRecordManager.GetPropertyStartRecordType(propertyType, propertyCanWrite); + + // Create the property start and end records + + XamlNode propertyStart; + XamlNode propertyEnd; + + switch (propertyRecordType) + { + case BamlRecordType.PropertyArrayStart: + { + propertyStart = new XamlPropertyArrayStartNode( + data.LineNumber, + data.LinePosition, + data.Depth, + data.Info, + declaringTypeAssemblyName, + declaringTypeFullName, + data.PropertyName); + + propertyEnd = new XamlPropertyArrayEndNode( + data.LineNumber, + data.LinePosition, + data.Depth); + break; + } + case BamlRecordType.PropertyIDictionaryStart: + { + propertyStart = new XamlPropertyIDictionaryStartNode( + data.LineNumber, + data.LinePosition, + data.Depth, + data.Info, + declaringTypeAssemblyName, + declaringTypeFullName, + data.PropertyName); + propertyEnd = new XamlPropertyIDictionaryEndNode( + data.LineNumber, + data.LinePosition, + data.Depth); + break; + } + case BamlRecordType.PropertyIListStart: + { + propertyStart = new XamlPropertyIListStartNode( + data.LineNumber, + data.LinePosition, + data.Depth, + data.Info, + declaringTypeAssemblyName, + declaringTypeFullName, + data.PropertyName); + propertyEnd = new XamlPropertyIListEndNode( + data.LineNumber, + data.LinePosition, + data.Depth); + break; + } + default: // PropertyComplexStart + { + propertyStart = new XamlPropertyComplexStartNode( + data.LineNumber, + data.LinePosition, + data.Depth, + data.Info, + declaringTypeAssemblyName, + declaringTypeFullName, + data.PropertyName); + propertyEnd = new XamlPropertyComplexEndNode( + data.LineNumber, + data.LinePosition, + data.Depth); + break; + } + } + + // NOTE: Add duplicate property checking here as is done in XamlReaderHelper + xamlNodes.Add(propertyStart); + + CompileAttributeCore(xamlNodes, data); + + xamlNodes.Add(propertyEnd); + } + + /// + /// Create nodes for an element tree. + /// Note that this is for general properties and not def attributes. + /// + internal void CompileAttributeCore( + ArrayList xamlNodes, + AttributeData data) + { + string typename = null; + string namespaceURI = null; + ArrayList list = TokenizeAttributes(data.Args, data.LineNumber, data.LinePosition, data.TargetType); + + // If the list is empty, or the second item on the list is an equal sign, then + // we have a simple markup extension that uses the default constructor. In all + // other cases we must have at least one constructor parameter. + + if (data.TargetType == typeof(UnknownMarkupExtension)) + { + // If the target type is unknown, then we record an unknown tag start, rather + // than an element start. + typename = data.TargetFullName; + string prefix = String.Empty; + int typeIndex = typename.IndexOf(':'); + if (typeIndex >= 0) + { + prefix = typename.Substring(0, typeIndex); + typename = typename.Substring(typeIndex + 1); + } + + namespaceURI = _parserHelper.LookupNamespace(prefix); + + xamlNodes.Add(new XamlUnknownTagStartNode( + data.LineNumber, + data.LinePosition, + ++data.Depth, + namespaceURI, + typename)); + } + else + { + xamlNodes.Add(new XamlElementStartNode( + data.LineNumber, + data.LinePosition, + ++data.Depth, + data.TargetAssemblyName, + data.TargetFullName, + data.TargetType, + data.SerializerType)); + } + + xamlNodes.Add(new XamlEndAttributesNode( + data.LineNumber, + data.LinePosition, + data.Depth, + true)); + int listIndex = 0; + if (list != null && + (list.Count == 1 || + (list.Count > 1 && !(list[1] is String) && ((Char)list[1] == ',')))) + { + // Go through the constructor parameters, writing them out like complex + // properties + WriteConstructorParams(xamlNodes, list, data, ref listIndex); + } + + // Write properties that come after the element constructor parameters + WriteProperties(xamlNodes, list, listIndex, data); + + // close up + if (data.TargetType == typeof(UnknownMarkupExtension)) + { + xamlNodes.Add(new XamlUnknownTagEndNode( + data.LineNumber, + data.LinePosition, + data.Depth--, + typename, + namespaceURI)); + } + else + { + xamlNodes.Add(new XamlElementEndNode( + data.LineNumber, + data.LinePosition, + data.Depth--)); + } + } + + /// + /// Parse the string representation of a set of def attributes in MarkupExtension + /// syntax and return a list of xaml nodes that represents those attributes. + /// + internal ArrayList CompileDictionaryKeys( + ArrayList complexDefAttributesList, + int startingDepth) + { + ArrayList xamlNodes = new ArrayList(complexDefAttributesList.Count * 5); + for (int i = 0; i + /// Parse the string representation of a set of def attributes in MarkupExtension + /// syntax and return a list of xaml nodes that represents those attributes. + /// + internal void CompileDictionaryKey( + ArrayList xamlNodes, + DefAttributeData data) + { + ArrayList list = TokenizeAttributes(data.Args, data.LineNumber, data.LinePosition, data.TargetType); + + // If the list is empty, or the second item on the list is an equal sign, then + // we have a simple markup extension that uses the default constructor. In all + // other cases we must have at least one constructor parameter. + xamlNodes.Add(new XamlKeyElementStartNode( + data.LineNumber, + data.LinePosition, + ++data.Depth, + data.TargetAssemblyName, + data.TargetFullName, + data.TargetType, + null)); + xamlNodes.Add(new XamlEndAttributesNode( + data.LineNumber, + data.LinePosition, + data.Depth, + true)); + int listIndex = 0; + if (list != null && + (list.Count == 1 || + (list.Count > 1 && !(list[1] is String) && ((Char)list[1] == ',')))) + { + // Go through the constructor parameters, writing them out like complex + // properties + WriteConstructorParams(xamlNodes, list, data, ref listIndex); + } + + // Write properties that come after the element constructor parameters + WriteProperties(xamlNodes, list, listIndex, data); + + // close up + xamlNodes.Add(new XamlKeyElementEndNode( + data.LineNumber, + data.LinePosition, + data.Depth--)); + + } + + /// + /// The core method that writes out the MarkupExtension itself without the surrounding + /// contextual xaml nodes. + /// The format of compact syntax is + /// "{typename constParam1, constParam2, name = value, name = value, ... }" + /// (whitespace is ignored near delimiters). The effect of this is to + /// create a new object of the given type, using the provided constructor + /// parameters. If they are absent, use the default constructor. Then to set + /// its properties. Each name=value pair causes a property + /// with the given name to be set to the given value (after type conversion). + /// + /// For constructor parameters, or on right-hand side of the = sign, some + /// characters are treated specially: + /// \ - escape charater - quotes the following character (including \) + /// , - terminates the clause + /// {} - matching braces, meaning a nested MarkupExtension + /// '' - matching single quotes + /// "" - matching double quotes + /// Inside matching delimiters, comma has no special meaning and + /// delimiters must nest correctly (unless escaped). Inside matching + /// quotes (either kind), no characters are special except \. + /// + /// If the string really is in "MarkupExtension syntax" form, return true. + /// + /// Exceptions are thrown for mismatching delimiters, and for errors while + /// assigning to properties. + /// Major changes in 4.6.2 : + /// MarkupExtensionBracketCharacterAttributes : Specified on a particular markup extension property, + /// these can be a pair of special characters (like (), [] etc). Anything enclosed inside these characters + /// has no special meaning, except \ and other such MarkupExtensionBracketCharacters themselves. + /// + private ArrayList TokenizeAttributes ( + string args, + int lineNumber, + int linePosition, + Type extensionType) + { + // As a result of having to rely on Reflection to find whether a property has a MarkupExtensionBracketCharacterAttribute + // set on it, we can't parse a locally defined Markup Extension in MarkupCompilePass1. Therefore, if we find an UnknownExtension + // here, we just return null. If this was MarkupCompilePass2 and the extension was still unknown, it would have errored out by now + // already. + + if (extensionType == typeof (UnknownMarkupExtension)) + { + return null; + } + + int maxConstructorParams = 0; + ParameterInfo[] constructorParameters = FindLongestConstructor(extensionType, out maxConstructorParams); + + Dictionary bracketCharacterCache = _parserContext.InitBracketCharacterCacheForType(extensionType); + Stack bracketCharacterStack = new Stack(); + int currentConstructorParam = 0; + bool inCtorParsingMode = constructorParameters != null && maxConstructorParams > 0; + bool inBracketCharacterMode = false; + + ArrayList list = null; + int length = args.Length; + bool inQuotes = false; + bool gotEscape = false; + bool nonWhitespaceFound = false; + bool gotFinalCloseCurly = false; + Char quoteChar = '\''; + int leftCurlies = 0; + StringBuilder stringBuilder = null; + int i = 0; + string parameterName = null; + SpecialBracketCharacters bracketCharacters = null; + if (inCtorParsingMode && bracketCharacterCache != null) + { + parameterName = maxConstructorParams > 0 ? constructorParameters[currentConstructorParam].Name : null; + if (!string.IsNullOrEmpty(parameterName)) + { + bracketCharacters = GetBracketCharacterForProperty(parameterName, bracketCharacterCache); + } + } + + // Loop through the args, creating a list of arguments and known delimiters. + // This loop does limited syntax checking, and serves to tokenize the argument + // string into chunks that are validated in greater detail in the next phase. + for (i=0; i < length && !gotFinalCloseCurly; i++) + { + // Escape character is always in effect for everything inside + // a MarkupExtension. We have to remember that the next character is + // escaped, and is not treated as a quote or delimiter. + if (!gotEscape && args[i] == '\\') + { + gotEscape = true; + continue; + } + + if (!nonWhitespaceFound && !Char.IsWhiteSpace(args[i])) + { + nonWhitespaceFound = true; + } + + // Process all characters that are not whitespace or are between quotes + if (inQuotes || leftCurlies > 0 || nonWhitespaceFound) + { + // We have a non-whitespace character, so ensure we have + // a string builder to accumulate characters and a list to collect + // attributes and delimiters. These are lazily + // created so that simple cases that have no parameters do not + // create any extra objects. + if (stringBuilder == null) + { + stringBuilder = new StringBuilder(length); + list = new ArrayList(1); + } + + // If the character is escaped, then it is part of the attribute + // being collected, regardless of its value and is not treated as + // a delimiter or special character. Write back the escape + // character since downstream processing will need it to determine + // whether the value is a MarkupExtension or not, and to prevent + // multiple escapes from being lost by recursive processing. + if (gotEscape) + { + stringBuilder.Append('\\'); + stringBuilder.Append(args[i]); + gotEscape = false; + continue; + } + + // If quoted or inside curlies then scoop up everything. + // Track yet deeper nestings of curlies. + if (inQuotes || leftCurlies > 0) + { + if (inQuotes && args[i] == quoteChar) + { + // If we're inside quotes, then only an end quote that is not + // escaped is special, and will act as a delimiter. + inQuotes = false; + nonWhitespaceFound = false; + + // Don't trim leading and trailing spaces that were inside quotes. + AddToTokenList(list, stringBuilder, false); + } + else + { + if (leftCurlies > 0 && args[i] == '}') + { + leftCurlies--; + } + else if (args[i] == '{') + { + leftCurlies++; + } + stringBuilder.Append(args[i]); + } + } + // If we are inside of MarkupExtensionBracketCharacters for a particular property or position parameter, + // scoop up everything inside one by one, and keep track of nested Bracket Characters in the stack. + else if (inBracketCharacterMode) + { + stringBuilder.Append(args[i]); + if (bracketCharacters.StartsEscapeSequence(args[i])) + { + bracketCharacterStack.Push(args[i]); + } + else if (bracketCharacters.EndsEscapeSequence(args[i])) + { + if (bracketCharacters.Match(bracketCharacterStack.Peek(), args[i])) + { + bracketCharacterStack.Pop(); + } + else + { + ThrowException(SRID.ParserMarkupExtensionInvalidClosingBracketCharacers, args[i].ToString(), lineNumber, linePosition); + } + } + + if (bracketCharacterStack.Count == 0) + { + inBracketCharacterMode = false; + } + } + else // not in quotes or inside nested curlies. Parse the Tokens + { // not in special escape mode either + switch(args[i]) + { + case '"': + case '\'': + // If we're not inside quotes, then a start quote can only + // occur as the first non-whitespace character in a name or value. + if (stringBuilder.Length != 0) + { + ThrowException(SRID.ParserMarkupExtensionNoQuotesInName, args, + lineNumber, linePosition); + } + inQuotes = true; + quoteChar = args[i]; + break; + + case ',': + case '=': + if (inCtorParsingMode && args[i] == ',') + { + inCtorParsingMode = ++currentConstructorParam < maxConstructorParams; + if (inCtorParsingMode) + { + parameterName = constructorParameters[currentConstructorParam].Name; + bracketCharacters = GetBracketCharacterForProperty(parameterName, bracketCharacterCache); + } + } + + // If we have a token in the stringbuilder, then store it + if (stringBuilder != null && stringBuilder.Length > 0) + { + AddToTokenList(list, stringBuilder, true); + if (bracketCharacterStack.Count != 0) + { + ThrowException(SRID.ParserMarkupExtensionMalformedBracketCharacers, bracketCharacterStack.Peek().ToString(), lineNumber, linePosition); + } + } + else if (list.Count == 0) + { + // Must have an attribute before you have the first delimeter + ThrowException(SRID.ParserMarkupExtensionDelimiterBeforeFirstAttribute, args, + lineNumber, linePosition); + } + else if (list[list.Count - 1] is Char) + { + // Can't have two delimiters in a row, so check what is on + // the list and complain if the last item is a character, or if + // a delimiter is the first item. + ThrowException(SRID.ParserMarkupExtensionBadDelimiter, args, + lineNumber, linePosition); + + } + + if (args[i] == '=') + { + inCtorParsingMode = false; + // find BracketCharacterAttribute for the property name that preceeded this = delimiter + parameterName = (string) list[list.Count - 1]; + bracketCharacters = GetBracketCharacterForProperty(parameterName, bracketCharacterCache); + } + + // Append known delimiters. + list.Add(args[i]); + nonWhitespaceFound = false; + break; + + case '}': + // If we hit the outside right curly brace, then end processing. If + // there is a delimiter on the top of the stack and we haven't + // hit another non-whitespace character, then its an error + gotFinalCloseCurly = true; + if (stringBuilder != null) + { + if (stringBuilder.Length > 0) + { + AddToTokenList(list, stringBuilder, true); + } + else if (list.Count > 0 && (list[list.Count-1] is Char)) + { + ThrowException(SRID.ParserMarkupExtensionBadDelimiter, args, + lineNumber, linePosition); + } + } + break; + + case '{': + leftCurlies++; + stringBuilder.Append(args[i]); + break; + + default: + if (bracketCharacters != null && bracketCharacters.StartsEscapeSequence(args[i])) + { + bracketCharacterStack.Clear(); + bracketCharacterStack.Push(args[i]); + inBracketCharacterMode = true; + } + + // Must just be a plain old character, so add it to the stringbuilder + stringBuilder.Append(args[i]); + break; + } + } + } + } + + + // If we've accumulated content but haven't hit a terminating '}' then the + // format is bad, so complain. + if (!gotFinalCloseCurly) + { + ThrowException(SRID.ParserMarkupExtensionNoEndCurlie, "}", lineNumber, linePosition); + } + // If there is junk after the closing '}', complain + else if (i < length) + { + ThrowException(SRID.ParserMarkupExtensionTrailingGarbage, "}", + args.Substring(i,length-(i)), lineNumber, linePosition); + } + + return list; + } + + + private static void AddToTokenList(ArrayList list, StringBuilder sb, bool trim) + { + if(trim) + { + Debug.Assert(sb.Length > 0); + Debug.Assert(!Char.IsWhiteSpace(sb[0])); + + int i = sb.Length-1; + while(Char.IsWhiteSpace(sb[i])) + --i; + sb.Length = i+1; + } + list.Add(sb.ToString()); + sb.Length = 0; + } + + /// + /// Returns the list of parameters of the constructor with the most number + /// of arguments. + /// + private ParameterInfo[] FindLongestConstructor(Type extensionType, out int maxConstructorArguments) + { + ParameterInfo[] constructorParameters = null; + ConstructorInfo[] constructors = extensionType.GetConstructors(BindingFlags.Public | BindingFlags.Instance); + maxConstructorArguments = 0; + foreach (ConstructorInfo ctor in constructors) + { + ParameterInfo[] parInfo = ctor.GetParameters(); + if (parInfo.Length >= maxConstructorArguments) + { + maxConstructorArguments = parInfo.Length; + constructorParameters = parInfo; + } + } + + return constructorParameters; + } + + /// + /// At this point the start element is written, and we have to process all + /// the constructor parameters that follow. Stop when we hit the first + /// name=value, or when the end of the attributes is reached. + /// + private void WriteConstructorParams( + ArrayList xamlNodes, + ArrayList list, + DefAttributeData data, + ref int listIndex) + { +#if PBTCOMPILER + int numberOfConstructorAttributes = 0; +#endif + + if (list != null && listIndex < list.Count) + { + // Mark the start of the constructor parameter section. Nodes directly + // under this one are constructor parameters. Note that we can have + // element trees under here. + xamlNodes.Add(new XamlConstructorParametersStartNode( + data.LineNumber, + data.LinePosition, + ++data.Depth)); + + for (; listIndex < list.Count; listIndex+=2) + { + if (!(list[listIndex] is String)) + { + ThrowException(SRID.ParserMarkupExtensionBadConstructorParam, data.Args, + data.LineNumber, data.LinePosition); + } + + // If the next item after the current one is '=', then we've hit the + // start of named parameters, so stop + if (list.Count > (listIndex+1) && + list[listIndex+1] is Char && + (Char)list[listIndex+1] == '=') + { + break; + } + +#if PBTCOMPILER + numberOfConstructorAttributes++; +#endif + + // Handle nested markup extensions by recursing here. If the + // value is not a markup extension, just store it as text for + // runtime resolution as a constructor parameter. + string value = (String)list[listIndex]; + AttributeData nestedData = IsMarkupExtensionAttribute(data.DeclaringType, + string.Empty, + ref value, + data.LineNumber, + data.LinePosition, + data.Depth, + null); + if (nestedData == null) + { + RemoveEscapes(ref value); + + xamlNodes.Add(new XamlTextNode( + data.LineNumber, + data.LinePosition, + data.Depth, + value, + null)); + } + else + { + CompileAttributeCore(xamlNodes, nestedData); + } + } + + // End of constructor parameter section. + xamlNodes.Add(new XamlConstructorParametersEndNode( + data.LineNumber, + data.LinePosition, + data.Depth--)); + +#if PBTCOMPILER + if (data.TargetType != typeof(UnknownMarkupExtension)) + { + // For compile mode, check that there is a constructor with the correct + // number of arguments. In xaml load scenarios, the BamlRecordReader + // will do this, so don't bother doing it here. If the target type is + // unknown, then we defer this check until it can be resolved. + + ConstructorInfo[] infos = data.TargetType.GetConstructors(BindingFlags.Public | BindingFlags.Instance); + for (int i=0; i + /// At this point the start element is created and all the constructor params + /// have been processed. Now handle the name=value pairs as property sets. + /// If we have used a regular start element record, then just use regular + /// properties. + /// + + private void WriteProperties( + ArrayList xamlNodes, + ArrayList list, + int listIndex, + DefAttributeData data) + { + if (list != null && listIndex < list.Count) + { + ArrayList propertyNamesSoFar = new ArrayList(list.Count/4); + + for (int k = listIndex; k < list.Count; k+=4) + { + if (k > (list.Count-3) || + (list[k+1] is String) || + ((Char)list[k+1]) != '=') + { + ThrowException(SRID.ParserMarkupExtensionNoNameValue, data.Args, + data.LineNumber, data.LinePosition); + } + + + // See if this is a duplicate property definition, and throw if it is. + + string propertyName = list[k] as String; + propertyName = propertyName.Trim(); + + if (propertyNamesSoFar.Contains(propertyName)) + { + ThrowException(SRID.ParserDuplicateMarkupExtensionProperty, propertyName, data.LineNumber, data.LinePosition); + } + propertyNamesSoFar.Add( propertyName ); + + // Fetch the property context + + int nameIndex = propertyName.IndexOf(':'); + string localName = (nameIndex < 0) ? propertyName : propertyName.Substring(nameIndex+1); + string prefix = (nameIndex < 0) ? String.Empty : propertyName.Substring(0, nameIndex); + + string attribNamespaceURI = ResolveAttributeNamespaceURI(prefix, localName, data.TargetNamespaceUri); + + object dynamicObject; + string assemblyName; + string typeFullName; + Type declaringType; + string dynamicObjectName; + + AttributeContext attributeContext = GetAttributeContext( + data.TargetType, + data.TargetNamespaceUri, + attribNamespaceURI, + localName, + out dynamicObject, + out assemblyName, + out typeFullName, + out declaringType, + out dynamicObjectName); + + // Handle nested markup extensions by recursing here. If the + // value is not a markup extension, just store it as text for + // runtime resolution. + string strValue = list[k+2] as String; + AttributeData nestedAttrData = IsMarkupExtensionAttribute( + data.TargetType, + propertyName, + ref strValue, + data.LineNumber, + data.LinePosition, + data.Depth, + dynamicObject); + + list[k+2] = strValue; + if (data.IsUnknownExtension) + { + // For unknown extensions, no more work should be done. + // In pass1, we don't yet have the context to make sense of the nested properties, + // so recursing into them would lead to spurious parse errors. + // In pass2 an unknown extension would have errored out before getting here. + return; + } + + if (nestedAttrData != null) + { + if (nestedAttrData.IsSimple) + { + CompileProperty(xamlNodes, + propertyName, + nestedAttrData.Args, + data.TargetType, + data.TargetNamespaceUri, // xmlns of TargetType + nestedAttrData, + nestedAttrData.LineNumber, + nestedAttrData.LinePosition, + nestedAttrData.Depth); + } + else + { + // NOTE: Consider checking validity of property by calling GetAttributeContext here. + CompileAttribute(xamlNodes, nestedAttrData); + } + } + else + { + CompileProperty(xamlNodes, + propertyName, + ((String)list[k+2]), + data.TargetType, + data.TargetNamespaceUri, // xmlns of TargetType + null, + data.LineNumber, + data.LinePosition, + data.Depth); + } + } + } + } + + private string ResolveAttributeNamespaceURI(string prefix, string name, string parentURI) + { + string attribNamespaceURI; + if(!String.IsNullOrEmpty(prefix)) + { + attribNamespaceURI = _parserHelper.LookupNamespace(prefix); + } + else + { + // if the prefix was "" then + // 1) normal properties resolve to the parent Tag namespace. + // 2) Attached properties resolve to the "" default namespace. + int dotIndex = name.IndexOf('.'); + if (-1 == dotIndex) + attribNamespaceURI = parentURI; + else + attribNamespaceURI = _parserHelper.LookupNamespace(""); + } + return attribNamespaceURI; + } + + /// + /// Looks up the already constructed BracketCharacter cache for the BracketCharacters on + /// the given property. + /// + private SpecialBracketCharacters GetBracketCharacterForProperty(string propertyName, Dictionary bracketCharacterCache) + { + SpecialBracketCharacters bracketCharacters = null; + if (bracketCharacterCache != null && bracketCharacterCache.ContainsKey(propertyName)) + { + bracketCharacters = bracketCharacterCache[propertyName]; + } + + return bracketCharacters; + } + + /// + /// Represent a single property for a MarkupExtension as a complex property. + /// + private void CompileProperty( + ArrayList xamlNodes, + string name, + string value, + Type parentType, + string parentTypeNamespaceUri, + AttributeData data, + int lineNumber, + int linePosition, + int depth) + { + RemoveEscapes(ref name); + RemoveEscapes(ref value); + + int nameIndex = name.IndexOf(':'); + string localName = (nameIndex < 0) ? name : name.Substring(nameIndex+1); + string prefix = (nameIndex < 0) ? String.Empty : name.Substring(0, nameIndex); + string attribNamespaceURI = ResolveAttributeNamespaceURI(prefix, localName, parentTypeNamespaceUri); + + object dynamicObject; + string assemblyName; + string typeFullName; + Type declaringType; + string dynamicObjectName; + + if (String.IsNullOrEmpty(attribNamespaceURI)) + { + ThrowException(SRID.ParserPrefixNSProperty, prefix, name, lineNumber, linePosition); + } + + AttributeContext attributeContext = GetAttributeContext( + parentType, + parentTypeNamespaceUri, + attribNamespaceURI, + localName, + out dynamicObject, + out assemblyName, + out typeFullName, + out declaringType, + out dynamicObjectName); + + if (attributeContext != AttributeContext.Property) + { + ThrowException(SRID.ParserMarkupExtensionUnknownAttr, localName, + parentType.FullName, lineNumber, linePosition); + } + + MemberInfo info = dynamicObject as MemberInfo; + + Debug.Assert(null != info, "No property or method info for field Name"); + + if (data != null && data.IsSimple) + { + if (data.IsTypeExtension) + { + string typeValueFullName = value; // set this to original value for error reporting if reqd. + string typeValueAssemblyFullName = null; + Type typeValue = _parserContext.XamlTypeMapper.GetTypeFromBaseString(value, + _parserContext, + true); + if (typeValue != null) + { + typeValueFullName = typeValue.FullName; + typeValueAssemblyFullName = typeValue.Assembly.FullName; + } + + XamlPropertyWithTypeNode xamlPropertyWithTypeNode = + new XamlPropertyWithTypeNode(data.LineNumber, + data.LinePosition, + data.Depth, + dynamicObject, + assemblyName, + typeFullName, + localName, + typeValueFullName, + typeValueAssemblyFullName, + typeValue, + string.Empty, + string.Empty); + + xamlNodes.Add(xamlPropertyWithTypeNode); + } + else + { + XamlPropertyWithExtensionNode xamlPropertyWithExtensionNode = + new XamlPropertyWithExtensionNode(data.LineNumber, + data.LinePosition, + data.Depth, + dynamicObject, + assemblyName, + typeFullName, + localName, + value, + data.ExtensionTypeId, + data.IsValueNestedExtension, + data.IsValueTypeExtension); + + xamlNodes.Add(xamlPropertyWithExtensionNode); + } + } + else + { + XamlPropertyNode xamlPropertyNode = + new XamlPropertyNode(lineNumber, + linePosition, + depth, + dynamicObject, + assemblyName, + typeFullName, + dynamicObjectName, + value, + BamlAttributeUsage.Default, + true); + + xamlNodes.Add(xamlPropertyNode); + } + } + + /// + /// Remove any '\' escape characters from the passed string. This does a simple + /// pass through the string and won't do anything if there are no '\' characters. + /// + internal static void RemoveEscapes(ref string value) + { + StringBuilder builder=null; + bool noEscape = true; + for (int i = 0; i < value.Length; i++) + { + if (noEscape && value[i] == '\\') + { + if (builder == null) + { + builder = new StringBuilder(value.Length); + builder.Append(value.Substring(0,i)); + } + noEscape = false; + } + else if (builder != null) + { + builder.Append(value[i]); + noEscape = true; + } + } + + if (builder != null) + { + value = builder.ToString(); + } + } + + /// + /// Get property information for an attribute in a MarkupExtension. This is + /// very similar code to what is done in XamlReaderHelper, but we only look for clr + /// properties here, since MarkupExtensions don't support events or + /// DependencyProperties. + /// + AttributeContext GetAttributeContext( + Type elementBaseType, + string elementBaseTypeNamespaceUri, + string attributeNamespaceUri, + string attributeLocalName, + out Object dynamicObject, // resolved object. + out string assemblyName, // assemblyName the declaringType is found in + out string typeFullName, // typeFullName of the object that the field is on + out Type declaringType, // type of the object that the field is on + out string dynamicObjectName) // name of the dynamicObject if found one + { + AttributeContext attributeContext = AttributeContext.Unknown; + + dynamicObject = null; + assemblyName = null; + typeFullName = null; + declaringType = null; + dynamicObjectName = null; + + // First, check if this is a CLR property using Static setter name + // matching or property info lookups on element base type. + MemberInfo mi = _parserContext.XamlTypeMapper.GetClrInfo(false, + elementBaseType, + attributeNamespaceUri, + attributeLocalName, + ref dynamicObjectName); + + if (null != mi) + { + attributeContext = AttributeContext.Property; + dynamicObject = mi; + declaringType = mi.DeclaringType; + typeFullName = declaringType.FullName; + assemblyName = declaringType.Assembly.FullName; + } + + return attributeContext; + } + + /// + /// Throw a XamlParseException + /// + void ThrowException( + string id, + string parameter1, + int lineNumber, + int linePosition) + { + string message = SR.Get(id, parameter1); + ThrowExceptionWithLine(message, lineNumber, linePosition); + } + + /// + /// Throw a XamlParseException + /// + void ThrowException( + string id, + string parameter1, + string parameter2, + int lineNumber, + int linePosition) + { + string message = SR.Get(id, parameter1, parameter2); + ThrowExceptionWithLine(message, lineNumber, linePosition); + } + + /// + /// Throw a XamlParseException + /// + void ThrowException( + string id, + string parameter1, + string parameter2, + string parameter3, + int lineNumber, + int linePosition) + { + string message = SR.Get(id, parameter1, parameter2, parameter3); + ThrowExceptionWithLine(message, lineNumber, linePosition); + } + + /// + /// Throw a XamlParseException + /// + void ThrowExceptionWithLine( + string message, + int lineNumber, + int linePosition) + { + message += " "; + message += SR.Get(SRID.ParserLineAndOffset, + lineNumber.ToString(CultureInfo.CurrentCulture), + linePosition.ToString(CultureInfo.CurrentCulture)); + + XamlParseException parseException = new XamlParseException(message, + lineNumber, linePosition); + + throw parseException; + } + + // Helper that provices namespace and type resolutions + private IParserHelper _parserHelper; + + // Parser Context for the current node being parsed. + private ParserContext _parserContext; + + internal class UnknownMarkupExtension + { + } + } + +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserContext.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserContext.cs new file mode 100644 index 00000000000..6d9e392c456 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserContext.cs @@ -0,0 +1,990 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//--------------------------------------------------------------------------- +// +// Description: +// class for the main TypeConverterContext object passed to type converters +// +//--------------------------------------------------------------------------- + +using System; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Xml; +using MS.Utility; +using System.Diagnostics; +using MS.Internal.Xaml.Parser; + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +using System.Windows; +using System.Security; +using MS.Internal; + +namespace System.Windows.Markup +#endif +{ + +#if PBTCOMPILER + + /// + /// The IUriContext interface allows elements (like Frame, PageViewer) and type converters + /// (like BitmapImage TypeConverters) a way to ensure that base uri is set on them by the + /// parser, codegen for xaml, baml and caml cases. The elements can then use this base uri + /// to navigate. + /// + internal interface IUriContext + { + /// + /// Provides the base uri of the current context. + /// + Uri BaseUri + { + get; + set; + } + } + +#endif + + /// + /// Provides all the context information required by Parser + /// +#if PBTCOMPILER + internal class ParserContext : IUriContext +#else + public class ParserContext : IUriContext +#endif + { + +#region Public Methods + + /// + /// Constructor + /// + public ParserContext() + { + Initialize(); + } + + // Initialize the ParserContext to a known, default state. DO NOT wipe out + // data that may be able to be shared between seperate parses, such as the + // xamlTypeMapper and the map table. + internal void Initialize() + { + _xmlnsDictionary = null; // created on its first use +#if !PBTCOMPILER + _nameScopeStack = null; +#endif + _xmlLang = String.Empty; + _xmlSpace = String.Empty; + } + + +#if !PBTCOMPILER + /// + /// Constructor that takes the XmlParserContext. + /// A parserContext object will be built based on this. + /// + /// xmlParserContext to use + + public ParserContext(XmlParserContext xmlParserContext) + { + if (xmlParserContext == null) + { + throw new ArgumentNullException( "xmlParserContext" ); + } + + _xmlLang = xmlParserContext.XmlLang; + + TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(XmlSpace)); + if (typeConverter != null) + _xmlSpace = (string) typeConverter.ConvertToString(null, TypeConverterHelper.InvariantEnglishUS, xmlParserContext.XmlSpace); + else + _xmlSpace = String.Empty; + + _xmlnsDictionary = new XmlnsDictionary() ; + + if (xmlParserContext.BaseURI != null && xmlParserContext.BaseURI.Length > 0) + { + _baseUri = new Uri(xmlParserContext.BaseURI, UriKind.RelativeOrAbsolute); + } + + XmlNamespaceManager xmlnsManager = xmlParserContext.NamespaceManager; + + if (null != xmlnsManager) + { + foreach (string key in xmlnsManager) + { + _xmlnsDictionary.Add(key, xmlnsManager.LookupNamespace(key)); + } + } + } +#endif + +#if !PBTCOMPILER + /// + /// Constructor overload that takes an XmlReader, in order to + /// pull the BaseURI, Lang, and Space from it. + /// + internal ParserContext( XmlReader xmlReader ) + { + if( xmlReader.BaseURI != null && xmlReader.BaseURI.Length != 0 ) + { + BaseUri = new Uri( xmlReader.BaseURI ); + } + + XmlLang = xmlReader.XmlLang; + + if( xmlReader.XmlSpace != System.Xml.XmlSpace.None ) + { + XmlSpace = xmlReader.XmlSpace.ToString(); + } + } +#endif + +#if !PBTCOMPILER + /// + /// Constructor that takes the ParserContext. + /// A parserContext object will be built based on this. + /// + /// xmlParserContext to use + internal ParserContext(ParserContext parserContext) + { + _xmlLang = parserContext.XmlLang; + _xmlSpace = parserContext.XmlSpace; + _xamlTypeMapper = parserContext.XamlTypeMapper; + _mapTable = parserContext.MapTable; + _baseUri = parserContext.BaseUri; + _masterBracketCharacterCache = parserContext.MasterBracketCharacterCache; + + _rootElement = parserContext._rootElement; + if (parserContext._nameScopeStack != null) + _nameScopeStack = (Stack)parserContext._nameScopeStack.Clone(); + else + _nameScopeStack = null; + + // Don't want to force the lazy init so we just set privates + _skipJournaledProperties = parserContext._skipJournaledProperties; + + _xmlnsDictionary = null; + + // when there are no namespace prefix mappings in incoming ParserContext, + // we are not going to create an empty XmlnsDictionary. + if (parserContext._xmlnsDictionary != null && + parserContext._xmlnsDictionary.Count > 0) + { + _xmlnsDictionary = new XmlnsDictionary(); + + XmlnsDictionary xmlDictionaryFrom = parserContext.XmlnsDictionary; + + if (null != xmlDictionaryFrom) + { + foreach (string key in xmlDictionaryFrom.Keys) + { + _xmlnsDictionary[key] = xmlDictionaryFrom[key]; + } + } + } + } +#endif + + /// + /// Constructs a cache of all the members in this particular type that have + /// MarkupExtensionBracketCharactersAttribute set on them. This cache is added to a master + /// cache which stores the BracketCharacter cache for each type. + /// + internal Dictionary InitBracketCharacterCacheForType(Type type) + { + if (!MasterBracketCharacterCache.ContainsKey(type)) + { + Dictionary map = BuildBracketCharacterCacheForType(type); + MasterBracketCharacterCache.Add(type, map); + } + + return MasterBracketCharacterCache[type]; + } + + /// + /// Pushes the context scope stack (modifications to the ParserContext only apply to levels below + /// the modification in the stack, except for the XamlTypeMapper property) + /// + internal void PushScope() + { + _repeat++; + _currentFreezeStackFrame.IncrementRepeatCount(); + + // Wait till the context needs XmlnsDictionary, create on first use. + if (_xmlnsDictionary != null) + _xmlnsDictionary.PushScope(); + } + + /// + /// Pops the context scope stack + /// + internal void PopScope() + { + // Pop state off of the _langSpaceStack + if (_repeat > 0) + { + _repeat--; + } + else + { + if (null != _langSpaceStack && _langSpaceStack.Count > 0) + { + _repeat = (int) _langSpaceStack.Pop(); + _targetType = (Type) _langSpaceStack.Pop(); + _xmlSpace = (string) _langSpaceStack.Pop(); + _xmlLang = (string) _langSpaceStack.Pop(); + } + } + + // Pop state off of _currentFreezeStackFrame + if (!_currentFreezeStackFrame.DecrementRepeatCount()) + { + // If the end of the current frame has been reached, pop + // the next frame off the freeze stack + _currentFreezeStackFrame = (FreezeStackFrame) _freezeStack.Pop(); + } + + // Wait till the context needs XmlnsDictionary, create on first use. + if (_xmlnsDictionary != null) + _xmlnsDictionary.PopScope(); + + } + + /// + /// XmlNamespaceDictionary + /// + public XmlnsDictionary XmlnsDictionary + { + get + { + // Entry Point to others, initialize if null. + if (_xmlnsDictionary == null) + _xmlnsDictionary = new XmlnsDictionary(); + + return _xmlnsDictionary; + } + } + + /// + /// XmlLang property + /// + public string XmlLang + { + get + { + return _xmlLang; + } + set + { + EndRepeat(); + _xmlLang = (null == value ? String.Empty : value); + } + } + + /// + /// XmlSpace property + /// + // (Why isn't this of type XmlSpace?) + public string XmlSpace + { + get + { + return _xmlSpace; + } + set + { + EndRepeat(); + _xmlSpace = value; + } + } + + // + // TargetType + // + // Keep track of the Style/Template TargetType's in the current context. This allows Setters etc + // to interpret properties without walking up the reader stack to see it. This is internal and + // hard-coded to target type, but the intent in the future is to generalize this so that we don't + // have to have the custom parser, and so that the designer can provide the same contextual information. + // + internal Type TargetType + { + get + { + return _targetType; + } + +#if !PBTCOMPILER + set + { + EndRepeat(); + _targetType = value; + } +#endif + } + + // Items specific to XAML + + /// + /// XamlTypeMapper that should be used when resolving XML + /// + public XamlTypeMapper XamlTypeMapper + { + get + { + return _xamlTypeMapper ; + } + set + { + // The BamlMapTable must always be kept in sync with the XamlTypeMapper. If + // the XamlTypeMapper changes, then the map table must also be reset. + if (_xamlTypeMapper != value) + { + _xamlTypeMapper = value; + _mapTable = new BamlMapTable(value); + _xamlTypeMapper.MapTable = _mapTable; + } + } + } +#if !PBTCOMPILER + /// + /// Gets or sets the list of INameScopes in parent chain + /// + internal Stack NameScopeStack + { + get + { + if (_nameScopeStack == null) + _nameScopeStack = new Stack(2); + + return _nameScopeStack; + } + } +#endif + + /// + /// Gets or sets the base Uri + /// + public Uri BaseUri + { + get + { + return _baseUri ; + } + set + { + _baseUri = value; + } + } + +#if !PBTCOMPILER + /// + /// Should DependencyProperties marked with the Journal metadata flag be set or skipped? + /// + /// + internal bool SkipJournaledProperties + { + get { return _skipJournaledProperties; } + set { _skipJournaledProperties = value; } + } + + // + // The Assembly which hosts the Baml stream. + // + /// + /// Critical - because it sets the value of the _streamCreatedAssembly field, and that is + /// SecurityCritical Data as this field is used by the BamlRecordReader to + /// allow legitimate internal types in Partial Trust. + /// + internal Assembly StreamCreatedAssembly + { + get { return _streamCreatedAssembly.Value; } + + [SecurityCritical] + set { _streamCreatedAssembly.Value = value; } + } +#endif + + /// + /// Operator for Converting a ParserContext to an XmlParserContext + /// + /// ParserContext to Convert + /// XmlParserContext + public static implicit operator XmlParserContext(ParserContext parserContext) + { + return ParserContext.ToXmlParserContext(parserContext); + } + + + /// + /// Operator for Converting a ParserContext to an XmlParserContext + /// + /// ParserContext to Convert + /// XmlParserContext + public static XmlParserContext ToXmlParserContext(ParserContext parserContext) + { + if (parserContext == null) + { + throw new ArgumentNullException( "parserContext" ); + } + + XmlNamespaceManager xmlnsMgr = new XmlNamespaceManager(new NameTable()); + XmlSpace xmlSpace = System.Xml.XmlSpace.None; + + if (parserContext.XmlSpace != null && parserContext.XmlSpace.Length != 0) + { + TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(System.Xml.XmlSpace)); + if (null != typeConverter) + { + try + { + xmlSpace = (System.Xml.XmlSpace)typeConverter.ConvertFromString(null, TypeConverterHelper.InvariantEnglishUS, parserContext.XmlSpace); + } + catch (System.FormatException) // If it's not a valid space value, ignore it + { + xmlSpace = System.Xml.XmlSpace.None; + } + } + } + + // We start getting Keys list only if we have non-empty dictionary + + if (parserContext._xmlnsDictionary != null) + { + foreach (string key in parserContext._xmlnsDictionary.Keys) + { + xmlnsMgr.AddNamespace(key, parserContext._xmlnsDictionary[key]); + } + } + + XmlParserContext xmlParserContext = new XmlParserContext(null, xmlnsMgr, parserContext.XmlLang, xmlSpace); + if( parserContext.BaseUri == null) + { + xmlParserContext.BaseURI = null; + } + else + { + string serializedSafe = parserContext.BaseUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.SafeUnescaped); + Uri sameUri = new Uri(serializedSafe); + string cannonicalString = sameUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped); + xmlParserContext.BaseURI = cannonicalString; + } + + return xmlParserContext; + } + +#endregion Public Methods + +#region Internal + + + // Reset stack to default state + private void EndRepeat() + { + if (_repeat > 0) + { + if (null == _langSpaceStack) + { + _langSpaceStack = new Stack(1); + } + + _langSpaceStack.Push(XmlLang); + _langSpaceStack.Push(XmlSpace); + _langSpaceStack.Push(TargetType); + _langSpaceStack.Push(_repeat); + _repeat = 0; + } + } + + /// + /// LineNumber for the first character in the given + /// stream. This is used when parsing a section of a larger file so + /// that proper line number in the overall file can be calculated. + /// + internal int LineNumber + { + get { return _lineNumber; } +#if !PBTCOMPILER + set { _lineNumber = value; } +#endif + } + + + /// + /// LinePosition for the first character in the given + /// stream. This is used when parsing a section of a larger file so + /// that proper line positions in the overall file can be calculated. + /// + internal int LinePosition + { + get { return _linePosition; } +#if !PBTCOMPILER + set { _linePosition = value; } +#endif + } + +#if !PBTCOMPILER + internal bool IsDebugBamlStream + { + get { return _isDebugBamlStream; } + set { _isDebugBamlStream = value; } + } + + /// + /// Gets or sets the object at the root of the portion of the tree + /// currently being parsed. Note that this may not be the very top of the tree + /// if the parsing operation is scoped to a specific subtree, such as in Style + /// parsing. + /// + internal object RootElement + { + get { return _rootElement; } + set { _rootElement = value; } + } + + // If this is false (default), then the parser does not own the stream and so if + // it has any defer loaded content, it needs to copy it into a byte array since + // the owner\caller will close the stream when parsing is complete. Currently, this + // is set to true only by the theme engine since the stream is a system-wide resource + // an dso will always be open for teh lifetime of the process laoding the theme and so + // it can be re-used for perf reasons. + internal bool OwnsBamlStream + { + get { return _ownsBamlStream; } + set { _ownsBamlStream = value; } + } +#endif + + /// + /// Allows sharing a map table between instances of BamlReaders and Writers. + /// + + internal BamlMapTable MapTable + { + get { return _mapTable; } +#if !PBTCOMPILER + set + { + // The XamlTypeMapper and the map table must always be kept in sync. If the + // map table changes, update the XamlTypeMapper also + if (_mapTable != value) + { + _mapTable = value; + _xamlTypeMapper = _mapTable.XamlTypeMapper; + _xamlTypeMapper.MapTable = _mapTable; + } + } +#endif + } + +#if !PBTCOMPILER + + + + internal IStyleConnector StyleConnector + { + get { return _styleConnector; } + set { _styleConnector = value; } + } + + // Keep a cached ProvideValueProvider so that we don't have to keep re-creating one. + internal ProvideValueServiceProvider ProvideValueProvider + { + get + { + if (_provideValueServiceProvider == null) + { + _provideValueServiceProvider = new ProvideValueServiceProvider(this); + } + + return _provideValueServiceProvider; + } + } + + /// + /// This is used to resolve a StaticResourceId record within a deferred content + /// section against a StaticResourceExtension on the parent dictionary. + /// + internal List StaticResourcesStack + { + get + { + if (_staticResourcesStack == null) + { + _staticResourcesStack = new List(); + } + + return _staticResourcesStack; + } + } + + /// + /// Says if we are we currently loading deferred content + /// + internal bool InDeferredSection + { + get { return (_staticResourcesStack != null && _staticResourcesStack.Count > 0); } + } +#endif + + // Return a new Parser context that has the same instance variables as this instance, with + // only scope dependent variables deep copied. Variables that are not dependent on scope + // (such as the baml map table) are not deep copied. + +#if !PBTCOMPILER + internal ParserContext ScopedCopy() + { + return ScopedCopy( true /* copyNameScopeStack */ ); + } +#endif + +#if !PBTCOMPILER + /// + /// Critical - because it sets _streamCreatedAssembly on the ParserContext, and that is + /// SecurityCritical Data as this field is used by the BamlRecordReader to + /// allow legitimate internal types in Partial Trust. + /// Safe - because it gets this value from a copy of itself that gets it from a stream that + /// implements an internal IStreamInfo interface and IStreamInfo.Assembly is set\ + /// by the ResourceContainer code that is SecurityCritical, but treated as safe. + /// + [SecurityCritical, SecurityTreatAsSafe] + internal ParserContext ScopedCopy(bool copyNameScopeStack) + { + ParserContext context = new ParserContext(); + + context._baseUri = _baseUri; + context._skipJournaledProperties = _skipJournaledProperties; + context._xmlLang = _xmlLang; + context._xmlSpace = _xmlSpace; + context._repeat = _repeat; + context._lineNumber = _lineNumber; + context._linePosition = _linePosition; + context._isDebugBamlStream = _isDebugBamlStream; + context._mapTable = _mapTable; + context._xamlTypeMapper = _xamlTypeMapper; + context._targetType = _targetType; + + context._streamCreatedAssembly.Value = _streamCreatedAssembly.Value; + context._rootElement = _rootElement; + context._styleConnector = _styleConnector; + + // Copy the name scope stack, if necessary. + + if (_nameScopeStack != null && copyNameScopeStack) + context._nameScopeStack = (_nameScopeStack != null) ? (Stack)_nameScopeStack.Clone() : null; + else + context._nameScopeStack = null; + + // Deep copy only selected scope dependent instance variables + context._langSpaceStack = (_langSpaceStack != null) ? (Stack)_langSpaceStack.Clone() : null; + + if (_xmlnsDictionary != null) + context._xmlnsDictionary = new XmlnsDictionary(_xmlnsDictionary); + else + context._xmlnsDictionary = null; + + context._currentFreezeStackFrame = _currentFreezeStackFrame; + context._freezeStack = (_freezeStack != null) ? (Stack) _freezeStack.Clone() : null; + + return context; + } +#endif + + // + // This is called by a user of a parser context when it is a good time to drop unnecessary + // references (today, just an empty stack). + // + +#if !PBTCOMPILER + internal void TrimState() + { + + if( _nameScopeStack != null && _nameScopeStack.Count == 0 ) + { + _nameScopeStack = null; + } + + } +#endif + + /// + /// Master cache of Bracket Characters which stores the BracketCharacter cache for each Type. + /// + internal Dictionary> MasterBracketCharacterCache + { + get + { + if (_masterBracketCharacterCache == null) + { + _masterBracketCharacterCache = new Dictionary>(); + } + + return _masterBracketCharacterCache; + } + } + + // Return a new Parser context that has the same instance variables as this instance, + // will all scoped and non-scoped complex properties deep copied. +#if !PBTCOMPILER + internal ParserContext Clone() + { + ParserContext context = ScopedCopy(); + + // Deep copy only selected instance variables + context._mapTable = (_mapTable != null) ? _mapTable.Clone() : null; + context._xamlTypeMapper = (_xamlTypeMapper != null) ? _xamlTypeMapper.Clone() : null; + + // Connect the XamlTypeMapper and bamlmaptable + context._xamlTypeMapper.MapTable = context._mapTable; + context._mapTable.XamlTypeMapper = context._xamlTypeMapper; + + return context; + } +#endif + +#if !PBTCOMPILER + // Set/Get whether or not Freezables within the current scope + // should be Frozen. + internal bool FreezeFreezables + { + get + { + return _currentFreezeStackFrame.FreezeFreezables; + } + + set + { + // If the freeze flag isn't actually changing, we don't need to + // register a change + if (value != _currentFreezeStackFrame.FreezeFreezables) + { + // When this scope was entered the repeat count was initially incremented, + // indicating no _freezeFreezables state changes within this scope. + // + // Now that a state change has been found, we need to replace that no-op with + // a directive to restore the old state by un-doing the increment + // and pushing the stack frame +#if DEBUG + bool canDecrement = +#endif + _currentFreezeStackFrame.DecrementRepeatCount(); +#if DEBUG + // We're replacing a no-op with a state change. Detect if we accidently + // start replacing actual state changes. This might happen if we allowed + // FreezeFreezable to be set twice within the same scope, for + // example. + Debug.Assert(canDecrement); +#endif + if (_freezeStack == null) + { + // Lazily allocate a _freezeStack if this is the first + // state change. + _freezeStack = new Stack(); + } + + // Save the old frame + _freezeStack.Push(_currentFreezeStackFrame); + + // Set the new frame + _currentFreezeStackFrame.Reset(value); + } + } + } + + internal bool TryCacheFreezable(string value, Freezable freezable) + { + if (FreezeFreezables) + { + if (freezable.CanFreeze) + { + if (!freezable.IsFrozen) + { + freezable.Freeze(); + } + if (_freezeCache == null) + { + _freezeCache = new Dictionary(); + } + _freezeCache.Add(value, freezable); + return true; + } + } + + return false; + } + + internal Freezable TryGetFreezable(string value) + { + Freezable freezable = null; + if (_freezeCache != null) + { + _freezeCache.TryGetValue(value, out freezable); + } + + return freezable; + } +#endif + +#endregion Internal + +#region Date + + private XamlTypeMapper _xamlTypeMapper; + private Uri _baseUri; + + private XmlnsDictionary _xmlnsDictionary; + private String _xmlLang = String.Empty; + private String _xmlSpace = String.Empty; + private Stack _langSpaceStack; + private int _repeat; + private Type _targetType; + private Dictionary> _masterBracketCharacterCache; + +#if !PBTCOMPILER + private bool _skipJournaledProperties; + private SecurityCriticalDataForSet _streamCreatedAssembly; + private bool _ownsBamlStream; + private ProvideValueServiceProvider _provideValueServiceProvider; + private IStyleConnector _styleConnector; + private Stack _nameScopeStack; + private List _staticResourcesStack; + + object _rootElement; // RootElement for the Page scoping [temporary, should be + // something like page name or baseUri] + +#endif + + /// + /// Looks up all properties via reflection on the given type, and scans through the attributes on all of them + /// to build a cache of properties which have MarkupExtensionBracketCharactersAttribute set on them. + /// + private Dictionary BuildBracketCharacterCacheForType(Type extensionType) + { + Dictionary cache = new Dictionary(StringComparer.OrdinalIgnoreCase); + PropertyInfo[] propertyInfo = extensionType.GetProperties(BindingFlags.Public | BindingFlags.Instance); + Type constructorArgumentType = null; + Type markupExtensionBracketCharacterType = null; + + foreach (PropertyInfo property in propertyInfo) + { + string propertyName = property.Name; + string constructorArgumentName = null; + IList customAttributes = CustomAttributeData.GetCustomAttributes(property); + SpecialBracketCharacters bracketCharacters = null; + foreach (CustomAttributeData attributeData in customAttributes) + { + Type attributeType = attributeData.AttributeType; + Assembly xamlAssembly = attributeType.Assembly; + if (constructorArgumentType == null || markupExtensionBracketCharacterType == null) + { + constructorArgumentType = + xamlAssembly.GetType("System.Windows.Markup.ConstructorArgumentAttribute"); + markupExtensionBracketCharacterType = + xamlAssembly.GetType("System.Windows.Markup.MarkupExtensionBracketCharactersAttribute"); + } + + if (attributeType.IsAssignableFrom(constructorArgumentType)) + { + constructorArgumentName = attributeData.ConstructorArguments[0].Value as string; + } + else if (attributeType.IsAssignableFrom(markupExtensionBracketCharacterType)) + { + if (bracketCharacters == null) + { + bracketCharacters = new SpecialBracketCharacters(); + } + + bracketCharacters.AddBracketCharacters((char)attributeData.ConstructorArguments[0].Value, (char)attributeData.ConstructorArguments[1].Value); + } + } + + if (bracketCharacters != null) + { + bracketCharacters.EndInit(); + cache.Add(propertyName, bracketCharacters); + if (constructorArgumentName != null) + { + cache.Add(constructorArgumentName, bracketCharacters); + } + } + } + + return cache.Count == 0 ? null : cache; + } + + // Struct that maintains both the freezeFreezable state & stack depth + // between freezeFreezable state changes + private struct FreezeStackFrame + { + internal void IncrementRepeatCount() { _repeatCount++; } + + // Returns false when the count reaches 0 such that the decrement can not occur + internal bool DecrementRepeatCount() + { + if (_repeatCount > 0) + { + _repeatCount--; + return true; + } + else + { + return false; + } + } + +#if !PBTCOMPILER + // Accessors for private state + internal bool FreezeFreezables + { + get { return _freezeFreezables; } + } + + // Reset's this frame to a new scope. Only used with _currentFreezeStackFrame. + internal void Reset(bool freezeFreezables) + { + _freezeFreezables = freezeFreezables; + _repeatCount = 0; + } + + // Whether or not Freezeables with the current scope should be Frozen + private bool _freezeFreezables; + +#endif + + // The number of frames until the next state change. + // We need to know how many times PopScope() is called until the + // state changes. That information is tracked by _repeatCount. + private int _repeatCount; + } + + // First frame is maintained off of the _freezeStack to avoid allocating + // a Stack for the common case where Freeze isn't specified. + FreezeStackFrame _currentFreezeStackFrame; + +#if !PBTCOMPILER + // When cloning, it isn't necessary to copy this cache of freezables. + // This cache allows frozen freezables to use a shared instance and save on memory. + private Dictionary _freezeCache; +#endif + + private Stack _freezeStack = null; + + private int _lineNumber = 0; // number of lines between the start of the file and + // our starting point (the starting point of this context) + private int _linePosition=0; // default start ot left of first character which is a zero + private BamlMapTable _mapTable; +#if !PBTCOMPILER + private bool _isDebugBamlStream = false; +#endif +#endregion Data + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserHooks.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserHooks.cs new file mode 100644 index 00000000000..e7fa5e53d18 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserHooks.cs @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/***************************************************************************\ +* +* Purpose: Callback at parse time for node processing +* +\***************************************************************************/ + +using System.ComponentModel; + +using System.ComponentModel.Design.Serialization; +using System.Reflection; +using System; +using System.Xml; + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + /// + /// Describes the action the parser is to take after it + /// has called back to the ParserHooks + /// + internal enum ParserAction + { + /// + /// parser should do normal processing + /// + Normal, + + /// + /// Parser should not process this node. + /// If the current node is an Element, skip the current node and all of its children + /// If the current node is an attribute,skip to the next attribute + /// + Skip + } + + /// + /// The base class for the parse time callbacks. + /// + /// + /// The localization team will use this under two scenarios + /// 1. The Uid generation tool wants to know the different xaml nodes and their positions in a xaml file + /// 2. Used to strip out the localization attributes during compilation to Baml + /// + internal abstract class ParserHooks + { + /// + /// Called by parser after it determines what node type for + /// the XML Node and has tokenized the xml node content. + /// + /// + /// Node types are Resources, Code: Element Object, properties, events etc. + /// The return value is a ParserAction value which indicates if the parser + /// should: continue normal processing; skip this node and any children + /// + internal virtual ParserAction LoadNode(XamlNode tokenNode) + { + return ParserAction.Normal; + } + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserStack.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserStack.cs new file mode 100644 index 00000000000..1519df59d5e --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserStack.cs @@ -0,0 +1,137 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/***************************************************************************\ +* +* Purpose: ParserStack...once was in XamlReaderHelper.cs +* +\***************************************************************************/ + +using System; +using System.Xml; +using System.Xml.Serialization; +using System.IO; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Reflection; +using System.Globalization; +using MS.Utility; +using System.Collections.Specialized; +using Microsoft.Win32; +using System.Runtime.InteropServices; +using MS.Internal; + + +#if !PBTCOMPILER + +using System.Windows; +using System.Windows.Documents; +using System.Windows.Media; +using System.Windows.Shapes; + +#endif + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + + /// + /// Parser Context stack + /// The built-in Stack class doesn't let you do things like look at nodes beyond the top of the stack... + /// so we'll use this instead. Note that this is not a complete stack implementation -- if you try to + /// convert to array or some such, you'll be missing a couple elements. But this is plenty for our purposes. + /// Main goal is to track current/parent context with a minimum of overhead. + /// This class is internal so it can be shared with the BamlRecordReader + /// + internal class ParserStack : ArrayList + { + /// + /// Creates a default ParserStack + /// + internal ParserStack() : base() + { + } + + /// + /// Creates a clone. + /// + private ParserStack(ICollection collection) : base(collection) + { + } + + #region StackOverrides + + public void Push(object o) + { + Add(o); + } + + public object Pop() + { + object o = this[Count - 1]; + RemoveAt(Count - 1); + return o; + } + +#if !PBTCOMPILER + public object Peek() + { + // Die if peeking on empty stack + return this[Count - 1]; + } +#endif + + public override object Clone() + { + return new ParserStack(this); + } + + #endregion // StackOverrides + + #region Properties + + /// + /// Returns the Current Context on the stack + /// + internal object CurrentContext + { + get { return Count > 0 ? this[Count - 1] : null; } + } + + /// + /// Returns the Parent of the Current Context + /// + internal object ParentContext + { + get { return Count > 1 ? this[Count - 2] : null; } + } + + /// + /// Returns the GrandParent of the Current Context + /// + internal object GrandParentContext + { + get { return Count > 2 ? this[Count - 3] : null; } + } + +#if !PBTCOMPILER + /// + /// Returns the GreatGrandParent of the Current Context + /// + internal object GreatGrandParentContext + { + get { return Count > 3 ? this[Count - 4] : null; } + } +#endif + + #endregion // Properties + + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/StyleModeStack.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/StyleModeStack.cs new file mode 100644 index 00000000000..5df48216bc9 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/StyleModeStack.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Xml; +using System.IO; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + internal enum StyleMode : byte + { + Base, // Style/Template tag, simple and top level complex properties + TargetTypeProperty, // Target type complex property under a Style/Template + BasedOnProperty, // BasedOn complex property under a Style/Template + DataTypeProperty, // Data type complex property under a Template + ComplexProperty, // Reading an allowed complex property under a Template + Resources, // Resources complex property under a Style + Setters, // Style.Setters IList complex property and subtree + Key, // x:Key subtree when Style is used in a dictionary + TriggerBase, // Style.TriggerBase complex property and subtree + TriggerActions, // When in the middle of parsing EventTrigger.TriggerActions + TriggerSetters, // When in the middle of parsing property trigger Setters collection + TriggerEnterExitActions, // Trigger.EnterActions or Trigger.ExitActions + VisualTree, // FrameworkTemplate.VisualTree's subtree + } + + internal class StyleModeStack + { + internal StyleModeStack() + { + Push(StyleMode.Base); + } + + internal int Depth + { + get { return _stack.Count - 1; } + } + + internal StyleMode Mode + { + get + { + Debug.Assert(Depth >= 0, "StyleModeStack's depth was " + Depth + ", should be >= 0"); + return _stack.Peek(); + } + } + + internal void Push (StyleMode mode) + { + _stack.Push(mode); + } + + internal void Push () + { + Push(Mode); + } + + internal StyleMode Pop() + { + Debug.Assert(Depth >= 0, "StyleMode::Pop() with depth of " + Depth + ", should be >= 0"); + return _stack.Pop(); + } + + private Stack _stack = new Stack(64); + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/StyleXamlParser.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/StyleXamlParser.cs new file mode 100644 index 00000000000..b397f17b5c6 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/StyleXamlParser.cs @@ -0,0 +1,1627 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/***************************************************************************\ +* +* Purpose: Class that interfaces with TokenReader and BamlWriter for +* parsing Style +* +\***************************************************************************/ + +using System; +using System.Xml; +using System.IO; +using System.Text; +using System.Collections; +using System.ComponentModel; + +using System.Diagnostics; +using System.Reflection; + +using MS.Utility; + +#if !PBTCOMPILER + +using System.Windows; +using System.Windows.Threading; + +#endif + +#if PBTCOMPILER +namespace MS.Internal.Markup +#else +namespace System.Windows.Markup +#endif +{ + /***************************************************************************\ + * + * StyleMode + * + * The style parser works in several modes, and tags are interpreted differently + * depending on which mode or section of the Style markup that the parser is + * currently interpreting. + * + \***************************************************************************/ + + /// + /// Handles overrides for case when Style is being built to a tree + /// instead of compiling to a file. + /// + internal class StyleXamlParser : XamlParser + { + +#region Constructors + +#if !PBTCOMPILER + /// + /// Constructor. + /// + /// + /// Note that we are re-using the token reader, so we'll swap out the XamlParser that + /// the token reader uses with ourself. Then restore it when we're done parsing. + /// + internal StyleXamlParser( + XamlTreeBuilder treeBuilder, + XamlReaderHelper tokenReader, + ParserContext parserContext) : this(tokenReader, parserContext) + { + _treeBuilder = treeBuilder; + } + +#endif + + /// + /// Constructor. + /// + /// + /// Note that we are re-using the token reader, so we'll swap out the XamlParser that + /// the token reader uses with ourself. Then restore it when we're done parsing. + /// + internal StyleXamlParser( + XamlReaderHelper tokenReader, + ParserContext parserContext) + { + TokenReader = tokenReader; + ParserContext = parserContext; + + _previousXamlParser = TokenReader.ControllingXamlParser; + TokenReader.ControllingXamlParser = this; + _startingDepth = TokenReader.XmlReader.Depth; + } + +#endregion Constructors + +#region Overrides + + + /// + /// Override of the main switch statement that processes the xaml nodes. + /// + /// + /// We need to control when cleanup is done and when the calling parse loop + /// is exited, so do this here. + /// + internal override void ProcessXamlNode( + XamlNode xamlNode, + ref bool cleanup, + ref bool done) + { + switch(xamlNode.TokenType) + { + // Ignore some types of xaml nodes, since they are not + // relevent to style parsing. + case XamlNodeType.DocumentStart: + case XamlNodeType.DocumentEnd: + break; + + case XamlNodeType.ElementEnd: + base.ProcessXamlNode(xamlNode, ref cleanup, ref done); + // If we're at the depth that we started out, then we must be done. In that case quit + // and restore the XamlParser that the token reader was using before parsing styles. + if (_styleModeStack.Depth == 0) + { + done = true; // Stop the style parse + cleanup = false; // Don't close the stream + TokenReader.ControllingXamlParser = _previousXamlParser; + } + break; + + case XamlNodeType.PropertyArrayStart: + case XamlNodeType.PropertyArrayEnd: + case XamlNodeType.DefTag: + ThrowException(SRID.StyleTagNotSupported, xamlNode.TokenType.ToString(), + xamlNode.LineNumber, xamlNode.LinePosition); + break; + + // Most nodes are handled by the base XamlParser by creating a + // normal BamlRecord. + default: + base.ProcessXamlNode(xamlNode, ref cleanup, ref done); + break; + } + + } + + /// + /// Write start of an unknown tag + /// + /// + /// For style parsing, the 'Set' tag is an unknown tag, but this will map to a + /// Trigger set command. Store this as an element start record here. + /// Also 'Set.Value' will map to the a complex Value set portion of the Set command. + /// + public override void WriteUnknownTagStart(XamlUnknownTagStartNode xamlUnknownTagStartNode) + { +#if PBTCOMPILER + string localElementFullName = string.Empty; + int lastIndex = xamlUnknownTagStartNode.Value.LastIndexOf('.'); + + // if local complex property bail out now and handle in 2nd pass when TypeInfo is available + if (-1 == lastIndex) + { + NamespaceMapEntry[] namespaceMaps = XamlTypeMapper.GetNamespaceMapEntries(xamlUnknownTagStartNode.XmlNamespace); + + if (namespaceMaps != null && namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly) + { + localElementFullName = namespaceMaps[0].ClrNamespace + "." + xamlUnknownTagStartNode.Value; + } + } + else if (IsLocalPass1) + { + return; + } + + if (localElementFullName.Length == 0 || !IsLocalPass1) + { +#endif + // It can be a fairly common error for , + // or to be specified + // at the wrong nesting level. Detect + // these cases to give more meaningful error messages. + if (xamlUnknownTagStartNode.Value == XamlStyleSerializer.VisualTriggersFullPropertyName || + xamlUnknownTagStartNode.Value == XamlStyleSerializer.SettersFullPropertyName) + { + ThrowException(SRID.StyleKnownTagWrongLocation, + xamlUnknownTagStartNode.Value, + xamlUnknownTagStartNode.LineNumber, + xamlUnknownTagStartNode.LinePosition); + } + else + { + base.WriteUnknownTagStart(xamlUnknownTagStartNode); + } +#if PBTCOMPILER + } +#endif + } + + /// + /// Write Start element for a dictionary key section. + /// + public override void WriteKeyElementStart( + XamlElementStartNode xamlKeyElementStartNode) + { + _styleModeStack.Push(StyleMode.Key); +#if PBTCOMPILER + _defNameFound = true; +#endif + base.WriteKeyElementStart(xamlKeyElementStartNode); + } + + /// + /// Write End element for a dictionary key section + /// + public override void WriteKeyElementEnd( + XamlElementEndNode xamlKeyElementEndNode) + { + _styleModeStack.Pop(); + base.WriteKeyElementEnd(xamlKeyElementEndNode); + } + + /// + /// Write end of an unknown tag + /// + /// + /// For style parsing, the 'Set' tag is an unknown tag, but this will map to a + /// Trigger set command. Store this as an element end record here. + /// + public override void WriteUnknownTagEnd(XamlUnknownTagEndNode xamlUnknownTagEndNode) + { +#if PBTCOMPILER + NamespaceMapEntry[] namespaceMaps = XamlTypeMapper.GetNamespaceMapEntries(xamlUnknownTagEndNode.XmlNamespace); + bool localTag = namespaceMaps != null && namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly; + + if (!localTag || !IsLocalPass1) + { +#endif + base.WriteUnknownTagEnd(xamlUnknownTagEndNode); +#if PBTCOMPILER + } +#endif + } + + /// + /// Write unknown attribute + /// + /// + /// For style parsing, the 'Set' tag is an unknown tag and contains properties that + /// are passed as UnknownAttributes. Translate these into Property records. + /// + public override void WriteUnknownAttribute(XamlUnknownAttributeNode xamlUnknownAttributeNode) + { +#if PBTCOMPILER + bool localAttrib = false; + string localTagFullName = string.Empty; + string localAttribName = xamlUnknownAttributeNode.Name; + NamespaceMapEntry[] namespaceMaps = null; + + if (xamlUnknownAttributeNode.OwnerTypeFullName.Length > 0) + { + // These are attributes on a local tag ... + localTagFullName = xamlUnknownAttributeNode.OwnerTypeFullName; + localAttrib = true; + } + else + { + // These are attributes on a non-local tag ... + namespaceMaps = XamlTypeMapper.GetNamespaceMapEntries(xamlUnknownAttributeNode.XmlNamespace); + localAttrib = namespaceMaps != null && namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly; + } + + if (localAttrib) + { + // ... and if there are any periods in the attribute name, then ... + int lastIndex = localAttribName.LastIndexOf('.'); + + if (-1 != lastIndex) + { + // ... these might be attached props or events defined by a locally defined component, + // but being set on this non-local tag. + + string ownerTagName = localAttribName.Substring(0, lastIndex); + + if (namespaceMaps != null) + { + if (namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly) + { + localTagFullName = namespaceMaps[0].ClrNamespace + "." + ownerTagName; + } + } + else + { + TypeAndSerializer typeAndSerializer = XamlTypeMapper.GetTypeOnly(xamlUnknownAttributeNode.XmlNamespace, + ownerTagName); + + if (typeAndSerializer != null) + { + Type ownerTagType = typeAndSerializer.ObjectType; + localTagFullName = ownerTagType.FullName; + } + else + { + namespaceMaps = XamlTypeMapper.GetNamespaceMapEntries(xamlUnknownAttributeNode.XmlNamespace); + if (namespaceMaps != null && namespaceMaps.Length == 1 && namespaceMaps[0].LocalAssembly) + { + localTagFullName = namespaceMaps[0].ClrNamespace + "." + ownerTagName; + } + else + { + localTagFullName = string.Empty; + } + } + } + + localAttribName = localAttribName.Substring(lastIndex + 1); + } + } + + if (localTagFullName.Length == 0 || !IsLocalPass1) + { +#endif + base.WriteUnknownAttribute(xamlUnknownAttributeNode); +#if PBTCOMPILER + } +#endif + } + + /// + /// WriteEndAttributes occurs after the last attribute (property, complex property or + /// def record) is written. Note that if there are none of the above, then WriteEndAttributes + /// is not called for a normal start tag. + /// + public override void WriteEndAttributes(XamlEndAttributesNode xamlEndAttributesNode) + { + if ((_styleModeStack.Mode == StyleMode.Setters || _styleModeStack.Mode == StyleMode.TriggerBase) && + !xamlEndAttributesNode.IsCompact) + { + if (_setterOrTriggerValueNode != null) + { + ProcessPropertyValueNode(); + } +#if PBTCOMPILER + else if (_inEventSetter) + { + ProcessEventSetterNode(xamlEndAttributesNode); + } +#endif + } + + base.WriteEndAttributes(xamlEndAttributesNode); + } + + private MemberInfo GetDependencyPropertyInfo(XamlPropertyNode xamlPropertyNode) + { + string member = xamlPropertyNode.Value; + MemberInfo dpInfo = GetPropertyOrEventInfo(xamlPropertyNode, ref member); + if (dpInfo != null) + { + // Note: Should we enforce that all DP fields should end with a + // "Property" or "PropertyKey" postfix here? + + if (BamlRecordWriter != null) + { + short typeId; + short propertyId = MapTable.GetAttributeOrTypeId(BamlRecordWriter.BinaryWriter, + dpInfo.DeclaringType, + member, + out typeId); + + if (propertyId < 0) + { + xamlPropertyNode.ValueId = propertyId; + xamlPropertyNode.MemberName = null; + } + else + { + xamlPropertyNode.ValueId = typeId; + xamlPropertyNode.MemberName = member; + } + } + } + + return dpInfo; + } + + private MemberInfo GetPropertyOrEventInfo(XamlNode xamlNode, ref string member) + { + // Strip off namespace prefix from the event or property name and + // map this to an xmlnamespace. Also extract the class name, if present + string prefix = string.Empty; + string target = member; + string propOrEvent = member; + int dotIndex = member.LastIndexOf('.'); + if (-1 != dotIndex) + { + target = propOrEvent.Substring(0, dotIndex); + member = propOrEvent.Substring(dotIndex + 1); + } + int colonIndex = target.IndexOf(':'); + if (-1 != colonIndex) + { + // If using .net then match against the class. + prefix = target.Substring(0, colonIndex); + if (-1 == dotIndex) + { + member = target.Substring(colonIndex + 1); + } + } + + string xmlNamespace = TokenReader.XmlReader.LookupNamespace(prefix); + Type targetType = null; + + // Get the type associated with the property or event from the XamlTypeMapper and + // use this to resolve the property or event into an EventInfo, PropertyInfo + // or MethodInfo + if (-1 != dotIndex) + { + targetType = XamlTypeMapper.GetTypeFromBaseString(target, ParserContext, false); + } + else if (_styleTargetTypeString != null) + { + targetType = XamlTypeMapper.GetTypeFromBaseString(_styleTargetTypeString, ParserContext, false); + target = _styleTargetTypeString; + } + else if (_styleTargetTypeType != null) + { + targetType = _styleTargetTypeType; + target = targetType.Name; + } + + MemberInfo memberInfo = null; + if (targetType != null) + { + string objectName = propOrEvent; + memberInfo = XamlTypeMapper.GetClrInfo( + _inEventSetter, + targetType, + xmlNamespace, + member, + ref objectName) as MemberInfo; + } + + if (memberInfo != null) + { + if (!_inEventSetter) + { + PropertyInfo pi = memberInfo as PropertyInfo; + if (pi != null) + { + // For trigger condition only allow if public or internal getter + if (_inSetterDepth < 0 && _styleModeStack.Mode == StyleMode.TriggerBase) + { + if (!XamlTypeMapper.IsAllowedPropertyGet(pi)) + { + ThrowException(SRID.ParserCantSetTriggerCondition, + pi.Name, + xamlNode.LineNumber, + xamlNode.LinePosition); + } + } + else // for general Setters check prop setters + { + if (!XamlTypeMapper.IsAllowedPropertySet(pi)) + { + ThrowException(SRID.ParserCantSetAttribute, + "Property Setter", + pi.Name, + "set", + xamlNode.LineNumber, + xamlNode.LinePosition); + } + } + } + } + } + // local properties and events will be added to the baml in pass2 of the compilation. + // so don't throw now. + else +#if PBTCOMPILER + if (!IsLocalPass1) +#endif + { + if (targetType != null) + { + ThrowException(SRID.StyleNoPropOrEvent, + (_inEventSetter ? "Event" : "Property"), + member, + targetType.FullName, + xamlNode.LineNumber, + xamlNode.LinePosition); + } + else + { + ThrowException(SRID.StyleNoTarget, + (_inEventSetter ? "Event" : "Property"), + member, + xamlNode.LineNumber, + xamlNode.LinePosition); + } + } + + return memberInfo; + } + +#if PBTCOMPILER + private void ProcessEventSetterNode(XamlEndAttributesNode xamlEndAttributesNode) + { + // Check for EventSetter properties. These aren't really stored as properties but + // resolved at the EventSetter end tag as events by the compiler + Debug.Assert(_inEventSetter); + + string member = _event; + MemberInfo memberInfo = GetPropertyOrEventInfo(xamlEndAttributesNode, ref member); + // If we have an event setter on a locally defined component, write it out + // as a property instead of an event so that it will be resolved at runtime. + if (null != memberInfo) + { + XamlClrEventNode eventNode = new XamlClrEventNode( + xamlEndAttributesNode.LineNumber, + xamlEndAttributesNode.LinePosition, + xamlEndAttributesNode.Depth, + member, + memberInfo, + _handler); +#if HANDLEDEVENTSTOO + eventNode.HandledEventsToo = _handledEventsToo; +#endif + WriteClrEvent(eventNode); + } + + _event = null; + _handler = null; +#if HANDLEDEVENTSTOO + _handledEventsToo = false; +#endif + } +#endif + + /// + /// The Value="foo" property node for a Setter and a Trigger has been saved + /// and is resolved some time afterwards using the associated Property="Bar" + /// attribute. This is done so that the property record can be written using + /// the type converter associated with "Bar" + /// + private void ProcessPropertyValueNode() + { + if (_setterOrTriggerPropertyInfo != null) + { + // Now we have PropertyInfo or a MethodInfo for the property setter. + // Get the type of the property from this which will be used + // by BamlRecordWriter.WriteProperty to find an associated + // TypeConverter to use at runtime. + // To allow for per-property type converters we need to extract + // information from the member info about the property + Type propertyType = XamlTypeMapper.GetPropertyType(_setterOrTriggerPropertyInfo); + _setterOrTriggerValueNode.ValuePropertyType = propertyType; + _setterOrTriggerValueNode.ValuePropertyMember = _setterOrTriggerPropertyInfo; + _setterOrTriggerValueNode.ValuePropertyName = XamlTypeMapper.GetPropertyName(_setterOrTriggerPropertyInfo); + _setterOrTriggerValueNode.ValueDeclaringType = _setterOrTriggerPropertyInfo.DeclaringType; + + base.WriteProperty(_setterOrTriggerValueNode); + } + else + { + base.WriteBaseProperty(_setterOrTriggerValueNode); + } + + _setterOrTriggerValueNode = null; + _setterOrTriggerPropertyInfo = null; + } + + /// + /// Write Def Attribute + /// + /// + /// Style parsing supports x:ID, so check for this here + /// + public override void WriteDefAttribute(XamlDefAttributeNode xamlDefAttributeNode) + { + if (xamlDefAttributeNode.Name == BamlMapTable.NameString) + { + if (BamlRecordWriter != null) + { + BamlRecordWriter.WriteDefAttribute(xamlDefAttributeNode); + } + } + else + { +#if PBTCOMPILER + // Remember that x:Key was read in, since this key has precedence over + // the TargetType="{x:Type SomeType}" key that may also be present. + if (xamlDefAttributeNode.Name == XamlReaderHelper.DefinitionName && + _styleModeStack.Mode == StyleMode.Base) + { + _defNameFound = true; + } +#endif + + // Skip Uids for EventSetter, since they are not localizable. + if (!_inEventSetter || + xamlDefAttributeNode.Name != XamlReaderHelper.DefinitionUid) + { + base.WriteDefAttribute(xamlDefAttributeNode); + } + } + } + +#if PBTCOMPILER + /// + /// Write out a key to a dictionary that has been resolved at compile or parse + /// time to a Type object. + /// + public override void WriteDefAttributeKeyType(XamlDefAttributeKeyTypeNode xamlDefNode) + { + // Remember that x:Key was read in, since this key has precedence over + // the TargetType="{x:Type SomeType}" key that may also be present. + if (_styleModeStack.Mode == StyleMode.Base) + { + _defNameFound = true; + } + base.WriteDefAttributeKeyType(xamlDefNode); + } +#endif + + /// + /// Write Start of an Element, which is a tag of the form / + /// + /// + /// For style parsing, determine when it is withing a Trigger or + /// MultiTrigger section. This is done for validity checking of + /// unknown tags and attributes. + /// + public override void WriteElementStart(XamlElementStartNode xamlElementStartNode) + { + StyleMode mode = _styleModeStack.Mode; + int depth = _styleModeStack.Depth; + _setterOrTriggerPropertyInfo = null; + bool tagWritten = false; + + // The very first element encountered within a style block should be the + // target type tag, or a Setter. + if (mode == StyleMode.Base && depth > 0) + { + if (KnownTypes.Types[(int)KnownElements.SetterBase].IsAssignableFrom(xamlElementStartNode.ElementType)) + { + if (_setterPropertyEncountered) + { + ThrowException(SRID.StyleImpliedAndComplexChildren, + xamlElementStartNode.ElementType.Name, + XamlStyleSerializer.SettersPropertyName, + xamlElementStartNode.LineNumber, + xamlElementStartNode.LinePosition); + } + mode = StyleMode.Setters; + _setterElementEncountered = true; + } + else + { + ThrowException(SRID.StyleNoTopLevelElement, + xamlElementStartNode.ElementType.Name, + xamlElementStartNode.LineNumber, + xamlElementStartNode.LinePosition); + } + } + else if (mode == StyleMode.TriggerBase && + (xamlElementStartNode.ElementType == KnownTypes.Types[(int)KnownElements.Trigger] || + xamlElementStartNode.ElementType == KnownTypes.Types[(int)KnownElements.MultiTrigger] || + xamlElementStartNode.ElementType == KnownTypes.Types[(int)KnownElements.DataTrigger] || + xamlElementStartNode.ElementType == KnownTypes.Types[(int)KnownElements.MultiDataTrigger] || + xamlElementStartNode.ElementType == KnownTypes.Types[(int)KnownElements.EventTrigger])) + { + _inPropertyTriggerDepth = xamlElementStartNode.Depth; + } + else if (mode == StyleMode.TriggerBase && + (KnownTypes.Types[(int)KnownElements.SetterBase].IsAssignableFrom(xamlElementStartNode.ElementType))) + { + // Just entered the section of a Trigger + _inSetterDepth = xamlElementStartNode.Depth; + } +#if PBTCOMPILER + else if (mode == StyleMode.TargetTypeProperty && + InDeferLoadedSection && + depth >= 2 && + !_defNameFound) + { + // We have to treat TargetType="{x:Type SomeType}" as a key in a + // resource dictionary, if one is present. This means generating + // a series of baml records to use as the key for the defer loaded + // body of the Style. + if (depth == 2) + { + base.WriteKeyElementStart(xamlElementStartNode); + } + else + { + base.WriteElementStart(xamlElementStartNode); + } + + tagWritten = true; + } +#endif + + if (mode == StyleMode.Setters) + { + if (xamlElementStartNode.ElementType == KnownTypes.Types[(int)KnownElements.EventSetter]) + { +#if !PBTCOMPILER + ThrowException(SRID.StyleNoEventSetters, + xamlElementStartNode.LineNumber, + xamlElementStartNode.LinePosition); +#else + _inEventSetter = true; +#endif + } + else if ((depth == 2 && _setterElementEncountered) || + (depth == 3 && _setterPropertyEncountered)) + { + ThrowException(SRID.ParserNoSetterChild, + xamlElementStartNode.TypeFullName, + xamlElementStartNode.LineNumber, + xamlElementStartNode.LinePosition); + } + } + + // Handle custom serializers within the style section by creating an instance + // of that serializer and handing off control. + if (xamlElementStartNode.SerializerType != null && depth > 0) + { + XamlSerializer serializer; + if (xamlElementStartNode.SerializerType == typeof(XamlStyleSerializer)) + { +#if PBTCOMPILER + // reset the event scope so that any other event setters encountered in this + // style after the nested Style is done parsing will be added to a new scope + _isSameScope = false; +#endif + serializer = new XamlStyleSerializer(ParserHooks); + } + else if (xamlElementStartNode.SerializerType == typeof(XamlTemplateSerializer)) + { +#if PBTCOMPILER + // reset the event scope so that any other event setters encountered in this + // style after the nested Template is done parsing will be added to a new scope + _isSameScope = false; +#endif + serializer = new XamlTemplateSerializer(ParserHooks); + } + else + { + serializer = XamlTypeMapper.CreateInstance(xamlElementStartNode.SerializerType) as XamlSerializer; + } + if (serializer == null) + { + ThrowException(SRID.ParserNoSerializer, + xamlElementStartNode.TypeFullName, + xamlElementStartNode.LineNumber, + xamlElementStartNode.LinePosition); + } + else + { + + // If we're compiling (or otherwise producing baml), convert to baml. + // When we don't have a TreeBuilder, we're producing baml. + +#if !PBTCOMPILER + + if( TreeBuilder == null ) + { +#endif + serializer.ConvertXamlToBaml(TokenReader, + BamlRecordWriter == null ? ParserContext : BamlRecordWriter.ParserContext, + xamlElementStartNode, BamlRecordWriter); +#if !PBTCOMPILER + } + else + { + serializer.ConvertXamlToObject(TokenReader, StreamManager, + BamlRecordWriter.ParserContext, xamlElementStartNode, + TreeBuilder.RecordReader); + } +#endif + + } + } + else + { + _styleModeStack.Push(mode); + + if (!_inEventSetter) + { +#if PBTCOMPILER + // If we DO NOT need a dictionary key, then set the flag that says + // a key was already found so that one is not manufactured from + // the TargetType property. + if (mode == StyleMode.Base && depth == 0) + { + _defNameFound = !xamlElementStartNode.NeedsDictionaryKey; + } +#endif + if (!tagWritten) + { + base.WriteElementStart(xamlElementStartNode); + } + } + } + } + + /// + /// Write End Element + /// + /// + /// For style parsing, determine when it is withing a Trigger or + /// MultiTrigger section. This is done for validity checking of + /// unknown tags and attributes. + /// + public override void WriteElementEnd(XamlElementEndNode xamlElementEndNode) + { + StyleMode mode = _styleModeStack.Mode; + bool tagWritten = false; + + if (mode == StyleMode.TriggerBase && + xamlElementEndNode.Depth == _inSetterDepth) + { + // Just exited the section of a Trigger + _inSetterDepth = -1; + } + + if (xamlElementEndNode.Depth == _inPropertyTriggerDepth) + { + _inPropertyTriggerDepth = -1; + } + +#if PBTCOMPILER + if (_styleModeStack.Depth != 1 && + mode == StyleMode.TargetTypeProperty && + InDeferLoadedSection && + !_defNameFound) + { + // We have to treat TargetType="{x:Type SomeType}" as a key in a + // resource dictionary, if one is present. This means generating + // a series of baml records to use as the key for the defer loaded + // body of the Style in addition to generating the records to set + // the TargetType value. + if (_styleModeStack.Depth == 3) + { + base.WriteKeyElementEnd(xamlElementEndNode); + } + else + { + base.WriteElementEnd(xamlElementEndNode); + } + + tagWritten = true; + } +#endif + + _styleModeStack.Pop(); + + if (!_inEventSetter) + { + if (!tagWritten) + { + base.WriteElementEnd(xamlElementEndNode); + } + } + else if (mode == StyleMode.Setters) + { + _inEventSetter = false; + } + } + +#if PBTCOMPILER + /// + /// Write the start of a constructor parameter section + /// + public override void WriteConstructorParameterType( + XamlConstructorParameterTypeNode xamlConstructorParameterTypeNode) + { + if (_styleModeStack.Mode == StyleMode.TargetTypeProperty && + InDeferLoadedSection && + !_defNameFound) + { + // Generate a series of baml records to use as the key for the defer loaded + // body of the Style in addition to generating the records to set + // the normal constructor for an element. + base.WriteConstructorParameterType(xamlConstructorParameterTypeNode); + } + base.WriteConstructorParameterType(xamlConstructorParameterTypeNode); + } +#endif + + /// + /// Write the start of a constructor parameter section + /// + public override void WriteConstructorParametersStart(XamlConstructorParametersStartNode xamlConstructorParametersStartNode) + { +#if PBTCOMPILER + if (_styleModeStack.Mode == StyleMode.TargetTypeProperty && + InDeferLoadedSection && + !_defNameFound) + { + // We have to treat TargetType="{x:Type SomeType}" as a key in a + // resource dictionary, if one is present. This means generating + // a series of baml records to use as the key for the defer loaded + // body of the Style in addition to generating the records to set + // the TargetType value. + base.WriteConstructorParametersStart(xamlConstructorParametersStartNode); + } +#endif + + _styleModeStack.Push(); + base.WriteConstructorParametersStart(xamlConstructorParametersStartNode); + } + + /// + /// Write the end of a constructor parameter section + /// + public override void WriteConstructorParametersEnd(XamlConstructorParametersEndNode xamlConstructorParametersEndNode) + { +#if PBTCOMPILER + if (_styleModeStack.Mode == StyleMode.TargetTypeProperty && + InDeferLoadedSection && + !_defNameFound && + _styleModeStack.Depth > 2) + { + // We have to treat TargetType="{x:Type SomeType}" as a key in a + // resource dictionary, if one is present. This means generating + // a series of baml records to use as the key for the defer loaded + // body of the Style in addition to generating the records to set + // the TargetType value. + base.WriteConstructorParametersEnd(xamlConstructorParametersEndNode); + } +#endif + + base.WriteConstructorParametersEnd(xamlConstructorParametersEndNode); + _styleModeStack.Pop(); + } + + /// + /// Write start of a complex property + /// + /// + /// For style parsing, treat complex property tags as + /// xml element tags for the purpose of validity checking + /// + public override void WritePropertyComplexStart(XamlPropertyComplexStartNode xamlNode) + { + StyleMode mode = _styleModeStack.Mode; + + if (_styleModeStack.Depth == 1) + { + if (xamlNode.PropName == XamlStyleSerializer.TargetTypePropertyName) + { + mode = StyleMode.TargetTypeProperty; + } + else if (xamlNode.PropName == XamlStyleSerializer.BasedOnPropertyName) + { + mode = StyleMode.BasedOnProperty; + } + else + { + ThrowException(SRID.StyleUnknownProp, xamlNode.PropName, + xamlNode.LineNumber, xamlNode.LinePosition); + } + } + else if (mode == StyleMode.TriggerBase) + { + _visualTriggerComplexPropertyDepth++; + } +#if PBTCOMPILER + else if (mode == StyleMode.TargetTypeProperty && + InDeferLoadedSection && + !_defNameFound) + { + // We have to treat TargetType="{x:Type SomeType}" as a key in a + // resource dictionary, if one is present. This means generating + // a series of baml records to use as the key for the defer loaded + // body of the Style in addition to generating the records to set + // the TargetType value. + base.WritePropertyComplexStart(xamlNode); + } +#endif + + _styleModeStack.Push(mode); + base.WritePropertyComplexStart(xamlNode); + } + + /// + /// Write end of a complex property + /// + /// + /// For style parsing, treat complex property tags as + /// xml element tags for the purpose of validity checking + /// + public override void WritePropertyComplexEnd(XamlPropertyComplexEndNode xamlNode) + { + if (_styleModeStack.Mode == StyleMode.TriggerBase) + { + _visualTriggerComplexPropertyDepth--; + } +#if PBTCOMPILER + else if (_styleModeStack.Mode == StyleMode.TargetTypeProperty && + InDeferLoadedSection && + !_defNameFound && + _styleModeStack.Depth > 2) + { + // We have to treat TargetType="{x:Type SomeType}" as a key in a + // resource dictionary, if one is present. This means generating + // a series of baml records to use as the key for the defer loaded + // body of the Style in addition to generating the records to set + // the TargetType value. + base.WritePropertyComplexEnd(xamlNode); + } +#endif + + base.WritePropertyComplexEnd(xamlNode); + _styleModeStack.Pop(); + } + + /// + /// Write start of a list complex property + /// + /// + /// For style parsing, treat complex property tags as + /// xml element tags for the purpose of validity checking + /// + public override void WritePropertyIListStart(XamlPropertyIListStartNode xamlNode) + { + StyleMode mode = _styleModeStack.Mode; + int depth = _styleModeStack.Depth; + + if (depth == 1) + { + if (xamlNode.PropName == XamlStyleSerializer.VisualTriggersPropertyName) + { + mode = StyleMode.TriggerBase; + } + else if (xamlNode.PropName == XamlStyleSerializer.SettersPropertyName) + { + if (_setterElementEncountered) + { + ThrowException(SRID.StyleImpliedAndComplexChildren, + XamlStyleSerializer.SetterTagName, + xamlNode.PropName, + xamlNode.LineNumber, xamlNode.LinePosition); + } + mode = StyleMode.Setters; + _setterPropertyEncountered = true; + } + else + { + ThrowException(SRID.StyleUnknownProp, xamlNode.PropName, + xamlNode.LineNumber, xamlNode.LinePosition); + } + } + else if ((mode == StyleMode.TriggerBase || + mode == StyleMode.Setters) && + depth == 2) + { + mode = StyleMode.Base; + } + else if (mode == StyleMode.TriggerBase && + depth == 3) + { + if (xamlNode.PropName == XamlStyleSerializer.EventTriggerActions) + { + mode = StyleMode.TriggerActions; + } + } + + _styleModeStack.Push(mode); + base.WritePropertyIListStart(xamlNode); + } + + /// + /// Write end of a list complex property + /// + /// + /// For style parsing, treat complex property tags as + /// xml element tags for the purpose of validity checking when we're counting + /// element tags. + /// + public override void WritePropertyIListEnd(XamlPropertyIListEndNode xamlNode) + { +#if PBTCOMPILER + if (_styleModeStack.Mode == StyleMode.Setters) + { + _isSameScope = false; + } +#endif + + base.WritePropertyIListEnd(xamlNode); + _styleModeStack.Pop(); + } + + /// + /// Write Property Array Start + /// + public override void WritePropertyArrayStart(XamlPropertyArrayStartNode xamlPropertyArrayStartNode) + { + base.WritePropertyArrayStart(xamlPropertyArrayStartNode); + _styleModeStack.Push(); + } + + + /// + /// Write Property Array End + /// + public override void WritePropertyArrayEnd(XamlPropertyArrayEndNode xamlPropertyArrayEndNode) + { + base.WritePropertyArrayEnd(xamlPropertyArrayEndNode); + _styleModeStack.Pop(); + } + + /// + /// Write Property IDictionary Start + /// + public override void WritePropertyIDictionaryStart(XamlPropertyIDictionaryStartNode xamlPropertyIDictionaryStartNode) + { + StyleMode mode = _styleModeStack.Mode; + if (_styleModeStack.Depth == 1 && mode == StyleMode.Base) + { + if (xamlPropertyIDictionaryStartNode.PropName == XamlStyleSerializer.ResourcesPropertyName) + { + mode = StyleMode.Resources; + } + else + { + ThrowException(SRID.StyleUnknownProp, xamlPropertyIDictionaryStartNode.PropName, + xamlPropertyIDictionaryStartNode.LineNumber, xamlPropertyIDictionaryStartNode.LinePosition); + } + } + + base.WritePropertyIDictionaryStart(xamlPropertyIDictionaryStartNode); + _styleModeStack.Push(mode); + } + + + /// + /// Write Property IDictionary End + /// + public override void WritePropertyIDictionaryEnd(XamlPropertyIDictionaryEndNode xamlPropertyIDictionaryEndNode) + { + base.WritePropertyIDictionaryEnd(xamlPropertyIDictionaryEndNode); + _styleModeStack.Pop(); + } + + /// + /// Write Text node and do style related error checking + /// + public override void WriteText(XamlTextNode xamlTextNode) + { + StyleMode mode = _styleModeStack.Mode; + // Text is only valid within certain locations in the