public override ABnfGuessError CheckError()
        {
            var src_map  = new Dictionary <string, ALittleScriptGuessTemplate>();
            var fill_map = new Dictionary <string, ABnfGuess>();
            var error    = CheckTemplateMap(src_map, fill_map, out ALittleScriptGuessFunctor pre_type_functor);

            if (error != null)
            {
                return(error);
            }
            if (pre_type_functor == null)
            {
                return(new ABnfGuessError(m_element, "括号前面必须是函数"));
            }

            // 检查填写的和函数定义的参数是否一致
            var value_stat_list = m_element.GetValueStatList();

            for (int i = 0; i < value_stat_list.Count; ++i)
            {
                var value_stat = value_stat_list[i];

                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 ABnfGuess guess);
                if (error != null)
                {
                    return(error);
                }
                // 如果参数返回的类型是tail,那么就可以不用检查
                if (guess is ALittleScriptGuessReturnTail)
                {
                    continue;
                }

                if (i >= pre_type_functor.param_list.Count)
                {
                    // 如果有参数占位符,那么就直接跳出,不检查了
                    // 如果没有,就表示超过参数数量了
                    if (pre_type_functor.param_tail != null)
                    {
                        break;
                    }
                    else
                    {
                        return(new ABnfGuessError(m_element, "该函数调用需要" + pre_type_functor.param_list.Count + "个参数,而不是" + value_stat_list.Count + "个"));
                    }
                }

                error = ALittleScriptOp.GuessTypeEqual(pre_type_functor.param_list[i], value_stat, guess, false, false);
                if (error != null)
                {
                    return(new ABnfGuessError(value_stat, "第" + (i + 1) + "个参数类型和函数定义的参数类型不同:" + error.GetError()));
                }
            }

            // 如果参数数量不足以填充
            if (value_stat_list.Count < pre_type_functor.param_list.Count)
            {
                // 不足的部分,参数必须都是nullable
                for (int i = value_stat_list.Count; i < pre_type_functor.param_nullable_list.Count; ++i)
                {
                    if (!pre_type_functor.param_nullable_list[i])
                    {
                        // 计算至少需要的参数个数
                        int count = pre_type_functor.param_nullable_list.Count;
                        for (int j = pre_type_functor.param_nullable_list.Count - 1; j >= 0; --j)
                        {
                            if (pre_type_functor.param_nullable_list[j])
                            {
                                --count;
                            }
                            else
                            {
                                break;
                            }
                        }
                        return(new ABnfGuessError(m_element, "该函数调用至少需要" + count + "个参数,而不是" + value_stat_list.Count + "个"));
                    }
                }
            }

            // 检查这个函数是不是await
            if (pre_type_functor.await_modifier)
            {
                // 检查这次所在的函数必须要有await或者async修饰
                error = ALittleScriptUtility.CheckInvokeAwait(m_element);
                if (error != null)
                {
                    return(error);
                }
            }
            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()));
        }
        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);
        }
예제 #4
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);
        }
예제 #5
0
        public override ABnfGuessError CheckError()
        {
            var value_stat = m_element.GetValueStat();

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

            var pair_dec_list = m_element.GetVarAssignDecList();

            if (pair_dec_list.Count == 0)
            {
                return(null);
            }

            // 如果返回值只有一个函数调用
            if (pair_dec_list.Count > 1)
            {
                // 获取右边表达式的
                var guess_error = value_stat.GuessTypes(out List <ABnfGuess> method_call_guess_list);
                if (guess_error != null)
                {
                    return(guess_error);
                }
                if (method_call_guess_list.Count == 0)
                {
                    return(new ABnfGuessError(value_stat, "调用的函数没有返回值"));
                }
                bool has_tail = method_call_guess_list[method_call_guess_list.Count - 1] is ALittleScriptGuessReturnTail;
                if (has_tail)
                {
                    // 不需要检查
                }
                else
                {
                    if (method_call_guess_list.Count < pair_dec_list.Count)
                    {
                        return(new ABnfGuessError(value_stat, "调用的函数返回值数量少于定义的变量数量"));
                    }
                }

                for (int i = 0; i < pair_dec_list.Count; ++i)
                {
                    var pair_dec = pair_dec_list[i];
                    if (i >= method_call_guess_list.Count)
                    {
                        break;
                    }
                    if (method_call_guess_list[i] is ALittleScriptGuessReturnTail)
                    {
                        break;
                    }

                    guess_error = pair_dec.GuessType(out ABnfGuess pair_dec_guess);
                    if (guess_error != null)
                    {
                        return(guess_error);
                    }
                    guess_error = ALittleScriptOp.GuessTypeEqual(pair_dec_guess, value_stat, method_call_guess_list[i], true, false);
                    if (guess_error != null)
                    {
                        return(new ABnfGuessError(value_stat, "等号左边的第" + (i + 1) + "个变量数量和函数定义的返回值类型不相等:" + guess_error.GetError()));
                    }
                }
                return(null);
            }

            var error = pair_dec_list[0].GuessType(out ABnfGuess pair_guess);

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

            error = ALittleScriptOp.GuessTypeEqual(pair_guess, value_stat, value_guess, true, false);
            if (error != null)
            {
                return(new ABnfGuessError(error.GetElement(), "等号左边的变量和表达式的类型不同:" + error.GetError()));
            }

            return(null);
        }
예제 #6
0
        public override ABnfGuessError CheckError()
        {
            var value_stat_list = m_element.GetValueStatList();

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

            // 第一个参数必须是函数
            var value_stat = value_stat_list[0];

            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 ABnfGuess guess);
            if (error != null)
            {
                return(error);
            }
            if (!(guess is ALittleScriptGuessFunctor))
            {
                return(new ABnfGuessError(value_stat, "tcall表达式第一个参数必须是一个函数"));
            }

            var guess_functor = guess as ALittleScriptGuessFunctor;

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

            // 后面跟的参数数量不能超过这个函数的参数个数
            if (value_stat_list.Count - 1 > guess_functor.param_list.Count)
            {
                if (guess_functor.param_tail == null)
                {
                    return(new ABnfGuessError(m_element, "tcall表达式参数太多了"));
                }
            }

            // 遍历所有的表达式,看下是否符合
            for (int i = 1; i < value_stat_list.Count; ++i)
            {
                if (i - 1 >= guess_functor.param_list.Count)
                {
                    break;
                }
                var param_guess      = guess_functor.param_list[i - 1];
                var param_value_stat = value_stat_list[i];

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

                error = param_value_stat.GuessType(out ABnfGuess param_value_stat_guess);
                if (error != null)
                {
                    return(error);
                }
                error = ALittleScriptOp.GuessTypeEqual(param_guess, param_value_stat, param_value_stat_guess, false, false);
                if (error != null)
                {
                    return(new ABnfGuessError(param_value_stat, "第" + i + "个参数类型和函数定义的参数类型不同:" + error.GetError()));
                }
            }

            // 检查这个函数是不是await
            if (guess_functor.await_modifier)
            {
                // 检查这次所在的函数必须要有await或者async修饰
                error = ALittleScriptUtility.CheckInvokeAwait(m_element);
                if (error != null)
                {
                    return(error);
                }
            }
            return(null);
        }
예제 #7
0
        public override ABnfGuessError CheckError()
        {
            var property_value_list = m_element.GetPropertyValueList();
            var value_stat          = m_element.GetValueStat();

            if (value_stat == null)
            {
                if (property_value_list.Count != 1)
                {
                    return(new ABnfGuessError(m_element, "没有赋值表达式时,只能是一个函数调用"));
                }
                var property_value = property_value_list[0];
                var suffix_list    = property_value.GetPropertyValueSuffixList();
                if (suffix_list.Count == 0)
                {
                    return(new ABnfGuessError(m_element, "没有赋值表达式时,只能是一个函数调用"));
                }
                var suffix = suffix_list[suffix_list.Count - 1];
                if (suffix.GetPropertyValueMethodCall() == null)
                {
                    return(new ABnfGuessError(m_element, "没有赋值表达式时,只能是一个函数调用"));
                }
                return(null);
            }

            if (property_value_list.Count == 0)
            {
                return(null);
            }

            // 如果返回值只有一个函数调用
            if (property_value_list.Count > 1)
            {
                if (value_stat == null)
                {
                    return(new ABnfGuessError(m_element, "调用的函数没有返回值"));
                }
                // 获取右边表达式的
                var guess_error = value_stat.GuessTypes(out List <ABnfGuess> method_call_guess_list);
                if (guess_error != null)
                {
                    return(guess_error);
                }
                if (method_call_guess_list.Count == 0)
                {
                    return(new ABnfGuessError(value_stat, "调用的函数没有返回值"));
                }

                bool hasTail = method_call_guess_list[method_call_guess_list.Count - 1] is ALittleScriptGuessReturnTail;
                if (hasTail)
                {
                    // 不做检查
                }
                else
                {
                    if (method_call_guess_list.Count < property_value_list.Count)
                    {
                        return(new ABnfGuessError(value_stat, "调用的函数返回值数量少于定义的变量数量"));
                    }
                }

                for (int i = 0; i < property_value_list.Count; ++i)
                {
                    var pair_dec = property_value_list[i];
                    if (i >= method_call_guess_list.Count)
                    {
                        break;
                    }
                    if (method_call_guess_list[i] is ALittleScriptGuessReturnTail)
                    {
                        break;
                    }
                    guess_error = pair_dec.GuessType(out ABnfGuess pair_dec_guess);
                    if (guess_error != null)
                    {
                        return(guess_error);
                    }
                    guess_error = ALittleScriptOp.GuessTypeEqual(pair_dec_guess, value_stat, method_call_guess_list[i], true, false);
                    if (guess_error != null)
                    {
                        return(new ABnfGuessError(value_stat, "等号左边的第" + (i + 1) + "个变量数量和函数定义的返回值类型不相等:" + guess_error.GetError()));
                    }
                }

                return(null);
            }

            var op_assign = m_element.GetOpAssign();

            if (op_assign == null)
            {
                return(new ABnfGuessError(m_element, "没有赋值符号"));
            }
            string op_string = op_assign.GetElementText();

            var error = property_value_list[0].GuessType(out ABnfGuess pair_guess);

            if (error != null)
            {
                return(error);
            }
            error = value_stat.GuessType(out ABnfGuess value_guess);
            if (error != null)
            {
                return(error);
            }
            if (pair_guess is ALittleScriptGuessTemplate)
            {
                if (pair_guess.GetValue() != value_guess.GetValue() && value_guess.GetValue() != "null")
                {
                    return(new ABnfGuessError(value_stat, "等号左边的变量和表达式的类型不同"));
                }
            }

            if (op_string == "=")
            {
                error = ALittleScriptOp.GuessTypeEqual(pair_guess, value_stat, value_guess, true, false);
                if (error != null)
                {
                    return(new ABnfGuessError(error.GetElement(), "等号左边的变量和表达式的类型不同:" + error.GetError()));
                }
            }
            else
            {
                error = ALittleScriptUtility.CalcReturnCount(value_stat, out int return_count, out _);
                if (error != null)
                {
                    return(error);
                }

                if (return_count != 1)
                {
                    return(new ABnfGuessError(value_stat, op_string + "右边必须只能是一个返回值"));
                }

                if (pair_guess.is_const)
                {
                    return(new ABnfGuessError(property_value_list[0], "const类型不能使用" + op_string + "运算符"));
                }

                if (!(pair_guess is ALittleScriptGuessInt) && !(pair_guess is ALittleScriptGuessDouble) && !(pair_guess is ALittleScriptGuessLong))
                {
                    return(new ABnfGuessError(property_value_list[0], op_string + "左边必须是int, double, long"));
                }

                if (!(value_guess is ALittleScriptGuessInt) && !(value_guess is ALittleScriptGuessDouble) && !(value_guess is ALittleScriptGuessLong))
                {
                    return(new ABnfGuessError(value_stat, op_string + "右边必须是int, double, long"));
                }
            }
            return(null);
        }
예제 #8
0
        public override ABnfGuessError CheckError()
        {
            var for_condition = m_element.GetForCondition();

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

            var for_pair_dec = for_condition.GetForPairDec();

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

            var step_condition = for_condition.GetForStepCondition();
            var in_condition   = for_condition.GetForInCondition();

            if (step_condition != null)
            {
                var for_start_stat = step_condition.GetForStartStat();
                if (for_start_stat == null)
                {
                    return(null);
                }

                var error = for_pair_dec.GuessType(out ABnfGuess start_guess);
                if (error != null)
                {
                    return(error);
                }
                if (!(start_guess is ALittleScriptGuessInt) && !(start_guess is ALittleScriptGuessLong))
                {
                    return(new ABnfGuessError(for_pair_dec.GetVarAssignNameDec(), "这个变量必须是int或long类型"));
                }

                var value_stat = for_start_stat.GetValueStat();
                if (value_stat == null)
                {
                    return(new ABnfGuessError(for_pair_dec.GetVarAssignNameDec(), "没有初始化表达式"));
                }

                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 ABnfGuess guess);
                if (error != null)
                {
                    return(error);
                }
                if (!(guess is ALittleScriptGuessInt) && !(guess is ALittleScriptGuessLong) && !(guess is ALittleScriptGuessDouble))
                {
                    return(new ABnfGuessError(value_stat, "等号右边的表达式类型必须是int,long,double 不能是:" + guess.GetValue()));
                }

                // 结束表达式
                var end_stat  = step_condition.GetForEndStat();
                var step_stat = step_condition.GetForStepStat();

                if (end_stat == null || end_stat.GetValueStat() == null)
                {
                    return(new ABnfGuessError(m_element, "必须有结束表达式"));
                }
                if (step_stat == null || step_stat.GetValueStat() == null)
                {
                    return(new ABnfGuessError(m_element, "必须有步长表达式"));
                }

                error = end_stat.GetValueStat().GuessType(out ABnfGuess end_guess);
                if (error != null)
                {
                    return(error);
                }
                if (!(end_guess is ALittleScriptGuessBool))
                {
                    return(new ABnfGuessError(end_stat, "for的结束条件表达式类型必须是bool, 不能是:" + end_guess.GetValue()));
                }

                // 返回值
                error = ALittleScriptUtility.CalcReturnCount(step_stat.GetValueStat(), out return_count, out _);
                if (error != null)
                {
                    return(error);
                }
                if (return_count != 1)
                {
                    return(new ABnfGuessError(value_stat, "for的步长条件表达式类型必须只能是一个返回值"));
                }

                error = step_stat.GetValueStat().GuessType(out ABnfGuess step_guess);
                if (error != null)
                {
                    return(error);
                }
                if (!(step_guess is ALittleScriptGuessInt) && !(step_guess is ALittleScriptGuessDouble) && !(step_guess is ALittleScriptGuessLong))
                {
                    return(new ABnfGuessError(step_stat, "for的步长条件表达式类型必须是int,double,long, 不能是:" + end_guess.GetValue()));
                }
            }
            else if (in_condition != null)
            {
                var value_stat = in_condition.GetValueStat();
                if (value_stat == null)
                {
                    return(null);
                }

                var error = ALittleScriptUtility.CalcReturnCount(value_stat, out int return_count, out List <ABnfGuess> return_guess_list);
                if (error != null)
                {
                    return(error);
                }
                if (ALittleScriptUtility.IsPairsFunction(return_guess_list))
                {
                    return_count = 1;
                }
                if (return_count != 1)
                {
                    return(new ABnfGuessError(value_stat, "for的遍历对象必须只能是一个返回值"));
                }

                var pair_dec_list = in_condition.GetForPairDecList();
                pair_dec_list.Insert(0, for_pair_dec);
                error = value_stat.GuessTypes(out List <ABnfGuess> guess_list);
                if (error != null)
                {
                    return(error);
                }

                // 检查List
                if (guess_list.Count == 1 && guess_list[0] is ALittleScriptGuessList)
                {
                    var guess = guess_list[0] as ALittleScriptGuessList;

                    // for变量必须是2个
                    if (pair_dec_list.Count != 2)
                    {
                        return(new ABnfGuessError(in_condition, "这里参数数量必须是2个"));
                    }

                    // 第一个参数必须是 int或者long
                    error = pair_dec_list[0].GuessType(out ABnfGuess key_guess_type);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (!(key_guess_type is ALittleScriptGuessInt) && !(key_guess_type is ALittleScriptGuessLong))
                    {
                        return(new ABnfGuessError(pair_dec_list[0], "这个变量必须是int或long类型"));
                    }

                    // 第二个参数必须和List元素相等
                    error = pair_dec_list[1].GuessType(out ABnfGuess value_guess_type);
                    if (error != null)
                    {
                        return(error);
                    }
                    var sub_type = guess.sub_type;
                    if (guess_list[0].is_const && !sub_type.is_const)
                    {
                        sub_type          = sub_type.Clone();
                        sub_type.is_const = true;
                        sub_type.UpdateValue();
                    }
                    error = ALittleScriptOp.GuessTypeEqual(sub_type, pair_dec_list[1], value_guess_type, false, false);
                    if (error != null)
                    {
                        return(new ABnfGuessError(error.GetElement(), "变量格式错误,不能是:" + value_guess_type.GetValue() + " :" + error.GetError()));
                    }
                    return(null);
                }

                // 检查Map
                if (guess_list.Count == 1 && guess_list[0] is ALittleScriptGuessMap)
                {
                    var guess_map = guess_list[0] as ALittleScriptGuessMap;

                    // for变量必须是2个
                    if (pair_dec_list.Count != 2)
                    {
                        return(new ABnfGuessError(in_condition, "这里参数数量必须是2个"));
                    }

                    // 第一个参数必须和Map的key元素相等
                    error = pair_dec_list[0].GuessType(out ABnfGuess key_guess_type);
                    if (error != null)
                    {
                        return(error);
                    }
                    var map_key_type = guess_map.key_type;
                    if (guess_list[0].is_const && !map_key_type.is_const)
                    {
                        map_key_type          = map_key_type.Clone();
                        map_key_type.is_const = true;
                        map_key_type.UpdateValue();
                    }
                    error = ALittleScriptOp.GuessTypeEqual(map_key_type, pair_dec_list[0], key_guess_type, false, false);
                    if (error != null)
                    {
                        return(new ABnfGuessError(error.GetElement(), "key变量格式错误,不能是:" + key_guess_type.GetValue() + " :" + error.GetError()));
                    }

                    // 第二个参数必须和Map的value元素相等
                    error = pair_dec_list[1].GuessType(out ABnfGuess value_guess_type);
                    if (error != null)
                    {
                        return(error);
                    }
                    var map_value_type = guess_map.value_type;
                    if (guess_list[0].is_const && !map_value_type.is_const)
                    {
                        map_value_type          = map_value_type.Clone();
                        map_value_type.is_const = true;
                        map_value_type.UpdateValue();
                    }
                    error = ALittleScriptOp.GuessTypeEqual(map_value_type, pair_dec_list[1], value_guess_type, false, false);
                    if (error != null)
                    {
                        return(new ABnfGuessError(error.GetElement(), "value变量格式错误,不能是:" + value_guess_type.GetValue() + " :" + error.GetError()));
                    }
                    return(null);
                }

                // 检查迭代函数
                if (ALittleScriptUtility.IsPairsFunction(guess_list))
                {
                    return(null);
                }

                return(new ABnfGuessError(value_stat, "遍历对象类型必须是List,Map或者迭代函数"));
            }
            return(null);
        }
예제 #9
0
        public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list)
        {
            guess_list = new List <ABnfGuess>();
            var parent = m_element.GetParent();

            // 如果直接就是定义,那么直接获取
            if (parent is ALittleScriptClassDecElement)
            {
                var error = parent.GuessType(out ABnfGuess guess);
                if (error != null)
                {
                    return(error);
                }
                guess_list.Add(guess);
            }
            // 如果是继承那么就从继承那边获取
            else if (parent is ALittleScriptClassExtendsDecElement)
            {
                if (m_key.Length == 0)
                {
                    return(new ABnfGuessError(m_element, "找不到类, namespace:" + m_namespace_name + ", key:" + m_key));
                }

                // 查找继承
                var class_name_dec_list = ALittleScriptIndex.inst.FindALittleNameDecList(
                    ALittleScriptUtility.ABnfElementType.CLASS_NAME, m_element.GetFile(), m_namespace_name, m_key, true);
                if (class_name_dec_list.Count == 0)
                {
                    return(new ABnfGuessError(m_element, "找不到类, namespace:" + m_namespace_name + ", key:" + m_key));
                }

                foreach (var class_name_dec in class_name_dec_list)
                {
                    var error = class_name_dec.GuessType(out ABnfGuess guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (!(guess is ALittleScriptGuessClass))
                    {
                        return(new ABnfGuessError(m_element, "继承的不是一个类, namespace:" + m_namespace_name + ", key:" + m_key));
                    }

                    var guess_class = guess as ALittleScriptGuessClass;
                    if (guess_class.template_list.Count > 0)
                    {
                        var sub_class = parent.GetParent() as ALittleScriptClassDecElement;
                        if (sub_class == null)
                        {
                            return(new ABnfGuessError(parent, "定义不完整"));
                        }

                        var sub_template_dec = sub_class.GetTemplateDec();
                        if (sub_template_dec == null)
                        {
                            return(new ABnfGuessError(parent, "子类的模板参数列表必须涵盖父类的模板参数列表"));
                        }

                        var sub_template_pair_list = sub_template_dec.GetTemplatePairDecList();
                        if (sub_template_pair_list.Count < guess_class.template_list.Count)
                        {
                            return(new ABnfGuessError(parent, "子类的模板参数列表必须涵盖父类的模板参数列表"));
                        }

                        for (int i = 0; i < guess_class.template_list.Count; ++i)
                        {
                            error = sub_template_pair_list[i].GuessType(out ABnfGuess sub_template);
                            if (error != null)
                            {
                                return(error);
                            }
                            error = ALittleScriptOp.GuessTypeEqual(guess_class.template_list[i], sub_template_pair_list[i], sub_template, false, false);
                            if (error != null)
                            {
                                return(new ABnfGuessError(sub_template_pair_list[i], "子类的模板参数和父类的模板参数不一致:" + error.GetError()));
                            }
                        }
                    }
                    guess_list.Add(guess);
                }
            }
            else
            {
                return(new ABnfGuessError(m_element, "ALittleClassNameDec出现未知的父节点"));
            }

            return(null);
        }
        public override ABnfGuessError CheckError()
        {
            var method_dec = m_element.GetParent();

            if (method_dec == null)
            {
                return(null);
            }
            var class_element_dec = method_dec.GetParent();

            if (class_element_dec == null)
            {
                return(null);
            }
            var class_body = class_element_dec.GetParent();

            if (class_body == null)
            {
                return(null);
            }
            var class_dec = class_body.GetParent() as ALittleScriptClassDecElement;

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

            // 计算父类
            var class_extends_dec = ALittleScriptUtility.FindClassExtends(class_dec);

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

            ALittleScriptUtility.ClassAttrType attrType;
            if (method_dec is ALittleScriptClassMethodDecElement)
            {
                attrType = ALittleScriptUtility.ClassAttrType.FUN;
            }
            else if (method_dec is ALittleScriptClassStaticDecElement)
            {
                attrType = ALittleScriptUtility.ClassAttrType.STATIC;
            }
            else if (method_dec is ALittleScriptClassGetterDecElement)
            {
                attrType = ALittleScriptUtility.ClassAttrType.GETTER;
            }
            else if (method_dec is ALittleScriptClassSetterDecElement)
            {
                attrType = ALittleScriptUtility.ClassAttrType.SETTER;
            }
            else
            {
                return(null);
            }

            var result = ALittleScriptUtility.FindFirstClassAttrFromExtends(class_extends_dec, attrType, m_key, 100);

            if (!(result is ALittleScriptMethodNameDecElement))
            {
                return(null);
            }
            var method_name_dec = result as ALittleScriptMethodNameDecElement;

            var error = m_element.GuessType(out ABnfGuess guess);

            if (error != null)
            {
                return(error);
            }
            error = method_name_dec.GuessType(out ABnfGuess extends_guess);
            if (error != null)
            {
                return(error);
            }
            error = ALittleScriptOp.GuessTypeEqual(extends_guess, m_element, guess, false, false);
            if (error != null)
            {
                return(new ABnfGuessError(m_element, "该函数是从父类继承下来,但是定义不一致:" + extends_guess.GetValue()));
            }
            return(null);
        }
        public override ABnfGuessError CheckError()
        {
            var value_stat = m_element.GetValueStat();

            if (value_stat == null)
            {
                return(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 suffixList = property_value.GetPropertyValueSuffixList();

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

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

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

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

            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 ABnfGuess key_guess_type);
            if (error != null)
            {
                return(error);
            }

            // 获取类型
            if (pre_type is ALittleScriptGuessList)
            {
                if (!(key_guess_type is ALittleScriptGuessInt) && !(key_guess_type is ALittleScriptGuessLong))
                {
                    return(new ABnfGuessError(value_stat, "索引值的类型必须是int或者是long,不能是:" + key_guess_type.GetValue()));
                }
            }
            else if (pre_type is ALittleScriptGuessMap)
            {
                var pre_type_map = pre_type as ALittleScriptGuessMap;
                error = ALittleScriptOp.GuessTypeEqual(((ALittleScriptGuessMap)pre_type).key_type, value_stat, key_guess_type, true, false);
                if (error != null)
                {
                    return(new ABnfGuessError(error.GetElement(), "索引值的类型不能是:" + key_guess_type.GetValue() + " :" + error.GetError()));
                }
            }

            {
                error = m_element.GuessTypes(out List <ABnfGuess> guess_list);
                if (error != null)
                {
                    return(error);
                }
                if (guess_list.Count == 0)
                {
                    return(new ABnfGuessError(m_element, "该元素不能直接使用[]取值,请先cast"));
                }
                else if (guess_list.Count != 1)
                {
                    return(new ABnfGuessError(m_element, "重复定义"));
                }
                return(null);
            }
        }
예제 #12
0
        public override ABnfGuessError CheckError()
        {
            var value_stat_list = m_element.GetValueStatList();

            if (m_element.GetGenericType() != null)
            {
                if (value_stat_list.Count > 0)
                {
                    return(new ABnfGuessError(m_element, "创建容器实例对象不能有参数"));
                }
                if (m_element.GetGenericType().GetGenericFunctorType() != null)
                {
                    return(new ABnfGuessError(m_element, "Functor不能new"));
                }
                return(null);
            }

            if (m_element.GetCustomType() != null)
            {
                var custom_type = m_element.GetCustomType();
                var error       = custom_type.GuessType(out ABnfGuess guess);
                if (error != null)
                {
                    return(error);
                }
                if (guess is ALittleScriptGuessStruct)
                {
                    if (value_stat_list.Count > 0)
                    {
                        return(new ABnfGuessError(m_element, "new的结构体不能有参数"));
                    }
                    return(null);
                }

                if (guess is ALittleScriptGuessMap)
                {
                    if (value_stat_list.Count > 0)
                    {
                        return(new ABnfGuessError(m_element, "new的Map不能有参数"));
                    }
                    return(null);
                }

                if (guess is ALittleScriptGuessList)
                {
                    if (value_stat_list.Count > 0)
                    {
                        return(new ABnfGuessError(m_element, "new的List不能有参数"));
                    }
                    return(null);
                }

                if (guess is ALittleScriptGuessTemplate)
                {
                    var guess_template = guess as ALittleScriptGuessTemplate;
                    if (guess_template.template_extends != null)
                    {
                        guess = guess_template.template_extends;
                    }
                    else if (guess_template.is_struct)
                    {
                        if (value_stat_list.Count > 0)
                        {
                            return(new ABnfGuessError(m_element, "new的结构体不能有参数"));
                        }
                        return(null);
                    }
                    else if (guess_template.is_class)
                    {
                        return(new ABnfGuessError(m_element, "如果要new改模板类型,请不要使用class,无法确定它的构造函数参数"));
                    }
                }

                if (guess is ALittleScriptGuessStruct)
                {
                    if (value_stat_list.Count > 0)
                    {
                        return(new ABnfGuessError(m_element, "new的结构体不能有参数"));
                    }
                    return(null);
                }

                if (guess is ALittleScriptGuessClass)
                {
                    var class_dec = (guess as ALittleScriptGuessClass).class_dec;
                    var ctor_dec  = ALittleScriptUtility.FindFirstCtorDecFromExtends(class_dec, 100);
                    if (ctor_dec == null)
                    {
                        if (value_stat_list.Count > 0)
                        {
                            return(new ABnfGuessError(m_element, "new的类的构造函数没有参数"));
                        }
                        return(null);
                    }

                    var param_dec = ctor_dec.GetMethodParamDec();
                    if (param_dec == null)
                    {
                        if (value_stat_list.Count > 0)
                        {
                            return(new ABnfGuessError(m_element, "new的类的构造函数没有参数"));
                        }
                        return(null);
                    }

                    var  param_one_dec_list  = param_dec.GetMethodParamOneDecList();
                    var  param_guess_list    = new List <ABnfGuess>();
                    var  param_nullable_list = new List <bool>();
                    bool has_param_tail      = false;
                    foreach (var param_one_dec in param_one_dec_list)
                    {
                        var all_type   = param_one_dec.GetAllType();
                        var param_tail = param_one_dec.GetMethodParamTailDec();
                        if (all_type != null)
                        {
                            error = all_type.GuessType(out ABnfGuess all_type_guess);
                            if (error != null)
                            {
                                return(error);
                            }
                            param_guess_list.Add(all_type_guess);
                            param_nullable_list.Add(ALittleScriptUtility.IsNullable(param_one_dec.GetModifierList()));
                        }
                        else if (param_tail != null)
                        {
                            has_param_tail = true;
                        }
                    }

                    // 如果参数数量不足以填充
                    if (value_stat_list.Count < param_guess_list.Count)
                    {
                        // 不足的部分,参数必须都是nullable
                        for (int i = value_stat_list.Count; i < param_nullable_list.Count; ++i)
                        {
                            if (!param_nullable_list[i])
                            {
                                // 计算至少需要的参数个数
                                int count = param_nullable_list.Count;
                                for (int j = param_nullable_list.Count - 1; j >= 0; --j)
                                {
                                    if (param_nullable_list[j])
                                    {
                                        --count;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                return(new ABnfGuessError(m_element, "new的类的构造函数调用需要" + count + "个参数,不能是:" + value_stat_list.Count + "个"));
                            }
                        }
                    }

                    for (int i = 0; i < value_stat_list.Count; ++i)
                    {
                        var value_stat = value_stat_list[i];

                        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 ABnfGuess value_stat_guess);
                        if (error != null)
                        {
                            return(error);
                        }
                        // 如果参数返回的类型是tail,那么就可以不用检查
                        if (value_stat_guess is ALittleScriptGuessReturnTail)
                        {
                            continue;
                        }

                        if (i >= param_guess_list.Count)
                        {
                            // 如果有参数占位符,那么就直接跳出,不检查了
                            // 如果没有,就表示超过参数数量了
                            if (has_param_tail)
                            {
                                break;
                            }
                            else
                            {
                                return(new ABnfGuessError(m_element, "该构造函数调用需要" + param_guess_list.Count + "个参数,而不是" + value_stat_list.Count + "个"));
                            }
                        }

                        error = ALittleScriptOp.GuessTypeEqual(param_guess_list[i], value_stat, value_stat_guess, false, false);
                        if (error != null)
                        {
                            return(new ABnfGuessError(value_stat, "第" + (i + 1) + "个参数类型和函数定义的参数类型不同:" + error.GetError()));
                        }
                    }
                    return(null);
                }

                return(new ABnfGuessError(m_element, "只能new结构体和类"));
            }

            return(null);
        }
        public override ABnfGuessError CheckError()
        {
            ABnfElement parent = null;

            if (m_element.GetReturnYield() != null)
            {
                // 对于ReturnYield就不需要做返回值检查
                // 对所在函数进行检查,必须要有async和await表示
                // 获取对应的函数对象
                ABnfElement element = null;

                parent = m_element;
                while (parent != null)
                {
                    if (parent is ALittleScriptClassMethodDecElement)
                    {
                        var method_dec = parent as ALittleScriptClassMethodDecElement;
                        var modifier   = (method_dec.GetParent() as ALittleScriptClassElementDecElement).GetModifierList();
                        if (ALittleScriptUtility.GetCoroutineType(modifier) == null)
                        {
                            element = method_dec.GetMethodNameDec();
                            if (element == null)
                            {
                                element = method_dec;
                            }
                        }
                        break;
                    }
                    else if (parent is ALittleScriptClassStaticDecElement)
                    {
                        var method_dec = parent as ALittleScriptClassStaticDecElement;
                        var modifier   = (method_dec.GetParent() as ALittleScriptClassElementDecElement).GetModifierList();
                        if (ALittleScriptUtility.GetCoroutineType(modifier) == null)
                        {
                            element = method_dec.GetMethodNameDec();
                            if (element == null)
                            {
                                element = method_dec;
                            }
                        }
                        break;
                    }
                    else if (parent is ALittleScriptGlobalMethodDecElement)
                    {
                        var method_dec = parent as ALittleScriptGlobalMethodDecElement;
                        var modifier   = (method_dec.GetParent() as ALittleScriptNamespaceElementDecElement).GetModifierList();
                        if (ALittleScriptUtility.GetCoroutineType(modifier) == null)
                        {
                            element = method_dec.GetMethodNameDec();
                            if (element == null)
                            {
                                element = method_dec;
                            }
                        }
                        break;
                    }

                    parent = parent.GetParent();
                }

                if (element != null)
                {
                    return(new ABnfGuessError(element, "函数内部使用了return yield表达式,所以必须使用async或await修饰"));
                }
                return(null);
            }

            var value_stat_list  = m_element.GetValueStatList();
            var return_type_list = new List <ALittleScriptAllTypeElement>();
            ALittleScriptMethodReturnTailDecElement return_tail_dec = null;

            // 获取对应的函数对象
            parent = m_element;
            while (parent != null)
            {
                if (parent is ALittleScriptClassGetterDecElement)
                {
                    var getterDec = parent as ALittleScriptClassGetterDecElement;
                    return_type_list.Clear();
                    var return_type_dec = getterDec.GetAllType();
                    if (return_type_dec != null)
                    {
                        return_type_list.Add(return_type_dec);
                    }
                    break;
                }
                else if (parent is ALittleScriptClassSetterDecElement)
                {
                    break;
                }
                else if (parent is ALittleScriptClassMethodDecElement)
                {
                    var method_dec = parent as ALittleScriptClassMethodDecElement;
                    var return_dec = method_dec.GetMethodReturnDec();
                    if (return_dec != null)
                    {
                        var return_one_list = return_dec.GetMethodReturnOneDecList();
                        foreach (var return_one in return_one_list)
                        {
                            var all_type = return_one.GetAllType();
                            if (all_type != null)
                            {
                                return_type_list.Add(all_type);
                            }

                            var return_tail = return_one.GetMethodReturnTailDec();
                            if (return_tail != null)
                            {
                                return_tail_dec = return_tail;
                            }
                        }
                    }
                    break;
                }
                else if (parent is ALittleScriptClassStaticDecElement)
                {
                    var method_dec = parent as ALittleScriptClassStaticDecElement;
                    var return_dec = method_dec.GetMethodReturnDec();
                    if (return_dec != null)
                    {
                        var return_one_list = return_dec.GetMethodReturnOneDecList();
                        foreach (var return_one in return_one_list)
                        {
                            var all_type = return_one.GetAllType();
                            if (all_type != null)
                            {
                                return_type_list.Add(all_type);
                            }

                            var return_tail = return_one.GetMethodReturnTailDec();
                            if (return_tail != null)
                            {
                                return_tail_dec = return_tail;
                            }
                        }
                    }
                    break;
                }
                else if (parent is ALittleScriptGlobalMethodDecElement)
                {
                    var method_dec = parent as ALittleScriptGlobalMethodDecElement;
                    var return_dec = method_dec.GetMethodReturnDec();
                    if (return_dec != null)
                    {
                        var return_one_list = return_dec.GetMethodReturnOneDecList();
                        foreach (var return_one in return_one_list)
                        {
                            var all_type = return_one.GetAllType();
                            if (all_type != null)
                            {
                                return_type_list.Add(all_type);
                            }

                            var return_tail = return_one.GetMethodReturnTailDec();
                            if (return_tail != null)
                            {
                                return_tail_dec = return_tail;
                            }
                        }
                    }
                    break;
                }

                parent = parent.GetParent();
            }

            // 参数的类型
            List <ABnfGuess> guess_list = null;

            // 如果返回值只有一个函数调用
            if (value_stat_list.Count == 1 && (return_type_list.Count > 1 || return_tail_dec != null))
            {
                var value_stat = value_stat_list[0];
                var error      = value_stat.GuessTypes(out guess_list);
                if (error != null)
                {
                    return(error);
                }
                bool has_value_tail = guess_list.Count > 0 &&
                                      guess_list[guess_list.Count - 1] is ALittleScriptGuessReturnTail;

                if (return_tail_dec == null)
                {
                    if (has_value_tail)
                    {
                        if (guess_list.Count < return_type_list.Count - 1)
                        {
                            return(new ABnfGuessError(m_element, "return的函数调用的返回值数量超过函数定义的返回值数量"));
                        }
                    }
                    else
                    {
                        if (guess_list.Count != return_type_list.Count)
                        {
                            return(new ABnfGuessError(m_element, "return的函数调用的返回值数量和函数定义的返回值数量不相等"));
                        }
                    }
                }
                else
                {
                    if (has_value_tail)
                    {
                        // 不用检查
                    }
                    else
                    {
                        if (guess_list.Count < return_type_list.Count)
                        {
                            return(new ABnfGuessError(m_element, "return的函数调用的返回值数量少于函数定义的返回值数量"));
                        }
                    }
                }
            }
            else
            {
                if (return_tail_dec == null)
                {
                    if (value_stat_list.Count != return_type_list.Count)
                    {
                        return(new ABnfGuessError(m_element, "return的返回值数量和函数定义的返回值数量不相等"));
                    }
                }
                else
                {
                    if (value_stat_list.Count < return_type_list.Count)
                    {
                        return(new ABnfGuessError(m_element, "return的返回值数量少于函数定义的返回值数量"));
                    }
                }
                guess_list = new List <ABnfGuess>();
                foreach (var value_stat in value_stat_list)
                {
                    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 ABnfGuess guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    if (guess is ALittleScriptGuessParamTail)
                    {
                        return(new ABnfGuessError(value_stat, "return表达式不能返回\"...\""));
                    }
                    error = value_stat.GuessType(out ABnfGuess value_stat_guess);
                    if (error != null)
                    {
                        return(error);
                    }
                    guess_list.Add(value_stat_guess);
                }
            }

            // 每个类型依次检查
            for (int i = 0; i < guess_list.Count; ++i)
            {
                ALittleScriptValueStatElement target_value_stat = null;
                if (i < value_stat_list.Count)
                {
                    target_value_stat = value_stat_list[i];
                }
                else
                {
                    target_value_stat = value_stat_list[0];
                }

                if (guess_list[i] is ALittleScriptGuessReturnTail)
                {
                    break;
                }
                if (i >= return_type_list.Count)
                {
                    break;
                }
                var error = return_type_list[i].GuessType(out ABnfGuess return_type_guess);
                if (error != null)
                {
                    return(error);
                }
                if (return_type_guess is ALittleScriptGuessReturnTail)
                {
                    break;
                }

                error = ALittleScriptOp.GuessTypeEqual(return_type_guess, target_value_stat, guess_list[i], false, true);
                if (error != null)
                {
                    return(new ABnfGuessError(target_value_stat, "return的第" + (i + 1) + "个返回值数量和函数定义的返回值类型不同:" + error.GetError()));
                }
            }

            return(null);
        }
예제 #14
0
        public override ABnfGuessError CheckError()
        {
            var error = m_element.GuessTypes(out List <ABnfGuess> guess_list);

            if (error != null)
            {
                return(error);
            }
            if (guess_list.Count == 0)
            {
                return(new ABnfGuessError(m_element, "未知类型"));
            }
            else if (guess_list.Count != 1)
            {
                return(new ABnfGuessError(m_element, "重复定义"));
            }

            // 检查赋值表达式
            var value_dec = m_element.GetClassVarValueDec();

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

                    error = ALittleScriptOp.GuessTypeEqual(guess_list[0], const_value, guess, true, false);
                    if (error != null)
                    {
                        return(new ABnfGuessError(error.GetElement(), "等号左边的变量和表达式的类型不同:" + error.GetError()));
                    }
                }

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

                    if (!(guess is ALittleScriptGuessList) && !(guess is ALittleScriptGuessMap))
                    {
                        return(new ABnfGuessError(op_new_stat, "成员变量初始化只能赋值List或者Map或者常量"));
                    }

                    error = ALittleScriptOp.GuessTypeEqual(guess_list[0], op_new_stat, guess, true, false);
                    if (error != null)
                    {
                        return(new ABnfGuessError(error.GetElement(), "等号左边的变量和表达式的类型不同:" + error.GetError()));
                    }
                }
            }

            return(null);
        }