e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
209 lines
5.9 KiB
C#
209 lines
5.9 KiB
C#
//------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//------------------------------------------------------------
|
|
|
|
namespace Microsoft.Build.Tasks.Xaml
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Xaml;
|
|
using System.Runtime;
|
|
using XamlBuildTask;
|
|
|
|
internal enum XamlStackFrameType
|
|
{
|
|
None,
|
|
Object,
|
|
GetObject,
|
|
Member
|
|
}
|
|
|
|
internal struct XamlStackFrame
|
|
{
|
|
private static object s_setSentinel = new object();
|
|
|
|
private object _data;
|
|
private object _isSet;
|
|
|
|
public XamlStackFrameType FrameType { get; private set; }
|
|
|
|
public XamlType Type
|
|
{
|
|
get { return FrameType == XamlStackFrameType.Object ? (XamlType)_data : null; }
|
|
}
|
|
|
|
public XamlMember Member
|
|
{
|
|
get { return FrameType == XamlStackFrameType.Member ? (XamlMember)_data : null; }
|
|
}
|
|
|
|
public bool IsSet()
|
|
{
|
|
return _isSet != null;
|
|
}
|
|
|
|
public bool IsSet(XamlMember member)
|
|
{
|
|
HashSet<XamlMember> setMembers = _isSet as HashSet<XamlMember>;
|
|
return (setMembers == null) ? false : setMembers.Contains(member);
|
|
}
|
|
|
|
internal void Set()
|
|
{
|
|
if (FrameType != XamlStackFrameType.Member)
|
|
{
|
|
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.UnexpectedXaml));
|
|
}
|
|
_isSet = s_setSentinel;
|
|
}
|
|
|
|
internal void Set(XamlMember member)
|
|
{
|
|
if (FrameType != XamlStackFrameType.Object && FrameType != XamlStackFrameType.GetObject)
|
|
{
|
|
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.UnexpectedXaml));
|
|
}
|
|
HashSet<XamlMember> setMembers = _isSet as HashSet<XamlMember>;
|
|
if (setMembers == null)
|
|
{
|
|
setMembers = new HashSet<XamlMember>();
|
|
_isSet = setMembers;
|
|
}
|
|
if (!setMembers.Contains(member))
|
|
{
|
|
setMembers.Add(member);
|
|
}
|
|
}
|
|
|
|
internal static XamlStackFrame ForObject(XamlType type)
|
|
{
|
|
XamlStackFrame result = new XamlStackFrame();
|
|
result._data = type;
|
|
result.FrameType = XamlStackFrameType.Object;
|
|
return result;
|
|
}
|
|
|
|
internal static XamlStackFrame ForGetObject()
|
|
{
|
|
XamlStackFrame result = new XamlStackFrame();
|
|
result.FrameType = XamlStackFrameType.GetObject;
|
|
return result;
|
|
}
|
|
|
|
internal static XamlStackFrame ForMember(XamlMember member)
|
|
{
|
|
XamlStackFrame result = new XamlStackFrame();
|
|
result._data = member;
|
|
result.FrameType = XamlStackFrameType.Member;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
internal class XamlStackWriter : XamlWriter
|
|
{
|
|
List<XamlStackFrame> _stack = new List<XamlStackFrame>();
|
|
|
|
// the stack writer does not care about schema context
|
|
public override XamlSchemaContext SchemaContext { get { return null; } }
|
|
|
|
public int Depth { get { return _stack.Count; } }
|
|
|
|
public XamlStackFrame TopFrame
|
|
{
|
|
get
|
|
{
|
|
Fx.Assert(_stack.Count != 0, "Stack cannot be empty");
|
|
return _stack[_stack.Count - 1];
|
|
}
|
|
}
|
|
|
|
public XamlStackFrame FrameAtDepth(int ndx)
|
|
{
|
|
return _stack[ndx - 1];
|
|
}
|
|
|
|
|
|
public override void WriteEndMember()
|
|
{
|
|
if (TopFrame.FrameType != XamlStackFrameType.Member)
|
|
{
|
|
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.UnexpectedXaml));
|
|
}
|
|
PopStack();
|
|
}
|
|
|
|
public override void WriteEndObject()
|
|
{
|
|
if (TopFrame.FrameType != XamlStackFrameType.Object &&
|
|
TopFrame.FrameType != XamlStackFrameType.GetObject)
|
|
{
|
|
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.UnexpectedXaml));
|
|
}
|
|
PopStack();
|
|
}
|
|
|
|
public override void WriteGetObject()
|
|
{
|
|
SetTopFrame();
|
|
_stack.Add(XamlStackFrame.ForGetObject());
|
|
}
|
|
|
|
public override void WriteNamespace(NamespaceDeclaration namespaceDeclaration)
|
|
{
|
|
throw FxTrace.Exception.AsError(new NotImplementedException());
|
|
}
|
|
|
|
public override void WriteStartMember(XamlMember property)
|
|
{
|
|
if (property == null)
|
|
{
|
|
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.UnexpectedXamlValueNull("property")));
|
|
}
|
|
SetTopFrame(property);
|
|
_stack.Add(XamlStackFrame.ForMember(property));
|
|
}
|
|
|
|
public override void WriteStartObject(XamlType type)
|
|
{
|
|
if (type == null)
|
|
{
|
|
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.UnexpectedXamlValueNull("type")));
|
|
}
|
|
SetTopFrame();
|
|
_stack.Add(XamlStackFrame.ForObject(type));
|
|
}
|
|
|
|
public override void WriteValue(object value)
|
|
{
|
|
SetTopFrame();
|
|
}
|
|
|
|
private void PopStack()
|
|
{
|
|
_stack.RemoveAt(_stack.Count - 1);
|
|
}
|
|
|
|
private void SetTopFrame()
|
|
{
|
|
if (Depth > 0 && TopFrame.FrameType == XamlStackFrameType.Member)
|
|
{
|
|
TopFrame.Set();
|
|
}
|
|
}
|
|
|
|
private void SetTopFrame(XamlMember member)
|
|
{
|
|
if (Depth > 0 &&
|
|
(TopFrame.FrameType == XamlStackFrameType.GetObject ||
|
|
TopFrame.FrameType == XamlStackFrameType.Object))
|
|
{
|
|
TopFrame.Set(member);
|
|
}
|
|
}
|
|
}
|
|
}
|