public override ABnfGuess Clone() { var guess = new ALittleScriptGuessClass(namespace_name, class_name, class_dec, using_name, is_const, is_native); guess.template_list.AddRange(template_list); foreach (var pair in template_map) { guess.template_map.Add(pair.Key, pair.Value); } guess.UpdateValue(); return(guess); }
public override ABnfGuessError GuessTypes(out List <ABnfGuess> guess_list) { guess_list = null; var name_dec = m_element.GetClassNameDec(); if (name_dec == null) { return(new ABnfGuessError(m_element, "没有定义类名")); } var body_dec = m_element.GetClassBodyDec(); if (body_dec == null) { return(new ABnfGuessError(m_element, "没有定义类体")); } var namespace_element_dec = m_element.GetParent() as ALittleScriptNamespaceElementDecElement; if (namespace_element_dec == null) { return(new ABnfGuessError(m_element, "ALittleScriptClassDecReference的父节点不是ALittleScriptNamespaceElementDecElement")); } bool is_native = ALittleScriptUtility.IsNative(namespace_element_dec.GetModifierList()); var info = new ALittleScriptGuessClass(m_namespace_name, name_dec.GetElementText(), m_element, null, false, is_native); var template_dec = m_element.GetTemplateDec(); if (template_dec != null) { var error = template_dec.GuessTypes(out info.template_list); if (error != null) { return(error); } } info.UpdateValue(); guess_list = new List <ABnfGuess>() { info }; return(null); }
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); }
private ABnfGuessError ReplaceTemplate(ABnfGuess guess, out ABnfGuess result) { result = null; if (m_class_guess == null) { result = guess; return(null); } if (guess is ALittleScriptGuessTemplate && m_class_guess.template_map.Count > 0) { if (m_class_guess.template_map.TryGetValue(guess.GetValueWithoutConst(), out ABnfGuess guess_template)) { if (guess.is_const && !guess_template.is_const) { guess_template = guess_template.Clone(); guess_template.is_const = true; guess_template.UpdateValue(); } result = guess_template; } else { result = guess; } return(null); } if (guess is ALittleScriptGuessFunctor) { var guess_functor = guess as ALittleScriptGuessFunctor; var info = new ALittleScriptGuessFunctor(guess_functor.element); info.await_modifier = guess_functor.await_modifier; info.const_modifier = guess_functor.const_modifier; info.proto = guess_functor.proto; info.template_param_list.AddRange(guess_functor.template_param_list); info.param_tail = guess_functor.param_tail; info.param_name_list.AddRange(guess_functor.param_name_list); info.return_tail = guess_functor.return_tail; int start_index = 0; if (guess_functor.element is ALittleScriptClassMethodDecElement || guess_functor.element is ALittleScriptClassSetterDecElement || guess_functor.element is ALittleScriptClassGetterDecElement) { info.param_list.Add(m_class_guess); info.param_nullable_list.Add(false); if (info.param_name_list.Count > 0) { info.param_name_list[0] = m_class_guess.GetValue(); } start_index = 1; } for (int i = start_index; i < guess_functor.param_list.Count; ++i) { var error = ReplaceTemplate(guess_functor.param_list[i], out ABnfGuess guess_info); if (error != null) { return(error); } info.param_list.Add(guess_info); } for (int i = start_index; i < guess_functor.param_nullable_list.Count; ++i) { info.param_nullable_list.Add(guess_functor.param_nullable_list[i]); } for (int i = 0; i < guess_functor.return_list.Count; ++i) { var error = ReplaceTemplate(guess_functor.return_list[i], out ABnfGuess guess_info); if (error != null) { return(error); } info.return_list.Add(guess_info); } info.UpdateValue(); result = info; return(null); } if (guess is ALittleScriptGuessList) { var guess_list = guess as ALittleScriptGuessList; var error = ReplaceTemplate(guess_list.sub_type, out ABnfGuess sub_info); if (error != null) { return(error); } var info = new ALittleScriptGuessList(sub_info, guess_list.is_const, guess_list.is_native); info.UpdateValue(); result = info; return(null); } if (guess is ALittleScriptGuessMap) { var guess_map = guess as ALittleScriptGuessMap; var error = ReplaceTemplate(guess_map.key_type, out ABnfGuess key_info); if (error != null) { return(error); } error = ReplaceTemplate(guess_map.value_type, out ABnfGuess value_info); if (error != null) { return(error); } var info = new ALittleScriptGuessMap(key_info, value_info, guess.is_const); info.UpdateValue(); result = info; return(null); } if (guess is ALittleScriptGuessClass) { var guess_class = guess as ALittleScriptGuessClass; var info = new ALittleScriptGuessClass(guess_class.namespace_name, guess_class.class_name, guess_class.class_dec, guess_class.using_name, guess_class.is_const, guess_class.is_native); info.template_list.AddRange(guess_class.template_list); foreach (var pair in guess_class.template_map) { if (info.template_map.ContainsKey(pair.Key)) { info.template_map.Remove(pair.Key); } var error = ReplaceTemplate(pair.Value, out ABnfGuess replace_guess); if (error != null) { return(error); } info.template_map.Add(pair.Key, replace_guess); } var src_class_dec = guess_class.class_dec; var src_class_name_dec = src_class_dec.GetClassNameDec(); if (src_class_name_dec == null) { return(new ABnfGuessError(m_element, "类模板没有定义类名")); } info.UpdateValue(); result = info; return(null); } result = guess; return(null); }