コード例 #1
0
        private void CollectHighlight(ABnfGuess target_guess, ABnfElement element, List <ALanguageHighlightWordInfo> list)
        {
            if (element is ALittleScriptPropertyValueCustomTypeElement ||
                element is ALittleScriptVarAssignNameDecElement)
            {
                if (element.GetElementText() != m_key)
                {
                    return;
                }

                var error = element.GuessType(out ABnfGuess guess);
                if (error != null)
                {
                    return;
                }
                if (guess.GetValue() == target_guess.GetValue())
                {
                    var info = new ALanguageHighlightWordInfo();
                    info.start = element.GetStart();
                    info.end   = element.GetEnd();
                    list.Add(info);
                }
                return;
            }

            if (element is ABnfNodeElement)
            {
                var childs = (element as ABnfNodeElement).GetChilds();
                foreach (var child in childs)
                {
                    CollectHighlight(target_guess, child, list);
                }
            }
        }
        public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list)
        {
            guess_list = new List <ABnfGuess>();

            ABnfGuess guess = null;

            if (m_element.GetReflectCustomType() != null)
            {
                var custom_type = m_element.GetReflectCustomType().GetCustomType();
                if (custom_type == null)
                {
                    return(null);
                }

                var error = custom_type.GuessType(out guess);
                if (error != null)
                {
                    return(error);
                }
            }
            else if (m_element.GetReflectValueStat() != null)
            {
                var value_stat = m_element.GetReflectValueStat().GetValueStat();
                if (value_stat == null)
                {
                    return(null);
                }

                var error = value_stat.GuessType(out guess);
                if (error != null)
                {
                    return(error);
                }
            }

            if (guess is ALittleScriptGuessStruct)
            {
                return(ALittleScriptIndex.inst.FindALittleStructGuessList("ALittle", "StructInfo", out guess_list));
            }
            else if (guess is ALittleScriptGuessClass)
            {
                return(ALittleScriptIndex.inst.FindALittleStructGuessList("ALittle", "ClassInfo", out guess_list));
            }
            else if (guess is ALittleScriptGuessTemplate)
            {
                var guess_template = guess as ALittleScriptGuessTemplate;
                if (guess_template.template_extends is ALittleScriptGuessClass || guess_template.is_class)
                {
                    return(ALittleScriptIndex.inst.FindALittleStructGuessList("ALittle", "ClassInfo", out guess_list));
                }
                else if (guess_template.template_extends is ALittleScriptGuessStruct || guess_template.is_struct)
                {
                    return(ALittleScriptIndex.inst.FindALittleStructGuessList("ALittle", "StructInfo", out guess_list));
                }
            }
            return(null);
        }
コード例 #3
0
ファイル: ABnfElement.cs プロジェクト: SonnyX/VSIX-ALanguage
        // 获取第一个类型
        public virtual ABnfGuessError GuessType(out ABnfGuess guess)
        {
            var error = GuessTypes(out List <ABnfGuess> guess_list);

            if (error != null)
            {
                guess = null;
                return(error);
            }
            if (guess_list == null || guess_list.Count == 0)
            {
                guess = null;
                return(new ABnfGuessError(this, "Unknown type"));
            }

            guess = guess_list[0];
            return(null);
        }
コード例 #4
0
        public ALittleScriptGuessTemplate(ALittleScriptTemplatePairDecElement p_template_pair_dec
                                          , ABnfGuess p_template_extends
                                          , bool p_is_class, bool p_is_struct)
        {
            is_register       = ALittleScriptUtility.IsRegister(p_template_pair_dec);
            template_pair_dec = p_template_pair_dec;
            template_extends  = p_template_extends;
            is_class          = p_is_class;
            is_struct         = p_is_struct;
            if (p_template_extends != null)
            {
                is_const = p_template_extends.is_const;
            }

            var name_dec = template_pair_dec.GetTemplateNameDec();

            if (name_dec != null)
            {
                native_value = name_dec.GetElementText();
            }
        }
コード例 #5
0
        public ALittleScriptIndex()
        {
            // 基础变量
            sPrimitiveGuessMap     = new Dictionary <string, ABnfGuess>();
            sPrimitiveGuessListMap = new Dictionary <string, List <ABnfGuess> >();
            List <ABnfGuess> tmp;

            tmp = new List <ABnfGuess>(); sIntGuess = new ALittleScriptGuessInt(false); tmp.Add(sIntGuess); sPrimitiveGuessListMap.Add(sIntGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sIntGuess.GetValue(), sIntGuess);
            tmp = new List <ABnfGuess>(); sDoubleGuess = new ALittleScriptGuessDouble(false); tmp.Add(sDoubleGuess); sPrimitiveGuessListMap.Add(sDoubleGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sDoubleGuess.GetValue(), sDoubleGuess);
            tmp = new List <ABnfGuess>(); sStringGuess = new ALittleScriptGuessString(false); tmp.Add(sStringGuess); sPrimitiveGuessListMap.Add(sStringGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sStringGuess.GetValue(), sStringGuess);
            tmp = new List <ABnfGuess>(); sBoolGuess = new ALittleScriptGuessBool(false); tmp.Add(sBoolGuess); sPrimitiveGuessListMap.Add(sBoolGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sBoolGuess.GetValue(), sBoolGuess);
            tmp = new List <ABnfGuess>(); sLongGuess = new ALittleScriptGuessLong(false); tmp.Add(sLongGuess); sPrimitiveGuessListMap.Add(sLongGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sLongGuess.GetValue(), sLongGuess);
            tmp = new List <ABnfGuess>(); sAnyGuess = new ALittleScriptGuessAny(false); tmp.Add(sAnyGuess); sPrimitiveGuessListMap.Add(sAnyGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sAnyGuess.GetValue(), sAnyGuess);

            tmp = new List <ABnfGuess>(); sConstIntGuess = new ALittleScriptGuessInt(true); tmp.Add(sConstIntGuess); sPrimitiveGuessListMap.Add(sConstIntGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sConstIntGuess.GetValue(), sConstIntGuess);
            tmp = new List <ABnfGuess>(); sConstDoubleGuess = new ALittleScriptGuessDouble(true); tmp.Add(sConstDoubleGuess); sPrimitiveGuessListMap.Add(sConstDoubleGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sConstDoubleGuess.GetValue(), sConstDoubleGuess);
            tmp = new List <ABnfGuess>(); sConstStringGuess = new ALittleScriptGuessString(true); tmp.Add(sConstStringGuess); sPrimitiveGuessListMap.Add(sConstStringGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sConstStringGuess.GetValue(), sConstStringGuess);
            tmp = new List <ABnfGuess>(); sConstBoolGuess = new ALittleScriptGuessBool(true); tmp.Add(sConstBoolGuess); sPrimitiveGuessListMap.Add(sConstBoolGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sConstBoolGuess.GetValue(), sConstBoolGuess);
            tmp = new List <ABnfGuess>(); sConstLongGuess = new ALittleScriptGuessLong(true); tmp.Add(sConstLongGuess); sPrimitiveGuessListMap.Add(sConstLongGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sConstLongGuess.GetValue(), sConstLongGuess);
            tmp = new List <ABnfGuess>(); sConstAnyGuess = new ALittleScriptGuessAny(true); tmp.Add(sConstAnyGuess); sPrimitiveGuessListMap.Add(sConstAnyGuess.GetValue(), tmp); sPrimitiveGuessMap.Add(sConstAnyGuess.GetValue(), sConstAnyGuess);

            // null常量
            sConstNullGuess = new List <ABnfGuess>();
            sConstNullGuess.Add(new ALittleScriptGuessConst("null"));

            // 控制关键字
            sCtrlKeyWord.Add("if");
            sCtrlKeyWord.Add("elseif");
            sCtrlKeyWord.Add("else");
            sCtrlKeyWord.Add("do");
            sCtrlKeyWord.Add("while");
            sCtrlKeyWord.Add("return");
            sCtrlKeyWord.Add("break");
            sCtrlKeyWord.Add("continue");
            sCtrlKeyWord.Add("for");
            sCtrlKeyWord.Add("in");
            sCtrlKeyWord.Add("throw");
            sCtrlKeyWord.Add("assert");
        }
コード例 #6
0
        private ABnfGuessError CalcResolve(out List <ABnfElement> result_list, out ABnfGuess pre_type)
        {
            pre_type    = null;
            result_list = new List <ABnfElement>();
            if (m_key.Length == 0)
            {
                return(null);
            }

            // 获取父节点
            var property_value_dot_id     = m_element.GetParent() as ALittleScriptPropertyValueDotIdElement;
            var property_value_suffix     = property_value_dot_id.GetParent() as ALittleScriptPropertyValueSuffixElement;
            var property_value            = property_value_suffix.GetParent() as ALittleScriptPropertyValueElement;
            var property_value_first_type = property_value.GetPropertyValueFirstType();
            var suffix_list = property_value.GetPropertyValueSuffixList();

            // 获取所在位置
            int index = suffix_list.IndexOf(property_value_suffix);

            if (index == -1)
            {
                return(null);
            }

            ABnfGuessError error = null;

            if (index == 0)
            {
                error = property_value_first_type.GuessType(out pre_type);
            }
            else
            {
                error = suffix_list[index - 1].GuessType(out pre_type);
            }
            if (error != null)
            {
                return(error);
            }

            // 判断当前后缀是否是最后一个后缀
            ALittleScriptPropertyValueSuffixElement next_suffix = null;

            if (index + 1 < suffix_list.Count)
            {
                next_suffix = suffix_list[index + 1];
            }

            bool is_const = false;

            if (pre_type != null)
            {
                is_const = pre_type.is_const;
            }

            if (pre_type is ALittleScriptGuessTemplate)
            {
                pre_type = (pre_type as ALittleScriptGuessTemplate).template_extends;
                if (pre_type != null && is_const && !pre_type.is_const)
                {
                    pre_type          = pre_type.Clone();
                    pre_type.is_const = true;
                    pre_type.UpdateValue();
                }
            }

            if (pre_type == null)
            {
                return(null);
            }

            // 处理类的实例对象
            if (pre_type is ALittleScriptGuessClass)
            {
                m_class_guess = pre_type as ALittleScriptGuessClass;
                var class_dec = m_class_guess.class_dec;

                // 计算当前元素对这个类的访问权限
                int access_level = ALittleScriptUtility.CalcAccessLevelByTargetClassDecForElement(m_element, class_dec);

                // 所有成员变量
                var class_var_dec_list = new List <ABnfElement>();
                ALittleScriptUtility.FindClassAttrList(class_dec,
                                                       access_level, ALittleScriptUtility.ClassAttrType.VAR, m_key, class_var_dec_list, 100);
                foreach (var class_var_dec in class_var_dec_list)
                {
                    result_list.Add(class_var_dec);
                }

                var class_method_name_dec_list = new List <ABnfElement>();
                // 在当前情况下,只有当前property_value在等号的左边,并且是最后一个属性才是setter,否则都是getter
                if (next_suffix == null && property_value.GetParent() is ALittleScriptOpAssignExprElement)
                {
                    m_setter_list = new List <ABnfElement>();
                    ALittleScriptUtility.FindClassAttrList(class_dec, access_level, ALittleScriptUtility.ClassAttrType.SETTER, m_key, m_setter_list, 100);
                    class_method_name_dec_list.AddRange(m_setter_list);
                }
                else
                {
                    m_getter_list = new List <ABnfElement>();
                    ALittleScriptUtility.FindClassAttrList(class_dec, access_level, ALittleScriptUtility.ClassAttrType.GETTER, m_key, m_getter_list, 100);
                    class_method_name_dec_list.AddRange(m_getter_list);
                }
                // 所有成员函数
                ALittleScriptUtility.FindClassAttrList(class_dec, access_level, ALittleScriptUtility.ClassAttrType.FUN, m_key, class_method_name_dec_list, 100);
                // 添加函数名元素
                class_method_name_dec_list = ALittleScriptUtility.FilterSameName(class_method_name_dec_list);
                foreach (var class_method_name_dec in class_method_name_dec_list)
                {
                    result_list.Add(class_method_name_dec);
                }
                // 处理结构体的实例对象
            }
            else if (pre_type is ALittleScriptGuessStruct)
            {
                var struct_dec          = ((ALittleScriptGuessStruct)pre_type).struct_dec;
                var struct_var_dec_list = new List <ALittleScriptStructVarDecElement>();
                // 所有成员变量
                ALittleScriptUtility.FindStructVarDecList(struct_dec, m_key, struct_var_dec_list, 100);
                foreach (var struct_var_dec in struct_var_dec_list)
                {
                    result_list.Add(struct_var_dec);
                }
                // 比如 ALittleName.XXX
            }
            else if (pre_type is ALittleScriptGuessNamespaceName)
            {
                var    namespace_name_dec = ((ALittleScriptGuessNamespaceName)pre_type).namespace_name_dec;
                string namespace_name     = namespace_name_dec.GetElementText();
                // 所有枚举名
                var enum_name_dec_list = ALittleScriptIndex.inst.FindALittleNameDecList(
                    ALittleScriptUtility.ABnfElementType.ENUM_NAME, m_element.GetFile(), namespace_name, m_key, true);
                foreach (var enum_name_dec in enum_name_dec_list)
                {
                    result_list.Add(enum_name_dec);
                }
                // 所有全局函数
                var method_name_dec_list = ALittleScriptIndex.inst.FindALittleNameDecList(
                    ALittleScriptUtility.ABnfElementType.GLOBAL_METHOD, m_element.GetFile(), namespace_name, m_key, true);
                foreach (var method_name_dec in method_name_dec_list)
                {
                    result_list.Add(method_name_dec);
                }
                // 所有类名
                var class_name_dec_list = ALittleScriptIndex.inst.FindALittleNameDecList(
                    ALittleScriptUtility.ABnfElementType.CLASS_NAME, m_element.GetFile(), namespace_name, m_key, true);
                foreach (var class_name_dec in class_name_dec_list)
                {
                    result_list.Add(class_name_dec);
                }
                // 所有结构体名
                var struct_name_dec_list = ALittleScriptIndex.inst.FindALittleNameDecList(
                    ALittleScriptUtility.ABnfElementType.STRUCT_NAME, m_element.GetFile(), namespace_name, m_key, true);
                foreach (var struct_name_dec in struct_name_dec_list)
                {
                    result_list.Add(struct_name_dec);
                }
                // 所有单例
                var instance_name_dec_list = ALittleScriptIndex.inst.FindALittleNameDecList(
                    ALittleScriptUtility.ABnfElementType.INSTANCE_NAME, m_element.GetFile(), namespace_name, m_key, false);
                foreach (var instance_name_dec in instance_name_dec_list)
                {
                    result_list.Add(instance_name_dec);
                }
                // 比如 AClassName.XXX
            }
            else if (pre_type is ALittleScriptGuessClassName)
            {
                var class_name_dec = ((ALittleScriptGuessClassName)pre_type).class_name_dec;
                var class_dec      = class_name_dec.GetParent() as ALittleScriptClassDecElement;

                // 计算当前元素对这个类的访问权限
                int access_level = ALittleScriptUtility.CalcAccessLevelByTargetClassDecForElement(m_element, class_dec);

                // 所有静态函数
                var class_method_name_dec_list = new List <ABnfElement>();
                ALittleScriptUtility.FindClassAttrList(class_dec, access_level, ALittleScriptUtility.ClassAttrType.STATIC, m_key, class_method_name_dec_list, 100);

                // 如果后面那个是MethodCall,并且有两个参数的是setter,是一个参数的是getter,否则两个都不是
                if (next_suffix != null)
                {
                    var method_call_stat = next_suffix.GetPropertyValueMethodCall();
                    if (method_call_stat != null)
                    {
                        int paramCount = method_call_stat.GetValueStatList().Count;
                        if (paramCount == 1)
                        {
                            // 所有getter
                            ALittleScriptUtility.FindClassAttrList(class_dec, access_level, ALittleScriptUtility.ClassAttrType.GETTER, m_key, class_method_name_dec_list, 100);
                        }
                        else if (paramCount == 2)
                        {
                            // 所有setter
                            ALittleScriptUtility.FindClassAttrList(class_dec, access_level, ALittleScriptUtility.ClassAttrType.SETTER, m_key, class_method_name_dec_list, 100);
                        }
                    }
                }

                // 所有成员函数
                ALittleScriptUtility.FindClassAttrList(class_dec, access_level, ALittleScriptUtility.ClassAttrType.FUN, m_key, class_method_name_dec_list, 100);
                class_method_name_dec_list = ALittleScriptUtility.FilterSameName(class_method_name_dec_list);
                foreach (var class_method_name_dec in class_method_name_dec_list)
                {
                    result_list.Add(class_method_name_dec);
                }
                // 比如 AEnumName.XXX
            }
            else if (pre_type is ALittleScriptGuessEnumName)
            {
                // 所有枚举字段
                var enum_name_dec = ((ALittleScriptGuessEnumName)pre_type).enum_name_dec;
                var enum_dec      = enum_name_dec.GetParent() as ALittleScriptEnumDecElement;
                var var_dec_list  = new List <ALittleScriptEnumVarDecElement>();
                ALittleScriptUtility.FindEnumVarDecList(enum_dec, m_key, var_dec_list);
                foreach (var var_name_dec in var_dec_list)
                {
                    result_list.Add(var_name_dec);
                }
            }

            return(null);
        }
        private ABnfGuessError AnalysisTemplate(Dictionary <string, ABnfGuess> fill_map, ABnfGuess left_guess, ABnfElement right_src, ABnfGuess right_guess, bool assign_or_call)
        {
            // 如果值等于null,那么可以赋值
            if (right_guess.GetValue() == "null")
            {
                return(null);
            }

            // const是否可以赋值给非const
            if (assign_or_call)
            {
                if (left_guess.is_const && !right_guess.is_const)
                {
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ", 不能是:" + right_guess.GetValue()));
                }
            }
            else
            {
                // 如果不是基本变量类型(排除any),基本都是值传递,函数调用时就不用检查const
                if (!(left_guess is ALittleScriptGuessPrimitive) || left_guess.GetValueWithoutConst() == "any")
                {
                    if (!left_guess.is_const && right_guess.is_const)
                    {
                        return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ", 不能是:" + right_guess.GetValue()));
                    }
                }
            }

            // 如果任何一方是any,那么就认为可以相等
            if (left_guess is ALittleScriptGuessAny)
            {
                return(null);
            }

            if (left_guess is ALittleScriptGuessPrimitive ||
                left_guess is ALittleScriptGuessStruct)
            {
                return(ALittleScriptOp.GuessTypeEqual(left_guess, right_src, right_guess, assign_or_call, false));
            }

            if (left_guess is ALittleScriptGuessMap)
            {
                if (!(right_guess is ALittleScriptGuessMap))
                {
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                }


                var error = AnalysisTemplate(fill_map, ((ALittleScriptGuessMap)left_guess).key_type, right_src, ((ALittleScriptGuessMap)right_guess).key_type, false);
                if (error != null)
                {
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                }
                error = AnalysisTemplate(fill_map, ((ALittleScriptGuessMap)left_guess).value_type, right_src, ((ALittleScriptGuessMap)right_guess).value_type, false);
                if (error != null)
                {
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                }
                return(null);
            }

            if (left_guess is ALittleScriptGuessList)
            {
                if (!(right_guess is ALittleScriptGuessList))
                {
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                }
                var error = AnalysisTemplate(fill_map, ((ALittleScriptGuessList)left_guess).sub_type, right_src, ((ALittleScriptGuessList)right_guess).sub_type, false);
                if (error != null)
                {
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                }
                return(null);
            }

            if (left_guess is ALittleScriptGuessFunctor)
            {
                if (!(right_guess is ALittleScriptGuessFunctor))
                {
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                }
                ALittleScriptGuessFunctor left_guess_functor  = (ALittleScriptGuessFunctor)left_guess;
                ALittleScriptGuessFunctor right_guess_functor = (ALittleScriptGuessFunctor)right_guess;

                if (left_guess_functor.param_list.Count != right_guess_functor.param_list.Count ||
                    left_guess_functor.param_nullable_list.Count != right_guess_functor.param_nullable_list.Count ||
                    left_guess_functor.return_list.Count != right_guess_functor.return_list.Count ||
                    left_guess_functor.template_param_list.Count != right_guess_functor.template_param_list.Count ||
                    left_guess_functor.await_modifier != right_guess_functor.await_modifier ||
                    left_guess_functor.proto == null && right_guess_functor.proto != null ||
                    left_guess_functor.proto != null && right_guess_functor.proto == null ||
                    (left_guess_functor.proto != null && left_guess_functor.proto != right_guess_functor.proto) ||
                    left_guess_functor.param_tail == null && right_guess_functor.param_tail != null ||
                    left_guess_functor.param_tail != null && right_guess_functor.param_tail == null ||
                    left_guess_functor.return_tail == null && right_guess_functor.return_tail != null ||
                    left_guess_functor.return_tail != null && right_guess_functor.return_tail == null
                    )
                {
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                }

                for (int i = 0; i < left_guess_functor.template_param_list.Count; ++i)
                {
                    var error = AnalysisTemplate(fill_map, left_guess_functor.template_param_list[i], right_src, right_guess_functor.template_param_list[i], false);
                    if (error != null)
                    {
                        return(error);
                    }
                }

                for (int i = 0; i < left_guess_functor.param_list.Count; ++i)
                {
                    var error = AnalysisTemplate(fill_map, left_guess_functor.param_list[i], right_src, right_guess_functor.param_list[i], false);
                    if (error != null)
                    {
                        return(error);
                    }
                }

                for (int i = 0; i < left_guess_functor.param_nullable_list.Count; ++i)
                {
                    if (left_guess_functor.param_nullable_list[i] != right_guess_functor.param_nullable_list[i])
                    {
                        return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                    }
                }

                for (int i = 0; i < left_guess_functor.return_list.Count; ++i)
                {
                    var error = AnalysisTemplate(fill_map, left_guess_functor.return_list[i], right_src, right_guess_functor.return_list[i], false);
                    if (error != null)
                    {
                        return(error);
                    }
                }
                return(null);
            }

            if (left_guess is ALittleScriptGuessClass)
            {
                if (right_guess is ALittleScriptGuessTemplate)
                {
                    right_guess = (right_guess as ALittleScriptGuessTemplate).template_extends;
                }

                if (!(right_guess is ALittleScriptGuessClass))
                {
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                }

                if (left_guess.GetValue() == right_guess.GetValue())
                {
                    return(null);
                }

                var error = ALittleScriptUtility.IsClassSuper((left_guess as ALittleScriptGuessClass).class_dec, right_guess.GetValue(), out bool result);
                if (error != null)
                {
                    return(error);
                }
                if (result)
                {
                    return(null);
                }
                error = ALittleScriptUtility.IsClassSuper((right_guess as ALittleScriptGuessClass).class_dec, left_guess.GetValue(), out result);
                if (error != null)
                {
                    return(error);
                }
                if (result)
                {
                    return(null);
                }

                return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
            }

            if (left_guess is ALittleScriptGuessTemplate)
            {
                var left_guess_template = left_guess as ALittleScriptGuessTemplate;

                // 查看模板是否已经被填充,那么就按填充的检查
                if (fill_map.TryGetValue(left_guess_template.GetValue(), out ABnfGuess fill_guess))
                {
                    return(ALittleScriptOp.GuessTypeEqual(fill_guess, right_src, right_guess, false, false));
                }

                // 处理还未填充
                if (left_guess_template.template_extends != null)
                {
                    var error = AnalysisTemplate(fill_map, left_guess_template.template_extends, right_src, right_guess, false);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (right_guess.is_const)
                    {
                        right_guess = right_guess.Clone(); right_guess.is_const = false; right_guess.UpdateValue();
                    }
                    fill_map.Add(left_guess_template.GetValueWithoutConst(), right_guess);
                    return(null);
                }
                else if (left_guess_template.is_class)
                {
                    if (right_guess is ALittleScriptGuessClass)
                    {
                        if (right_guess.is_const)
                        {
                            right_guess = right_guess.Clone(); right_guess.is_const = false; right_guess.UpdateValue();
                        }
                        fill_map.Add(left_guess_template.GetValueWithoutConst(), right_guess);
                        return(null);
                    }
                    else if (right_guess is ALittleScriptGuessTemplate)
                    {
                        var right_guess_template = right_guess as ALittleScriptGuessTemplate;
                        if (right_guess_template.template_extends is ALittleScriptGuessClass || right_guess_template.is_class)
                        {
                            if (right_guess.is_const)
                            {
                                right_guess = right_guess.Clone(); right_guess.is_const = false; right_guess.UpdateValue();
                            }
                            fill_map.Add(right_guess_template.GetValueWithoutConst(), right_guess);
                            return(null);
                        }
                    }
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                }
                else if (left_guess_template.is_struct)
                {
                    if (right_guess is ALittleScriptGuessStruct)
                    {
                        if (right_guess.is_const)
                        {
                            right_guess = right_guess.Clone(); right_guess.is_const = false; right_guess.UpdateValue();
                        }
                        fill_map.Add(left_guess_template.GetValueWithoutConst(), right_guess);
                        return(null);
                    }
                    else if (right_guess is ALittleScriptGuessTemplate)
                    {
                        var right_guess_template = right_guess as ALittleScriptGuessTemplate;
                        if (right_guess_template.template_extends is ALittleScriptGuessStruct || right_guess_template.is_struct)
                        {
                            if (right_guess.is_const)
                            {
                                right_guess = right_guess.Clone(); right_guess.is_const = false; right_guess.UpdateValue();
                            }
                            fill_map.Add(left_guess_template.GetValue(), right_guess);
                            return(null);
                        }
                    }
                    return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
                }

                if (right_guess.is_const)
                {
                    right_guess = right_guess.Clone(); right_guess.is_const = false; right_guess.UpdateValue();
                }
                fill_map.Add(left_guess_template.GetValueWithoutConst(), right_guess);
                return(null);
            }

            return(new ABnfGuessError(right_src, "要求是" + left_guess.GetValue() + ",不能是:" + right_guess.GetValue()));
        }
        public ABnfGuessError GuessPreType(out ABnfGuess guess)
        {
            guess = null;

            // 获取父节点
            var property_value_suffix     = m_element.GetParent() as ALittleScriptPropertyValueSuffixElement;
            var property_value            = property_value_suffix.GetParent() as ALittleScriptPropertyValueElement;
            var property_value_first_type = property_value.GetPropertyValueFirstType();
            var suffix_list = property_value.GetPropertyValueSuffixList();

            // 获取所在位置
            int index = suffix_list.IndexOf(property_value_suffix);

            if (index == -1)
            {
                return(null);
            }

            // 获取前一个类型
            ABnfGuess      pre_type     = null;
            ABnfGuess      pre_pre_type = null;
            ABnfGuessError error        = null;

            if (index == 0)
            {
                error = property_value_first_type.GuessType(out pre_type);
                if (error != null)
                {
                    return(error);
                }
            }
            else if (index == 1)
            {
                error = suffix_list[index - 1].GuessType(out pre_type);
                if (error != null)
                {
                    return(error);
                }
                error = property_value_first_type.GuessType(out pre_pre_type);
                if (error != null)
                {
                    return(error);
                }
            }
            else
            {
                error = suffix_list[index - 1].GuessType(out pre_type);
                if (error != null)
                {
                    return(error);
                }
                error = suffix_list[index - 2].GuessType(out pre_pre_type);
                if (error != null)
                {
                    return(error);
                }
            }

            // 如果是Functor
            if (pre_type is ALittleScriptGuessFunctor)
            {
                var pre_type_functor = pre_type as ALittleScriptGuessFunctor;
                if (pre_pre_type is ALittleScriptGuessTemplate)
                {
                    pre_pre_type = (pre_pre_type as ALittleScriptGuessTemplate).template_extends;
                }

                // 如果再往前一个是一个Class实例对象,那么就要去掉第一个参数
                if (pre_pre_type is ALittleScriptGuessClass && pre_type_functor.param_list.Count > 0 &&
                    (pre_type_functor.element is ALittleScriptClassMethodDecElement ||
                     pre_type_functor.element is ALittleScriptClassGetterDecElement ||
                     pre_type_functor.element is ALittleScriptClassSetterDecElement))
                {
                    var new_pre_type_functor = new ALittleScriptGuessFunctor(pre_type_functor.element);
                    pre_type = new_pre_type_functor;

                    new_pre_type_functor.await_modifier = pre_type_functor.await_modifier;
                    new_pre_type_functor.const_modifier = pre_type_functor.const_modifier;
                    new_pre_type_functor.proto          = pre_type_functor.proto;
                    new_pre_type_functor.template_param_list.AddRange(pre_type_functor.template_param_list);
                    new_pre_type_functor.param_list.AddRange(pre_type_functor.param_list);
                    new_pre_type_functor.param_nullable_list.AddRange(pre_type_functor.param_nullable_list);
                    new_pre_type_functor.param_name_list.AddRange(pre_type_functor.param_name_list);
                    new_pre_type_functor.param_tail = pre_type_functor.param_tail;
                    new_pre_type_functor.return_list.AddRange(pre_type_functor.return_list);
                    new_pre_type_functor.return_tail = pre_type_functor.return_tail;

                    // 移除掉第一个参数
                    new_pre_type_functor.param_list.RemoveAt(0);
                    new_pre_type_functor.param_nullable_list.RemoveAt(0);
                    new_pre_type_functor.param_name_list.RemoveAt(0);

                    new_pre_type_functor.UpdateValue();
                }
            }

            guess = pre_type;
            return(null);
        }
コード例 #9
0
 public ALittleScriptGuessMap(ABnfGuess p_key_type, ABnfGuess p_value_type, bool p_is_const)
 {
     key_type   = p_key_type;
     value_type = p_value_type;
     is_const   = p_is_const;
 }
コード例 #10
0
 public ALittleScriptGuessList(ABnfGuess p_sub_type, bool p_is_const, bool p_is_native)
 {
     sub_type  = p_sub_type;
     is_const  = p_is_const;
     is_native = p_is_native;
 }
        public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list)
        {
            guess_list = new List <ABnfGuess>();

            ALittleScriptAllTypeElement all_type = null;
            ALittleScriptTemplateExtendsClassDecElement  extends_class_dec  = null;
            ALittleScriptTemplateExtendsStructDecElement extends_struct_dec = null;

            var extends = m_element.GetTemplateExtendsDec();

            if (extends != null)
            {
                all_type           = extends.GetAllType();
                extends_class_dec  = extends.GetTemplateExtendsClassDec();
                extends_struct_dec = extends.GetTemplateExtendsStructDec();
            }

            ABnfGuess template_extends = null;
            bool      is_class         = false;
            bool      is_struct        = false;

            if (all_type != null)
            {
                var error = all_type.GuessType(out ABnfGuess guess);
                if (error != null)
                {
                    return(error);
                }
                if (!(guess is ALittleScriptGuessClass) && !(guess is ALittleScriptGuessStruct))
                {
                    return(new ABnfGuessError(all_type, "继承的对象必须是一个类或者结构体"));
                }
                template_extends = guess;
            }
            else if (extends_class_dec != null)
            {
                is_class = true;
            }
            else if (extends_struct_dec != null)
            {
                is_struct = true;
            }

            if (m_element.GetParent() == null)
            {
                return(new ABnfGuessError(m_element, "没有父节点"));
            }
            var parent = m_element.GetParent();

            if (parent.GetParent() == null)
            {
                return(new ABnfGuessError(parent, "没有父节点"));
            }
            parent = parent.GetParent();

            // 根据定义区分类模板还是函数模板
            if (parent is ALittleScriptClassDecElement)
            {
                var info = new ALittleScriptGuessClassTemplate(m_element, template_extends, is_class, is_struct);
                info.UpdateValue();
                guess_list.Add(info);
            }
            else
            {
                var info = new ALittleScriptGuessMethodTemplate(m_element, template_extends, is_class, is_struct);
                info.UpdateValue();
                guess_list.Add(info);
            }
            return(null);
        }
        public override ABnfGuessError CheckError()
        {
            ABnfGuess guess = null;

            if (m_element.GetReflectCustomType() != null)
            {
                var custom_type = m_element.GetReflectCustomType().GetCustomType();
                if (custom_type == null)
                {
                    return(null);
                }

                var error = custom_type.GuessType(out guess);
                if (error != null)
                {
                    return(error);
                }
            }
            else if (m_element.GetReflectValueStat() != null)
            {
                var value_stat = m_element.GetReflectValueStat().GetValueStat();
                if (value_stat == null)
                {
                    return(null);
                }

                var error = ALittleScriptUtility.CalcReturnCount(value_stat, out int return_count, out _);
                if (error != null)
                {
                    return(error);
                }
                if (return_count != 1)
                {
                    return(new ABnfGuessError(value_stat, "表达式必须只能是一个返回值"));
                }

                error = value_stat.GuessType(out guess);
                if (error != null)
                {
                    return(error);
                }
            }

            if (guess is ALittleScriptGuessStruct || guess is ALittleScriptGuessClass)
            {
                return(null);
            }

            if (guess is ALittleScriptGuessTemplate)
            {
                var guess_template = guess as ALittleScriptGuessTemplate;
                if (guess_template.template_extends is ALittleScriptGuessClass || guess_template.is_class)
                {
                    return(null);
                }
                else if (m_element.GetReflectCustomType() != null &&
                         (guess_template.template_extends is ALittleScriptGuessStruct || guess_template.is_struct))
                {
                    return(null);
                }
            }

            return(new ABnfGuessError(m_element, "反射对象必须是struct或者是class以及class对象"));
        }
コード例 #13
0
        public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list)
        {
            guess_list = new List <ABnfGuess>();

            m_getter_list = null;
            m_setter_list = null;
            m_class_guess = null;

            var error = CalcResolve(out List <ABnfElement> result_list, out ABnfGuess pre_type);

            if (error != null)
            {
                return(error);
            }
            foreach (var result in result_list)
            {
                ABnfGuess guess = null;
                if (result is ALittleScriptClassVarDecElement)
                {
                    error = result.GuessType(out guess);
                    if (error != null)
                    {
                        return(error);
                    }

                    if (m_class_guess != null && guess is ALittleScriptGuessTemplate)
                    {
                        if (!m_class_guess.template_map.TryGetValue(guess.GetValueWithoutConst(), out ABnfGuess guess_template))
                        {
                            for (int i = 0; i < m_class_guess.template_list.Count; ++i)
                            {
                                guess_template = m_class_guess.template_list[i];

                                if (guess_template.GetValueWithoutConst() == guess.GetValueWithoutConst())
                                {
                                    break;
                                }
                            }
                        }

                        if (guess_template != null)
                        {
                            if (guess.is_const && !guess_template.is_const)
                            {
                                guess_template          = guess_template.Clone();
                                guess_template.is_const = true;
                                guess_template.UpdateValue();
                            }

                            guess = guess_template;
                        }
                    }
                }
                else if (result is ALittleScriptStructVarDecElement)
                {
                    error = result.GuessType(out guess);
                    if (error != null)
                    {
                        return(error);
                    }
                }
                else if (result is ALittleScriptEnumVarDecElement)
                {
                    error = result.GuessType(out guess);
                    if (error != null)
                    {
                        return(error);
                    }
                }
                else if (result is ALittleScriptMethodNameDecElement)
                {
                    error = result.GuessType(out guess);
                    if (error != null)
                    {
                        return(error);
                    }

                    // 如果前一个数据是const,那么调用的函数也必须是const
                    if (pre_type != null && pre_type.is_const)
                    {
                        var guess_functor = guess as ALittleScriptGuessFunctor;
                        if (guess_functor != null && !guess_functor.const_modifier)
                        {
                            return(new ABnfGuessError(m_element, "请使用带Const修饰的函数"));
                        }
                    }

                    if (result.GetParent() is ALittleScriptClassGetterDecElement)
                    {
                        if (m_getter_list != null && m_getter_list.IndexOf(result) >= 0 && guess is ALittleScriptGuessFunctor)
                        {
                            guess = ((ALittleScriptGuessFunctor)guess).return_list[0];
                        }
                    }
                    else if (result.GetParent() is ALittleScriptClassSetterDecElement)
                    {
                        if (m_setter_list != null && m_setter_list.IndexOf(result) >= 0 && guess is ALittleScriptGuessFunctor)
                        {
                            guess = ((ALittleScriptGuessFunctor)guess).param_list[1];
                        }
                    }
                    error = ReplaceTemplate(guess, out guess);
                    if (error != null)
                    {
                        return(error);
                    }
                }
                else if (result is ALittleScriptVarAssignNameDecElement)
                {
                    error = result.GuessType(out guess);
                    if (error != null)
                    {
                        return(error);
                    }
                }
                else if (result is ALittleScriptEnumNameDecElement)
                {
                    error = result.GuessType(out ABnfGuess enum_guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (!(enum_guess is ALittleScriptGuessEnum))
                    {
                        return(new ABnfGuessError(m_element, "ALittleEnumNameDec.guessType的结果不是ALittleGuessEnum"));
                    }
                    var enum_guess_enum = enum_guess as ALittleScriptGuessEnum;
                    var info            = new ALittleScriptGuessEnumName(enum_guess_enum.namespace_name, enum_guess_enum.enum_name, result as ALittleScriptEnumNameDecElement);
                    info.UpdateValue();
                    guess = info;
                }
                else if (result is ALittleScriptStructNameDecElement)
                {
                    error = result.GuessType(out ABnfGuess struct_guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (!(struct_guess is ALittleScriptGuessStruct))
                    {
                        return(new ABnfGuessError(m_element, "ALittleStructNameDec.guessType的结果不是ALittleGuessStruct"));
                    }
                    var struct_guess_struct = struct_guess as ALittleScriptGuessStruct;
                    var info = new ALittleScriptGuessStructName(struct_guess_struct.namespace_name, struct_guess_struct.struct_name, result as ALittleScriptStructNameDecElement);
                    info.UpdateValue();
                    guess = info;
                }
                else if (result is ALittleScriptClassNameDecElement)
                {
                    error = result.GuessType(out ABnfGuess class_guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (!(class_guess is ALittleScriptGuessClass))
                    {
                        return(new ABnfGuessError(m_element, "ALittleClassNameDec.guessType的结果不是ALittleGuessClass"));
                    }
                    var class_guess_class = class_guess as ALittleScriptGuessClass;
                    if (class_guess_class.template_list.Count > 0)
                    {
                        return(new ABnfGuessError(m_element, "模板类" + class_guess_class.GetValue() + "不能直接使用"));
                    }
                    var info = new ALittleScriptGuessClassName(class_guess_class.namespace_name, class_guess_class.class_name, result as ALittleScriptClassNameDecElement);
                    info.UpdateValue();
                    guess = info;
                }

                if (guess != null)
                {
                    if (pre_type != null && pre_type.is_const && !guess.is_const)
                    {
                        if (guess is ALittleScriptGuessPrimitive)
                        {
                            var guess_value = guess.GetValue();
                            ALittleScriptIndex.inst.sPrimitiveGuessMap.TryGetValue("const " + guess.GetValue(), out guess);
                            if (guess == null)
                            {
                                return(new ABnfGuessError(m_element, "找不到const " + guess_value));
                            }
                        }
                        else
                        {
                            guess          = guess.Clone();
                            guess.is_const = true;
                            guess.UpdateValue();
                        }
                    }
                    guess_list.Add(guess);
                }
            }

            m_getter_list = null;
            m_setter_list = null;
            m_class_guess = null;

            return(null);
        }
        public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list)
        {
            guess_list = new List <ABnfGuess>();
            // 标记是否已经包含了命名域,命名域的guess不要重复
            bool has_namespace = false;

            var result_list = CalcResolve();

            foreach (var result in result_list)
            {
                ABnfGuess guess = null;
                if (result is ALittleScriptNamespaceNameDecElement)
                {
                    if (!has_namespace)
                    {
                        var error = result.GuessType(out ABnfGuess result_guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        has_namespace = true;
                        var guess_namespace_name = new ALittleScriptGuessNamespaceName(
                            result_guess.GetValue(),
                            (ALittleScriptNamespaceNameDecElement)result
                            );
                        guess_namespace_name.UpdateValue();
                        guess = guess_namespace_name;
                    }
                }
                else if (result is ALittleScriptClassNameDecElement)
                {
                    var error = result.GuessType(out ABnfGuess class_guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (!(class_guess is ALittleScriptGuessClass))
                    {
                        return(new ABnfGuessError(m_element, "ALittleClassNameDec.guessType()的结果不是ALittleScriptGuessClass"));
                    }

                    var class_guess_class = class_guess as ALittleScriptGuessClass;
                    if (class_guess_class.template_list.Count > 0)
                    {
                        return(new ABnfGuessError(m_element, "模板类" + class_guess_class.GetValue() + "不能直接使用"));
                    }

                    var guess_class_name = new ALittleScriptGuessClassName(class_guess_class.namespace_name,
                                                                           class_guess_class.class_name, result as ALittleScriptClassNameDecElement);
                    guess_class_name.UpdateValue();
                    guess = guess_class_name;
                }
                else if (result is ALittleScriptStructNameDecElement)
                {
                    var error = result.GuessType(out ABnfGuess struct_guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (!(struct_guess is ALittleScriptGuessStruct))
                    {
                        return(new ABnfGuessError(m_element, "ALittleStructNameDec.guessType()的结果不是ALittleScriptGuessStruct"));
                    }
                    var struct_guess_struct = struct_guess as ALittleScriptGuessStruct;

                    var guess_struct_name = new ALittleScriptGuessStructName(struct_guess_struct.namespace_name,
                                                                             struct_guess_struct.struct_name, result as ALittleScriptStructNameDecElement);
                    guess_struct_name.UpdateValue();
                    guess = guess_struct_name;
                }
                else if (result is ALittleScriptEnumNameDecElement)
                {
                    var error = result.GuessType(out ABnfGuess enum_guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (!(enum_guess is ALittleScriptGuessEnum))
                    {
                        return(new ABnfGuessError(m_element, "ALittleEnumNameDec.guessType()的结果不是ALittleScriptGuessEnum"));
                    }
                    var enum_guess_enum = enum_guess as ALittleScriptGuessEnum;

                    var guess_enum_name = new ALittleScriptGuessEnumName(enum_guess_enum.namespace_name,
                                                                         enum_guess_enum.enum_name, result as ALittleScriptEnumNameDecElement);
                    guess_enum_name.UpdateValue();
                    guess = guess_enum_name;
                }
                else if (result is ALittleScriptMethodParamNameDecElement)
                {
                    var error = result.GuessType(out guess);
                    if (error != null)
                    {
                        return(error);
                    }
                }
                else if (result is ALittleScriptVarAssignNameDecElement)
                {
                    var error = result.GuessType(out guess);
                    if (error != null)
                    {
                        return(error);
                    }
                }
                else if (result is ALittleScriptMethodNameDecElement)
                {
                    var error = result.GuessType(out guess);
                    if (error != null)
                    {
                        return(error);
                    }
                }
                else if (result is ALittleScriptUsingNameDecElement)
                {
                    var error = result.GuessType(out guess);
                    if (error != null)
                    {
                        return(error);
                    }
                }

                if (guess != null)
                {
                    guess_list.Add(guess);
                }
            }

            return(null);
        }
コード例 #15
0
        public ABnfGuessError FindALittleStructGuess(string namespace_name, string name, out ABnfGuess guess)
        {
            var element = FindALittleNameDec(ALittleScriptUtility.ABnfElementType.STRUCT_NAME, null, namespace_name, name, true);

            if (element is ALittleScriptStructNameDecElement)
            {
                return(element.GuessType(out guess));
            }
            guess = null;
            return(null);
        }
        private ABnfGuessError CheckJsonStruct(ABnfElement element, ABnfGuess guess, HashSet <string> map)
        {
            if (guess is ALittleScriptGuessList)
            {
                var guess_list = guess as ALittleScriptGuessList;
                var error      = CheckJsonStruct(element, guess_list.sub_type, map);
                if (error != null)
                {
                    return(error);
                }
            }
            else if (guess is ALittleScriptGuessMap)
            {
                var guess_map = guess as ALittleScriptGuessMap;
                if (!(guess_map.key_type is ALittleScriptGuessString))
                {
                    return(new ABnfGuessError(element, "http协议接口的参数使用json序列化,内部使用的Map的key必须是string类型"));
                }
                var error = CheckJsonStruct(element, guess_map.value_type, map);
                if (error != null)
                {
                    return(error);
                }
            }
            else if (guess is ALittleScriptGuessStruct)
            {
                var guess_struct = guess as ALittleScriptGuessStruct;
                // 如果有继承,那么就检查一下继承
                if (guess_struct.struct_dec.GetStructExtendsDec() != null)
                {
                    var extends_name = guess_struct.struct_dec.GetStructExtendsDec().GetStructNameDec();
                    if (extends_name != null)
                    {
                        var extends_error = extends_name.GuessType(out ABnfGuess extends_guess);
                        if (extends_error != null)
                        {
                            return(extends_error);
                        }
                        var extends_struct_guess = extends_guess as ALittleScriptGuessStruct;
                        extends_error = CheckJsonStruct(element, extends_struct_guess, map);
                        if (extends_error != null)
                        {
                            return(extends_error);
                        }
                    }
                }

                // 如果已经识别了,那么就直接返回
                if (map.Contains(guess_struct.GetValueWithoutConst()))
                {
                    return(null);
                }
                map.Add(guess_struct.GetValueWithoutConst());

                var body_dec = guess_struct.struct_dec.GetStructBodyDec();
                if (body_dec == null)
                {
                    return(new ABnfGuessError(element, "struct不完整"));
                }

                var var_dec_list = body_dec.GetStructVarDecList();
                foreach (var var_dec in var_dec_list)
                {
                    var error = var_dec.GuessType(out guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    error = CheckJsonStruct(element, guess, map);
                    if (error != null)
                    {
                        return(error);
                    }
                }
            }
            else if (guess is ALittleScriptGuessClass)
            {
                return(new ABnfGuessError(element, "http协议接口的参数使用json序列化,内部不能使用类"));
            }
            else if (guess is ALittleScriptGuessFunctor)
            {
                return(new ABnfGuessError(element, "http协议接口的参数使用json序列化,内部不能使用函数"));
            }
            else if (guess.HasAny())
            {
                return(new ABnfGuessError(element, "http协议接口的参数使用json序列化,内部不能使用any"));
            }

            return(null);
        }
コード例 #17
0
        private ABnfGuessError ReplaceTemplate(ABnfGuess guess, out ABnfGuess result)
        {
            result = null;
            if (m_class_guess == null)
            {
                result = guess;
                return(null);
            }

            if (guess is ALittleScriptGuessTemplate && m_class_guess.template_map.Count > 0)
            {
                if (m_class_guess.template_map.TryGetValue(guess.GetValueWithoutConst(), out ABnfGuess guess_template))
                {
                    if (guess.is_const && !guess_template.is_const)
                    {
                        guess_template          = guess_template.Clone();
                        guess_template.is_const = true;
                        guess_template.UpdateValue();
                    }
                    result = guess_template;
                }
                else
                {
                    result = guess;
                }
                return(null);
            }

            if (guess is ALittleScriptGuessFunctor)
            {
                var guess_functor = guess as ALittleScriptGuessFunctor;
                var info          = new ALittleScriptGuessFunctor(guess_functor.element);
                info.await_modifier = guess_functor.await_modifier;
                info.const_modifier = guess_functor.const_modifier;
                info.proto          = guess_functor.proto;
                info.template_param_list.AddRange(guess_functor.template_param_list);
                info.param_tail = guess_functor.param_tail;
                info.param_name_list.AddRange(guess_functor.param_name_list);
                info.return_tail = guess_functor.return_tail;

                int start_index = 0;
                if (guess_functor.element is ALittleScriptClassMethodDecElement ||
                    guess_functor.element is ALittleScriptClassSetterDecElement ||
                    guess_functor.element is ALittleScriptClassGetterDecElement)
                {
                    info.param_list.Add(m_class_guess);
                    info.param_nullable_list.Add(false);
                    if (info.param_name_list.Count > 0)
                    {
                        info.param_name_list[0] = m_class_guess.GetValue();
                    }
                    start_index = 1;
                }
                for (int i = start_index; i < guess_functor.param_list.Count; ++i)
                {
                    var error = ReplaceTemplate(guess_functor.param_list[i], out ABnfGuess guess_info);
                    if (error != null)
                    {
                        return(error);
                    }
                    info.param_list.Add(guess_info);
                }
                for (int i = start_index; i < guess_functor.param_nullable_list.Count; ++i)
                {
                    info.param_nullable_list.Add(guess_functor.param_nullable_list[i]);
                }
                for (int i = 0; i < guess_functor.return_list.Count; ++i)
                {
                    var error = ReplaceTemplate(guess_functor.return_list[i], out ABnfGuess guess_info);
                    if (error != null)
                    {
                        return(error);
                    }
                    info.return_list.Add(guess_info);
                }
                info.UpdateValue();
                result = info;
                return(null);
            }

            if (guess is ALittleScriptGuessList)
            {
                var guess_list = guess as ALittleScriptGuessList;
                var error      = ReplaceTemplate(guess_list.sub_type, out ABnfGuess sub_info);
                if (error != null)
                {
                    return(error);
                }
                var info = new ALittleScriptGuessList(sub_info, guess_list.is_const, guess_list.is_native);
                info.UpdateValue();
                result = info;
                return(null);
            }

            if (guess is ALittleScriptGuessMap)
            {
                var guess_map = guess as ALittleScriptGuessMap;
                var error     = ReplaceTemplate(guess_map.key_type, out ABnfGuess key_info);
                if (error != null)
                {
                    return(error);
                }
                error = ReplaceTemplate(guess_map.value_type, out ABnfGuess value_info);
                if (error != null)
                {
                    return(error);
                }

                var info = new ALittleScriptGuessMap(key_info, value_info, guess.is_const);
                info.UpdateValue();
                result = info;
                return(null);
            }

            if (guess is ALittleScriptGuessClass)
            {
                var guess_class = guess as ALittleScriptGuessClass;
                var info        = new ALittleScriptGuessClass(guess_class.namespace_name,
                                                              guess_class.class_name, guess_class.class_dec, guess_class.using_name, guess_class.is_const, guess_class.is_native);
                info.template_list.AddRange(guess_class.template_list);
                foreach (var pair in guess_class.template_map)
                {
                    if (info.template_map.ContainsKey(pair.Key))
                    {
                        info.template_map.Remove(pair.Key);
                    }
                    var error = ReplaceTemplate(pair.Value, out ABnfGuess replace_guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    info.template_map.Add(pair.Key, replace_guess);
                }

                var src_class_dec      = guess_class.class_dec;
                var src_class_name_dec = src_class_dec.GetClassNameDec();
                if (src_class_name_dec == null)
                {
                    return(new ABnfGuessError(m_element, "类模板没有定义类名"));
                }
                info.UpdateValue();
                result = info;
                return(null);
            }

            result = guess;
            return(null);
        }