//
// NKalore Compiler related class
//
// Licensed under the terms of the GNU GPL
//
// Author:
// Guilherme Labigalini (glabega@gmail.com), 2005
//
// http://aspectsharpcomp.sourceforge.net/
using System;
using System.Collections;
namespace Mono.CSharp.AOP{
public class Aspect: Class
{
private ArrayList pointCuts;
private ArrayList advices;
#region CTOR
public Aspect(NamespaceEntry ns, TypeContainer parent, string name, int mod,
Attributes attrs, Location l)
: base (ns, parent, name, Modifiers.INTERNAL | Modifiers.SEALED, attrs, l)
{
pointCuts = new ArrayList();
advices = new ArrayList();
}
#endregion
#region Public Members
public override AdditionResult AddField (Field field)
{
field.ModFlags |= Modifiers.STATIC;
return base.AddField(field);
}
public AdditionResult AddPointCut(PointCut pointCut)
{
AdditionResult res;
string basename = pointCut.Name;
string fullname = Name + "." + basename;
if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
return res;
pointCuts.Add (pointCut);
DefineName (fullname, pointCut);
return AdditionResult.Success;
}
public AdditionResult AddAdvice(Advice advice)
{
advices.Add (advice);
return AdditionResult.Success;
}
public override bool DefineMembers(TypeContainer parent)
{
//make all members in the aspect static
DefineStatic();
//generate a private and static constructor or make user constructor private and static
DefineConstructor();
//apply the advicess to user classes
DefineAdvices(true);
DefineAdvices(false);
return base.DefineMembers(parent);
}
#endregion
#region Private Members
private PointCut FindPointCut(Advice advice)
{
foreach (PointCut pointCut in pointCuts)
{
if (advice.AdviceName == pointCut.Name)
{
if (advice.CanHandle(pointCut))
{
return pointCut;
}
break;
}
}
return null;
}
private void DefineAdvices(bool arounds)
{
foreach (Advice advice in advices)
{
if ((arounds && (! (advice is Around))) ||
((! arounds) && (advice is Around)))
{
continue;
}
AddMethod(advice);
PointCut pointCut = FindPointCut(advice);
if (pointCut == null)
{
Report.Error(0,
advice.Location,
"Pointcut named '{0}' does not exists", advice.AdviceName);
}
advice.ApplyAspect(pointCut);
}
}
private void AddPrivateConstrutor()
{
Location l = this.Location;
Constructor c = new Constructor(this, this.Basename,
Modifiers.PRIVATE,
new Parameters(null, false, l), null, l);
c.Block = new Block(null);
this.AddConstructor(c);
}
private void DefineConstructor()
{
int numConstructor = 0;
if (InstanceConstructors != null)
numConstructor = this.InstanceConstructors.Count;
if (numConstructor == 0)
{
AddPrivateConstrutor();
}
else if (numConstructor == 1 && default_static_constructor == null)
{
Constructor c = (Constructor)InstanceConstructors[0];
if ((c.ModFlags & Modifiers.STATIC) != 0)
return;
if (! c.Parameters.Empty)
Report.Error(0, c.Location,
"Arguments are not allowed in an aspect constructors");
//set the protection level of the constructor to protected
c.ModFlags = Modifiers.STATIC;
this.InstanceConstructors.Clear();
this.AddConstructor(c);
AddPrivateConstrutor();
}
else
{
Report.Error(0, this.Location, "Multiple constructors are not allowed in an aspect");
}
}
private void SetStatic(ArrayList members)
{
if (members != null)
{
foreach (MemberCore m in members)
m.ModFlags |= Modifiers.STATIC;
}
}
private void DefineStatic()
{
SetStatic(this.Methods);
SetStatic(this.Fields);
}
#endregion
}
}
|