Ejemplo n.º 1
0
        /// <summary>
        /// 实例。
        /// </summary>
        /// <param name="constant">常量。</param>
        public ICaseHandler Case(ConstantAst constant)
        {
            if (constant is null)
            {
                throw new ArgumentNullException(nameof(constant));
            }

            IPrivateCaseHandler handler;

            switch (switchValueKind)
            {
            case MySwitchValueKind.Arithmetic when IsArithmetic(constant.RuntimeType):
                handler = new SwitchCaseArithmeticAst(constant, RuntimeType);

                break;

            case MySwitchValueKind.RuntimeType:
                throw new AstException("当前流程控制为类型转换,请使用“{Case(VariableAst variable)}”方法处理!");

            case MySwitchValueKind.Equality:
                var types = new Type[2] {
                    switchValueType, constant.RuntimeType
                };
                MethodInfo comparison = switchValueType.GetMethod("op_Equality", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, types, null);

                if (comparison is null && !EmitUtils.AreEquivalent(switchValueType, constant.RuntimeType))
                {
                    comparison = constant.RuntimeType.GetMethod("op_Equality", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, types, null);
                }

                if (comparison is null && switchValueType.IsAssignableFrom(typeof(IEquatable <>).MakeGenericType(constant.RuntimeType)))
                {
                    comparison = switchValueType.GetMethod("Equals", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { constant.RuntimeType }, null);
                }

                if (comparison is null)
                {
                    throw new InvalidOperationException($"未找到“{constant.RuntimeType}”和“{switchValueType}”有效的比较函数!");
                }

                handler = new SwitchCaseEqualityAst(constant, comparison, RuntimeType);

                break;

            default:
                throw new NotSupportedException();
            }

            switchCases.Add(handler);

            return(handler);
        }
Ejemplo n.º 2
0
 public SwitchCaseArithmeticAst(ConstantAst constant, Type returnType) : base(returnType)
 {
     this.constant = constant;
 }
Ejemplo n.º 3
0
 public SwitchCase(ConstantAst value, AstExpression body)
 {
     Value = value;
     Body  = body;
 }
Ejemplo n.º 4
0
 public SwitchCaseEqualityAst(ConstantAst constant, MethodInfo comparison, Type returnType) : base(returnType)
 {
     this.constant   = constant;
     this.comparison = comparison;
 }