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); }
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); }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }