Re: А не замутить ли AOP на основе R#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.04 20:21
Оценка: 15 (1)
Здравствуйте, gloomy rocker, Вы писали:

GR>Есть идея замутить сабж. Нечто типа Aspect#, только чтобы грамматика этого расширения укладывалась в грамматику C#.

...

GR>Можно делать не только пре и пост обработку. Можно например обернуть все это в try...catch. Ну в общем что угодно...

GR>Аналогичную обработку можно сделать и для свойств, полей, конструкторов.

GR>Надеюсь, идею я изложил понятно. Прошу высказываться, кто что думает по этому поводу.


Идея здравая, но делать для этого Aspect# не нужно. Это реализуется R#-ом уже сейчас. Нужно только сделать качественную реализацию соотвествующего правила.

Вот тут:
* Обзор современного состояния проекта, TODO и т.п.
Автор: VladD2
Дата: 30.10.04

* Мета-правило реализующиее паттерн Visitor
Автор: VladD2
Дата: 16.11.04

можно получить общее представление как это можно сделать.

В двух словах все выглядит так:
R# реализован как некий компилятор-препроцессор. Он запускается перед окончательной комплиляцией, парсит проект (путь к которому получает в качестве параметра), ищет мета-правали, выполняет их (те в свою очередь меняют AST как хотят), генерирует по преобразованному AST код на чистом C#.

Таким образом ничто не мешает сделать правило которое с помощью XPath-запроса найдет все конструкции помеченные неким атрибутом, найдет аспект и интеллектуально скопирует аспектный код в нужные места.

Причем в принципе можно даже обходиться без пометок атрибутами. То что называется PointCut-ами и т.п. можно сделать XPath-запросами. Это намного гибче (хотя никто не мешает использовать и атрибуты).

Сделать это можно уже сейчас. Нужно только изучить как писать мета-правила.

Я сейчас делаю намного более сложные вещи. Проект RSharp.Rules генерирует код для самого R#-а. Например, вот из такого шаблона:
  [NodeName("class")]
  public class RTypeClass : RTypeUdt // обрати внимание! При генерации учитываются члены базового класса
  {
    public abstract RTypeClass NextPart
    {
      get; 
      set; 
    }
}

генерируется вот такой мудреный код:
[NodeName("class")]
public class RTypeClass : RTypeUdt
{
    #line default
    
    
    RTypeClass _nextPart;
    #line 25 "..\..\..\rsctest\codedom\types\RTypeClass.cs"
    
    public RTypeClass NextPart
    {
        get
        {
            #line default
            
            return _nextPart;
        }
        set
        {
            #line default
            
            if (value.Parent != null)
                _nextPart = ((RTypeClass)(value.Clone()));
            else
                _nextPart = value;
            value.Parent = this;
        }
    }
    [RSParser.CodeDom.Design.TypeID(TypeID.RTypeClass)]
    public override TypeID TypeID
    {
        get
        {
            return TypeID.RTypeClass;
        }
    }
    public override AstNode Clone()
    {
        RTypeClass clone = new RTypeClass();
        clone.BaseTypes.AddRange(this.BaseTypes);
        clone.Members.AddRange(this.Members);
        clone.TypeParameters.AddRange(this.TypeParameters);
        clone.CustomAttributeSections.AddRange(this.CustomAttributeSections);
        clone.Name = this.Name;
        clone.Modifiers = this.Modifiers;
        clone.StartLocation = this.StartLocation;
        clone.EndLocation = this.EndLocation;
        clone.FileName = this.FileName;
        {
            RTypeClass temp = this.NextPart;
            if (temp != null)
                clone.NextPart = ((RTypeClass)(temp.Clone()));
        }
        #line default
        
        return clone;
    }
    #line default
    
    public override IDomContainer GetChild(int index)
    {
        switch (index)
        {
        case 0:
            return this.BaseTypes;
        case 1:
            return this.Members;
        case 2:
            return this.TypeParameters;
        case 3:
            return this.CustomAttributeSections;
        case 4:
            return this.NextPart;
        }
        throw new ArgumentException("Illegal index.");
    }
    public override int GetChildCount()
    {
        return 5;
    }
    public override string[] GetChildNames()
    {
        return _childNames;
    }
    public override int[] GetWritableStringPropertyIndices()
    {
        return _writableStringPropertyIndices;
    }
    public override int[] GetStringPropertyIndices()
    {
        return _stringPropertyIndices;
    }
    public override string[] GetPropertyNames()
    {
        return _propertyNames;
    }
    
    private readonly static string[] _childNames = 
    {
        #line default
        "NextPart","BaseTypes","Members","TypeParameters","CustomAttributeSections"
    };
    #line default
    
    
    private readonly static string[] _propertyNames = 
    {
        #line default
        "Name","Modifiers","StartLocation","EndLocation","FileName","TypeCode",
    "NamespaceName","FullName","TypeID"
    };
    #line default
    
    
    protected new static int[] _stringPropertyIndices = 
    {
        #line default
        0,4,6,7
    };
    #line default
    
    
    protected new static int[] _writableStringPropertyIndices = 
    {
        #line default
        0,4
    };
    #line default
    
    public override void AcceptVisitor(IAstVisitor visitor)
    {
        visitor.Visit(this);
    }
}

Это намного сложнее чем АОП, так как подставляемая реализация автоматически генерируется по определенному алгоритму. Так что сделать АОП вообще не сложная задача. Вот только у меня и так много проблем. Нужно доделать самогенерацию кода R#, а у меня на работе полный завал.

Так что есль есть решимость, желание и смелость, то милости просим... Я со своей соторы постараюсь помчь советом и ответить на любые вопросы.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.