Здравствуйте, 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>>