public override bool Rewrite( CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder) { if (args.Length == 0) throw new InvalidOperationException("The attribute SignalProperty was applied to the wrong method"); LiteralReference refExpr = args[0].Expr as LiteralReference; if (refExpr == null) throw new InvalidOperationException("Unable to resolve port/signal reference expression"); ISignal sigSample = args[0].Sample as ISignal; SignalRef sigRef = null; LambdaLiteralVisitor llv = new LambdaLiteralVisitor() { OnVisitConstant = x => { sigRef = ((ISignal)x.ConstantValue).ToSignalRef(Prop); }, OnVisitSignalRef = x => { sigRef = new SignalRef(x.Desc, Prop, x.Indices, x.IndexSample, x.IsStaticIndex); }, OnVisitVariable = x => { SignalArgumentDescriptor desc = decompilee.GetSignalArguments().Where(y => y.Name.Equals(x.Name)).Single(); sigRef = new SignalRef(desc, Prop); }, OnVisitFieldRef = x => { sigRef = ((ISignal)x.FieldDesc.ConstantValue).ToSignalRef(Prop); }, OnVisitThisRef = x => { throw new InvalidOperationException(); }, OnVisitArrayRef = x => { throw new InvalidOperationException(); } }; refExpr.ReferencedObject.Accept(llv); ParameterInfo[] pis = callee.GetParameters(); switch (Prop) { case SignalRef.EReferencedProperty.ChangedEvent: case SignalRef.EReferencedProperty.Cur: case SignalRef.EReferencedProperty.FallingEdge: case SignalRef.EReferencedProperty.Pre: case SignalRef.EReferencedProperty.RisingEdge: //if (pis.Length != 0 || callee.IsStatic) // throw new InvalidOperationException("The attribute SignalProperty was applied to the wrong method."); switch (Prop) { case SignalRef.EReferencedProperty.Cur: case SignalRef.EReferencedProperty.Pre: stack.Push( sigRef, sigSample != null ? sigSample.InitialValueObject : null); break; case SignalRef.EReferencedProperty.ChangedEvent: stack.Push( sigRef, null); break; case SignalRef.EReferencedProperty.FallingEdge: case SignalRef.EReferencedProperty.RisingEdge: stack.Push( sigRef, false); break; default: throw new NotImplementedException(); } break; case SignalRef.EReferencedProperty.Next: if (pis.Length != 1 || callee.IsStatic) throw new InvalidOperationException("The attribute SignalProperty was applied to the wrong method."); builder.Store(sigRef, args[1].Expr); decompilee.AddDrivenSignal(sigRef.Desc); break; default: throw new NotImplementedException(); } return true; }