Ejemplo n.º 1
0
        public void OnFindReferences(object sender, EventArgs e)
        {
            try
            {
                IModel model = Apsim.Get(this.explorerPresenter.ApsimXFile, this.explorerPresenter.CurrentNodePath) as IModel;
                if (model != null)
                {
                    string           modelPath  = Apsim.FullPath(model);
                    StringBuilder    message    = new StringBuilder($"Searching for references to model {Apsim.FullPath(model)}...");
                    List <Reference> references = new List <Reference>();
                    message.AppendLine();
                    message.AppendLine();
                    Stopwatch timer = Stopwatch.StartNew();

                    foreach (VariableReference reference in Apsim.FindAll(model, typeof(VariableReference)))
                    {
                        try
                        {
                            if (Apsim.Get(reference, reference.VariableName.Replace(".Value()", "")) == model)
                            {
                                references.Add(new Reference()
                                {
                                    Member = typeof(VariableReference).GetProperty("VariableName"), Model = reference, Target = model
                                });
                            }
                        }
                        catch
                        {
                        }
                    }
                    timer.Stop();
                    message.AppendLine();
                    message.AppendLine($"Finished. Elapsed time: {timer.Elapsed.TotalSeconds.ToString("#.00")} seconds");
                    explorerPresenter.MainPresenter.ShowMessage(message.ToString(), Simulation.MessageType.Information);
                    var dialog = new Utility.FindAllReferencesDialog(model, references, explorerPresenter);
                }
            }
            catch (Exception err)
            {
                explorerPresenter.MainPresenter.ShowError(err);
            }
        }
Ejemplo n.º 2
0
        public void OnFindReferences(object sender, EventArgs e)
        {
            try
            {
                IModel model = Apsim.Get(this.explorerPresenter.ApsimXFile, this.explorerPresenter.CurrentNodePath) as IModel;
                if (model != null)
                {
                    string           modelPath  = Apsim.FullPath(model);
                    StringBuilder    message    = new StringBuilder($"Searching for references to model {Apsim.FullPath(model)}...");
                    List <Reference> references = new List <Reference>();
                    message.AppendLine();
                    message.AppendLine();
                    Stopwatch    timer = Stopwatch.StartNew();
                    BindingFlags flags;

                    foreach (IModel child in Apsim.FindAll(model))
                    {
                        if (Apsim.FullPath(child) == Apsim.FullPath(model))
                        {
                            continue;
                        }

                        // Resolve links (this doesn't seem to work properly).
                        explorerPresenter.ApsimXFile.Links.Resolve(child, throwOnFail: false);
                        MemberInfo[] members   = null;
                        Type         childType = child.GetType();

                        // First, find all links to the model.
                        // First, try the cache.
                        if (!links.TryGetValue(childType, out members))
                        {
                            // We haven't looked for members of this type before.
                            List <MemberInfo> localMembers = new List <MemberInfo>();

                            // Links may be static or non-static (instance), and can have any accessibility.
                            flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

                            // Find all properties which are links.
                            localMembers.AddRange(child.GetType().GetProperties(flags).Where(p => ReflectionUtilities.GetAttribute(p, typeof(LinkAttribute), true) != null));

                            // Find all fields which are links.
                            localMembers.AddRange(child.GetType().GetFields(flags).Where(f => ReflectionUtilities.GetAttribute(f, typeof(LinkAttribute), true) != null));

                            members = localMembers.ToArray();

                            // Add members to cache.
                            links.Add(childType, members);
                        }

                        // Now iterate over all members of this type which are links.
                        foreach (MemberInfo member in members)
                        {
                            IModel linkValue = ReflectionUtilities.GetValueOfFieldOrProperty(member.Name, child) as IModel;
                            if (linkValue == null)
                            {
                                continue; // Silently ignore this member.
                            }
                            bool isCorrectType  = model.GetType().IsAssignableFrom(linkValue.GetType());
                            bool hasCorrectPath = string.Equals(Apsim.FullPath(linkValue), modelPath, StringComparison.InvariantCulture);
                            if (isCorrectType && hasCorrectPath)
                            {
                                message.AppendLine($"Found member {member.Name} of node {Apsim.FullPath(child)}.");
                                references.Add(new Reference()
                                {
                                    Member = member, Target = model, Model = child
                                });
                            }
                        }

                        //if (model is IFunction && child is IFunction)
                        {
                            // Next, search all public string properties for the path to this model.
                            PropertyInfo[] properties;
                            if (!stringProperties.TryGetValue(childType, out properties))
                            {
                                flags      = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
                                properties = childType.GetProperties(flags).Where(p => p.PropertyType == typeof(string) && p.CanRead).ToArray();
                                stringProperties.Add(childType, properties);
                            }
                            foreach (PropertyInfo property in properties)
                            {
                                string value;
                                try
                                {
                                    // An exception could be thrown here from inside the property's getter.
                                    value = property.GetValue(child) as string;
                                }
                                catch
                                {
                                    continue;
                                }
                                if (value == null)
                                {
                                    continue;
                                }

                                value = value.Replace(".Value()", "").Replace(".Value", "");
                                IModel result = null;
                                try
                                {
                                    result = Apsim.Get(child, value) as IModel;
                                }
                                catch
                                {
                                    continue;
                                }
                                if (result == null)
                                {
                                    continue;
                                }
                                bool correctType = model.GetType().IsAssignableFrom(result.GetType());
                                bool correctPath = string.Equals(Apsim.FullPath(result), modelPath, StringComparison.InvariantCulture);
                                if (correctType && correctPath)
                                {
                                    message.AppendLine($"Found reference in string property {property.Name} of node {Apsim.FullPath(child)}.");
                                    references.Add(new Reference()
                                    {
                                        Member = property, Target = model, Model = child
                                    });
                                }
                            }
                        }
                    }
                    timer.Stop();
                    message.AppendLine();
                    message.AppendLine($"Finished. Elapsed time: {timer.Elapsed.TotalSeconds.ToString("#.00")} seconds");
                    explorerPresenter.MainPresenter.ShowMessage(message.ToString(), Simulation.MessageType.Information);
                    var dialog = new Utility.FindAllReferencesDialog(model, references, explorerPresenter);
                }
            }
            catch (Exception err)
            {
                explorerPresenter.MainPresenter.ShowError(err);
            }
        }