package lawOfDemeter.objectform;



aspect checkingLoD extends LawofDemeter{
	private pointcut AssRule1_SelfCall(Object thiz, MethodSupplier target): 
		call(* *.*(..)) && target(target) && this(thiz) 
		&& if(target == thiz) && Scope();

	private pointcut AssRule2_StaticCall():
		call(static * *.*(..)) && this(Object) && Scope();

	private pointcut AssRule3_ConstructorCall():
		call(*.new(..)) && this(Object) && Scope();
	
	private pointcut ArgRule1_MethodCall():
		call(* *.*(..)) && target(MethodSupplier) &&
		Scope() ;

	private pointcut ArgRule2_ConstructorCall():
		call(*.new(..))  && Scope();

	private pointcut Scope(): 
		!within(lawOfDemeter..*)&& !cflow(withincode(* lawOfDemeter..*(..)));
	
	public pointcut Check(Object thiz, Checked target): 
		call(* *.*(..)) && target(target) && this(thiz) && 
		this(MethodSupplier) && this(FieldSupplier) && 
		Scope();

	public pointcut ArgumentRule(): 
		ArgRule1_MethodCall() || ArgRule2_ConstructorCall();

	public pointcut AssociatedRule():
		AssRule1_SelfCall(Object, MethodSupplier) || 
		AssRule2_StaticCall() || 
		AssRule3_ConstructorCall();

        public pointcut Set(FieldSupplier target, Object value): 
		set(* *.*) && args(value) && target(target) && Scope();

	declare parents: * && ! lawOfDemeter..* implements Checked;
	declare parents: * && ! lawOfDemeter..* implements MethodSupplier;
	declare parents: * && ! lawOfDemeter..* implements FieldSupplier;

}

