/// <summary> /// Обработка локальных переменных метода и их типов для корректного захвата /// </summary> /// <param className="pd">Объявление метода</param> /// <returns>Коллекция посещенных локальных переменных</returns> // SSM - Эта функция уже не нужна - я иногда использую ее чтобы посмотреть как выглядит функция после Loweringа private void CreateLocalVariablesTypeProxies(procedure_definition pd, out IEnumerable<var_def_statement> localsClonesCollection) { // Выполняем определение типов локальных переменных с автовыводом типов // Клонируем исходный метод для вставки оберток-хелперов для локальных переменных и дальнейшей обработки на семантике var pdCloned = ObjectCopier.Clone(pd); //var pdCloned = pd; pdCloned.has_yield = false; // Заменяем локальные переменные с неизвестным типом на обертки-хелперы (откладываем до семантики) var localsTypeDetectorHelperVisitor = new LocalVariablesTypeDetectorHelperVisior(); pdCloned.visit(localsTypeDetectorHelperVisitor); // frninja 16/03/16 - строим список локальных переменных в правильном порядке localsTypeDetectorHelperVisitor.LocalDeletedDefs.AddRange(localsTypeDetectorHelperVisitor.LocalDeletedVS); localsTypeDetectorHelperVisitor.LocalDeletedVS.Clear(); localsClonesCollection = localsTypeDetectorHelperVisitor.LocalDeletedDefs.ToArray(); // Добавляем в класс метод с обертками для локальных переменных pdCloned.proc_header.name.meth_name = new ident(YieldConsts.YieldHelperMethodPrefix+ "_locals_type_detector>" + pd.proc_header.name.meth_name.name, // frninja 05/06/16 - фиксим source_context pd.proc_header.name.meth_name.source_context); // = new method_name("<yield_helper_locals_type_detector>" + pd.proc_header.className.meth_name.className); InsertHelperMethod(pd, pdCloned); // SSM 13.07.16 - вызов этого метода можно не добавлять }
/// <summary> /// Обработка локальных переменных метода и их типов для корректного захвата /// </summary> /// <param className="pd">Объявление метода</param> /// <returns>Коллекция посещенных локальных переменных</returns> private void CreateLocalVariablesTypeProxies(procedure_definition pd, out IEnumerable<var_def_statement> localsClonesCollection, out yield_locals_type_map_helper localsTypeMapHelper) { // Выполняем определение типов локальных переменных с автовыводом типов // Клонируем исходный метод для вставки оберток-хелперов для локальных переменных и дальнейшей обработки на семантике var pdCloned = ObjectCopier.Clone(pd); // Заменяем локальные переменные с неизвестным типом на обертки-хелперы (откладываем до семантики) localsTypeMapHelper = new yield_locals_type_map_helper(); LocalVariablesTypeDetectorHelperVisior localsTypeDetectorHelperVisitor = new LocalVariablesTypeDetectorHelperVisior(localsTypeMapHelper); pdCloned.visit(localsTypeDetectorHelperVisitor); // frninja 16/03/16 - строим список локальных переменных в правильном порядке localsTypeDetectorHelperVisitor.LocalDeletedDefs.AddRange(localsTypeDetectorHelperVisitor.LocalDeletedVS); localsTypeDetectorHelperVisitor.LocalDeletedVS.Clear(); localsClonesCollection = localsTypeDetectorHelperVisitor.LocalDeletedDefs.ToArray(); // Добавляем в класс метод с обертками для локальных переменных pdCloned.proc_header.name.meth_name = new ident(YieldConsts.YieldHelperMethodPrefix+ "_locals_type_detector>" + pd.proc_header.name.meth_name.name); // = new method_name("<yield_helper_locals_type_detector>" + pd.proc_header.className.meth_name.className); if (IsClassMethod(pd)) { var cd = UpperTo<class_definition>(); if (cd != null) { // Метод класса описан в классе var classMembers = UpperTo<class_members>(); classMembers.Add(pdCloned); } else { // Метод класса описан вне класса var decls = UpperTo<declarations>(); var classMembers = decls.list .Select(decl => decl as type_declarations) .Where(tdecls => tdecls != null) .SelectMany(tdecls => tdecls.types_decl) .Where(td => td.type_name.name == GetClassName(pd).name) .Select(td => td.type_def as class_definition) .Where(_cd => _cd != null) .SelectMany(_cd => _cd.body.class_def_blocks); // Вставляем предописание метода-хелпера var helperPredefHeader = ObjectCopier.Clone(pdCloned.proc_header); helperPredefHeader.name.class_name = null; classMembers.First().members.Insert(0, helperPredefHeader); // Вставляем тело метода-хелпера UpperTo<declarations>().InsertBefore(pd, pdCloned); } } else { UpperTo<declarations>().InsertBefore(pd, pdCloned); } }