Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / XamlBuildTask / Microsoft / Build / Tasks / Xaml / XamlValidatingReader.cs / 1305376 / XamlValidatingReader.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace Microsoft.Build.Tasks.Xaml { using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Xaml; using System.Xaml.Schema; using System.Reflection; using System.Runtime; using System.Globalization; using System.Diagnostics.CodeAnalysis; using System.IO; internal class XamlValidatingReader : XamlWrappingReader { XamlStackWriter _stack = new XamlStackWriter(); Assembly assembly; Type definedType; string rootNamespace; string localAssemblyName; string realAssemblyName; public event EventHandlerOnValidationError; public XamlValidatingReader(XamlReader underlyingReader, Assembly assembly, string rootNamespace, string realAssemblyName) : base(underlyingReader) { this.assembly = assembly; this.definedType = null; this.rootNamespace = rootNamespace; this.localAssemblyName = assembly != null ? assembly.GetName().Name : null; this.realAssemblyName = realAssemblyName; } [SuppressMessage(FxCop.Category.Design, FxCop.Rule.DoNotCatchGeneralExceptionTypes, Justification = "Need to catch and log the exception here so that all the errors, including the exception thrown, are surfaced.")] public override bool Read() { if (!base.Read()) { return false; } try { if (_stack.Depth == 0) { State_AtRoot(); } else if (_stack.TopFrame.FrameType == XamlStackFrameType.Member) { if (_stack.TopFrame.IsSet() && !AllowsMultiple(_stack.TopFrame.Member)) { State_ExpectEndMember(); } else { State_InsideMember(); } } else { if (_stack.TopFrame.FrameType != XamlStackFrameType.Object && _stack.TopFrame.FrameType != XamlStackFrameType.GetObject) { ValidationError(SR.UnexpectedXaml); } State_InsideObject(); } } catch (FileLoadException e) { if (Fx.IsFatal(e)) { throw; } ValidationError(SR.AssemblyCannotBeResolved(XamlBuildTaskServices.FileNotLoaded)); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } ValidationError(e.Message); } return true; } protected virtual void ValidationError(string message, params object[] args) { EventHandler handler = OnValidationError; if (handler != null) { string formattedMessage = (args == null || args.Length == 0) ? message : string.Format(CultureInfo.InvariantCulture, message, args); handler(this, new ValidationEventArgs(formattedMessage, LineNumber, LinePosition)); } } private void State_AtRoot() { switch (NodeType) { case XamlNodeType.NamespaceDeclaration: return; case XamlNodeType.StartObject: ValidateUnknown(Type); break; default: ValidationError(SR.UnexpectedXaml); break; } _stack.WriteNode(this); } private void State_InsideObject() { switch (NodeType) { case XamlNodeType.NamespaceDeclaration: return; case XamlNodeType.StartMember: if (_stack.TopFrame.IsSet(Member)) { ValidationError(SR.UnexpectedXaml); } if (_stack.TopFrame.FrameType == XamlStackFrameType.GetObject) { ValidateMemberOnGetObject(Member); } else { ValidateUnknown(Member); ValidateMemberOnType(Member, _stack.TopFrame.Type); } break; case XamlNodeType.EndObject: break; default: ValidationError(SR.UnexpectedXamlDupMember); break; } _stack.WriteNode(this); } private void State_InsideMember() { switch (NodeType) { case XamlNodeType.NamespaceDeclaration: return; case XamlNodeType.StartObject: ValidateUnknown(Type); ValidateTypeToMemberOnStack(Type); break; case XamlNodeType.GetObject: ValidateGetObjectOnMember(_stack.TopFrame.Member); break; case XamlNodeType.Value: ValidateValueToMemberOnStack(Value); break; case XamlNodeType.EndMember: break; default: ValidationError(SR.UnexpectedXaml); break; } _stack.WriteNode(this); } private void State_ExpectEndMember() { if (NodeType != XamlNodeType.EndMember) { ValidationError(SR.UnexpectedXaml); } _stack.WriteNode(this); } private void ValidateGetObjectOnMember(XamlMember member) { if (member == XamlLanguage.Items || member == XamlLanguage.PositionalParameters) { ValidationError(SR.UnexpectedXaml); } else if (!member.IsUnknown && member != XamlLanguage.UnknownContent && !member.Type.IsCollection && !member.Type.IsDictionary) { ValidationError(SR.UnexpectedXaml); } } private void ValidateMemberOnGetObject(XamlMember member) { if (member != XamlLanguage.Items) { ValidationError(SR.UnexpectedXaml); } } private void ValidateMemberOnType(XamlMember member, XamlType type) { if (member.IsUnknown || type.IsUnknown) { return; } if (member.IsDirective) { if (member == XamlLanguage.Items) { if (!type.IsCollection && !type.IsDictionary) { ValidationError(SR.UnexpectedXamlDictionary(member.Name, GetXamlTypeName(_stack.TopFrame.Type))); } } if (member == XamlLanguage.Class && _stack.Depth > 1) { ValidationError(SR.UnexpectedXamlClass); } } else if (member.IsAttachable) { if (!type.CanAssignTo(member.TargetType)) { ValidationError(SR.UnexpectedXamlAttachableMember(member.Name, GetXamlTypeName(member.TargetType))); } } else if (!member.IsDirective && !type.CanAssignTo(member.DeclaringType)) { ValidationError(SR.UnexpectedXamlMemberNotAssignable(member.Name, GetXamlTypeName(type))); } } private void ValidateTypeToMemberOnStack(XamlType type) { if (type.IsUnknown) { return; } if (type == XamlLanguage.Null) { ValidateValueToMemberOnStack(null); } XamlMember member = _stack.TopFrame.Member; if (member == XamlLanguage.PositionalParameters || type.IsMarkupExtension || member.IsUnknown) { return; } if (member == XamlLanguage.Items) { XamlType collectionType = GetCollectionTypeOnStack(); if (collectionType == null || collectionType.IsUnknown || collectionType.AllowedContentTypes == null) { return; } if (!collectionType.AllowedContentTypes.Any(contentType => type.CanAssignTo(contentType))) { ValidationError(SR.UnassignableCollection(GetXamlTypeName(type), GetXamlTypeName(collectionType.ItemType), GetXamlTypeName(collectionType))); } } else if (member.IsDirective && (member.Type.IsCollection || member.Type.IsDictionary)) { XamlType collectionType = member.Type; if (collectionType == null || collectionType.IsUnknown || collectionType.AllowedContentTypes == null) { return; } if (!collectionType.AllowedContentTypes.Any(contentType => type.CanAssignTo(contentType))) { ValidationError(SR.UnassignableCollection(GetXamlTypeName(type), GetXamlTypeName(collectionType.ItemType), GetXamlTypeName(collectionType))); } } else if (!type.CanAssignTo(member.Type)) { if (member.DeferringLoader != null) { return; } if (NodeType == XamlNodeType.Value) { ValidationError(SR.UnassignableTypes(GetXamlTypeName(type), GetXamlTypeName(member.Type), member.Name)); } else { ValidationError(SR.UnassignableTypesObject(GetXamlTypeName(type), GetXamlTypeName(member.Type), member.Name)); } } } private void ValidateValueToMemberOnStack(object value) { XamlMember member = _stack.TopFrame.Member; if (member.IsUnknown) { return; } if (value != null) { if (member.IsEvent) { if (this.definedType != null && this.definedType.GetMethod(value as string, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) == null) { ValidationError(SR.UnexpectedXamlEventHandlerNotFound(value, definedType.FullName)); } return; } else if (member == XamlLanguage.Class) { string className = value as string; Fx.Assert(!string.IsNullOrEmpty(className), "ClassName cannot be null"); if (!string.IsNullOrEmpty(this.rootNamespace)) { className = this.rootNamespace + "." + className; } if (this.assembly != null) { this.definedType = this.assembly.GetType(className); } return; } else if (member.TypeConverter != null) { return; } XamlType typeOfValue = SchemaContext.GetXamlType(value.GetType()); ValidateTypeToMemberOnStack(typeOfValue); } else { if (member == XamlLanguage.PositionalParameters) { return; } if (member == XamlLanguage.Items) { XamlType collectionType = GetCollectionTypeOnStack(); if (collectionType == null || collectionType.IsUnknown || collectionType.AllowedContentTypes == null) { return; } if (!collectionType.AllowedContentTypes.Any(contentType => contentType.IsNullable)) { ValidationError(SR.UnassignableCollection("(null)", GetXamlTypeName(collectionType.ItemType), GetXamlTypeName(collectionType))); } } else { if (!member.Type.IsNullable) { ValidationError(SR.UnassignableTypes("(null)", GetXamlTypeName(member.Type), member.Name)); } } } } private bool AllowsMultiple(XamlMember member) { return member == XamlLanguage.Items || member == XamlLanguage.PositionalParameters || member == XamlLanguage.UnknownContent; } private XamlType GetCollectionTypeOnStack() { Fx.Assert(_stack.TopFrame.Member == XamlLanguage.Items, "CollectionType should have _Items member"); XamlType result; if (_stack.FrameAtDepth(_stack.Depth - 1).FrameType == XamlStackFrameType.GetObject) { XamlMember member = _stack.FrameAtDepth(_stack.Depth - 2).Member; if (member.IsUnknown) { return null; } result = member.Type; } else { result = _stack.FrameAtDepth(_stack.Depth - 1).Type; } Fx.Assert(result.IsUnknown || result.IsCollection || result.IsDictionary, "Incorrect Collection Type Encountered"); return result; } private void ValidateUnknown(XamlMember member) { if (member == XamlLanguage.UnknownContent) { ValidationError(SR.MemberUnknownContect(GetXamlTypeName(_stack.TopFrame.Type))); } else if (member.IsUnknown) { bool retryAttachable = false; XamlType declaringType = member.DeclaringType; if (_stack.Depth == 1 && declaringType.IsUnknown && !string.IsNullOrEmpty(this.rootNamespace) && this.definedType != null && declaringType.Name == this.definedType.Name) { // Need to handle the case where the namespace of a member on the document root // is missing the project root namespace string clrNs; if (XamlBuildTaskServices.TryExtractClrNs(declaringType.PreferredXamlNamespace, out clrNs)) { clrNs = string.IsNullOrEmpty(clrNs) ? this.rootNamespace : this.rootNamespace + "." + clrNs; if (clrNs == this.definedType.Namespace) { declaringType = SchemaContext.GetXamlType(this.definedType); retryAttachable = true; } } } XamlMember typeMember = declaringType.GetMember(member.Name); if (typeMember == null && retryAttachable) { typeMember = declaringType.GetAttachableMember(member.Name); } if (typeMember == null || typeMember.IsUnknown) { if (member.IsAttachable) { ValidationError(SR.UnresolvedAttachableMember(GetXamlTypeName(member.DeclaringType) + "." + member.Name)); } else if (member.IsDirective) { ValidationError(SR.UnresolvedDirective(member.PreferredXamlNamespace + ":" + member.Name)); } else { // Skip if declaring type is unknown as the member unknown error messages become redundant. if (declaringType != null && !declaringType.IsUnknown) { ValidationError(SR.UnresolvedMember(member.Name, GetXamlTypeName(declaringType))); } } } } } private void ValidateUnknown(XamlType type) { if (type.IsUnknown) { if (type.IsGeneric) { ThrowGenericTypeValidationError(type); } else { ThrowTypeValidationError(type); } } } private void ThrowGenericTypeValidationError(XamlType type) { IList unresolvedLeafTypeList = new List (); XamlBuildTaskServices.GetUnresolvedLeafTypeArg(type, ref unresolvedLeafTypeList); if (unresolvedLeafTypeList.Count > 1 || !unresolvedLeafTypeList.Contains(type)) { string fullTypeName = GetXamlTypeName(type); ValidationError(SR.UnresolvedGenericType(fullTypeName)); foreach (XamlType xamlType in unresolvedLeafTypeList) { ThrowTypeValidationError(xamlType); } } else { ThrowTypeValidationError(type); } } private void ThrowTypeValidationError(XamlType type) { string typeName, assemblyName, ns; if (XamlBuildTaskServices.GetTypeNameInAssemblyOrNamespace(type, this.localAssemblyName, this.realAssemblyName, out typeName, out assemblyName, out ns)) { ValidationError(SR.UnresolvedTypeWithAssemblyName(ns + "." + typeName, assemblyName)); } else { ValidationError(SR.UnresolvedTypeWithNamespace(typeName, ns)); } } private string GetXamlTypeName(XamlType type) { return XamlBuildTaskServices.GetTypeName(type, this.localAssemblyName, this.realAssemblyName); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CollectionExtensions.cs
- StrokeFIndices.cs
- CoTaskMemHandle.cs
- WindowsImpersonationContext.cs
- QueryableDataSourceHelper.cs
- StorageBasedPackageProperties.cs
- XPathExpr.cs
- AudioFormatConverter.cs
- HtmlAnchor.cs
- OdbcConnection.cs
- DataServicePagingProviderWrapper.cs
- BrowserCapabilitiesCodeGenerator.cs
- DefaultPropertyAttribute.cs
- SqlConnectionPoolGroupProviderInfo.cs
- SectionInformation.cs
- Serializer.cs
- RenderDataDrawingContext.cs
- PrintDialog.cs
- SymbolPair.cs
- LineUtil.cs
- PerfCounterSection.cs
- XPathChildIterator.cs
- DocumentPageViewAutomationPeer.cs
- DrawingAttributeSerializer.cs
- contentDescriptor.cs
- Privilege.cs
- DefaultValueTypeConverter.cs
- SqlSupersetValidator.cs
- PageBuildProvider.cs
- TableCell.cs
- AnimatedTypeHelpers.cs
- Tablet.cs
- BufferModesCollection.cs
- DependsOnAttribute.cs
- TextProperties.cs
- XdrBuilder.cs
- DataBindingList.cs
- Divide.cs
- ListView.cs
- ElementUtil.cs
- SerializeAbsoluteContext.cs
- DoubleConverter.cs
- XmlDocumentViewSchema.cs
- TargetInvocationException.cs
- EventData.cs
- BoundingRectTracker.cs
- FontUnit.cs
- ProtocolsConfigurationHandler.cs
- UnsafeNetInfoNativeMethods.cs
- RowSpanVector.cs
- KeyMatchBuilder.cs
- TextEditorLists.cs
- ClientSideQueueItem.cs
- NamedPipeActivation.cs
- CustomPopupPlacement.cs
- ParseChildrenAsPropertiesAttribute.cs
- XslCompiledTransform.cs
- QilInvoke.cs
- MissingFieldException.cs
- ElementNotAvailableException.cs
- ResourcePermissionBaseEntry.cs
- ExpressionReplacer.cs
- PrinterUnitConvert.cs
- Polygon.cs
- AttachedPropertyBrowsableForChildrenAttribute.cs
- PromptStyle.cs
- ShaderEffect.cs
- MemberAccessException.cs
- ClientBuildManagerCallback.cs
- ColorPalette.cs
- MultilineStringConverter.cs
- PartialTrustVisibleAssembly.cs
- Margins.cs
- RegexReplacement.cs
- SafeFileHandle.cs
- SafeEventHandle.cs
- SecurityValidationBehavior.cs
- CommandValueSerializer.cs
- MailWebEventProvider.cs
- RichTextBox.cs
- SmiEventStream.cs
- ToolStripSeparatorRenderEventArgs.cs
- ForceCopyBuildProvider.cs
- FrameworkElement.cs
- Int16Animation.cs
- DiffuseMaterial.cs
- NumericUpDownAcceleration.cs
- _SSPIWrapper.cs
- TextParaClient.cs
- _AutoWebProxyScriptWrapper.cs
- ProtectedConfigurationSection.cs
- HttpWriter.cs
- CollectionBuilder.cs
- UIInitializationException.cs
- XMLSchema.cs
- DataSourceControlBuilder.cs
- PropertyTab.cs
- OdbcConnectionFactory.cs
- securestring.cs
- KeyToListMap.cs