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
- PropertyNames.cs
- FlowDecisionDesigner.xaml.cs
- ProxyHelper.cs
- PointValueSerializer.cs
- RangeEnumerable.cs
- ToolStripArrowRenderEventArgs.cs
- DataColumnCollection.cs
- FileCodeGroup.cs
- SafeCryptoHandles.cs
- DataKey.cs
- ReflectTypeDescriptionProvider.cs
- DbBuffer.cs
- Point3DAnimationUsingKeyFrames.cs
- AspNetRouteServiceHttpHandler.cs
- AppliedDeviceFiltersDialog.cs
- Propagator.JoinPropagator.cs
- SwitchLevelAttribute.cs
- BinaryObjectReader.cs
- KeyGestureConverter.cs
- VBIdentifierDesigner.xaml.cs
- TemplateXamlParser.cs
- HttpCapabilitiesEvaluator.cs
- RSATokenProvider.cs
- DataGridViewRowsRemovedEventArgs.cs
- WorkflowApplicationUnhandledExceptionEventArgs.cs
- RightsManagementManager.cs
- Msec.cs
- XmlNamespaceMapping.cs
- ApplicationSettingsBase.cs
- RootContext.cs
- Point3DAnimation.cs
- DataObjectFieldAttribute.cs
- AudioException.cs
- X509Certificate.cs
- SpotLight.cs
- SortKey.cs
- OrderedEnumerableRowCollection.cs
- DataTableNewRowEvent.cs
- MetadataLocation.cs
- FieldAccessException.cs
- DependencyPropertyDescriptor.cs
- ObjectToIdCache.cs
- IndexerNameAttribute.cs
- TypeForwardedToAttribute.cs
- DataControlReference.cs
- DataGridViewCellStyle.cs
- TimeStampChecker.cs
- CommentEmitter.cs
- PerSessionInstanceContextProvider.cs
- HelpKeywordAttribute.cs
- JournalEntryStack.cs
- RangeBaseAutomationPeer.cs
- ImplicitInputBrush.cs
- DataObjectPastingEventArgs.cs
- FixedTextView.cs
- NumericUpDown.cs
- Pool.cs
- InkCanvas.cs
- XmlConvert.cs
- SignatureToken.cs
- StorageSetMapping.cs
- VectorValueSerializer.cs
- ClientConvert.cs
- HTTPNotFoundHandler.cs
- WebColorConverter.cs
- BadImageFormatException.cs
- TableAdapterManagerGenerator.cs
- ConversionHelper.cs
- Parameter.cs
- AmbientEnvironment.cs
- BlurBitmapEffect.cs
- ControlCollection.cs
- VirtualDirectoryMappingCollection.cs
- DoubleSumAggregationOperator.cs
- BidOverLoads.cs
- ConstraintManager.cs
- Metafile.cs
- Margins.cs
- TransformProviderWrapper.cs
- DesignerActionTextItem.cs
- HitTestWithPointDrawingContextWalker.cs
- FilterElement.cs
- ByteRangeDownloader.cs
- BamlRecordHelper.cs
- IPHostEntry.cs
- _ConnectOverlappedAsyncResult.cs
- TypeViewSchema.cs
- WebPartEditorOkVerb.cs
- ReadOnlyHierarchicalDataSourceView.cs
- NativeObjectSecurity.cs
- UserNamePasswordClientCredential.cs
- ReaderContextStackData.cs
- ImageMapEventArgs.cs
- NullableDecimalMinMaxAggregationOperator.cs
- ApplicationActivator.cs
- IDReferencePropertyAttribute.cs
- WebPartEditorOkVerb.cs
- AssemblyCollection.cs
- IpcServerChannel.cs
- BitArray.cs