Пример #1
0
        public override ABnfGuess Clone()
        {
            var guess = new ALittleScriptGuessFunctor(element);

            guess.template_param_list.AddRange(template_param_list);
            guess.param_list.AddRange(param_list);
            guess.param_nullable_list.AddRange(param_nullable_list);
            guess.param_name_list.AddRange(param_name_list);
            guess.param_tail = param_tail;
            guess.return_list.AddRange(return_list);
            guess.return_tail    = return_tail;
            guess.proto          = proto;
            guess.await_modifier = await_modifier;
            guess.const_modifier = const_modifier;
            guess.UpdateValue();
            return(guess);
        }
        private ABnfGuessError CheckTemplateMap(Dictionary <string, ALittleScriptGuessTemplate> src_map, Dictionary <string, ABnfGuess> fill_map, out ALittleScriptGuessFunctor guess)
        {
            guess = null;
            var error = GuessPreType(out ABnfGuess pre_type);

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

            // 如果需要处理
            if (!(pre_type is ALittleScriptGuessFunctor))
            {
                return(null);
            }
            ALittleScriptGuessFunctor pre_type_functor = (ALittleScriptGuessFunctor)pre_type;

            var value_stat_list = m_element.GetValueStatList();

            if (pre_type_functor.param_list.Count < value_stat_list.Count && pre_type_functor.param_tail == null)
            {
                return(new ABnfGuessError(m_element, "函数调用最多需要" + pre_type_functor.param_list.Count + "个参数,不能是:" + value_stat_list.Count + "个"));
            }

            // 检查模板参数
            if (pre_type_functor.template_param_list.Count > 0)
            {
                foreach (var template_param in pre_type_functor.template_param_list)
                {
                    if (src_map.ContainsKey(template_param.GetValue()))
                    {
                        src_map.Remove(template_param.GetValue());
                    }
                    src_map.Add(template_param.GetValue(), template_param);
                }

                var method_template = m_element.GetPropertyValueMethodTemplate();
                if (method_template != null)
                {
                    var all_type_list = method_template.GetAllTypeList();
                    if (all_type_list.Count > pre_type_functor.template_param_list.Count)
                    {
                        return(new ABnfGuessError(m_element, "函数调用最多需要" + pre_type_functor.template_param_list.Count + "个模板参数,不能是:" + all_type_list.Count + "个"));
                    }

                    for (int i = 0; i < all_type_list.Count; ++i)
                    {
                        error = all_type_list[i].GuessType(out ABnfGuess all_type_guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        error = ALittleScriptOp.GuessTypeEqual(pre_type_functor.template_param_list[i], all_type_list[i], all_type_guess, false, false);
                        if (error != null)
                        {
                            return(error);
                        }
                        var key = pre_type_functor.template_param_list[i].GetValueWithoutConst();
                        if (fill_map.ContainsKey(key))
                        {
                            fill_map.Remove(key);
                        }
                        if (all_type_guess.is_const)
                        {
                            all_type_guess = all_type_guess.Clone(); all_type_guess.is_const = false; all_type_guess.UpdateValue();
                        }
                        fill_map.Add(key, all_type_guess);
                    }
                }

                // 根据填充的参数来分析以及判断
                for (int i = 0; i < value_stat_list.Count; ++i)
                {
                    var value_stat = value_stat_list[i];
                    error = value_stat.GuessType(out ABnfGuess value_stat_guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    // 如果参数返回的类型是tail,那么就可以不用检查
                    if (value_stat_guess is ALittleScriptGuessReturnTail)
                    {
                        continue;
                    }
                    if (i >= pre_type_functor.param_list.Count)
                    {
                        break;
                    }

                    // 逐个分析,并且填充模板
                    error = AnalysisTemplate(fill_map, pre_type_functor.param_list[i], value_stat, value_stat_guess, false);
                    if (error != null)
                    {
                        return(error);
                    }
                }

                // 判断如果还未有模板解析,就报错
                foreach (var pair in src_map)
                {
                    if (!fill_map.ContainsKey(pair.Key))
                    {
                        return(new ABnfGuessError(m_element, pair.Key + "模板无法解析"));
                    }
                }
            }

            guess = pre_type_functor;
            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);
        }
        public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list)
        {
            guess_list = new List <ABnfGuess>();
            var parent = m_element.GetParent();

            // 处理getter
            if (parent is ALittleScriptClassGetterDecElement)
            {
                var class_getter_dec  = parent as ALittleScriptClassGetterDecElement;
                var class_element_dec = class_getter_dec.GetParent() as ALittleScriptClassElementDecElement;
                var class_body_dec    = class_element_dec.GetParent();
                var class_dec         = class_body_dec.GetParent() as ALittleScriptClassDecElement;

                var info = new ALittleScriptGuessFunctor(class_getter_dec);
                info.const_modifier = ALittleScriptUtility.IsConst(class_element_dec.GetModifierList());

                // 第一个参数是类
                var error = class_dec.GuessType(out ABnfGuess class_guess);
                if (error != null)
                {
                    return(error);
                }
                info.param_list.Add(class_guess);
                info.param_nullable_list.Add(false);
                info.param_name_list.Add(class_guess.GetValue());

                // 添加返回值列表
                var all_type = class_getter_dec.GetAllType();
                if (all_type == null)
                {
                    return(new ABnfGuessError(m_element, "指向的getter函数没有定义返回值"));
                }
                error = all_type.GuessType(out ABnfGuess all_type_guess);
                if (error != null)
                {
                    return(error);
                }
                info.return_list.Add(all_type_guess);

                info.UpdateValue();
                guess_list.Add(info);
            }
            else if (parent is ALittleScriptClassSetterDecElement)
            {
                var class_setter_dec  = parent as ALittleScriptClassSetterDecElement;
                var class_element_dec = class_setter_dec.GetParent() as ALittleScriptClassElementDecElement;
                var class_body_dec    = class_element_dec.GetParent();
                var class_dec         = class_body_dec.GetParent() as ALittleScriptClassDecElement;

                var info = new ALittleScriptGuessFunctor(class_setter_dec);
                info.const_modifier = ALittleScriptUtility.IsConst(class_element_dec.GetModifierList());

                // 第一个参数是类
                var error = class_dec.GuessType(out ABnfGuess class_guess);
                if (error != null)
                {
                    return(error);
                }
                info.param_list.Add(class_guess);
                info.param_nullable_list.Add(false);
                info.param_name_list.Add(class_guess.GetValue());

                var param_dec = class_setter_dec.GetMethodSetterParamDec();
                if (param_dec == null)
                {
                    return(new ABnfGuessError(m_element, "指向的setter函数没有定义参数"));
                }

                // 添加参数列表
                var one_dec = param_dec.GetMethodParamOneDec();
                if (one_dec == null)
                {
                    return(new ABnfGuessError(m_element, "指向的setter函数没有定义参数"));
                }
                var all_type = one_dec.GetAllType();
                if (all_type == null)
                {
                    return(new ABnfGuessError(m_element, "指向的setter函数没有定义参数类型"));
                }
                error = all_type.GuessType(out ABnfGuess all_type_guess);
                if (error != null)
                {
                    return(error);
                }
                info.param_list.Add(all_type_guess);
                info.param_nullable_list.Add(ALittleScriptUtility.IsNullable(one_dec.GetModifierList()));
                if (one_dec.GetMethodParamNameDec() != null)
                {
                    info.param_name_list.Add(one_dec.GetMethodParamNameDec().GetElementText());
                }
                else
                {
                    info.param_name_list.Add("");
                }

                info.UpdateValue();
                guess_list.Add(info);
            }
            else if (parent is ALittleScriptClassMethodDecElement)
            {
                var class_method_dec  = parent as ALittleScriptClassMethodDecElement;
                var class_element_dec = class_method_dec.GetParent() as ALittleScriptClassElementDecElement;
                var class_body_dec    = class_element_dec.GetParent();
                var class_dec         = class_body_dec.GetParent() as ALittleScriptClassDecElement;

                var info     = new ALittleScriptGuessFunctor(class_method_dec);
                var modifier = class_element_dec.GetModifierList();
                info.const_modifier = ALittleScriptUtility.IsConst(class_element_dec.GetModifierList());
                info.await_modifier = ALittleScriptUtility.GetCoroutineType(modifier) == "await";

                // 第一个参数是类
                var error = class_dec.GuessType(out ABnfGuess class_guess);
                if (error != null)
                {
                    return(error);
                }
                info.param_list.Add(class_guess);
                info.param_nullable_list.Add(false);
                info.param_name_list.Add(class_guess.GetValue());

                // 添加模板参数列表
                var template_dec = class_method_dec.GetTemplateDec();
                if (template_dec != null)
                {
                    error = template_dec.GuessTypes(out List <ABnfGuess> template_guess_list);
                    if (error != null)
                    {
                        return(error);
                    }
                    foreach (var guess in template_guess_list)
                    {
                        if (!(guess is ALittleScriptGuessTemplate))
                        {
                            return(new ABnfGuessError(m_element, "template_dec.GuessTypes()取到的不是ALittleScriptGuessTemplate"));
                        }
                        info.template_param_list.Add(guess as ALittleScriptGuessTemplate);
                    }
                }

                // 添加参数列表
                var param_dec = class_method_dec.GetMethodParamDec();
                if (param_dec != null)
                {
                    var one_dec_list = param_dec.GetMethodParamOneDecList();
                    for (int i = 0; i < one_dec_list.Count; ++i)
                    {
                        var one_dec    = one_dec_list[i];
                        var all_type   = one_dec.GetAllType();
                        var param_tail = one_dec.GetMethodParamTailDec();
                        if (all_type != null)
                        {
                            error = all_type.GuessType(out ABnfGuess all_type_guess);
                            if (error != null)
                            {
                                return(error);
                            }
                            info.param_list.Add(all_type_guess);
                            info.param_nullable_list.Add(ALittleScriptUtility.IsNullable(one_dec.GetModifierList()));
                            if (one_dec.GetMethodParamNameDec() != null)
                            {
                                info.param_name_list.Add(one_dec.GetMethodParamNameDec().GetElementText());
                            }
                            else
                            {
                                info.param_name_list.Add("");
                            }
                        }
                        else if (param_tail != null)
                        {
                            if (i + 1 != one_dec_list.Count)
                            {
                                return(new ABnfGuessError(one_dec, "参数占位符必须定义在最后"));
                            }
                            error = param_tail.GuessType(out info.param_tail);
                            if (error != null)
                            {
                                return(error);
                            }
                        }
                    }
                }

                // 添加返回值列表
                var return_dec = class_method_dec.GetMethodReturnDec();
                if (return_dec != null)
                {
                    var one_dec_list = return_dec.GetMethodReturnOneDecList();
                    for (int i = 0; i < one_dec_list.Count; ++i)
                    {
                        var one_dec     = one_dec_list[i];
                        var all_type    = one_dec.GetAllType();
                        var return_tail = one_dec.GetMethodReturnTailDec();
                        if (all_type != null)
                        {
                            error = all_type.GuessType(out ABnfGuess all_type_guess);
                            if (error != null)
                            {
                                return(error);
                            }
                            info.return_list.Add(all_type_guess);
                        }
                        else if (return_tail != null)
                        {
                            if (i + 1 != one_dec_list.Count)
                            {
                                return(new ABnfGuessError(one_dec, "返回值占位符必须定义在最后"));
                            }
                            error = return_tail.GuessType(out info.return_tail);
                            if (error != null)
                            {
                                return(error);
                            }
                        }
                    }
                }
                info.UpdateValue();
                guess_list.Add(info);
            }
            else if (parent is ALittleScriptClassStaticDecElement)
            {
                var class_static_dec  = parent as ALittleScriptClassStaticDecElement;
                var class_element_dec = class_static_dec.GetParent() as ALittleScriptClassElementDecElement;

                var info = new ALittleScriptGuessFunctor(class_static_dec);
                info.await_modifier = ALittleScriptUtility.GetCoroutineType(class_element_dec.GetModifierList()) == "await";

                // 添加模板参数列表
                var template_dec = class_static_dec.GetTemplateDec();
                if (template_dec != null)
                {
                    var error = template_dec.GuessTypes(out List <ABnfGuess> template_guess_list);
                    if (error != null)
                    {
                        return(error);
                    }
                    foreach (var guess in template_guess_list)
                    {
                        if (!(guess is ALittleScriptGuessTemplate))
                        {
                            return(new ABnfGuessError(m_element, "template_dec.GuessTypes()取到的不是ALittleScriptGuessTemplate"));
                        }
                        info.template_param_list.Add(guess as ALittleScriptGuessTemplate);
                    }
                }

                // 添加参数列表
                var param_dec = class_static_dec.GetMethodParamDec();
                if (param_dec != null)
                {
                    var one_dec_list = param_dec.GetMethodParamOneDecList();
                    for (int i = 0; i < one_dec_list.Count; ++i)
                    {
                        var one_dec    = one_dec_list[i];
                        var all_type   = one_dec.GetAllType();
                        var param_tail = one_dec.GetMethodParamTailDec();
                        if (all_type != null)
                        {
                            var error = all_type.GuessType(out ABnfGuess all_type_guess);
                            if (error != null)
                            {
                                return(error);
                            }
                            info.param_list.Add(all_type_guess);
                            info.param_nullable_list.Add(ALittleScriptUtility.IsNullable(one_dec.GetModifierList()));
                            if (one_dec.GetMethodParamNameDec() != null)
                            {
                                info.param_name_list.Add(one_dec.GetMethodParamNameDec().GetElementText());
                            }
                            else
                            {
                                info.param_name_list.Add("");
                            }
                        }
                        else if (param_tail != null)
                        {
                            if (i + 1 != one_dec_list.Count)
                            {
                                return(new ABnfGuessError(one_dec, "参数占位符必须定义在最后"));
                            }
                            var error = param_tail.GuessType(out info.param_tail);
                            if (error != null)
                            {
                                return(error);
                            }
                        }
                    }
                }

                // 添加返回值列表
                var return_dec = class_static_dec.GetMethodReturnDec();
                if (return_dec != null)
                {
                    var one_dec_list = return_dec.GetMethodReturnOneDecList();
                    for (int i = 0; i < one_dec_list.Count; ++i)
                    {
                        var one_dec     = one_dec_list[i];
                        var all_type    = one_dec.GetAllType();
                        var return_tail = one_dec.GetMethodReturnTailDec();
                        if (all_type != null)
                        {
                            var error = all_type.GuessType(out ABnfGuess all_type_guess);
                            if (error != null)
                            {
                                return(error);
                            }
                            info.return_list.Add(all_type_guess);
                        }
                        else if (return_tail != null)
                        {
                            if (i + 1 != one_dec_list.Count)
                            {
                                return(new ABnfGuessError(one_dec, "返回值占位符必须定义在最后"));
                            }
                            var error = return_tail.GuessType(out info.return_tail);
                            if (error != null)
                            {
                                return(error);
                            }
                        }
                    }
                }
                info.UpdateValue();
                guess_list.Add(info);
            }
            else if (parent is ALittleScriptGlobalMethodDecElement)
            {
                var global_method_dec     = parent as ALittleScriptGlobalMethodDecElement;
                var namespace_element_dec = global_method_dec.GetParent() as ALittleScriptNamespaceElementDecElement;

                var info = new ALittleScriptGuessFunctor(global_method_dec);
                info.await_modifier = ALittleScriptUtility.GetCoroutineType(namespace_element_dec.GetModifierList()) == "await";

                var protocol_type = ALittleScriptUtility.GetProtocolType(namespace_element_dec.GetModifierList());
                if (protocol_type != null)
                {
                    ABnfElement error_element = global_method_dec.GetMethodNameDec();
                    if (error_element == null)
                    {
                        error_element = global_method_dec;
                    }

                    if (global_method_dec.GetTemplateDec() != null)
                    {
                        return(new ABnfGuessError(error_element, "带" + info.proto + "不能定义函数模板"));
                    }

                    // 如果是带协议注解,那么一定是一个await
                    info.await_modifier = true;
                    info.proto          = protocol_type;

                    var param_dec = global_method_dec.GetMethodParamDec();
                    if (param_dec == null)
                    {
                        return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数必须是两个参数"));
                    }
                    var one_dec_list = param_dec.GetMethodParamOneDecList();
                    if (one_dec_list.Count != 2)
                    {
                        return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数必须是两个参数"));
                    }
                    if (ALittleScriptUtility.IsNullable(one_dec_list[0].GetModifierList()) || ALittleScriptUtility.IsNullable(one_dec_list[1].GetModifierList()))
                    {
                        return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数参数不能使用Nullable修饰"));
                    }
                    var all_type = one_dec_list[1].GetAllType();
                    if (all_type == null)
                    {
                        return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数,第二个参数没有定义类型"));
                    }
                    var error = all_type.GuessType(out ABnfGuess guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (!(guess is ALittleScriptGuessStruct))
                    {
                        return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数第二个参数必须是struct"));
                    }

                    if (info.proto == "Http")
                    {
                        ABnfElement element = ALittleScriptIndex.inst.FindALittleNameDec(ALittleScriptUtility.ABnfElementType.CLASS_NAME, m_element.GetFile(), "ALittle", "IHttpSender", true);
                        if (!(element is ALittleScriptClassNameDecElement))
                        {
                            return(new ABnfGuessError(error_element, "语言框架中找不到ALittle.IHttpSender"));
                        }
                        var class_name_dec = element as ALittleScriptClassNameDecElement;
                        error = class_name_dec.GuessType(out ABnfGuess class_name_dec_guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        info.param_list.Add(class_name_dec_guess);
                        info.param_nullable_list.Add(false);
                        info.param_name_list.Add("sender");
                        info.param_list.Add(guess);
                        info.param_nullable_list.Add(false);
                        info.param_name_list.Add("param");

                        var return_dec = global_method_dec.GetMethodReturnDec();
                        if (return_dec == null)
                        {
                            return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数返回值必须是struct"));
                        }
                        var return_one_list = return_dec.GetMethodReturnOneDecList();
                        if (return_one_list.Count != 1)
                        {
                            return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数返回值有且仅有一个struct"));
                        }
                        var return_one_all_type = return_one_list[0].GetAllType();
                        if (return_one_all_type == null)
                        {
                            return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数返回值有且仅有一个struct"));
                        }
                        error = return_one_all_type.GuessType(out ABnfGuess return_guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        if (!(return_guess is ALittleScriptGuessStruct))
                        {
                            return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数返回值必须是struct"));
                        }
                        info.return_list.Add(ALittleScriptIndex.inst.sStringGuess);
                        info.return_list.Add(return_guess);
                    }
                    else if (info.proto == "HttpDownload")
                    {
                        ABnfElement element = ALittleScriptIndex.inst.FindALittleNameDec(ALittleScriptUtility.ABnfElementType.CLASS_NAME, m_element.GetFile(), "ALittle", "IHttpFileSender", true);
                        if (!(element is ALittleScriptClassNameDecElement))
                        {
                            return(new ABnfGuessError(error_element, "语言框架中找不到ALittle.IHttpFileSender"));
                        }
                        var class_name_dec = element as ALittleScriptClassNameDecElement;
                        error = class_name_dec.GuessType(out ABnfGuess class_name_dec_guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        info.param_list.Add(class_name_dec_guess);
                        info.param_nullable_list.Add(false);
                        info.param_name_list.Add("sender");
                        info.param_list.Add(guess);
                        info.param_nullable_list.Add(false);
                        info.param_name_list.Add("param");

                        info.return_list.Add(ALittleScriptIndex.inst.sStringGuess);
                        error = element.GuessType(out ABnfGuess sender_guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        info.return_list.Add(sender_guess);
                    }
                    else if (info.proto == "HttpUpload")
                    {
                        ABnfElement element = ALittleScriptIndex.inst.FindALittleNameDec(ALittleScriptUtility.ABnfElementType.CLASS_NAME, m_element.GetFile(), "ALittle", "IHttpFileSender", true);
                        if (!(element is ALittleScriptClassNameDecElement))
                        {
                            return(new ABnfGuessError(error_element, "语言框架中找不到ALittle.IHttpFileSender"));
                        }
                        var class_name_dec = element as ALittleScriptClassNameDecElement;
                        error = class_name_dec.GuessType(out ABnfGuess class_name_dec_guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        info.param_list.Add(class_name_dec_guess);
                        info.param_nullable_list.Add(false);
                        info.param_name_list.Add("sender");
                        info.param_list.Add(guess);
                        info.param_nullable_list.Add(false);
                        info.param_name_list.Add("param");

                        info.return_list.Add(ALittleScriptIndex.inst.sStringGuess);
                    }
                    else if (info.proto == "Msg")
                    {
                        ABnfElement element = ALittleScriptIndex.inst.FindALittleNameDec(ALittleScriptUtility.ABnfElementType.CLASS_NAME, m_element.GetFile(), "ALittle", "IMsgCommon", true);
                        if (!(element is ALittleScriptClassNameDecElement))
                        {
                            return(new ABnfGuessError(error_element, "语言框架中找不到ALittle.IMsgCommon"));
                        }
                        var class_name_dec = element as ALittleScriptClassNameDecElement;
                        error = class_name_dec.GuessType(out ABnfGuess class_name_dec_guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        info.param_list.Add(class_name_dec_guess);
                        info.param_nullable_list.Add(false);
                        info.param_name_list.Add("sender");
                        info.param_list.Add(guess);
                        info.param_nullable_list.Add(false);
                        info.param_name_list.Add("param");

                        var return_dec = global_method_dec.GetMethodReturnDec();
                        if (return_dec != null)
                        {
                            var return_one_list = return_dec.GetMethodReturnOneDecList();
                            if (return_one_list.Count > 0)
                            {
                                var return_one_all_type = return_one_list[0].GetAllType();
                                if (return_one_all_type == null)
                                {
                                    return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数返回值必须是struct"));
                                }
                                error = return_one_all_type.GuessType(out ABnfGuess return_guess);
                                if (error != null)
                                {
                                    return(error);
                                }
                                if (!(return_guess is ALittleScriptGuessStruct))
                                {
                                    return(new ABnfGuessError(error_element, "带" + info.proto + "注解的函数返回值必须是struct"));
                                }
                                info.return_list.Add(ALittleScriptIndex.inst.sStringGuess);
                                info.return_list.Add(return_guess);
                            }
                        }
                    }
                    else
                    {
                        return(new ABnfGuessError(error_element, "未知的注解类型:" + info.proto));
                    }
                }
                else
                {
                    // 添加模板参数列表
                    var template_dec = global_method_dec.GetTemplateDec();
                    if (template_dec != null)
                    {
                        var error = template_dec.GuessTypes(out List <ABnfGuess> template_guess_list);
                        if (error != null)
                        {
                            return(error);
                        }
                        foreach (var guess in template_guess_list)
                        {
                            if (!(guess is ALittleScriptGuessTemplate))
                            {
                                return(new ABnfGuessError(m_element, "template_dec.GuessTypes()取到的不是ALittleScriptGuessTemplate"));
                            }
                            info.template_param_list.Add(guess as ALittleScriptGuessTemplate);
                        }
                    }

                    // 添加参数列表
                    var param_dec = global_method_dec.GetMethodParamDec();
                    if (param_dec != null)
                    {
                        var one_dec_list = param_dec.GetMethodParamOneDecList();
                        for (int i = 0; i < one_dec_list.Count; ++i)
                        {
                            var one_dec    = one_dec_list[i];
                            var all_type   = one_dec.GetAllType();
                            var param_tail = one_dec.GetMethodParamTailDec();
                            if (all_type != null)
                            {
                                var error = all_type.GuessType(out ABnfGuess all_type_guess);
                                if (error != null)
                                {
                                    return(error);
                                }
                                info.param_list.Add(all_type_guess);
                                info.param_nullable_list.Add(ALittleScriptUtility.IsNullable(one_dec.GetModifierList()));
                                if (one_dec.GetMethodParamNameDec() != null)
                                {
                                    info.param_name_list.Add(one_dec.GetMethodParamNameDec().GetElementText());
                                }
                                else
                                {
                                    info.param_name_list.Add("");
                                }
                            }
                            else if (param_tail != null)
                            {
                                if (i + 1 != one_dec_list.Count)
                                {
                                    return(new ABnfGuessError(one_dec, "参数占位符必须定义在最后"));
                                }
                                var error = param_tail.GuessType(out info.param_tail);
                                if (error != null)
                                {
                                    return(error);
                                }
                            }
                        }
                    }

                    // 添加返回值列表
                    var return_dec = global_method_dec.GetMethodReturnDec();
                    if (return_dec != null)
                    {
                        var one_dec_list = return_dec.GetMethodReturnOneDecList();
                        for (int i = 0; i < one_dec_list.Count; ++i)
                        {
                            var one_dec     = one_dec_list[i];
                            var all_type    = one_dec.GetAllType();
                            var return_tail = one_dec.GetMethodReturnTailDec();
                            if (all_type != null)
                            {
                                var error = all_type.GuessType(out ABnfGuess all_type_guess);
                                if (error != null)
                                {
                                    return(error);
                                }
                                info.return_list.Add(all_type_guess);
                            }
                            else if (return_tail != null)
                            {
                                if (i + 1 != one_dec_list.Count)
                                {
                                    return(new ABnfGuessError(one_dec, "返回值占位符必须定义在最后"));
                                }
                                var error = return_tail.GuessType(out info.return_tail);
                                if (error != null)
                                {
                                    return(error);
                                }
                            }
                        }
                    }
                }
                info.UpdateValue();
                guess_list.Add(info);
            }

            return(null);
        }
Пример #6
0
        public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list)
        {
            guess_list = new List <ABnfGuess>();

            // 处理List
            if (m_element.GetGenericListType() != null)
            {
                var dec      = m_element.GetGenericListType();
                var all_type = dec.GetAllType();
                if (all_type == null)
                {
                    return(null);
                }

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

                var info = new ALittleScriptGuessList(guess, false, false);
                info.UpdateValue();
                guess_list.Add(info);
            }
            // 处理Map
            else if (m_element.GetGenericMapType() != null)
            {
                var dec           = m_element.GetGenericMapType();
                var all_type_list = dec.GetAllTypeList();
                if (all_type_list.Count != 2)
                {
                    return(null);
                }

                var error = all_type_list[0].GuessType(out ABnfGuess key_guess);
                if (error != null)
                {
                    return(error);
                }
                error = all_type_list[1].GuessType(out ABnfGuess value_guess);
                if (error != null)
                {
                    return(error);
                }

                var info = new ALittleScriptGuessMap(key_guess, value_guess, false);
                info.UpdateValue();
                guess_list.Add(info);
            }
            // 处理函数
            else if (m_element.GetGenericFunctorType() != null)
            {
                var dec = m_element.GetGenericFunctorType();
                if (dec != null)
                {
                    var info = new ALittleScriptGuessFunctor(m_element);
                    // 处理是不是const
                    info.const_modifier = dec.GetAllTypeConst() != null;
                    // 处理是不是await
                    info.await_modifier = (dec.GetCoroutineModifier() != null && dec.GetCoroutineModifier().GetElementText() == "await");

                    // 处理参数
                    var param_type = dec.GetGenericFunctorParamType();
                    if (param_type != null)
                    {
                        var param_one_list = param_type.GetGenericFunctorParamOneTypeList();
                        for (int i = 0; i < param_one_list.Count; ++i)
                        {
                            var param_one = param_one_list[i];
                            var all_type  = param_one.GetAllType();
                            if (all_type != null)
                            {
                                var error = all_type.GuessType(out ABnfGuess guess);
                                if (error != null)
                                {
                                    return(error);
                                }
                                info.param_list.Add(guess);
                                info.param_nullable_list.Add(false);
                                info.param_name_list.Add(guess.GetValue());
                            }
                            else
                            {
                                var param_tail = param_one.GetGenericFunctorParamTail();
                                if (param_tail == null)
                                {
                                    return(new ABnfGuessError(param_one, "未知类型"));
                                }
                                if (i + 1 != param_one_list.Count)
                                {
                                    return(new ABnfGuessError(param_one, "参数占位符必须定义在最后"));
                                }
                                info.param_tail = new ALittleScriptGuessParamTail(param_tail.GetElementText());
                            }
                        }
                    }

                    // 处理返回值
                    var return_type = dec.GetGenericFunctorReturnType();
                    if (return_type != null)
                    {
                        var return_one_list = return_type.GetGenericFunctorReturnOneTypeList();
                        for (int i = 0; i < return_one_list.Count; ++i)
                        {
                            var return_one = return_one_list[i];
                            var all_type   = return_one.GetAllType();
                            if (all_type != null)
                            {
                                var error = all_type.GuessType(out ABnfGuess guess);
                                if (error != null)
                                {
                                    return(error);
                                }
                                info.return_list.Add(guess);
                            }
                            else
                            {
                                var return_tail = return_one.GetGenericFunctorReturnTail();
                                if (return_tail == null)
                                {
                                    return(new ABnfGuessError(return_one, "未知类型"));
                                }
                                if (i + 1 != return_one_list.Count)
                                {
                                    return(new ABnfGuessError(return_one, "返回值占位符必须定义在最后"));
                                }
                                info.return_tail = new ALittleScriptGuessReturnTail(return_tail.GetElementText());
                            }
                        }
                    }
                    info.UpdateValue();
                    guess_list.Add(info);
                }
            }

            return(null);
        }
        public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list)
        {
            guess_list = null;

            var value_stat_list = m_element.GetValueStatList();

            if (value_stat_list.Count == 0)
            {
                return(new ABnfGuessError(m_element, "bind表达式不能没有参数"));
            }

            var value_stat = value_stat_list[0];
            var error      = value_stat.GuessType(out ABnfGuess guess);

            if (error != null)
            {
                return(error);
            }

            var guess_functor = guess as ALittleScriptGuessFunctor;

            if (guess_functor == null)
            {
                return(new ABnfGuessError(m_element, "bind表达式第一个参数必须是一个函数"));
            }

            if (guess_functor.template_param_list.Count > 0)
            {
                return(new ABnfGuessError(m_element, "bind表达式要绑定的函数不能有模板定义"));
            }

            // 开始构建类型
            var info = new ALittleScriptGuessFunctor(m_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_list.AddRange(guess_functor.param_list);
            info.param_nullable_list.AddRange(guess_functor.param_nullable_list);
            info.param_name_list.AddRange(guess_functor.param_name_list);
            info.param_tail = guess_functor.param_tail;
            info.return_list.AddRange(guess_functor.return_list);
            info.return_tail = guess_functor.return_tail;
            // 移除已填写的参数
            int param_count = value_stat_list.Count - 1;

            while (param_count > 0 &&
                   info.param_list.Count > 0 &&
                   info.param_nullable_list.Count > 0 &&
                   info.param_name_list.Count > 0)
            {
                info.param_list.RemoveAt(0);
                info.param_nullable_list.RemoveAt(0);
                info.param_name_list.RemoveAt(0);
                --param_count;
            }
            info.UpdateValue();
            guess_list = new List <ABnfGuess>()
            {
                info
            };
            return(null);
        }
Пример #8
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);
        }