метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 11.02.12 12:07
Оценка: 2 (2)
нужен в данный момент, чтобы изменить поле на свойство. после сгодится для любых трансформаций внутри N-данных на ранних фазах.
возможно в его код надо вписать ограничение на фазу. использование на этапе BeforeInheritance проблем не вызывает, все тесты ок.



From 68d2c7f61b8bcc06b334148768ccecc466bad8c7 Mon Sep 17 00:00:00 2001
From: George Dernovoy <g.dernovoy@gmail.com>
Date: Sat, 11 Feb 2012 03:33:13 +0200
Subject: [PATCH] add TypeBuilder.RemoveParsedMember

---
 ncc/hierarchy/TypeBuilder.n |   11 ++++++++++-
 ncc/parsing/ParseTree.n     |   22 ++++++++++++++++++----
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/ncc/hierarchy/TypeBuilder.n b/ncc/hierarchy/TypeBuilder.n
index c6a1e5a..55ae80e 100644
--- a/ncc/hierarchy/TypeBuilder.n
+++ b/ncc/hierarchy/TypeBuilder.n
@@ -783,7 +783,16 @@ public partial class TypeBuilder : TypeInfo
 
     result.NToList()
   }
-
+  
+  public RemoveParsedMember(member : PT.ClassMember) : void
+  {
+    match(AstParts.Find(x => x.GetMembers().Contains(member)))
+    {
+      | Some(val) => val.Remove(member);
+      | _ => {}
+    }
+  }
+      
   public override GetFields (bindingAttr : BindingFlags) : list[IField]
   {
     def mems = get_members (bindingAttr, fun (x : IMember) {
diff --git a/ncc/parsing/ParseTree.n b/ncc/parsing/ParseTree.n
index e1ab8f9..79e0c87 100644
--- a/ncc/parsing/ParseTree.n
+++ b/ncc/parsing/ParseTree.n
@@ -38,7 +38,7 @@ namespace Nemerle.Compiler.Parsetree
     | Class
       {
         mutable t_extends : list[PExpr];
-                decls     : list[ClassMember];
+        mutable decls     : list[ClassMember];
       }
 
     | Alias { ty : PExpr; }
@@ -46,7 +46,7 @@ namespace Nemerle.Compiler.Parsetree
     | Interface
       {
         mutable t_extends : list [PExpr];
-        methods : list [ClassMember]; // only iface_member
+        mutable methods : list [ClassMember]; // only iface_member
       }
 
     | Variant
@@ -55,7 +55,7 @@ namespace Nemerle.Compiler.Parsetree
         mutable decls : list [ClassMember];
       }
 
-    | VariantOption { decls : list [ClassMember]; }
+    | VariantOption { mutable decls : list [ClassMember]; }
 
     | Macro
       {
@@ -73,7 +73,7 @@ namespace Nemerle.Compiler.Parsetree
     | Enum
       {
         t_extends : list [PExpr];
-        decls : list[ClassMember];
+        mutable decls : list[ClassMember];
       }
 
     [RecordIgnore]
@@ -186,6 +186,20 @@ namespace Nemerle.Compiler.Parsetree
       }
     }
 
+    public Remove(m : ClassMember) : void
+    {
+      match (this)
+      {
+        | x is Class      =>     x.decls = x.decls.Remove(m)
+        | x is Interface  =>     x.methods = x.methods.Remove(m)
+        | x is Variant    =>     x.decls = x.decls.Remove(m)
+        | x is VariantOption =>  x.decls = x.decls.Remove(m)
+        | x is Enum       =>     x.decls = x.decls.Remove(m)
+        | _  => {}
+      }
+    }
+      
+    
     public GetMembers() : list[ClassMember]
     {
       match (this)
-- 
1.7.8.msysgit.0
Re: метод TypeBuilder.RemoveParsedMember
От: CodingUnit Россия  
Дата: 11.02.12 17:17
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>нужен в данный момент, чтобы изменить поле на свойство. после сгодится для любых трансформаций внутри N-данных на ранних фазах.

_C_>возможно в его код надо вписать ограничение на фазу. использование на этапе BeforeInheritance проблем не вызывает, все тесты ок.

Лучше приводи не весь патч, а код который ты добавил, возможно с комментариями. Изменять дерево из неизменяемого в изменяемое не совсем верная практика, надо идти другим путем, можно создать новое дерево без члена который был удален. И делать это нужно не только с парсед деревом, этого может будет достаточно для удаления на стадии BeforeInheritance, но и с типизированным деревом тоже. Нам же нужно более универсальное решение, это может быть немалая работа, но мне кажется это возможно, если ссылок на код нет то проблем не возникнет, не вижу почему мы не можем сделать столь простой операции. Надо продумать все основательно, чтобы решение было принято сообществом. Вообще хорошая работа, ты делаешь уже первые шаги в компиляторе, так держать, надо продумать все и сделать лучшее решение, на основе того что я сказал.
Re[2]: метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 11.02.12 20:05
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Здравствуйте, _Claus_, Вы писали:


_C_>>нужен в данный момент, чтобы изменить поле на свойство. после сгодится для любых трансформаций внутри N-данных на ранних фазах.

_C_>>возможно в его код надо вписать ограничение на фазу. использование на этапе BeforeInheritance проблем не вызывает, все тесты ок.

CU>Лучше приводи не весь патч, а код который ты добавил, возможно с комментариями.


код который добавил — +
изменил — +-


CU>Изменять дерево из неизменяемого в изменяемое не совсем верная практика, надо идти другим путем, можно создать новое дерево без члена который был удален.


это большие накладные расходы. но если так Н-идеологически лучше, пусть так. в конце концов это нечастая операция.

CU>И делать это нужно не только с парсед деревом, этого может будет достаточно для удаления на стадии BeforeInheritance, но и с типизированным деревом тоже.


не возражаю. но если на стадии BeforeInheritance никаких проблем нет, то дальше вам виднее. это решает проблему модификации, с минимальными изменениями.
Re[2]: метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 12.02.12 00:52
Оценка:
CU>Лучше приводи не весь патч, а код который ты добавил, возможно с комментариями. Изменять дерево из неизменяемого в изменяемое не совсем верная практика, надо идти другим путем, можно создать новое дерево без члена который был удален.

все таки не соглашусь. если мы признаем возможность менять-удалять в нем данные, то какой смысл держаться за его неизменяемость?
кого мы обманываем? компилятор? сторонников неизменяемости? только усложним себе жизнь запутанным кодом.
Re[3]: метод TypeBuilder.RemoveParsedMember
От: CodingUnit Россия  
Дата: 12.02.12 01:08
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>все таки не соглашусь. если мы признаем возможность менять-удалять в нем данные, то какой смысл держаться за его неизменяемость?

_C_>кого мы обманываем? компилятор? сторонников неизменяемости? только усложним себе жизнь запутанным кодом.

Мы признаем возможность менять удалять, но это не значит что дерево теперь надо делать изменяемым, с изменяемостью больше проблем, никогда нельзя гарантировать что где то этот экземпляр не будет изменен, со временем ты познаешь пользу этого.
Дерево должно быть неизменямым, компилятор был написан в плохих манерах, кругом иммутабельные данные, мы стараемся его приблизить более к функциональному стилю, то что было до этого неизменяемым не делаем изменяемым. Нужно изменение порождай новое дерево, вот и все, Н2 будет таким, любое изменение будет порождать новую копию, здесь если делать, то также, поведение будет тоже самое, это лишь скрыто в деталях, зато пользы от неизменяемости будет больше. Если уж взялся за функциональный язык и компилятор, то пиши в функциональном стиле, поначалу это кажется бредом, лишней работой, но потом узнаешь пользу этого.
Re[4]: метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 12.02.12 01:57
Оценка:
_C_>>все таки не соглашусь. если мы признаем возможность менять-удалять в нем данные, то какой смысл держаться за его неизменяемость?
_C_>>кого мы обманываем? компилятор? сторонников неизменяемости? только усложним себе жизнь запутанным кодом.

CU> Если уж взялся за функциональный язык и компилятор, то пиши в функциональном стиле, поначалу это кажется бредом, лишней работой, но потом узнаешь пользу этого.


приведу пример: в проекте 20 классов по 10 полей в каждом. в процессе генерации компилятору придется 200 раз пересоздать все(!) дерево разбора.
если мнимая иммутабельность просадит скорость компиляции на порядок, где логика?
Re[5]: метод TypeBuilder.RemoveParsedMember
От: CodingUnit Россия  
Дата: 12.02.12 02:13
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>приведу пример: в проекте 20 классов по 10 полей в каждом. в процессе генерации компилятору придется 200 раз пересоздать все(!) дерево разбора.

_C_>если мнимая иммутабельность просадит скорость компиляции на порядок, где логика?

Все дерево не надо пересоздавать, а только ту часть которую ты хотел изменить, сейчас это наверное касается одного класса. Смотря что ты хочешь делать с этими полями, пересоздавать дерево для класса, то есть его содержимое, нужно только когда нужно изменение, если в 20 классах ты будешь удалять одно поле, из 10, то надо будет создавать новый список в каждом классе, который содержит 9 полей, таких созданий будет 20, ничего страшного от этого не будет.
Re[5]: метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 12.02.12 02:16
Оценка:
_C_>приведу пример: в проекте 20 классов по 10 полей в каждом. в процессе генерации компилятору придется 200 раз пересоздать все(!) дерево разбора.
_C_>если мнимая иммутабельность просадит скорость компиляции на порядок, где логика?

если же дерево фрагментируется на заменяемые поддеревья, то почему ту же логику нельзя применить и к нижним веткам?
надуманные ограничения это, имхо. именно в данном месте.
Re[6]: метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 12.02.12 02:19
Оценка:
CU>Все дерево не надо пересоздавать, а только ту часть которую ты хотел изменить, сейчас это наверное касается одного класса. Смотря что ты хочешь делать с этими полями, пересоздавать дерево для класса, то есть его содержимое, нужно только когда нужно изменение, если в 20 классах ты будешь удалять одно поле, из 10, то надо будет создавать новый список в каждом классе, который содержит 9 полей, таких созданий будет 20, ничего страшного от этого не будет.

в 20 классах я по описанию буду менять все поля с обычных на свойства. итого 200 полей.
Re[7]: метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 12.02.12 02:21
Оценка:
_C_>в 20 классах я по описанию буду менять все поля с обычных на свойства. итого 200 полей.

эт я не выдумываю. так будет работать.
Re[6]: метод TypeBuilder.RemoveParsedMember
От: CodingUnit Россия  
Дата: 12.02.12 02:24
Оценка:
Здравствуйте, _Claus_, Вы писали:


_C_>если же дерево фрагментируется на заменяемые поддеревья, то почему ту же логику нельзя применить и к нижним веткам?

_C_>надуманные ограничения это, имхо. именно в данном месте.

Потому что идем к функциональному стилю, а не наоборот, то что было создано изменяемое пока остается так, если можно быстро создать его лучше, то можно сделать, но обратно к изменяемому виду не нужно делать, мы наоборот стараемся избавиться от изменяемых данных, и все новое делается в хорошем стиле.
Re[7]: метод TypeBuilder.RemoveParsedMember
От: CodingUnit Россия  
Дата: 12.02.12 02:29
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>в 20 классах я по описанию буду менять все поля с обычных на свойства. итого 200 полей.


Ну так меняй их пачками, а не по одному, зачем для каждого делать операцию удаления, можно считать все поля и изменить их определение на свойства, потом разом добавить в класс, заменив старые объявления, так получится одно пересоздание. Даже если будет несколько пересозданий, ничего плохого не будет заметно, там совсем небольшие списки полей.
Re[8]: метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 12.02.12 02:35
Оценка:
CU>Ну так меняй их пачками, а не по одному, зачем для каждого делать операцию удаления, можно считать все поля и изменить их определение на свойства, потом разом добавить в класс, заменив старые объявления, так получится одно пересоздание. Даже если будет несколько пересозданий, ничего плохого не будет заметно, там совсем небольшие списки полей.

сильно мудрено для меня. но код на это посмотрю, если кто покажет.
Re: метод TypeBuilder.RemoveParsedMember
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.02.12 02:38
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>нужен в данный момент, чтобы изменить поле на свойство. после сгодится для любых трансформаций внутри N-данных на ранних фазах.

_C_>возможно в его код надо вписать ограничение на фазу. использование на этапе BeforeInheritance проблем не вызывает, все тесты ок.


Возможно? Да твой код просто приведет к некорректному поведению на WithTypedMembers. Уже добавленные члены не удалятся, так как типизированные их представления уже будут закэшированы. А вот если кто-о захочет получить АСТ для типизированных представлений, то будет "фиаско".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 12.02.12 02:58
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, _Claus_, Вы писали:


_C_>>нужен в данный момент, чтобы изменить поле на свойство. после сгодится для любых трансформаций внутри N-данных на ранних фазах.

_C_>>возможно в его код надо вписать ограничение на фазу. использование на этапе BeforeInheritance проблем не вызывает, все тесты ок.


VD>Возможно? Да твой код просто приведет к некорректному поведению на WithTypedMembers. Уже добавленные члены не удалятся, так как типизированные их представления уже будут закэшированы. А вот если кто-о захочет получить АСТ для типизированных представлений, то будет "фиаско".


так потому и предложил вписать ограничение. догадывался... а типизированные представления — я такого вообще не говорил. мне нетипизированного хватит. а дальше или глубже — на ваше усмотрение.
Re[3]: метод TypeBuilder.RemoveParsedMember
От: CodingUnit Россия  
Дата: 12.02.12 03:11
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>так потому и предложил вписать ограничение. догадывался... а типизированные представления — я такого вообще не говорил. мне нетипизированного хватит. а дальше или глубже — на ваше усмотрение.


Надо делать универсальный метод, который будет удалять члены, в нем можно сделать перегрузку для парсед и типизированных членов, они должны знать на какой фазе работает компилятор и могут удалять из обоих деревьев.
Re: метод TypeBuilder.RemoveParsedMember
От: Аноним  
Дата: 12.02.12 13:13
Оценка:
тогда все внутренние обращения будут идти к свойству, что возможно не есть хорошо. Кроме того как быть с внешними сборками
Re[2]: метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 12.02.12 13:24
Оценка:
А>тогда все внутренние обращения будут идти к свойству, что возможно не есть хорошо. Кроме того как быть с внешними сборками

речь идет о возможности сделать это когда нужно. всегда это не нужно. иногда — да. на код использования внешним кодом никак не влияет — деталь реализации.
Re[3]: метод TypeBuilder.RemoveParsedMember
От: Аноним  
Дата: 12.02.12 14:12
Оценка:
Здравствуйте, _Claus_, Вы писали:


А>>тогда все внутренние обращения будут идти к свойству, что возможно не есть хорошо. Кроме того как быть с внешними сборками


_C_>речь идет о возможности сделать это когда нужно. всегда это не нужно. иногда — да. на код использования внешним кодом никак не влияет — деталь реализации.

Если класс уже скомпилирован то тут вряд ли пройдет данный подход. Сделать изменение так можно только в исходнике. Тогда почему Просто не прописать макрос свойство?
Вообщем чем дальше смотрю на мучения с немерли тем больше верю в пословицу. Любая попытка сделать макросы это попытка изобрести лисп
Re[4]: метод TypeBuilder.RemoveParsedMember
От: _Claus_  
Дата: 12.02.12 15:27
Оценка:
А>Если класс уже скомпилирован то тут вряд ли пройдет данный подход. Сделать изменение так можно только в исходнике.
конечно речь о исходниках.

А>Тогда почему Просто не прописать макрос свойство?

да это оно и есть. кусок этого. самый критичный. только более универсальный.

A>Вообщем чем дальше смотрю на мучения с немерли тем больше верю в пословицу. Любая попытка сделать макросы это попытка изобрести лисп

переизобрести. лучше. быстрее. проще.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.