From 94220091d5077dcbde6d8bff5fee0c23b9ff3b42 Mon Sep 17 00:00:00 2001 From: Vatsan Madhavan Date: Thu, 4 Apr 2019 09:41:15 -0700 Subject: [PATCH 01/11] Add files needed for PresentationBuildTasks --- .../LocalizationDirectivesToLocFile.cs | 18 + .../Localization/LocalizationParserHooks.cs | 183 + .../MarkupCompiler/CompilationUnit.cs | 279 + .../MS/Internal/MarkupCompiler/FileUnit.cs | 55 + .../Internal/MarkupCompiler/MarkupCompiler.cs | 3540 +++++++++ .../MarkupCompiler/ParserExtension.cs | 948 +++ .../MS/Internal/Shared/SourceFileInfo.cs | 169 + .../Internal/Tasks/CompilerLocalReference.cs | 347 + .../MS/Internal/Tasks/CompilerState.cs | 388 + .../MS/Internal/Tasks/CompilerWrapper.cs | 437 ++ .../MS/Internal/Tasks/IPersistFileCheckSum.cs | 47 + .../Tasks/IVsMSBuildTaskFileManager.cs | 94 + .../Tasks/IncrementalCompileAnalyzer.cs | 614 ++ .../MS/Internal/Tasks/TaskFileService.cs | 447 ++ .../MS/Internal/Tasks/TaskHelper.cs | 383 + .../MS/Internal/Tasks/shared.cs | 85 + .../Microsoft.WinFx.targets | 953 +++ .../Build/Tasks/Windows/FileClassifier.cs | 381 + .../GenerateTemporaryTargetAssembly.cs | 550 ++ .../Build/Tasks/Windows/MarkupCompilePass1.cs | 1908 +++++ .../Build/Tasks/Windows/MarkupCompilePass2.cs | 900 +++ .../Windows/MergeLocalizationDirectives.cs | 150 + .../Build/Tasks/Windows/ResourcesGenerator.cs | 446 ++ .../Build/Tasks/Windows/UidManager.cs | 1361 ++++ .../UpdateManifestForBrowserApplication.cs | 228 + .../Microsoft/Build/Tasks/Windows/review.htm | 1396 ++++ .../PresentationBuildTasks.csproj | 211 + .../PresentationBuildTasks.sln | 37 + .../Resources/Strings.resx | 861 ++ .../Resources/window.ico | Bin 0 -> 3310 bytes .../src/PresentationBuildTasks/SR.cs | 34 + .../src/PresentationBuildTasks/dir.props | 11 + .../Globalization/LocalizationComments.cs | 461 ++ .../System/Windows/Markup/AttributeData.cs | 171 + .../System/Windows/Markup/BamlBinaryWriter.cs | 52 + .../System/Windows/Markup/BamlMapTable.cs | 1986 +++++ .../System/Windows/Markup/BamlRecordHelper.cs | 137 + .../System/Windows/Markup/BamlRecordWriter.cs | 1955 +++++ .../System/Windows/Markup/BamlRecords.cs | 5540 +++++++++++++ .../Windows/Markup/BamlVersionHeader.cs | 122 + .../System/Windows/Markup/KnownTypes.cs | 6311 +++++++++++++++ .../System/Windows/Markup/KnownTypesHelper.cs | 80 + .../Windows/Markup/MarkupExtensionParser.cs | 1769 +++++ .../System/Windows/Markup/ParserContext.cs | 990 +++ .../System/Windows/Markup/ParserHooks.cs | 68 + .../System/Windows/Markup/ParserStack.cs | 137 + .../System/Windows/Markup/StyleModeStack.cs | 74 + .../System/Windows/Markup/StyleXamlParser.cs | 1627 ++++ .../Windows/Markup/TemplateXamlParser.cs | 1890 +++++ .../System/Windows/Markup/TreeBuilder.cs | 343 + .../System/Windows/Markup/TypeContext.cs | 195 + .../Windows/Markup/XAMLParseException.cs | 570 ++ .../Windows/Markup/XamlBrushSerializer.cs | 170 + .../Markup/XamlInt32CollectionSerializer.cs | 361 + .../System/Windows/Markup/XamlNodes.cs | 2305 ++++++ .../System/Windows/Markup/XamlParser.cs | 1467 ++++ .../Windows/Markup/XamlPathDataSerializer.cs | 104 + .../Markup/XamlPoint3DCollectionSerializer.cs | 106 + .../Markup/XamlPointCollectionSerializer.cs | 111 + .../Windows/Markup/XamlReaderConstants.cs | 105 + .../System/Windows/Markup/XamlReaderHelper.cs | 6898 +++++++++++++++++ .../System/Windows/Markup/XamlSerializer.cs | 154 + .../Windows/Markup/XamlStyleSerializer.cs | 220 + .../Windows/Markup/XamlTemplateSerializer.cs | 261 + .../System/Windows/Markup/XamlTypeMapper.cs | 4625 +++++++++++ .../XamlVector3DCollectionSerializer.cs | 111 + .../Windows/Markup/XmlAttributeProperties.cs | 360 + .../System/Windows/Markup/XmlnsCache.cs | 471 ++ .../System/Windows/Markup/XmlnsDictionary.cs | 782 ++ .../System/Windows/SystemResourceKey.cs | 2198 ++++++ .../Shared/MS/Internal/ResourceIDHelper.cs | 84 + .../src/Shared/MS/Internal/SecurityHelper.cs | 1431 ++++ .../src/Shared/MS/Internal/TokenizerHelper.cs | 369 + .../Compoundfile/ContainerUtilities.cs | 524 ++ .../Packaging/Compoundfile/FormatVersion.cs | 571 ++ .../IO/Packaging/Compoundfile/versionPair.cs | 383 + .../Windows/Markup/DateTimeConverter2.cs | 72 + .../Windows/Markup/TypeTypeConverter.cs | 43 + 78 files changed, 66225 insertions(+) create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Localization/LocalizationDirectivesToLocFile.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Localization/LocalizationParserHooks.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/CompilationUnit.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/FileUnit.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/ParserExtension.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Shared/SourceFileInfo.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerLocalReference.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerState.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerWrapper.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IPersistFileCheckSum.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IVsMSBuildTaskFileManager.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/IncrementalCompileAnalyzer.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskFileService.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskHelper.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/shared.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.targets create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/FileClassifier.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/GenerateTemporaryTargetAssembly.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass1.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass2.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MergeLocalizationDirectives.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/ResourcesGenerator.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/UidManager.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/UpdateManifestForBrowserApplication.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/review.htm create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.csproj create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.sln create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Resources/Strings.resx create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Resources/window.ico create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/SR.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/dir.props create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Globalization/LocalizationComments.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/AttributeData.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlBinaryWriter.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlMapTable.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecordHelper.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecordWriter.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlRecords.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlVersionHeader.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/KnownTypes.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/KnownTypesHelper.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/MarkupExtensionParser.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserContext.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserHooks.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ParserStack.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/StyleModeStack.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/StyleXamlParser.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/TemplateXamlParser.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/TreeBuilder.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/TypeContext.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XAMLParseException.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlBrushSerializer.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlInt32CollectionSerializer.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlNodes.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlParser.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlPathDataSerializer.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlPoint3DCollectionSerializer.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlPointCollectionSerializer.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReaderConstants.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReaderHelper.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlSerializer.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlStyleSerializer.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlTemplateSerializer.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlTypeMapper.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlVector3DCollectionSerializer.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XmlAttributeProperties.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XmlnsCache.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XmlnsDictionary.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/SystemResourceKey.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/ResourceIDHelper.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/SecurityHelper.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/TokenizerHelper.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/Compoundfile/ContainerUtilities.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/Compoundfile/FormatVersion.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/Compoundfile/versionPair.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Markup/DateTimeConverter2.cs create mode 100644 src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Markup/TypeTypeConverter.cs 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..86a9c114c3b --- /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..99be5747d5b --- /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..db490bcbf6e --- /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..77725ea23a0 --- /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..93ee4cff84c --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs @@ -0,0 +1,3540 @@ +// 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 (VS#542946) was fixed but +// exposes a different bug (VS#572060) To work around the second bug, we +// remove the workaround for the first one. (RogerCh 20020918) + +// Note that #542946 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; + } + + // TODO: remove after Extension is made a required project attribute. + 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..7acac0f0777 --- /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..9964b7614d0 --- /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..1d668ba53e2 --- /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 alreay 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..131d3b47b73 --- /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..1f1a521725f --- /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 hanlder for the Compiler Errors + // + // sd brancx + // + 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..ea2c49dcf10 --- /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..28b1981edfe --- /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..932467d6207 --- /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 invidual 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..48b3288c583 --- /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..d1752544c00 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskHelper.cs @@ -0,0 +1,383 @@ +// 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 + // TODO: PresentationBuildTasks Porting : Review and refactor. No GAC for .NET core. + _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) + { + // TODO: PresentationBuildTasks Porting. AppDomains don't exist on .NET core. Update. + 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..981daabfea8 --- /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..f016f966514 --- /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 + + /// + /// Constrcutor + /// + 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..c35e5bdaa6f --- /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 tatk + /// ResolveAssemblyReference (RAR) again. + /// + /// + public sealed class GenerateTemporaryTargetAssembly : Task + { + //------------------------------------------------------ + // + // Constructors + // + //------------------------------------------------------ + + #region Constructors + + /// + /// Constrcutor + /// + 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..6d7de76d62a --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass1.cs @@ -0,0 +1,1908 @@ +// 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: hamidm 04/13/05 + // + // 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) + { + // TODO: TaskLoggingHelper does not contain a definition for MarkAsInactive + // Log.MarkAsInactive(); // see Dev11 354473 + 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 handding 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 xmal 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, delelet it + // so that it won't affec 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..d10e211107a --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/MarkupCompilePass2.cs @@ -0,0 +1,900 @@ +// 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) + { + // TODO: TaskLoggingHelper does not contain a definition for MarkAsInactive + // Log.MarkAsInactive(); // see Dev11 354473 + 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 xmal 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..467a15624c9 --- /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 + ">"); + + // keey 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..c9f8811fb44 --- /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..c42bbce17fa --- /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..3bd7142ec07 --- /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..5db4a87cd66 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.csproj @@ -0,0 +1,211 @@ + + + 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 0000000000000000000000000000000000000000..8b74374fbd5a12ae6077a0e741cda4de24d43135 GIT binary patch literal 3310 zcmb`JziS*v6vv+;!O6j3yKx~7tQZzzt{jNjD#1k>pTHcrjk_rw!>u^(2;?f)f&+`$ z>WU;JMH>GF2Z9vw)OHhtK!t+|L~ep0CX>&5vwL?^?2sZ)H?uSE*Y`VbW>+J!A)9jb z>Qzzscthk9p1Zqw{_6)KU!dFFRjbJN+ajND;m24#c4-@e0-0K$JGJEuI-h3abZS1@ zGo(#ru~=YF_LG!!MB`6Y+KGgqy#(iUaLFMDA~RR=)2TiW@>9qEXo1LbRt98NUMe+y zrv54iuvY&eUS6bS{YLv8j*xYK+Eeopx!T(b_r*HErd8 ztW%qE?KwgoE$5xlIE2HMViab#sZ6UFjkOfc9gZxb(@b4?XemZBY+7GenuD3OwnX62 zQHxv6&Apjxz<9W_yF=zWZR{jy&~m)a57+JGqnw^ioT+|%VSdq`=epx6FjoK4CUmnL z-%gpAkKkiV(dI{5Bfj&EqCsb7@Y^{TCR9rI^V1bIwOXWh+0d=iT51Xk?mSBHn*SH2xUqw_x$h zLQa4FPPVqTWP5vCE?>SZ*REZY>({SKx7(GQH*dx>@W%^Z; zd-syeY5D<)dFs$PboxY&?3 zRc!TWc+%@OQiBLygjEuMcqGfMK3+bOZ{@**2l};<$B!S&lP6E)*|TTz^yyQ1 z@#2NNeECvNPEO?Y>(}z;%^Nv8JCoBtlYBFu+y8XX?ME^l(KIhlx)1-mbce%XRXrRI zyWMvL4Xa`)4~G{$x@sLXQWVwQ^A1C`j+fFeivD^Ea`%@;8}!y4$lV6_TE9LH4NI^a za~P~VacDTKk_QD2D0Zx=QKk5@wTHT%A7T6Bs3_{Aqxrm^;8Rqseb7T#T%QW*u%~7U*Wj=1 zy_P`5@Qokk(a;Mrm{1^FANAoxu&AB7-U0b&GH0a))v_I80c=}s1=NKhlX?OG%hMg! z?b9t#k8IP$_xg2ll25>@0%MJ|@X4ee=;|!NezU>Uy|HS6S~CcHjRP1YP{F*Pvs;GN z0e$`riv7xx=dNN~a>;YgMy;EH0HZyntah)Vww^*gvg}pogB!1^mF8Tp1;2l2mxbd^ w?kSS=4#8dG26qa*qg*-8_l)=5QJTAg-WSf_T^7x~hWJg*@y>h7alWVg4cw*8-T(jq literal 0 HcmV?d00001 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/PresentationFramework/MS/Internal/Globalization/LocalizationComments.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Globalization/LocalizationComments.cs new file mode 100644 index 00000000000..d8d698227b4 --- /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/System/Windows/Markup/AttributeData.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/AttributeData.cs new file mode 100644 index 00000000000..023d0b93824 --- /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..a5c39abe862 --- /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..5e684548b3b --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/BamlMapTable.cs @@ -0,0 +1,1986 @@ +// 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 + // TODO: Relax assemby name restriction until runtime types are replaced with EcmaTypeDefinitions + 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..7fbd86c3b6a --- /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..c9f8417cfe2 --- /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..89dc2f82f68 --- /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..499f9ce4a4a --- /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..767f8225ef3 --- /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..1f0cd367ea2 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/MarkupExtensionParser.cs @@ -0,0 +1,1769 @@ +// 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) + { + // TODO - need better syntax checking here... + 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 (Bug 1160665). + // 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 + { + // Bug: Need to check 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..461a150f2d3 --- /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..8c9e87ebbec --- /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..a19765661bd --- /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..b3ed2cf3a87 --- /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..1758458ed3c --- /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 (See Windows bug 966137). 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