public override ABnfGuess Clone()
        {
            var guess = new ALittleScriptGuessClass(namespace_name, class_name, class_dec, using_name, is_const, is_native);

            guess.template_list.AddRange(template_list);
            foreach (var pair in template_map)
            {
                guess.template_map.Add(pair.Key, pair.Value);
            }
            guess.UpdateValue();
            return(guess);
        }
        public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list)
        {
            guess_list = null;

            var name_dec = m_element.GetClassNameDec();

            if (name_dec == null)
            {
                return(new ABnfGuessError(m_element, "没有定义类名"));
            }

            var body_dec = m_element.GetClassBodyDec();

            if (body_dec == null)
            {
                return(new ABnfGuessError(m_element, "没有定义类体"));
            }

            var namespace_element_dec = m_element.GetParent() as ALittleScriptNamespaceElementDecElement;

            if (namespace_element_dec == null)
            {
                return(new ABnfGuessError(m_element, "ALittleScriptClassDecReference的父节点不是ALittleScriptNamespaceElementDecElement"));
            }

            bool is_native    = ALittleScriptUtility.IsNative(namespace_element_dec.GetModifierList());
            var  info         = new ALittleScriptGuessClass(m_namespace_name, name_dec.GetElementText(), m_element, null, false, is_native);
            var  template_dec = m_element.GetTemplateDec();

            if (template_dec != null)
            {
                var error = template_dec.GuessTypes(out info.template_list);
                if (error != null)
                {
                    return(error);
                }
            }
            info.UpdateValue();

            guess_list = new List <ABnfGuess>()
            {
                info
            };
            return(null);
        }
Пример #3
0
        public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list)
        {
            guess_list = new List <ABnfGuess>();
            if (m_key.Length == 0)
            {
                return(new ABnfGuessError(m_element, "找不到指定类型, namespace:" + m_namespace_name + ", key:" + m_key));
            }

            var custom_type_template = m_custom_type.GetCustomTypeTemplate();

            {
                var dec_list = ALittleScriptIndex.inst.FindALittleNameDecList(
                    ALittleScriptUtility.ABnfElementType.USING_NAME, m_element.GetFile(), m_namespace_name, m_key, true);
                foreach (var dec in dec_list)
                {
                    var error = dec.GuessType(out ABnfGuess guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    guess_list.Add(guess);
                }

                if (dec_list.Count > 0 && custom_type_template != null && custom_type_template.GetAllTypeList().Count > 0)
                {
                    return(new ABnfGuessError(m_element, "使用using定义的类不能再使用模板参数, namespace:" + m_namespace_name + ", key:" + m_key));
                }
            }
            {
                // 根据名字获取对应的类
                var dec_list = ALittleScriptIndex.inst.FindALittleNameDecList(
                    ALittleScriptUtility.ABnfElementType.CLASS_NAME, m_element.GetFile(), m_namespace_name, m_key, true);

                // 获取模板的填充对象,并计算类型
                var src_guess_list = new List <ABnfGuess>();
                List <ALittleScriptAllTypeElement> template_list;
                if (custom_type_template != null)
                {
                    template_list = custom_type_template.GetAllTypeList();
                    foreach (var all_type in template_list)
                    {
                        var error = all_type.GuessType(out ABnfGuess all_type_guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        src_guess_list.Add(all_type_guess);
                    }
                }
                else
                {
                    template_list = new List <ALittleScriptAllTypeElement>();
                }

                // 遍历所有的类
                foreach (var dec in dec_list)
                {
                    // 获取dec的类型
                    var error = dec.GuessType(out ABnfGuess guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    var guess_class = guess as ALittleScriptGuessClass;
                    if (guess_class == null)
                    {
                        return(new ABnfGuessError(m_element, "模板参数数量和类定义的不一致, namespace:" + m_namespace_name + ", key:" + m_key));
                    }
                    // 类模板列表的参数数量必须和填充的一致
                    if (template_list.Count != guess_class.template_list.Count)
                    {
                        return(new ABnfGuessError(m_element, "模板参数数量和类定义的不一致, namespace:" + m_namespace_name + ", key:" + m_key));
                    }

                    // 对比两种
                    for (int i = 0; i < template_list.Count; ++i)
                    {
                        error = ALittleScriptOp.GuessTypeEqual(guess_class.template_list[i], template_list[i], src_guess_list[i], false, false);
                        if (error != null)
                        {
                            return(error);
                        }
                    }

                    if (guess_class.template_list.Count > 0)
                    {
                        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_custom_type, "类模板没有定义类名"));
                        }

                        var info = new ALittleScriptGuessClass(ALittleScriptUtility.GetNamespaceName(src_class_dec),
                                                               src_class_name_dec.GetElementText(),
                                                               guess_class.class_dec, guess_class.using_name, guess_class.is_const, guess_class.is_native);
                        info.template_list.AddRange(guess_class.template_list);
                        for (int i = 0; i < guess_class.template_list.Count; ++i)
                        {
                            if (info.template_map.ContainsKey(guess_class.template_list[i].GetValueWithoutConst()))
                            {
                                info.template_map.Remove(guess_class.template_list[i].GetValueWithoutConst());
                            }
                            info.template_map.Add(guess_class.template_list[i].GetValueWithoutConst(), src_guess_list[i]);
                        }
                        info.UpdateValue();
                        guess = info;
                    }

                    guess_list.Add(guess);
                }
            }
            {
                var class_dec = GetClassDec();
                if (class_dec != null)
                {
                    var dec_list = new List <ABnfElement>();
                    ALittleScriptIndex.inst.FindClassAttrList(class_dec, ALittleScriptUtility.sAccessPrivateAndProtectedAndPublic, ALittleScriptUtility.ClassAttrType.TEMPLATE, m_key, dec_list);
                    // 不能再静态函数中使用模板定义
                    if (dec_list.Count > 0 && ALittleScriptUtility.IsInClassStaticMethod(m_element))
                    {
                        return(new ABnfGuessError(m_element, "类静态函数不能使用模板符号"));
                    }
                    foreach (var dec in dec_list)
                    {
                        var error = dec.GuessType(out ABnfGuess guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        guess_list.Add(guess);
                    }
                }
            }
            {
                var template_dec = GetMethodTemplateDec();
                if (template_dec != null)
                {
                    var pair_dec_list = template_dec.GetTemplatePairDecList();
                    foreach (var dec in pair_dec_list)
                    {
                        var name_dec = dec.GetTemplateNameDec();
                        if (name_dec == null)
                        {
                            continue;
                        }

                        if (name_dec.GetElementText() == m_key)
                        {
                            var error = dec.GuessType(out ABnfGuess guess);
                            if (error != null)
                            {
                                return(error);
                            }
                            guess_list.Add(guess);
                        }
                    }
                }
            }
            {
                var dec_list = ALittleScriptIndex.inst.FindALittleNameDecList(
                    ALittleScriptUtility.ABnfElementType.STRUCT_NAME, m_element.GetFile(), m_namespace_name, m_key, true);
                foreach (var dec in dec_list)
                {
                    var error = dec.GuessType(out ABnfGuess guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    guess_list.Add(guess);
                }
            }
            {
                var dec_list = ALittleScriptIndex.inst.FindALittleNameDecList(
                    ALittleScriptUtility.ABnfElementType.ENUM_NAME, m_element.GetFile(), m_namespace_name, m_key, true);
                foreach (var dec in dec_list)
                {
                    var error = dec.GuessType(out ABnfGuess guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    guess_list.Add(guess);
                }
            }
            if (m_element is ALittleScriptCustomTypeElement)
            {
                var dec_list = ALittleScriptIndex.inst.FindNamespaceNameDecList(m_key);
                foreach (var dec in dec_list)
                {
                    var error = dec.Value.GuessType(out ABnfGuess guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    guess_list.Add(guess);
                }
            }

            if (guess_list.Count == 0)
            {
                return(new ABnfGuessError(m_element, "找不到指定类型, namespace:" + m_namespace_name + ", key:" + m_key));
            }

            return(null);
        }
Пример #4
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);
        }