| /****************************************************************************  | 
| **  | 
| ** Copyright (C) 2018 The Qt Company Ltd.  | 
| ** Contact: https://www.qt.io/licensing/  | 
| **  | 
| ** This file is part of the Qt VS Tools.  | 
| **  | 
| ** $QT_BEGIN_LICENSE:GPL-EXCEPT$  | 
| ** Commercial License Usage  | 
| ** Licensees holding valid commercial Qt licenses may use this file in  | 
| ** accordance with the commercial license agreement provided with the  | 
| ** Software or, alternatively, in accordance with the terms contained in  | 
| ** a written agreement between you and The Qt Company. For licensing terms  | 
| ** and conditions see https://www.qt.io/terms-conditions. For further  | 
| ** information use the contact form at https://www.qt.io/contact-us.  | 
| **  | 
| ** GNU General Public License Usage  | 
| ** Alternatively, this file may be used under the terms of the GNU  | 
| ** General Public License version 3 as published by the Free Software  | 
| ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT  | 
| ** included in the packaging of this file. Please review the following  | 
| ** information to ensure the GNU General Public License requirements will  | 
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html.  | 
| **  | 
| ** $QT_END_LICENSE$  | 
| **  | 
| ****************************************************************************/  | 
|   | 
| using System;  | 
| using System.CodeDom;  | 
| using System.CodeDom.Compiler;  | 
| using System.IO;  | 
| using System.Linq;  | 
| using System.Runtime.Serialization;  | 
|   | 
| namespace QtVsTools.Qml.Debug.V4  | 
| {  | 
|     using Json;  | 
|   | 
|     [DataContract]  | 
|     class JsValue : Serializable<JsValue>  | 
|     {  | 
|         //  { "handle" : <handle>,  | 
|         //    "type"   : <"undefined", "null", "boolean", "number", "string", "object", "function"  | 
|         //               or "frame">  | 
|         //  }  | 
|         protected JsValue()  | 
|         { }  | 
|   | 
|         [DataMember(Name = "handle")]  | 
|         public int Handle { get; set; }  | 
|   | 
|         public enum DataType  | 
|         {  | 
|             [EnumString("undefined")] Undefined = 0,  | 
|             [EnumString("null")] Null,  | 
|             [EnumString("boolean")] Boolean,  | 
|             [EnumString("number")] Number,  | 
|             [EnumString("string")] String,  | 
|             [EnumString("object")] Object,  | 
|             [EnumString("function")] Function,  | 
|             [EnumString("frame")] Frame  | 
|         }  | 
|   | 
|         [DataMember(Name = "type")]  | 
|         protected string TypeString { get; set; }  | 
|   | 
|         public DataType Type  | 
|         {  | 
|             get { return SerializableEnum.Deserialize<DataType>(TypeString); }  | 
|             set { TypeString = SerializableEnum.Serialize<DataType>(value); }  | 
|         }  | 
|   | 
|         [DataMember(Name = "name")]  | 
|         public string Name { get; set; }  | 
|   | 
|         public override string ToString()  | 
|         {  | 
|             return string.Empty;  | 
|         }  | 
|   | 
|         protected override bool? IsCompatible(JsValue that)  | 
|         {  | 
|             System.Diagnostics.Debug.Assert(IsPrototype);  | 
|   | 
|             if (base.IsCompatible(that) == false)  | 
|                 return false;  | 
|   | 
|             if (that == null)  | 
|                 return false;  | 
|             if (string.IsNullOrEmpty(TypeString))  | 
|                 return null;  | 
|             return (this.TypeString == that.TypeString);  | 
|         }  | 
|   | 
|         public static JsValue Create<T>(T value)  | 
|         {  | 
|             return (JsPrimitive<T>)value;  | 
|         }  | 
|   | 
|         protected static readonly CodeDomProvider JScriptProvider  | 
|             = CodeDomProvider.CreateProvider("JScript");  | 
|     }  | 
|   | 
|     [DataContract]  | 
|     [SkipDeserialization]  | 
|     class JsError : JsValue  | 
|     {  | 
|         public string Message { get; set; }  | 
|   | 
|         public JsError()  | 
|         {  | 
|             Type = DataType.Undefined;  | 
|         }  | 
|   | 
|         protected override bool? IsCompatible(JsValue that)  | 
|         {  | 
|             System.Diagnostics.Debug.Assert(IsPrototype);  | 
|   | 
|             return false;  | 
|         }  | 
|   | 
|         public override string ToString()  | 
|         {  | 
|             return Message;  | 
|         }  | 
|     }  | 
|   | 
|     [DataContract]  | 
|     [SkipDeserialization]  | 
|     class JsPrimitive : JsValue  | 
|     {  | 
|         public static string Format(object obj)  | 
|         {  | 
|             using (var writer = new StringWriter()) {  | 
|                 JScriptProvider.GenerateCodeFromExpression(  | 
|                     new CodePrimitiveExpression(obj), writer, null);  | 
|                 return writer.ToString();  | 
|             }  | 
|         }  | 
|     }  | 
|   | 
|     [DataContract]  | 
|     class JsUndefined : JsPrimitive  | 
|     {  | 
|         //  {"handle":<handle>,"type":"undefined"}  | 
|         public JsUndefined()  | 
|         {  | 
|             Type = DataType.Undefined;  | 
|         }  | 
|   | 
|         public override string ToString()  | 
|         {  | 
|             return "undefined";  | 
|         }  | 
|     }  | 
|   | 
|     [DataContract]  | 
|     class JsNull : JsPrimitive  | 
|     {  | 
|         //  {"handle":<handle>,"type":"null"}  | 
|         public JsNull()  | 
|         {  | 
|             Type = DataType.Null;  | 
|         }  | 
|   | 
|         public override string ToString()  | 
|         {  | 
|             return "null";  | 
|         }  | 
|     }  | 
|   | 
|     [DataContract]  | 
|     class JsNumberSymbolic : JsPrimitive  | 
|     {  | 
|         //  {"handle":<handle>,"type":"null"}  | 
|         public JsNumberSymbolic()  | 
|         {  | 
|             Type = DataType.Number;  | 
|         }  | 
|   | 
|         [DataMember(Name = "value")]  | 
|         public virtual string Value { get; set; }  | 
|   | 
|         protected override bool? IsCompatible(JsValue obj)  | 
|         {  | 
|             System.Diagnostics.Debug.Assert(IsPrototype);  | 
|   | 
|             if (base.IsCompatible(obj) == false)  | 
|                 return false;  | 
|   | 
|             var that = obj as JsNumberSymbolic;  | 
|             if (that == null)  | 
|                 return null;  | 
|   | 
|             var symbolicValues = new[] { "NaN", "Infinity", "+Infinity", "-Infinity" };  | 
|             return symbolicValues.Contains(that.Value);  | 
|         }  | 
|   | 
|         public override string ToString()  | 
|         {  | 
|             return Value;  | 
|         }  | 
|     }  | 
|   | 
|     [DataContract]  | 
|     [SkipDeserialization]  | 
|     class JsPrimitive<T> : JsPrimitive  | 
|     {  | 
|         //  { "handle" : <handle>,  | 
|         //    "type"   : <"boolean", "number" or "string">  | 
|         //    "value"  : <JSON encoded value>  | 
|         //  }  | 
|         protected JsPrimitive()  | 
|         { }  | 
|   | 
|         [DataMember(Name = "value")]  | 
|         public virtual T Value { get; set; }  | 
|   | 
|         public static implicit operator JsPrimitive<T>(T value)  | 
|         {  | 
|             foreach (var subType in SubClass.Get(typeof(JsPrimitive<T>)).SubTypes) {  | 
|                 var valueType = subType.GetGenericArguments().FirstOrDefault();  | 
|                 if (valueType.IsAssignableFrom(typeof(T))) {  | 
|                     var _this = CreateInstance(subType) as JsPrimitive<T>;  | 
|                     if (_this == null)  | 
|                         return null;  | 
|                     _this.Value = value;  | 
|                     return _this;  | 
|                 }  | 
|             }  | 
|             return null;  | 
|         }  | 
|   | 
|         public static implicit operator T(JsPrimitive<T> _this)  | 
|         {  | 
|             return _this.Value;  | 
|         }  | 
|   | 
|         public override string ToString()  | 
|         {  | 
|             return Value.ToString();  | 
|         }  | 
|     }  | 
|   | 
|     [DataContract]  | 
|     class JsBoolean : JsPrimitive<bool>  | 
|     {  | 
|         public JsBoolean()  | 
|         {  | 
|             Type = DataType.Boolean;  | 
|         }  | 
|   | 
|         public override string ToString()  | 
|         {  | 
|             return Value ? "true" : "false";  | 
|         }  | 
|     }  | 
|   | 
|     [DataContract]  | 
|     class JsNumber : JsPrimitive<decimal>  | 
|     {  | 
|         public JsNumber()  | 
|         {  | 
|             Type = DataType.Number;  | 
|         }  | 
|   | 
|         public override string ToString()  | 
|         {  | 
|             if (Value - Math.Floor(Value) == 0)  | 
|                 return string.Format("{0:0}", Value);  | 
|             return Format(Value);  | 
|         }  | 
|     }  | 
|   | 
|     [DataContract]  | 
|     class JsString : JsPrimitive<string>  | 
|     {  | 
|         public JsString()  | 
|         {  | 
|             Type = DataType.String;  | 
|         }  | 
|   | 
|         public override string ToString()  | 
|         {  | 
|             return Format(Value);  | 
|         }  | 
|     }  | 
| }  |