public override void ImplementDeclaration(DescriptorBase container, PropertyInfo declSite) { ComponentDescriptor cd = container as ComponentDescriptor; if (cd == null) throw new ArgumentException("Cannot implement property " + declSite.Name + " as port because it is not declared inside a component!"); Channel boundChannel = (Channel)declSite.GetValue(cd.Instance, new object[0]); // Ignore unbound ports if (boundChannel == null) { AttributeInjector.InjectOnce( declSite.GetGetMethod(true), cd.Instance, new AssumeNotCalled()); return; } if (boundChannel is SignalBase) { SignalBase boundSignal = (SignalBase)boundChannel; SignalDescriptor boundSignalDesc = boundSignal.Descriptor; TypeDescriptor elType = boundSignalDesc.ElementType; Descriptor = new PortDescriptor( declSite, boundSignalDesc, elType, Direction); CreateChildPDs(Descriptor, boundSignalDesc); container.AddChild(Descriptor, Descriptor.DeclarationSite.Name); IPackageOrComponentDescriptor pcd = container as IPackageOrComponentDescriptor; if (pcd != null && elType.Package != null) pcd.AddDependency(elType.Package); IPortDescriptor port = cd.FindPort(declSite.Name); // Accesses to port-like properties are statically evaluated AttributeInjector.InjectOnce( declSite.GetGetMethod(true), cd.Instance, new StaticEvaluation(x => new SignalRef(port, SignalRef.EReferencedProperty.Instance))); } else { throw new NotImplementedException("Non-signal ports are not yet supported"); } }
private IEnumerable <SignalArgumentDescriptor> InspectMethod(MethodDescriptor md) { List <Statement> stmts = md.Implementation.Body.GetAtomicStatements(); IEnumerable <StoreStatement> stores = stmts.Select(s => s as StoreStatement).Where(s => s != null); Dictionary <ISignalOrPortDescriptor, SignalArgumentDescriptor> map = new Dictionary <ISignalOrPortDescriptor, SignalArgumentDescriptor>(); int order = md.GetArguments().Count(); foreach (StoreStatement stmt in stores) { SignalRef sref = stmt.Container as SignalRef; if (sref == null) { continue; } if (sref.Desc is SignalArgumentDescriptor) { continue; } SignalArgumentDescriptor sad; if (!map.TryGetValue(sref.Desc, out sad)) { string name = "a_" + sref.Desc.Name; SignalDescriptor sd = sref.Desc as SignalDescriptor; PortDescriptor pd = sref.Desc as PortDescriptor; SignalBase signalInst; if (pd != null) { signalInst = ((SignalDescriptor)pd.BoundSignal).Instance; } else { signalInst = sd.Instance; } ArgumentDescriptor.EArgDirection flowDir; if (pd == null) { flowDir = ArgumentDescriptor.EArgDirection.InOut; } else { switch (pd.Direction) { case EFlowDirection.In: flowDir = ArgumentDescriptor.EArgDirection.In; break; case EFlowDirection.InOut: flowDir = ArgumentDescriptor.EArgDirection.InOut; break; case EFlowDirection.Out: flowDir = ArgumentDescriptor.EArgDirection.Out; break; default: throw new NotImplementedException(); } } sad = new SignalArgumentDescriptor( SignalRef.Create(sref.Desc, SignalRef.EReferencedProperty.Instance), ArgumentDescriptor.EArgDirection.In, flowDir, EVariability.Constant, order++); map[sref.Desc] = sad; } SignalRef srefArg = new SignalRef(sad, sref.Prop, sref.Indices, sref.IndexSample, sref.IsStaticIndex); stmt.Container = srefArg; } foreach (SignalArgumentDescriptor sad in map.Values) { md.AddChild(sad, sad.Argument.Name); } return(map.Values.OrderBy(k => k.Order)); }
private void CreateChildPDs(PortDescriptor pd, SignalDescriptor sd) { foreach (SignalDescriptor sdc in sd.GetSignals()) { PortDescriptor pdc = new PortDescriptor( pd.DeclarationSite, sdc.SignalInstance.Descriptor, sdc.SignalInstance.ElementType, Direction); pd.AddChild(pdc, sdc.Name); CreateChildPDs(pdc, sdc); } }